1 | /* |
---|
2 | * Copyright (c) 2018 embedded brains GmbH |
---|
3 | * Copyright (c) 2015 Hesham Almatary <hesham@alumni.york.ac.uk> |
---|
4 | * |
---|
5 | * Redistribution and use in source and binary forms, with or without |
---|
6 | * modification, are permitted provided that the following conditions |
---|
7 | * are met: |
---|
8 | * 1. Redistributions of source code must retain the above copyright |
---|
9 | * notice, this list of conditions and the following disclaimer. |
---|
10 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
11 | * notice, this list of conditions and the following disclaimer in the |
---|
12 | * documentation and/or other materials provided with the distribution. |
---|
13 | * |
---|
14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
---|
15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
---|
18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
24 | * SUCH DAMAGE. |
---|
25 | */ |
---|
26 | |
---|
27 | #ifdef HAVE_CONFIG_H |
---|
28 | #include "config.h" |
---|
29 | #endif |
---|
30 | |
---|
31 | #include <rtems/asm.h> |
---|
32 | #include <rtems/score/cpu.h> |
---|
33 | |
---|
34 | #define OFFSET(i) ((i) * CPU_SIZEOF_POINTER) |
---|
35 | |
---|
36 | #define RA_OFFSET OFFSET(0) |
---|
37 | #define T0_OFFSET OFFSET(1) |
---|
38 | #define T1_OFFSET OFFSET(2) |
---|
39 | #define T2_OFFSET OFFSET(3) |
---|
40 | #define S0_OFFSET OFFSET(4) |
---|
41 | #define S1_OFFSET OFFSET(5) |
---|
42 | #define A0_OFFSET OFFSET(6) |
---|
43 | #define A1_OFFSET OFFSET(7) |
---|
44 | #define A2_OFFSET OFFSET(8) |
---|
45 | #define A3_OFFSET OFFSET(9) |
---|
46 | #define A4_OFFSET OFFSET(10) |
---|
47 | #define A5_OFFSET OFFSET(11) |
---|
48 | #define A6_OFFSET OFFSET(12) |
---|
49 | #define A7_OFFSET OFFSET(13) |
---|
50 | #define S2_OFFSET OFFSET(14) |
---|
51 | #define S3_OFFSET OFFSET(15) |
---|
52 | #define S4_OFFSET OFFSET(16) |
---|
53 | #define S5_OFFSET OFFSET(17) |
---|
54 | #define S6_OFFSET OFFSET(18) |
---|
55 | #define S7_OFFSET OFFSET(19) |
---|
56 | #define S8_OFFSET OFFSET(20) |
---|
57 | #define S9_OFFSET OFFSET(21) |
---|
58 | #define S10_OFFSET OFFSET(22) |
---|
59 | #define S11_OFFSET OFFSET(23) |
---|
60 | #define T3_OFFSET OFFSET(24) |
---|
61 | #define T4_OFFSET OFFSET(25) |
---|
62 | #define T5_OFFSET OFFSET(26) |
---|
63 | #define T6_OFFSET OFFSET(27) |
---|
64 | #define TMP_OFFSET OFFSET(28) |
---|
65 | |
---|
66 | #if __riscv_flen == 32 |
---|
67 | #define FOFFSET(i) (OFFSET(29) + (i) * 4) |
---|
68 | #elif __riscv_flen == 64 |
---|
69 | #define FOFFSET(i) (OFFSET(29) + (i) * 8) |
---|
70 | #else |
---|
71 | #define FOFFSET(i) OFFSET(29) |
---|
72 | #endif /* __riscv_flen */ |
---|
73 | |
---|
74 | #define FRAME_SIZE \ |
---|
75 | ((FOFFSET(32) + CPU_STACK_ALIGNMENT - 1) & ~(CPU_STACK_ALIGNMENT - 1)) |
---|
76 | |
---|
77 | .section .text, "ax", @progbits |
---|
78 | .align 2 |
---|
79 | |
---|
80 | PUBLIC(_CPU_Context_validate) |
---|
81 | SYM(_CPU_Context_validate): |
---|
82 | addi sp, sp, -FRAME_SIZE |
---|
83 | |
---|
84 | /* Save */ |
---|
85 | |
---|
86 | SREG ra, RA_OFFSET(sp) |
---|
87 | SREG t0, T0_OFFSET(sp) |
---|
88 | SREG t1, T1_OFFSET(sp) |
---|
89 | SREG t2, T2_OFFSET(sp) |
---|
90 | SREG s0, S0_OFFSET(sp) |
---|
91 | SREG s1, S1_OFFSET(sp) |
---|
92 | SREG a0, A0_OFFSET(sp) |
---|
93 | SREG a1, A1_OFFSET(sp) |
---|
94 | SREG a2, A2_OFFSET(sp) |
---|
95 | SREG a3, A3_OFFSET(sp) |
---|
96 | SREG a4, A4_OFFSET(sp) |
---|
97 | SREG a5, A5_OFFSET(sp) |
---|
98 | SREG a6, A6_OFFSET(sp) |
---|
99 | SREG a7, A7_OFFSET(sp) |
---|
100 | SREG s2, S2_OFFSET(sp) |
---|
101 | SREG s3, S3_OFFSET(sp) |
---|
102 | SREG s4, S4_OFFSET(sp) |
---|
103 | SREG s5, S5_OFFSET(sp) |
---|
104 | SREG s6, S6_OFFSET(sp) |
---|
105 | SREG s7, S7_OFFSET(sp) |
---|
106 | SREG s8, S8_OFFSET(sp) |
---|
107 | SREG s9, S9_OFFSET(sp) |
---|
108 | SREG s10, S10_OFFSET(sp) |
---|
109 | SREG s11, S11_OFFSET(sp) |
---|
110 | SREG t3, T3_OFFSET(sp) |
---|
111 | SREG t4, T4_OFFSET(sp) |
---|
112 | SREG t5, T5_OFFSET(sp) |
---|
113 | SREG t6, T6_OFFSET(sp) |
---|
114 | |
---|
115 | #if __riscv_flen > 0 |
---|
116 | FSREG f0, FOFFSET(0)(sp) |
---|
117 | FSREG f1, FOFFSET(1)(sp) |
---|
118 | FSREG f2, FOFFSET(2)(sp) |
---|
119 | FSREG f3, FOFFSET(3)(sp) |
---|
120 | FSREG f4, FOFFSET(4)(sp) |
---|
121 | FSREG f5, FOFFSET(5)(sp) |
---|
122 | FSREG f6, FOFFSET(6)(sp) |
---|
123 | FSREG f7, FOFFSET(7)(sp) |
---|
124 | FSREG f8, FOFFSET(8)(sp) |
---|
125 | FSREG f9, FOFFSET(9)(sp) |
---|
126 | FSREG f10, FOFFSET(10)(sp) |
---|
127 | FSREG f11, FOFFSET(11)(sp) |
---|
128 | FSREG f12, FOFFSET(12)(sp) |
---|
129 | FSREG f13, FOFFSET(13)(sp) |
---|
130 | FSREG f14, FOFFSET(14)(sp) |
---|
131 | FSREG f15, FOFFSET(15)(sp) |
---|
132 | FSREG f16, FOFFSET(16)(sp) |
---|
133 | FSREG f17, FOFFSET(17)(sp) |
---|
134 | FSREG f18, FOFFSET(18)(sp) |
---|
135 | FSREG f19, FOFFSET(19)(sp) |
---|
136 | FSREG f20, FOFFSET(20)(sp) |
---|
137 | FSREG f21, FOFFSET(21)(sp) |
---|
138 | FSREG f22, FOFFSET(22)(sp) |
---|
139 | FSREG f23, FOFFSET(23)(sp) |
---|
140 | FSREG f24, FOFFSET(24)(sp) |
---|
141 | FSREG f25, FOFFSET(25)(sp) |
---|
142 | FSREG f26, FOFFSET(26)(sp) |
---|
143 | FSREG f27, FOFFSET(27)(sp) |
---|
144 | FSREG f28, FOFFSET(28)(sp) |
---|
145 | FSREG f29, FOFFSET(29)(sp) |
---|
146 | FSREG f30, FOFFSET(30)(sp) |
---|
147 | FSREG f31, FOFFSET(31)(sp) |
---|
148 | #endif /* __riscv_flen */ |
---|
149 | |
---|
150 | /* Fill */ |
---|
151 | |
---|
152 | addi ra, a0, 1 |
---|
153 | /* sp must remain as is */ |
---|
154 | /* gp must remain as is */ |
---|
155 | /* tp must remain as is */ |
---|
156 | /* t0 is used for temporary values */ |
---|
157 | addi t1, a0, 2 |
---|
158 | addi t2, a0, 3 |
---|
159 | addi s0, a0, 4 |
---|
160 | addi s1, a0, 5 |
---|
161 | /* a0 is the pattern */ |
---|
162 | addi a1, a0, 6 |
---|
163 | addi a2, a0, 7 |
---|
164 | addi a3, a0, 8 |
---|
165 | addi a4, a0, 9 |
---|
166 | addi a5, a0, 10 |
---|
167 | addi a6, a0, 11 |
---|
168 | addi a7, a0, 12 |
---|
169 | addi s2, a0, 13 |
---|
170 | addi s3, a0, 14 |
---|
171 | addi s4, a0, 15 |
---|
172 | addi s5, a0, 16 |
---|
173 | addi s6, a0, 17 |
---|
174 | addi s7, a0, 18 |
---|
175 | addi s8, a0, 19 |
---|
176 | addi s9, a0, 20 |
---|
177 | addi s10, a0, 21 |
---|
178 | addi s11, a0, 22 |
---|
179 | addi t3, a0, 23 |
---|
180 | |
---|
181 | xor t4, sp, a0 |
---|
182 | xor t5, gp, a0 |
---|
183 | xor t6, tp, a0 |
---|
184 | |
---|
185 | #if __riscv_flen > 0 |
---|
186 | andi t0, a0, 0x1f |
---|
187 | fsflags t0 |
---|
188 | |
---|
189 | .macro fill_f reg, inc |
---|
190 | addi t0, a0, 24 + \inc |
---|
191 | FMVYX \reg, t0 |
---|
192 | .endm |
---|
193 | |
---|
194 | fill_f f0, 0 |
---|
195 | fill_f f1, 1 |
---|
196 | fill_f f2, 2 |
---|
197 | fill_f f3, 3 |
---|
198 | fill_f f4, 4 |
---|
199 | fill_f f5, 5 |
---|
200 | fill_f f6, 6 |
---|
201 | fill_f f7, 7 |
---|
202 | fill_f f8, 8 |
---|
203 | fill_f f9, 9 |
---|
204 | fill_f f10, 10 |
---|
205 | fill_f f11, 11 |
---|
206 | fill_f f12, 12 |
---|
207 | fill_f f13, 13 |
---|
208 | fill_f f14, 14 |
---|
209 | fill_f f15, 15 |
---|
210 | fill_f f16, 16 |
---|
211 | fill_f f17, 17 |
---|
212 | fill_f f18, 18 |
---|
213 | fill_f f19, 19 |
---|
214 | fill_f f20, 20 |
---|
215 | fill_f f21, 21 |
---|
216 | fill_f f22, 22 |
---|
217 | fill_f f23, 23 |
---|
218 | fill_f f24, 24 |
---|
219 | fill_f f25, 25 |
---|
220 | fill_f f26, 26 |
---|
221 | fill_f f27, 27 |
---|
222 | fill_f f28, 28 |
---|
223 | fill_f f29, 29 |
---|
224 | fill_f f30, 30 |
---|
225 | fill_f f31, 31 |
---|
226 | #endif /* __riscv_flen */ |
---|
227 | |
---|
228 | /* Check */ |
---|
229 | |
---|
230 | .Lcheck: |
---|
231 | .macro check_register reg, inc |
---|
232 | addi t0, a0, \inc |
---|
233 | bne \reg, t0, .Lrestore |
---|
234 | .endm |
---|
235 | |
---|
236 | check_register ra, 1 |
---|
237 | check_register t1, 2 |
---|
238 | check_register t2, 3 |
---|
239 | check_register s0, 4 |
---|
240 | check_register s1, 5 |
---|
241 | check_register a1, 6 |
---|
242 | check_register a2, 7 |
---|
243 | check_register a3, 8 |
---|
244 | check_register a4, 9 |
---|
245 | check_register a5, 10 |
---|
246 | check_register a6, 11 |
---|
247 | check_register a7, 12 |
---|
248 | check_register s2, 13 |
---|
249 | check_register s3, 14 |
---|
250 | check_register s4, 15 |
---|
251 | check_register s5, 16 |
---|
252 | check_register s6, 17 |
---|
253 | check_register s7, 18 |
---|
254 | check_register s8, 19 |
---|
255 | check_register s9, 20 |
---|
256 | check_register s10, 21 |
---|
257 | check_register s11, 22 |
---|
258 | check_register t3, 23 |
---|
259 | |
---|
260 | xor t0, sp, a0 |
---|
261 | bne t4, t0, .Lrestore |
---|
262 | |
---|
263 | xor t0, gp, a0 |
---|
264 | bne t5, t0, .Lrestore |
---|
265 | |
---|
266 | xor t0, tp, a0 |
---|
267 | bne t6, t0, .Lrestore |
---|
268 | |
---|
269 | #if __riscv_flen > 0 |
---|
270 | SREG t1, TMP_OFFSET(sp) |
---|
271 | frflags t0 |
---|
272 | andi t1, a0, 0x1f |
---|
273 | xor t0, t1, t0 |
---|
274 | LREG t1, TMP_OFFSET(sp) |
---|
275 | bnez t0, .Lrestore |
---|
276 | |
---|
277 | |
---|
278 | .macro check_f reg, inc |
---|
279 | FMVXY t0, \reg |
---|
280 | addi t0, t0, -24 - \inc |
---|
281 | bne t0, a0, .Lrestore |
---|
282 | .endm |
---|
283 | |
---|
284 | check_f f0, 0 |
---|
285 | check_f f1, 1 |
---|
286 | check_f f2, 2 |
---|
287 | check_f f3, 3 |
---|
288 | check_f f4, 4 |
---|
289 | check_f f5, 5 |
---|
290 | check_f f6, 6 |
---|
291 | check_f f7, 7 |
---|
292 | check_f f8, 8 |
---|
293 | check_f f9, 9 |
---|
294 | check_f f10, 10 |
---|
295 | check_f f11, 11 |
---|
296 | check_f f12, 12 |
---|
297 | check_f f13, 13 |
---|
298 | check_f f14, 14 |
---|
299 | check_f f15, 15 |
---|
300 | check_f f16, 16 |
---|
301 | check_f f17, 17 |
---|
302 | check_f f18, 18 |
---|
303 | check_f f19, 19 |
---|
304 | check_f f20, 20 |
---|
305 | check_f f21, 21 |
---|
306 | check_f f22, 22 |
---|
307 | check_f f23, 23 |
---|
308 | check_f f24, 24 |
---|
309 | check_f f25, 25 |
---|
310 | check_f f26, 26 |
---|
311 | check_f f27, 27 |
---|
312 | check_f f28, 28 |
---|
313 | check_f f29, 29 |
---|
314 | check_f f30, 30 |
---|
315 | check_f f31, 31 |
---|
316 | #endif /* __riscv_flen */ |
---|
317 | |
---|
318 | j .Lcheck |
---|
319 | |
---|
320 | /* Restore */ |
---|
321 | |
---|
322 | .Lrestore: |
---|
323 | |
---|
324 | LREG ra, RA_OFFSET(sp) |
---|
325 | LREG t0, T0_OFFSET(sp) |
---|
326 | LREG t1, T1_OFFSET(sp) |
---|
327 | LREG t2, T2_OFFSET(sp) |
---|
328 | LREG s0, S0_OFFSET(sp) |
---|
329 | LREG s1, S1_OFFSET(sp) |
---|
330 | LREG a0, A0_OFFSET(sp) |
---|
331 | LREG a1, A1_OFFSET(sp) |
---|
332 | LREG a2, A2_OFFSET(sp) |
---|
333 | LREG a3, A3_OFFSET(sp) |
---|
334 | LREG a4, A4_OFFSET(sp) |
---|
335 | LREG a5, A5_OFFSET(sp) |
---|
336 | LREG a6, A6_OFFSET(sp) |
---|
337 | LREG a7, A7_OFFSET(sp) |
---|
338 | LREG s2, S2_OFFSET(sp) |
---|
339 | LREG s3, S3_OFFSET(sp) |
---|
340 | LREG s4, S4_OFFSET(sp) |
---|
341 | LREG s5, S5_OFFSET(sp) |
---|
342 | LREG s6, S6_OFFSET(sp) |
---|
343 | LREG s7, S7_OFFSET(sp) |
---|
344 | LREG s8, S8_OFFSET(sp) |
---|
345 | LREG s9, S9_OFFSET(sp) |
---|
346 | LREG s10, S10_OFFSET(sp) |
---|
347 | LREG s11, S11_OFFSET(sp) |
---|
348 | LREG t3, T3_OFFSET(sp) |
---|
349 | LREG t4, T4_OFFSET(sp) |
---|
350 | LREG t5, T5_OFFSET(sp) |
---|
351 | LREG t6, T6_OFFSET(sp) |
---|
352 | |
---|
353 | #if __riscv_flen > 0 |
---|
354 | FLREG f0, FOFFSET(0)(sp) |
---|
355 | FLREG f1, FOFFSET(1)(sp) |
---|
356 | FLREG f2, FOFFSET(2)(sp) |
---|
357 | FLREG f3, FOFFSET(3)(sp) |
---|
358 | FLREG f4, FOFFSET(4)(sp) |
---|
359 | FLREG f5, FOFFSET(5)(sp) |
---|
360 | FLREG f6, FOFFSET(6)(sp) |
---|
361 | FLREG f7, FOFFSET(7)(sp) |
---|
362 | FLREG f8, FOFFSET(8)(sp) |
---|
363 | FLREG f9, FOFFSET(9)(sp) |
---|
364 | FLREG f10, FOFFSET(10)(sp) |
---|
365 | FLREG f11, FOFFSET(11)(sp) |
---|
366 | FLREG f12, FOFFSET(12)(sp) |
---|
367 | FLREG f13, FOFFSET(13)(sp) |
---|
368 | FLREG f14, FOFFSET(14)(sp) |
---|
369 | FLREG f15, FOFFSET(15)(sp) |
---|
370 | FLREG f16, FOFFSET(16)(sp) |
---|
371 | FLREG f17, FOFFSET(17)(sp) |
---|
372 | FLREG f18, FOFFSET(18)(sp) |
---|
373 | FLREG f19, FOFFSET(19)(sp) |
---|
374 | FLREG f20, FOFFSET(20)(sp) |
---|
375 | FLREG f21, FOFFSET(21)(sp) |
---|
376 | FLREG f22, FOFFSET(22)(sp) |
---|
377 | FLREG f23, FOFFSET(23)(sp) |
---|
378 | FLREG f24, FOFFSET(24)(sp) |
---|
379 | FLREG f25, FOFFSET(25)(sp) |
---|
380 | FLREG f26, FOFFSET(26)(sp) |
---|
381 | FLREG f27, FOFFSET(27)(sp) |
---|
382 | FLREG f28, FOFFSET(28)(sp) |
---|
383 | FLREG f29, FOFFSET(29)(sp) |
---|
384 | FLREG f30, FOFFSET(30)(sp) |
---|
385 | FLREG f31, FOFFSET(31)(sp) |
---|
386 | #endif /* __riscv_flen */ |
---|
387 | |
---|
388 | addi sp, sp, FRAME_SIZE |
---|
389 | ret |
---|