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  * 2019-12-04     Jiaxun Yang  Initial version
9  */
10 
11 #ifndef __STACKFRAME_H__
12 #define __STACKFRAME_H__
13 
14 #include "asm.h"
15 #include "mips_regs.h"
16 #include "ptrace.h"
17 
18 /* You MUST ensure FP is enabled before SAVE_FPU! */
19     .macro SAVE_FPU
20     .set push
21     .set noreorder
22 #ifdef RT_USING_FPU
23     /* Ensure CU1 (FPU) is enabled */
24     MFC0 v1, CP0_STATUS
25     lui t1, %hi(ST0_CU1)
26     addiu t1, t1, %lo(ST0_CU1)
27     or v1, v1, t1
28     MTC0 v1, CP0_STATUS
29     SSNOP
30     cfc1 v1, fcr31
31     /* Store as delay slot */
32     s.d $f0, PT_FPU_R0(sp)
33     s.d $f2, PT_FPU_R2(sp)
34     s.d $f4, PT_FPU_R4(sp)
35     s.d $f6, PT_FPU_R6(sp)
36     s.d $f8, PT_FPU_R8(sp)
37     s.d $f10, PT_FPU_R10(sp)
38     s.d $f12, PT_FPU_R12(sp)
39     s.d $f14, PT_FPU_R14(sp)
40     s.d $f16, PT_FPU_R16(sp)
41     s.d $f18, PT_FPU_R18(sp)
42     s.d $f20, PT_FPU_R20(sp)
43     s.d $f22, PT_FPU_R22(sp)
44     s.d $f24, PT_FPU_R24(sp)
45     s.d $f26, PT_FPU_R26(sp)
46     s.d $f28, PT_FPU_R28(sp)
47     s.d $f30, PT_FPU_R30(sp)
48     LONG_S v1, PT_FPU_FCSR31(sp)
49 #endif
50     .set reorder
51     .set pop
52     .endm
53 
54     .macro  SAVE_AT
55     .set    push
56     .set    noat
57     LONG_S  $1, PT_R1(sp)
58     .set    pop
59     .endm
60 
61     .macro  SAVE_TEMP
62     mfhi    v1
63     LONG_S  $8, PT_R8(sp)
64     LONG_S  $9, PT_R9(sp)
65     sw  v1, PT_HI(sp)
66     mflo    v1
67     LONG_S  $10, PT_R10(sp)
68     LONG_S  $11, PT_R11(sp)
69     sw  v1,  PT_LO(sp)
70     LONG_S  $12, PT_R12(sp)
71     LONG_S  $13, PT_R13(sp)
72     LONG_S  $14, PT_R14(sp)
73     LONG_S  $15, PT_R15(sp)
74     LONG_S  $24, PT_R24(sp)
75     .endm
76 
77     .macro  SAVE_STATIC
78     LONG_S  $16, PT_R16(sp)
79     LONG_S  $17, PT_R17(sp)
80     LONG_S  $18, PT_R18(sp)
81     LONG_S  $19, PT_R19(sp)
82     LONG_S  $20, PT_R20(sp)
83     LONG_S  $21, PT_R21(sp)
84     LONG_S  $22, PT_R22(sp)
85     LONG_S  $23, PT_R23(sp)
86     LONG_S  $30, PT_R30(sp)
87     .endm
88 
89     .macro  SAVE_SOME
90     .set    push
91     .set    noat
92     .set    reorder
93     move    k1, sp
94     move    k0, sp
95     PTR_SUBU sp, k1, PT_SIZE
96     LONG_S  k0, PT_R29(sp)
97     LONG_S  $3, PT_R3(sp)
98     LONG_S  $0, PT_R0(sp)
99     MFC0    v1, CP0_STATUS
100     LONG_S  $2, PT_R2(sp)
101     LONG_S  v1, PT_STATUS(sp)
102     LONG_S  $4, PT_R4(sp)
103     MFC0    v1, CP0_CAUSE
104     LONG_S  $5, PT_R5(sp)
105     LONG_S  v1, PT_CAUSE(sp)
106     LONG_S  $6, PT_R6(sp)
107     MFC0    v1, CP0_EPC
108     LONG_S  $7, PT_R7(sp)
109     LONG_S  v1, PT_EPC(sp)
110     LONG_S  $25, PT_R25(sp)
111     LONG_S  $28, PT_R28(sp)
112     LONG_S  $31, PT_R31(sp)
113     .set    pop
114     .endm
115 
116     .macro  SAVE_ALL
117     SAVE_SOME
118     SAVE_AT
119     SAVE_TEMP
120     SAVE_FPU
121     SAVE_STATIC
122     .endm
123 
124     .macro RESTORE_FPU
125     .set push
126     .set noreorder
127 #ifdef RT_USING_FPU
128     /* Ensure CU1 (FPU) is enabled */
129     MFC0 v1, CP0_STATUS
130     lui t1, %hi(ST0_CU1)
131     addiu t1, t1, %lo(ST0_CU1)
132     or v1, v1, t1
133     MTC0 v1, CP0_STATUS
134     SSNOP
135     LONG_L v1, PT_FPU_FCSR31(sp)
136     ctc1 v1, fcr31
137     l.d $f0, PT_FPU_R0(sp)
138     l.d $f2, PT_FPU_R2(sp)
139     l.d $f4, PT_FPU_R4(sp)
140     l.d $f6, PT_FPU_R6(sp)
141     l.d $f8, PT_FPU_R8(sp)
142     l.d $f10, PT_FPU_R10(sp)
143     l.d $f12, PT_FPU_R12(sp)
144     l.d $f14, PT_FPU_R14(sp)
145     l.d $f16, PT_FPU_R16(sp)
146     l.d $f18, PT_FPU_R18(sp)
147     l.d $f20, PT_FPU_R20(sp)
148     l.d $f22, PT_FPU_R22(sp)
149     l.d $f24, PT_FPU_R24(sp)
150     l.d $f26, PT_FPU_R26(sp)
151     l.d $f28, PT_FPU_R28(sp)
152     l.d $f30, PT_FPU_R30(sp)
153 #endif
154     .set reorder
155     .set pop
156     .endm
157 
158     .macro  RESTORE_AT
159     .set    push
160     .set    noat
161     LONG_L  $1,  PT_R1(sp)
162     .set    pop
163     .endm
164 
165     .macro  RESTORE_TEMP
166     lw  $24, PT_LO(sp)
167     LONG_L  $8, PT_R8(sp)
168     LONG_L  $9, PT_R9(sp)
169     mtlo    $24
170     lw  $24, PT_HI(sp)
171     LONG_L  $10, PT_R10(sp)
172     LONG_L  $11, PT_R11(sp)
173     mthi    $24
174     LONG_L  $12, PT_R12(sp)
175     LONG_L  $13, PT_R13(sp)
176     LONG_L  $14, PT_R14(sp)
177     LONG_L  $15, PT_R15(sp)
178     LONG_L  $24, PT_R24(sp)
179     .endm
180 
181     .macro  RESTORE_STATIC
182     LONG_L  $16, PT_R16(sp)
183     LONG_L  $17, PT_R17(sp)
184     LONG_L  $18, PT_R18(sp)
185     LONG_L  $19, PT_R19(sp)
186     LONG_L  $20, PT_R20(sp)
187     LONG_L  $21, PT_R21(sp)
188     LONG_L  $22, PT_R22(sp)
189     LONG_L  $23, PT_R23(sp)
190     LONG_L  $30, PT_R30(sp)
191     .endm
192 
193 #define STATMASK 0x1f
194 
195     .macro  RESTORE_SOME
196     .set    push
197     .set    reorder
198     .set    noat
199     mfc0    a0, CP0_STATUS
200     ori a0, STATMASK
201     xori    a0, STATMASK
202     mtc0    a0, CP0_STATUS
203     li  v1, (ST0_CU1 | ST0_FR | ST0_IM)
204     and a0, v1, a0
205     LONG_L  v0, PT_STATUS(sp)
206     li  v1, ~(ST0_CU1 | ST0_FR | ST0_IM)
207     and v0, v1
208     or  v0, a0
209     li  v1, (ST0_KX | ST0_SX | ST0_UX)
210     or  v0, v1
211     mtc0    v0, CP0_STATUS
212     LONG_L  v1, PT_EPC(sp)
213     MTC0    v1, CP0_EPC
214     LONG_L  $31, PT_R31(sp)
215     LONG_L  $28, PT_R28(sp)
216     LONG_L  $25, PT_R25(sp)
217     LONG_L  $7,  PT_R7(sp)
218     LONG_L  $6,  PT_R6(sp)
219     LONG_L  $5,  PT_R5(sp)
220     LONG_L  $4,  PT_R4(sp)
221     LONG_L  $3,  PT_R3(sp)
222     LONG_L  $2,  PT_R2(sp)
223     .set    pop
224     .endm
225 
226     .macro  RESTORE_SP_AND_RET
227     LONG_L  sp, PT_R29(sp)
228     eret
229     nop
230     .endm
231 
232 
233     .macro  RESTORE_SP
234     LONG_L  sp, PT_R29(sp)
235     .endm
236 
237     .macro  RESTORE_ALL
238     RESTORE_TEMP
239     RESTORE_FPU
240     RESTORE_STATIC
241     RESTORE_AT
242     RESTORE_SOME
243     RESTORE_SP
244     .endm
245 
246     .macro  RESTORE_ALL_AND_RET
247     RESTORE_TEMP
248     RESTORE_FPU
249     RESTORE_STATIC
250     RESTORE_AT
251     RESTORE_SOME
252     RESTORE_SP_AND_RET
253     .endm
254 
255 #endif /* end of __STACKFRAME_H__ */
256 
257