📄 start.s
字号:
mov r1, #0xffffffff ldr r0, =INTMR str r1, [r0] /* FCLK:HCLK:PCLK = 1:2:4 */ /* default FCLK is 120 MHz ! */ ldr r0, =CLKDIVN mov r1, #3 str r1, [r0] /* END stuff after relocation */#endif@jun#if defined(CONFIG_S3C2440)@ ldr r0, S_startC_OK@ ldr r1, SerBase@ bl PrintWord mov r1, #GPIO_CTL_BASE /*only light one led for progress indication*/ add r1, r1, #oGPIO_F mov r2, #0x70 /*light4*/ str r2, [r1, #oGPIO_DAT]@debug_loop:@ b debug_loop @for debug#endif @end CONFIG_S3C2440 ldr pc, _start_armboot/***************************************************************************/_start_armboot: .word start_armboot/* ************************************************************************* * * CPU_init_critical registers * * setup important registers * setup memory timing * ************************************************************************* */cpu_init_crit: /* * flush v4 I/D caches */ mov r0, #0 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ /* * disable MMU stuff and caches */ mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) orr r0, r0, #0x00000002 @ set bit 2 (A) Align orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache mcr p15, 0, r0, c1, c0, 0 /* * before relocating, we have to setup RAM timing * because memory timing is board-dependend, you will * find a lowlevel_init.S in your board directory. */ mov ip, lr bl lowlevel_init mov lr, ip mov pc, lr/* initial values for DRAM */.align 4mem_cfg_val: .long vBWSCON .long vBANKCON0 .long vBANKCON1 .long vBANKCON2 .long vBANKCON3 .long vBANKCON4 .long vBANKCON5 .long vBANKCON6 .long vBANKCON7 .long vREFRESH .long vBANKSIZE .long vMRSRB6 .long vMRSRB7memsetup: @ initialise the static memory @ set memory control registers mov r1, #MEM_CTL_BASE adrl r2, mem_cfg_val add r3, r1, #521: ldr r4, [r2], #4 str r4, [r1], #4 cmp r1, r3 bne 1b mov pc, lr/*jun*/@ 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]#define UART_BRD ((UART_PCLK / (UART_BAUD_RATE * 16)) - 1) mov r2, #UART_BRD str r2, [r1, #oUBRDIV] mov r3, #100 mov r2, #0x01: sub r3, r3, #0x1 tst r2, r3 bne 1b#if 0 mov r2, #'U' str r2, [r1, #oUTXHL]1: ldr r3, [r1, #oUTRSTAT] and r3, r3, #UTRSTAT_TX_EMPTY tst r3, #UTRSTAT_TX_EMPTY bne 1b mov r2, #'0' str r2, [r1, #oUTXHL]1: ldr r3, [r1, #oUTRSTAT] and r3, r3, #UTRSTAT_TX_EMPTY tst r3, #UTRSTAT_TX_EMPTY bne 1b#endif 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 handlingPrintChar:TXBusy: 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.align 4SerBase:#if defined(CONFIG_SERIAL_UART0) .long UART0_CTL_BASE#elif defined(CONFIG_SERIAL_UART1) .long UART1_CTL_BASE#elif defined(CONFIG_SERIAL_UART2) .long UART2_CTL_BASE#else#error not defined base address of serial#endifgpio_con_uart: .long 0x0016faaagpio_up_uart: .long 0x000007ff.align 2DW_STACK_START: .word STACK_BASE+STACK_SIZE-4.align 2HEX_TO_ASCII_TABLE: .ascii "0123456789ABCDEF"SS_OK: .ascii "OK "S_startC_OK: .ascii "SO "/* ************************************************************************* * * Interrupt handling * ************************************************************************* */@@ IRQ stack frame.@#define S_FRAME_SIZE 72#define S_OLD_R0 68#define S_PSR 64#define S_PC 60#define S_LR 56#define S_SP 52#define S_IP 48#define S_FP 44#define S_R10 40#define S_R9 36#define S_R8 32#define S_R7 28#define S_R6 24#define S_R5 20#define S_R4 16#define S_R3 12#define S_R2 8#define S_R1 4#define S_R0 0#define MODE_SVC 0x13#define I_BIT 0x80/* * use bad_save_user_regs for abort/prefetch/undef/swi ... * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling */ .macro bad_save_user_regs sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Calling r0-r12 ldr r2, _armboot_start sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack ldmia r2, {r2 - r3} @ get pc, cpsr add r0, sp, #S_FRAME_SIZE @ restore sp_SVC add r5, sp, #S_SP mov r1, lr stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr mov r0, sp .endm .macro irq_save_user_regs sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Calling r0-r12 add r8, sp, #S_PC stmdb r8, {sp, lr}^ @ Calling SP, LR str lr, [r8, #0] @ Save calling PC mrs r6, spsr str r6, [r8, #4] @ Save CPSR str r0, [r8, #8] @ Save OLD_R0 mov r0, sp .endm .macro irq_restore_user_regs ldmia sp, {r0 - lr}^ @ Calling r0 - lr mov r0, r0 ldr lr, [sp, #S_PC] @ Get PC add sp, sp, #S_FRAME_SIZE subs pc, lr, #4 @ return & move spsr_svc into cpsr .endm .macro get_bad_stack ldr r13, _armboot_start @ setup our mode stack sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack str lr, [r13] @ save caller lr / spsr mrs lr, spsr str lr, [r13, #4] mov r13, #MODE_SVC @ prepare SVC-Mode @ msr spsr_c, r13 msr spsr, r13 mov lr, pc movs pc, lr .endm .macro get_irq_stack @ setup IRQ stack ldr sp, IRQ_STACK_START .endm .macro get_fiq_stack @ setup FIQ stack ldr sp, FIQ_STACK_START .endm/* * exception handlers */ .align 5undefined_instruction: get_bad_stack bad_save_user_regs bl do_undefined_instruction .align 5software_interrupt: get_bad_stack bad_save_user_regs bl do_software_interrupt .align 5prefetch_abort: get_bad_stack bad_save_user_regs bl do_prefetch_abort .align 5data_abort: get_bad_stack bad_save_user_regs bl do_data_abort .align 5not_used: get_bad_stack bad_save_user_regs bl do_not_used#ifdef CONFIG_USE_IRQ .align 5irq: get_irq_stack irq_save_user_regs bl do_irq irq_restore_user_regs .align 5fiq: get_fiq_stack /* someone ought to write a more effiction fiq_save_user_regs */ irq_save_user_regs bl do_fiq irq_restore_user_regs#else .align 5irq: get_bad_stack bad_save_user_regs bl do_irq .align 5fiq: get_bad_stack bad_save_user_regs bl do_fiq#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -