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

5
Last change on this file since ca9490c was b437a360, checked in by Sebastian Huber <sebastian.huber@…>, on 03/09/17 at 13:32:04

arm: Fix CPU context validation for Cortex-R4

Do not touch the FPSCR[QC] bit since this is DNM/RAZ on Cortex-R4.

  • Property mode set to 100644
File size: 5.7 KB
Line 
1/*
2 * Copyright (c) 2013, 2017 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <rtems/asm.h>
20#include <rtems/score/cpu.h>
21
22#define FRAME_OFFSET_R4 0
23#define FRAME_OFFSET_R5 4
24#define FRAME_OFFSET_R6 8
25#define FRAME_OFFSET_R7 12
26#define FRAME_OFFSET_R8 16
27#define FRAME_OFFSET_R9 20
28#define FRAME_OFFSET_R10 24
29#define FRAME_OFFSET_R11 28
30#define FRAME_OFFSET_LR 32
31
32#ifdef ARM_MULTILIB_VFP
33  #define FRAME_OFFSET_D8 40
34  #define FRAME_OFFSET_D9 48
35  #define FRAME_OFFSET_D10 56
36  #define FRAME_OFFSET_D11 64
37  #define FRAME_OFFSET_D12 72
38  #define FRAME_OFFSET_D13 80
39  #define FRAME_OFFSET_D14 88
40  #define FRAME_OFFSET_D15 96
41
42  #define FRAME_SIZE (FRAME_OFFSET_D15 + 8)
43#else
44  #define FRAME_SIZE (FRAME_OFFSET_LR + 4)
45#endif
46
47        .section        .text
48
49#ifdef __thumb__
50FUNCTION_THUMB_ENTRY(_CPU_Context_validate)
51#else
52FUNCTION_ENTRY(_CPU_Context_validate)
53#endif
54
55        /* Save */
56
57        sub     sp, sp, #FRAME_SIZE
58
59        mov     r1, r4
60        str     r1, [sp, #FRAME_OFFSET_R4]
61        mov     r1, r5
62        str     r1, [sp, #FRAME_OFFSET_R5]
63        mov     r1, r6
64        str     r1, [sp, #FRAME_OFFSET_R6]
65        mov     r1, r7
66        str     r1, [sp, #FRAME_OFFSET_R7]
67        mov     r1, r8
68        str     r1, [sp, #FRAME_OFFSET_R8]
69        mov     r1, r9
70        str     r1, [sp, #FRAME_OFFSET_R9]
71        mov     r1, r10
72        str     r1, [sp, #FRAME_OFFSET_R10]
73        mov     r1, r11
74        str     r1, [sp, #FRAME_OFFSET_R11]
75        mov     r1, lr
76        str     r1, [sp, #FRAME_OFFSET_LR]
77
78#ifdef ARM_MULTILIB_VFP
79        vstr    d8, [sp, #FRAME_OFFSET_D8]
80        vstr    d9, [sp, #FRAME_OFFSET_D9]
81        vstr    d10, [sp, #FRAME_OFFSET_D10]
82        vstr    d11, [sp, #FRAME_OFFSET_D11]
83        vstr    d12, [sp, #FRAME_OFFSET_D12]
84        vstr    d13, [sp, #FRAME_OFFSET_D13]
85        vstr    d14, [sp, #FRAME_OFFSET_D14]
86        vstr    d15, [sp, #FRAME_OFFSET_D15]
87#endif
88
89        /* Fill */
90
91        /* R1 is used for temporary values */
92        mov     r1, r0
93
94        /* R2 contains the stack pointer */
95        mov     r2, sp
96
97.macro fill_register reg
98        add     r1, r1, #1
99        mov     \reg, r1
100.endm
101
102
103#ifdef ARM_MULTILIB_VFP
104        /* R3 contains the FPSCR */
105        vmrs    r3, FPSCR
106        ldr     r4, =0xf000001f
107        bic     r3, r3, r4
108        and     r4, r4, r0
109        orr     r3, r3, r4
110        vmsr    FPSCR, r3
111#else
112        fill_register   r3
113#endif
114
115        fill_register   r4
116        fill_register   r5
117        fill_register   r6
118        fill_register   r7
119        fill_register   r8
120        fill_register   r9
121        fill_register   r10
122        fill_register   r11
123        fill_register   r12
124        fill_register   lr
125
126#ifdef ARM_MULTILIB_VFP
127.macro fill_vfp_register reg
128        add     r1, r1, #1
129        vmov    \reg, r1, r1
130.endm
131
132        fill_vfp_register       d0
133        fill_vfp_register       d1
134        fill_vfp_register       d2
135        fill_vfp_register       d3
136        fill_vfp_register       d4
137        fill_vfp_register       d5
138        fill_vfp_register       d6
139        fill_vfp_register       d7
140        fill_vfp_register       d8
141        fill_vfp_register       d9
142        fill_vfp_register       d10
143        fill_vfp_register       d11
144        fill_vfp_register       d12
145        fill_vfp_register       d13
146        fill_vfp_register       d14
147        fill_vfp_register       d15
148#ifdef ARM_MULTILIB_VFP_D32
149        fill_vfp_register       d16
150        fill_vfp_register       d17
151        fill_vfp_register       d18
152        fill_vfp_register       d19
153        fill_vfp_register       d20
154        fill_vfp_register       d21
155        fill_vfp_register       d22
156        fill_vfp_register       d23
157        fill_vfp_register       d24
158        fill_vfp_register       d25
159        fill_vfp_register       d26
160        fill_vfp_register       d27
161        fill_vfp_register       d28
162        fill_vfp_register       d29
163        fill_vfp_register       d30
164        fill_vfp_register       d31
165#endif /* ARM_MULTILIB_VFP_D32 */
166#endif /* ARM_MULTILIB_VFP */
167
168        /* Check */
169check:
170
171.macro check_register reg
172        add     r1, r1, #1
173        cmp     \reg, r1
174        bne     restore
175.endm
176
177        cmp     r2, sp
178        bne     restore
179
180        mov     r1, r0
181
182#ifndef ARM_MULTILIB_VFP
183        check_register  r3
184#endif
185
186        check_register  r4
187        check_register  r5
188        check_register  r6
189        check_register  r7
190        check_register  r8
191        check_register  r9
192        check_register  r10
193        check_register  r11
194        check_register  r12
195        check_register  lr
196
197#ifdef ARM_MULTILIB_VFP
198        b       check_vfp
199#endif
200
201        b       check
202
203        /* Restore */
204restore:
205
206        ldr     r1, [sp, #FRAME_OFFSET_R4]
207        mov     r4, r1
208        ldr     r1, [sp, #FRAME_OFFSET_R5]
209        mov     r5, r1
210        ldr     r1, [sp, #FRAME_OFFSET_R6]
211        mov     r6, r1
212        ldr     r1, [sp, #FRAME_OFFSET_R7]
213        mov     r7, r1
214        ldr     r1, [sp, #FRAME_OFFSET_R8]
215        mov     r8, r1
216        ldr     r1, [sp, #FRAME_OFFSET_R9]
217        mov     r9, r1
218        ldr     r1, [sp, #FRAME_OFFSET_R10]
219        mov     r10, r1
220        ldr     r1, [sp, #FRAME_OFFSET_R11]
221        mov     r11, r1
222        ldr     r1, [sp, #FRAME_OFFSET_LR]
223        mov     lr, r1
224
225#ifdef ARM_MULTILIB_VFP
226        vldr    d8, [sp, #FRAME_OFFSET_D8]
227        vldr    d9, [sp, #FRAME_OFFSET_D9]
228        vldr    d10, [sp, #FRAME_OFFSET_D10]
229        vldr    d11, [sp, #FRAME_OFFSET_D11]
230        vldr    d12, [sp, #FRAME_OFFSET_D12]
231        vldr    d13, [sp, #FRAME_OFFSET_D13]
232        vldr    d14, [sp, #FRAME_OFFSET_D14]
233        vldr    d15, [sp, #FRAME_OFFSET_D15]
234#endif
235
236        add     sp, sp, #FRAME_SIZE
237
238        bx      lr
239
240FUNCTION_END(_CPU_Context_validate)
241
242#ifdef ARM_MULTILIB_VFP
243check_vfp:
244
245.macro check_vfp_register reg
246        add     r1, r1, #1
247        vmov    r4, r5, \reg
248        cmp     r4, r5
249        bne     1f
250        cmp     r1, r4
251        bne     1f
252        b       2f
2531:
254        b       restore
2552:
256.endm
257
258        vmrs    r4, FPSCR
259        cmp     r4, r3
260        bne     restore
261
262        check_vfp_register      d0
263        check_vfp_register      d1
264        check_vfp_register      d2
265        check_vfp_register      d3
266        check_vfp_register      d4
267        check_vfp_register      d5
268        check_vfp_register      d6
269        check_vfp_register      d7
270        check_vfp_register      d8
271        check_vfp_register      d9
272        check_vfp_register      d10
273        check_vfp_register      d11
274        check_vfp_register      d12
275        check_vfp_register      d13
276        check_vfp_register      d14
277        check_vfp_register      d15
278#ifdef ARM_MULTILIB_VFP_D32
279        check_vfp_register      d16
280        check_vfp_register      d17
281        check_vfp_register      d18
282        check_vfp_register      d19
283        check_vfp_register      d20
284        check_vfp_register      d21
285        check_vfp_register      d22
286        check_vfp_register      d23
287        check_vfp_register      d24
288        check_vfp_register      d25
289        check_vfp_register      d26
290        check_vfp_register      d27
291        check_vfp_register      d28
292        check_vfp_register      d29
293        check_vfp_register      d30
294        check_vfp_register      d31
295#endif /* ARM_MULTILIB_VFP_D32 */
296
297        /* Restore r4 and r5 */
298        mov     r1, r0
299        fill_register   r4
300        fill_register   r5
301
302        b       check
303#endif /* ARM_MULTILIB_VFP */
Note: See TracBrowser for help on using the repository browser.