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/etrap.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/etrap.S')
-rw-r--r-- | arch/sparc64/kernel/etrap.S | 104 |
1 files changed, 25 insertions, 79 deletions
diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S index b5f6bc52d917..4a0e01b14044 100644 --- a/arch/sparc64/kernel/etrap.S +++ b/arch/sparc64/kernel/etrap.S | |||
@@ -55,7 +55,31 @@ etrap_irq: | |||
55 | rd %y, %g3 | 55 | rd %y, %g3 |
56 | stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TNPC] | 56 | stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TNPC] |
57 | st %g3, [%g2 + STACKFRAME_SZ + PT_V9_Y] | 57 | st %g3, [%g2 + STACKFRAME_SZ + PT_V9_Y] |
58 | save %g2, -STACK_BIAS, %sp ! Ordering here is critical | 58 | |
59 | rdpr %cansave, %g1 | ||
60 | brnz,pt %g1, etrap_save | ||
61 | nop | ||
62 | |||
63 | rdpr %cwp, %g1 | ||
64 | add %g1, 2, %g1 | ||
65 | wrpr %g1, %cwp | ||
66 | be,pt %xcc, etrap_user_spill | ||
67 | mov ASI_AIUP, %g3 | ||
68 | |||
69 | rdpr %otherwin, %g3 | ||
70 | brz %g3, etrap_kernel_spill | ||
71 | mov ASI_AIUS, %g3 | ||
72 | |||
73 | etrap_user_spill: | ||
74 | |||
75 | wr %g3, 0x0, %asi | ||
76 | ldx [%g6 + TI_FLAGS], %g3 | ||
77 | and %g3, _TIF_32BIT, %g3 | ||
78 | brnz,pt %g3, etrap_user_spill_32bit | ||
79 | nop | ||
80 | ba,a,pt %xcc, etrap_user_spill_64bit | ||
81 | |||
82 | etrap_save: save %g2, -STACK_BIAS, %sp | ||
59 | mov %g6, %l6 | 83 | mov %g6, %l6 |
60 | 84 | ||
61 | bne,pn %xcc, 3f | 85 | bne,pn %xcc, 3f |
@@ -176,83 +200,5 @@ etraptl1: /* Save tstate/tpc/tnpc of TL 1-->4 and the tl register itself. | |||
176 | ba,pt %xcc, 1b | 200 | ba,pt %xcc, 1b |
177 | andcc %g1, TSTATE_PRIV, %g0 | 201 | andcc %g1, TSTATE_PRIV, %g0 |
178 | 202 | ||
179 | .align 64 | ||
180 | .globl scetrap | ||
181 | scetrap: | ||
182 | TRAP_LOAD_THREAD_REG(%g6, %g1) | ||
183 | rdpr %pil, %g2 | ||
184 | rdpr %tstate, %g1 | ||
185 | sllx %g2, 20, %g3 | ||
186 | andcc %g1, TSTATE_PRIV, %g0 | ||
187 | or %g1, %g3, %g1 | ||
188 | bne,pn %xcc, 1f | ||
189 | sub %sp, (STACKFRAME_SZ+TRACEREG_SZ-STACK_BIAS), %g2 | ||
190 | wrpr %g0, 7, %cleanwin | ||
191 | |||
192 | sllx %g1, 51, %g3 | ||
193 | sethi %hi(TASK_REGOFF), %g2 | ||
194 | or %g2, %lo(TASK_REGOFF), %g2 | ||
195 | brlz,pn %g3, 1f | ||
196 | add %g6, %g2, %g2 | ||
197 | wr %g0, 0, %fprs | ||
198 | 1: rdpr %tpc, %g3 | ||
199 | stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TSTATE] | ||
200 | |||
201 | rdpr %tnpc, %g1 | ||
202 | stx %g3, [%g2 + STACKFRAME_SZ + PT_V9_TPC] | ||
203 | stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TNPC] | ||
204 | save %g2, -STACK_BIAS, %sp ! Ordering here is critical | ||
205 | mov %g6, %l6 | ||
206 | bne,pn %xcc, 2f | ||
207 | mov ASI_P, %l7 | ||
208 | rdpr %canrestore, %g3 | ||
209 | |||
210 | rdpr %wstate, %g2 | ||
211 | wrpr %g0, 0, %canrestore | ||
212 | sll %g2, 3, %g2 | ||
213 | mov PRIMARY_CONTEXT, %l4 | ||
214 | wrpr %g3, 0, %otherwin | ||
215 | wrpr %g2, 0, %wstate | ||
216 | sethi %hi(sparc64_kern_pri_context), %g2 | ||
217 | ldx [%g2 + %lo(sparc64_kern_pri_context)], %g3 | ||
218 | stxa %g3, [%l4] ASI_DMMU | ||
219 | sethi %hi(KERNBASE), %l4 | ||
220 | flush %l4 | ||
221 | |||
222 | mov ASI_AIUS, %l7 | ||
223 | 2: mov %g4, %l4 | ||
224 | mov %g5, %l5 | ||
225 | add %g7, 0x4, %l2 | ||
226 | wrpr %g0, ETRAP_PSTATE1, %pstate | ||
227 | stx %g1, [%sp + PTREGS_OFF + PT_V9_G1] | ||
228 | stx %g2, [%sp + PTREGS_OFF + PT_V9_G2] | ||
229 | sllx %l7, 24, %l7 | ||
230 | |||
231 | stx %g3, [%sp + PTREGS_OFF + PT_V9_G3] | ||
232 | rdpr %cwp, %l0 | ||
233 | stx %g4, [%sp + PTREGS_OFF + PT_V9_G4] | ||
234 | stx %g5, [%sp + PTREGS_OFF + PT_V9_G5] | ||
235 | stx %g6, [%sp + PTREGS_OFF + PT_V9_G6] | ||
236 | stx %g7, [%sp + PTREGS_OFF + PT_V9_G7] | ||
237 | or %l7, %l0, %l7 | ||
238 | sethi %hi(TSTATE_RMO | TSTATE_PEF), %l0 | ||
239 | |||
240 | or %l7, %l0, %l7 | ||
241 | wrpr %l2, %tnpc | ||
242 | wrpr %l7, (TSTATE_PRIV | TSTATE_IE), %tstate | ||
243 | stx %i0, [%sp + PTREGS_OFF + PT_V9_I0] | ||
244 | stx %i1, [%sp + PTREGS_OFF + PT_V9_I1] | ||
245 | stx %i2, [%sp + PTREGS_OFF + PT_V9_I2] | ||
246 | stx %i3, [%sp + PTREGS_OFF + PT_V9_I3] | ||
247 | stx %i4, [%sp + PTREGS_OFF + PT_V9_I4] | ||
248 | |||
249 | stx %i5, [%sp + PTREGS_OFF + PT_V9_I5] | ||
250 | stx %i6, [%sp + PTREGS_OFF + PT_V9_I6] | ||
251 | mov %l6, %g6 | ||
252 | stx %i7, [%sp + PTREGS_OFF + PT_V9_I7] | ||
253 | LOAD_PER_CPU_BASE(%g5, %g6, %g4, %g3, %l1) | ||
254 | ldx [%g6 + TI_TASK], %g4 | ||
255 | done | ||
256 | |||
257 | #undef TASK_REGOFF | 203 | #undef TASK_REGOFF |
258 | #undef ETRAP_PSTATE1 | 204 | #undef ETRAP_PSTATE1 |