aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/rtrap.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/rtrap.S')
-rw-r--r--arch/sparc64/kernel/rtrap.S115
1 files changed, 105 insertions, 10 deletions
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index b80eba0081ca..7130e866f935 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -223,12 +223,26 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
223 ldx [%sp + PTREGS_OFF + PT_V9_G3], %g3 223 ldx [%sp + PTREGS_OFF + PT_V9_G3], %g3
224 ldx [%sp + PTREGS_OFF + PT_V9_G4], %g4 224 ldx [%sp + PTREGS_OFF + PT_V9_G4], %g4
225 ldx [%sp + PTREGS_OFF + PT_V9_G5], %g5 225 ldx [%sp + PTREGS_OFF + PT_V9_G5], %g5
226 mov TSB_REG, %g6 226 brz,pt %l3, 1f
227 brnz,a,pn %l3, 1f 227 mov %g6, %l2
228 ldxa [%g6] ASI_IMMU, %g5 228
2291: ldx [%sp + PTREGS_OFF + PT_V9_G6], %g6 229 /* Must do this before thread reg is clobbered below. */
230 LOAD_PER_CPU_BASE(%g5, %g6, %i0, %i1, %i2)
2311:
232 ldx [%sp + PTREGS_OFF + PT_V9_G6], %g6
230 ldx [%sp + PTREGS_OFF + PT_V9_G7], %g7 233 ldx [%sp + PTREGS_OFF + PT_V9_G7], %g7
231 wrpr %g0, RTRAP_PSTATE_AG_IRQOFF, %pstate 234
235 /* Normal globals are restored, go to trap globals. */
236661: wrpr %g0, RTRAP_PSTATE_AG_IRQOFF, %pstate
237 nop
238 .section .sun4v_2insn_patch, "ax"
239 .word 661b
240 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
241 SET_GL(1)
242 .previous
243
244 mov %l2, %g6
245
232 ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0 246 ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0
233 ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1 247 ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1
234 248
@@ -252,27 +266,108 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
252 266
253 brnz,pn %l3, kern_rtt 267 brnz,pn %l3, kern_rtt
254 mov PRIMARY_CONTEXT, %l7 268 mov PRIMARY_CONTEXT, %l7
255 ldxa [%l7 + %l7] ASI_DMMU, %l0 269
270661: ldxa [%l7 + %l7] ASI_DMMU, %l0
271 .section .sun4v_1insn_patch, "ax"
272 .word 661b
273 ldxa [%l7 + %l7] ASI_MMU, %l0
274 .previous
275
256 sethi %hi(sparc64_kern_pri_nuc_bits), %l1 276 sethi %hi(sparc64_kern_pri_nuc_bits), %l1
257 ldx [%l1 + %lo(sparc64_kern_pri_nuc_bits)], %l1 277 ldx [%l1 + %lo(sparc64_kern_pri_nuc_bits)], %l1
258 or %l0, %l1, %l0 278 or %l0, %l1, %l0
259 stxa %l0, [%l7] ASI_DMMU 279
260 flush %g6 280661: stxa %l0, [%l7] ASI_DMMU
281 .section .sun4v_1insn_patch, "ax"
282 .word 661b
283 stxa %l0, [%l7] ASI_MMU
284 .previous
285
286 sethi %hi(KERNBASE), %l7
287 flush %l7
261 rdpr %wstate, %l1 288 rdpr %wstate, %l1
262 rdpr %otherwin, %l2 289 rdpr %otherwin, %l2
263 srl %l1, 3, %l1 290 srl %l1, 3, %l1
264 291
265 wrpr %l2, %g0, %canrestore 292 wrpr %l2, %g0, %canrestore
266 wrpr %l1, %g0, %wstate 293 wrpr %l1, %g0, %wstate
267 wrpr %g0, %g0, %otherwin 294 brnz,pt %l2, user_rtt_restore
295 wrpr %g0, %g0, %otherwin
296
297 ldx [%g6 + TI_FLAGS], %g3
298 wr %g0, ASI_AIUP, %asi
299 rdpr %cwp, %g1
300 andcc %g3, _TIF_32BIT, %g0
301 sub %g1, 1, %g1
302 bne,pt %xcc, user_rtt_fill_32bit
303 wrpr %g1, %cwp
304 ba,a,pt %xcc, user_rtt_fill_64bit
305
306user_rtt_fill_fixup:
307 rdpr %cwp, %g1
308 add %g1, 1, %g1
309 wrpr %g1, 0x0, %cwp
310
311 rdpr %wstate, %g2
312 sll %g2, 3, %g2
313 wrpr %g2, 0x0, %wstate
314
315 /* We know %canrestore and %otherwin are both zero. */
316
317 sethi %hi(sparc64_kern_pri_context), %g2
318 ldx [%g2 + %lo(sparc64_kern_pri_context)], %g2
319 mov PRIMARY_CONTEXT, %g1
320
321661: stxa %g2, [%g1] ASI_DMMU
322 .section .sun4v_1insn_patch, "ax"
323 .word 661b
324 stxa %g2, [%g1] ASI_MMU
325 .previous
326
327 sethi %hi(KERNBASE), %g1
328 flush %g1
329
330 or %g4, FAULT_CODE_WINFIXUP, %g4
331 stb %g4, [%g6 + TI_FAULT_CODE]
332 stx %g5, [%g6 + TI_FAULT_ADDR]
333
334 mov %g6, %l1
335 wrpr %g0, 0x0, %tl
336
337661: nop
338 .section .sun4v_1insn_patch, "ax"
339 .word 661b
340 SET_GL(0)
341 .previous
342
343 wrpr %g0, RTRAP_PSTATE, %pstate
344
345 mov %l1, %g6
346 ldx [%g6 + TI_TASK], %g4
347 LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
348 call do_sparc64_fault
349 add %sp, PTREGS_OFF, %o0
350 ba,pt %xcc, rtrap
351 nop
352
353user_rtt_pre_restore:
354 add %g1, 1, %g1
355 wrpr %g1, 0x0, %cwp
356
357user_rtt_restore:
268 restore 358 restore
269 rdpr %canrestore, %g1 359 rdpr %canrestore, %g1
270 wrpr %g1, 0x0, %cleanwin 360 wrpr %g1, 0x0, %cleanwin
271 retry 361 retry
272 nop 362 nop
273 363
274kern_rtt: restore 364kern_rtt: rdpr %canrestore, %g1
365 brz,pn %g1, kern_rtt_fill
366 nop
367kern_rtt_restore:
368 restore
275 retry 369 retry
370
276to_kernel: 371to_kernel:
277#ifdef CONFIG_PREEMPT 372#ifdef CONFIG_PREEMPT
278 ldsw [%g6 + TI_PRE_COUNT], %l5 373 ldsw [%g6 + TI_PRE_COUNT], %l5