source: trunk/libs/newlib/src/libgloss/sparc_leon/regwinflush.S @ 684

Last change on this file since 684 was 444, checked in by satin@…, 7 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 6.5 KB
Line 
1/*
2 * Copyright (c) 2011 Aeroflex Gaisler
3 *
4 * BSD license:
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25
26#include <asm-leon/leon.h>
27#include <asm-leon/leonstack.h>
28#include <asm-leon/asmmacro.h>
29       
30        .seg    "data"
31        .global _lb_spillglobals, _lb_issideflush
32        .align  4
33_lb_spillglobals:
34        .word 0
35        .word 0
36        .word 0
37        .word 0
38        .word 0
39        .word 0
40        .word 0
41_lb_issideflush:
42        .word 0 /* off: 28 */
43       
44        .seg    "text"
45
46/* =============================================== */
47       
48#define _SV     save    %sp, -SF_REGS_SZ, %sp
49#define _RS     restore
50
51        /* ------- */
52        .weak   _flush_windows
53        .set    _flush_windows,__flush_windows
54        .weak   _flush_windows_svt
55        .set    _flush_windows_svt,__flush_windows_svt
56        /* ------- */
57        !.global        _flush_windows,_flush_windows_svt
58__flush_windows_svt:
59        rd %wim, %l3
60
61__flush_windows:
62        SAVE_ALL
63       
64#ifndef _FLAT
65
66        set     _lb_issideflush, %l3
67        st      %l0, [%l3]      /* mark as inside flush */
68       
69        wr      %l0, SPARC_PSR_ET_MASK, %psr
70        nop; nop; nop
71
72        _SV; _SV; _SV; _SV; _SV; _SV; _SV;
73        _RS; _RS; _RS; _RS; _RS; _RS; _RS;
74
75        set     _lb_issideflush, %l3
76        st      %g0, [%l3]      /* mark as outside flush */
77       
78        /* Advance over the trap instruction. */
79        ld      [%sp + SF_REGS_SZ + PT_NPC], %l1
80        add     %l1, 0x4, %l2
81        st      %l1, [%sp + SF_REGS_SZ + PT_PC]
82        st      %l2, [%sp + SF_REGS_SZ + PT_NPC]
83#endif
84       
85        RESTORE_ALL
86
87/* =============================================== */
88
89_irqcall_flush_windows:
90#ifndef _FLAT
91        set    _lb_spillglobals,%l4
92        st     %g1,[%l4+0]
93        st     %g4,[%l4+4]
94        st     %l0,[%l4+16]
95        st     %l1,[%l4+20]
96        st     %l2,[%l4+24]
97        st     %l4,[%l4+28] /* mark as inside flush */
98       
99        restore
100
101        mov     %psr, %g1
102        or      %g1, SPARC_PSR_PIL_MASK, %g1
103        wr      %g1, SPARC_PSR_ET_MASK, %psr         /* disable irq, enable traps */
104        nop
105        nop
106        nop
107       
108        sethi %hi(_nwindows_min1), %g4               /* flush registers */
109        ld [%g4+%lo(_nwindows_min1)], %g4
1101:      save                                         /* NWINDOWS-1 times */
111        sub    %g4,1,%g4
112
113        /*****************/
114        andncc   %g4,0xff,%g0
115        be    .lab1
116         nop
117        nop
118       
119.lab1:  /*****************/
120       
121        cmp    %g4,%g0
122        bne    1b
123         nop
124       
125        sethi %hi(_nwindows_min1), %g4
126        ld [%g4+%lo(_nwindows_min1)], %g4
1272:      restore                                      /* NWINDOWS-1 times */
128         
129        /*****************/
130        andncc   %g4,0xff,%g0
131        be    .lab2
132         nop
133        nop
134       
135.lab2:  /*****************/
136       
137        sub    %g4,1,%g4
138        cmp    %g4,%g0
139        bne    2b
140         nop
141
142        save
143
144        set    _lb_spillglobals,%l4
145        ld     [%l4+4], %g4
146        ld     [%l4+0], %g1
147        ld     [%l4+16],%l0
148        ld     [%l4+20],%l1
149        ld     [%l4+24],%l2
150        st     %g0,[%l4+28] /* clean inside flush mark */
151       
152#endif
153       
154        wr      %l0, 0, %psr                         /* restore psr */
155        nop
156        nop
157        nop
158       
159        jmpl    %l2, %g0
160        rett    %l2 + 4
161
162/* =============================================== */
163
164        /* ------- */
165        .weak   _irqcall_disableirq
166        .set    _irqcall_disableirq,__irqcall_disableirq
167        .weak   _irqcall_disableirq_svt
168        .set    _irqcall_disableirq_svt,__irqcall_disableirq_svt
169        /* ------- */
170       
171__irqcall_disableirq:   
172__irqcall_disableirq_svt:       
173        or      %l0, SPARC_PSR_PIL_MASK, %l0
174        mov     %l0, %psr
175        nop; nop; nop
176        jmpl    %l2, %g0
177        rett    %l2 + 4
178
179/* =============================================== */
180       
181        /*
182         *  system call (ta 0x2):       
183         *  2: irq_disable:
184         *      o1 = 2
185         *  3: irq_enable:
186         *      o0 = old_flags
187         *      o1 = 3
188         *  4: enter supervisor mode (from user mode):
189         *      o1 = 4
190         *  5: enter user mode:
191         *      o1 = 5
192         *  6: flush windows
193         *
194         *  On entry:
195         *
196         *    l0 = psr (from trap table)
197         *    l1 = pc
198         *    l2 = npc
199         *    i0 = system call id
200         */
201
202        /* ------- */
203        .weak   _irqcall
204        .set    _irqcall,__irqcall
205        .weak   _irqcall_svt
206        .set    _irqcall_svt,__irqcall_svt
207        /* ------- */
208        !.global _irqcall,_irqcall_svt
209__irqcall_svt: 
210__irqcall:
211
212        subcc   %i1, 2, %g0             ! syscall 2, disable interrupts
213        bne     3f
214        or      %l0, 0x0f00, %l4        ! set PIL=15
215        mov     %l4, %psr
216        or      %l0, SPARC_PSR_ET_MASK, %i0     ! return old psr with ET=1
217        ba,a    9f
2183:
219        subcc   %i1, 3, %g0             ! syscall 3, enable interrupts
220        bne     4f
221        and     %i0, SPARC_PSR_PIL_MASK, %l4
222        andn    %l0, SPARC_PSR_PIL_MASK, %l5
223        or      %l5, %l4, %l4
224        mov     %l4, %psr
225        ba,a    9f             
2264:     
227        subcc   %i1, 4, %g0             ! syscall 4, enter supervisor
228        bne     5f
229       
230        mov     %psr, %l4
231        or      %l4,SPARC_PSR_PS_MASK,%l4
232        mov     %l4, %psr               ! set previous supervisor %psr
233        nop; nop; nop
234        ba,a    9f
235       
2365:     
237        subcc   %i1, 5, %g0             ! syscall 5, enter user
238        bne     6f
239       
240        mov     %psr, %l4
241        andn    %l4,SPARC_PSR_PS_MASK,%l4
242        mov     %l4, %psr               ! clear previous supervisor %psr, return to user mode
243        nop; nop; nop
244        ba,a    9f
245       
2466:     
247        subcc   %i1, 6, %g0             ! syscall 6,  flush windows
248        bne     1f
249         nop
250       
251        ba,a    _irqcall_flush_windows
252       
2531:                                     
254        ta      0                       ! halt
2559:                                      ! leave
256        jmpl    %l2, %g0
257        rett    %l2 + 4
258
259/* =============================================== */
260       
261        /* call _irqcall through trap */
262        .global leonbare_enable_traps !void leonbare_enable_traps(unsigned long old_flags);
263leonbare_enable_traps:
264        set 3,%o1
265        retl
266        ta 0x2
267       
268/* =============================================== */
269       
270        /* call _irqcall through trap */
271        .global leonbare_disable_traps !unsigned long leonbare_disable_traps();
272leonbare_disable_traps:
273        set 2,%o1
274        retl
275        ta 0x2       
276
277/* =============================================== */
278       
279        /* flush all windows */
280        .global leonbare_flush_windows !void leonbare_flush_windows();
281leonbare_flush_windows:
282        set 6,%o1
283        retl
284         ta 0x2       
285
Note: See TracBrowser for help on using the repository browser.