diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-04 03:10:01 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:11:36 -0500 |
commit | 314ef6859750b6539eac48d78059bb7986f29cb1 (patch) | |
tree | 26c7da386349c1cf377225356e1012ae62da6f07 /arch/sparc64/kernel/rtrap.S | |
parent | ffe483d55229fadbaf4cc7316d47024a24ecd1a2 (diff) |
[SPARC64]: Refine register window trap handling.
When saving and restoing trap state, do the window spill/fill
handling inline so that we never trap deeper than 2 trap levels.
This is important for chips like Niagara.
The window fixup code is massively simplified, and many more
improvements are now possible.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/rtrap.S')
-rw-r--r-- | arch/sparc64/kernel/rtrap.S | 58 |
1 files changed, 56 insertions, 2 deletions
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index 61bd45e7697e..ecfbbdc56125 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S | |||
@@ -267,15 +267,69 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 | |||
267 | 267 | ||
268 | wrpr %l2, %g0, %canrestore | 268 | wrpr %l2, %g0, %canrestore |
269 | wrpr %l1, %g0, %wstate | 269 | wrpr %l1, %g0, %wstate |
270 | wrpr %g0, %g0, %otherwin | 270 | brnz,pt %l2, user_rtt_restore |
271 | wrpr %g0, %g0, %otherwin | ||
272 | |||
273 | ldx [%g6 + TI_FLAGS], %g3 | ||
274 | wr %g0, ASI_AIUP, %asi | ||
275 | rdpr %cwp, %g1 | ||
276 | andcc %g3, _TIF_32BIT, %g0 | ||
277 | sub %g1, 1, %g1 | ||
278 | bne,pt %xcc, user_rtt_fill_32bit | ||
279 | wrpr %g1, %cwp | ||
280 | ba,a,pt %xcc, user_rtt_fill_64bit | ||
281 | |||
282 | user_rtt_fill_fixup: | ||
283 | rdpr %cwp, %g1 | ||
284 | add %g1, 1, %g1 | ||
285 | wrpr %g1, 0x0, %cwp | ||
286 | |||
287 | rdpr %wstate, %g2 | ||
288 | sll %g2, 3, %g2 | ||
289 | wrpr %g2, 0x0, %wstate | ||
290 | |||
291 | /* We know %canrestore and %otherwin are both zero. */ | ||
292 | |||
293 | sethi %hi(sparc64_kern_pri_context), %g2 | ||
294 | ldx [%g2 + %lo(sparc64_kern_pri_context)], %g2 | ||
295 | mov PRIMARY_CONTEXT, %g1 | ||
296 | stxa %g2, [%g1] ASI_DMMU | ||
297 | sethi %hi(KERNBASE), %g1 | ||
298 | flush %g1 | ||
299 | |||
300 | or %g4, FAULT_CODE_WINFIXUP, %g4 | ||
301 | stb %g4, [%g6 + TI_FAULT_CODE] | ||
302 | stx %g5, [%g6 + TI_FAULT_ADDR] | ||
303 | |||
304 | mov %g6, %l1 | ||
305 | wrpr %g0, 0x0, %tl | ||
306 | wrpr %g0, RTRAP_PSTATE, %pstate | ||
307 | mov %l1, %g6 | ||
308 | ldx [%g6 + TI_TASK], %g4 | ||
309 | LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3) | ||
310 | call do_sparc64_fault | ||
311 | add %sp, PTREGS_OFF, %o0 | ||
312 | ba,pt %xcc, rtrap | ||
313 | nop | ||
314 | |||
315 | user_rtt_pre_restore: | ||
316 | add %g1, 1, %g1 | ||
317 | wrpr %g1, 0x0, %cwp | ||
318 | |||
319 | user_rtt_restore: | ||
271 | restore | 320 | restore |
272 | rdpr %canrestore, %g1 | 321 | rdpr %canrestore, %g1 |
273 | wrpr %g1, 0x0, %cleanwin | 322 | wrpr %g1, 0x0, %cleanwin |
274 | retry | 323 | retry |
275 | nop | 324 | nop |
276 | 325 | ||
277 | kern_rtt: restore | 326 | kern_rtt: rdpr %canrestore, %g1 |
327 | brz,pn %g1, kern_rtt_fill | ||
328 | nop | ||
329 | kern_rtt_restore: | ||
330 | restore | ||
278 | retry | 331 | retry |
332 | |||
279 | to_kernel: | 333 | to_kernel: |
280 | #ifdef CONFIG_PREEMPT | 334 | #ifdef CONFIG_PREEMPT |
281 | ldsw [%g6 + TI_PRE_COUNT], %l5 | 335 | ldsw [%g6 + TI_PRE_COUNT], %l5 |