unbroke sparc front-end server protocol
[akaros.git] / kern / arch / sparc / spillfill.S
1 #include <arch/mmu.h>
2 #include <arch/sparc.h>
3 #include <arch/trap.h>
4 #include <ros/memlayout.h>
5
6 # before spilling a window, we must be certain
7 # that %sp is 8-byte aligned and the range [%sp,%sp+64)
8 # is validly mapped in
9 #define VALIDATE_STACK(reg1,reg2,misaligned,pagefault)  \
10         mov     %psr,reg1               ;\
11         btst    7,%sp                   ;\
12         bne     misaligned              ;\
13          mov    reg1,%psr               ;\
14         andn    %sp,0xFFF,reg1          ;\
15         or      reg1,0x400,reg1         ;\
16         lda     [reg1] 3,reg2           ;\
17         add     %sp,56,reg1             ;\
18         andn    reg1,0xFFF,reg1         ;\
19         or      reg1,0x400,reg1         ;\
20         lda     [reg1] 3,reg1           ;\
21         and     reg2,reg1,reg2          ;\
22         mov     %psr,reg1               ;\
23         btst    PTE_PTE,reg2            ;\
24         be      pagefault               ;\
25          mov    reg1,%psr
26
27 #define RETHROW_TRAP(func)              \
28         mov     %psr,%l7                ;\
29         and     %l7,PSR_CWP,%l4         ;\
30         set     NWINDOWS,%l3            ;\
31         ld      [%l3],%l3               ;\
32         dec     %l3                     ;\
33         cmp     %l3,%l4                 ;\
34         inc     %l4                     ;\
35         be,a    7f                      ;\
36          mov    0,%l4                   ;\
37 7:      mov     1,%l3                   ;\
38         sll     %l3,%l4,%l4             ;\
39         mov     %g0,%wim                ;\
40         set     bootstacktop-64-SIZEOF_TRAPFRAME_T,%sp  ;\
41         mov     CORE_ID_REG,%l5         ;\
42         sll     %l5,KSTKSHIFT,%l5       ;\
43         sub     %sp,%l5,%sp             ;\
44         btst    PSR_PS,%l7              ;\
45         bne,a   8f                      ;\
46          sub    %fp,64+SIZEOF_TRAPFRAME_T,%sp ;\
47 8:      mov     %l7,%psr                ;\
48         mov     %l1,%o1                 ;\
49         mov     %l2,%o2                 ;\
50         call    env_save_tf             ;\
51          add    %sp,64,%o0              ;\
52         mov     %l4,%wim                ;\
53         mov     %psr,%o0                ;\
54         wr      %o0,PSR_ET,%psr         ;\
55         call    func                    ;\
56          add    %sp,64,%o0
57
58         .global handle_window_overflow
59 handle_window_overflow:
60         sethi   %hi(spill),%l7
61         jmpl    %l7+%lo(spill),%l7
62          nop
63         jmp     %l1
64         rett    %l2
65
66         .global handle_window_underflow
67 handle_window_underflow:
68         sethi   %hi(fill),%l7
69         jmpl    %l7+%lo(fill),%l7
70          nop
71         jmp     %l1
72         rett    %l2
73
74 ! after handling a window trap, spill/fill will return to window_rett+8,
75 ! so these two nops are necessary!
76         .global window_rett
77 window_rett:
78         nop
79         nop
80         jmp     %l1
81         rett    %l2
82
83 ! preconditions:
84 ! WIM & (1<<CWP) != 0
85 ! link address in %l7
86 ! postconditions:
87 ! CWP same, but is now valid
88 ! %l0, %l1, %l2, %l5, %l6 have not changed 
89 .global spill
90 spill:
91         mov     %g1,%l4
92         mov     %wim,%l3
93         mov     %g0,%wim
94         and     %l3,1,%g1
95
96         ! this will be patched at runtime; 0 is really NWINDOWS-1
97 .global spill_patchme
98 spill_patchme:
99         sll     %g1,0,%g1
100
101         srl     %l3,1,%l3
102         or      %g1,%l3,%g1
103         mov     %g2,%l3
104
105         save
106         mov     %g1,%wim
107         VALIDATE_STACK(%g1,%g2,1f,2f)
108         std     %l0,[%sp+ 0]
109         std     %l2,[%sp+ 8]
110         std     %l4,[%sp+16]
111         std     %l6,[%sp+24]
112         std     %i0,[%sp+32]
113         std     %i2,[%sp+40]
114         std     %i4,[%sp+48]
115         std     %i6,[%sp+56]
116         restore
117
118         mov     %l3,%g2
119         jmp     %l7+8
120         mov     %l4,%g1
121
122 # spill failed!
123 1:      restore
124         RETHROW_TRAP(stack_misaligned)
125 2:      restore
126         RETHROW_TRAP(stack_pagefault)
127
128 ! preconditions:
129 ! WIM & (1<<((CWP+2)%NWINDOWS)) != 0
130 ! link address in %l7
131 ! postconditions:
132 ! CWP same, but (CWP+2)%NWINDOWS now valid
133 ! %l0, %l1, %l2, %l5, %l6 have not changed
134 .global fill 
135 fill:
136         mov     %g1,%l4
137         mov     %wim,%l3
138         mov     %g0,%wim
139
140         ! this will be patched at runtime; 0 is really NWINDOWS-1
141 .global fill_patchme
142 fill_patchme:
143         srl     %l3,0,%g1
144
145         and     %g1,1,%g1
146         sll     %l3,1,%l3
147         or      %g1,%l3,%g1
148
149         restore
150         restore
151         VALIDATE_STACK(%l0,%l1,3f,4f)
152         ldd     [%sp+ 0],%l0
153         ldd     [%sp+ 8],%l2
154         ldd     [%sp+16],%l4
155         ldd     [%sp+24],%l6
156         ldd     [%sp+32],%i0
157         ldd     [%sp+40],%i2
158         ldd     [%sp+48],%i4
159         ldd     [%sp+56],%i6
160         save
161         save
162         mov     %g1,%wim
163         nop
164
165         jmp     %l7+8
166         mov     %l4,%g1
167
168
169 # spill failed!
170 3:      save
171         save
172         RETHROW_TRAP(stack_misaligned)
173 4:      save
174         save
175         RETHROW_TRAP(stack_pagefault)