DSPRelated.com
Forums

booting

Started by raja nayaka January 24, 2003

ROM  -BOOTING 

 

TMS320C6211 DSP  is a single  map device with on chip SRAM  beginning  from 0x00000000     TO    0x00010000.  It  has a 64Kb of on- chip memory.

 

The device is designed to operate in little endian mode controlled by HD[8] pin.

HD[8]=1 Little endian ( Default state)

HD[8]=0 Big   endian

 

Upon  reset   TMS320C6211 DSP  loads  1Kb of code from  CE1 space to the on-chip memory  starting at 0x00000000 and starts executing from the 0th location.

We are using winbond  EPROM  W27L010 which is 128K X 8  in size. The EPROM is connected at CE1 space as desired.

 

The DSP has 4  modes of booting i.e. 

(1)   HPI BOOT

(2)   8 bit ROM BOOT

(3)   16 bit ROM BOOT

(4)   32 bit ROM BOOT.

 

 The configuration of the boot mode is selectable from the 2 pins i.e. HD[3] and HD[4].

 

HD[4]   HD[3]

   0         0               HPI BOOT

   0         1               8 bit ROM BOOT  ( Default state)

1                    0              16 bit ROM BOOT

1         1               32 bit ROM BOOT

 

 

The HPI data bus  is directly connected to the PCI-2040 bridge  without a Buffering.

The  BOOT code burnt into the  EPROM  consists  of the following .

 

(1)   Initialization of all the EMIF registers.

(2)   Initialization of all the QDMA registers.

(3)    Secondary software boot loader code

(4)    Reset vector table.

 

As the hardware boot loader loads only  1Kb  of code on to the on-chip memory , its not sufficient to execute , thats  the reason why we go for the Secondary  software boot loader.

In the secondary software boot loader, we use the QDMA ( quick DMA) for the data transfer from the EPROM to the on-chip memory.

The QDMA  register consists of the

Start address             :

Destination Address  :

Word count                :

 

The values for the above parameters are obtained from the MAP file generated by the linker .

 

The reset vector table is the entry point for the user code. Here in this code  the Program counter is made a  jump to the _main()  of the source code  ( Entry point of the application code).

 

 

PROBLEMS ON HAND

 

(1)    The Boot code was not getting loaded onto the on-chip memory from the                                                 

         EPROM.

 

Solution : The problem was suspected to be the PCI-2040 Bridge  as it has a direct interface with the HPI  bus of the DSP.  Thus the  HD[4] and HD[3] pins were lifted . The code then started to load on to the on-chip memory.

 

The problem in the design can be solved by having a 16 bit buffer in between the DSP and the Bridge.

 

(2)    The  code gets loaded on to the on-chip memory but does not execute.

i.e. the program counter does not vary, and remains at 0x00000000.

 

Solution :    NOT YET

 

 

 

 

 

 

Observation:  There is a very interesting observation here..

 

When I reset, I get some code (which is actually not what I have written).

When I tried to manually reset it again and again (say around 10 times continuously) I get my actual code, which I am supposed to get.

But still the program counter was at 0x00000000.

 

When I try again and again with the reset procedure, I find   some junk code getting loaded and to the surprise the Program counter change to some value

i.e. PC=0x8F000000.

 

Then again when I switched off all the power and applied it again, I was left with the same old code with (pc=0x0000000).

 

 

Understanding:   Our understanding is that the 8 bit op-codes that are burnt into the EPROM are not getting properly buffered to form the 32 bit valid op-code.

As the DSP is a 32-bit processor, the EMIF has to buffer the 8 bits of data to form a 32-bit op-code.

 




Hello C6x Pals
   I am using a custom C6211 DSP board. I have written a simple application to
write a 32 bit data into the extrnal RAM. Here is my map file.

I want to fuse this code into the ROM ( 128Kx8). The Rom is connected at
CE1 space and the DSP is in little endian mode.

I have wriiten the custom boot code as follows ( below the map file).
I want to know as what are the various sections that I need to copy
from the ROM to the onchip memory using QDMA.
( The DSP 6211 copies 1Kb code from CE1 space to on chip memory).

I tried copying the .text and .cinit sections ..but the code is not getting
executed on reset.

can any one suggest as what sections i need to copy onchip so that the code executes..

whats the problem with this code?
( I have also included my linker file below)

 

Thanking you

R.J.Nayaka
Scientist Core R&D,
CTI Group,
ITILTD
Bangalore
India
www.itiltd-india.com


******************************************************************************
          TMS320C6x COFF Linker PC Version 4.10               
******************************************************************************
>> Linked Thu Jan 20 15:47:27 2000

OUTPUT FILE NAME:   <main.out>
ENTRY POINT SYMBOL: "_c_int00"  address: 000007a0


