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