source: rtems/cpukit/score/cpu/sparc/sparc-context-validate.S @ 1c59cad

4.115
Last change on this file since 1c59cad was 1c59cad, checked in by Alexander Krutwig <alexander.krutwig@…>, on 04/24/15 at 14:05:50

sparc: Add support for sptests/spcontext01

Implement _CPU_Context_validate() and _CPU_Context_volatile_clobber().

Update #2270.

  • Property mode set to 100644
File size: 8.3 KB
Line 
1/*
2 * Copyright (c) 2015 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_BUFFER (CPU_MINIMUM_STACK_FRAME_SIZE)
23#define FRAME_OFFSET_L0 (FRAME_OFFSET_BUFFER + 0x04)
24#define FRAME_OFFSET_L1 (FRAME_OFFSET_L0 + 0x04)
25#define FRAME_OFFSET_L2 (FRAME_OFFSET_L1 + 0x04)
26#define FRAME_OFFSET_L3 (FRAME_OFFSET_L2 + 0x04)
27#define FRAME_OFFSET_L4 (FRAME_OFFSET_L3 + 0x04)
28#define FRAME_OFFSET_L5 (FRAME_OFFSET_L4 + 0x04)
29#define FRAME_OFFSET_L6 (FRAME_OFFSET_L5 + 0x04)
30#define FRAME_OFFSET_L7 (FRAME_OFFSET_L6 + 0x04)
31#define FRAME_OFFSET_I0 (FRAME_OFFSET_L7 + 0x04)
32#define FRAME_OFFSET_I1 (FRAME_OFFSET_I0 + 0x04)
33#define FRAME_OFFSET_I2 (FRAME_OFFSET_I1 + 0x04)
34#define FRAME_OFFSET_I3 (FRAME_OFFSET_I2 + 0x04)
35#define FRAME_OFFSET_I4 (FRAME_OFFSET_I3 + 0x04)
36#define FRAME_OFFSET_I5 (FRAME_OFFSET_I4 + 0x04)
37#define FRAME_OFFSET_I6 (FRAME_OFFSET_I5 + 0x04)
38#define FRAME_OFFSET_I7 (FRAME_OFFSET_I6 + 0x04)
39#define FRAME_OFFSET_SP (FRAME_OFFSET_I7 + 0x04)
40#define FRAME_END (FRAME_OFFSET_SP + 0x04)
41#define FRAME_SIZE \
42  ((FRAME_END + CPU_STACK_ALIGNMENT - 1) & ~(CPU_STACK_ALIGNMENT - 1))
43
44.macro check_register reg
45        sub     %g1, 1, %g1
46        cmp     %g1, \reg
47        bne     restore_registers
48         nop
49.endm
50
51.macro check_float_register reg
52        sub     %g1, 1, %g1
53        st      \reg, [%sp + FRAME_OFFSET_BUFFER]
54        ld      [%sp + FRAME_OFFSET_BUFFER], %o1
55        cmp     %g1, %o1
56        bne     restore_registers
57         nop
58.endm
59
60.macro check_fsr_register reg
61        st      \reg, [%sp + FRAME_OFFSET_BUFFER]
62        ld      [%sp + FRAME_OFFSET_BUFFER], %o1
63        sub     %g1, 1, %g1
64        clr     %g3
65        sethi   %hi(0xCF800000), %g3
66        or      %g3, %lo(0x0FFF), %g3
67        and     %g1, %g3, %g3
68        and     %o1, %g3, %o1
69        cmp     %o1, %g3
70        bne     restore_registers
71         nop
72.endm
73
74.macro write_register reg
75        add     %g1, 1, %g1
76        mov     %g1, \reg
77.endm
78
79.macro write_float_register reg
80        add     %g1, 1, %g1
81        st      %g1, [%sp + FRAME_OFFSET_BUFFER]
82        ld      [%sp + FRAME_OFFSET_BUFFER], \reg
83.endm
84
85.macro write_fsr_register reg
86        st      \reg, [%sp + FRAME_OFFSET_BUFFER]
87        ld      [%sp + FRAME_OFFSET_BUFFER], %o1
88        add     %g1, 1, %g1
89        clr     %g3
90
91        /*
92         * FSR is masked with undefined, reserved or system-specific values
93         * (e.g. FPU architecture version, FP queue).
94         */
95        sethi   %hi(0xCF800000), %g3
96        or      %g3, %lo(0x0FFF), %g3
97        and     %g1, %g3, %g3
98        or      %o1, %g3, %g3
99        st      %g3, [%sp + FRAME_OFFSET_BUFFER]
100        ld      [%sp + FRAME_OFFSET_BUFFER], \reg
101.endm
102
103        .align 4
104        PUBLIC(_CPU_Context_validate)
105SYM(_CPU_Context_validate):
106
107        /*
108         * g2 checks if the Floating Point Unit in the Processor Status
109         * Register (PSR) is set.
110         */
111        mov     %psr, %g2
112        sethi   %hi(SPARC_PSR_EF_MASK), %g3
113        and     %g2, %g3, %g2
114
115        /* g1 is used to save the original pattern */
116        mov     %o0, %g1
117
118        /* g4 establishes window counter */
119        clr     %g4
120
121        add     %sp, -FRAME_SIZE, %sp
122
123        st      %l0, [%sp + FRAME_OFFSET_L0]
124        st      %l1, [%sp + FRAME_OFFSET_L1]
125        st      %l2, [%sp + FRAME_OFFSET_L2]
126        st      %l3, [%sp + FRAME_OFFSET_L3]
127        st      %l4, [%sp + FRAME_OFFSET_L4]
128        st      %l5, [%sp + FRAME_OFFSET_L5]
129        st      %l6, [%sp + FRAME_OFFSET_L6]
130        st      %l7, [%sp + FRAME_OFFSET_L7]
131        st      %i0, [%sp + FRAME_OFFSET_I0]
132        st      %i1, [%sp + FRAME_OFFSET_I1]
133        st      %i2, [%sp + FRAME_OFFSET_I2]
134        st      %i3, [%sp + FRAME_OFFSET_I3]
135        st      %i4, [%sp + FRAME_OFFSET_I4]
136        st      %i5, [%sp + FRAME_OFFSET_I5]
137        st      %i6, [%sp + FRAME_OFFSET_I6]
138        st      %i7, [%sp + FRAME_OFFSET_I7]
139        st      %sp, [%sp + FRAME_OFFSET_SP]
140
141        cmp     %g4, 0
142        bne     write_locals_and_outputs
143         nop
144        be      check_for_fp
145         nop
146
147new_check_cycle:
148        clr     %g4
149        sub     %g1, 1, %g1
150
151        /* Write pattern values into registers */
152
153check_for_fp:
154        cmp     %g2, 0
155        be      write_y
156         nop
157
158        write_fsr_register      %fsr
159        write_float_register    %f0
160        write_float_register    %f1
161        write_float_register    %f2
162        write_float_register    %f3
163        write_float_register    %f4
164        write_float_register    %f5
165        write_float_register    %f6
166        write_float_register    %f7
167        write_float_register    %f8
168        write_float_register    %f9
169        write_float_register    %f10
170        write_float_register    %f11
171        write_float_register    %f12
172        write_float_register    %f13
173        write_float_register    %f14
174        write_float_register    %f15
175        write_float_register    %f16
176        write_float_register    %f17
177        write_float_register    %f18
178        write_float_register    %f19
179        write_float_register    %f20
180        write_float_register    %f21
181        write_float_register    %f22
182        write_float_register    %f23
183        write_float_register    %f24
184        write_float_register    %f25
185        write_float_register    %f26
186        write_float_register    %f27
187        write_float_register    %f28
188        write_float_register    %f29
189        write_float_register    %f30
190        write_float_register    %f31
191
192write_y:
193        write_register  %y
194
195        write_register  %i0
196        write_register  %i1
197        write_register  %i2
198        write_register  %i3
199        write_register  %i4
200        write_register  %i5
201        /* Don't write register $i6 => frame pointer */
202        /* Don't write register $i7 => return address */
203        b       write_locals_and_outputs
204         nop
205
206switch_to_next_window:
207        save    %sp, -FRAME_SIZE, %sp
208
209write_locals_and_outputs:
210        /* l0 is used as a scratch register */
211        write_register  %l1
212        write_register  %l2
213        write_register  %l3
214        write_register  %l4
215        write_register  %l5
216        write_register  %l6
217        write_register  %l7
218        write_register  %o1
219        write_register  %o2
220        write_register  %o3
221        write_register  %o4
222        write_register  %o5
223        /* Don't write register $o6 => stack pointer */
224        /* Don't write register $o7 => return address */
225
226        add     %g4, 1, %g4
227        cmp     %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS
228        bne     switch_to_next_window
229         nop
230
231        /* Dummy increment to set up reverse mechanism for checking process */
232        add     %g1, 1, %g1
233        clr     %g4
234
235        /* Checking begins here */
236window_checking:
237        cmp     %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS
238        be      y_checking
239         nop
240
241further_checking:
242        cmp     %g4, 0
243        bne     goto_local_registers
244         nop
245
246        /* Check normal registers */
247        check_register  %o5
248        check_register  %o4
249        check_register  %o3
250        check_register  %o2
251        check_register  %o1
252
253goto_local_registers:
254        check_register  %l7
255        check_register  %l6
256        check_register  %l5
257        check_register  %l4
258        check_register  %l3
259        check_register  %l2
260        check_register  %l1
261
262        check_register  %i5
263        check_register  %i4
264        check_register  %i3
265        check_register  %i2
266        check_register  %i1
267        /*
268        For the last window i0 also needs to be checked as this variable
269        is not overwritten by the outputs of another window.
270        */
271        add     %g4, 1, %g4
272        cmp     %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS
273        bne     dont_check_i0
274         nop
275        check_register  %i0
276        b       y_checking
277         nop
278
279dont_check_i0:
280        restore
281
282        ba      window_checking
283         nop
284
285        /* Check Y register */
286y_checking:
287        mov     %y, %o1
288        check_register  %o1
289        cmp     %g2, 0
290        be      new_check_cycle
291         nop
292
293        /* Check floating point registers */
294        check_float_register    %f31
295        check_float_register    %f30
296        check_float_register    %f29
297        check_float_register    %f28
298        check_float_register    %f27
299        check_float_register    %f26
300        check_float_register    %f25
301        check_float_register    %f24
302        check_float_register    %f23
303        check_float_register    %f22
304        check_float_register    %f21
305        check_float_register    %f20
306        check_float_register    %f19
307        check_float_register    %f18
308        check_float_register    %f17
309        check_float_register    %f16
310        check_float_register    %f15
311        check_float_register    %f14
312        check_float_register    %f13
313        check_float_register    %f12
314        check_float_register    %f11
315        check_float_register    %f10
316        check_float_register    %f9
317        check_float_register    %f8
318        check_float_register    %f7
319        check_float_register    %f6
320        check_float_register    %f5
321        check_float_register    %f4
322        check_float_register    %f3
323        check_float_register    %f2
324        check_float_register    %f1
325        check_float_register    %f0
326        check_fsr_register      %fsr
327
328        be      new_check_cycle
329         nop
330
331        /****** RESTORE STARTS HERE *******/
332
333        /* Restore non-volatile registers */
334
335restore_registers:
336        and     %g4, (SPARC_NUMBER_OF_REGISTER_WINDOWS - 1), %g4
337        cmp     %g4, 0
338        be      real_restore
339         nop
340        restore
341        sub     %g4, 1, %g4
342        bne     restore_registers
343         nop
344
345real_restore:
346        ld      [%sp + FRAME_OFFSET_L0], %l0
347        ld      [%sp + FRAME_OFFSET_L1], %l1
348        ld      [%sp + FRAME_OFFSET_L2], %l2
349        ld      [%sp + FRAME_OFFSET_L3], %l3
350        ld      [%sp + FRAME_OFFSET_L4], %l4
351        ld      [%sp + FRAME_OFFSET_L5], %l5
352        ld      [%sp + FRAME_OFFSET_L6], %l6
353        ld      [%sp + FRAME_OFFSET_L7], %l7
354        ld      [%sp + FRAME_OFFSET_I0], %i0
355        ld      [%sp + FRAME_OFFSET_I1], %i1
356        ld      [%sp + FRAME_OFFSET_I2], %i2
357        ld      [%sp + FRAME_OFFSET_I3], %i3
358        ld      [%sp + FRAME_OFFSET_I4], %i4
359        ld      [%sp + FRAME_OFFSET_I5], %i5
360        ld      [%sp + FRAME_OFFSET_I6], %i6
361        ld      [%sp + FRAME_OFFSET_I7], %i7
362
363        sub     %sp, -FRAME_SIZE, %sp
364
365return_value:
366        /* Load callback address and jump back */
367        jmp     %o7 + 8
368         add    %sp, FRAME_SIZE, %sp
Note: See TracBrowser for help on using the repository browser.