diff options
Diffstat (limited to 'arch/sparc64/kernel/etrap.S')
-rw-r--r-- | arch/sparc64/kernel/etrap.S | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S new file mode 100644 index 000000000000..50d2af1d98ae --- /dev/null +++ b/arch/sparc64/kernel/etrap.S | |||
@@ -0,0 +1,301 @@ | |||
1 | /* $Id: etrap.S,v 1.46 2002/02/09 19:49:30 davem Exp $ | ||
2 | * etrap.S: Preparing for entry into the kernel on Sparc V9. | ||
3 | * | ||
4 | * Copyright (C) 1996, 1997 David S. Miller (davem@caip.rutgers.edu) | ||
5 | * Copyright (C) 1997, 1998, 1999 Jakub Jelinek (jj@ultra.linux.cz) | ||
6 | */ | ||
7 | |||
8 | #include <linux/config.h> | ||
9 | |||
10 | #include <asm/asi.h> | ||
11 | #include <asm/pstate.h> | ||
12 | #include <asm/ptrace.h> | ||
13 | #include <asm/page.h> | ||
14 | #include <asm/spitfire.h> | ||
15 | #include <asm/head.h> | ||
16 | #include <asm/processor.h> | ||
17 | #include <asm/mmu.h> | ||
18 | |||
19 | #define TASK_REGOFF (THREAD_SIZE-TRACEREG_SZ-STACKFRAME_SZ) | ||
20 | #define ETRAP_PSTATE1 (PSTATE_RMO | PSTATE_PRIV) | ||
21 | #define ETRAP_PSTATE2 \ | ||
22 | (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV | PSTATE_IE) | ||
23 | |||
24 | /* | ||
25 | * On entry, %g7 is return address - 0x4. | ||
26 | * %g4 and %g5 will be preserved %l4 and %l5 respectively. | ||
27 | */ | ||
28 | |||
29 | .text | ||
30 | .align 64 | ||
31 | .globl etrap, etrap_irq, etraptl1 | ||
32 | etrap: rdpr %pil, %g2 | ||
33 | etrap_irq: | ||
34 | rdpr %tstate, %g1 | ||
35 | sllx %g2, 20, %g3 | ||
36 | andcc %g1, TSTATE_PRIV, %g0 | ||
37 | or %g1, %g3, %g1 | ||
38 | bne,pn %xcc, 1f | ||
39 | sub %sp, STACKFRAME_SZ+TRACEREG_SZ-STACK_BIAS, %g2 | ||
40 | wrpr %g0, 7, %cleanwin | ||
41 | |||
42 | sethi %hi(TASK_REGOFF), %g2 | ||
43 | sethi %hi(TSTATE_PEF), %g3 | ||
44 | or %g2, %lo(TASK_REGOFF), %g2 | ||
45 | and %g1, %g3, %g3 | ||
46 | brnz,pn %g3, 1f | ||
47 | add %g6, %g2, %g2 | ||
48 | wr %g0, 0, %fprs | ||
49 | 1: rdpr %tpc, %g3 | ||
50 | |||
51 | stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TSTATE] | ||
52 | rdpr %tnpc, %g1 | ||
53 | stx %g3, [%g2 + STACKFRAME_SZ + PT_V9_TPC] | ||
54 | rd %y, %g3 | ||
55 | stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TNPC] | ||
56 | st %g3, [%g2 + STACKFRAME_SZ + PT_V9_Y] | ||
57 | save %g2, -STACK_BIAS, %sp ! Ordering here is critical | ||
58 | mov %g6, %l6 | ||
59 | |||
60 | bne,pn %xcc, 3f | ||
61 | mov PRIMARY_CONTEXT, %l4 | ||
62 | rdpr %canrestore, %g3 | ||
63 | rdpr %wstate, %g2 | ||
64 | wrpr %g0, 0, %canrestore | ||
65 | sll %g2, 3, %g2 | ||
66 | mov 1, %l5 | ||
67 | stb %l5, [%l6 + TI_FPDEPTH] | ||
68 | |||
69 | wrpr %g3, 0, %otherwin | ||
70 | wrpr %g2, 0, %wstate | ||
71 | cplus_etrap_insn_1: | ||
72 | sethi %hi(0), %g3 | ||
73 | sllx %g3, 32, %g3 | ||
74 | cplus_etrap_insn_2: | ||
75 | sethi %hi(0), %g2 | ||
76 | or %g3, %g2, %g3 | ||
77 | stxa %g3, [%l4] ASI_DMMU | ||
78 | flush %l6 | ||
79 | wr %g0, ASI_AIUS, %asi | ||
80 | 2: wrpr %g0, 0x0, %tl | ||
81 | mov %g4, %l4 | ||
82 | mov %g5, %l5 | ||
83 | |||
84 | mov %g7, %l2 | ||
85 | wrpr %g0, ETRAP_PSTATE1, %pstate | ||
86 | stx %g1, [%sp + PTREGS_OFF + PT_V9_G1] | ||
87 | stx %g2, [%sp + PTREGS_OFF + PT_V9_G2] | ||
88 | stx %g3, [%sp + PTREGS_OFF + PT_V9_G3] | ||
89 | stx %g4, [%sp + PTREGS_OFF + PT_V9_G4] | ||
90 | stx %g5, [%sp + PTREGS_OFF + PT_V9_G5] | ||
91 | stx %g6, [%sp + PTREGS_OFF + PT_V9_G6] | ||
92 | |||
93 | stx %g7, [%sp + PTREGS_OFF + PT_V9_G7] | ||
94 | stx %i0, [%sp + PTREGS_OFF + PT_V9_I0] | ||
95 | stx %i1, [%sp + PTREGS_OFF + PT_V9_I1] | ||
96 | stx %i2, [%sp + PTREGS_OFF + PT_V9_I2] | ||
97 | stx %i3, [%sp + PTREGS_OFF + PT_V9_I3] | ||
98 | stx %i4, [%sp + PTREGS_OFF + PT_V9_I4] | ||
99 | stx %i5, [%sp + PTREGS_OFF + PT_V9_I5] | ||
100 | |||
101 | stx %i6, [%sp + PTREGS_OFF + PT_V9_I6] | ||
102 | stx %i7, [%sp + PTREGS_OFF + PT_V9_I7] | ||
103 | wrpr %g0, ETRAP_PSTATE2, %pstate | ||
104 | mov %l6, %g6 | ||
105 | #ifdef CONFIG_SMP | ||
106 | mov TSB_REG, %g3 | ||
107 | ldxa [%g3] ASI_IMMU, %g5 | ||
108 | #endif | ||
109 | jmpl %l2 + 0x4, %g0 | ||
110 | ldx [%g6 + TI_TASK], %g4 | ||
111 | |||
112 | 3: ldub [%l6 + TI_FPDEPTH], %l5 | ||
113 | add %l6, TI_FPSAVED + 1, %l4 | ||
114 | srl %l5, 1, %l3 | ||
115 | add %l5, 2, %l5 | ||
116 | stb %l5, [%l6 + TI_FPDEPTH] | ||
117 | ba,pt %xcc, 2b | ||
118 | stb %g0, [%l4 + %l3] | ||
119 | nop | ||
120 | |||
121 | etraptl1: /* Save tstate/tpc/tnpc of TL 1-->4 and the tl register itself. | ||
122 | * We place this right after pt_regs on the trap stack. | ||
123 | * The layout is: | ||
124 | * 0x00 TL1's TSTATE | ||
125 | * 0x08 TL1's TPC | ||
126 | * 0x10 TL1's TNPC | ||
127 | * 0x18 TL1's TT | ||
128 | * ... | ||
129 | * 0x58 TL4's TT | ||
130 | * 0x60 TL | ||
131 | */ | ||
132 | sub %sp, ((4 * 8) * 4) + 8, %g2 | ||
133 | rdpr %tl, %g1 | ||
134 | |||
135 | wrpr %g0, 1, %tl | ||
136 | rdpr %tstate, %g3 | ||
137 | stx %g3, [%g2 + STACK_BIAS + 0x00] | ||
138 | rdpr %tpc, %g3 | ||
139 | stx %g3, [%g2 + STACK_BIAS + 0x08] | ||
140 | rdpr %tnpc, %g3 | ||
141 | stx %g3, [%g2 + STACK_BIAS + 0x10] | ||
142 | rdpr %tt, %g3 | ||
143 | stx %g3, [%g2 + STACK_BIAS + 0x18] | ||
144 | |||
145 | wrpr %g0, 2, %tl | ||
146 | rdpr %tstate, %g3 | ||
147 | stx %g3, [%g2 + STACK_BIAS + 0x20] | ||
148 | rdpr %tpc, %g3 | ||
149 | stx %g3, [%g2 + STACK_BIAS + 0x28] | ||
150 | rdpr %tnpc, %g3 | ||
151 | stx %g3, [%g2 + STACK_BIAS + 0x30] | ||
152 | rdpr %tt, %g3 | ||
153 | stx %g3, [%g2 + STACK_BIAS + 0x38] | ||
154 | |||
155 | wrpr %g0, 3, %tl | ||
156 | rdpr %tstate, %g3 | ||
157 | stx %g3, [%g2 + STACK_BIAS + 0x40] | ||
158 | rdpr %tpc, %g3 | ||
159 | stx %g3, [%g2 + STACK_BIAS + 0x48] | ||
160 | rdpr %tnpc, %g3 | ||
161 | stx %g3, [%g2 + STACK_BIAS + 0x50] | ||
162 | rdpr %tt, %g3 | ||
163 | stx %g3, [%g2 + STACK_BIAS + 0x58] | ||
164 | |||
165 | wrpr %g0, 4, %tl | ||
166 | rdpr %tstate, %g3 | ||
167 | stx %g3, [%g2 + STACK_BIAS + 0x60] | ||
168 | rdpr %tpc, %g3 | ||
169 | stx %g3, [%g2 + STACK_BIAS + 0x68] | ||
170 | rdpr %tnpc, %g3 | ||
171 | stx %g3, [%g2 + STACK_BIAS + 0x70] | ||
172 | rdpr %tt, %g3 | ||
173 | stx %g3, [%g2 + STACK_BIAS + 0x78] | ||
174 | |||
175 | wrpr %g1, %tl | ||
176 | stx %g1, [%g2 + STACK_BIAS + 0x80] | ||
177 | |||
178 | rdpr %tstate, %g1 | ||
179 | sub %g2, STACKFRAME_SZ + TRACEREG_SZ - STACK_BIAS, %g2 | ||
180 | ba,pt %xcc, 1b | ||
181 | andcc %g1, TSTATE_PRIV, %g0 | ||
182 | |||
183 | .align 64 | ||
184 | .globl scetrap | ||
185 | scetrap: rdpr %pil, %g2 | ||
186 | rdpr %tstate, %g1 | ||
187 | sllx %g2, 20, %g3 | ||
188 | andcc %g1, TSTATE_PRIV, %g0 | ||
189 | or %g1, %g3, %g1 | ||
190 | bne,pn %xcc, 1f | ||
191 | sub %sp, (STACKFRAME_SZ+TRACEREG_SZ-STACK_BIAS), %g2 | ||
192 | wrpr %g0, 7, %cleanwin | ||
193 | |||
194 | sllx %g1, 51, %g3 | ||
195 | sethi %hi(TASK_REGOFF), %g2 | ||
196 | or %g2, %lo(TASK_REGOFF), %g2 | ||
197 | brlz,pn %g3, 1f | ||
198 | add %g6, %g2, %g2 | ||
199 | wr %g0, 0, %fprs | ||
200 | 1: rdpr %tpc, %g3 | ||
201 | stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TSTATE] | ||
202 | |||
203 | rdpr %tnpc, %g1 | ||
204 | stx %g3, [%g2 + STACKFRAME_SZ + PT_V9_TPC] | ||
205 | stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TNPC] | ||
206 | save %g2, -STACK_BIAS, %sp ! Ordering here is critical | ||
207 | mov %g6, %l6 | ||
208 | bne,pn %xcc, 2f | ||
209 | mov ASI_P, %l7 | ||
210 | rdpr %canrestore, %g3 | ||
211 | |||
212 | rdpr %wstate, %g2 | ||
213 | wrpr %g0, 0, %canrestore | ||
214 | sll %g2, 3, %g2 | ||
215 | mov PRIMARY_CONTEXT, %l4 | ||
216 | wrpr %g3, 0, %otherwin | ||
217 | wrpr %g2, 0, %wstate | ||
218 | cplus_etrap_insn_3: | ||
219 | sethi %hi(0), %g3 | ||
220 | sllx %g3, 32, %g3 | ||
221 | cplus_etrap_insn_4: | ||
222 | sethi %hi(0), %g2 | ||
223 | or %g3, %g2, %g3 | ||
224 | stxa %g3, [%l4] ASI_DMMU | ||
225 | flush %l6 | ||
226 | |||
227 | mov ASI_AIUS, %l7 | ||
228 | 2: mov %g4, %l4 | ||
229 | mov %g5, %l5 | ||
230 | add %g7, 0x4, %l2 | ||
231 | wrpr %g0, ETRAP_PSTATE1, %pstate | ||
232 | stx %g1, [%sp + PTREGS_OFF + PT_V9_G1] | ||
233 | stx %g2, [%sp + PTREGS_OFF + PT_V9_G2] | ||
234 | sllx %l7, 24, %l7 | ||
235 | |||
236 | stx %g3, [%sp + PTREGS_OFF + PT_V9_G3] | ||
237 | rdpr %cwp, %l0 | ||
238 | stx %g4, [%sp + PTREGS_OFF + PT_V9_G4] | ||
239 | stx %g5, [%sp + PTREGS_OFF + PT_V9_G5] | ||
240 | stx %g6, [%sp + PTREGS_OFF + PT_V9_G6] | ||
241 | stx %g7, [%sp + PTREGS_OFF + PT_V9_G7] | ||
242 | or %l7, %l0, %l7 | ||
243 | sethi %hi(TSTATE_RMO | TSTATE_PEF), %l0 | ||
244 | |||
245 | or %l7, %l0, %l7 | ||
246 | wrpr %l2, %tnpc | ||
247 | wrpr %l7, (TSTATE_PRIV | TSTATE_IE), %tstate | ||
248 | stx %i0, [%sp + PTREGS_OFF + PT_V9_I0] | ||
249 | stx %i1, [%sp + PTREGS_OFF + PT_V9_I1] | ||
250 | stx %i2, [%sp + PTREGS_OFF + PT_V9_I2] | ||
251 | stx %i3, [%sp + PTREGS_OFF + PT_V9_I3] | ||
252 | stx %i4, [%sp + PTREGS_OFF + PT_V9_I4] | ||
253 | |||
254 | stx %i5, [%sp + PTREGS_OFF + PT_V9_I5] | ||
255 | stx %i6, [%sp + PTREGS_OFF + PT_V9_I6] | ||
256 | mov %l6, %g6 | ||
257 | stx %i7, [%sp + PTREGS_OFF + PT_V9_I7] | ||
258 | #ifdef CONFIG_SMP | ||
259 | mov TSB_REG, %g3 | ||
260 | ldxa [%g3] ASI_IMMU, %g5 | ||
261 | #endif | ||
262 | ldx [%g6 + TI_TASK], %g4 | ||
263 | done | ||
264 | |||
265 | #undef TASK_REGOFF | ||
266 | #undef ETRAP_PSTATE1 | ||
267 | |||
268 | cplus_einsn_1: | ||
269 | sethi %uhi(CTX_CHEETAH_PLUS_NUC), %g3 | ||
270 | cplus_einsn_2: | ||
271 | sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2 | ||
272 | |||
273 | .globl cheetah_plus_patch_etrap | ||
274 | cheetah_plus_patch_etrap: | ||
275 | /* We configure the dTLB512_0 for 4MB pages and the | ||
276 | * dTLB512_1 for 8K pages when in context zero. | ||
277 | */ | ||
278 | sethi %hi(cplus_einsn_1), %o0 | ||
279 | sethi %hi(cplus_etrap_insn_1), %o2 | ||
280 | lduw [%o0 + %lo(cplus_einsn_1)], %o1 | ||
281 | or %o2, %lo(cplus_etrap_insn_1), %o2 | ||
282 | stw %o1, [%o2] | ||
283 | flush %o2 | ||
284 | sethi %hi(cplus_etrap_insn_3), %o2 | ||
285 | or %o2, %lo(cplus_etrap_insn_3), %o2 | ||
286 | stw %o1, [%o2] | ||
287 | flush %o2 | ||
288 | |||
289 | sethi %hi(cplus_einsn_2), %o0 | ||
290 | sethi %hi(cplus_etrap_insn_2), %o2 | ||
291 | lduw [%o0 + %lo(cplus_einsn_2)], %o1 | ||
292 | or %o2, %lo(cplus_etrap_insn_2), %o2 | ||
293 | stw %o1, [%o2] | ||
294 | flush %o2 | ||
295 | sethi %hi(cplus_etrap_insn_4), %o2 | ||
296 | or %o2, %lo(cplus_etrap_insn_4), %o2 | ||
297 | stw %o1, [%o2] | ||
298 | flush %o2 | ||
299 | |||
300 | retl | ||
301 | nop | ||