MEMORY CONFIGURATION

                  name            origin    length      used    attr    fill
         ----------------------  --------  ---------  --------  ----  --------
         VECS                    00000000   00000200  00000120  RWIX
         PMEM                    00000200   00007e00  00000700  RWIX
         DMEM                    00008000   00007e00  000002e8  RWIX
         CE0                     80000000   01000000  00000000  RWIX
         CE1VECS                 90000000   00000200  00000120  RWIX
         CE1PMEM                 90000200   00007e00  00000700  RWIX
         CE1init                 90008000   00007e00  00000054  RWIX


SECTION ALLOCATION MAP

 output                                  attributes/
section   page    origin      length       input sections
--------  ----  ----------  ----------   ----------------
.boot_load   0    90000000    00000120     RUN ADDR = 00000000
                  90000000    00000120     boot.obj (.boot_load)

.text      0    90000200    00000700     RUN ADDR = 00000200
                  90000200    00000260     rts6201.lib : memcpy.obj (.text)
                  90000460    00000000     boot.obj (.text)
                  90000460    00000240     rts6201.lib : exit.obj (.text)
                  900006a0    00000100                 : autoinit.obj (.text)
                  900007a0    000000a0                 : boot.obj (.text)
                  90000840    00000080     test.obj (.text)
                  900008c0    00000040     rts6201.lib : _lock.obj (.text)

.cinit     0    90008000    00000054     RUN ADDR = 00008000
                  90008000    0000002c     rts6201.lib : exit.obj (.cinit)
                  9000802c    00000004     --HOLE-- [fill = 00000000]
                  90008030    0000001c                 : _lock.obj (.cinit)
                  9000804c    00000008     --HOLE-- [fill = 00000000]

.const     0    00008000    00000000     UNINITIALIZED

.data      0    00008000    00000000     UNINITIALIZED
                  00008000    00000000     boot.obj (.data)
                  00008000    00000000     rts6201.lib : memcpy.obj (.data)
                  00008000    00000000                 : autoinit.obj (.data)
                  00008000    00000000                 : _lock.obj (.data)
                  00008000    00000000                 : exit.obj (.data)
                  00008000    00000000                 : boot.obj (.data)
                  00008000    00000000     test.obj (.data)

.cio       0    00008000    00000000     UNINITIALIZED

.far       0    00008054    00000094     UNINITIALIZED
                  00008054    0000008c     rts6201.lib : exit.obj (.far)
                  000080e0    00000008                 : _lock.obj (.far)

.stack     0    000080e8    00000200     UNINITIALIZED
                  000080e8    00000000     rts6201.lib : boot.obj (.stack)

.bss       0    00008000    00000000     UNINITIALIZED
                  00008000    00000000     boot.obj (.bss)
                  00008000    00000000     rts6201.lib : memcpy.obj (.bss)
                  00008000    00000000                 : autoinit.obj (.bss)
                  00008000    00000000                 : _lock.obj (.bss)
                  00008000    00000000                 : exit.obj (.bss)
                  00008000    00000000                 : boot.obj (.bss)
                  00008000    00000000     test.obj (.bss)

.sysmem    0    00008000    00000000     UNINITIALIZED


GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name

address    name
--------   ----
00008000   $bss
00008000   .bss
00008000   .data
00000200   .text
00000688   C$$EXIT
00000200   __STACK_SIZE
00008000   ___bss__
00008000   ___cinit__
00008000   ___data__
00008000   ___edata__
00008000   ___end__
00000900   ___etext__
ffffffff   ___pinit__
00000200   ___text__
000006a0   __auto_init
000080d8   __cleanup_ptr
000080dc   __dtors_ptr
000080e0   __lock
000008c0   __nop
000008c8   __register_lock
000008dc   __register_unlock
000080e8   __stack
000080e4   __unlock
00000688   _abort
000005b0   _atexit
00000000   _boot
000007a0   _c_int00
00000460   _exit
00000840   _main
00000200   _memcpy
00008000   cinit
00008000   edata
00008000   end
00000900   etext
ffffffff   pinit


GLOBAL SYMBOLS: SORTED BY Symbol Address

address    name
--------   ----
00000000   _boot
00000200   ___text__
00000200   __STACK_SIZE
00000200   .text
00000200   _memcpy
00000460   _exit
000005b0   _atexit
00000688   _abort
00000688   C$$EXIT
000006a0   __auto_init
000007a0   _c_int00
00000840   _main
000008c0   __nop
000008c8   __register_lock
000008dc   __register_unlock
00000900   ___etext__
00000900   etext
00008000   ___bss__
00008000   ___cinit__
00008000   ___end__
00008000   $bss
00008000   .data
00008000   .bss
00008000   end
00008000   ___data__
00008000   ___edata__
00008000   cinit
00008000   edata
000080d8   __cleanup_ptr
000080dc   __dtors_ptr
000080e0   __lock
000080e4   __unlock
000080e8   __stack
ffffffff   pinit
ffffffff   ___pinit__

[35 symbols]
______________________________________________________________________________________________

custom boot code


 .title  "ROM boot"
      
; EMIF registers and values  

