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 rirq_7win_patch1, rirq_7win_patch2, rirq_7win_patch3
27 .globl rirq_7win_patch4, rirq_7win_patch5
28 rirq_7win_patch1: srl %t_wim, 0x6, %twin_tmp2
29 rirq_7win_patch2: and %twin_tmp2, 0x7f, %twin_tmp2
30 rirq_7win_patch3: srl %g1, 7, %g2
31 rirq_7win_patch4: srl %g2, 6, %g2
32 rirq_7win_patch5: and %g1, 0x7f, %g1
33
34
35 .globl ret_irq_entry, rirq_patch1, rirq_patch2
36 .globl rirq_patch3, rirq_patch4, rirq_patch5
37 ret_irq_entry:
38 ld [%sp + REGWIN_SZ + PT_PSR], %t_psr
39 andcc %t_psr, PSR_PS, %g0
40 bne ret_irq_kernel
41 nop
42
43 ret_irq_user:
44 wr %t_psr, 0x0, %psr
45 WRITE_PAUSE
46
47 LOAD_CURRENT(twin_tmp2, twin_tmp1)
48 ld [%twin_tmp2 + THREAD_W_SAVED], %twin_tmp1
49 orcc %g0, %twin_tmp1, %g0
50 be ret_irq_nobufwins
51 nop
52
53
54 ENTER_SYSCALL
55
56 wr %t_psr, PSR_ET, %psr
57 WRITE_PAUSE
58
59 mov 1, %o1
60 call C_LABEL(try_to_clear_window_buffer)
61 add %sp, REGWIN_SZ, %o0
62
63
64 b ret_trap_entry
65 nop
66
67 ret_irq_nobufwins:
68
69
70
71 LOAD_PT_INS(sp)
72
73
74
75
76 ld [%twin_tmp2 + THREAD_UMASK], %twin_tmp1
77 orcc %g0, %twin_tmp1, %g0
78 bne ret_irq_userwins_ok
79 nop
80
81
82
83
84 ret_irq_pull_one_window:
85 rd %wim, %t_wim
86 sll %t_wim, 0x1, %twin_tmp1
87 rirq_patch1: srl %t_wim, 0x7, %twin_tmp2
88 or %twin_tmp2, %twin_tmp1, %twin_tmp2
89 rirq_patch2: and %twin_tmp2, 0xff, %twin_tmp2
90
91 wr %twin_tmp2, 0x0, %wim
92 WRITE_PAUSE
93
94
95
96
97
98 .globl C_LABEL(rirq_mmu_patchme)
99 C_LABEL(rirq_mmu_patchme): b C_LABEL(sun4c_reti_stackchk)
100 andcc %fp, 0x7, %g0
101
102 ret_irq_userwins_ok:
103 LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc)
104 or %t_pc, %t_npc, %g2
105 andcc %g2, 0x3, %g0
106 bne ret_irq_unaligned_pc
107 nop
108
109 LOAD_PT_YREG(sp, g1)
110 LOAD_PT_GLOBALS(sp)
111
112 wr %t_psr, 0x0, %psr
113 WRITE_PAUSE
114
115 jmp %t_pc
116 rett %t_npc
117
118 ret_irq_unaligned_pc:
119 add %sp, REGWIN_SZ, %o0
120 ld [%sp + REGWIN_SZ + PT_PC], %o1
121 ld [%sp + REGWIN_SZ + PT_NPC], %o2
122 ld [%sp + REGWIN_SZ + PT_PSR], %o3
123
124 wr %t_wim, 0x0, %wim ! or else...
125 WRITE_PAUSE
126
127
128 ENTER_SYSCALL
129
130 wr %t_psr, PSR_ET, %psr
131 WRITE_PAUSE
132
133 call C_LABEL(do_memaccess_unaligned)
134 nop
135
136
137 b ret_trap_entry
138 nop
139
140 ret_irq_kernel:
141 wr %t_psr, 0x0, %psr
142 WRITE_PAUSE
143
144
145 mov 2, %g1
146 sll %g1, %t_psr, %g1
147 rirq_patch3: srl %g1, 8, %g2
148 or %g1, %g2, %g1
149 rd %wim, %g2
150 andcc %g2, %g1, %g0
151 be 1f ! Nope, just return from the trap
152 nop
153
154
155 sll %g2, 0x1, %g1
156 rirq_patch4: srl %g2, 7, %g2
157 or %g1, %g2, %g1
158 rirq_patch5: and %g1, 0xff, %g1
159
160 wr %g1, 0x0, %wim
161 WRITE_PAUSE
162
163 restore %g0, %g0, %g0
164 LOAD_WINDOW(sp)
165 save %g0, %g0, %g0
166
167
168
169
170 1:
171 LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
172
173 wr %t_psr, 0x0, %psr
174 WRITE_PAUSE
175
176 jmp %t_pc
177 rett %t_npc
178
179 ret_irq_user_stack_is_bolixed:
180 wr %t_wim, 0x0, %wim
181 WRITE_PAUSE
182
183
184 ENTER_SYSCALL
185
186 wr %t_psr, PSR_ET, %psr
187 WRITE_PAUSE
188
189 call C_LABEL(window_ret_fault)
190 add %sp, REGWIN_SZ, %o0
191
192
193 b ret_trap_entry
194 nop
195
196 .globl C_LABEL(sun4c_reti_stackchk)
197 C_LABEL(sun4c_reti_stackchk):
198 be 1f
199 and %fp, 0xfff, %g1 ! delay slot
200
201 b ret_irq_user_stack_is_bolixed
202 nop
203
204
205 1:
206 add %g1, 0x38, %g1
207 sra %fp, 29, %g2
208 add %g2, 0x1, %g2
209 andncc %g2, 0x1, %g0
210 be 1f
211 andncc %g1, 0xff8, %g0
212
213
214 b ret_irq_user_stack_is_bolixed
215 nop
216
217 1:
218 be sun4c_reti_onepage
219 lda [%fp] ASI_PTE, %g2
220
221 sun4c_reti_twopages:
222 add %fp, 0x38, %g1
223 sra %g1, 29, %g2
224 add %g2, 0x1, %g2
225 andncc %g2, 0x1, %g0
226 be 1f
227 lda [%g1] ASI_PTE, %g2
228
229
230 b ret_irq_user_stack_is_bolixed
231 nop
232
233 1:
234 srl %g2, 29, %g2
235 andcc %g2, 0x4, %g0
236 bne sun4c_reti_onepage
237 lda [%fp] ASI_PTE, %g2
238
239
240 b ret_irq_user_stack_is_bolixed
241 nop
242
243 sun4c_reti_onepage:
244 srl %g2, 29, %g2
245 andcc %g2, 0x4, %g0
246 bne 1f
247 nop
248
249
250 b ret_irq_user_stack_is_bolixed
251 nop
252
253
254 1:
255 restore %g0, %g0, %g0
256
257 LOAD_WINDOW(sp)
258
259 save %g0, %g0, %g0
260 b ret_irq_userwins_ok
261 nop
262
263 .globl C_LABEL(srmmu_reti_stackchk)
264 C_LABEL(srmmu_reti_stackchk):
265 bne ret_irq_user_stack_is_bolixed
266 sethi %hi(KERNBASE), %g1
267 cmp %g1, %fp
268 bleu ret_irq_user_stack_is_bolixed
269 mov AC_M_SFSR, %g1
270 lda [%g1] ASI_M_MMUREGS, %g0
271
272 lda [%g0] ASI_M_MMUREGS, %g1
273 or %g1, 0x2, %g1
274 sta %g1, [%g0] ASI_M_MMUREGS
275
276 restore %g0, %g0, %g0
277
278 LOAD_WINDOW(sp)
279
280 save %g0, %g0, %g0
281
282 andn %g1, 0x2, %g1
283 sta %g1, [%g0] ASI_M_MMUREGS
284
285 mov AC_M_SFAR, %g2
286 lda [%g2] ASI_M_MMUREGS, %g2
287
288 mov AC_M_SFSR, %g1
289 lda [%g1] ASI_M_MMUREGS, %g1
290 andcc %g1, 0x2, %g0
291 bne ret_irq_user_stack_is_bolixed
292 nop
293
294 b ret_irq_userwins_ok
295 nop