📄 flash_boot.s
字号:
;---------------------------------------------------------------------------------------------
;File Name : nand_driver.s
;Description: boot from nand flash
;---------------------------------------------------------------------------------------------
;Nand Flash Boot ROM Struct
;type Name Offset
;UINT32 BootLength: 0x00
;UINT8 Encrypt: 0x04
;UINT8 Access Cycle 0x05
;UINT8 InterfaceWidth 0x06
;UINT8 ColumnAddress 0x07
;UINT8 RowAddress 0x08
;UINT8 Reserved 0x09
;UINT8 Reserved 0x0A
;UINT8 Reserved 0x0B
;UINT32 DestAddress 0x0C
;;Exsample
;;XX XX XX XX 00 03 08 01 02 00 00 00 00 00 00 70
;---------------------------------------------------------------------------------------------
AREA FLASH_DRIVER, CODE, READONLY
;---------------------------------------------------------------------------------------------
ENTRY
;---------------------------------------------------------------------------------------------
FLASH_CONFIG EQU (NAND_ECC_EN | NAND_ECC_R | NAND_WAIT7 | NAND_DATA16 | NAND_CS)
CYCLE_OFFSET EQU 0x05
INTERFACE_OFFSET EQU 0x06
COLUMN_OFFSET EQU 0x07
ROW_OFFSET EQU 0x08
DEST_OFFSET EQU 0x0C
FLASH_HEADER_LENGTH EQU 0x10
;---------------------------------------------------------------------------------------------
;;void flash_init(void);
;;Description: enable nand flash and gpio module, set gpio config, send reset command to flash
;;input: none
;;return: none
EXPORT flash_init
flash_init
stmfd sp!, {lr}
ldr r0, =(PMC_NAND | PMC_GPIO)
bl en_module_clk
bl get_gpio_b_cfg
ldr r1, =0x3dffff
orr r0, r0, r1
bl set_gpio_b_cfg
bl get_gpio_a_cfg
mov r1, #0x10
orr r0, r0, r1
bl set_gpio_a_cfg
ldr r0, =FLASH_CONFIG
bl nand_set_cfg
mov r0, #0xff
bl nand_write_cmd
ldmfd sp!, {pc}
;---------------------------------------------------------------------------------------------
;;void flash_read_boot_header(INT8U *pBuf, INT16U BytesCounter);
;;input: r0 = valide pointer of data buffer, r1 = bytes counter
;;return: none
EXPORT flash_read_boot_header
flash_read_boot_header
stmfd sp!, {r4, lr}
ldr r4, =P_NAND_BASE
0
ldrb r3, [r4, #P_NAND_STATUS]
movs r3, r3
beq %B0
mov r3, #0
strb r3, [r4, #P_NAND_CMD]
nop
strb r3, [r4, #P_NAND_ADD] ;;addr 0
nop
strb r3, [r4, #P_NAND_ADD] ;;addr 1
nop
strb r3, [r4, #P_NAND_ADD] ;;addr 2
nop
strb r3, [r4, #P_NAND_ADD] ;;addr 3
nop
strb r3, [r4, #P_NAND_ADD] ;;addr 4
nop
nop
nop
nop
nop
mov r2, #0x30
ldrb r3, [r4, #P_NAND_STATUS] ;;big page must write 0x30 command
movs r3, r3
strneb r2, [r4, #P_NAND_CMD]
nop
nop
nop
nop
nop
1
ldrb r3, [r4, #P_NAND_STATUS]
movs r3, r3
beq %B1
add r1, r1, r0
2
ldrb r2, [r4, #P_NAND_DATA]
strb r2, [r0], #1
cmp r0, r1
bcc %B2
ldmfd sp!, {r4, pc}
;---------------------------------------------------------------------------------------------
;;void nand_set_user_cfg(UINT32 cfg);
;;input: r0 = nand flash cfg, (Cycle, interface, Clo, Row)
;;return: none
EXPORT nand_set_user_cfg
nand_set_user_cfg
ldr r3, =P_NAND_BASE
and r2, r0, #0x07
mov r2, r2, lsl #NAND_WAIT_SHL
and r1, r0, #0xff00
cmp r1, #0x1000
orreq r2, r2, #NAND_DATA16
orr r2, r2, #NAND_CS
strh r2, [r4, #P_NAND_CFG] ;;config nand flash cfg again
tst r2, #NAND_DATA16
movne pc, lr ;;16 bits interface
ldr r3, =P_GPIO_BASE
ldr r0, [r3, #P_PORTB_CFG]
bic r0, r0, #0xff00
str r0, [r3, #P_PORTB_CFG] ;;8 bits interface
mov pc, lr
;---------------------------------------------------------------------------------------------
;;void nand_set_boot_addr(UINT32 ColumnAddr, UINT32 RowAddr, UINT32 cfg);
;;input: r0 = Colmn Address, r1 = Row Addrss, r2 = cfg
;;return: none
EXPORT nand_set_boot_addr
nand_set_boot_addr
stmfd sp!, {r4, lr}
ldr r4, =P_NAND_BASE
mov r3, #0
strb r3, [r4, #P_NAND_CMD]
mov r2, r2, lsr #16
and r3, r2, #0xff ;;r3 = column width
mov r2, r2, lsr #8 ;;r2 = row width
strb r0, [r4, #P_NAND_ADD] ;;Column addr 1
subs r3, r3, #1
beq %F3
mov r0, r0, lsr #8
strb r0, [r4, #P_NAND_ADD] ;;Column Addr 2
3
strb r1, [r4, #P_NAND_ADD] ;;row addr 1
subs r2, r2, #1
beq %F4
mov r1, r1, lsr #8
strb r1, [r4, #P_NAND_ADD] ;;row addr 2
subs r2, r2, #1
beq %F4
mov r1, r1, lsr #8
strb r1, [r4, #P_NAND_ADD]
4
mov r0, #0x30
cmp r3, #1
streqb r0, [r4, #P_NAND_CMD]
ldmfd sp!, {r4, pc}
;---------------------------------------------------------------------------------------------
;;void flash_read_boot(UINT8 *pBuf, UINT32 Counter, UINT32 cfg)
;;Input: r0 = valide pointer of data buffer, r1 = bytes Counter, r2 = cfg
;;return: r0 = new data pointer
EXPORT flash_read_boot
flash_read_boot
stmfd sp!, {r4, lr}
ldr r4, =P_NAND_BASE
5
ldrb r3, [r4, #P_NAND_STATUS]
movs r3, r3
beq %B5
and r2, r2, #0xff00
cmp r2, #0x1000
beq flash_read_boot_w
flash_read_boot_b
ldrb r3, [r4, #P_NAND_STATUS]
movs r3, r3
beq flash_read_boot_b
ldrb r2, [r4, #P_NAND_DATA]
strb r2, [r0], #1
subs r1, r1, #1
bne flash_read_boot_b
ldmfd sp!, {r4, pc}
flash_read_boot_w
ldrb r3, [r4, #P_NAND_STATUS]
movs r3, r3
beq flash_read_boot_w
ldrh r2, [r4, #P_NAND_DATA]
strh r2, [r0], #2
subs r1, r1, #2
bne flash_read_boot_w
ldmfd sp!, {r4, pc}
;---------------------------------------------------------------------------------------------
;;void nand_read_code(UINT32 *pMem, UINT32 length, UINT32 cfg);
;;input: r0 = memory address, r1 = length, r2 = cfg
;;return: none
EXPORT nand_read_code
nand_read_code
stmfd sp!, {r4-r8, lr}
mov r4, r0 ;;r4 = memory start poniter
add r5, r0, r1 ;;r5 = momory end pointer
mov r6, r2 ;;r6 = nand flash cfg
mov r0, #FLASH_HEADER_LENGTH
mov r1, #0
bl nand_set_boot_addr ;;write read command and column + row address
ldr r8, =(512+16) ;;r8 = page size
ldr r3, =(2048+64)
sub r1, r8, #FLASH_HEADER_LENGTH ;;default small page
ands r0, r6, #0x00ff0000
cmp r0, #0x00020000
moveq r8, r3
subeq r1, r8, #(FLASH_HEADER_LENGTH<<1) ;;change to large page
mov r0, r4
mov r2, r6
bl flash_read_boot ;;read page 0
mov r4, r0
cmp r4, r5
bcs end_nand_read_code
mov r7, #1
nand_read_code_loop
mov r0, #0
mov r1, r7
mov r2, r6
bl nand_set_boot_addr ;;write read command and column + row address
mov r0, r4
mov r1, r8
mov r2, r6
bl flash_read_boot
mov r4, r0
add r7, r7, #1 ;;next page
cmp r4, r5
bcc nand_read_code_loop
end_nand_read_code
ldmfd sp!, {r4-r8, pc}
;---------------------------------------------------------------------------------------------
;;void boot_nand_flash(UINT32 *pBuf);
;;input: r0 = pointer of temp data memory
;;return: none
EXPORT boot_nand_flash
boot_nand_flash
stmfd sp!, {r4-r10, lr}
mov r4, r0
bl flash_init
mov r0, r4
mov r1, #FLASH_HEADER_LENGTH
bl flash_read_boot_header
ldr r8, [r4] ;;r8 = length
ldrb r9, [r4, #CYCLE_OFFSET]
ldrb r2, [r4, #INTERFACE_OFFSET]
orr r9, r9, r2, lsl #8
ldrb r2, [r4, #COLUMN_OFFSET]
orr r9, r9, r2, lsl #16
ldrb r2, [r4, #ROW_OFFSET]
orr r9, r9, r2, lsl #24 ;;r9 = cfg
ldr r10, [r4, #DEST_OFFSET] ;;r10 = memory destion address
mov r0, r9
bl nand_set_user_cfg
mov r0, r10
mov r1, r8
mov r2, r9
bl nand_read_code
ldmfd sp!, {r4-r10, pc}
;---------------------------------------------------------------------------------------------
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -