source: rtems/cpukit/score/cpu/sparc/syscall.S @ 1c34a9b

5
Last change on this file since 1c34a9b was 1c34a9b, checked in by Daniel Cederman <cederman@…>, on 12/19/17 at 12:36:33

sparc: Remove sequence that could trigger B2BST errata

  • Property mode set to 100644
File size: 7.2 KB
Line 
1/*
2 *  systrap.S
3 *
4 *  This file contains emulated system calls using software trap 0.
5 *  The following calls are supported:
6 *
7 *    + SYS_exit        (halt)
8 *    + SYS_irqdis      (disable interrupts)
9 *    + SYS_irqset      (set interrupt level)
10 *
11 *  COPYRIGHT:
12 *
13 *  COPYRIGHT (c) 1995. European Space Agency.
14 *  Copyright (c) 2016, 2017 embedded brains GmbH
15 *
16 *  This terms of the RTEMS license apply to this file.
17 *
18 */
19
20#include <rtems/asm.h>
21#include <rtems/score/cpuimpl.h>
22#include <rtems/score/percpu.h>
23#include "syscall.h"
24
25        .section    ".text"
26        /*
27         *  system call - halt
28         *
29         *  On entry:
30         *
31         *    l0 = psr (from trap table)
32         *    l1 = pc
33         *    l2 = npc
34         *    g1 = system call id (1)
35         *
36         *  System Call 1 (exit):
37         *    g2 = additional exit code 1
38         *    g3 = additional exit code 2
39         */
40
41        PUBLIC(syscall)
42
43SYM(syscall):
44        ta      0                       ! syscall 1, halt with %g1,%g2,%g3 info
45
46        PUBLIC(sparc_syscall_exit)
47
48SYM(sparc_syscall_exit):
49
50        mov     SYS_exit, %g1
51        mov     %o0, %g2        ! Additional exit code 1
52        mov     %o1, %g3        ! Additional exit code 2
53        ta      SPARC_SWTRAP_SYSCALL
54
55        /*
56         *  system call - Interrupt Disable
57         *
58         *  On entry:
59         *
60         *    l0 = psr (from trap table)
61         *    l1 = pc
62         *    l2 = npc
63         *    l3 = psr | SPARC_PSR_PIL_MASK
64         *
65         *  On exit:
66         *    g1 = old psr (to user)
67         */
68
69.align 32                               ! Align to 32-byte cache-line
70        PUBLIC(syscall_irqdis)
71
72SYM(syscall_irqdis):
73        mov     %l3, %psr                       ! Set PSR. Write delay 3 instr
74        or      %l0, SPARC_PSR_ET_MASK, %g1     ! return old PSR with ET=1
75        nop                                     ! PSR write delay
76        jmp     %l2                             ! Return to after TA 9.
77         rett   %l2 + 4
78
79        /*
80         *  system call - Interrupt Enable
81         *
82         *  On entry:
83         *
84         *    l0 = psr (from trap table)
85         *    l1 = pc
86         *    l2 = npc
87         *    l3 = psr & ~0x0f00
88         *    g1 = new PIL to write (from user)
89         */
90
91.align 32                               ! Align to 32-byte cache-line
92        PUBLIC(syscall_irqen)
93
94SYM(syscall_irqen):
95        and     %g1, SPARC_PSR_PIL_MASK, %l4    ! %l4 = (%g1 & 0xf00)
96        wr      %l3, %l4, %psr                  ! PSR = (PSR & ~0xf00) ^ %l4
97        nop; nop                                ! PSR write delay;
98        jmp     %l2                             ! Return to after TA 10.
99         rett   %l2 + 4
100
101#if defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH)
102        /*
103         *  system call - Interrupt disable and set PSR[EF] according to caller
104         *                specified %g1
105         *
106         *  On entry:
107         *
108         *    g1 = the desired PSR[EF] value (from caller)
109         *    l0 = psr (from trap table)
110         *    l1 = pc
111         *    l2 = npc
112         *    l3 = psr | SPARC_PSR_PIL_MASK
113         *
114         *  On exit:
115         *    g1 = old psr (to user)
116         */
117
118.align 32                               ! Align to 32-byte cache-line
119        PUBLIC(syscall_irqdis_fp)
120
121SYM(syscall_irqdis_fp):
122        /*
123         * We cannot use an intermediate value for operations with the PSR[EF]
124         * bit since they use a 13-bit sign extension and PSR[EF] is bit 12.
125         */
126        sethi   %hi(SPARC_PSR_EF_MASK), %l4
127
128        andn    %l3, %l4, %l3                   ! Clear PSR[EF]
129        and     %g1, %l4, %g1                   ! Select PSR[EF] only from %g1
130        or      %l3, %g1, %l3                   ! Set PSR[EF] according to %g1
131        mov     %l3, %psr                       ! Set PSR. Write delay 3 instr
132        or      %l0, SPARC_PSR_ET_MASK, %g1     ! return old PSR with ET=1
133        nop                                     ! PSR write delay
134        jmp     %l2                             ! Return to after TA 9.
135         rett   %l2 + 4
136#endif
137
138#if defined(SPARC_USE_LAZY_FP_SWITCH)
139
140        /*
141         *  system call - Perform a lazy floating point switch
142         *
143         *  On entry:
144         *
145         *    l0 = psr (from trap table)
146         *    l1 = pc
147         *    l2 = npc
148         *    l3 = SPARC_PSR_EF_MASK
149         */
150
151.align 32                               ! Align to 32-byte cache-line
152        PUBLIC(syscall_lazy_fp_switch)
153
154SYM(syscall_lazy_fp_switch):
155        ld      [%g6 + PER_CPU_OFFSET_EXECUTING], %l4
156        ld      [%g6 + PER_CPU_ISR_NEST_LEVEL], %l5
157        ld      [%l4 + %lo(SPARC_THREAD_CONTROL_FP_CONTEXT_OFFSET)], %l6
158        ld      [%g6 + SPARC_PER_CPU_FP_OWNER_OFFSET], %l7
159
160        /* Ensure that we are not in interrupt context */
161        cmp     %l5, 0
162        bne     .Lillegal_use_of_floating_point_unit
163         or     %l0, %l3, %l0
164
165        /* Ensure that we are a proper floating point thread */
166        cmp     %l6, 0
167        be      .Lillegal_use_of_floating_point_unit
168         ld     [%l4 + %lo(SPARC_THREAD_CONTROL_REGISTERS_FP_CONTEXT_OFFSET)], %l6
169
170        /* Set PSR[EF] to 1, PSR write delay 3 instructions! */
171        mov     %l0, %psr
172
173        /*
174         * Check if there is a floating point owner.  We have to check this
175         * here, since the floating point owner may have been deleted in the
176         * meantime.  Save the floating point context if necessary.
177         */
178        cmp     %l7, 0
179        be      .Lfp_save_done
180         nop
181        ld      [%l7 + %lo(SPARC_THREAD_CONTROL_FP_CONTEXT_OFFSET)], %l5
182        std     %f0, [%l5 + SPARC_FP_CONTEXT_OFFSET_F0_F1]
183        SPARC_LEON3FT_B2BST_NOP
184        std     %f2, [%l5 + SPARC_FP_CONTEXT_OFFSET_F2_F3]
185        SPARC_LEON3FT_B2BST_NOP
186        std     %f4, [%l5 + SPARC_FP_CONTEXT_OFFSET_F4_F5]
187        SPARC_LEON3FT_B2BST_NOP
188        std     %f6, [%l5 + SPARC_FP_CONTEXT_OFFSET_F6_F7]
189        SPARC_LEON3FT_B2BST_NOP
190        std     %f8, [%l5 + SPARC_FP_CONTEXT_OFFSET_F8_F9]
191        SPARC_LEON3FT_B2BST_NOP
192        std     %f10, [%l5 + SPARC_FP_CONTEXT_OFFSET_F10_F11]
193        SPARC_LEON3FT_B2BST_NOP
194        std     %f12, [%l5 + SPARC_FP_CONTEXT_OFFSET_F12_F13]
195        SPARC_LEON3FT_B2BST_NOP
196        std     %f14, [%l5 + SPARC_FP_CONTEXT_OFFSET_F14_F15]
197        SPARC_LEON3FT_B2BST_NOP
198        std     %f16, [%l5 + SPARC_FP_CONTEXT_OFFSET_F16_F17]
199        SPARC_LEON3FT_B2BST_NOP
200        std     %f18, [%l5 + SPARC_FP_CONTEXT_OFFSET_F18_F19]
201        SPARC_LEON3FT_B2BST_NOP
202        std     %f20, [%l5 + SPARC_FP_CONTEXT_OFFSET_F20_F21]
203        SPARC_LEON3FT_B2BST_NOP
204        std     %f22, [%l5 + SPARC_FP_CONTEXT_OFFSET_F22_F23]
205        SPARC_LEON3FT_B2BST_NOP
206        std     %f24, [%l5 + SPARC_FP_CONTEXT_OFFSET_F24_F25]
207        SPARC_LEON3FT_B2BST_NOP
208        std     %f26, [%l5 + SPARC_FP_CONTEXT_OFFSET_F26_F27]
209        SPARC_LEON3FT_B2BST_NOP
210        std     %f28, [%l5 + SPARC_FP_CONTEXT_OFFSET_F28_F29]
211        SPARC_LEON3FT_B2BST_NOP
212        std     %f30, [%l5 + SPARC_FP_CONTEXT_OFFSET_F30_F31]
213        SPARC_LEON3FT_B2BST_NOP
214        st      %fsr, [%l5 + SPARC_FP_CONTEXT_OFFSET_FSR]
215        st      %g0, [%g6 + SPARC_PER_CPU_FP_OWNER_OFFSET]
216        st      %l5, [%l7 + %lo(SPARC_THREAD_CONTROL_REGISTERS_FP_CONTEXT_OFFSET)]
217
218.Lfp_save_done:
219
220        /* Restore the floating point context if necessary */
221        cmp     %l6, 0
222        be      .Lfp_restore_done
223         st     %g0, [%l4 + %lo(SPARC_THREAD_CONTROL_REGISTERS_FP_CONTEXT_OFFSET)]
224        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F0_F1], %f0
225        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F2_F3], %f2
226        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F4_F5], %f4
227        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F6_F7], %f6
228        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F8_F9], %f8
229        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F10_F11], %f10
230        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F12_F13], %f12
231        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F14_F15], %f14
232        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F16_F17], %f16
233        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F18_F19], %f18
234        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F20_F21], %f20
235        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F22_F23], %f22
236        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F24_F25], %f24
237        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F26_F27], %f26
238        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F28_F29], %f28
239        ldd     [%l6 + SPARC_FP_CONTEXT_OFFSET_F30_F31], %f30
240        ld      [%l6 + SPARC_FP_CONTEXT_OFFSET_FSR], %fsr
241
242.Lfp_restore_done:
243
244        /* Now, retry the floating point instruction with PSR[EF] == 1 */
245        jmp     %l1
246         rett   %l2
247
248.Lillegal_use_of_floating_point_unit:
249
250        sethi   %hi(_Internal_error), %l1
251        or      %l1, %lo(_Internal_error), %l1
252        mov     38, %i0
253        jmp     %l1
254         rett   %l1 + 4
255#endif
256
257#if defined(RTEMS_PARAVIRT)
258
259        PUBLIC(_SPARC_Get_PSR)
260
261SYM(_SPARC_Get_PSR):
262
263        retl
264         rd     %psr, %o0
265
266        PUBLIC(_SPARC_Set_PSR)
267
268SYM(_SPARC_Set_PSR):
269
270        mov     %o0, %psr
271        nop
272        nop
273        nop
274        retl
275         nop
276
277        PUBLIC(_SPARC_Get_TBR)
278
279SYM(_SPARC_Get_TBR):
280
281        retl
282         rd    %tbr, %o0
283
284        PUBLIC(_SPARC_Set_TBR)
285
286SYM(_SPARC_Set_TBR):
287
288        retl
289         wr    %o0, 0, %tbr
290
291#endif /* defined(RTEMS_PARAVIRT) */
292
293/* end of file */
Note: See TracBrowser for help on using the repository browser.