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