1/* 2 * Copyright (c) 2006-2019, 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 * 2019-07-28 zdzn add smp support 10 */ 11 12#include "../rtconfig.h" 13.section .text, "ax" 14 15#ifdef RT_USING_SMP 16#define rt_hw_interrupt_disable rt_hw_local_irq_disable 17#define rt_hw_interrupt_enable rt_hw_local_irq_enable 18#endif 19 20/* 21 * rt_base_t rt_hw_interrupt_disable(); 22 */ 23.globl rt_hw_interrupt_disable 24rt_hw_interrupt_disable: 25 mrs r0, cpsr 26 cpsid i 27 bx lr 28 29/* 30 * void rt_hw_interrupt_enable(rt_base_t level); 31 */ 32.globl rt_hw_interrupt_enable 33rt_hw_interrupt_enable: 34 msr cpsr, r0 35 bx lr 36 37/* 38 * void rt_hw_context_switch_to(rt_uint32 to, struct rt_thread *to_thread); 39 * r0 --> to (thread stack) 40 * r1 --> to_thread 41 */ 42.globl rt_hw_context_switch_to 43rt_hw_context_switch_to: 44 ldr sp, [r0] @ get new task stack pointer 45 46#ifdef RT_USING_SMP 47 mov r0, r1 48 bl rt_cpus_lock_status_restore 49#endif /*RT_USING_SMP*/ 50 b rt_hw_context_switch_exit 51 52.section .bss.share.isr 53_guest_switch_lvl: 54 .word 0 55 56.globl vmm_virq_update 57 58.section .text.isr, "ax" 59/* 60 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to, struct rt_thread *to_thread); 61 * r0 --> from (from_thread stack) 62 * r1 --> to (to_thread stack) 63 * r2 --> to_thread 64 */ 65.globl rt_hw_context_switch 66rt_hw_context_switch: 67 stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) 68 stmfd sp!, {r0-r12, lr} @ push lr & register file 69 70 mrs r4, cpsr 71 tst lr, #0x01 72 orrne r4, r4, #0x20 @ it's thumb code 73 74 stmfd sp!, {r4} @ push cpsr 75 76#ifdef RT_USING_SMART 77 stmfd sp, {r13, r14}^ @ push usr_sp usr_lr 78 sub sp, #8 79#endif 80#ifdef RT_USING_FPU 81 /* fpu context */ 82 vmrs r6, fpexc 83 tst r6, #(1<<30) 84 beq 1f 85 vstmdb sp!, {d0-d15} 86 vstmdb sp!, {d16-d31} 87 vmrs r5, fpscr 88 stmfd sp!, {r5} 891: 90 stmfd sp!, {r6} 91#endif 92 93 str sp, [r0] @ store sp in preempted tasks TCB 94 ldr sp, [r1] @ get new task stack pointer 95 96#ifdef RT_USING_SMP 97 mov r0, r2 98 bl rt_cpus_lock_status_restore 99#endif /*RT_USING_SMP*/ 100 b rt_hw_context_switch_exit 101 102/* 103 * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); 104 */ 105.equ Mode_USR, 0x10 106.equ Mode_FIQ, 0x11 107.equ Mode_IRQ, 0x12 108.equ Mode_SVC, 0x13 109.equ Mode_ABT, 0x17 110.equ Mode_UND, 0x1B 111.equ Mode_SYS, 0x1F 112 113.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled 114.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled 115 116.globl rt_thread_switch_interrupt_flag 117.globl rt_interrupt_from_thread 118.globl rt_interrupt_to_thread 119.globl rt_hw_context_switch_interrupt 120rt_hw_context_switch_interrupt: 121#ifdef RT_USING_SMP 122 /* r0 :svc_mod context 123 * r1 :addr of from_thread's sp 124 * r2 :addr of to_thread's sp 125 * r3 :to_thread's tcb 126 */ 127 128 str r0, [r1] 129 130 ldr sp, [r2] 131 mov r0, r3 132 bl rt_cpus_lock_status_restore 133 134 b rt_hw_context_switch_exit 135 136#else /*RT_USING_SMP*/ 137 ldr r2, =rt_thread_switch_interrupt_flag 138 ldr r3, [r2] 139 cmp r3, #1 140 beq _reswitch 141 ldr ip, =rt_interrupt_from_thread @ set rt_interrupt_from_thread 142 mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1 143 str r0, [ip] 144 str r3, [r2] 145_reswitch: 146 ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread 147 str r1, [r2] 148 bx lr 149#endif /*RT_USING_SMP*/ 150 151.global rt_hw_context_switch_exit 152rt_hw_context_switch_exit: 153 154#ifdef RT_USING_SMP 155#ifdef RT_USING_SIGNALS 156 mov r0, sp 157 cps #Mode_IRQ 158 bl rt_signal_check 159 cps #Mode_SVC 160 mov sp, r0 161#endif 162#endif 163#ifdef RT_USING_FPU 164/* fpu context */ 165 ldmfd sp!, {r6} 166 vmsr fpexc, r6 167 tst r6, #(1<<30) 168 beq 1f 169 ldmfd sp!, {r5} 170 vmsr fpscr, r5 171 vldmia sp!, {d16-d31} 172 vldmia sp!, {d0-d15} 173 174#endif 175 176#ifdef RT_USING_SMART 177 ldmfd sp, {r13, r14}^ /* usr_sp, usr_lr */ 178 add sp, #8 179#endif 180 ldmfd sp!, {r4} 181 msr spsr_cxsf, r4 /* original mode */ 182 ldmfd sp!, {r0-r12,lr,pc}^ /* irq return */ 183 184