EMIF_GCR      .equ    0x01800000  ;EMIF global control    
EMIF_CE1      .equ    0x01800004  ;address of EMIF CE1 control reg.
EMIF_CE0      .equ    0x01800008  ;EMIF CE0control         
EMIF_CE1_8    .equ    0xffffff03  ;
EMIF_CE0_V    .equ    0xc0ffff30  ;EMIF CE0control   ;0x30


; QDMA registers and values

QDMA_OPT   .equ   0x02000000  ;QDMA options register
QDMA_OPT_VAL  .equ   0x21200001  ;QDMA options
QDMA_SRC   .equ   0x02000004  ;QDMA source address register
QDMA_CNT   .equ   0x02000008  ;QDMA count register
QDMA_DST   .equ   0x0200000c  ;QDMA destination address register
QDMA_S_IDX   .equ   0x02000030  ;QDMA index pseudo-register

 
 .sect ".boot_load"
 .global _boot
 .ref _c_int00
 
 
_boot:            
                                          
; **************      
; Configure EMIF               
; **************
                           
            mvkl  EMIF_GCR,A4    ;EMIF_GCR address ->A4
      ||    mvkl  0xffff,B4     

            mvkh  EMIF_GCR,A4
      ||    mvkh  0xffff,B4 
                           
            stw   B4,*A4            

            mvkl  EMIF_CE0,A4       ;EMIF_CE0 address ->A4
      ||    mvkl  EMIF_CE0_V,B4     ;

            mvkh  EMIF_CE0,A4
      ||    mvkh  EMIF_CE0_V,B4
     
            stw   B4,*A4

            mvkl  EMIF_CE1,A4       ;EMIF_CE1 address ->A4
      ||    mvkl  EMIF_CE1_8,B4     ;

            mvkh  EMIF_CE1,A4
      ||    mvkh  EMIF_CE1_8,B4
     
            stw   B4,*A4
   
; *************           
; Copy Sections
; *************


      mvkl  copyTable, a3 ; load table pointer
      mvkh  copyTable, a3
      
copy_section_top: 
      ldw   *a3++, b0 ; byte count
      ldw   *a3++, a4 ; load ram start address
      ldw   *a3++, b4 ; load flash start address
      nop   2
 [!b0]   b copy_done  ; have we copied all sections?
      nop 5
      
; copy this section with QDMA

   mvkl  QDMA_OPT,A5 ; set QDMA options
  ||  mvkl  QDMA_OPT_VAL,B5     
    mvkh  QDMA_OPT,A5
  ||  mvkh  QDMA_OPT_VAL,B5
    stw   B5,*A5
    mvkl  QDMA_SRC,A5 ; load source address
    mvkh  QDMA_SRC,A5     
    stw   B4,*A5        
   shr   B0,2,B1       ; divide size by 4 (because we're in 32-bit mode)
   mvkl  QDMA_CNT,A5  ; load word count
   mvkh  QDMA_CNT,A5     
    stw   B1,*A5           
    mvkl  QDMA_DST,A5 ; load destination address
    mvkh  QDMA_DST,A5     
    stw   A4,*A5  
   mvkl  QDMA_S_IDX,A5 ; set index. writing to this register will
    mvkh  QDMA_S_IDX,A5 ; also initiate the transfer.
    zero  B5
    stw   B5,*A5        ; go!

; next section           

   b   copy_section_top
   nop   5

copy_done:  ; done with section copying. 
   
    ; jump to _c_int00
   
     mvkl .S2 _c_int00, B0
            mvkh .S2 _c_int00, B0
            B    .S2 B0
            nop   5
              
              
; *************           
; Section Table
; *************
              
              
    ;; Table of sections to copy. Format is:
    ;; word 0: byte count
    ;; word 1: run address
    ;; word 2: load address
   
  
  
copyTable:      
    ;; .text
    .word 0x000006c0
    .word 0x00000200
    .word 0x90000200
 
  ;;.cinit
    .word 0x00000054
    .word 0x00008000
    .word 0x90008000
   
    .word
   
    .word 0
    .word 0
    .word 0             
__________________________________________________________________________________________________
Linker file

-c
boot.obj
test.obj
-o main.out
-heap 0x200
-stack 0x200
-l rts6201.lib
MEMORY
{
VECS:    o = 00000000h l = 00000200h
PMEM:    o = 00000200h l = 00007E00h
DMEM:    o = 00008000h l = 00007E00h
CE0:     o = 80000000h l = 01000000h
CE1VECS: o = 90000000h l = 00000200h
CE1PMEM: o = 90000200h l = 00007E00h
CE1init: o = 90008000h l = 00007E00h
}
SECTIONS
{
".boot_load" : loadVECS, run=VECS
.text        : loadPMEM, run=PMEM
.cinit       : loadinit, run=DMEM
.const        >DMEM
.data         >DMEM
.cio          > DMEM
.far          > DMEM
.stack        > DMEM
.bss          > DMEM
.sysmem       > DMEM
}