1
2
3
4
5
6
7 #include <asm/cprefix.h>
8 #include <asm/page.h>
9 #include <asm/ptrace.h>
10 #include <asm/psr.h>
11 #include <asm/asi.h>
12 #include <asm/smp.h>
13 #include <asm/contregs.h>
14 #include <asm/winmacro.h>
15 #include <asm/asmmacro.h>
16
17 #define t_psr l0
18 #define t_pc l1
19 #define t_npc l2
20 #define t_wim l3
21 #define twin_tmp1 l4
22 #define twin_tmp2 l5
23 #define twin_tmp3 l6
24
25
26 .globl rtrap_7win_patch1, rtrap_7win_patch2, rtrap_7win_patch3
27 .globl rtrap_7win_patch4, rtrap_7win_patch5
28 rtrap_7win_patch1: srl %t_wim, 0x6, %twin_tmp2
29 rtrap_7win_patch2: and %twin_tmp2, 0x7f, %twin_tmp2
30 rtrap_7win_patch3: srl %g1, 7, %g2
31 rtrap_7win_patch4: srl %g2, 6, %g2
32 rtrap_7win_patch5: and %g1, 0x7f, %g1
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 .globl ret_trap_entry, rtrap_patch1, rtrap_patch2
48 .globl rtrap_patch3, rtrap_patch4, rtrap_patch5
49 ret_trap_entry:
50 ld [%sp + REGWIN_SZ + PT_PSR], %t_psr
51 andcc %t_psr, PSR_PS, %g0
52 bne ret_trap_kernel
53 nop
54
55 sethi %hi(C_LABEL(need_resched)), %twin_tmp1
56 ld [%twin_tmp1 + %lo(C_LABEL(need_resched))], %twin_tmp2
57
58 cmp %twin_tmp2, 0
59 be signal_p
60 nop
61
62 call C_LABEL(schedule)
63 nop
64
65
66
67
68
69 b ret_trap_entry
70 nop
71
72 signal_p:
73
74 LOAD_CURRENT(twin_tmp1, twin_tmp3)
75 set C_LABEL(init_task), %twin_tmp3
76 cmp %twin_tmp3, %twin_tmp1
77 be ret_trap_continue
78 nop
79
80 ld [%twin_tmp1 + TASK_SIGNAL], %twin_tmp2
81 ld [%twin_tmp1 + TASK_BLOCKED], %o0
82 andncc %twin_tmp2, %o0, %g0
83 be ret_trap_continue
84 nop
85
86 call C_LABEL(do_signal)
87 add %sp, REGWIN_SZ, %o1 ! pt_regs ptr
88
89
90 ret_trap_continue:
91 ld [%sp + REGWIN_SZ + PT_PSR], %t_psr
92 wr %t_psr, 0x0, %psr
93 WRITE_PAUSE
94
95 LOAD_CURRENT(twin_tmp2, twin_tmp1)
96 ld [%twin_tmp2 + THREAD_W_SAVED], %twin_tmp1
97 orcc %g0, %twin_tmp1, %g0
98 be ret_trap_nobufwins
99 nop
100
101 wr %t_psr, PSR_ET, %psr
102 WRITE_PAUSE
103
104 mov 1, %o1
105 call C_LABEL(try_to_clear_window_buffer)
106 add %sp, REGWIN_SZ, %o0
107
108 b ret_trap_entry
109 nop
110
111 ret_trap_nobufwins:
112
113
114
115 LOAD_PT_INS(sp)
116
117
118
119
120 ld [%twin_tmp2 + THREAD_UMASK], %twin_tmp1
121 orcc %g0, %twin_tmp1, %g0
122 bne ret_trap_userwins_ok
123 nop
124
125
126
127
128 ret_trap_pull_one_window:
129 rd %wim, %t_wim
130 sll %t_wim, 0x1, %twin_tmp1
131 rtrap_patch1: srl %t_wim, 0x7, %twin_tmp2
132 or %twin_tmp2, %twin_tmp1, %twin_tmp2
133 rtrap_patch2: and %twin_tmp2, 0xff, %twin_tmp2
134
135 wr %twin_tmp2, 0x0, %wim
136 WRITE_PAUSE
137
138
139
140
141
142 .globl C_LABEL(rtrap_mmu_patchme)
143 C_LABEL(rtrap_mmu_patchme): b C_LABEL(sun4c_rett_stackchk)
144 andcc %fp, 0x7, %g0
145
146 ret_trap_userwins_ok:
147 LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc)
148 or %t_pc, %t_npc, %g2
149 andcc %g2, 0x3, %g0
150 bne ret_trap_unaligned_pc
151 nop
152
153 LOAD_PT_YREG(sp, g1)
154 LOAD_PT_GLOBALS(sp)
155
156 LEAVE_SYSCALL
157
158 wr %t_psr, 0x0, %psr
159 WRITE_PAUSE
160
161 jmp %t_pc
162 rett %t_npc
163
164 ret_trap_unaligned_pc:
165 add %sp, REGWIN_SZ, %o0
166 ld [%sp + REGWIN_SZ + PT_PC], %o1
167 ld [%sp + REGWIN_SZ + PT_NPC], %o2
168 ld [%sp + REGWIN_SZ + PT_PSR], %o3
169
170 wr %t_wim, 0x0, %wim ! or else...
171 WRITE_PAUSE
172
173 wr %t_psr, PSR_ET, %psr
174 WRITE_PAUSE
175
176 call C_LABEL(do_memaccess_unaligned)
177 nop
178
179 b ret_trap_entry ! maybe signal posted
180 nop
181
182 ret_trap_kernel:
183 ld [%sp + REGWIN_SZ + PT_PSR], %t_psr
184 wr %t_psr, 0x0, %psr
185 WRITE_PAUSE
186
187
188 mov 2, %g1
189 sll %g1, %t_psr, %g1
190 rtrap_patch3: srl %g1, 8, %g2
191 or %g1, %g2, %g1
192 rd %wim, %g2
193 andcc %g2, %g1, %g0
194 be 1f ! Nope, just return from the trap
195 nop
196
197
198 sll %g2, 0x1, %g1
199 rtrap_patch4: srl %g2, 7, %g2
200 or %g1, %g2, %g1
201 rtrap_patch5: and %g1, 0xff, %g1
202
203 wr %g1, 0x0, %wim
204 WRITE_PAUSE
205
206 restore %g0, %g0, %g0
207 LOAD_WINDOW(sp)
208 save %g0, %g0, %g0
209
210
211
212
213 1:
214 LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
215
216 LEAVE_SYSCALL
217
218 wr %t_psr, 0x0, %psr
219 WRITE_PAUSE
220
221 jmp %t_pc
222 rett %t_npc
223
224 ret_trap_user_stack_is_bolixed:
225 wr %t_wim, 0x0, %wim
226 WRITE_PAUSE
227
228 wr %t_psr, PSR_ET, %psr
229 WRITE_PAUSE
230
231 call C_LABEL(window_ret_fault)
232 add %sp, REGWIN_SZ, %o0
233
234 b ret_trap_entry
235 nop
236
237 .globl C_LABEL(sun4c_rett_stackchk)
238 C_LABEL(sun4c_rett_stackchk):
239 be 1f
240 and %fp, 0xfff, %g1 ! delay slot
241
242 b ret_trap_user_stack_is_bolixed
243 nop
244
245
246 1:
247 add %g1, 0x38, %g1
248 sra %fp, 29, %g2
249 add %g2, 0x1, %g2
250 andncc %g2, 0x1, %g0
251 be 1f
252 andncc %g1, 0xff8, %g0
253
254
255 b ret_trap_user_stack_is_bolixed
256 nop
257
258 1:
259 be sun4c_rett_onepage
260 lda [%fp] ASI_PTE, %g2
261
262 sun4c_rett_twopages:
263 add %fp, 0x38, %g1
264 sra %g1, 29, %g2
265 add %g2, 0x1, %g2
266 andncc %g2, 0x1, %g0
267 be 1f
268 lda [%g1] ASI_PTE, %g2
269
270
271 b ret_trap_user_stack_is_bolixed
272 nop
273
274 1:
275 srl %g2, 29, %g2
276 andcc %g2, 0x4, %g0
277 bne sun4c_rett_onepage
278 lda [%fp] ASI_PTE, %g2
279
280
281 b ret_trap_user_stack_is_bolixed
282 nop
283
284 sun4c_rett_onepage:
285 srl %g2, 29, %g2
286 andcc %g2, 0x4, %g0
287 bne 1f
288 nop
289
290
291 b ret_trap_user_stack_is_bolixed
292 nop
293
294
295 1:
296 restore %g0, %g0, %g0
297
298 LOAD_WINDOW(sp)
299
300 save %g0, %g0, %g0
301 b ret_trap_userwins_ok
302 nop
303
304 .globl C_LABEL(srmmu_rett_stackchk)
305 C_LABEL(srmmu_rett_stackchk):
306 bne ret_trap_user_stack_is_bolixed
307 sethi %hi(KERNBASE), %g1
308 cmp %g1, %fp
309 bleu ret_trap_user_stack_is_bolixed
310 mov AC_M_SFSR, %g1
311 lda [%g1] ASI_M_MMUREGS, %g0
312
313 lda [%g0] ASI_M_MMUREGS, %g1
314 or %g1, 0x2, %g1
315 sta %g1, [%g0] ASI_M_MMUREGS
316
317 restore %g0, %g0, %g0
318
319 LOAD_WINDOW(sp)
320
321 save %g0, %g0, %g0
322
323 andn %g1, 0x2, %g1
324 sta %g1, [%g0] ASI_M_MMUREGS
325
326 mov AC_M_SFAR, %g2
327 lda [%g2] ASI_M_MMUREGS, %g2
328
329 mov AC_M_SFSR, %g1
330 lda [%g1] ASI_M_MMUREGS, %g1
331 andcc %g1, 0x2, %g0
332 bne ret_trap_user_stack_is_bolixed
333 nop
334
335 b ret_trap_userwins_ok
336 nop