DSPRelated.com
Forums

DM642 Bootloading from flash past 512KB

Started by thew...@gmail.com August 11, 2008
Hello!

I have been able to successfully bootload 512KB programs from flash on our EVM DM642 board. But I'm having difficulty when we exceed the first flash page. I've read some of the following related notes:

1. The hex6x utility is bugged for 500KB+. But apparently v6.0.8 corrects this, and I am using v6.0.8.

2. I've seen some people say they can accomplish this by writing 2 programs where both include a 2nd-level bootloader but the 1st program changes the flash page before launching the 2nd program. This is a weak solution for me for several reasons:

- My primary program is 1.2MB, requiring 3 flash pages.
- I am unclear how to avoid initialization in the 2nd program such that we don't initialize twice. CSL for example.
- Harder to maintain multiple codes

3. I've seen some confusing mentions that the FPGA needs to be loaded and running before you can change the FLASH page, but I believed the FLASH page register was in the CPLD so wasn't sure if this was accurate?

4. I've disabled RTDX as mentioned by Spectrum Digital.

5. Glancing at the code for the FBTC642 (EVM v3, 720Mhz), it appears to be page-aware in this up-to-date version.

My ideal solution is to modify the boot.asm to switch FLASH pages when we reach the end of the address space. This is challenging because it is very hard to troubleshoot the process. I did some uglies in the ASM, but here it is. It continues to work ok on <512KB loads but hangs for larger.

.title "Flash bootup utility for DM642 EVM"
.option D,T
;; .length 102
;; .width 140

COPY_TABLE .equ 0x90000400
EMIF_BASE .equ 0x01800000

FLASH_NEXT .equ 0x9007FFFF ; Address for a greater-than comparison with current src addr.
EVDM642_FPG .equ 0x90080018 ; EVDM642 Flash Page Control Register Address
NEW_COPY_AT .equ 0x90000000 ; Address to restart reading after flash page change.

.sect ".boot_load"
.global _boot

_boot:
;************************************************************************
;* Debug Loop - Comment out B for Normal Operation
;************************************************************************

zero B1
_myloop: ; [!B1] B _myloop
nop 5
_myloopend: nop

;************************************************************************
;* Configure EMIF
;************************************************************************

mvkl emif_values, a3 ; load pointer to emif values
mvkh emif_values, a3

mvkl EMIF_BASE, a4 ; load EMIF base address
mvkh EMIF_BASE, a4

mvkl 0x0009, b0 ; load number of registers to set
mvkh 0x0000, b0

emif_loop:
ldw *a3++, b5 ; load register value
sub b0,1,b0 ; decrement counter
nop 2
[ b0] b emif_loop
stw b5, *a4++ ; store register value
nop 4

;****************************************************************************
;* Copy code sections
;****************************************************************************
mvkl COPY_TABLE, a3 ; load table pointer
mvkh COPY_TABLE, a3

mvkl FLASH_NEXT, a8 ; load constant
mvkh FLASH_NEXT, a8
mvkl EVDM642_FPG, b9 ; load constant
mvkh EVDM642_FPG, b9
zero b10 ; b10 will hold our current flash page. Start on flash page 0x00.

ldw *a3++, b1 ; Load entry point

copy_section_top:
ldw *a3++, b0 ; byte count
ldw *a3++, a4 ; ram start address
nop 3

[!b0] b copy_done ; have we copied all sections?
nop 5

copy_loop:

cmpgt a3,a8,a2 ; check if a flash-page-change is due...
[a2] b new_page
; I'm sure there's a better way to do this, but I just came up with this
; "Conditional NOP" to facilitate the branching without slowing down
; the !a2 case.
[a2] zero b5
[a2] zero b5
[a2] zero b5
[a2] zero b5
[a2] zero b5

ldb *a3++,b5
sub b0,1,b0 ; decrement counter

[ b0] b copy_loop ; setup branch if not done
[!b0] b copy_section_top
zero a1
[!b0] and 3,a3,a1
stb b5,*a4++
[!b0] and -4,a3,a5 ; round address up to next multiple of 4
[ a1] add 4,a5,a3 ; round address up to next multiple of 4

;****************************************************************************
;* Jump to entry point
;****************************************************************************
copy_done:
b .S2 b1
nop 5

new_page:
add 1,b10,b10
stb b10,*b9
mvkl 1000,b11
mvkh 1000,b11

do_pause:
nop 5
sub b2,1,b2
[ b2] b do_pause
nop 5

mvkl NEW_COPY_AT,a3
mvkh NEW_COPY_AT,a3
nop 5
b copy_loop
nop 5

