xref: /openbmc/linux/arch/sparc/include/asm/ttable.h (revision 3cf3cdea)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _SPARC64_TTABLE_H
3 #define _SPARC64_TTABLE_H
4 
5 #include <asm/utrap.h>
6 #include <asm/pil.h>
7 
8 #ifdef __ASSEMBLY__
9 #include <asm/thread_info.h>
10 #endif
11 
12 #define BOOT_KERNEL b sparc64_boot; nop; nop; nop; nop; nop; nop; nop;
13 
14 /* We need a "cleaned" instruction... */
15 #define CLEAN_WINDOW							\
16 	rdpr	%cleanwin, %l0;		add	%l0, 1, %l0;		\
17 	wrpr	%l0, 0x0, %cleanwin;					\
18 	clr	%o0;	clr	%o1;	clr	%o2;	clr	%o3;	\
19 	clr	%o4;	clr	%o5;	clr	%o6;	clr	%o7;	\
20 	clr	%l0;	clr	%l1;	clr	%l2;	clr	%l3;	\
21 	clr	%l4;	clr	%l5;	clr	%l6;	clr	%l7;	\
22 	retry;								\
23 	nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
24 
25 #define TRAP(routine)					\
26 	sethi	%hi(109f), %g7;				\
27 	ba,pt	%xcc, etrap;				\
28 109:	 or	%g7, %lo(109b), %g7;			\
29 	call	routine;				\
30 	 add	%sp, PTREGS_OFF, %o0;			\
31 	ba,pt	%xcc, rtrap;				\
32 	 nop;						\
33 	nop;
34 
35 #define TRAP_7INSNS(routine)				\
36 	sethi	%hi(109f), %g7;				\
37 	ba,pt	%xcc, etrap;				\
38 109:	 or	%g7, %lo(109b), %g7;			\
39 	call	routine;				\
40 	 add	%sp, PTREGS_OFF, %o0;			\
41 	ba,pt	%xcc, rtrap;				\
42 	 nop;
43 
44 #define TRAP_SAVEFPU(routine)				\
45 	sethi	%hi(109f), %g7;				\
46 	ba,pt	%xcc, do_fptrap;			\
47 109:	 or	%g7, %lo(109b), %g7;			\
48 	call	routine;				\
49 	 add	%sp, PTREGS_OFF, %o0;			\
50 	ba,pt	%xcc, rtrap;				\
51 	 nop;						\
52 	nop;
53 
54 #define TRAP_NOSAVE(routine)				\
55 	ba,pt	%xcc, routine;				\
56 	 nop;						\
57 	nop; nop; nop; nop; nop; nop;
58 
59 #define TRAP_NOSAVE_7INSNS(routine)			\
60 	ba,pt	%xcc, routine;				\
61 	 nop;						\
62 	nop; nop; nop; nop; nop;
63 
64 #define TRAPTL1(routine)				\
65 	sethi	%hi(109f), %g7;				\
66 	ba,pt	%xcc, etraptl1;				\
67 109:	 or	%g7, %lo(109b), %g7;			\
68 	call	routine;				\
69 	 add	%sp, PTREGS_OFF, %o0;			\
70 	ba,pt	%xcc, rtrap;				\
71 	 nop;						\
72 	nop;
73 
74 #define TRAP_ARG(routine, arg)				\
75 	sethi	%hi(109f), %g7;				\
76 	ba,pt	%xcc, etrap;				\
77 109:	 or	%g7, %lo(109b), %g7;			\
78 	add	%sp, PTREGS_OFF, %o0;			\
79 	call	routine;				\
80 	 mov	arg, %o1;				\
81 	ba,pt	%xcc, rtrap;				\
82 	 nop;
83 
84 #define TRAPTL1_ARG(routine, arg)			\
85 	sethi	%hi(109f), %g7;				\
86 	ba,pt	%xcc, etraptl1;				\
87 109:	 or	%g7, %lo(109b), %g7;			\
88 	add	%sp, PTREGS_OFF, %o0;			\
89 	call	routine;				\
90 	 mov	arg, %o1;				\
91 	ba,pt	%xcc, rtrap;				\
92 	 nop;
93 
94 #define SYSCALL_TRAP(routine, systbl)			\
95 	rdpr	%pil, %g2;				\
96 	mov	TSTATE_SYSCALL, %g3;			\
97 	sethi	%hi(109f), %g7;				\
98 	ba,pt	%xcc, etrap_syscall;			\
99 109:	 or	%g7, %lo(109b), %g7;			\
100 	sethi	%hi(systbl), %l7;			\
101 	ba,pt	%xcc, routine;				\
102 	 or	%l7, %lo(systbl), %l7;
103 
104 #define TRAP_UTRAP(handler,lvl)				\
105 	mov	handler, %g3;				\
106 	ba,pt	%xcc, utrap_trap;			\
107 	 mov	lvl, %g4;				\
108 	nop;						\
109 	nop;						\
110 	nop;						\
111 	nop;						\
112 	nop;
113 
114 #ifdef CONFIG_COMPAT
115 #define	LINUX_32BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sys_call_table32)
116 #else
117 #define	LINUX_32BIT_SYSCALL_TRAP BTRAP(0x110)
118 #endif
119 #define LINUX_64BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall, sys_call_table64)
120 #define GETCC_TRAP TRAP(getcc)
121 #define SETCC_TRAP TRAP(setcc)
122 #define BREAKPOINT_TRAP TRAP(breakpoint_trap)
123 
124 #ifdef CONFIG_TRACE_IRQFLAGS
125 
126 #define TRAP_IRQ(routine, level)			\
127 	rdpr	%pil, %g2;				\
128 	wrpr	%g0, PIL_NORMAL_MAX, %pil;		\
129 	sethi	%hi(1f-4), %g7;				\
130 	ba,pt	%xcc, etrap_irq;			\
131 	 or	%g7, %lo(1f-4), %g7;			\
132 	nop;						\
133 	nop;						\
134 	nop;						\
135 	.subsection	2;				\
136 1:	call	trace_hardirqs_off;			\
137 	 nop;						\
138 	mov	level, %o0;				\
139 	call	routine;				\
140 	 add	%sp, PTREGS_OFF, %o1;			\
141 	ba,a,pt	%xcc, rtrap_irq;			\
142 	.previous;
143 
144 #else
145 
146 #define TRAP_IRQ(routine, level)			\
147 	rdpr	%pil, %g2;				\
148 	wrpr	%g0, PIL_NORMAL_MAX, %pil;		\
149 	ba,pt	%xcc, etrap_irq;			\
150 	 rd	%pc, %g7;				\
151 	mov	level, %o0;				\
152 	call	routine;				\
153 	 add	%sp, PTREGS_OFF, %o1;			\
154 	ba,a,pt	%xcc, rtrap_irq;
155 
156 #endif
157 
158 #define TRAP_NMI_IRQ(routine, level)			\
159 	rdpr	%pil, %g2;				\
160 	wrpr	%g0, PIL_NMI, %pil;			\
161 	ba,pt	%xcc, etrap_irq;			\
162 	 rd	%pc, %g7;				\
163 	mov	level, %o0;				\
164 	call	routine;				\
165 	 add	%sp, PTREGS_OFF, %o1;			\
166 	ba,a,pt	%xcc, rtrap_nmi;
167 
168 #define TRAP_IVEC TRAP_NOSAVE(do_ivec)
169 
170 #define BTRAP(lvl) TRAP_ARG(bad_trap, lvl)
171 
172 #define BTRAPTL1(lvl) TRAPTL1_ARG(bad_trap_tl1, lvl)
173 
174 #define FLUSH_WINDOW_TRAP						\
175 	ba,pt	%xcc, etrap;						\
176 	 rd	%pc, %g7;						\
177 	flushw;								\
178 	ldx	[%sp + PTREGS_OFF + PT_V9_TNPC], %l1;			\
179 	add	%l1, 4, %l2;						\
180 	stx	%l1, [%sp + PTREGS_OFF + PT_V9_TPC];			\
181 	ba,pt	%xcc, rtrap;						\
182 	 stx	%l2, [%sp + PTREGS_OFF + PT_V9_TNPC];
183 
184 #ifdef CONFIG_KPROBES
185 #define KPROBES_TRAP(lvl) TRAP_IRQ(kprobe_trap, lvl)
186 #else
187 #define KPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl)
188 #endif
189 
190 #ifdef CONFIG_UPROBES
191 #define UPROBES_TRAP(lvl) TRAP_ARG(uprobe_trap, lvl)
192 #else
193 #define UPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl)
194 #endif
195 
196 #ifdef CONFIG_KGDB
197 #define KGDB_TRAP(lvl) TRAP_IRQ(kgdb_trap, lvl)
198 #else
199 #define KGDB_TRAP(lvl) TRAP_ARG(bad_trap, lvl)
200 #endif
201 
202 #define SUN4V_ITSB_MISS					\
203 	ldxa	[%g0] ASI_SCRATCHPAD, %g2;		\
204 	ldx	[%g2 + HV_FAULT_I_ADDR_OFFSET], %g4;	\
205 	ldx	[%g2 + HV_FAULT_I_CTX_OFFSET], %g5;	\
206 	srlx	%g4, 22, %g6;				\
207 	ba,pt	%xcc, sun4v_itsb_miss;			\
208 	 nop;						\
209 	nop;						\
210 	nop;
211 
212 #define SUN4V_DTSB_MISS					\
213 	ldxa	[%g0] ASI_SCRATCHPAD, %g2;		\
214 	ldx	[%g2 + HV_FAULT_D_ADDR_OFFSET], %g4;	\
215 	ldx	[%g2 + HV_FAULT_D_CTX_OFFSET], %g5;	\
216 	srlx	%g4, 22, %g6;				\
217 	ba,pt	%xcc, sun4v_dtsb_miss;			\
218 	 nop;						\
219 	nop;						\
220 	nop;
221 
222 #define SUN4V_MCD_PRECISE				\
223 	ldxa	[%g0] ASI_SCRATCHPAD, %g2;		\
224 	ldx	[%g2 + HV_FAULT_D_ADDR_OFFSET], %g4;	\
225 	ldx	[%g2 + HV_FAULT_D_CTX_OFFSET], %g5;	\
226 	ba,pt	%xcc, etrap;				\
227 	 rd	%pc, %g7;				\
228 	ba,pt	%xcc, sun4v_mcd_detect_precise;		\
229 	 nop;						\
230 	nop;
231 
232 /* Before touching these macros, you owe it to yourself to go and
233  * see how arch/sparc64/kernel/winfixup.S works... -DaveM
234  *
235  * For the user cases we used to use the %asi register, but
236  * it turns out that the "wr xxx, %asi" costs ~5 cycles, so
237  * now we use immediate ASI loads and stores instead.  Kudos
238  * to Greg Onufer for pointing out this performance anomaly.
239  *
240  * Further note that we cannot use the g2, g4, g5, and g7 alternate
241  * globals in the spill routines, check out the save instruction in
242  * arch/sparc64/kernel/etrap.S to see what I mean about g2, and
243  * g4/g5 are the globals which are preserved by etrap processing
244  * for the caller of it.  The g7 register is the return pc for
245  * etrap.  Finally, g6 is the current thread register so we cannot
246  * us it in the spill handlers either.  Most of these rules do not
247  * apply to fill processing, only g6 is not usable.
248  */
249 
250 /* Normal kernel spill */
251 #define SPILL_0_NORMAL					\
252 	stx	%l0, [%sp + STACK_BIAS + 0x00];		\
253 	stx	%l1, [%sp + STACK_BIAS + 0x08];		\
254 	stx	%l2, [%sp + STACK_BIAS + 0x10];		\
255 	stx	%l3, [%sp + STACK_BIAS + 0x18];		\
256 	stx	%l4, [%sp + STACK_BIAS + 0x20];		\
257 	stx	%l5, [%sp + STACK_BIAS + 0x28];		\
258 	stx	%l6, [%sp + STACK_BIAS + 0x30];		\
259 	stx	%l7, [%sp + STACK_BIAS + 0x38];		\
260 	stx	%i0, [%sp + STACK_BIAS + 0x40];		\
261 	stx	%i1, [%sp + STACK_BIAS + 0x48];		\
262 	stx	%i2, [%sp + STACK_BIAS + 0x50];		\
263 	stx	%i3, [%sp + STACK_BIAS + 0x58];		\
264 	stx	%i4, [%sp + STACK_BIAS + 0x60];		\
265 	stx	%i5, [%sp + STACK_BIAS + 0x68];		\
266 	stx	%i6, [%sp + STACK_BIAS + 0x70];		\
267 	stx	%i7, [%sp + STACK_BIAS + 0x78];		\
268 	saved; retry; nop; nop; nop; nop; nop; nop;	\
269 	nop; nop; nop; nop; nop; nop; nop; nop;
270 
271 #define SPILL_0_NORMAL_ETRAP				\
272 etrap_kernel_spill:					\
273 	stx	%l0, [%sp + STACK_BIAS + 0x00];		\
274 	stx	%l1, [%sp + STACK_BIAS + 0x08];		\
275 	stx	%l2, [%sp + STACK_BIAS + 0x10];		\
276 	stx	%l3, [%sp + STACK_BIAS + 0x18];		\
277 	stx	%l4, [%sp + STACK_BIAS + 0x20];		\
278 	stx	%l5, [%sp + STACK_BIAS + 0x28];		\
279 	stx	%l6, [%sp + STACK_BIAS + 0x30];		\
280 	stx	%l7, [%sp + STACK_BIAS + 0x38];		\
281 	stx	%i0, [%sp + STACK_BIAS + 0x40];		\
282 	stx	%i1, [%sp + STACK_BIAS + 0x48];		\
283 	stx	%i2, [%sp + STACK_BIAS + 0x50];		\
284 	stx	%i3, [%sp + STACK_BIAS + 0x58];		\
285 	stx	%i4, [%sp + STACK_BIAS + 0x60];		\
286 	stx	%i5, [%sp + STACK_BIAS + 0x68];		\
287 	stx	%i6, [%sp + STACK_BIAS + 0x70];		\
288 	stx	%i7, [%sp + STACK_BIAS + 0x78];		\
289 	saved;						\
290 	sub	%g1, 2, %g1;				\
291 	ba,pt	%xcc, etrap_save;			\
292 	wrpr	%g1, %cwp;				\
293 	nop; nop; nop; nop; nop; nop; nop; nop;		\
294 	nop; nop; nop; nop;
295 
296 /* Normal 64bit spill */
297 #define SPILL_1_GENERIC(ASI)				\
298 	add	%sp, STACK_BIAS + 0x00, %g1;		\
299 	stxa	%l0, [%g1 + %g0] ASI;			\
300 	mov	0x08, %g3;				\
301 	stxa	%l1, [%g1 + %g3] ASI;			\
302 	add	%g1, 0x10, %g1;				\
303 	stxa	%l2, [%g1 + %g0] ASI;			\
304 	stxa	%l3, [%g1 + %g3] ASI;			\
305 	add	%g1, 0x10, %g1;				\
306 	stxa	%l4, [%g1 + %g0] ASI;			\
307 	stxa	%l5, [%g1 + %g3] ASI;			\
308 	add	%g1, 0x10, %g1;				\
309 	stxa	%l6, [%g1 + %g0] ASI;			\
310 	stxa	%l7, [%g1 + %g3] ASI;			\
311 	add	%g1, 0x10, %g1;				\
312 	stxa	%i0, [%g1 + %g0] ASI;			\
313 	stxa	%i1, [%g1 + %g3] ASI;			\
314 	add	%g1, 0x10, %g1;				\
315 	stxa	%i2, [%g1 + %g0] ASI;			\
316 	stxa	%i3, [%g1 + %g3] ASI;			\
317 	add	%g1, 0x10, %g1;				\
318 	stxa	%i4, [%g1 + %g0] ASI;			\
319 	stxa	%i5, [%g1 + %g3] ASI;			\
320 	add	%g1, 0x10, %g1;				\
321 	stxa	%i6, [%g1 + %g0] ASI;			\
322 	stxa	%i7, [%g1 + %g3] ASI;			\
323 	saved;						\
324 	retry; nop; nop;				\
325 	b,a,pt	%xcc, spill_fixup_dax;			\
326 	b,a,pt	%xcc, spill_fixup_mna;			\
327 	b,a,pt	%xcc, spill_fixup;
328 
329 #define SPILL_1_GENERIC_ETRAP				\
330 etrap_user_spill_64bit:					\
331 	stxa	%l0, [%sp + STACK_BIAS + 0x00] %asi;	\
332 	stxa	%l1, [%sp + STACK_BIAS + 0x08] %asi;	\
333 	stxa	%l2, [%sp + STACK_BIAS + 0x10] %asi;	\
334 	stxa	%l3, [%sp + STACK_BIAS + 0x18] %asi;	\
335 	stxa	%l4, [%sp + STACK_BIAS + 0x20] %asi;	\
336 	stxa	%l5, [%sp + STACK_BIAS + 0x28] %asi;	\
337 	stxa	%l6, [%sp + STACK_BIAS + 0x30] %asi;	\
338 	stxa	%l7, [%sp + STACK_BIAS + 0x38] %asi;	\
339 	stxa	%i0, [%sp + STACK_BIAS + 0x40] %asi;	\
340 	stxa	%i1, [%sp + STACK_BIAS + 0x48] %asi;	\
341 	stxa	%i2, [%sp + STACK_BIAS + 0x50] %asi;	\
342 	stxa	%i3, [%sp + STACK_BIAS + 0x58] %asi;	\
343 	stxa	%i4, [%sp + STACK_BIAS + 0x60] %asi;	\
344 	stxa	%i5, [%sp + STACK_BIAS + 0x68] %asi;	\
345 	stxa	%i6, [%sp + STACK_BIAS + 0x70] %asi;	\
346 	stxa	%i7, [%sp + STACK_BIAS + 0x78] %asi;	\
347 	saved;						\
348 	sub	%g1, 2, %g1;				\
349 	ba,pt	%xcc, etrap_save;			\
350 	 wrpr	%g1, %cwp;				\
351 	nop; nop; nop; nop; nop;			\
352 	nop; nop; nop; nop;				\
353 	ba,a,pt	%xcc, etrap_spill_fixup_64bit;		\
354 	ba,a,pt	%xcc, etrap_spill_fixup_64bit;		\
355 	ba,a,pt	%xcc, etrap_spill_fixup_64bit;
356 
357 #define SPILL_1_GENERIC_ETRAP_FIXUP			\
358 etrap_spill_fixup_64bit:				\
359 	ldub	[%g6 + TI_WSAVED], %g1;			\
360 	sll	%g1, 3, %g3;				\
361 	add	%g6, %g3, %g3;				\
362 	stx	%sp, [%g3 + TI_RWIN_SPTRS];		\
363 	sll	%g1, 7, %g3;				\
364 	add	%g6, %g3, %g3;				\
365 	stx	%l0, [%g3 + TI_REG_WINDOW + 0x00];	\
366 	stx	%l1, [%g3 + TI_REG_WINDOW + 0x08];	\
367 	stx	%l2, [%g3 + TI_REG_WINDOW + 0x10];	\
368 	stx	%l3, [%g3 + TI_REG_WINDOW + 0x18];	\
369 	stx	%l4, [%g3 + TI_REG_WINDOW + 0x20];	\
370 	stx	%l5, [%g3 + TI_REG_WINDOW + 0x28];	\
371 	stx	%l6, [%g3 + TI_REG_WINDOW + 0x30];	\
372 	stx	%l7, [%g3 + TI_REG_WINDOW + 0x38];	\
373 	stx	%i0, [%g3 + TI_REG_WINDOW + 0x40];	\
374 	stx	%i1, [%g3 + TI_REG_WINDOW + 0x48];	\
375 	stx	%i2, [%g3 + TI_REG_WINDOW + 0x50];	\
376 	stx	%i3, [%g3 + TI_REG_WINDOW + 0x58];	\
377 	stx	%i4, [%g3 + TI_REG_WINDOW + 0x60];	\
378 	stx	%i5, [%g3 + TI_REG_WINDOW + 0x68];	\
379 	stx	%i6, [%g3 + TI_REG_WINDOW + 0x70];	\
380 	stx	%i7, [%g3 + TI_REG_WINDOW + 0x78];	\
381 	add	%g1, 1, %g1;				\
382 	stb	%g1, [%g6 + TI_WSAVED];			\
383 	saved;						\
384 	rdpr	%cwp, %g1;				\
385 	sub	%g1, 2, %g1;				\
386 	ba,pt	%xcc, etrap_save;			\
387 	 wrpr	%g1, %cwp;				\
388 	nop; nop; nop
389 
390 /* Normal 32bit spill */
391 #define SPILL_2_GENERIC(ASI)				\
392 	and	%sp, 1, %g3;				\
393 	brnz,pn	%g3, (. - (128 + 4));			\
394 	 srl	%sp, 0, %sp;				\
395 	stwa	%l0, [%sp + %g0] ASI;			\
396 	mov	0x04, %g3;				\
397 	stwa	%l1, [%sp + %g3] ASI;			\
398 	add	%sp, 0x08, %g1;				\
399 	stwa	%l2, [%g1 + %g0] ASI;			\
400 	stwa	%l3, [%g1 + %g3] ASI;			\
401 	add	%g1, 0x08, %g1;				\
402 	stwa	%l4, [%g1 + %g0] ASI;			\
403 	stwa	%l5, [%g1 + %g3] ASI;			\
404 	add	%g1, 0x08, %g1;				\
405 	stwa	%l6, [%g1 + %g0] ASI;			\
406 	stwa	%l7, [%g1 + %g3] ASI;			\
407 	add	%g1, 0x08, %g1;				\
408 	stwa	%i0, [%g1 + %g0] ASI;			\
409 	stwa	%i1, [%g1 + %g3] ASI;			\
410 	add	%g1, 0x08, %g1;				\
411 	stwa	%i2, [%g1 + %g0] ASI;			\
412 	stwa	%i3, [%g1 + %g3] ASI;			\
413 	add	%g1, 0x08, %g1;				\
414 	stwa	%i4, [%g1 + %g0] ASI;			\
415 	stwa	%i5, [%g1 + %g3] ASI;			\
416 	add	%g1, 0x08, %g1;				\
417 	stwa	%i6, [%g1 + %g0] ASI;			\
418 	stwa	%i7, [%g1 + %g3] ASI;			\
419 	saved;						\
420         retry;						\
421 	b,a,pt	%xcc, spill_fixup_dax;			\
422 	b,a,pt	%xcc, spill_fixup_mna;			\
423 	b,a,pt	%xcc, spill_fixup;
424 
425 #define SPILL_2_GENERIC_ETRAP		\
426 etrap_user_spill_32bit:			\
427 	and	%sp, 1, %g3;		\
428 	brnz,pn	%g3, etrap_user_spill_64bit;	\
429 	 srl	%sp, 0, %sp;		\
430 	stwa	%l0, [%sp + 0x00] %asi;	\
431 	stwa	%l1, [%sp + 0x04] %asi;	\
432 	stwa	%l2, [%sp + 0x08] %asi;	\
433 	stwa	%l3, [%sp + 0x0c] %asi;	\
434 	stwa	%l4, [%sp + 0x10] %asi;	\
435 	stwa	%l5, [%sp + 0x14] %asi;	\
436 	stwa	%l6, [%sp + 0x18] %asi;	\
437 	stwa	%l7, [%sp + 0x1c] %asi;	\
438 	stwa	%i0, [%sp + 0x20] %asi;	\
439 	stwa	%i1, [%sp + 0x24] %asi;	\
440 	stwa	%i2, [%sp + 0x28] %asi;	\
441 	stwa	%i3, [%sp + 0x2c] %asi;	\
442 	stwa	%i4, [%sp + 0x30] %asi;	\
443 	stwa	%i5, [%sp + 0x34] %asi;	\
444 	stwa	%i6, [%sp + 0x38] %asi;	\
445 	stwa	%i7, [%sp + 0x3c] %asi;	\
446 	saved;				\
447 	sub	%g1, 2, %g1;		\
448 	ba,pt	%xcc, etrap_save;	\
449 	 wrpr	%g1, %cwp;		\
450 	nop; nop; nop; nop;		\
451 	nop; nop;			\
452 	ba,a,pt	%xcc, etrap_spill_fixup_32bit; \
453 	ba,a,pt	%xcc, etrap_spill_fixup_32bit; \
454 	ba,a,pt	%xcc, etrap_spill_fixup_32bit;
455 
456 #define SPILL_2_GENERIC_ETRAP_FIXUP			\
457 etrap_spill_fixup_32bit:				\
458 	ldub	[%g6 + TI_WSAVED], %g1;			\
459 	sll	%g1, 3, %g3;				\
460 	add	%g6, %g3, %g3;				\
461 	stx	%sp, [%g3 + TI_RWIN_SPTRS];		\
462 	sll	%g1, 7, %g3;				\
463 	add	%g6, %g3, %g3;				\
464 	stw	%l0, [%g3 + TI_REG_WINDOW + 0x00];	\
465 	stw	%l1, [%g3 + TI_REG_WINDOW + 0x04];	\
466 	stw	%l2, [%g3 + TI_REG_WINDOW + 0x08];	\
467 	stw	%l3, [%g3 + TI_REG_WINDOW + 0x0c];	\
468 	stw	%l4, [%g3 + TI_REG_WINDOW + 0x10];	\
469 	stw	%l5, [%g3 + TI_REG_WINDOW + 0x14];	\
470 	stw	%l6, [%g3 + TI_REG_WINDOW + 0x18];	\
471 	stw	%l7, [%g3 + TI_REG_WINDOW + 0x1c];	\
472 	stw	%i0, [%g3 + TI_REG_WINDOW + 0x20];	\
473 	stw	%i1, [%g3 + TI_REG_WINDOW + 0x24];	\
474 	stw	%i2, [%g3 + TI_REG_WINDOW + 0x28];	\
475 	stw	%i3, [%g3 + TI_REG_WINDOW + 0x2c];	\
476 	stw	%i4, [%g3 + TI_REG_WINDOW + 0x30];	\
477 	stw	%i5, [%g3 + TI_REG_WINDOW + 0x34];	\
478 	stw	%i6, [%g3 + TI_REG_WINDOW + 0x38];	\
479 	stw	%i7, [%g3 + TI_REG_WINDOW + 0x3c];	\
480 	add	%g1, 1, %g1;				\
481 	stb	%g1, [%g6 + TI_WSAVED];			\
482 	saved;						\
483 	rdpr	%cwp, %g1;				\
484 	sub	%g1, 2, %g1;				\
485 	ba,pt	%xcc, etrap_save;			\
486 	 wrpr	%g1, %cwp;				\
487 	nop; nop; nop
488 
489 #define SPILL_1_NORMAL SPILL_1_GENERIC(ASI_AIUP)
490 #define SPILL_2_NORMAL SPILL_2_GENERIC(ASI_AIUP)
491 #define SPILL_3_NORMAL SPILL_0_NORMAL
492 #define SPILL_4_NORMAL SPILL_0_NORMAL
493 #define SPILL_5_NORMAL SPILL_0_NORMAL
494 #define SPILL_6_NORMAL SPILL_0_NORMAL
495 #define SPILL_7_NORMAL SPILL_0_NORMAL
496 
497 #define SPILL_0_OTHER SPILL_0_NORMAL
498 #define SPILL_1_OTHER SPILL_1_GENERIC(ASI_AIUS)
499 #define SPILL_2_OTHER SPILL_2_GENERIC(ASI_AIUS)
500 #define SPILL_3_OTHER SPILL_3_NORMAL
501 #define SPILL_4_OTHER SPILL_4_NORMAL
502 #define SPILL_5_OTHER SPILL_5_NORMAL
503 #define SPILL_6_OTHER SPILL_6_NORMAL
504 #define SPILL_7_OTHER SPILL_7_NORMAL
505 
506 /* Normal kernel fill */
507 #define FILL_0_NORMAL					\
508 	ldx	[%sp + STACK_BIAS + 0x00], %l0;		\
509 	ldx	[%sp + STACK_BIAS + 0x08], %l1;		\
510 	ldx	[%sp + STACK_BIAS + 0x10], %l2;		\
511 	ldx	[%sp + STACK_BIAS + 0x18], %l3;		\
512 	ldx	[%sp + STACK_BIAS + 0x20], %l4;		\
513 	ldx	[%sp + STACK_BIAS + 0x28], %l5;		\
514 	ldx	[%sp + STACK_BIAS + 0x30], %l6;		\
515 	ldx	[%sp + STACK_BIAS + 0x38], %l7;		\
516 	ldx	[%sp + STACK_BIAS + 0x40], %i0;		\
517 	ldx	[%sp + STACK_BIAS + 0x48], %i1;		\
518 	ldx	[%sp + STACK_BIAS + 0x50], %i2;		\
519 	ldx	[%sp + STACK_BIAS + 0x58], %i3;		\
520 	ldx	[%sp + STACK_BIAS + 0x60], %i4;		\
521 	ldx	[%sp + STACK_BIAS + 0x68], %i5;		\
522 	ldx	[%sp + STACK_BIAS + 0x70], %i6;		\
523 	ldx	[%sp + STACK_BIAS + 0x78], %i7;		\
524 	restored; retry; nop; nop; nop; nop; nop; nop;	\
525 	nop; nop; nop; nop; nop; nop; nop; nop;
526 
527 #define FILL_0_NORMAL_RTRAP				\
528 kern_rtt_fill:						\
529 	rdpr	%cwp, %g1;				\
530 	sub	%g1, 1, %g1;				\
531 	wrpr	%g1, %cwp;				\
532 	ldx	[%sp + STACK_BIAS + 0x00], %l0;		\
533 	ldx	[%sp + STACK_BIAS + 0x08], %l1;		\
534 	ldx	[%sp + STACK_BIAS + 0x10], %l2;		\
535 	ldx	[%sp + STACK_BIAS + 0x18], %l3;		\
536 	ldx	[%sp + STACK_BIAS + 0x20], %l4;		\
537 	ldx	[%sp + STACK_BIAS + 0x28], %l5;		\
538 	ldx	[%sp + STACK_BIAS + 0x30], %l6;		\
539 	ldx	[%sp + STACK_BIAS + 0x38], %l7;		\
540 	ldx	[%sp + STACK_BIAS + 0x40], %i0;		\
541 	ldx	[%sp + STACK_BIAS + 0x48], %i1;		\
542 	ldx	[%sp + STACK_BIAS + 0x50], %i2;		\
543 	ldx	[%sp + STACK_BIAS + 0x58], %i3;		\
544 	ldx	[%sp + STACK_BIAS + 0x60], %i4;		\
545 	ldx	[%sp + STACK_BIAS + 0x68], %i5;		\
546 	ldx	[%sp + STACK_BIAS + 0x70], %i6;		\
547 	ldx	[%sp + STACK_BIAS + 0x78], %i7;		\
548 	restored;					\
549 	add	%g1, 1, %g1;				\
550 	ba,pt	%xcc, kern_rtt_restore;			\
551 	 wrpr	%g1, %cwp;				\
552 	nop; nop; nop; nop; nop;			\
553 	nop; nop; nop; nop;
554 
555 
556 /* Normal 64bit fill */
557 #define FILL_1_GENERIC(ASI)				\
558 	add	%sp, STACK_BIAS + 0x00, %g1;		\
559 	ldxa	[%g1 + %g0] ASI, %l0;			\
560 	mov	0x08, %g2;				\
561 	mov	0x10, %g3;				\
562 	ldxa	[%g1 + %g2] ASI, %l1;			\
563 	mov	0x18, %g5;				\
564 	ldxa	[%g1 + %g3] ASI, %l2;			\
565 	ldxa	[%g1 + %g5] ASI, %l3;			\
566 	add	%g1, 0x20, %g1;				\
567 	ldxa	[%g1 + %g0] ASI, %l4;			\
568 	ldxa	[%g1 + %g2] ASI, %l5;			\
569 	ldxa	[%g1 + %g3] ASI, %l6;			\
570 	ldxa	[%g1 + %g5] ASI, %l7;			\
571 	add	%g1, 0x20, %g1;				\
572 	ldxa	[%g1 + %g0] ASI, %i0;			\
573 	ldxa	[%g1 + %g2] ASI, %i1;			\
574 	ldxa	[%g1 + %g3] ASI, %i2;			\
575 	ldxa	[%g1 + %g5] ASI, %i3;			\
576 	add	%g1, 0x20, %g1;				\
577 	ldxa	[%g1 + %g0] ASI, %i4;			\
578 	ldxa	[%g1 + %g2] ASI, %i5;			\
579 	ldxa	[%g1 + %g3] ASI, %i6;			\
580 	ldxa	[%g1 + %g5] ASI, %i7;			\
581 	restored;					\
582 	retry; nop; nop; nop; nop;			\
583 	b,a,pt	%xcc, fill_fixup_dax;			\
584 	b,a,pt	%xcc, fill_fixup_mna;			\
585 	b,a,pt	%xcc, fill_fixup;
586 
587 #define FILL_1_GENERIC_RTRAP				\
588 user_rtt_fill_64bit:					\
589 	ldxa	[%sp + STACK_BIAS + 0x00] %asi, %l0;	\
590 	ldxa	[%sp + STACK_BIAS + 0x08] %asi, %l1;	\
591 	ldxa	[%sp + STACK_BIAS + 0x10] %asi, %l2;	\
592 	ldxa	[%sp + STACK_BIAS + 0x18] %asi, %l3;	\
593 	ldxa	[%sp + STACK_BIAS + 0x20] %asi, %l4;	\
594 	ldxa	[%sp + STACK_BIAS + 0x28] %asi, %l5;	\
595 	ldxa	[%sp + STACK_BIAS + 0x30] %asi, %l6;	\
596 	ldxa	[%sp + STACK_BIAS + 0x38] %asi, %l7;	\
597 	ldxa	[%sp + STACK_BIAS + 0x40] %asi, %i0;	\
598 	ldxa	[%sp + STACK_BIAS + 0x48] %asi, %i1;	\
599 	ldxa	[%sp + STACK_BIAS + 0x50] %asi, %i2;	\
600 	ldxa	[%sp + STACK_BIAS + 0x58] %asi, %i3;	\
601 	ldxa	[%sp + STACK_BIAS + 0x60] %asi, %i4;	\
602 	ldxa	[%sp + STACK_BIAS + 0x68] %asi, %i5;	\
603 	ldxa	[%sp + STACK_BIAS + 0x70] %asi, %i6;	\
604 	ldxa	[%sp + STACK_BIAS + 0x78] %asi, %i7;	\
605 	ba,pt	%xcc, user_rtt_pre_restore;		\
606 	 restored;					\
607 	nop; nop; nop; nop; nop; nop;			\
608 	nop; nop; nop; nop; nop;			\
609 	ba,a,pt	%xcc, user_rtt_fill_fixup_dax;		\
610 	ba,a,pt	%xcc, user_rtt_fill_fixup_mna;		\
611 	ba,a,pt	%xcc, user_rtt_fill_fixup;
612 
613 
614 /* Normal 32bit fill */
615 #define FILL_2_GENERIC(ASI)				\
616 	and	%sp, 1, %g3;				\
617 	brnz,pn	%g3, (. - (128 + 4));			\
618 	 srl	%sp, 0, %sp;				\
619 	lduwa	[%sp + %g0] ASI, %l0;			\
620 	mov	0x04, %g2;				\
621 	mov	0x08, %g3;				\
622 	lduwa	[%sp + %g2] ASI, %l1;			\
623 	mov	0x0c, %g5;				\
624 	lduwa	[%sp + %g3] ASI, %l2;			\
625 	lduwa	[%sp + %g5] ASI, %l3;			\
626 	add	%sp, 0x10, %g1;				\
627 	lduwa	[%g1 + %g0] ASI, %l4;			\
628 	lduwa	[%g1 + %g2] ASI, %l5;			\
629 	lduwa	[%g1 + %g3] ASI, %l6;			\
630 	lduwa	[%g1 + %g5] ASI, %l7;			\
631 	add	%g1, 0x10, %g1;				\
632 	lduwa	[%g1 + %g0] ASI, %i0;			\
633 	lduwa	[%g1 + %g2] ASI, %i1;			\
634 	lduwa	[%g1 + %g3] ASI, %i2;			\
635 	lduwa	[%g1 + %g5] ASI, %i3;			\
636 	add	%g1, 0x10, %g1;				\
637 	lduwa	[%g1 + %g0] ASI, %i4;			\
638 	lduwa	[%g1 + %g2] ASI, %i5;			\
639 	lduwa	[%g1 + %g3] ASI, %i6;			\
640 	lduwa	[%g1 + %g5] ASI, %i7;			\
641 	restored;					\
642 	retry; nop; nop;				\
643 	b,a,pt	%xcc, fill_fixup_dax;			\
644 	b,a,pt	%xcc, fill_fixup_mna;			\
645 	b,a,pt	%xcc, fill_fixup;
646 
647 #define FILL_2_GENERIC_RTRAP				\
648 user_rtt_fill_32bit:					\
649 	and	%sp, 1, %g3;				\
650 	brnz,pn	%g3, user_rtt_fill_64bit;		\
651 	 srl	%sp, 0, %sp;				\
652 	lduwa	[%sp + 0x00] %asi, %l0;			\
653 	lduwa	[%sp + 0x04] %asi, %l1;			\
654 	lduwa	[%sp + 0x08] %asi, %l2;			\
655 	lduwa	[%sp + 0x0c] %asi, %l3;			\
656 	lduwa	[%sp + 0x10] %asi, %l4;			\
657 	lduwa	[%sp + 0x14] %asi, %l5;			\
658 	lduwa	[%sp + 0x18] %asi, %l6;			\
659 	lduwa	[%sp + 0x1c] %asi, %l7;			\
660 	lduwa	[%sp + 0x20] %asi, %i0;			\
661 	lduwa	[%sp + 0x24] %asi, %i1;			\
662 	lduwa	[%sp + 0x28] %asi, %i2;			\
663 	lduwa	[%sp + 0x2c] %asi, %i3;			\
664 	lduwa	[%sp + 0x30] %asi, %i4;			\
665 	lduwa	[%sp + 0x34] %asi, %i5;			\
666 	lduwa	[%sp + 0x38] %asi, %i6;			\
667 	lduwa	[%sp + 0x3c] %asi, %i7;			\
668 	ba,pt	%xcc, user_rtt_pre_restore;		\
669 	 restored;					\
670 	nop; nop; nop; nop; nop;			\
671 	nop; nop; nop;					\
672 	ba,a,pt	%xcc, user_rtt_fill_fixup_dax;		\
673 	ba,a,pt	%xcc, user_rtt_fill_fixup_mna;		\
674 	ba,a,pt	%xcc, user_rtt_fill_fixup;
675 
676 
677 #define FILL_1_NORMAL FILL_1_GENERIC(ASI_AIUP)
678 #define FILL_2_NORMAL FILL_2_GENERIC(ASI_AIUP)
679 #define FILL_3_NORMAL FILL_0_NORMAL
680 #define FILL_4_NORMAL FILL_0_NORMAL
681 #define FILL_5_NORMAL FILL_0_NORMAL
682 #define FILL_6_NORMAL FILL_0_NORMAL
683 #define FILL_7_NORMAL FILL_0_NORMAL
684 
685 #define FILL_0_OTHER FILL_0_NORMAL
686 #define FILL_1_OTHER FILL_1_GENERIC(ASI_AIUS)
687 #define FILL_2_OTHER FILL_2_GENERIC(ASI_AIUS)
688 #define FILL_3_OTHER FILL_3_NORMAL
689 #define FILL_4_OTHER FILL_4_NORMAL
690 #define FILL_5_OTHER FILL_5_NORMAL
691 #define FILL_6_OTHER FILL_6_NORMAL
692 #define FILL_7_OTHER FILL_7_NORMAL
693 
694 #endif /* !(_SPARC64_TTABLE_H) */
695