e9d3f8bf18a7bf59df8bb84ec412166d91137af0
[akaros.git] / kern / arch / sparc / trap_entry.S
1 #include <arch/sparc.h>
2 #include <arch/trap.h>
3 #include <arch/mmu.h>
4 #include <ros/memlayout.h>
5
6         .section        ".text"!,#alloc,#execinstr,#progbits
7         .align          4
8
9         .global tflush
10
11         .global handle_trap
12 handle_trap:
13
14         // At this point, %l1 = pc, %l2 = npc, and %l0/3/4/5
15         // might contain an active message.  so we only get %l6/%l7
16
17         // calculate stack pointer (-64 is space for window spill).
18         // sp = bootstacktop - core_id*KSTKSIZE - 64 - sizeof(trapframe_t).
19         // should you change this, make sure to change stack_fucked()
20         set     bootstacktop-64-SIZEOF_TRAPFRAME_T,%l6
21         mov     CORE_ID_REG,%l7
22         sll     %l7,KSTKSHIFT,%l7
23         sub     %l6,%l7,%l6
24
25         // see if trap came from kernel; if so, use that stack
26         // also preserve the psr, since we'll screw with the condition codes
27         mov     %psr,%l7
28         btst    PSR_PS,%l7
29         bne,a   1f
30          sub    %fp,64+SIZEOF_TRAPFRAME_T,%l6
31
32         // here is where we might do something with an active message
33
34 1:      mov     %l7,%l0
35         // At this point we may use %l3/4/5/7 as temporary regs
36
37         // is CWP valid?
38         and     %l0,PSR_CWP,%l4 ! %l4 = cwp
39         mov     1,%l7
40         sll     %l7,%l4,%l4     ! %l4 = 1 << cwp
41         mov     %wim,%l3
42         btst    %l3,%l4         ! (%wim & %l4) == 0?
43         be      2f
44          sethi  %hi(spill),%l7
45         jmpl    %lo(spill)+%l7,%l7      !no, spill a window
46          nop
47
48
49         // At this point we may use %o0-7, %l3/4/5/7 as temporary regs
50         // save the whole user context to a trapframe_t
51
52 2:      mov     %l0,%psr
53         mov     %l6,%sp
54         mov     %l1,%o1
55         mov     %l2,%o2
56         call    env_save_tf
57          add    %sp,64,%o0
58
59         // enable traps (but not interrupts)
60         or      %l0,PSR_PIL,%l3
61         wr      %l3,0,%psr
62         wr      %l3,PSR_ET,%psr
63
64         // spill all trapper's windows out to the stack.
65         // the 'save' may trap (triggering the spill),
66         // and if the stack is corrupted, the process may die
67         set     NWINDOWS,%g1
68         ld      [%g1],%g1
69         sub     %g1,1,%g2
70 5:      deccc   %g2
71         bne,a   5b
72 tflush:  save   %sp,0,%sp
73
74         // get our old cwp back (restore should NOT trap)
75         sub     %g1,1,%g2
76 6:      deccc   %g2
77         bne,a   6b
78          restore
79
80         // restore interrupt level
81         wr      %l0,PSR_ET,%psr
82
83         // call the handler and pass in the tf, message, and handler addr
84         add     %sp,64,%o0
85         call    trap
86          mov    %l5,%o1
87
88         // should never get here
89         unimp
90
91 // void env_save_tf(trapframe_t* tf, uint32_t trap_pc, uint32_t trap_npc)
92         .global env_save_tf
93 env_save_tf:
94
95         mov     %psr,%o4
96         st      %o4,[%o0+128]
97         st      %o1,[%o0+132]
98         st      %o2,[%o0+136]
99         mov     %wim,%o4
100         st      %o4,[%o0+140]
101         mov     %tbr,%o4
102         mov     %y,%o5
103         std     %o4,[%o0+144]
104
105         set     0x300,%o4
106         set     0x400,%o5
107         lda     [%o4] 4,%o4
108         lda     [%o5] 4,%o5
109         std     %o4,[%o0+152]
110         lda     [%g0] 2,%o4
111         mov     4,%o5
112         lda     [%o5] 2,%o5
113         std     %o4,[%o0+160]
114
115         std     %g0,[%o0+ 0]
116         std     %g2,[%o0+ 8]
117         std     %g4,[%o0+16]
118         std     %g6,[%o0+24]
119
120         mov     %o0,%g2
121
122         restore
123         std     %o0,[%g2+32]
124         std     %o2,[%g2+40]
125         std     %o4,[%g2+48]
126         std     %o6,[%g2+56]
127         std     %l0,[%g2+64]
128         std     %l2,[%g2+72]
129         std     %l4,[%g2+80]
130         std     %l6,[%g2+88]
131         std     %i0,[%g2+96]
132         std     %i2,[%g2+104]
133         std     %i4,[%g2+112]
134         std     %i6,[%g2+120]
135         save
136
137         retl
138          nop
139
140         .global env_pop_tf
141 env_pop_tf:
142
143         // disable interrupts.
144         // since wrpsr/rdpsr is interruptible, all interrupt handlers
145         // must restore the psr to its interrupt-time value
146         mov     %psr,%o1
147         or      %o1,PSR_PIL,%o2
148         wr      %o2,%psr
149
150         // spill all kernel windows to the stack
151         set     NWINDOWS,%g1
152         ld      [%g1],%g1
153         sub     %g1,1,%g2
154 5:      deccc   %g2
155         bne,a   5b
156          save   %sp,0,%sp
157
158         // get our old cwp back (restore should NOT trap)
159         sub     %g1,1,%g2
160 6:      deccc   %g2
161         bne,a   6b
162          restore
163         
164
165         // disable traps, and restore interrupt level
166         wr      %o2,PSR_ET,%psr
167         wr      %o1,PSR_ET,%psr
168
169         // if we did this right (and didn't get an NMI!),
170         // then (CWP+1) % NWINDOWS should be invalid.  fix that.
171         save
172         mov     %i0,%o0
173
174 #if 0
175         // is (CWP+1) % NWINDOWS valid?
176         and     %o1,PSR_CWP,%o2
177         set     NWINDOWS,%o1
178         ld      [%o1],%o1
179         add     %o2,1,%o2
180         cmp     %o2,%o1
181         be,a    3f
182          mov    0,%o2
183
184 3:      mov     1,%o3
185         sll     %o3,%o2,%o2             ! %o2 = 1 << ((CWP+1)%NWINDOWS)
186         mov     %wim,%o3
187         btst    %o2,%o3                 ! (%wim & %o2) == 0?
188         be      4f
189          nop
190
191         sethi   %hi(fill),%o3           ! gotta fill a window
192         jmpl    %lo(fill)+%o3,%o3
193          save   %o3,0,%l7               ! fill returns to %l7
194         restore
195
196 #endif
197
198         // restore user context
199 4:      mov     %o0,%g2
200         restore
201         ldd     [%g2+32],%o0
202         ldd     [%g2+40],%o2
203         ldd     [%g2+48],%o4
204         ldd     [%g2+56],%o6
205         ldd     [%g2+64],%l0
206         ldd     [%g2+72],%l2
207         ldd     [%g2+80],%l4
208         ldd     [%g2+88],%l6
209         ldd     [%g2+96],%i0
210         ldd     [%g2+104],%i2
211         ldd     [%g2+112],%i4
212         ldd     [%g2+120],%i6
213         save
214
215         ld      [%o0+ 4],%g1
216         ldd     [%o0+ 8],%g2
217         ldd     [%o0+16],%g4
218         ldd     [%o0+24],%g6
219
220         ldd     [%o0+128],%l0
221         mov     %psr,%l2
222         and     %l2,PSR_CWP,%l2
223         andn    %l0,PSR_CWP,%l0
224         wr      %l2,%l0,%psr
225
226         ldd     [%o0+136],%l2
227         !mov    %l3,%wim
228         ldd     [%o0+144],%l4
229         mov     %l4,%tbr
230         mov     %l5,%y
231         nop
232
233         jmp     %l1
234         rett    %l2
235
236         .global send_active_message_raw
237 send_active_message_raw:
238         retl
239          .word  0x81f00000