1/* 2 * Copyright (c) 2006-2021, 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, 0x00000000 23.equ SVC_Stack_Size, 0x00000100 24.equ ABT_Stack_Size, 0x00000000 25.equ RT_FIQ_STACK_PGSZ, 0x00000000 26.equ RT_IRQ_STACK_PGSZ, 0x00000100 27.equ USR_Stack_Size, 0x00000100 28 29#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ 30 RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ) 31 32.section .data.share.isr 33/* stack */ 34.globl stack_start 35.globl stack_top 36 37.align 3 38stack_start: 39.rept ISR_Stack_Size 40.byte 0 41.endr 42stack_top: 43 44.text 45/* reset entry */ 46.globl _reset 47_reset: 48 /* Disable IRQ & FIQ */ 49 cpsid if 50 51 /* Check for HYP mode */ 52 mrs r0, cpsr_all 53 and r0, r0, #0x1F 54 mov r8, #0x1A 55 cmp r0, r8 56 beq overHyped 57 b continue 58 59overHyped: /* Get out of HYP mode */ 60 ldr r1, =continue 61 msr ELR_hyp, r1 62 mrs r1, cpsr_all 63 and r1, r1, #0x1f ;@ CPSR_MODE_MASK 64 orr r1, r1, #0x13 ;@ CPSR_MODE_SUPERVISOR 65 msr SPSR_hyp, r1 66 eret 67 68continue: 69 70 /* disable smp */ 71 bl arm_smp_disable 72 73 /* disable mmu */ 74 bl rt_cpu_mmu_disable 75 /* set the cpu to SVC32 mode and disable interrupt */ 76 mrs r0, cpsr 77 bic r0, r0, #0x1f 78 orr r0, r0, #0x13 79 msr cpsr_c, r0 80 81 /* setup stack */ 82 bl stack_setup 83 84 /* clear .bss */ 85 mov r0,#0 /* get a zero */ 86 ldr r1,=__bss_start /* bss start */ 87 ldr r2,=__bss_end /* bss end */ 88 89bss_loop: 90 cmp r1,r2 /* check if data to clear */ 91 strlo r0,[r1],#4 /* clear 4 bytes */ 92 blo bss_loop /* loop until done */ 93 94 /* start RT-Thread Kernel */ 95 ldr pc, _rtthread_startup 96_rtthread_startup: 97 .word rtthread_startup 98 99stack_setup: 100 ldr r0, =stack_top 101 102 @ Set the startup stack for svc 103 mov sp, r0 104 sub r0, r0, #SVC_Stack_Size 105 106 @ Enter Undefined Instruction Mode and set its Stack Pointer 107 msr cpsr_c, #Mode_UND|I_Bit|F_Bit 108 mov sp, r0 109 sub r0, r0, #UND_Stack_Size 110 111 @ Enter Abort Mode and set its Stack Pointer 112 msr cpsr_c, #Mode_ABT|I_Bit|F_Bit 113 mov sp, r0 114 sub r0, r0, #ABT_Stack_Size 115 116 @ Enter FIQ Mode and set its Stack Pointer 117 msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit 118 mov sp, r0 119 sub r0, r0, #RT_FIQ_STACK_PGSZ 120 121 @ Enter IRQ Mode and set its Stack Pointer 122 msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit 123 mov sp, r0 124 sub r0, r0, #RT_IRQ_STACK_PGSZ 125 126 /* come back to SVC mode */ 127 msr cpsr_c, #Mode_SVC|I_Bit|F_Bit 128 bx lr 129 130.text 131;@ void arm_smp_enable(void); 132.globl arm_smp_enable 133arm_smp_enable: 134 mrc p15, 0, r0, c1, c0, 1 ;@ set SMP bit in ACTLR 135 orr r0, r0, #0x40 136 mcr p15, 0, r0, c1, c0, 1 137 bx lr 138 139.text 140;@ void arm_smp_disable(void); 141.globl arm_smp_disable 142arm_smp_disable: 143 mrc p15, 0, r0, c1, c0, 1 ;@ clear SMP bit in ACTLR 144 bic r0, r0, #0x40 145 mcr p15, 0, r0, c1, c0, 1 146 bx lr 147 148/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */ 149.section .text.isr, "ax" 150 .align 5 151.globl vector_fiq 152vector_fiq: 153 stmfd sp!,{r0-r7,lr} 154 bl rt_hw_trap_fiq 155 ldmfd sp!,{r0-r7,lr} 156 subs pc, lr, #4 157 158.globl rt_interrupt_enter 159.globl rt_interrupt_leave 160.globl rt_thread_switch_interrupt_flag 161.globl rt_interrupt_from_thread 162.globl rt_interrupt_to_thread 163 164.globl rt_current_thread 165.globl vmm_thread 166.globl vmm_virq_check 167 168 .align 5 169.globl vector_irq 170vector_irq: 171 stmfd sp!, {r0-r12,lr} 172 173 bl rt_interrupt_enter 174 bl rt_hw_trap_irq 175 bl rt_interrupt_leave 176 177 @ if rt_thread_switch_interrupt_flag set, jump to 178 @ rt_hw_context_switch_interrupt_do and don't return 179 ldr r0, =rt_thread_switch_interrupt_flag 180 ldr r1, [r0] 181 cmp r1, #1 182 beq rt_hw_context_switch_interrupt_do 183 184 ldmfd sp!, {r0-r12,lr} 185 subs pc, lr, #4 186 187rt_hw_context_switch_interrupt_do: 188 mov r1, #0 @ clear flag 189 str r1, [r0] 190 191 mov r1, sp @ r1 point to {r0-r3} in stack 192 add sp, sp, #4*4 193 ldmfd sp!, {r4-r12,lr}@ reload saved registers 194 mrs r0, spsr @ get cpsr of interrupt thread 195 sub r2, lr, #4 @ save old task's pc to r2 196 197 @ Switch to SVC mode with no interrupt. If the usr mode guest is 198 @ interrupted, this will just switch to the stack of kernel space. 199 @ save the registers in kernel space won't trigger data abort. 200 msr cpsr_c, #I_Bit|F_Bit|Mode_SVC 201 202 stmfd sp!, {r2} @ push old task's pc 203 stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 204 ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread 205 stmfd sp!, {r1-r4} @ push old task's r0-r3 206 stmfd sp!, {r0} @ push old task's cpsr 207 208 ldr r4, =rt_interrupt_from_thread 209 ldr r5, [r4] 210 str sp, [r5] @ store sp in preempted tasks's TCB 211 212 ldr r6, =rt_interrupt_to_thread 213 ldr r6, [r6] 214 ldr sp, [r6] @ get new task's stack pointer 215 216 ldmfd sp!, {r4} @ pop new task's cpsr to spsr 217 msr spsr_cxsf, r4 218 219 ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr 220 221.macro push_svc_reg 222 sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ 223 stmia sp, {r0 - r12} @/* Calling r0-r12 */ 224 mov r0, sp 225 mrs r6, spsr @/* Save CPSR */ 226 str lr, [r0, #15*4] @/* Push PC */ 227 str r6, [r0, #16*4] @/* Push CPSR */ 228 cps #Mode_SVC 229 str sp, [r0, #13*4] @/* Save calling SP */ 230 str lr, [r0, #14*4] @/* Save calling PC */ 231.endm 232 233 .align 5 234 .globl vector_swi 235vector_swi: 236 push_svc_reg 237 bl rt_hw_trap_swi 238 b . 239 240 .align 5 241 .globl vector_undef 242vector_undef: 243 push_svc_reg 244 bl rt_hw_trap_undef 245 b . 246 247 .align 5 248 .globl vector_pabt 249vector_pabt: 250 push_svc_reg 251 bl rt_hw_trap_pabt 252 b . 253 254 .align 5 255 .globl vector_dabt 256vector_dabt: 257 push_svc_reg 258 bl rt_hw_trap_dabt 259 b . 260 261 .align 5 262 .globl vector_resv 263vector_resv: 264 push_svc_reg 265 bl rt_hw_trap_resv 266 b . 267