1/* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2013-07-05 Bernard the first version 9 */ 10 11.equ Mode_USR, 0x10 12.equ Mode_FIQ, 0x11 13.equ Mode_IRQ, 0x12 14.equ Mode_SVC, 0x13 15.equ Mode_ABT, 0x17 16.equ Mode_UND, 0x1B 17.equ Mode_SYS, 0x1F 18 19.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled 20.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled 21 22.equ UND_Stack_Size, 0x00000200 23.equ SVC_Stack_Size, 0x00000100 24.equ ABT_Stack_Size, 0x00000000 25.equ FIQ_Stack_Size, 0x00000000 26.equ IRQ_Stack_Size, 0x00000100 27.equ USR_Stack_Size, 0x00000100 28 29#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ 30 FIQ_Stack_Size + IRQ_Stack_Size) 31 32/* stack */ 33.globl stack_start 34.globl stack_top 35 36stack_start: 37.rept ISR_Stack_Size 38.long 0 39.endr 40stack_top: 41 42/* reset entry */ 43.globl _reset 44_reset: 45 /* set the cpu to SVC32 mode and disable interrupt */ 46 mrs r0, cpsr 47 bic r0, r0, #0x1f 48 orr r0, r0, #0x13 49 msr cpsr_c, r0 50 51 /* setup stack */ 52 bl stack_setup 53 54 /* clear .bss */ 55 mov r0,#0 /* get a zero */ 56 ldr r1,=__bss_start /* bss start */ 57 ldr r2,=__bss_end /* bss end */ 58 59bss_loop: 60 cmp r1,r2 /* check if data to clear */ 61 strlo r0,[r1],#4 /* clear 4 bytes */ 62 blo bss_loop /* loop until done */ 63 64 /* call C++ constructors of global objects */ 65 ldr r0, =__ctors_start__ 66 ldr r1, =__ctors_end__ 67 68ctor_loop: 69 cmp r0, r1 70 beq ctor_end 71 ldr r2, [r0], #4 72 stmfd sp!, {r0-r1} 73 mov lr, pc 74 bx r2 75 ldmfd sp!, {r0-r1} 76 b ctor_loop 77ctor_end: 78 79 /* start RT-Thread Kernel */ 80 ldr pc, _rtthread_startup 81_rtthread_startup: 82 .word rtthread_startup 83 84stack_setup: 85 ldr r0, =stack_top 86 87 @ Enter Undefined Instruction Mode and set its Stack Pointer 88 msr cpsr_c, #Mode_UND|I_Bit|F_Bit 89 mov sp, r0 90 sub r0, r0, #UND_Stack_Size 91 92 @ Enter Abort Mode and set its Stack Pointer 93 msr cpsr_c, #Mode_ABT|I_Bit|F_Bit 94 mov sp, r0 95 sub r0, r0, #ABT_Stack_Size 96 97 @ Enter FIQ Mode and set its Stack Pointer 98 msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit 99 mov sp, r0 100 sub r0, r0, #FIQ_Stack_Size 101 102 @ Enter IRQ Mode and set its Stack Pointer 103 msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit 104 mov sp, r0 105 sub r0, r0, #IRQ_Stack_Size 106 107 @ Enter Supervisor Mode and set its Stack Pointer 108 msr cpsr_c, #Mode_SVC|I_Bit|F_Bit 109 mov sp, r0 110 sub r0, r0, #SVC_Stack_Size 111 112 @ Enter User Mode and set its Stack Pointer 113 mov sp, r0 114 sub sl, sp, #USR_Stack_Size 115 bx lr 116 117/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */ 118 .align 5 119.globl vector_undef 120vector_undef: 121 sub sp, sp, #72 122 stmia sp, {r0 - r12} @/* Calling r0-r12 */ 123 add r8, sp, #60 124 125 mrs r1, cpsr 126 mrs r2, spsr 127 orr r2,r2, #I_Bit|F_Bit 128 msr cpsr_c, r2 129 mov r0, r0 130 stmdb r8, {sp, lr} @/* Calling SP, LR */ 131 msr cpsr_c, r1 @/* return to Undefined Instruction mode */ 132 133 str lr, [r8, #0] @/* Save calling PC */ 134 mrs r6, spsr 135 str r6, [r8, #4] @/* Save CPSR */ 136 str r0, [r8, #8] @/* Save OLD_R0 */ 137 mov r0, sp 138 139 bl rt_hw_trap_udef 140 141 ldmia sp, {r0 - r12} @/* Calling r0 - r2 */ 142 mov r0, r0 143 ldr lr, [sp, #60] @/* Get PC */ 144 add sp, sp, #72 145 movs pc, lr @/* return & move spsr_svc into cpsr */ 146 147 .align 5 148.globl vector_swi 149vector_swi: 150 bl rt_hw_trap_swi 151 152 .align 5 153.globl vector_pabt 154vector_pabt: 155 bl rt_hw_trap_pabt 156 157 .align 5 158.globl vector_dabt 159vector_dabt: 160 sub sp, sp, #72 161 stmia sp, {r0 - r12} @/* Calling r0-r12 */ 162 add r8, sp, #60 163 stmdb r8, {sp, lr} @/* Calling SP, LR */ 164 str lr, [r8, #0] @/* Save calling PC */ 165 mrs r6, spsr 166 str r6, [r8, #4] @/* Save CPSR */ 167 str r0, [r8, #8] @/* Save OLD_R0 */ 168 mov r0, sp 169 170 bl rt_hw_trap_dabt 171 172 ldmia sp, {r0 - r12} @/* Calling r0 - r2 */ 173 mov r0, r0 174 ldr lr, [sp, #60] @/* Get PC */ 175 add sp, sp, #72 176 movs pc, lr @/* return & move spsr_svc into cpsr */ 177 178 .align 5 179.globl vector_resv 180vector_resv: 181 b . 182 183 .align 5 184.globl vector_fiq 185vector_fiq: 186 stmfd sp!,{r0-r7,lr} 187 bl rt_hw_trap_fiq 188 ldmfd sp!,{r0-r7,lr} 189 subs pc,lr,#4 190 191.globl rt_interrupt_enter 192.globl rt_interrupt_leave 193.globl rt_thread_switch_interrupt_flag 194.globl rt_interrupt_from_thread 195.globl rt_interrupt_to_thread 196 197.globl rt_current_thread 198.globl vmm_thread 199.globl vmm_virq_check 200 201.globl vector_irq 202vector_irq: 203 stmfd sp!, {r0-r12,lr} 204 205 bl rt_interrupt_enter 206 bl rt_hw_trap_irq 207 bl rt_interrupt_leave 208 209 @ if rt_thread_switch_interrupt_flag set, jump to 210 @ rt_hw_context_switch_interrupt_do and don't return 211 ldr r0, =rt_thread_switch_interrupt_flag 212 ldr r1, [r0] 213 cmp r1, #1 214 beq rt_hw_context_switch_interrupt_do 215 216 ldmfd sp!, {r0-r12,lr} 217 subs pc, lr, #4 218 219rt_hw_context_switch_interrupt_do: 220 mov r1, #0 @ clear flag 221 str r1, [r0] 222 223 ldmfd sp!, {r0-r12,lr}@ reload saved registers 224 stmfd sp, {r0-r2} @ save r0-r2 225 226 mrs r0, spsr @ get cpsr of interrupt thread 227 228 sub r1, sp, #4*3 229 sub r2, lr, #4 @ save old task's pc to r2 230 231 @ switch to SVC mode with no interrupt 232 msr cpsr_c, #I_Bit|F_Bit|Mode_SVC 233 234 stmfd sp!, {r2} @ push old task's pc 235 stmfd sp!, {r3-r12,lr}@ push old task's lr,r12-r4 236 ldmfd r1, {r1-r3} @ restore r0-r2 of the interrupt thread 237 stmfd sp!, {r1-r3} @ push old task's r0-r2 238 stmfd sp!, {r0} @ push old task's cpsr 239 240 ldr r4, =rt_interrupt_from_thread 241 ldr r5, [r4] 242 str sp, [r5] @ store sp in preempted tasks's TCB 243 244 ldr r6, =rt_interrupt_to_thread 245 ldr r6, [r6] 246 ldr sp, [r6] @ get new task's stack pointer 247 248 ldmfd sp!, {r4} @ pop new task's cpsr to spsr 249 msr spsr_cxsf, r4 250 251 ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr 252