123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- .extern main /* 引入外部C入口 */
- .extern __bss_beg__
- .extern __bss_end__
- .extern __stack_end__
- .extern __data_beg__
- .extern __data_end__
- .extern __data+beg_src__
- .extern rt_interrupt_enter
- .extern rt_interrupt_leave
- .extern rt_thread_switch_interrput_flag
- .extern rt_interrupt_from_thread
- .extern rt_interrupt_to_thread
- .extern rt_hw_trap_irq
- .global start
- .global endless_loop
- .global rt_hw_context_switch_interrupt_do
- /************* 目标配置 *************/
- .set UND_STACK_SIZE, 0x00000004
- .set ABT_STACK_SIZE, 0x00000004
- .set FIQ_STACK_SIZE, 0x00000004
- .set IRQ_STACK_SIZE, 0x00000400
- .set SVC_STACK_SIZE, 0x00000400
- .set UND_Stack_Size, 0x00000004
- .set ABT_Stack_Size, 0x00000004
- .set FIQ_Stack_Size, 0x00000004
- .set IRQ_Stack_Size, 0x00000400
- .set SVC_Stack_Size, 0x00000400
- /* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */
- .set MODE_USR, 0x10 /* User Mode */
- .set MODE_FIQ, 0x11 /* FIQ Mode */
- .set MODE_IRQ, 0x12 /* IRQ Mode */
- .set MODE_SVC, 0x13 /* Supervisor Mode */
- .set MODE_ABT, 0x17 /* Abort Mode */
- .set MODE_UND, 0x1B /* Undefined Mode */
- .set MODE_SYS, 0x1F /* System Mode */
- .set MODE_USR, 0x10 /* User Mode */
- .set Mode_FIQ, 0x11 /* FIQ Mode */
- .set Mode_IRQ, 0x12 /* IRQ Mode */
- .set Mode_SVC, 0x13 /* Supervisor Mode */
- .set Mode_ABT, 0x17 /* Abort Mode */
- .set Mode_UND, 0x1B /* Undefined Mode */
- .set Mode_SYS, 0x1F /* System Mode */
- .equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */
- .equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */
- .equ I_Bit, 0x80 /* when I bit is set, IRQ is disabled */
- .equ F_Bit, 0x40 /* when F bit is set, FIQ is disabled */
- /* VPBDIV definitions*/
- .equ VPBDIV, 0xE01FC100
- .set VPBDIV_VALUE, 0x00000000
- /* Phase Locked Loop (PLL) definitions*/
- .equ PLL_BASE, 0xE01FC080
- .equ PLLCON_OFS, 0x00
- .equ PLLCFG_OFS, 0x04
- .equ PLLSTAT_OFS, 0x08
- .equ PLLFEED_OFS, 0x0C
- .equ PLLCON_PLLE, (1<<0) /* PLL Enable */
- .equ PLLCON_PLLC, (1<<1) /* PLL Connect */
- .equ PLLSTAT_LOCK, (1<<10) /* PLL Lock Status */
- .equ PLLCFG_MSEL, ((PLL_MUL - 1) << 0)
- .equ PLLCFG_PSEL, (0x02 << 5)
- .equ PLLCFG_Val, (PLLCFG_MSEL|PLLCFG_PSEL)
- .equ MEMMAP, 0xE01FC040 /*Memory Mapping Control*/
- /* Memory Accelerator Module (MAM) definitions*/
- .equ MAM_BASE, 0xE01FC000
- .equ MAMCR_OFS, 0x00
- .equ MAMTIM_OFS, 0x04
- .equ MAMCR_Val, 0x00000002
- .equ MAMTIM_Val, 0x00000004
- .equ VICIntEnClr, 0xFFFFF014
- .equ VICIntSelect, 0xFFFFF00C
- /************* 目标配置结束 *************/
- /* Setup the operating mode & stack.*/
- /* --------------------------------- */
- .global _start, start, _reset, reset,
- .func _start,
- _start:
- start:
- _reset:
- reset:
- .code 32
- .align 0
- /************************* PLL_SETUP **********************************/
- #if (PLL_MUL>1)
- ldr r0, =PLL_BASE
- mov r1, #0xAA
- mov r2, #0x55
- /* Configure and Enable PLL */
- mov r3, #PLLCFG_Val
- str r3, [r0, #PLLCFG_OFS]
- mov r3, #PLLCON_PLLE
- str r3, [r0, #PLLCON_OFS]
- str r1, [r0, #PLLFEED_OFS]
- str r2, [r0, #PLLFEED_OFS]
- /* Wait until PLL Locked */
- PLL_Locked_loop:
- ldr r3, [r0, #PLLSTAT_OFS]
- ands r3, r3, #PLLSTAT_LOCK
- beq PLL_Locked_loop
- /* Switch to PLL Clock */
- mov r3, #(PLLCON_PLLE|PLLCON_PLLC)
- str r3, [r0, #PLLCON_OFS]
- str r1, [r0, #PLLFEED_OFS]
- str R2, [r0, #PLLFEED_OFS]
- #endif
- /************************* PLL_SETUP **********************************/
- /************************ Setup VPBDIV ********************************/
- ldr r0, =VPBDIV
- ldr r1, =VPBDIV_VALUE
- str r1, [r0]
- /************************ Setup VPBDIV ********************************/
- /************** Setup MAM **************/
- ldr r0, =MAM_BASE
- mov r1, #MAMTIM_Val
- str r1, [r0, #MAMTIM_OFS]
- mov r1, #MAMCR_Val
- str r1, [r0, #MAMCR_OFS]
- /************** Setup MAM **************/
- /************************ setup stack *********************************/
- ldr r0, .LC6 /* LC6:__stack_end__ */
- msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */
- mov sp, r0
- sub r0, r0, #UND_STACK_SIZE
- msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
- mov sp, r0
- sub r0, r0, #ABT_STACK_SIZE
- msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
- mov sp, r0
- sub r0, r0, #FIQ_STACK_SIZE
- msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
- mov sp, r0
- sub r0, r0, #IRQ_STACK_SIZE
- msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */
- mov sp, r0
- /************************ setup stack ********************************/
- /************************ Clear BSS ********************************/
- /* Clear BSS. */
- mov a2, #0 /* Fill value */
- mov fp, a2 /* Null frame pointer */
- mov r7, a2 /* Null frame pointer for Thumb */
- ldr r1, .LC1 /* Start of memory block */
- ldr r3, .LC2 /* End of memory block */
- subs r3, r3, r1 /* Length of block */
- beq .end_clear_loop
- mov r2, #0
- .clear_loop:
- strb r2, [r1], #1
- subs r3, r3, #1
- bgt .clear_loop
- .end_clear_loop:
- /* Initialise data. */
- ldr r1, .LC3 /* Start of memory block */
- ldr r2, .LC4 /* End of memory block */
- ldr r3, .LC5
- subs r3, r3, r1 /* Length of block */
- beq .end_set_loop
- .set_loop:
- ldrb r4, [r2], #1
- strb r4, [r1], #1
- subs r3, r3, #1
- bgt .set_loop
- .end_set_loop:
- mov r0, #0 /* no arguments */
- mov r1, #0 /* no argv either */
- bl main
- endless_loop:
- b endless_loop
- .align 0
- .LC1:
- .word __bss_beg__
- .LC2:
- .word __bss_end__
- .LC3:
- .word __data_beg__
- .LC4:
- .word __data_beg_src__
- .LC5:
- .word __data_end__
- .LC6:
- .word __stack_end__
- /*********************** END Clear BSS ******************************/
- /******************** 跳转到 main() ********************/
- LDR R0, =main /* 获得main()入口地址 */
- BX R0 /* 长跳转到main() */
- /******************** 跳转到 main() ********************/
- /* 本段为.startup段 在链接脚本中被链接到程序最开头 */
- .section .startup,"ax"
- .code 32
- .align 0
- ldr pc, __start /* reset - _start */
- ldr pc, _undf /* undefined - _undf */
- ldr pc, _swi /* SWI - _swi */
- ldr pc, _pabt /* program abort - _pabt */
- ldr pc, _dabt /* data abort - _dabt */
- //.word 0xB9205F80 /* 默认 0xB9205F80 */
- .word 0xB8A06F58 /* 0xB8A06F58 全为 */
- ldr pc, __IRQ_Handler /* IRQ - read the VIC */
- ldr pc, _fiq /* FIQ - _fiq */
- __start:.word _start
- _undf: .word __undf /* undefined */
- _swi: .word __swi /* SWI */
- _pabt: .word __pabt /* program abort */
- _dabt: .word __dabt /* data abort */
- temp1: .word 0
- __IRQ_Handler: .word IRQ_Handler
- _fiq: .word __fiq /* FIQ */
- __undf: b . /* undefined */
- __swi : b .
- __pabt: b . /* program abort */
- __dabt: b . /* data abort */
- __fiq : b . /* FIQ */
- /* IRQ入口 */
- IRQ_Handler :
- stmfd sp!, {r0-r12,lr} /* 对R0 – R12,LR寄存器压栈 */
- bl rt_interrupt_enter /* 通知RT-Thread进入中断模式 */
- bl rt_hw_trap_irq /* 相应中断服务例程处理 */
- bl rt_interrupt_leave /* ; 通知RT-Thread要离开中断模式 */
- /* 如果设置了rt_thread_switch_interrput_flag,进行中断中的线程上下文处理 */
- ldr r0, =rt_thread_switch_interrput_flag
- ldr r1, [r0]
- cmp r1, #1
- beq rt_hw_context_switch_interrupt_do /* 中断中切换发生 */
- /* 如果跳转了,将不会回来 */
- ldmfd sp!, {r0-r12,lr} /* 恢复栈 */
- subs pc, lr, #4 /* 从IRQ中返回 */
- /*
- * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
- * 中断结束后的上下文切换
- */
- rt_hw_context_switch_interrupt_do:
- mov r1, #0 /* clear flag */
- /* 清楚中断中切换标志 */
- str r1, [r0] /* */
- ldmfd sp!, {r0-r12,lr}/* reload saved registers */
- /* 先恢复被中断线程的上下文 */
- stmfd sp!, {r0-r3} /* save r0-r3 */
- /* 对R0 – R3压栈,因为后面会用到 */
- mov r1, sp /* 把此处的栈值保存到R1 */
- add sp, sp, #16 /* restore sp */
- /* 恢复IRQ的栈,后面会跳出IRQ模式 */
- sub r2, lr, #4 /* save old task's pc to r2 */
- /* 保存切换出线程的PC到R2 */
- mrs r3, spsr /* disable interrupt 保存中断前的CPSR到R3寄存器 */
- /* 获得SPSR寄存器值 */
- orr r0, r3, #I_BIT|F_BIT
- msr spsr_c, r0 /* 关闭SPSR中的IRQ/FIQ中断 */
- ldr r0, =.+8 /* 把当前地址+8载入到R0寄存器中 switch to interrupted task's stack */
- movs pc, r0 /* 退出IRQ模式,由于SPSR被设置成关中断模式 */
- /* 所以从IRQ返回后,中断并没有打开
- ; R0寄存器中的位置实际就是下一条指令,
- ; 即PC继续往下走
- ; 此时
- ; 模式已经换成中断前的SVC模式,
- ; SP寄存器也是SVC模式下的栈寄存器
- ; R1保存IRQ模式下的栈指针
- ; R2保存切换出线程的PC
- ; R3保存切换出线程的CPSR */
- stmfd sp!, {r2} /* push old task's pc */
- /* 保存切换出任务的PC */
- stmfd sp!, {r4-r12,lr}/* push old task's lr,r12-r4 */
- /* 保存R4 – R12,LR寄存器 */
- mov r4, r1 /* Special optimised code below */
- /* R1保存有压栈R0 – R3处的栈位置 */
- mov r5, r3 /* R3切换出线程的CPSR */
- ldmfd r4!, {r0-r3} /* 恢复R0 – R3 */
- stmfd sp!, {r0-r3} /* push old task's r3-r0 */
- /* R0 – R3压栈到切换出线程 */
- stmfd sp!, {r5} /* push old task's psr */
- /* 切换出线程CPSR压栈 */
- mrs r4, spsr
- stmfd sp!, {r4} /* push old task's spsr */
- /* 切换出线程SPSR压栈 */
- ldr r4, =rt_interrupt_from_thread
- ldr r5, [r4]
- str sp, [r5] /* store sp in preempted tasks's TCB */
- /* 保存切换出线程的SP指针 */
- ldr r6, =rt_interrupt_to_thread
- ldr r6, [r6]
- ldr sp, [r6] /* get new task's stack pointer */
- /* 获得切换到线程的栈 */
- ldmfd sp!, {r4} /* pop new task's spsr */
- /* 恢复SPSR */
- msr SPSR_cxsf, r4
- ldmfd sp!, {r4} /* pop new task's psr */
- /* 恢复CPSR */
- msr CPSR_cxsf, r4
- ldmfd sp!, {r0-r12,lr,pc} /* pop new task's r0-r12,lr & pc */
- /* 恢复R0 – R12,LR及PC寄存器 */
- /* 代码加密功能 */
- #if defined(CODE_PROTECTION)
- .org 0x01FC
- .word 0x87654321
- #endif
|