1 /* $Id: ttable.h,v 1.17 2001/11/28 23:32:16 davem Exp $ */
2 #ifndef _SPARC64_TTABLE_H
3 #define _SPARC64_TTABLE_H
4 
5 #include <linux/config.h>
6 #include <asm/asm_offsets.h>
7 #include <asm/utrap.h>
8 
9 #define BOOT_KERNEL b sparc64_boot; nop; nop; nop; nop; nop; nop; nop;
10 
11 /* We need a "cleaned" instruction... */
12 #define CLEAN_WINDOW							\
13 	rdpr	%cleanwin, %l0;		add	%l0, 1, %l0;		\
14 	wrpr	%l0, 0x0, %cleanwin;					\
15 	clr	%o0;	clr	%o1;	clr	%o2;	clr	%o3;	\
16 	clr	%o4;	clr	%o5;	clr	%o6;	clr	%o7;	\
17 	clr	%l0;	clr	%l1;	clr	%l2;	clr	%l3;	\
18 	clr	%l4;	clr	%l5;	clr	%l6;	clr	%l7;	\
19 	retry;								\
20 	nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
21 
22 #define TRAP(routine)					\
23 	sethi	%hi(109f), %g7;				\
24 	ba,pt	%xcc, etrap;				\
25 109:	 or	%g7, %lo(109b), %g7;			\
26 	call	routine;				\
27 	 add	%sp, PTREGS_OFF, %o0;			\
28 	ba,pt	%xcc, rtrap;				\
29 	 clr	%l6;					\
30 	nop;
31 
32 #define TRAP_7INSNS(routine)				\
33 	sethi	%hi(109f), %g7;				\
34 	ba,pt	%xcc, etrap;				\
35 109:	 or	%g7, %lo(109b), %g7;			\
36 	call	routine;				\
37 	 add	%sp, PTREGS_OFF, %o0;			\
38 	ba,pt	%xcc, rtrap;				\
39 	 clr	%l6;
40 
41 #define TRAP_SAVEFPU(routine)				\
42 	sethi	%hi(109f), %g7;				\
43 	ba,pt	%xcc, do_fptrap;			\
44 109:	 or	%g7, %lo(109b), %g7;			\
45 	call	routine;				\
46 	 add	%sp, PTREGS_OFF, %o0;			\
47 	ba,pt	%xcc, rtrap;				\
48 	 clr	%l6;					\
49 	nop;
50 
51 #define TRAP_NOSAVE(routine)				\
52 	ba,pt	%xcc, routine;				\
53 	 nop;						\
54 	nop; nop; nop; nop; nop; nop;
55 
56 #define TRAP_NOSAVE_7INSNS(routine)			\
57 	ba,pt	%xcc, routine;				\
58 	 nop;						\
59 	nop; nop; nop; nop; nop;
60 
61 #define TRAPTL1(routine)				\
62 	sethi	%hi(109f), %g7;				\
63 	ba,pt	%xcc, etraptl1;				\
64 109:	 or	%g7, %lo(109b), %g7;			\
65 	call	routine;				\
66 	 add	%sp, PTREGS_OFF, %o0;			\
67 	ba,pt	%xcc, rtrap;				\
68 	 clr	%l6;					\
69 	nop;
70 
71 #define TRAP_ARG(routine, arg)				\
72 	sethi	%hi(109f), %g7;				\
73 	ba,pt	%xcc, etrap;				\
74 109:	 or	%g7, %lo(109b), %g7;			\
75 	add	%sp, PTREGS_OFF, %o0;			\
76 	call	routine;				\
77 	 mov	arg, %o1;				\
78 	ba,pt	%xcc, rtrap;				\
79 	 clr	%l6;
80 
81 #define TRAPTL1_ARG(routine, arg)			\
82 	sethi	%hi(109f), %g7;				\
83 	ba,pt	%xcc, etraptl1;				\
84 109:	 or	%g7, %lo(109b), %g7;			\
85 	add	%sp, PTREGS_OFF, %o0;			\
86 	call	routine;				\
87 	 mov	arg, %o1;				\
88 	ba,pt	%xcc, rtrap;				\
89 	 clr	%l6;
90 
91 #define SYSCALL_TRAP(routine, systbl)			\
92 	sethi	%hi(109f), %g7;				\
93 	ba,pt	%xcc, scetrap;				\
94 109:	 or	%g7, %lo(109b), %g7;			\
95 	ba,pt	%xcc, routine;				\
96 	 sethi	%hi(systbl), %l7;			\
97 	nop; nop; nop;
98 
99 #define INDIRECT_SOLARIS_SYSCALL(num)			\
100 	sethi	%hi(109f), %g7;				\
101 	ba,pt	%xcc, etrap;				\
102 109:	 or	%g7, %lo(109b), %g7;			\
103 	ba,pt	%xcc, tl0_solaris + 0xc;		\
104 	 mov	num, %g1;				\
105 	nop;nop;nop;
106 
107 #define TRAP_UTRAP(handler,lvl)						\
108 	ldx	[%g6 + AOFF_task_thread + AOFF_thread_utraps], %g1;	\
109 	sethi	%hi(109f), %g7;						\
110 	brz,pn	%g1, utrap;						\
111 	 or	%g7, %lo(109f), %g7;					\
112 	ba,pt	%xcc, utrap;						\
113 109:	 ldx	[%g1 + handler*8], %g1;					\
114 	ba,pt	%xcc, utrap_ill;					\
115 	 mov	lvl, %o1;
116 
117 #ifdef CONFIG_SUNOS_EMUL
118 #define SUNOS_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sunos_sys_table)
119 #else
120 #define SUNOS_SYSCALL_TRAP TRAP(sunos_syscall)
121 #endif
122 #define	LINUX_32BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sys_call_table32)
123 #define LINUX_64BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall, sys_call_table64)
124 #define GETCC_TRAP TRAP(getcc)
125 #define SETCC_TRAP TRAP(setcc)
126 #ifdef CONFIG_SOLARIS_EMUL
127 #define SOLARIS_SYSCALL_TRAP TRAP(solaris_sparc_syscall)
128 #else
129 #define SOLARIS_SYSCALL_TRAP TRAP(solaris_syscall)
130 #endif
131 /* FIXME: Write these actually */
132 #define NETBSD_SYSCALL_TRAP TRAP(netbsd_syscall)
133 #define BREAKPOINT_TRAP TRAP(breakpoint_trap)
134 
135 #define TRAP_IRQ(routine, level)			\
136 	rdpr	%pil, %g2;				\
137 	wrpr	%g0, 15, %pil;				\
138 	b,pt	%xcc, etrap_irq;			\
139 	 rd	%pc, %g7;				\
140 	mov	level, %o0;				\
141 	call	routine;				\
142 	 add	%sp, PTREGS_OFF, %o1;			\
143 	ba,a,pt	%xcc, rtrap_clr_l6;
144 
145 #define TICK_SMP_IRQ					\
146 	rdpr	%pil, %g2;				\
147 	wrpr	%g0, 15, %pil;				\
148 	sethi	%hi(109f), %g7;				\
149 	b,pt	%xcc, etrap_irq;			\
150 109:	 or	%g7, %lo(109b), %g7;			\
151 	call	smp_percpu_timer_interrupt;		\
152 	 add	%sp, PTREGS_OFF, %o0;			\
153 	ba,a,pt	%xcc, rtrap_clr_l6;
154 
155 #define TRAP_IVEC TRAP_NOSAVE(do_ivec)
156 
157 #define BTRAP(lvl) TRAP_ARG(bad_trap, lvl)
158 
159 #define BTRAPTL1(lvl) TRAPTL1_ARG(bad_trap_tl1, lvl)
160 
161 #define FLUSH_WINDOW_TRAP						\
162 	ba,pt	%xcc, etrap;						\
163 	 rd	%pc, %g7;						\
164 	flushw;								\
165 	ldx	[%sp + PTREGS_OFF + PT_V9_TNPC], %l1;			\
166 	add	%l1, 4, %l2;						\
167 	stx	%l1, [%sp + PTREGS_OFF + PT_V9_TPC];			\
168 	ba,pt	%xcc, rtrap_clr_l6;					\
169 	 stx	%l2, [%sp + PTREGS_OFF + PT_V9_TNPC];
170 
171 /* Before touching these macros, you owe it to yourself to go and
172  * see how arch/sparc64/kernel/winfixup.S works... -DaveM
173  *
174  * For the user cases we used to use the %asi register, but
175  * it turns out that the "wr xxx, %asi" costs ~5 cycles, so
176  * now we use immediate ASI loads and stores instead.  Kudos
177  * to Greg Onufer for pointing out this performance anomaly.
178  *
179  * Further note that we cannot use the g2, g4, g5, and g7 alternate
180  * globals in the spill routines, check out the save instruction in
181  * arch/sparc64/kernel/etrap.S to see what I mean about g2, and
182  * g4/g5 are the globals which are preserved by etrap processing
183  * for the caller of it.  The g7 register is the return pc for
184  * etrap.  Finally, g6 is the current thread register so we cannot
185  * us it in the spill handlers either.  Most of these rules do not
186  * apply to fill processing, only g6 is not usable.
187  */
188 
189 /* Normal kernel spill */
190 #define SPILL_0_NORMAL					\
191 	stx	%l0, [%sp + STACK_BIAS + 0x00];		\
192 	stx	%l1, [%sp + STACK_BIAS + 0x08];		\
193 	stx	%l2, [%sp + STACK_BIAS + 0x10];		\
194 	stx	%l3, [%sp + STACK_BIAS + 0x18];		\
195 	stx	%l4, [%sp + STACK_BIAS + 0x20];		\
196 	stx	%l5, [%sp + STACK_BIAS + 0x28];		\
197 	stx	%l6, [%sp + STACK_BIAS + 0x30];		\
198 	stx	%l7, [%sp + STACK_BIAS + 0x38];		\
199 	stx	%i0, [%sp + STACK_BIAS + 0x40];		\
200 	stx	%i1, [%sp + STACK_BIAS + 0x48];		\
201 	stx	%i2, [%sp + STACK_BIAS + 0x50];		\
202 	stx	%i3, [%sp + STACK_BIAS + 0x58];		\
203 	stx	%i4, [%sp + STACK_BIAS + 0x60];		\
204 	stx	%i5, [%sp + STACK_BIAS + 0x68];		\
205 	stx	%i6, [%sp + STACK_BIAS + 0x70];		\
206 	stx	%i7, [%sp + STACK_BIAS + 0x78];		\
207 	saved; retry; nop; nop; nop; nop; nop; nop;	\
208 	nop; nop; nop; nop; nop; nop; nop; nop;
209 
210 /* Normal 64bit spill */
211 #define SPILL_1_GENERIC(ASI)				\
212 	add	%sp, STACK_BIAS + 0x00, %g1;		\
213 	stxa	%l0, [%g1 + %g0] ASI;			\
214 	mov	0x08, %g3;				\
215 	stxa	%l1, [%g1 + %g3] ASI;			\
216 	add	%g1, 0x10, %g1;				\
217 	stxa	%l2, [%g1 + %g0] ASI;			\
218 	stxa	%l3, [%g1 + %g3] ASI;			\
219 	add	%g1, 0x10, %g1;				\
220 	stxa	%l4, [%g1 + %g0] ASI;			\
221 	stxa	%l5, [%g1 + %g3] ASI;			\
222 	add	%g1, 0x10, %g1;				\
223 	stxa	%l6, [%g1 + %g0] ASI;			\
224 	stxa	%l7, [%g1 + %g3] ASI;			\
225 	add	%g1, 0x10, %g1;				\
226 	stxa	%i0, [%g1 + %g0] ASI;			\
227 	stxa	%i1, [%g1 + %g3] ASI;			\
228 	add	%g1, 0x10, %g1;				\
229 	stxa	%i2, [%g1 + %g0] ASI;			\
230 	stxa	%i3, [%g1 + %g3] ASI;			\
231 	add	%g1, 0x10, %g1;				\
232 	stxa	%i4, [%g1 + %g0] ASI;			\
233 	stxa	%i5, [%g1 + %g3] ASI;			\
234 	add	%g1, 0x10, %g1;				\
235 	stxa	%i6, [%g1 + %g0] ASI;			\
236 	stxa	%i7, [%g1 + %g3] ASI;			\
237 	saved;						\
238 	retry; nop; nop;				\
239 	b,a,pt	%xcc, spill_fixup_dax;			\
240 	b,a,pt	%xcc, spill_fixup_mna;			\
241 	b,a,pt	%xcc, spill_fixup;
242 
243 /* Normal 32bit spill */
244 #define SPILL_2_GENERIC(ASI)				\
245 	srl	%sp, 0, %sp;				\
246 	stwa	%l0, [%sp + %g0] ASI;			\
247 	mov	0x04, %g3;				\
248 	stwa	%l1, [%sp + %g3] ASI;			\
249 	add	%sp, 0x08, %g1;				\
250 	stwa	%l2, [%g1 + %g0] ASI;			\
251 	stwa	%l3, [%g1 + %g3] ASI;			\
252 	add	%g1, 0x08, %g1;				\
253 	stwa	%l4, [%g1 + %g0] ASI;			\
254 	stwa	%l5, [%g1 + %g3] ASI;			\
255 	add	%g1, 0x08, %g1;				\
256 	stwa	%l6, [%g1 + %g0] ASI;			\
257 	stwa	%l7, [%g1 + %g3] ASI;			\
258 	add	%g1, 0x08, %g1;				\
259 	stwa	%i0, [%g1 + %g0] ASI;			\
260 	stwa	%i1, [%g1 + %g3] ASI;			\
261 	add	%g1, 0x08, %g1;				\
262 	stwa	%i2, [%g1 + %g0] ASI;			\
263 	stwa	%i3, [%g1 + %g3] ASI;			\
264 	add	%g1, 0x08, %g1;				\
265 	stwa	%i4, [%g1 + %g0] ASI;			\
266 	stwa	%i5, [%g1 + %g3] ASI;			\
267 	add	%g1, 0x08, %g1;				\
268 	stwa	%i6, [%g1 + %g0] ASI;			\
269 	stwa	%i7, [%g1 + %g3] ASI;			\
270 	saved;						\
271         retry; nop; nop;				\
272 	b,a,pt	%xcc, spill_fixup_dax;			\
273 	b,a,pt	%xcc, spill_fixup_mna;			\
274 	b,a,pt	%xcc, spill_fixup;
275 
276 #define SPILL_1_NORMAL SPILL_1_GENERIC(ASI_AIUP)
277 #define SPILL_2_NORMAL SPILL_2_GENERIC(ASI_AIUP)
278 #define SPILL_3_NORMAL SPILL_0_NORMAL
279 #define SPILL_4_NORMAL SPILL_0_NORMAL
280 #define SPILL_5_NORMAL SPILL_0_NORMAL
281 #define SPILL_6_NORMAL SPILL_0_NORMAL
282 #define SPILL_7_NORMAL SPILL_0_NORMAL
283 
284 #define SPILL_0_OTHER SPILL_0_NORMAL
285 #define SPILL_1_OTHER SPILL_1_GENERIC(ASI_AIUS)
286 #define SPILL_2_OTHER SPILL_2_GENERIC(ASI_AIUS)
287 #define SPILL_3_OTHER SPILL_3_NORMAL
288 #define SPILL_4_OTHER SPILL_4_NORMAL
289 #define SPILL_5_OTHER SPILL_5_NORMAL
290 #define SPILL_6_OTHER SPILL_6_NORMAL
291 #define SPILL_7_OTHER SPILL_7_NORMAL
292 
293 /* Normal kernel fill */
294 #define FILL_0_NORMAL					\
295 	ldx	[%sp + STACK_BIAS + 0x00], %l0;		\
296 	ldx	[%sp + STACK_BIAS + 0x08], %l1;		\
297 	ldx	[%sp + STACK_BIAS + 0x10], %l2;		\
298 	ldx	[%sp + STACK_BIAS + 0x18], %l3;		\
299 	ldx	[%sp + STACK_BIAS + 0x20], %l4;		\
300 	ldx	[%sp + STACK_BIAS + 0x28], %l5;		\
301 	ldx	[%sp + STACK_BIAS + 0x30], %l6;		\
302 	ldx	[%sp + STACK_BIAS + 0x38], %l7;		\
303 	ldx	[%sp + STACK_BIAS + 0x40], %i0;		\
304 	ldx	[%sp + STACK_BIAS + 0x48], %i1;		\
305 	ldx	[%sp + STACK_BIAS + 0x50], %i2;		\
306 	ldx	[%sp + STACK_BIAS + 0x58], %i3;		\
307 	ldx	[%sp + STACK_BIAS + 0x60], %i4;		\
308 	ldx	[%sp + STACK_BIAS + 0x68], %i5;		\
309 	ldx	[%sp + STACK_BIAS + 0x70], %i6;		\
310 	ldx	[%sp + STACK_BIAS + 0x78], %i7;		\
311 	restored; retry; nop; nop; nop; nop; nop; nop;	\
312 	nop; nop; nop; nop; nop; nop; nop; nop;
313 
314 /* Normal 64bit fill */
315 #define FILL_1_GENERIC(ASI)				\
316 	add	%sp, STACK_BIAS + 0x00, %g1;		\
317 	ldxa	[%g1 + %g0] ASI, %l0;			\
318 	mov	0x08, %g2;				\
319 	mov	0x10, %g3;				\
320 	ldxa	[%g1 + %g2] ASI, %l1;			\
321 	mov	0x18, %g5;				\
322 	ldxa	[%g1 + %g3] ASI, %l2;			\
323 	ldxa	[%g1 + %g5] ASI, %l3;			\
324 	add	%g1, 0x20, %g1;				\
325 	ldxa	[%g1 + %g0] ASI, %l4;			\
326 	ldxa	[%g1 + %g2] ASI, %l5;			\
327 	ldxa	[%g1 + %g3] ASI, %l6;			\
328 	ldxa	[%g1 + %g5] ASI, %l7;			\
329 	add	%g1, 0x20, %g1;				\
330 	ldxa	[%g1 + %g0] ASI, %i0;			\
331 	ldxa	[%g1 + %g2] ASI, %i1;			\
332 	ldxa	[%g1 + %g3] ASI, %i2;			\
333 	ldxa	[%g1 + %g5] ASI, %i3;			\
334 	add	%g1, 0x20, %g1;				\
335 	ldxa	[%g1 + %g0] ASI, %i4;			\
336 	ldxa	[%g1 + %g2] ASI, %i5;			\
337 	ldxa	[%g1 + %g3] ASI, %i6;			\
338 	ldxa	[%g1 + %g5] ASI, %i7;			\
339 	restored;					\
340 	retry; nop; nop; nop; nop;			\
341 	b,a,pt	%xcc, fill_fixup_dax;			\
342 	b,a,pt	%xcc, fill_fixup_mna;			\
343 	b,a,pt	%xcc, fill_fixup;
344 
345 /* Normal 32bit fill */
346 #define FILL_2_GENERIC(ASI)				\
347 	srl	%sp, 0, %sp;				\
348 	lduwa	[%sp + %g0] ASI, %l0;			\
349 	mov	0x04, %g2;				\
350 	mov	0x08, %g3;				\
351 	lduwa	[%sp + %g2] ASI, %l1;			\
352 	mov	0x0c, %g5;				\
353 	lduwa	[%sp + %g3] ASI, %l2;			\
354 	lduwa	[%sp + %g5] ASI, %l3;			\
355 	add	%sp, 0x10, %g1;				\
356 	lduwa	[%g1 + %g0] ASI, %l4;			\
357 	lduwa	[%g1 + %g2] ASI, %l5;			\
358 	lduwa	[%g1 + %g3] ASI, %l6;			\
359 	lduwa	[%g1 + %g5] ASI, %l7;			\
360 	add	%g1, 0x10, %g1;				\
361 	lduwa	[%g1 + %g0] ASI, %i0;			\
362 	lduwa	[%g1 + %g2] ASI, %i1;			\
363 	lduwa	[%g1 + %g3] ASI, %i2;			\
364 	lduwa	[%g1 + %g5] ASI, %i3;			\
365 	add	%g1, 0x10, %g1;				\
366 	lduwa	[%g1 + %g0] ASI, %i4;			\
367 	lduwa	[%g1 + %g2] ASI, %i5;			\
368 	lduwa	[%g1 + %g3] ASI, %i6;			\
369 	lduwa	[%g1 + %g5] ASI, %i7;			\
370 	restored;					\
371 	retry; nop; nop; nop; nop;			\
372 	b,a,pt	%xcc, fill_fixup_dax;			\
373 	b,a,pt	%xcc, fill_fixup_mna;			\
374 	b,a,pt	%xcc, fill_fixup;
375 
376 #define FILL_1_NORMAL FILL_1_GENERIC(ASI_AIUP)
377 #define FILL_2_NORMAL FILL_2_GENERIC(ASI_AIUP)
378 #define FILL_3_NORMAL FILL_0_NORMAL
379 #define FILL_4_NORMAL FILL_0_NORMAL
380 #define FILL_5_NORMAL FILL_0_NORMAL
381 #define FILL_6_NORMAL FILL_0_NORMAL
382 #define FILL_7_NORMAL FILL_0_NORMAL
383 
384 #define FILL_0_OTHER FILL_0_NORMAL
385 #define FILL_1_OTHER FILL_1_GENERIC(ASI_AIUS)
386 #define FILL_2_OTHER FILL_2_GENERIC(ASI_AIUS)
387 #define FILL_3_OTHER FILL_3_NORMAL
388 #define FILL_4_OTHER FILL_4_NORMAL
389 #define FILL_5_OTHER FILL_5_NORMAL
390 #define FILL_6_OTHER FILL_6_NORMAL
391 #define FILL_7_OTHER FILL_7_NORMAL
392 
393 #endif /* !(_SPARC64_TTABLE_H) */
394