📄 xldr.s
字号:
copy_xldr
ldmia r1!, {r4 - r11}
stmia r0!, {r4 - r11}
subs r2, r2, #32
bne copy_xldr
; Jump to image we just copied to RAM
ldr r0, =IMAGE_BOOT_XLDR_RAM_START
ldr r1, =CSP_BASE_REG_PA_NANDFC
adr r2, entry_point
sub r2, r2, r1
add r2, r0, r2
mov pc, r2
nop
nop
nop
nop
entry_point
; Select NANDFC RAM buffer address
;
; RBA - 1st internal RAM buffer (0 << 0) = 0x0000
; --------
; 0x0000
;
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_RAM_BUFF_ADDRESS_OFFSET)
ldr r0, =0x0000
strh r0, [r1]
; Configure NANDFC operation
;
; SP_EN - main and spare read/write (0 << 2) = 0x0000
; ECC_EN - enable ECC (1 << 3) = 0x0008
; INT_MSK - mask interrupt (1 << 4) = 0x0010
; NF_BIG - little endian (0 << 5) = 0x0000
; NF_RST - no reset (0 << 6) = 0x0000
; NF_CE - normal CE signal (0 << 7) = 0x0000
; --------
; 0x0018
;
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_NAND_FLASH_CONFIG1_OFFSET)
ldr r0, =0x0018
strh r0, [r1]
; Configure NANDFC unlock start block
;
; USBA - block #0 (0 << 0) = 0x0000
; --------
; 0x0000
;
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_UNLOCK_START_BLK_ADD_OFFSET)
ldr r0, =0x0000
strh r0, [r1]
; Configure NANDFC unlock end block
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_UNLOCK_END_BLK_ADD_OFFSET)
ldr r0, =(NAND_BLOCK_CNT-1)
strh r0, [r1]
; Configure NANDFC write protection status
;
; WPC - unlock specified range (4 << 0) = 0x0004
; --------
; 0x0004
;
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_NF_WR_PROT_OFFSET)
ldr r0, =0x0004
strh r0, [r1]
; Current external RAM load address is kept in R3
ldr r3, =(IMAGE_BOOT_BOOTIMAGE_RAM_PA_START)
; Current page address is kept in R12
ldr r12, =(IMAGE_BOOT_BOOTIMAGE_NAND_OFFSET)
; Current block is kept in R13
ldr r13, =(IMAGE_BOOT_BOOTIMAGE_NAND_OFFSET >> NAND_BLOCK_SIZE_LSH)
load_eboot
; Read 2KB of data from the NAND device into NANDFC buffers 0-3
bl NfcRd2K
; Check bad block indicator in first two pages of each block and
; skip bad blocks
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_SPARE_BUFF0_OFFSET+4)
ldrh r0, [r1]
mov r0, r0, lsr #8
cmp r0, #0xFF
bne next_block
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_SPARE_BUFF1_OFFSET+4)
ldrh r0, [r1]
mov r0, r0, lsr #8
cmp r0, #0xFF
bne next_block
; Copy the 2KB of data in the NANDFC buffers to RAM
next_page
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_MAIN_BUFF0_OFFSET)
mov r2, #2048
copy_eboot
ldmia r1!, {r4 - r11}
stmia r3!, {r4 - r11}
subs r2, r2, #32
bne copy_eboot
; Check if we have hit a block boundary
ldr r1, =(NAND_BLOCK_SIZE-1)
ands r1, r1, r3
beq next_block
; Read another 2KB from the NAND device
bl NfcRd2K
b next_page
next_block
; Advance to next NAND block
add r13, r13, #1
; Calculate page address (BLOCK * BLOCK_SIZE)
mov r12, r13, lsl #(NAND_BLOCK_SIZE_LSH)
; Check if we are done
ldr r1, =(IMAGE_BOOT_BOOTIMAGE_NAND_OFFSET+IMAGE_BOOT_BOOTIMAGE_NAND_SIZE)
cmp r12, r1
blt load_eboot
; Jump to EBOOT image copied to DRAM
ldr r1, =(IMAGE_BOOT_BOOTIMAGE_RAM_PA_START)
mov pc, r1
nop
nop
nop
nop
forever
b forever
;-------------------------------------------------------------------------------
;
; Function: NfcCmd
;
; This function issues the specified command to the NAND device.
;
; Parameters:
; command (r0)
; [in] - Command to issue to the NAND device.
;
; Returns:
; None.
;-------------------------------------------------------------------------------
LEAF_ENTRY NfcCmd
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_NAND_FLASH_CMD_OFFSET)
strh r0, [r1]
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_NAND_FLASH_CONFIG2_OFFSET)
ldr r0, =(NANDFC_CONFIG2_FCMD)
strh r0, [r1]
RETURN
;-------------------------------------------------------------------------------
;
; Function: NfcAddr
;
; This function sends an address (single cycle) to the NAND device.
;
; Parameters:
; address (r0)
; [in] - Address to issue to the NAND device.
;
; Returns:
; None.
;-------------------------------------------------------------------------------
LEAF_ENTRY NfcAddr
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_NAND_FLASH_ADD_OFFSET)
strh r0, [r1]
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_NAND_FLASH_CONFIG2_OFFSET)
ldr r0, =(NANDFC_CONFIG2_FADD)
strh r0, [r1]
RETURN
;-------------------------------------------------------------------------------
;
; Function: NfcRdPage
;
; This function reads a page of data from the NAND device.
;
; Parameters:
; NFC buffer (r0)
; [in] - NFC buffer (0-3) into which the page is read
;
; Returns:
; None.
;-------------------------------------------------------------------------------
LEAF_ENTRY NfcRdPage
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_RAM_BUFF_ADDRESS_OFFSET)
strh r0, [r1]
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_NAND_FLASH_CONFIG1_OFFSET)
ldrh r0, [r1]
bic r0, r0, #NANDFC_CONFIG1_SP_EN ; SP_EN = 0 (read main and spare)
strh r0, [r1]
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_NAND_FLASH_CONFIG2_OFFSET)
ldr r0, =(NANDFC_CONFIG2_FDO_PAGE)
strh r0, [r1]
RETURN
;-------------------------------------------------------------------------------
;
; Function: NfcWait
;
; This function waits for the current NAND device operation to complete.
;
; Parameters:
; None.
;
; Returns:
; None.
;-------------------------------------------------------------------------------
LEAF_ENTRY NfcWait
ldr r1, =(CSP_BASE_REG_PA_NANDFC+NANDFC_NAND_FLASH_CONFIG2_OFFSET)
wait_loop
ldrh r0, [r1]
ands r0, r0, #NANDFC_CONFIG2_INT
beq wait_loop
; Clear INT status
bic r0, r0, #NANDFC_CONFIG2_INT
strh r0, [r1]
RETURN
;-------------------------------------------------------------------------------
;
; Function: NfcRd2K
;
; This function reads 2KB (four 512-byte pages) from the NAND device
; from the specified NAND device address.
;
; Parameters:
; address (r12)
; [in/out] - Full page address for NAND device. Advanced to next
; 2KB device offset during read.
;
; Returns:
; None.
;-------------------------------------------------------------------------------
LEAF_ENTRY NfcRd2K
; Save return address
mov r11, r14
; Send page read command
ldr r0, =(CMD_READ)
bl NfcCmd
bl NfcWait
; Start with NANDFC buffer #0
mov r10, #0
NfcRd2Kloop
; Send column address (cycle 1)
and r0, r12, #(0xFF)
bl NfcAddr
bl NfcWait
; Send page address (cycle 2)
mov r0, r12, lsr #NAND_ADDR_CYCLE2_LSH
and r0, r0, #(0xFF)
bl NfcAddr
bl NfcWait
; Send page address (cycle 3)
mov r0, r12, lsr #NAND_ADDR_CYCLE3_LSH
and r0, r0, #(0xFF)
bl NfcAddr
bl NfcWait
; Send page address (cycle 4)
mov r0, r12, lsr #NAND_ADDR_CYCLE4_LSH
and r0, r0, #(0xFF)
bl NfcAddr
bl NfcWait
IF LARGE_PAGE_NAND
; Send the second cycle page read command
ldr r0, =(CMD_READ2CYCLE)
bl NfcCmd
bl NfcWait
ENDIF
NfcRd528Bytes
; Read the page
mov r0, r10
bl NfcRdPage
bl NfcWait
IF :LNOT: LARGE_PAGE_NAND
; Advance page pointer to next page
add r12, r12, #NAND_PAGE_SIZE
; Advance to next NANDFC buffer
add r10, r10, #1
; See if we are done
cmp r10, #3
ble NfcRd2Kloop
ELSE
; Advance to next NANDFC buffer
add r10, r10, #1
; See if we are done
cmp r10, #3
ble NfcRd528Bytes
; Advance page pointer to next page
add r12, r12, #NAND_PAGE_SIZE
ENDIF
; Restore return address
mov r14, r11
RETURN
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -