📄 nandloader.s
字号:
;* PARAMETERS: None
;*
;* RETURNS: None
;*
;******************************************************************************
NandBoot
ldr r4, =(NFC_BASE + NFC_REGISTERS_OFFSET)
; unlock ram buffers
ldrh r5, [r4, #NFC_CONFIGURATION_OFFSET]
bic r5, r5, #3
orr r5, r5, #NFC_BLS_UNLOCK
strh r5, [r4, #NFC_CONFIGURATION_OFFSET]
; Set ram buffer to use
ldr r5, =NAND_BUFFER_IN_USE_ID
strh r5, [r4, #NFC_RAM_BUFF_ADD_OFFSET]
; config1 use default
; r5 - image to ram
ldr r5, =(RamPABase + EbootInRamOffset)
; r6 - loaded block counter
mov r6, #0
; load from first good block after block 0
mov r7, #1
5
; Valid block sanity check
ldr r0, =NAND_NUM_BLOCKS
cmp r0, r7
bls LoopForever
mov r0, r7
bl IsBlockGood
tst r0, #1
addeq r7, r7, #1
beq %b5
15
; Good block found. Read all pages from block.
mov r0, r7, LSL #NAND_NUM_PAGE_LSHIFT
add r1, r5, r6, LSL #NAND_BLOCK_SIZE_LSHIFT
mov r2, #0
ldr r3, =NAND_NUM_PAGES
bl NfcReadSectors
; increment counters
add r6, r6, #1
add r7, r7, #1
cmp r6, #NAND_INFO_LOAD_IMAGE_BLOCKS
bne %b5
30
; Done. Jump to start of loaded image
mov pc, r5
b LoopForever
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; FUNCTION: NfcWaitForReady
;
; DESCRIPTION: loops until NFC indicates operation done.
;
; PARAMETERS: None
;
; RETURNS: None
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
NfcWaitForReady
stmfd sp!, {r4-r5, lr}
ldr r4, =(NFC_BASE + NFC_REGISTERS_OFFSET)
10
ldrh r5, [r4, #NFC_CONFIG2_OFFSET]
tst r5, #NFC_CONFIG2_INT
beq %b10
ldmfd sp!, {r4-r5, pc}
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; FUNCTION: NfcSendCmd
;
; DESCRIPTION: Send a Nand flash command cycle.
;
; PARAMETERS:
; r0 - cmd to send
;
; RETURNS: None
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
NfcSendCmd
stmfd sp!, {r4-r5, lr}
ldr r4, =(NFC_BASE + NFC_REGISTERS_OFFSET)
strh r0, [r4, #NFC_FLASH_CMD_OFFSET]
ldr r5, =NFC_FCMD_CMD_WRITE
strh r5, [r4, #NFC_CONFIG2_OFFSET]
bl NfcWaitForReady
ldmfd sp!, {r4-r5, pc}
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; FUNCTION: NfcSendAddr
;
; DESCRIPTION: Send a Nand flash address cycle.
;
; PARAMETERS:
; r0 - address to send
;
; RETURNS: None
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
NfcSendAddr
stmfd sp!, {r4-r5, lr}
ldr r4, =(NFC_BASE + NFC_REGISTERS_OFFSET)
strh r0, [r4, #NFC_FLASH_ADD_OFFSET]
ldr r5, =NFC_FADD_ADDR_WRITE
strh r5, [r4, #NFC_CONFIG2_OFFSET]
bl NfcWaitForReady
ldmfd sp!, {r4-r5, pc}
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; FUNCTION: NfcReadSectors
;
; DESCRIPTION: Reads NFC sector data. Assumes ram buffer to use
; is already set in NfcInit. If a buffer for read
; data is 0, that data is not read.
;
; PARAMETERS:
; r0 - start sector address to read from
; r1 - address to read main data to
; r2 - address to read spare data to
; r3 - number of sectors to read
;
; RETURNS: None
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
NfcReadSectors
stmfd sp!, {r4-r11, lr}
ldr r4, =(NFC_BASE + NFC_REGISTERS_OFFSET)
; Set to read main & spare
ldrh r5, [r4, #NFC_CONFIG1_OFFSET]
bic r5, r5, #NFC_CONFIG1_SP_EN
strh r5, [r4, #NFC_CONFIG1_OFFSET]
mov r5, r0
10
; send page read command
ldr r0, =NAND_CMD_READ
bl NfcSendCmd
; send full address
mov r6, r5, LSL #NAND_PAGE_SIZE_LSHIFT
and r0, r6, #0xFF
bl NfcSendAddr
mov r6, r6, LSR #9
and r0, r6, #0xFF
bl NfcSendAddr
mov r6, r6, LSR #8
and r0, r6, #0xFF
bl NfcSendAddr
IF SEND_4TH_ADDR_CYCLE
mov r6, r6, LSR #8
and r0, r6, #0xFF
bl NfcSendAddr
ENDIF
15
; read sector data
ldr r6, =NFC_FDO_PAGE_READ
strh r6, [r4, #NFC_CONFIG2_OFFSET]
bl NfcWaitForReady
; Check ECC status
;; ldrh r0, [r4, #NFC_ECC_STATUS_RESULT_OFFSET]
;; and r0, r0, #NFC_ECC_ERM_RESERVED
;; cmp r0, #NFC_ECC_ERM_UNRECV_ERR
;; bhs LoopForever
; copy main data if required
teq r1, #0
beq %f25
; copy from main buffer# to destination
; Set NFC main buffer address
ldr r6, =NFC_MAIN_BUFFER_IN_USE_ADDR
ldr r7, =(NFC_MAIN_BUF_SIZE / 16)
20
ldmia r6!, {r8-r11}
stmia r1!, {r8-r11}
subs r7, r7, #1
bne %b20
25
; copy spare data if required
teq r2, #0
beq %f40
; copy from buffer spare area to destination
ldr r6, =NFC_SPARE_BUFFER_IN_USE_ADDR
ldr r7, =(NFC_SPARE_BUF_SIZE / 16)
30
ldmia r6!, {r8-r11}
stmia r2!, {r8-r11}
subs r7, r7, #1
bne %b30
40
; update page counters
add r5, r5, #1
subs r3, r3, #1
IF SEQUENTIAL_PAGE_READ_SUPPORT
bne %b15
ELSE
bne %b10
ENDIF
ldmfd sp!, {r4-r11, pc}
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; FUNCTION: IsBlockGood
;
; DESCRIPTION: Checks if a block is good by checking the bad
; block indicators of first 2 sectors of block.
;
; PARAMETERS:
; r0 - block to test
;
; RETURNS: r0 - 0 for bad block
; r0 - 1 for good block
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
IsBlockGood
stmfd sp!, {r4-r8, lr}
ldr r4, =(NFC_BASE + NFC_REGISTERS_OFFSET)
; r5 - start page address
mov r5, r0, LSL #NAND_NUM_PAGE_LSHIFT
; r6 - page counter
mov r6, #2
10
; send spare read command
ldr r0, =NAND_CMD_READ2
bl NfcSendCmd
; send address
mov r0, #0
bl NfcSendAddr
mov r7, r5
and r0, r7, #0xFF
bl NfcSendAddr
mov r7, r7, LSR #8
and r0, r7, #0xFF
bl NfcSendAddr
IF SEND_4TH_ADDR_CYCLE
mov r7, r7, LSR #8
and r0, r7, #0xFF
bl NfcSendAddr
ENDIF
; Set to read spare only
ldrh r7, [r4, #NFC_CONFIG1_OFFSET]
orr r7, r7, #NFC_CONFIG1_SP_EN
strh r7, [r4, #NFC_CONFIG1_OFFSET]
mov r0, #1
15
; read sector data
ldr r7, =NFC_FDO_PAGE_READ
strh r7, [r4, #NFC_CONFIG2_OFFSET]
bl NfcWaitForReady
; Check ECC status
;; ldrh r7, [r4, #NFC_ECC_STATUS_RESULT_OFFSET]
;; and r7, r7, #NFC_ECC_ERM_RESERVED
;; cmp r7, #NFC_ECC_ERM_UNRECV_ERR
;; bhs LoopForever
; test for bad block indicator
ldr r7, =NFC_SPARE_BUFFER_IN_USE_ADDR
ldr r8, =NAND_BAD_BLOCK_OFFSET
ldrh r7, [r7, r8]
tst r8, #1
beq %f25
mov r7, r7, ASR #8
25
teq r7, #0xFF
movne r0, #0
bne %f40
; Update counters
add r5, r5, #1
subs r6, r6, #1
IF SEQUENTIAL_PAGE_READ_SUPPORT
bne %b15
ELSE
bne %b10
ENDIF
40
ldmfd sp!, {r4-r8, pc}
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -