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;				\
28109:	 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;				\
38109:	 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;			\
47109:	 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;				\
67109:	 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;				\
77109:	 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;				\
87109:	 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;			\
99109:	 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;				\
1361:	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				\
272etrap_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				\
330etrap_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			\
358etrap_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		\
426etrap_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			\
457etrap_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				\
528kern_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				\
588user_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				\
648user_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