📄 boot_c6727.asm
字号:
ldw *A4,B4
nop 4
and B4,B3,B0 ; bit5 is the /HCS pin on reset: 1=>FLASH-BOOT, 0=>UHPI-BOOT
[B0] b _flash_boot_tablecopy ; if bit 4 is set, then we are in a flash boot scenario
nop 5
;************************************************************************
; let UHPI host copy the sections and enter the start address from the table in the image
; this is mainly sending a request and waiting for a handshake value
;************************************************************************
_uhpi_boot_tablecopy:
mvkl _boot2_start_address, A4 ; load addres where symbol value of startup routine is stored
mvkh _boot2_start_address, A4
ldw *A4, B2 ; create a backup of the opcode at the entry point
nop 4
; re-enable the UHPI unit, keep all registers as they were at boot
mvkl CFGHPI, A4 ; load address for UHPI config register
mvkh CFGHPI, A4
mvkl CFGHPI_ENA, B4 ; load bitmask for HPI enable bit
mvkh CFGHPI_ENA, B4
ldw *A4, B3 ; re-enable UHPI by simply setting its enable bit
nop 4
or B3,B4,B3
nop 4
stw B3, *A4
nop 4
; communicate with the host
mvkl _boot2_handshake, A4 ; load address for handshake register
mvkh _boot2_handshake, A4
mvkl TRANSFER_REQUEST, B4 ; request value for boot loader stage 2
mvkh TRANSFER_REQUEST, B4
mvkl TRANSFER_DONE, B3 ; reply value for boot loader stage 2
mvkh TRANSFER_DONE, B3
stw B4,*A4 ; send request to UHPI master "please load all section data"
nop 4
_uhpi_boot_wait:
ldw *A4, B4 ; read the value from the handshake location
nop 4
sub B4, B3, B0 ; check for a match
nop 4
[B0] b _uhpi_boot_wait ; no match until now, check once again
nop 5
; keep the UHPI unit enabled - this allows UHPI to read back its very own reply: the written handshake values
mvkl _boot2_start_address, A3 ; load addres where symbol value of startup routine is stored
mvkh _boot2_start_address, A3
ldw *A3, B1 ; load start address into B1
nop 4
stw B2, *A3 ; restore the backup of the opcode at the entry point
; this will ease debugging and other tricks from main...
b copy_done
nop 5
;************************************************************************
; Enable the GPIO-lines on the UHPI-interface
; some GPIOs are used as virtual address lines for addressing the FLASH
;************************************************************************
_flash_boot_tablecopy:
; The upper part of the UHPI is used as GPIO-lines
;*GPIOEN |= 0x00000200; Enable pin group to be GPIO
;*GPIODIR1 |= 0x007f0000; HD16-HD22 are the address lines
;*GPIODAT1 &= ~0x007f0000; clear all address lines to 0
mvkl UHPI_REG_START,A0
mvkh UHPI_REG_START,A0
LDW *+A0[(GPIOEN-UHPI_REG_START)/4],A3
LDW *+A0[(GPIODIR1-UHPI_REG_START)/4],A4
LDW *+A0[(GPIODAT1-UHPI_REG_START)/4],A5
NOP 3
SET A3,9,9,A3
STW A3,*+A0[(GPIOEN-UHPI_REG_START)/4]
SET A4,16,22,A4
STW A4,*+A0[(GPIODIR1-UHPI_REG_START)/4]
CLR A5,16,22,A5
STW A5,*+A0[(GPIODAT1-UHPI_REG_START)/4]
NOP 4
;************************************************************************
; copy sections from FLASH to RAM using linker generated copy table.
; compare: spra999A.pdf "2.3 Writing the Secondary Bootloader" Figure 3
;************************************************************************
mvkl COPY_TABLE, a3 ; load pointer to the copy table
mvkh COPY_TABLE, a3
; Prepare generation of flash address signals using GPIO
MVKL GPIODAT1,a10
MVKH GPIODAT1,a10
mvkl 0x003f8000,b10 ;
mvkh 0x003f8000,b10 ;
LDW *a10,a11 ; *GPIODAT1 & ~0x007f0000
NOP 4
;*GPIODAT1 = (*GPIODAT1 & ~0x007f0000) | (((U32)Addr & 0x003F80000) << 1);
AND b10,a3,a12 ; Addr & 0x003f8000
CLR a11,16,22,a11 ; *GPIODAT1 & ~0x007f0000
ADD a12,a12,a12 ; << 1
OR a12,A11,A11 ; |
STW A11,*a10 ;
NOP 5 ; address simulation via GPIO block END
ldw *a3++, b1 ; load entry point adress
copy_section_top:
;*GPIODAT1 = (*GPIODAT1 & ~0x007f0000) | (((U32)Addr & 0x003F80000) << 1);
AND b10,a3,a12 ; Addr & 0x003f8000
CLR a11,16,22,a11 ; *GPIODAT1 & ~0x007f0000
ADD a12,a12,a12 ; << 1
OR a12,A11,A11 ; |
STW A11,*a10 ;
NOP 5 ; address simulation via GPIO block END
ldw *a3, b0 ; load byte count of section
ldw *a3++, b0 ; load byte count of section
;*GPIODAT1 = (*GPIODAT1 & ~0x007f0000) | (((U32)Addr & 0x003F80000) << 1);
AND b10,a3,a12 ; Addr & 0x003f8000
CLR a11,16,22,a11 ; *GPIODAT1 & ~0x007f0000
ADD a12,a12,a12 ; << 1
OR a12,A11,A11 ; |
STW A11,*a10 ;
NOP 5 ; address simulation via GPIO block END
ldw *a3, a4 ; load ram start address of section
ldw *a3++, a4 ; load ram start address of section
nop 3
[!b0] b copy_done ; if byte count from table is 0, then we have we copied all sections
nop 5
copy_bytes_loop:
;*GPIODAT1 = (*GPIODAT1 & ~0x007f0000) | (((U32)Addr & 0x003F80000) << 1);
AND b10,a3,a12 ; Addr & 0x003F80000
CLR a11,16,22,a11 ; *GPIODAT1 & ~0x007f0000
ADD a12,a12,a12 ; << 1
OR a12,A11,A11 ; |
STW A11,*a10 ;
NOP 5 ; address simulation via GPIO block END
ldb *a3++,b5 ; load next data byte
sub b0,1,b0 ; decrement byte counter by one
[ b0] b copy_bytes_loop ; if there are still bytes to copy then setup a branch for the next byte
[!b0] b copy_section_top ; if there are no more bytes to copy then setup a branch for the next section
zero a1 ; speculative pre-assignment source address fraction bits with zero
[!b0] and 3,a3,a1 ; (conditionally) determine fraction bits of source address for a 4 byte alignment
stb b5,*a4++ ; store previousely loaded data byte to target location
[!b0] and -4,a3,a5 ; (conditionally) round source address up down to 4 byte alignment, store in temp
[ a1] add 4,a5,a3 ; (conditionally) add 4 bytes to temp, store in real source address
copy_done:
.if $isdefed("WAIT_ON_FINALE")
;************************************************************************
;* DEBUG LOOP
;************************************************************************
zero B2
_myloop2:
[!B2] B _myloop2
nop 5
_myloopend2:
nop
.endif ; WAIT_ON_STARTUP
;************************************************************************
; jump to start_address in B1
;************************************************************************
b .S2 B1 ; jump to start address
nop 5
; ### EOF ###
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -