xref: /illumos-gate/usr/src/uts/sun4u/ml/wbuf.S (revision 55fea89dcaa64928bed4327112404dcb3e07b79f)
1*5d9d9091SRichard Lowe/*
2*5d9d9091SRichard Lowe * CDDL HEADER START
3*5d9d9091SRichard Lowe *
4*5d9d9091SRichard Lowe * The contents of this file are subject to the terms of the
5*5d9d9091SRichard Lowe * Common Development and Distribution License (the "License").
6*5d9d9091SRichard Lowe * You may not use this file except in compliance with the License.
7*5d9d9091SRichard Lowe *
8*5d9d9091SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5d9d9091SRichard Lowe * or http://www.opensolaris.org/os/licensing.
10*5d9d9091SRichard Lowe * See the License for the specific language governing permissions
11*5d9d9091SRichard Lowe * and limitations under the License.
12*5d9d9091SRichard Lowe *
13*5d9d9091SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
14*5d9d9091SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5d9d9091SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
16*5d9d9091SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
17*5d9d9091SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
18*5d9d9091SRichard Lowe *
19*5d9d9091SRichard Lowe * CDDL HEADER END
20*5d9d9091SRichard Lowe */
21*5d9d9091SRichard Lowe/*
22*5d9d9091SRichard Lowe * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*5d9d9091SRichard Lowe * Use is subject to license terms.
24*5d9d9091SRichard Lowe */
25*5d9d9091SRichard Lowe
26*5d9d9091SRichard Lowe#include <sys/asm_linkage.h>
27*5d9d9091SRichard Lowe#include <sys/machthread.h>
28*5d9d9091SRichard Lowe#include <sys/privregs.h>
29*5d9d9091SRichard Lowe#include <sys/machasi.h>
30*5d9d9091SRichard Lowe#include <sys/trap.h>
31*5d9d9091SRichard Lowe#include <sys/mmu.h>
32*5d9d9091SRichard Lowe#include <sys/machparam.h>
33*5d9d9091SRichard Lowe#include <sys/machtrap.h>
34*5d9d9091SRichard Lowe#include <sys/traptrace.h>
35*5d9d9091SRichard Lowe
36*5d9d9091SRichard Lowe#include "assym.h"
37*5d9d9091SRichard Lowe
38*5d9d9091SRichard Lowe	/*
39*5d9d9091SRichard Lowe	 * Spill fault handlers
40*5d9d9091SRichard Lowe	 *   sn0 - spill normal tl 0
41*5d9d9091SRichard Lowe	 *   sn1 - spill normal tl >0
42*5d9d9091SRichard Lowe	 *   so0 - spill other tl 0
43*5d9d9091SRichard Lowe	 *   so1 - spill other tl >0
44*5d9d9091SRichard Lowe	 */
45*5d9d9091SRichard Lowe
46*5d9d9091SRichard Lowe	ENTRY_NP(fault_32bit_sn0)
47*5d9d9091SRichard Lowe	!
48*5d9d9091SRichard Lowe	FAULT_WINTRACE(%g1, %g2, %g3, TT_F32_SN0)
49*5d9d9091SRichard Lowe	!
50*5d9d9091SRichard Lowe	! Spill normal tl0 fault.
51*5d9d9091SRichard Lowe	! This happens when a user tries to spill to an unmapped or
52*5d9d9091SRichard Lowe	! misaligned stack. We handle an unmapped stack by simulating
53*5d9d9091SRichard Lowe	! a pagefault at the trap pc and a misaligned stack by generating
54*5d9d9091SRichard Lowe	! a user alignment trap.
55*5d9d9091SRichard Lowe	!
56*5d9d9091SRichard Lowe	! spill the window into wbuf slot 0
57*5d9d9091SRichard Lowe	! (we know wbuf is empty since we came from user mode)
58*5d9d9091SRichard Lowe	!
59*5d9d9091SRichard Lowe	! g5 = mmu trap type, g6 = tag access reg (g5 != T_ALIGNMENT) or
60*5d9d9091SRichard Lowe	! sfar (g5 == T_ALIGNMENT)
61*5d9d9091SRichard Lowe	!
62*5d9d9091SRichard Lowe	CPU_ADDR(%g4, %g1)
63*5d9d9091SRichard Lowe	ldn	[%g4 + CPU_MPCB], %g1
64*5d9d9091SRichard Lowe	stn	%sp, [%g1 + MPCB_SPBUF]
65*5d9d9091SRichard Lowe	ldn	[%g1 + MPCB_WBUF], %g2
66*5d9d9091SRichard Lowe	SAVE_V8WINDOW(%g2)
67*5d9d9091SRichard Lowe	mov	1, %g2
68*5d9d9091SRichard Lowe	st	%g2, [%g1 + MPCB_WBCNT]
69*5d9d9091SRichard Lowe	saved
70*5d9d9091SRichard Lowe	!
71*5d9d9091SRichard Lowe	! setup user_trap args
72*5d9d9091SRichard Lowe	!
73*5d9d9091SRichard Lowe	set	sfmmu_tsbmiss_exception, %g1
74*5d9d9091SRichard Lowe	mov	%g6, %g2			! arg2 = tagaccess
75*5d9d9091SRichard Lowe	mov	T_WIN_OVERFLOW, %g3		! arg3 = traptype
76*5d9d9091SRichard Lowe	cmp	%g5, T_ALIGNMENT
77*5d9d9091SRichard Lowe	bne	%icc, 1f
78*5d9d9091SRichard Lowe	nop
79*5d9d9091SRichard Lowe	set	trap, %g1
80*5d9d9091SRichard Lowe	mov	T_ALIGNMENT, %g3
81*5d9d9091SRichard Lowe1:
82*5d9d9091SRichard Lowe	sub	%g0, 1, %g4
83*5d9d9091SRichard Lowe	!
84*5d9d9091SRichard Lowe	! spill traps increment %cwp by 2,
85*5d9d9091SRichard Lowe	! but user_trap wants the trap %cwp
86*5d9d9091SRichard Lowe	!
87*5d9d9091SRichard Lowe	rdpr	%tstate, %g5
88*5d9d9091SRichard Lowe	and	%g5, TSTATE_CWP, %g5
89*5d9d9091SRichard Lowe	ba,pt	%xcc, user_trap
90*5d9d9091SRichard Lowe	wrpr	%g0, %g5, %cwp
91*5d9d9091SRichard Lowe	SET_SIZE(fault_32bit_sn0)
92*5d9d9091SRichard Lowe
93*5d9d9091SRichard Lowe	!
94*5d9d9091SRichard Lowe	! Spill normal tl1 fault.
95*5d9d9091SRichard Lowe	! This happens when sys_trap's save spills to an unmapped stack.
96*5d9d9091SRichard Lowe	! We handle it by spilling the window to the wbuf and trying
97*5d9d9091SRichard Lowe	! sys_trap again.
98*5d9d9091SRichard Lowe	!
99*5d9d9091SRichard Lowe	! spill the window into wbuf slot 0
100*5d9d9091SRichard Lowe	! (we know wbuf is empty since we came from user mode)
101*5d9d9091SRichard Lowe	!
102*5d9d9091SRichard Lowe	ENTRY_NP(fault_32bit_sn1)
103*5d9d9091SRichard Lowe	FAULT_WINTRACE(%g5, %g6, %g7, TT_F32_SN1)
104*5d9d9091SRichard Lowe	CPU_ADDR(%g5, %g6)
105*5d9d9091SRichard Lowe	ldn	[%g5 + CPU_MPCB], %g6
106*5d9d9091SRichard Lowe	stn	%sp, [%g6 + MPCB_SPBUF]
107*5d9d9091SRichard Lowe	ldn	[%g6 + MPCB_WBUF], %g5
108*5d9d9091SRichard Lowe	SAVE_V8WINDOW(%g5)
109*5d9d9091SRichard Lowe	mov	1, %g5
110*5d9d9091SRichard Lowe	st	%g5, [%g6 + MPCB_WBCNT]
111*5d9d9091SRichard Lowe	saved
112*5d9d9091SRichard Lowe	set	sys_trap, %g5
113*5d9d9091SRichard Lowe	wrpr	%g5, %tnpc
114*5d9d9091SRichard Lowe	done
115*5d9d9091SRichard Lowe	SET_SIZE(fault_32bit_sn1)
116*5d9d9091SRichard Lowe
117*5d9d9091SRichard Lowe	ENTRY_NP(fault_32bit_so0)
118*5d9d9091SRichard Lowe	!
119*5d9d9091SRichard Lowe	FAULT_WINTRACE(%g5, %g6, %g1, TT_F32_SO0)
120*5d9d9091SRichard Lowe	!
121*5d9d9091SRichard Lowe	! Spill other tl0 fault.
122*5d9d9091SRichard Lowe	! This happens when the kernel spills a user window and that
123*5d9d9091SRichard Lowe	! user's stack has been unmapped.
124*5d9d9091SRichard Lowe	! We handle it by spilling the window into the user's wbuf.
125*5d9d9091SRichard Lowe	!
126*5d9d9091SRichard Lowe	! find lwp & increment wbcnt
127*5d9d9091SRichard Lowe	!
128*5d9d9091SRichard Lowe	CPU_ADDR(%g5, %g6)
129*5d9d9091SRichard Lowe	ldn	[%g5 + CPU_MPCB], %g1
130*5d9d9091SRichard Lowe	ld	[%g1 + MPCB_WBCNT], %g2
131*5d9d9091SRichard Lowe	add	%g2, 1, %g3
132*5d9d9091SRichard Lowe	st	%g3, [%g1 + MPCB_WBCNT]
133*5d9d9091SRichard Lowe	!
134*5d9d9091SRichard Lowe	! use previous wbcnt to spill new spbuf & wbuf
135*5d9d9091SRichard Lowe	!
136*5d9d9091SRichard Lowe	sll	%g2, CPTRSHIFT, %g4		! spbuf size is sizeof (caddr_t)
137*5d9d9091SRichard Lowe	add	%g1, MPCB_SPBUF, %g3
138*5d9d9091SRichard Lowe	stn	%sp, [%g3 + %g4]
139*5d9d9091SRichard Lowe	sll	%g2, RWIN32SHIFT, %g4
140*5d9d9091SRichard Lowe	ldn	[%g1 + MPCB_WBUF], %g3
141*5d9d9091SRichard Lowe	add	%g3, %g4, %g3
142*5d9d9091SRichard Lowe	SAVE_V8WINDOW(%g3)
143*5d9d9091SRichard Lowe	saved
144*5d9d9091SRichard Lowe	retry
145*5d9d9091SRichard Lowe	SET_SIZE(fault_32bit_so0)
146*5d9d9091SRichard Lowe
147*5d9d9091SRichard Lowe	!
148*5d9d9091SRichard Lowe	! Spill other tl1 fault.
149*5d9d9091SRichard Lowe	! This happens when priv_trap spills a user window and that
150*5d9d9091SRichard Lowe	! user's stack has been unmapped.
151*5d9d9091SRichard Lowe	! We handle it by spilling the window to the wbuf and retrying
152*5d9d9091SRichard Lowe	! the save.
153*5d9d9091SRichard Lowe	!
154*5d9d9091SRichard Lowe	ENTRY_NP(fault_32bit_so1)
155*5d9d9091SRichard Lowe	FAULT_WINTRACE(%g5, %g6, %g7, TT_F32_SO1)
156*5d9d9091SRichard Lowe	CPU_ADDR(%g5, %g6)
157*5d9d9091SRichard Lowe	!
158*5d9d9091SRichard Lowe	! find lwp & increment wbcnt
159*5d9d9091SRichard Lowe	!
160*5d9d9091SRichard Lowe	ldn	[%g5 + CPU_MPCB], %g6
161*5d9d9091SRichard Lowe	ld	[%g6 + MPCB_WBCNT], %g5
162*5d9d9091SRichard Lowe	add	%g5, 1, %g7
163*5d9d9091SRichard Lowe	st	%g7, [%g6 + MPCB_WBCNT]
164*5d9d9091SRichard Lowe	!
165*5d9d9091SRichard Lowe	! use previous wbcnt to spill new spbuf & wbuf
166*5d9d9091SRichard Lowe	!
167*5d9d9091SRichard Lowe	sll	%g5, CPTRSHIFT, %g7		! spbuf size is sizeof (caddr_t)
168*5d9d9091SRichard Lowe	add	%g6, %g7, %g7
169*5d9d9091SRichard Lowe	stn	%sp, [%g7 + MPCB_SPBUF]
170*5d9d9091SRichard Lowe	sll	%g5, RWIN32SHIFT, %g7
171*5d9d9091SRichard Lowe	ldn	[%g6 + MPCB_WBUF], %g5
172*5d9d9091SRichard Lowe	add	%g5, %g7, %g7
173*5d9d9091SRichard Lowe	SAVE_V8WINDOW(%g7)
174*5d9d9091SRichard Lowe	saved
175*5d9d9091SRichard Lowe	set	sys_trap, %g5
176*5d9d9091SRichard Lowe	wrpr	%g5, %tnpc
177*5d9d9091SRichard Lowe	done
178*5d9d9091SRichard Lowe	SET_SIZE(fault_32bit_so1)
179*5d9d9091SRichard Lowe
180*5d9d9091SRichard Lowe	ENTRY_NP(fault_64bit_sn0)
181*5d9d9091SRichard Lowe	!
182*5d9d9091SRichard Lowe	FAULT_WINTRACE(%g1, %g2, %g3, TT_F64_SN0)
183*5d9d9091SRichard Lowe	!
184*5d9d9091SRichard Lowe	! Spill normal tl0 fault.
185*5d9d9091SRichard Lowe	! This happens when a user tries to spill to an unmapped or
186*5d9d9091SRichard Lowe	! misaligned stack. We handle an unmapped stack by simulating
187*5d9d9091SRichard Lowe	! a pagefault at the trap pc and a misaligned stack by generating
188*5d9d9091SRichard Lowe	! a user alignment trap.
189*5d9d9091SRichard Lowe	!
190*5d9d9091SRichard Lowe	! spill the window into wbuf slot 0
191*5d9d9091SRichard Lowe	! (we know wbuf is empty since we came from user mode)
192*5d9d9091SRichard Lowe	!
193*5d9d9091SRichard Lowe	! g5 = mmu trap type, g6 = tag access reg (g5 != T_ALIGNMENT) or
194*5d9d9091SRichard Lowe	! sfar (g5 == T_ALIGNMENT)
195*5d9d9091SRichard Lowe	!
196*5d9d9091SRichard Lowe	CPU_ADDR(%g4, %g1)
197*5d9d9091SRichard Lowe	ldn	[%g4 + CPU_MPCB], %g1
198*5d9d9091SRichard Lowe	stn	%sp, [%g1 + MPCB_SPBUF]
199*5d9d9091SRichard Lowe	ldn	[%g1 + MPCB_WBUF], %g2
200*5d9d9091SRichard Lowe	SAVE_V9WINDOW(%g2)
201*5d9d9091SRichard Lowe	mov	1, %g2
202*5d9d9091SRichard Lowe	st	%g2, [%g1 + MPCB_WBCNT]
203*5d9d9091SRichard Lowe	saved
204*5d9d9091SRichard Lowe	!
205*5d9d9091SRichard Lowe	! setup user_trap args
206*5d9d9091SRichard Lowe	!
207*5d9d9091SRichard Lowe	set	sfmmu_tsbmiss_exception, %g1
208*5d9d9091SRichard Lowe	mov	%g6, %g2			! arg2 = tagaccess
209*5d9d9091SRichard Lowe	mov	%g5, %g3			! arg3 = traptype
210*5d9d9091SRichard Lowe	cmp	%g5, T_ALIGNMENT
211*5d9d9091SRichard Lowe	bne	%icc, 1f
212*5d9d9091SRichard Lowe	nop
213*5d9d9091SRichard Lowe	set	trap, %g1
214*5d9d9091SRichard Lowe	mov	T_ALIGNMENT, %g3
215*5d9d9091SRichard Lowe1:
216*5d9d9091SRichard Lowe	sub	%g0, 1, %g4
217*5d9d9091SRichard Lowe	!
218*5d9d9091SRichard Lowe	! spill traps increment %cwp by 2,
219*5d9d9091SRichard Lowe	! but user_trap wants the trap %cwp
220*5d9d9091SRichard Lowe	!
221*5d9d9091SRichard Lowe	rdpr	%tstate, %g5
222*5d9d9091SRichard Lowe	and	%g5, TSTATE_CWP, %g5
223*5d9d9091SRichard Lowe	ba,pt	%xcc, user_trap
224*5d9d9091SRichard Lowe	  wrpr	%g0, %g5, %cwp
225*5d9d9091SRichard Lowe	SET_SIZE(fault_64bit_sn0)
226*5d9d9091SRichard Lowe
227*5d9d9091SRichard Lowe	!
228*5d9d9091SRichard Lowe	! Spill normal tl1 fault.
229*5d9d9091SRichard Lowe	! This happens when sys_trap's save spills to an unmapped stack.
230*5d9d9091SRichard Lowe	! We handle it by spilling the window to the wbuf and trying
231*5d9d9091SRichard Lowe	! sys_trap again.
232*5d9d9091SRichard Lowe	!
233*5d9d9091SRichard Lowe	! spill the window into wbuf slot 0
234*5d9d9091SRichard Lowe	! (we know wbuf is empty since we came from user mode)
235*5d9d9091SRichard Lowe	!
236*5d9d9091SRichard Lowe	ENTRY_NP(fault_64bit_sn1)
237*5d9d9091SRichard Lowe	FAULT_WINTRACE(%g5, %g6, %g7, TT_F64_SN1)
238*5d9d9091SRichard Lowe	CPU_ADDR(%g5, %g6)
239*5d9d9091SRichard Lowe	ldn	[%g5 + CPU_MPCB], %g6
240*5d9d9091SRichard Lowe	stn	%sp, [%g6 + MPCB_SPBUF]
241*5d9d9091SRichard Lowe	ldn	[%g6 + MPCB_WBUF], %g5
242*5d9d9091SRichard Lowe	SAVE_V9WINDOW(%g5)
243*5d9d9091SRichard Lowe	mov	1, %g5
244*5d9d9091SRichard Lowe	st	%g5, [%g6 + MPCB_WBCNT]
245*5d9d9091SRichard Lowe	saved
246*5d9d9091SRichard Lowe	set	sys_trap, %g5
247*5d9d9091SRichard Lowe	wrpr	%g5, %tnpc
248*5d9d9091SRichard Lowe	done
249*5d9d9091SRichard Lowe	SET_SIZE(fault_64bit_sn1)
250*5d9d9091SRichard Lowe
251*5d9d9091SRichard Lowe	ENTRY_NP(fault_64bit_so0)
252*5d9d9091SRichard Lowe	!
253*5d9d9091SRichard Lowe	FAULT_WINTRACE(%g5, %g6, %g1, TT_F64_SO0)
254*5d9d9091SRichard Lowe	!
255*5d9d9091SRichard Lowe	! Spill other tl0 fault.
256*5d9d9091SRichard Lowe	! This happens when the kernel spills a user window and that
257*5d9d9091SRichard Lowe	! user's stack has been unmapped.
258*5d9d9091SRichard Lowe	! We handle it by spilling the window into the user's wbuf.
259*5d9d9091SRichard Lowe	!
260*5d9d9091SRichard Lowe	! find lwp & increment wbcnt
261*5d9d9091SRichard Lowe	!
262*5d9d9091SRichard Lowe	CPU_ADDR(%g5, %g6)
263*5d9d9091SRichard Lowe	ldn	[%g5 + CPU_MPCB], %g1
264*5d9d9091SRichard Lowe	ld	[%g1 + MPCB_WBCNT], %g2
265*5d9d9091SRichard Lowe	add	%g2, 1, %g3
266*5d9d9091SRichard Lowe	st	%g3, [%g1 + MPCB_WBCNT]
267*5d9d9091SRichard Lowe	!
268*5d9d9091SRichard Lowe	! use previous wbcnt to spill new spbuf & wbuf
269*5d9d9091SRichard Lowe	!
270*5d9d9091SRichard Lowe	sll	%g2, CPTRSHIFT, %g4		! spbuf size is sizeof (caddr_t)
271*5d9d9091SRichard Lowe	add	%g1, MPCB_SPBUF, %g3
272*5d9d9091SRichard Lowe	stn	%sp, [%g3 + %g4]
273*5d9d9091SRichard Lowe	sll	%g2, RWIN64SHIFT, %g4
274*5d9d9091SRichard Lowe	ldn	[%g1 + MPCB_WBUF], %g3
275*5d9d9091SRichard Lowe	add	%g3, %g4, %g3
276*5d9d9091SRichard Lowe	SAVE_V9WINDOW(%g3)
277*5d9d9091SRichard Lowe	saved
278*5d9d9091SRichard Lowe	retry
279*5d9d9091SRichard Lowe	SET_SIZE(fault_64bit_so0)
280*5d9d9091SRichard Lowe
281*5d9d9091SRichard Lowe	!
282*5d9d9091SRichard Lowe	! Spill other tl1 fault.
283*5d9d9091SRichard Lowe	! This happens when priv_trap spills a user window and that
284*5d9d9091SRichard Lowe	! user's stack has been unmapped.
285*5d9d9091SRichard Lowe	! We handle it by spilling the window to the wbuf and retrying
286*5d9d9091SRichard Lowe	! the save.
287*5d9d9091SRichard Lowe	!
288*5d9d9091SRichard Lowe	ENTRY_NP(fault_64bit_so1)
289*5d9d9091SRichard Lowe	FAULT_WINTRACE(%g5, %g6, %g7, TT_F64_SO1)
290*5d9d9091SRichard Lowe	CPU_ADDR(%g5, %g6)
291*5d9d9091SRichard Lowe	!
292*5d9d9091SRichard Lowe	! find lwp & increment wbcnt
293*5d9d9091SRichard Lowe	!
294*5d9d9091SRichard Lowe	ldn	[%g5 + CPU_MPCB], %g6
295*5d9d9091SRichard Lowe	ld	[%g6 + MPCB_WBCNT], %g5
296*5d9d9091SRichard Lowe	add	%g5, 1, %g7
297*5d9d9091SRichard Lowe	st	%g7, [%g6 + MPCB_WBCNT]
298*5d9d9091SRichard Lowe	!
299*5d9d9091SRichard Lowe	! use previous wbcnt to spill new spbuf & wbuf
300*5d9d9091SRichard Lowe	!
301*5d9d9091SRichard Lowe	sll	%g5, CPTRSHIFT, %g7		! spbuf size is sizeof (caddr_t)
302*5d9d9091SRichard Lowe	add	%g6, %g7, %g7
303*5d9d9091SRichard Lowe	stn	%sp, [%g7 + MPCB_SPBUF]
304*5d9d9091SRichard Lowe	sll	%g5, RWIN64SHIFT, %g7
305*5d9d9091SRichard Lowe	ldn	[%g6 + MPCB_WBUF], %g5
306*5d9d9091SRichard Lowe	add	%g5, %g7, %g7
307*5d9d9091SRichard Lowe	SAVE_V9WINDOW(%g7)
308*5d9d9091SRichard Lowe	saved
309*5d9d9091SRichard Lowe	set	sys_trap, %g5
310*5d9d9091SRichard Lowe	wrpr	%g5, %tnpc
311*5d9d9091SRichard Lowe	done
312*5d9d9091SRichard Lowe	SET_SIZE(fault_64bit_so1)
313*5d9d9091SRichard Lowe
314*5d9d9091SRichard Lowe	/*
315*5d9d9091SRichard Lowe	 * Fill fault handlers
316*5d9d9091SRichard Lowe	 *   fn0 - fill normal tl 0
317*5d9d9091SRichard Lowe	 *   fn1 - fill normal tl 1
318*5d9d9091SRichard Lowe	 */
319*5d9d9091SRichard Lowe
320*5d9d9091SRichard Lowe	ENTRY_NP(fault_32bit_fn0)
321*5d9d9091SRichard Lowe	!
322*5d9d9091SRichard Lowe	FAULT_WINTRACE(%g1, %g2, %g3, TT_F32_FN0)
323*5d9d9091SRichard Lowe	!
324*5d9d9091SRichard Lowe.fault_fn0_common:
325*5d9d9091SRichard Lowe	!
326*5d9d9091SRichard Lowe	! Fill normal tl0 fault.
327*5d9d9091SRichard Lowe	! This happens when a user tries to fill to an unmapped or
328*5d9d9091SRichard Lowe	! misaligned stack. We handle an unmapped stack by simulating
329*5d9d9091SRichard Lowe	! a pagefault at the trap pc and a misaligned stack by generating
330*5d9d9091SRichard Lowe	! a user alignment trap.
331*5d9d9091SRichard Lowe	!
332*5d9d9091SRichard Lowe	! setup user_trap args
333*5d9d9091SRichard Lowe	!
334*5d9d9091SRichard Lowe	! g5 = mmu trap type, g6 = tag access reg (g5 != T_ALIGNMENT) or
335*5d9d9091SRichard Lowe	! sfar (g5 == T_ALIGNMENT)
336*5d9d9091SRichard Lowe	!
337*5d9d9091SRichard Lowe	set	sfmmu_tsbmiss_exception, %g1
338*5d9d9091SRichard Lowe	mov	%g6, %g2			! arg2 = tagaccess
339*5d9d9091SRichard Lowe	mov	T_WIN_UNDERFLOW, %g3
340*5d9d9091SRichard Lowe	cmp	%g5, T_ALIGNMENT
341*5d9d9091SRichard Lowe	bne	%icc, 1f
342*5d9d9091SRichard Lowe	nop
343*5d9d9091SRichard Lowe	set	trap, %g1
344*5d9d9091SRichard Lowe	mov	T_ALIGNMENT, %g3
345*5d9d9091SRichard Lowe1:
346*5d9d9091SRichard Lowe	sub	%g0, 1, %g4
347*5d9d9091SRichard Lowe	!
348*5d9d9091SRichard Lowe	! sys_trap wants %cwp to be the same as when the trap occured,
349*5d9d9091SRichard Lowe	! so set it from %tstate
350*5d9d9091SRichard Lowe	!
351*5d9d9091SRichard Lowe	rdpr	%tstate, %g5
352*5d9d9091SRichard Lowe	and	%g5, TSTATE_CWP, %g5
353*5d9d9091SRichard Lowe	ba,pt	%xcc, user_trap
354*5d9d9091SRichard Lowe	wrpr	%g0, %g5, %cwp
355*5d9d9091SRichard Lowe	SET_SIZE(fault_32bit_fn0)
356*5d9d9091SRichard Lowe
357*5d9d9091SRichard Lowe	ENTRY_NP(fault_32bit_fn1)
358*5d9d9091SRichard Lowe	!
359*5d9d9091SRichard Lowe	FAULT_WINTRACE(%g1, %g2, %g3, TT_F32_FN1)
360*5d9d9091SRichard Lowe	!
361*5d9d9091SRichard Lowe.fault_fn1_common:
362*5d9d9091SRichard Lowe	!
363*5d9d9091SRichard Lowe	! Fill normal tl1 fault.
364*5d9d9091SRichard Lowe	! This happens when user_rtt's restore fills from an unmapped or
365*5d9d9091SRichard Lowe	! misaligned stack. We handle an unmapped stack by simulating
366*5d9d9091SRichard Lowe	! a pagefault at user_rtt and a misaligned stack by generating
367*5d9d9091SRichard Lowe	! a RTT alignment trap.
368*5d9d9091SRichard Lowe	!
369*5d9d9091SRichard Lowe	! save fault addr & fix %cwp
370*5d9d9091SRichard Lowe	!
371*5d9d9091SRichard Lowe	rdpr	%tstate, %g1
372*5d9d9091SRichard Lowe	and	%g1, TSTATE_CWP, %g1
373*5d9d9091SRichard Lowe	wrpr	%g0, %g1, %cwp
374*5d9d9091SRichard Lowe	!
375*5d9d9091SRichard Lowe	! fake tl1 traps regs so that after pagefault runs, we
376*5d9d9091SRichard Lowe	! re-execute at user_rtt.
377*5d9d9091SRichard Lowe	!
378*5d9d9091SRichard Lowe	wrpr	%g0, 1, %tl
379*5d9d9091SRichard Lowe	set	TSTATE_KERN | TSTATE_IE, %g1
380*5d9d9091SRichard Lowe	wrpr	%g0, %g1, %tstate
381*5d9d9091SRichard Lowe	set	user_rtt, %g1
382*5d9d9091SRichard Lowe	wrpr	%g0, %g1, %tpc
383*5d9d9091SRichard Lowe	add	%g1, 4, %g1
384*5d9d9091SRichard Lowe	wrpr	%g0, %g1, %tnpc
385*5d9d9091SRichard Lowe	!
386*5d9d9091SRichard Lowe	! setup sys_trap args
387*5d9d9091SRichard Lowe	!
388*5d9d9091SRichard Lowe	! g5 = mmu trap type, g6 = tag access reg (g5 != T_ALIGNMENT) or
389*5d9d9091SRichard Lowe	! sfar (g5 == T_ALIGNMENT)
390*5d9d9091SRichard Lowe	!
391*5d9d9091SRichard Lowe	set	sfmmu_tsbmiss_exception, %g1
392*5d9d9091SRichard Lowe	mov	%g6, %g2			! arg2 = tagaccess
393*5d9d9091SRichard Lowe	set	T_USER | T_SYS_RTT_PAGE, %g3	! arg3 = traptype
394*5d9d9091SRichard Lowe	cmp	%g5, T_ALIGNMENT
395*5d9d9091SRichard Lowe	bne	%icc, 1f
396*5d9d9091SRichard Lowe	nop
397*5d9d9091SRichard Lowe	set	trap, %g1
398*5d9d9091SRichard Lowe	set	T_USER | T_SYS_RTT_ALIGN, %g3
399*5d9d9091SRichard Lowe1:
400*5d9d9091SRichard Lowe	sub	%g0, 1, %g4
401*5d9d9091SRichard Lowe	!
402*5d9d9091SRichard Lowe	! setup to run kernel again by setting THREAD_REG, %wstate
403*5d9d9091SRichard Lowe	! and the mmu to their kernel values.
404*5d9d9091SRichard Lowe	!
405*5d9d9091SRichard Lowe	rdpr	%pstate, %l1
406*5d9d9091SRichard Lowe	wrpr	%l1, PSTATE_AG, %pstate
407*5d9d9091SRichard Lowe	mov	%l6, THREAD_REG			! %l6 is user_rtt's thread
408*5d9d9091SRichard Lowe	wrpr	%g0, %l1, %pstate
409*5d9d9091SRichard Lowe	rdpr	%wstate, %l1
410*5d9d9091SRichard Lowe	sllx	%l1, WSTATE_SHIFT, %l1
411*5d9d9091SRichard Lowe	wrpr	%l1, WSTATE_K64, %wstate
412*5d9d9091SRichard Lowe	sethi   %hi(kcontextreg), %g5           ! mov   KCONTEXT, %g5
413*5d9d9091SRichard Lowe        ldx     [%g5 + %lo(kcontextreg)], %g5
414*5d9d9091SRichard Lowe	mov	MMU_PCONTEXT, %g6
415*5d9d9091SRichard Lowe	ldxa	[%g6]ASI_MMU_CTX, %g7
416*5d9d9091SRichard Lowe	xor	%g5, %g7, %g7
417*5d9d9091SRichard Lowe	srlx	%g7, CTXREG_NEXT_SHIFT, %g7
418*5d9d9091SRichard Lowe	brz	%g7, 1f				! if N_pgsz0/1 changed, need demap
419*5d9d9091SRichard Lowe	  nop
420*5d9d9091SRichard Lowe	mov	DEMAP_ALL_TYPE, %g7
421*5d9d9091SRichard Lowe	stxa	%g0, [%g7]ASI_DTLB_DEMAP
422*5d9d9091SRichard Lowe	stxa	%g0, [%g7]ASI_ITLB_DEMAP
423*5d9d9091SRichard Lowe1:
424*5d9d9091SRichard Lowe	stxa	%g5, [%g6]ASI_MMU_CTX
425*5d9d9091SRichard Lowe	sethi   %hi(FLUSH_ADDR), %g5
426*5d9d9091SRichard Lowe	flush   %g5
427*5d9d9091SRichard Lowe
428*5d9d9091SRichard Lowe	ba,pt	%xcc, priv_trap
429*5d9d9091SRichard Lowe	nop
430*5d9d9091SRichard Lowe	SET_SIZE(fault_32bit_fn1)
431*5d9d9091SRichard Lowe
432*5d9d9091SRichard Lowe	ENTRY_NP(fault_64bit_fn0)
433*5d9d9091SRichard Lowe	FAULT_WINTRACE(%g1, %g2, %g3, TT_F64_FN0)
434*5d9d9091SRichard Lowe	b	.fault_fn0_common
435*5d9d9091SRichard Lowe	  nop
436*5d9d9091SRichard Lowe	SET_SIZE(fault_64bit_fn0)
437*5d9d9091SRichard Lowe
438*5d9d9091SRichard Lowe	ENTRY_NP(fault_64bit_fn1)
439*5d9d9091SRichard Lowe	FAULT_WINTRACE(%g1, %g2, %g3, TT_F64_FN1)
440*5d9d9091SRichard Lowe	b	.fault_fn1_common
441*5d9d9091SRichard Lowe	  nop
442*5d9d9091SRichard Lowe	SET_SIZE(fault_64bit_fn1)
443*5d9d9091SRichard Lowe
444*5d9d9091SRichard Lowe	/*
445*5d9d9091SRichard Lowe	 * Kernel fault handlers
446*5d9d9091SRichard Lowe	 */
447*5d9d9091SRichard Lowe	ENTRY_NP(fault_32bit_not)
448*5d9d9091SRichard Lowe	ENTRY_NP(fault_64bit_not)
449*5d9d9091SRichard Lowe	ba,pt	%xcc, ptl1_panic
450*5d9d9091SRichard Lowe	mov	PTL1_BAD_WTRAP, %g1
451*5d9d9091SRichard Lowe	SET_SIZE(fault_32bit_not)
452*5d9d9091SRichard Lowe	SET_SIZE(fault_64bit_not)
453