📄 head.s
字号:
mov r0, #'T' ldr r1, SerBase bl PrintChar mov r0, #' ' ldr r1, SerBase bl PrintChar ] /* check the first 1MB in increments of 4k */ mov r7, #0x1000 mov r6, r7, lsl #8 /* 4k << 2^8 = 1MB */ mov r5, #DRAM_BASEmem_test_loop mov r0, r5 bl testram_nostack teq r0, #1 beq badram add r5, r5, r7 subs r6, r6, r7 bne mem_test_loop ; the first megabyte is OK. so let us clear it. mov r0, #((1024 * 1024) / (8 * 4)) ; 1MB in steps of 32 bytes mov r1, #DRAM_BASE mov r2, #0 mov r3, #0 mov r4, #0 mov r5, #0 mov r6, #0 mov r7, #0 mov r8, #0 mov r9, #0 clear_loop_memtest stmia r1!, {r2-r9} subs r0, r0, #(8 * 4) bne clear_loop_memtest [ :DEF: CONFIG_DEBUG_LL ldr r0, STR_OK ldr r1, SerBase bl PrintWord ] mov pc, r10 ; returnbadram [ :DEF: CONFIG_DEBUG_LL ldr r0, STR_FAIL ldr r1, SerBase bl PrintWord ]1 b %b1 ; loop ; testmem.S: memory tester, test if there is RAM available at given location;; Copyright (C) 2001 Russell King (rmk;arm.linux.org.uk);; This version clobbers registers r1-r4, so be sure to store their contents; in a safe position. This function is not APCS compliant, so only use it; from assembly code.;; r0 = address to test ; returns r0 = 0 - ram present, r0 = 1 - no ram; clobbers r1 - r4 ENTRY(testram_nostack) ldmia r0, {r1, r2} ; store current value in r1 and r2 mov r3, #0x55 ; write 0x55 to first word mov r4, #0xaa ; 0xaa to second stmia r0, {r3, r4} ldmia r0, {r3, r4} ; read it back teq r3, #0x55 ; do the values match teqeq r4, #0xaa bne bad ; oops, no mov r3, #0xaa ; write 0xaa to first word mov r4, #0x55 ; 0x55 to second stmia r0, {r3, r4} ldmia r0, {r3, r4} ; read it back teq r3, #0xaa ; do the values match teqeq r4, #0x55bad stmia r0, {r1, r2} ; in any case, restore old data moveq r0, #0 ; ok - all values matched movne r0, #1 ; no ram at this location mov pc, lr ] ; CONFIG_BOOTUP_MEMTEST; Initialize UART;; r0 = number of UART portInitUART 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] mov r2, #UART_BRD str r2, [r1, #oUBRDIV] mov r3, #100 mov r2, #0x01 sub r3, r3, #0x1 tst r2, r3 bne %b1 [ {FALSE} mov r2, #'U' str r2, [r1, #oUTXHL]1 ldr r3, [r1, #oUTRSTAT] and r3, r3, #UTRSTAT_TX_EMPTY tst r3, #UTRSTAT_TX_EMPTY bne %b1 mov r2, #'0' str r2, [r1, #oUTXHL]1 ldr r3, [r1, #oUTRSTAT] and r3, r3, #UTRSTAT_TX_EMPTY tst r3, #UTRSTAT_TX_EMPTY bne %b1 ] mov pc, lr;; Exception handling functions;HandleUndef [ :DEF: CONFIG_DEBUG_LL mov r12, r14 ldr r0, STR_UNDEF ldr r1, SerBase bl PrintWord bl PrintFaultAddr ]1 b %b1 ; infinite loopHandleSWI [ :DEF: CONFIG_DEBUG_LL mov r12, r14 ldr r0, STR_SWI ldr r1, SerBase bl PrintWord bl PrintFaultAddr ]1 b %b1 ; infinite loopHandlePrefetchAbort [ :DEF: CONFIG_DEBUG_LL mov r12, r14 ldr r0, STR_PREFETCH_ABORT ldr r1, SerBase bl PrintWord bl PrintFaultAddr ]1 b %b1 ; infinite loopHandleDataAbort [ :DEF: CONFIG_DEBUG_LL mov r12, r14 ldr r0, STR_DATA_ABORT ldr r1, SerBase bl PrintWord bl PrintFaultAddr ]1 b %b1 ; infinite loopHandleIRQ [ :DEF: CONFIG_DEBUG_LL1 mov r12, r14 ldr r0, STR_IRQ ldr r1, SerBase bl PrintWord bl PrintFaultAddr ] [ :DEF: CONFIG_DEBUG_LL sub sp,sp,#4 ; @reserved for PC stmfd sp!,{r8-r9} ldr r9,=INTOFFSET ldr r9,[r9] ;@ Load the INTOFFSET register value to r9 ldr r8,=HandleEINT0 ;@ Load the ISR vector base address to r8 add r8,r8,r9,lsl #2 ;@ get the ISR vector r8 = r8 + r9 * 4 ldr r8,[r8] ;@ Load the ISR address str r8,[sp,#8] ;@ store to sp, new PC ldmfd sp!,{r8-r9,pc} ;@ jump to new PC, that is to ISR ]1 b %b1 ; infinite loopHandleFIQ [ :DEF: CONFIG_DEBUG_LL mov r12, r14 ldr r0, STR_FIQ ldr r1, SerBase bl PrintWord bl PrintFaultAddr ]1 b %b1 ; infinite loopHandleNotUsed [ :DEF: CONFIG_DEBUG_LL mov r12, r14 ldr r0, STR_NOT_USED ldr r1, SerBase bl PrintWord bl PrintFaultAddr ]1 b %b1 ; infinite loop;; Low Level Debug; [ :DEF: CONFIG_DEBUG_LL;; PrintFaultAddr: Print falut address;; r12: contains address of instruction + 4;PrintFaultAddr mov r0, r12 ; Print address of instruction + 4 ldr r1, SerBase bl PrintHexWord mrc p15, 0, r0, c6, c0, 0 ; Read fault virtual address ldr r1, SerBase bl PrintHexWord mov pc, lr; PrintHexNibble : prints the least-significant nibble in R0 as a; hex digit; r0 contains nibble to write as Hex; r1 contains base of serial port; writes ro with XXX, modifies r0,r1,r2; TODO : write ro with XXX reg to error handling; Falls through to PrintCharPrintHexNibble adr r2, HEX_TO_ASCII_TABLE and r0, r0, #0xF ldr r0, [r2, r0] ; convert to ascii b PrintChar; PrintChar : prints the character in R0; r0 contains the character; r1 contains base of serial port; writes ro with XXX, modifies r0,r1,r2; TODO : write ro with XXX reg to error handlingPrintCharTXBusy ldr r2, [r1, #oUTRSTAT] and r2, r2, #UTRSTAT_TX_EMPTY tst r2, #UTRSTAT_TX_EMPTY beq TXBusy str r0, [r1, #oUTXHL] mov pc, lr; PrintWord : prints the 4 characters in R0; r0 contains the binary word; r1 contains the base of the serial port; writes ro with XXX, modifies r0,r1,r2; TODO : write ro with XXX reg to error handlingPrintWord mov r3, r0 mov r4, lr bl PrintChar mov r0, r3, LSR #8 ;/* shift word right 8 bits */ bl PrintChar mov r0, r3, LSR #16 ;/* shift word right 16 bits */ bl PrintChar mov r0, r3, LSR #24 ;/* shift word right 24 bits */ bl PrintChar mov r0, #'\r' bl PrintChar mov r0, #'\n' bl PrintChar mov pc, r4; PrintHexWord : prints the 4 bytes in R0 as 8 hex ascii characters; followed by a newline; r0 contains the binary word; r1 contains the base of the serial port; writes ro with XXX, modifies r0,r1,r2; TODO : write ro with XXX reg to error handlingPrintHexWord mov r4, lr mov r3, r0 mov r0, r3, LSR #28 bl PrintHexNibble mov r0, r3, LSR #24 bl PrintHexNibble mov r0, r3, LSR #20 bl PrintHexNibble mov r0, r3, LSR #16 bl PrintHexNibble mov r0, r3, LSR #12 bl PrintHexNibble mov r0, r3, LSR #8 bl PrintHexNibble mov r0, r3, LSR #4 bl PrintHexNibble mov r0, r3 bl PrintHexNibble mov r0, #'\r' bl PrintChar mov r0, #'\n' bl PrintChar mov pc, r4 ] ;; Data Area;; Memory configuration values ALIGN 4mem_cfg_val DCD vBWSCON DCD vBANKCON0 DCD vBANKCON1 DCD vBANKCON2 DCD vBANKCON3 DCD vBANKCON4 DCD vBANKCON5 DCD vBANKCON6 DCD vBANKCON7 DCD vREFRESH DCD vBANKSIZE DCD vMRSRB6 DCD vMRSRB7; Processor clock values ALIGN 4clock_locktime DCD vLOCKTIMEmpll_50mhz DCD vMPLLCON_50 [ :DEF: CONFIG_S3C2410_MPORT1mpll_100mhz DCD vMPLLCON_100 ]mpll_200mhz DCD vMPLLCON_200clock_clkcon DCD vCLKCONclock_clkdivn DCD vCLKDIVN; initial values for serialuart_ulcon DCD vULCONuart_ucon DCD vUCONuart_ufcon DCD vUFCONuart_umcon DCD vUMCON; inital values for GPIOgpio_con_uart DCD vGPHCONgpio_up_uart DCD vGPHUP ALIGN 2DW_STACK_START DCD STACK_BASE+STACK_SIZE-4 [ :DEF: CONFIG_DEBUG_LL ALIGN 2HEX_TO_ASCII_TABLE DCB "0123456789ABCDEF"STR_STACK DCB "STKP"STR_UNDEF DCB "UNDF"STR_SWI DCB "SWI "STR_PREFETCH_ABORT DCB "PABT"STR_DATA_ABORT DCB "DABT"STR_IRQ DCB "IRQ "STR_FIQ DCB "FIQ"STR_NOT_USED DCB "NUSD" ALIGN 2STR_OK DCB "OK "STR_FAIL DCB "FAIL"STR_CR DCB "\r\n" ] ALIGN 4SerBase [ :DEF: CONFIG_SERIAL_UART0 DCD UART0_CTL_BASE | [ :DEF: CONFIG_SERIAL_UART1 DCD UART1_CTL_BASE | [ :DEF: CONFIG_SERIAL_UART2 DCD UART2_CTL_BASE | ;#error not defined base address of serial ] ] ] [ :DEF: CONFIG_PM ALIGN 4PMCTL0_ADDR DCD 0x4c00000cPMCTL1_ADDR DCD 0x56000080PMST_ADDR DCD 0x560000B4PMSR0_ADDR DCD 0x560000B8REFR_ADDR DCD 0x48000024 ] END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -