1/* $Id: etrap.S,v 1.45 2001/09/07 21:04:40 kanoj 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 <asm/asi.h>
9#include <asm/pstate.h>
10#include <asm/ptrace.h>
11#include <asm/page.h>
12#include <asm/spitfire.h>
13#include <asm/head.h>
14#include <asm/processor.h>
15
16#define		TASK_REGOFF		(THREAD_SIZE-TRACEREG_SZ-STACKFRAME_SZ)
17#define		ETRAP_PSTATE1		(PSTATE_RMO | PSTATE_PRIV)
18#define		ETRAP_PSTATE2		(PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV | PSTATE_IE)
19
20/*
21 * On entry, %g7 is return address - 0x4.
22 * %g4 and %g5 will be preserved %l4 and %l5 respectively.
23 */
24
25		.text
26		.align	64
27		.globl	etrap, etrap_irq, etraptl1
28
29etrap:		rdpr	%pil, %g2						! Single 	Group
30etrap_irq:	rdpr	%tstate, %g1						! Single 	Group
31		sllx	%g2, 20, %g3						! IEU0		Group
32		andcc	%g1, TSTATE_PRIV, %g0					! IEU1
33		or	%g1, %g3, %g1						! IEU0		Group
34		bne,pn	%xcc, 1f							! CTI
35		 sub	%sp, STACKFRAME_SZ+TRACEREG_SZ-STACK_BIAS, %g2		! IEU1
36		wrpr	%g0, 7, %cleanwin					! Single	Group+4bubbles
37
38		sethi	%hi(TASK_REGOFF), %g2					! IEU0		Group
39		sethi	%hi(TSTATE_PEF), %g3					! IEU1
40		or	%g2, %lo(TASK_REGOFF), %g2				! IEU0		Group
41		and	%g1, %g3, %g3						! IEU1
42		brnz,pn	%g3, 1f							! CTI+IEU1	Group
43		 add	%g6, %g2, %g2						! IEU0
44		wr	%g0, 0, %fprs						! Single	Group+4bubbles
451:		rdpr	%tpc, %g3						! Single	Group
46
47		stx	%g1, [%g2 + STACKFRAME_SZ + PT_V9_TSTATE]		! Store		Group
48		rdpr	%tnpc, %g1						! Single	Group
49		stx	%g3, [%g2 + STACKFRAME_SZ + PT_V9_TPC]			! Store		Group
50		rd	%y, %g3							! Single	Group+4bubbles
51		stx	%g1, [%g2 + STACKFRAME_SZ + PT_V9_TNPC]			! Store		Group
52		st	%g3, [%g2 + STACKFRAME_SZ + PT_V9_Y]			! Store		Group
53		save	%g2, -STACK_BIAS, %sp	! Ordering here is critical	! Single	Group
54		mov	%g6, %l6						! IEU0		Group
55
56		bne,pn	%xcc, 3f						! CTI
57		 mov	PRIMARY_CONTEXT, %l4					! IEU1
58		rdpr	%canrestore, %g3					! Single	Group+4bubbles
59		rdpr	%wstate, %g2						! Single	Group+4bubbles
60		wrpr	%g0, 0, %canrestore					! Single	Group+4bubbles
61		sll	%g2, 3, %g2						! IEU0		Group
62		mov	1, %l5							! IEU1
63		stb	%l5, [%l6 + AOFF_task_thread + AOFF_thread_fpdepth]	! Store
64
65		wrpr	%g3, 0, %otherwin					! Single	Group+4bubbles
66		wrpr	%g2, 0, %wstate						! Single	Group+4bubbles
67		stxa	%g0, [%l4] ASI_DMMU					! Store		Group
68		flush	%l6							! Single	Group+9bubbles
69		wr	%g0, ASI_AIUS, %asi					! Single	Group+4bubbles
702:		wrpr	%g0, 0x0, %tl						! Single	Group+4bubbles
71		mov	%g4, %l4						! IEU1
72		mov	%g5, %l5						! IEU0		Group
73
74		mov	%g7, %l2						! IEU1
75		wrpr	%g0, ETRAP_PSTATE1, %pstate				! Single	Group+4bubbles
76		stx	%g1, [%sp + PTREGS_OFF + PT_V9_G1]		! Store		Group
77		stx	%g2, [%sp + PTREGS_OFF + PT_V9_G2]		! Store		Group
78		stx	%g3, [%sp + PTREGS_OFF + PT_V9_G3]		! Store		Group
79		stx	%g4, [%sp + PTREGS_OFF + PT_V9_G4]		! Store		Group
80		stx	%g5, [%sp + PTREGS_OFF + PT_V9_G5]		! Store		Group
81		stx	%g6, [%sp + PTREGS_OFF + PT_V9_G6]		! Store		Group
82
83		stx	%g7, [%sp + PTREGS_OFF + PT_V9_G7]		! Store		Group
84		stx	%i0, [%sp + PTREGS_OFF + PT_V9_I0]		! Store		Group
85		stx	%i1, [%sp + PTREGS_OFF + PT_V9_I1]		! Store		Group
86		stx	%i2, [%sp + PTREGS_OFF + PT_V9_I2]		! Store		Group
87		stx	%i3, [%sp + PTREGS_OFF + PT_V9_I3]		! Store		Group
88		stx	%i4, [%sp + PTREGS_OFF + PT_V9_I4]		! Store		Group
89		sethi	%uhi(PAGE_OFFSET), %g4					! IEU0
90		stx	%i5, [%sp + PTREGS_OFF + PT_V9_I5]		! Store		Group
91
92		stx	%i6, [%sp + PTREGS_OFF + PT_V9_I6]		! Store		Group
93		sllx	%g4, 32, %g4						! IEU0
94		stx	%i7, [%sp + PTREGS_OFF + PT_V9_I7]		! Store		Group
95		wrpr	%g0, ETRAP_PSTATE2, %pstate				! Single	Group+4bubbles
96		jmpl	%l2 + 0x4, %g0						! CTI		Group
97		 mov	%l6, %g6						! IEU0
98		nop
99		nop
100
1013:		ldub	[%l6 + AOFF_task_thread + AOFF_thread_fpdepth], %l5	! Load		Group
102		add	%l6, AOFF_task_thread + AOFF_thread_fpsaved + 1, %l4	! IEU0
103		srl	%l5, 1, %l3						! IEU0		Group
104		add	%l5, 2, %l5						! IEU1
105		stb	%l5, [%l6 + AOFF_task_thread + AOFF_thread_fpdepth]	! Store
106		ba,pt	%xcc, 2b						! CTI
107		 stb	%g0, [%l4 + %l3]					! Store		Group
108		nop
109
110etraptl1:	/* Save tstate/tpc/tnpc of TL 1-->4 and the tl register itself.
111		 * We place this right after pt_regs on the trap stack.  The layout
112		 * is:
113		 *	0x00	TL1's TSTATE
114		 *	0x08	TL1's TPC
115		 *	0x10	TL1's TNPC
116		 *	0x18	TL1's TT
117		 *	 ...
118		 *	0x58	TL4's TT
119		 *	0x60	TL
120		 */
121		sub	%sp, ((4 * 8) * 4) + 8, %g2
122		rdpr	%tl, %g1
123
124		wrpr	%g0, 1, %tl
125		rdpr	%tstate, %g3
126		stx	%g3, [%g2 + STACK_BIAS + 0x00]
127		rdpr	%tpc, %g3
128		stx	%g3, [%g2 + STACK_BIAS + 0x08]
129		rdpr	%tnpc, %g3
130		stx	%g3, [%g2 + STACK_BIAS + 0x10]
131		rdpr	%tt, %g3
132		stx	%g3, [%g2 + STACK_BIAS + 0x18]
133
134		wrpr	%g0, 2, %tl
135		rdpr	%tstate, %g3
136		stx	%g3, [%g2 + STACK_BIAS + 0x20]
137		rdpr	%tpc, %g3
138		stx	%g3, [%g2 + STACK_BIAS + 0x28]
139		rdpr	%tnpc, %g3
140		stx	%g3, [%g2 + STACK_BIAS + 0x30]
141		rdpr	%tt, %g3
142		stx	%g3, [%g2 + STACK_BIAS + 0x38]
143
144		wrpr	%g0, 3, %tl
145		rdpr	%tstate, %g3
146		stx	%g3, [%g2 + STACK_BIAS + 0x40]
147		rdpr	%tpc, %g3
148		stx	%g3, [%g2 + STACK_BIAS + 0x48]
149		rdpr	%tnpc, %g3
150		stx	%g3, [%g2 + STACK_BIAS + 0x50]
151		rdpr	%tt, %g3
152		stx	%g3, [%g2 + STACK_BIAS + 0x58]
153
154		wrpr	%g0, 4, %tl
155		rdpr	%tstate, %g3
156		stx	%g3, [%g2 + STACK_BIAS + 0x60]
157		rdpr	%tpc, %g3
158		stx	%g3, [%g2 + STACK_BIAS + 0x68]
159		rdpr	%tnpc, %g3
160		stx	%g3, [%g2 + STACK_BIAS + 0x70]
161		rdpr	%tt, %g3
162		stx	%g3, [%g2 + STACK_BIAS + 0x78]
163
164		wrpr	%g1, %tl
165		stx	%g1, [%g2 + STACK_BIAS + 0x80]
166
167		rdpr	%tstate, %g1						! Single	Group+4bubbles
168		sub	%g2, STACKFRAME_SZ + TRACEREG_SZ - STACK_BIAS, %g2	! IEU1
169		ba,pt	%xcc, 1b						! CTI		Group
170		 andcc	%g1, TSTATE_PRIV, %g0					! IEU0
171
172		.align	64
173		.globl	scetrap
174scetrap:	rdpr	%pil, %g2						! Single 	Group
175		rdpr	%tstate, %g1						! Single 	Group
176		sllx	%g2, 20, %g3						! IEU0		Group
177		andcc	%g1, TSTATE_PRIV, %g0					! IEU1
178		or	%g1, %g3, %g1						! IEU0		Group
179		bne,pn	%xcc, 1f						! CTI
180		 sub	%sp, (STACKFRAME_SZ+TRACEREG_SZ-STACK_BIAS), %g2	! IEU1
181		wrpr	%g0, 7, %cleanwin					! Single	Group+4bubbles
182
183		sllx	%g1, 51, %g3						! IEU0		Group
184		sethi	%hi(TASK_REGOFF), %g2					! IEU1
185		or	%g2, %lo(TASK_REGOFF), %g2				! IEU0		Group
186		brlz,pn	%g3, 1f							! CTI+IEU1
187		 add	%g6, %g2, %g2						! IEU0		Group
188		wr	%g0, 0, %fprs						! Single	Group+4bubbles
1891:		rdpr	%tpc, %g3						! Single	Group
190		stx	%g1, [%g2 + STACKFRAME_SZ + PT_V9_TSTATE]		! Store		Group
191
192		rdpr	%tnpc, %g1						! Single	Group
193		stx	%g3, [%g2 + STACKFRAME_SZ + PT_V9_TPC]			! Store		Group
194		stx	%g1, [%g2 + STACKFRAME_SZ + PT_V9_TNPC]			! Store		Group
195		save	%g2, -STACK_BIAS, %sp	! Ordering here is critical	! Single	Group
196		mov	%g6, %l6						! IEU0		Group
197		bne,pn	%xcc, 2f						! CTI
198		 mov	ASI_P, %l7						! IEU1
199		rdpr	%canrestore, %g3					! Single	Group+4bubbles
200
201		rdpr	%wstate, %g2						! Single	Group+4bubbles
202		wrpr	%g0, 0, %canrestore					! Single	Group+4bubbles
203		sll	%g2, 3, %g2						! IEU0		Group
204		mov	PRIMARY_CONTEXT, %l4					! IEU1
205		wrpr	%g3, 0, %otherwin					! Single	Group+4bubbles
206		wrpr	%g2, 0, %wstate						! Single	Group+4bubbles
207		stxa	%g0, [%l4] ASI_DMMU					! Store
208		flush	%l6							! Single	Group+9bubbles
209
210		mov	ASI_AIUS, %l7						! IEU0		Group
2112:		mov	%g4, %l4						! IEU1
212		mov	%g5, %l5						! IEU0		Group
213		add	%g7, 0x4, %l2						! IEU1
214		wrpr	%g0, ETRAP_PSTATE1, %pstate				! Single	Group+4bubbles
215		stx	%g1, [%sp + PTREGS_OFF + PT_V9_G1]		! Store		Group
216		stx	%g2, [%sp + PTREGS_OFF + PT_V9_G2]		! Store		Group
217		sllx	%l7, 24, %l7						! IEU0
218
219		stx	%g3, [%sp + PTREGS_OFF + PT_V9_G3]		! Store		Group
220		rdpr	%cwp, %l0						! Single	Group
221		stx	%g4, [%sp + PTREGS_OFF + PT_V9_G4]		! Store		Group
222		stx	%g5, [%sp + PTREGS_OFF + PT_V9_G5]		! Store		Group
223		stx	%g6, [%sp + PTREGS_OFF + PT_V9_G6]		! Store		Group
224		stx	%g7, [%sp + PTREGS_OFF + PT_V9_G7]		! Store		Group
225		or	%l7, %l0, %l7						! IEU0
226		sethi	%hi(TSTATE_RMO | TSTATE_PEF), %l0			! IEU1
227
228		or	%l7, %l0, %l7						! IEU0		Group
229		wrpr	%l2, %tnpc						! Single	Group+4bubbles
230		wrpr	%l7, (TSTATE_PRIV | TSTATE_IE), %tstate			! Single	Group+4bubbles
231		stx	%i0, [%sp + PTREGS_OFF + PT_V9_I0]		! Store		Group
232		stx	%i1, [%sp + PTREGS_OFF + PT_V9_I1]		! Store		Group
233		stx	%i2, [%sp + PTREGS_OFF + PT_V9_I2]		! Store		Group
234		stx	%i3, [%sp + PTREGS_OFF + PT_V9_I3]		! Store		Group
235		stx	%i4, [%sp + PTREGS_OFF + PT_V9_I4]		! Store		Group
236
237		sethi	%uhi(PAGE_OFFSET), %g4					! IEU0
238		stx	%i5, [%sp + PTREGS_OFF + PT_V9_I5]		! Store		Group
239		stx	%i6, [%sp + PTREGS_OFF + PT_V9_I6]		! Store		Group
240		sllx	%g4, 32, %g4						! IEU0
241		mov	%l6, %g6						! IEU1
242		stx	%i7, [%sp + PTREGS_OFF + PT_V9_I7]		! Store		Group
243		done
244		nop
245
246#undef TASK_REGOFF
247#undef ETRAP_PSTATE1
248#undef ETRAP_PSTATE2
249