source: rtems/cpukit/score/cpu/arm/arm-context-validate.S

Last change on this file was bcef89f2, checked in by Sebastian Huber <sebastian.huber@…>, on 05/19/23 at 06:18:25

Update company name

The embedded brains GmbH & Co. KG is the legal successor of embedded
brains GmbH.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/*
4 * Copyright (C) 2013, 2017 embedded brains GmbH & Co. KG
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <rtems/asm.h>
33#include <rtems/score/cpu.h>
34
35#define FRAME_OFFSET_R4 0
36#define FRAME_OFFSET_R5 4
37#define FRAME_OFFSET_R6 8
38#define FRAME_OFFSET_R7 12
39#define FRAME_OFFSET_R8 16
40#define FRAME_OFFSET_R9 20
41#define FRAME_OFFSET_R10 24
42#define FRAME_OFFSET_R11 28
43#define FRAME_OFFSET_LR 32
44
45#ifdef ARM_MULTILIB_VFP
46  #define FRAME_OFFSET_D8 40
47  #define FRAME_OFFSET_D9 48
48  #define FRAME_OFFSET_D10 56
49  #define FRAME_OFFSET_D11 64
50  #define FRAME_OFFSET_D12 72
51  #define FRAME_OFFSET_D13 80
52  #define FRAME_OFFSET_D14 88
53  #define FRAME_OFFSET_D15 96
54
55  #define FRAME_SIZE (FRAME_OFFSET_D15 + 8)
56#else
57  #define FRAME_SIZE (FRAME_OFFSET_LR + 4)
58#endif
59
60        .syntax unified
61        .section        .text
62
63#ifdef __thumb2__
64FUNCTION_THUMB_ENTRY(_CPU_Context_validate)
65#else
66FUNCTION_ENTRY(_CPU_Context_validate)
67#endif
68
69        /* Save */
70
71        sub     sp, sp, #FRAME_SIZE
72
73        mov     r1, r4
74        str     r1, [sp, #FRAME_OFFSET_R4]
75        mov     r1, r5
76        str     r1, [sp, #FRAME_OFFSET_R5]
77        mov     r1, r6
78        str     r1, [sp, #FRAME_OFFSET_R6]
79        mov     r1, r7
80        str     r1, [sp, #FRAME_OFFSET_R7]
81        mov     r1, r8
82        str     r1, [sp, #FRAME_OFFSET_R8]
83        mov     r1, r9
84        str     r1, [sp, #FRAME_OFFSET_R9]
85        mov     r1, r10
86        str     r1, [sp, #FRAME_OFFSET_R10]
87        mov     r1, r11
88        str     r1, [sp, #FRAME_OFFSET_R11]
89        mov     r1, lr
90        str     r1, [sp, #FRAME_OFFSET_LR]
91
92#ifdef ARM_MULTILIB_VFP
93        vstr    d8, [sp, #FRAME_OFFSET_D8]
94        vstr    d9, [sp, #FRAME_OFFSET_D9]
95        vstr    d10, [sp, #FRAME_OFFSET_D10]
96        vstr    d11, [sp, #FRAME_OFFSET_D11]
97        vstr    d12, [sp, #FRAME_OFFSET_D12]
98        vstr    d13, [sp, #FRAME_OFFSET_D13]
99        vstr    d14, [sp, #FRAME_OFFSET_D14]
100        vstr    d15, [sp, #FRAME_OFFSET_D15]
101#endif
102
103        /* Fill */
104
105        /* R1 is used for temporary values */
106        mov     r1, r0
107
108        /* R2 contains the stack pointer */
109        mov     r2, sp
110
111.macro fill_register reg
112        add     r1, r1, #1
113        mov     \reg, r1
114.endm
115
116
117#ifdef ARM_MULTILIB_VFP
118        /* R3 contains the FPSCR */
119        vmrs    r3, FPSCR
120        ldr     r4, =0xf000001f
121        bic     r3, r3, r4
122        and     r4, r4, r0
123        orr     r3, r3, r4
124        vmsr    FPSCR, r3
125#else
126        fill_register   r3
127#endif
128
129        fill_register   r4
130        fill_register   r5
131        fill_register   r6
132        fill_register   r7
133        fill_register   r8
134        fill_register   r9
135        fill_register   r10
136        fill_register   r11
137        fill_register   r12
138        fill_register   lr
139
140#ifdef ARM_MULTILIB_VFP
141.macro fill_vfp_register reg
142        add     r1, r1, #1
143        vmov    \reg, r1, r1
144.endm
145
146        fill_vfp_register       d0
147        fill_vfp_register       d1
148        fill_vfp_register       d2
149        fill_vfp_register       d3
150        fill_vfp_register       d4
151        fill_vfp_register       d5
152        fill_vfp_register       d6
153        fill_vfp_register       d7
154        fill_vfp_register       d8
155        fill_vfp_register       d9
156        fill_vfp_register       d10
157        fill_vfp_register       d11
158        fill_vfp_register       d12
159        fill_vfp_register       d13
160        fill_vfp_register       d14
161        fill_vfp_register       d15
162#ifdef ARM_MULTILIB_VFP_D32
163        fill_vfp_register       d16
164        fill_vfp_register       d17
165        fill_vfp_register       d18
166        fill_vfp_register       d19
167        fill_vfp_register       d20
168        fill_vfp_register       d21
169        fill_vfp_register       d22
170        fill_vfp_register       d23
171        fill_vfp_register       d24
172        fill_vfp_register       d25
173        fill_vfp_register       d26
174        fill_vfp_register       d27
175        fill_vfp_register       d28
176        fill_vfp_register       d29
177        fill_vfp_register       d30
178        fill_vfp_register       d31
179#endif /* ARM_MULTILIB_VFP_D32 */
180#endif /* ARM_MULTILIB_VFP */
181
182        /* Check */
183check:
184
185.macro check_register reg
186        add     r1, r1, #1
187        cmp     \reg, r1
188        bne     restore
189.endm
190
191        /* A compare involving the stack pointer is deprecated */
192        mov     r1, sp
193        cmp     r2, r1
194        bne     restore
195
196        mov     r1, r0
197
198#ifdef __thumb2__
199        cmp     r1, r1
200        itttt   eq
201        addeq   r1, #1
202        addeq   r1, #2
203        addeq   r1, #4
204        addeq   r1, #8
205        subs    r1, #15
206        cmp     r1, r0
207        bne     restore
208        cmp     r1, r1
209        iteee   eq
210        addeq   r1, #1
211        addne   r1, #2
212        addne   r1, #4
213        addne   r1, #8
214        subs    r1, #1
215        cmp     r1, r0
216        bne     restore
217#endif
218
219#ifndef ARM_MULTILIB_VFP
220        check_register  r3
221#endif
222
223        check_register  r4
224        check_register  r5
225        check_register  r6
226        check_register  r7
227        check_register  r8
228        check_register  r9
229        check_register  r10
230        check_register  r11
231        check_register  r12
232        check_register  lr
233
234#ifdef ARM_MULTILIB_VFP
235        b       check_vfp
236#endif
237
238        b       check
239
240        /* Restore */
241restore:
242
243        ldr     r1, [sp, #FRAME_OFFSET_R4]
244        mov     r4, r1
245        ldr     r1, [sp, #FRAME_OFFSET_R5]
246        mov     r5, r1
247        ldr     r1, [sp, #FRAME_OFFSET_R6]
248        mov     r6, r1
249        ldr     r1, [sp, #FRAME_OFFSET_R7]
250        mov     r7, r1
251        ldr     r1, [sp, #FRAME_OFFSET_R8]
252        mov     r8, r1
253        ldr     r1, [sp, #FRAME_OFFSET_R9]
254        mov     r9, r1
255        ldr     r1, [sp, #FRAME_OFFSET_R10]
256        mov     r10, r1
257        ldr     r1, [sp, #FRAME_OFFSET_R11]
258        mov     r11, r1
259        ldr     r1, [sp, #FRAME_OFFSET_LR]
260        mov     lr, r1
261
262#ifdef ARM_MULTILIB_VFP
263        vldr    d8, [sp, #FRAME_OFFSET_D8]
264        vldr    d9, [sp, #FRAME_OFFSET_D9]
265        vldr    d10, [sp, #FRAME_OFFSET_D10]
266        vldr    d11, [sp, #FRAME_OFFSET_D11]
267        vldr    d12, [sp, #FRAME_OFFSET_D12]
268        vldr    d13, [sp, #FRAME_OFFSET_D13]
269        vldr    d14, [sp, #FRAME_OFFSET_D14]
270        vldr    d15, [sp, #FRAME_OFFSET_D15]
271#endif
272
273        add     sp, sp, #FRAME_SIZE
274
275        bx      lr
276
277FUNCTION_END(_CPU_Context_validate)
278
279#ifdef ARM_MULTILIB_VFP
280check_vfp:
281
282.macro check_vfp_register reg
283        add     r1, r1, #1
284        vmov    r4, r5, \reg
285        cmp     r4, r5
286        bne     1f
287        cmp     r1, r4
288        bne     1f
289        b       2f
2901:
291        b       restore
2922:
293.endm
294
295        vmrs    r4, FPSCR
296        cmp     r4, r3
297        bne     restore
298
299        check_vfp_register      d0
300        check_vfp_register      d1
301        check_vfp_register      d2
302        check_vfp_register      d3
303        check_vfp_register      d4
304        check_vfp_register      d5
305        check_vfp_register      d6
306        check_vfp_register      d7
307        check_vfp_register      d8
308        check_vfp_register      d9
309        check_vfp_register      d10
310        check_vfp_register      d11
311        check_vfp_register      d12
312        check_vfp_register      d13
313        check_vfp_register      d14
314        check_vfp_register      d15
315#ifdef ARM_MULTILIB_VFP_D32
316        check_vfp_register      d16
317        check_vfp_register      d17
318        check_vfp_register      d18
319        check_vfp_register      d19
320        check_vfp_register      d20
321        check_vfp_register      d21
322        check_vfp_register      d22
323        check_vfp_register      d23
324        check_vfp_register      d24
325        check_vfp_register      d25
326        check_vfp_register      d26
327        check_vfp_register      d27
328        check_vfp_register      d28
329        check_vfp_register      d29
330        check_vfp_register      d30
331        check_vfp_register      d31
332#endif /* ARM_MULTILIB_VFP_D32 */
333
334        /* Restore r4 and r5 */
335        mov     r1, r0
336        fill_register   r4
337        fill_register   r5
338
339        b       check
340#endif /* ARM_MULTILIB_VFP */
Note: See TracBrowser for help on using the repository browser.