@ 0x00: Reset
b Reset
@ 0x04: Undefined instruction exception
UndefEntryPoint:
b HandleUndef
@ 0x08: Software interrupt exception
SWIEntryPoint:
b HandleSWI
@ 0x0c: Prefetch Abort (Instruction Fetch Memory Abort)
PrefetchAbortEnteryPoint:
b HandlePrefetchAbort
@ 0x10: Data Access Memory Abort
DataAbortEntryPoint:
b HandleDataAbort
@ 0x14: Not used
NotUsedEntryPoint:
b HandleNotUsed
@ 0x18: IRQ(Interrupt Request) exception
IRQEntryPoint:
b HandleIRQ
@ 0x1c: FIQ(Fast Interrupt Request) exception
FIQEntryPoint:
b HandleFIQ 设置中断向量,ARM体系规定
Reset: @ disable watch dog timer mov r1, #0x53000000 mov r2, #0x0 str r2, [r1] 禁止看门狗
@ disable all interrupts mov r1, #INT_CTL_BASE mov r2, #0xffffffff str r2, [r1, #oINTMSK] ldr r2, =0x7ff str r2, [r1, #oINTSUBMSK] 禁止所有中断
@ initialise system clocks mov r1, #CLK_CTL_BASE mvn r2, #0xff000000 str r2, [r1, #oLOCKTIME] mov r1, #CLK_CTL_BASE ldr r2, clkdivn_value str r2, [r1, #oCLKDIVN]
mrc p15, 0, r1, c1, c0, 0 @ read ctrl register orr r1, r1, #0xc0000000 @ Asynchronous mcr p15, 0, r1, c1, c0, 0 @ write ctrl register
mov r1, #CLK_CTL_BASE @ldr r2, mpll_value @ clock default ldr r2, =0x7f021 @mpll_value_USER @ clock user set str r2, [r1, #oMPLLCON] 初始化时钟 bl memsetup
ENTRY(memsetup) @ initialise the static memory
@ set memory control registers mov r1, #MEM_CTL_BASE adrl r2, mem_cfg_val add r3, r1, #52 1: ldr r4, [r2], #4 str r4, [r1], #4 cmp r1, r3 bne 1b mov pc, lr 初始化内存控制寄存器
@ Initialize UART @ @ r0 = number of UART port InitUART: ldr r1, SerBase mov r2, #0x0 str r2, [r1, #oUFCON] str r2, [r1, #oUMCON] mov r2, #0x3 str r2, [r1, #oULCON] ldr r2, =0x245 str r2, [r1, #oUCON] #define UART_BRD ((UART_PCLK / (UART_BAUD_RATE * 16)) - 1) mov r2, #UART_BRD str r2, [r1, #oUBRDIV]
mov r3, #100 mov r2, #0x0 1: sub r3, r3, #0x1 tst r2, r3 bne 1b mov pc, lr 初始化串口 @ @ copy_myself: copy vivi to ram @ copy_myself: mov r10, lr
@ reset NAND mov r1, #NAND_CTL_BASE ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) ) str r2, [r1, #oNFCONF] ldr r2, [r1, #oNFCONF]
ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control str r2, [r1, #oNFCONT] ldr r2, [r1, #oNFCONT]
ldr r2, =(0x6) @ RnB Clear str r2, [r1, #oNFSTAT] ldr r2, [r1, #oNFSTAT] mov r2, #0xff @ RESET command strb r2, [r1, #oNFCMD] mov r3, #0 @ wait 1: add r3, r3, #0x1 cmp r3, #0xa blt 1b 2: ldr r2, [r1, #oNFSTAT] @ wait ready tst r2, #0x4 beq 2b
ldr r2, [r1, #oNFCONT] orr r2, r2, #0x2 @ Flash Memory Chip Disable str r2, [r1, #oNFCONT]
@ get read to call C functions (for nand_read()) ldr sp, DW_STACK_START @ setup stack pointer mov fp, #0 @ no previous frame, so fp=0
mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_F mov r2, #0xe0 str r2, [r1, #oGPIO_DAT]
@ copy vivi to RAM ldr r0, =VIVI_RAM_BASE mov r1, #0x0 mov r2, #0x20000 bl nand_read_ll 设置NAND FLASH控制寄存器,设置堆栈,调用C函数nand_read_ll 将vivi从NAND FLASH(包括SRAM的那4K)搬到RAM #if 1 mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_F mov r2, #0xb0 str r2, [r1, #oGPIO_DAT] #endif
tst r0, #0x0 beq ok_nand_read #ifdef CONFIG_DEBUG_LL bad_nand_read: ldr r0, STR_FAIL ldr r1, SerBase bl PrintWord 1: b 1b @ infinite loop #endif ok_nand_read: #ifdef CONFIG_DEBUG_LL ldr r0, STR_OK ldr r1, SerBase bl PrintWord #endif
@ verify mov r0, #0 ldr r1, =0x33f00000 mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes go_next: ldr r3, [r0], #4 ldr r4, [r1], #4 teq r3, r4 bne notmatch subs r2, r2, #4 beq done_nand_read bne go_next notmatch: #ifdef CONFIG_DEBUG_LL sub r0, r0, #4 ldr r1, SerBase bl PrintHexWord ldr r0, STR_FAIL ldr r1, SerBase bl PrintWord #endif 1: b 1b done_nand_read:
#ifdef CONFIG_DEBUG_LL ldr r0, STR_OK ldr r1, SerBase bl PrintWord #endif
#if 1 mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_F mov r2, #0x70 str r2, [r1, #oGPIO_DAT] #endif
mov pc, r10 依然是一些NAND的操作 @ jump to ram ldr r1, =on_the_ram add pc, r1, #0 nop nop 1: b 1b @ infinite loop
on_the_ram: @ get read to call C functions ldr sp, DW_STACK_START @ setup stack pointer mov fp, #0 @ no previous frame, so fp=0 mov a2, #0 @ set argv to NULL
bl main @ call main
mov pc, #FLASH_BASE @ otherwise, reboot 跳转到RAM上的VIVI,之后调用C部分MAIN函数
|