xref: /nrf52832-nimble/rt-thread/libcpu/ti-dsp/c28x/context.s (revision 104654410c56c573564690304ae786df310c91fc)
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