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; 2018-09-01 xuzhuoyi the first version. 9; 10 11 .ref _rt_interrupt_to_thread 12 .ref _rt_interrupt_from_thread 13 .ref _rt_thread_switch_interrupt_flag 14 15 .def _RTOSINT_Handler 16 .def _rt_hw_get_st0 17 .def _rt_hw_get_st1 18 .def _rt_hw_context_switch_interrupt 19 .def _rt_hw_context_switch 20 .def _rt_hw_context_switch_to 21 .def _rt_hw_interrupt_thread_switch 22 .def _rt_hw_interrupt_disable 23 .def _rt_hw_interrupt_enable 24 25 26RT_CTX_SAVE .macro 27 28 29 PUSH AR1H:AR0H 30 PUSH XAR2 31 PUSH XAR3 32 PUSH XAR4 33 PUSH XAR5 34 PUSH XAR6 35 PUSH XAR7 36 PUSH XT 37 PUSH RPC 38 39 40 .endm 41 42 43RT_CTX_RESTORE .macro 44 45 POP RPC 46 POP XT 47 POP XAR7 48 POP XAR6 49 POP XAR5 50 POP XAR4 51 POP XAR3 52 POP XAR2 53 54 55 MOVZ AR0 , @SP 56 SUBB XAR0, #6 57 MOVL ACC , *XAR0 58 AND ACC, #0xFFFF << 16 59 MOV AL, IER 60 MOVL *XAR0, ACC 61 62 63 POP AR1H:AR0H 64 65 .endm 66 67 68.text 69 .newblock 70 71; 72; rt_base_t rt_hw_interrupt_disable(); 73; 74 .asmfunc 75_rt_hw_interrupt_disable: 76 DINT 77 LRETR 78 .endasmfunc 79 80; 81; void rt_hw_interrupt_enable(rt_base_t level); 82; 83 .asmfunc 84_rt_hw_interrupt_enable: 85 EINT 86 LRETR 87 .endasmfunc 88 89; 90; void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); 91; r0 --> from 92; r4 --> to 93 94 95 .asmfunc 96_rt_hw_context_switch_interrupt: 97_rt_hw_context_switch: 98 MOVL XAR0, #0 99 MOV AR0, AL 100 MOVL XAR4, *-SP[4] 101 ; set rt_thread_switch_interrupt_flag to 1 102 MOVL XAR5, #_rt_thread_switch_interrupt_flag 103 MOVL XAR6, *XAR5 104 MOVL ACC, XAR6 105 CMPB AL, #1 106 B _reswitch, EQ 107 MOVL XAR6, #1 108 MOVL *XAR5, XAR6 109 110 MOVL XAR5, #_rt_interrupt_from_thread ; set rt_interrupt_from_thread 111 MOVL *XAR5, XAR0 112 113_reswitch: 114 MOVL XAR5, #_rt_interrupt_to_thread ; set rt_interrupt_to_thread 115 MOVL *XAR5, XAR4 116 117 TRAP #16 118 LRETR 119 .endasmfunc 120 121 .asmfunc 122_RTOSINT_Handler: 123; disable interrupt to protect context switch 124 DINT 125 126 ; get rt_thread_switch_interrupt_flag 127 MOV AR0, #_rt_thread_switch_interrupt_flag 128 MOV AL, *AR0 129 MOV AR1, AL 130 CMP AR1, #0 131 B rtosint_exit, EQ ; pendsv already handled 132 133 ; clear rt_thread_switch_interrupt_flag to 0 134 MOV AR1, #0x00 135 MOV *AR0, AR1 136 137 MOV AR0, #_rt_interrupt_from_thread 138 MOV AL, *AR0 139 MOV AR1, AL 140 CMP AR1, #0 141 B switch_to_thread, EQ ; skip register save at the first time 142 143 ;MOVZ AR1, @SP ; get from thread stack pointer 144 145;#if defined (__VFP_FP__) && !defined(__SOFTFP__) 146; TST lr, #0x10 ; if(!EXC_RETURN[4]) 147; VSTMDBEQ r1!, {d8 - d15} ; push FPU register s16~s31 148;#endif 149 150 RT_CTX_SAVE ; push r4 - r11 register 151 152;#if defined (__VFP_FP__) && !defined(__SOFTFP__) 153; MOV r4, #0x00 ; flag = 0 154 155; TST lr, #0x10 ; if(!EXC_RETURN[4]) 156; MOVEQ r4, #0x01 ; flag = 1 157 158; STMFD r1!, {r4} ; push flag 159;#endif 160 161 MOV AL, *AR0 162 MOV AR1, AL 163 MOVZ AR1, @SP ; get from thread stack pointer 164 MOV *AR0, AR1 ; update from thread stack pointer 165 166switch_to_thread: 167 MOV AR1, #_rt_interrupt_to_thread 168 MOV AL, *AR1 169 MOV AR1, AL 170 MOV AL, *AR1 171 MOV AR1, AL ; load thread stack pointer 172 173;#if defined (__VFP_FP__) && !defined(__SOFTFP__) 174; LDMFD r1!, {r3} ; pop flag 175;#endif 176 177 MOV @SP, AR1 178 INC SP 179 RT_CTX_RESTORE ; pop r4 - r11 register 180 181rtosint_exit: 182 ; restore interrupt 183 EINT 184 185 IRET 186 .endasmfunc 187 188 .asmfunc 189_rt_hw_get_st0: 190 PUSH ST0 191 POP AL 192 LRETR 193 .endasmfunc 194 195 .asmfunc 196_rt_hw_get_st1: 197 PUSH ST1 198 POP AL 199 LRETR 200 .endasmfunc 201 202; 203; * void rt_hw_context_switch_to(rt_uint32 to); 204; * r0 --> to 205 206 .asmfunc 207_rt_hw_context_switch_to: 208 MOV AR1, #_rt_interrupt_to_thread 209 MOV *AR1, AL 210 211;#if defined (__VFP_FP__) && !defined(__SOFTFP__) 212 ; CLEAR CONTROL.FPCA 213; MRS r2, CONTROL ; read 214; BIC r2, #0x04 ; modify 215; MSR CONTROL, r2 ; write-back 216;#endif 217 218 ; set from thread to 0 219 MOV AR1, #_rt_interrupt_from_thread 220 MOV AR0, #0x0 221 MOV *AR1, AR0 222 223 ; set interrupt flag to 1 224 MOV AR1, #_rt_thread_switch_interrupt_flag 225 MOV AR0, #1 226 MOV *AR1, AR0 227 228 TRAP #16 229 230 231 ; never reach here! 232 .endasmfunc 233 234; compatible with old version 235 .asmfunc 236_rt_hw_interrupt_thread_switch: 237 LRETR 238 NOP 239 .endasmfunc 240 241.end 242