emif_values:
.long 0x00052078 ; GBLCTL
.long 0x73a28e01 ; CECTL1 (Flash/FPGA)
.long 0xffffffd3 ; CECTL0 (SDRAM)
.long 0x00000000 ; Reserved
.long 0x22a28a22 ; CECTL2
.long 0x22a28a22 ; CECTL3
.long 0x57115000 ; SDCTL
.long 0x0000081b ; SDTIM (refresh period)
.long 0x001faf4d ; SDEXT
thewiley,

Amongst other things, the a3 register, once set to entries in the 'COPY_TABLE'
should be left pointing at the copy table, not used to step through code addresses.
my inline comments are prefixed with '> -------'
The incorrect usage of a3 as the data source address is not the only problem,
would be get you started in the right direction for debugging the problems with
this code.

R. Williams
---------- Original Message -----------
From: t...@gmail.com
To: c...
Sent: Mon, 11 Aug 2008 20:19:18 -0400
Subject: [c6x] DM642 Bootloading from flash past 512KB

.title "Flash bootup utility for DM642 EVM"
> .option D,T
> ;; .length 102
> ;; .width 140
>
> COPY_TABLE .equ 0x90000400
> EMIF_BASE .equ 0x01800000
>
> FLASH_NEXT .equ 0x9007FFFF ; Address for a greater-than comparison
> with current src addr.
EVDM642_FPG .equ 0x90080018 ; EVDM642 Flash
> Page Control Register Address NEW_COPY_AT .equ 0x90000000 ; Address to
restart reading after flash page change.
>
> .sect ".boot_load"
> .global _boot
>
> _boot:
>
> ;************************************************************************
> ;* Configure EMIF
> ;************************************************************************

> ;****************************************************************************
> ;* Copy code sections
> ;****************************************************************************
> mvkl COPY_TABLE, a3 ; load table pointer
> mvkh COPY_TABLE, a3
>
> mvkl FLASH_NEXT, a8 ; load constant
> mvkh FLASH_NEXT, a8
> mvkl EVDM642_FPG, b9 ; load constant
> mvkh EVDM642_FPG, b9

> zero b10 ; b10 will hold our current flash page. Start on flash page
0x00.
>
> ldw *a3++, b1 ; Load entry point
>
> copy_section_top:
> ldw *a3++, b0 ; byte count
> ldw *a3++, a4 ; ram start address
> nop 3
>
> [!b0] b copy_done ; have we copied all sections?
> nop 5
>
> copy_loop:

> -------a3 is pointing into the copy table,
> -------so has no relationship to 'if a full flash page has been copied

> cmpgt a3,a8,a2 ; check if a flash-page-change is due...
> [a2] b new_page
> ; I'm sure there's a better way to do this, but I just came up with this
> ; "Conditional NOP" to facilitate the branching without slowing down
> ; the !a2 case.
> [a2] zero b5
> [a2] zero b5
> [a2] zero b5
> [a2] zero b5
> [a2] zero b5
>
> --------From here on, the source address is NOT a3 but rather b1
> ldb *a3++,b5
> sub b0,1,b0 ; decrement counter
>
> [ b0] b copy_loop ; setup branch if not done
> [!b0] b copy_section_top
> zero a1
> [!b0] and 3,a3,a1
> stb b5,*a4++
> [!b0] and -4,a3,a5 ; round address up to next multiple of 4
> [ a1] add 4,a5,a3 ; round address up to next multiple of 4
>
> ;****************************************************************************
> ;* Jump to entry point
> ;****************************************************************************
> copy_done:
> b .S2 b1
> nop 5
>
> new_page:
> add 1,b10,b10
> stb b10,*b9
> mvkl 1000,b11
> mvkh 1000,b11
>
> do_pause:
> nop 5
> sub b2,1,b2
> [ b2] b do_pause
> nop 5
>
> mvkl NEW_COPY_AT,a3
> mvkh NEW_COPY_AT,a3
> nop 5
> b copy_loop
> nop 5
>
> emif_values:
> .long 0x00052078 ; GBLCTL
> .long 0x73a28e01 ; CECTL1 (Flash/FPGA)
> .long 0xffffffd3 ; CECTL0 (SDRAM)
> .long 0x00000000 ; Reserved
> .long 0x22a28a22 ; CECTL2
> .long 0x22a28a22 ; CECTL3
> .long 0x57115000 ; SDCTL
> .long 0x0000081b ; SDTIM (refresh period)
> .long 0x001faf4d ; SDEXT
------- End of Original Message -------