exception.S revision 81135
1/*-
2 * Copyright (c) 2001 Jake Burkholder.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/sparc64/sparc64/exception.S 81135 2001-08-04 18:55:15Z tmm $
27 */
28
29#include "opt_ddb.h"
30
31#include <machine/asi.h>
32#include <machine/asmacros.h>
33#include <machine/trap.h>
34
35#include "assym.s"
36
37#define	SPILL(storer, base, asi) \
38	storer	%l0, [base + F_L0] asi ; \
39	storer	%l1, [base + F_L1] asi ; \
40	storer	%l2, [base + F_L2] asi ; \
41	storer	%l3, [base + F_L3] asi ; \
42	storer	%l4, [base + F_L4] asi ; \
43	storer	%l5, [base + F_L5] asi ; \
44	storer	%l6, [base + F_L6] asi ; \
45	storer	%l7, [base + F_L7] asi ; \
46	storer	%i0, [base + F_I0] asi ; \
47	storer	%i1, [base + F_I1] asi ; \
48	storer	%i2, [base + F_I2] asi ; \
49	storer	%i3, [base + F_I3] asi ; \
50	storer	%i4, [base + F_I4] asi ; \
51	storer	%i5, [base + F_I5] asi ; \
52	storer	%i6, [base + F_I6] asi ; \
53	storer	%i7, [base + F_I7] asi
54
55#define	FILL(loader, base, asi) \
56	loader	[base + F_L0] asi, %l0 ; \
57	loader	[base + F_L1] asi, %l1 ; \
58	loader	[base + F_L2] asi, %l2 ; \
59	loader	[base + F_L3] asi, %l3 ; \
60	loader	[base + F_L4] asi, %l4 ; \
61	loader	[base + F_L5] asi, %l5 ; \
62	loader	[base + F_L6] asi, %l6 ; \
63	loader	[base + F_L7] asi, %l7 ; \
64	loader	[base + F_I0] asi, %i0 ; \
65	loader	[base + F_I1] asi, %i1 ; \
66	loader	[base + F_I2] asi, %i2 ; \
67	loader	[base + F_I3] asi, %i3 ; \
68	loader	[base + F_I4] asi, %i4 ; \
69	loader	[base + F_I5] asi, %i5 ; \
70	loader	[base + F_I6] asi, %i6 ; \
71	loader	[base + F_I7] asi, %i7
72
73DATA(intrnames)
74	.asciz	"foo"
75DATA(eintrnames)
76
77DATA(intrcnt)
78	.long	0
79DATA(eintrcnt)
80
81	.macro	clean_window
82	clr	%o0
83	clr	%o1
84	clr	%o2
85	clr	%o3
86	clr	%o4
87	clr	%o5
88	clr	%o6
89	clr	%o7
90	clr	%l0
91	clr	%l1
92	clr	%l2
93	clr	%l3
94	clr	%l4
95	clr	%l5
96	clr	%l6
97	rdpr	%cleanwin, %l7
98	inc	%l7
99	wrpr	%l7, 0, %cleanwin
100	clr	%l7
101	retry
102	.align	128
103	.endm
104
105	.macro	tl0_gen		type
106	save	%sp, -CCFSZ, %sp
107	b	%xcc, tl1_trap
108	 mov	\type, %o0
109	.align	32
110	.endm
111
112	.macro	tl0_wide	type
113	save	%sp, -CCFSZ, %sp
114	b	%xcc, tl1_trap
115	 mov	\type, %o0
116	.align	128
117	.endm
118
119	.macro	tl0_reserved	count
120	.rept	\count
121	tl0_gen	T_RESERVED
122	.endr
123	.endm
124
125	.macro	tl0_intr_level
126	tl0_reserved 15
127	.endm
128
129	.macro	tl0_intr_vector
130	tl0_gen	0
131	.endm
132
133	.macro	tl0_immu_miss
134	tl0_wide T_IMMU_MISS
135	.endm
136
137	.macro	tl0_dmmu_miss
138	tl0_wide T_DMMU_MISS
139	.endm
140
141	.macro	tl0_dmmu_prot
142	tl0_wide T_DMMU_PROT
143	.endm
144
145	.macro	tl0_spill_0_n
146	wr	%g0, ASI_AIUP, %asi
147	SPILL(stxa, %sp + SPOFF, %asi)
148	saved
149	retry
150	.align	128
151	.endm
152
153	.macro	tl0_spill_bad	count
154	.rept	\count
155	tl0_wide T_SPILL
156	.endr
157	.endm
158
159	.macro	tl0_fill_0_n
160	wr	%g0, ASI_AIUP, %asi
161	FILL(ldxa, %sp + SPOFF, %asi)
162	restored
163	retry
164	.align	128
165	.endm
166
167	.macro	tl0_fill_bad	count
168	.rept	\count
169	tl0_wide T_FILL
170	.endr
171	.endm
172
173	.macro	tl0_soft	count
174	tl0_reserved \count
175	.endm
176
177	.macro	tl1_gen		type
178	save	%sp, -CCFSZ, %sp
179	b	%xcc, tl1_trap
180	 mov	\type | T_KERNEL, %o0
181	.align	32
182	.endm
183
184	.macro	tl1_wide	type
185	save	%sp, -CCFSZ, %sp
186	b	%xcc, tl1_trap
187	 mov	\type | T_KERNEL, %o0
188	.align	128
189	.endm
190
191	.macro	tl1_reserved	count
192	.rept	\count
193	tl1_gen	T_RESERVED
194	.endr
195	.endm
196
197	.macro	tl1_insn_excptn
198	rdpr	%pstate, %g1
199	wrpr	%g1, PSTATE_MG | PSTATE_AG, %pstate
200	save	%sp, -CCFSZ, %sp
201	b	%xcc, tl1_trap
202	 mov	T_INSN_EXCPTN | T_KERNEL, %o0
203	.align	32
204	.endm
205
206	.macro	tl1_align
207	b	%xcc, tl1_sfsr_trap
208	 nop
209	.align	32
210	.endm
211
212ENTRY(tl1_sfsr_trap)
213	wr	%g0, ASI_DMMU, %asi
214	ldxa	[%g0 + AA_DMMU_SFAR] %asi, %g1
215	ldxa	[%g0 + AA_DMMU_SFSR] %asi, %g2
216	stxa	%g0, [%g0 + AA_DMMU_SFSR] %asi
217	membar	#Sync
218	save	%sp, -(CCFSZ + MF_SIZEOF), %sp
219	stx	%g1, [%sp + SPOFF + CCFSZ + MF_SFAR]
220	stx	%g2, [%sp + SPOFF + CCFSZ + MF_SFSR]
221	mov	T_ALIGN | T_KERNEL, %o0
222	b	%xcc, tl1_trap
223	 add	%sp, SPOFF + CCFSZ, %o1
224END(tl1_sfsr_trap)
225
226	.macro	tl1_intr_level
227	tl1_reserved 15
228	.endm
229
230	.macro	tl1_intr_vector
231	rdpr	%pstate, %g1
232	wrpr	%g1, PSTATE_IG | PSTATE_AG, %pstate
233	save	%sp, -CCFSZ, %sp
234	b	%xcc, tl1_trap
235	 mov	T_INTERRUPT | T_KERNEL, %o0
236	.align	8
237	.endm
238
239	.macro	tl1_immu_miss
240	rdpr	%pstate, %g1
241	wrpr	%g1, PSTATE_MG | PSTATE_AG, %pstate
242	save	%sp, -CCFSZ, %sp
243	b	%xcc, tl1_trap
244	 mov	T_IMMU_MISS | T_KERNEL, %o0
245	.align	128
246	.endm
247
248	.macro	tl1_dmmu_miss
249	/*
250	 * Load the target tte tag, and extract the context.  If the context
251	 * is non-zero handle as user space access.  In either case, load the
252	 * tsb 8k pointer.
253	 */
254	ldxa	[%g0] ASI_DMMU_TAG_TARGET_REG, %g1
255	srlx	%g1, TT_CTX_SHIFT, %g2
256	brnz,pn	%g2, 2f
257	 ldxa	[%g0] ASI_DMMU_TSB_8KB_PTR_REG, %g2
258
259	/*
260	 * Convert the tte pointer to an stte pointer, and add extra bits to
261	 * accomodate for large tsb.
262	 */
263	sllx	%g2, STTE_SHIFT - TTE_SHIFT, %g2
264#ifdef notyet
265	mov	AA_DMMU_TAR, %g3
266	ldxa	[%g3] ASI_DMMU, %g3
267	srlx	%g3, TSB_1M_STTE_SHIFT, %g3
268	and	%g3, TSB_KERNEL_MASK >> TSB_1M_STTE_SHIFT, %g3
269	sllx	%g3, TSB_1M_STTE_SHIFT, %g3
270	add	%g2, %g3, %g2
271#endif
272
273	/*
274	 * Load the tte, check that it's valid and that the tags match.
275	 */
276	ldda	[%g2] ASI_NUCLEUS_QUAD_LDD, %g4 /*, %g5 */
277	brgez,pn %g5, 2f
278	 cmp	%g4, %g1
279	bne	%xcc, 2f
280	 EMPTY
281
282	/*
283	 * Set the refence bit, if its currently clear.
284	 */
285	andcc	%g5, TD_REF, %g0
286	bnz	%xcc, 1f
287	 or	%g5, TD_REF, %g1
288	stx	%g1, [%g2 + ST_TTE + TTE_DATA]
289
290	/*
291	 * If the mod bit is clear, clear the write bit too.
292	 */
2931:	andcc	%g5, TD_MOD, %g1
294	movz	%xcc, TD_W, %g1
295	andn	%g5, %g1, %g5
296
297	/*
298	 * Load the tte data into the TLB and retry the instruction.
299	 */
300	stxa	%g5, [%g0] ASI_DTLB_DATA_IN_REG
301	retry
302
303	/*
304	 * For now just bail.  This might cause a red state exception,
305	 * but oh well.
306	 */
3072:	DEBUGGER()
308	.align	128
309	.endm
310
311	.macro	tl1_dmmu_prot
312	rdpr	%pstate, %g1
313	wrpr	%g1, PSTATE_MG | PSTATE_AG, %pstate
314	save	%sp, -CCFSZ, %sp
315	b	%xcc, tl1_trap
316	 mov	T_DMMU_PROT | T_KERNEL, %o0
317	.align	128
318	.endm
319
320	.macro	tl1_spill_0_n
321	SPILL(stx, %sp + SPOFF, EMPTY)
322	saved
323	retry
324	.align	128
325	.endm
326
327	.macro	tl1_spill_bad	count
328	.rept	\count
329	tl1_wide T_SPILL
330	.endr
331	.endm
332
333	.macro	tl1_fill_0_n
334	FILL(ldx, %sp + SPOFF, EMPTY)
335	restored
336	retry
337	.align	128
338	.endm
339
340	.macro	tl1_fill_bad	count
341	.rept	\count
342	tl1_wide T_FILL
343	.endr
344	.endm
345
346	.macro	tl1_breakpoint
347	b	%xcc, tl1_breakpoint_trap
348	 nop
349	.align	32
350	.endm
351
352ENTRY(tl1_breakpoint_trap)
353	save	%sp, -(CCFSZ + KF_SIZEOF), %sp
354	flushw
355	stx	%fp, [%sp + SPOFF + CCFSZ + KF_FP]
356	mov	T_BREAKPOINT | T_KERNEL, %o0
357	b	%xcc, tl1_trap
358	 add	%sp, SPOFF + CCFSZ, %o1
359END(tl1_breakpoint_trap)
360
361	.macro	tl1_soft	count
362	tl1_reserved \count
363	.endm
364
365	.sect	.trap
366	.align	0x8000
367	.globl	tl0_base
368
369tl0_base:
370	tl0_reserved	1		! 0x0 unused
371tl0_power_on:
372	tl0_gen		T_POWER_ON	! 0x1 power on reset
373tl0_watchdog:
374	tl0_gen		T_WATCHDOG	! 0x2 watchdog rest
375tl0_reset_ext:
376	tl0_gen		T_RESET_EXT	! 0x3 externally initiated reset
377tl0_reset_soft:
378	tl0_gen		T_RESET_SOFT	! 0x4 software initiated reset
379tl0_red_state:
380	tl0_gen		T_RED_STATE	! 0x5 red state exception
381	tl0_reserved	2		! 0x6-0x7 reserved
382tl0_insn_excptn:
383	tl0_gen		T_INSN_EXCPTN	! 0x8 instruction access exception
384	tl0_reserved	1		! 0x9 reserved
385tl0_insn_error:
386	tl0_gen		T_INSN_ERROR	! 0xa instruction access error
387	tl0_reserved	5		! 0xb-0xf reserved
388tl0_insn_illegal:
389	tl0_gen		T_INSN_ILLEGAL	! 0x10 illegal instruction
390tl0_priv_opcode:
391	tl0_gen		T_PRIV_OPCODE	! 0x11 privileged opcode
392	tl0_reserved	14		! 0x12-0x1f reserved
393tl0_fp_disabled:
394	tl0_gen		T_FP_DISABLED	! 0x20 floating point disabled
395tl0_fp_ieee:
396	tl0_gen		T_FP_IEEE	! 0x21 floating point exception ieee
397tl0_fp_other:
398	tl0_gen		T_FP_OTHER	! 0x22 floating point exception other
399tl0_tag_ovflw:
400	tl0_gen		T_TAG_OVFLW	! 0x23 tag overflow
401tl0_clean_window:
402	clean_window			! 0x24 clean window
403tl0_divide:
404	tl0_gen		T_DIVIDE	! 0x28 division by zero
405	tl0_reserved	7		! 0x29-0x2f reserved
406tl0_data_excptn:
407	tl0_gen		T_DATA_EXCPTN	! 0x30 data access exception
408	tl0_reserved	1		! 0x31 reserved
409tl0_data_error:
410	tl0_gen		T_DATA_ERROR	! 0x32 data access error
411	tl0_reserved	1		! 0x33 reserved
412tl0_align:
413	tl0_gen		T_ALIGN		! 0x34 memory address not aligned
414tl0_align_lddf:
415	tl0_gen		T_ALIGN_LDDF	! 0x35 lddf memory address not aligned
416tl0_align_stdf:
417	tl0_gen		T_ALIGN_STDF	! 0x36 stdf memory address not aligned
418tl0_priv_action:
419	tl0_gen		T_PRIV_ACTION	! 0x37 privileged action
420	tl0_reserved	9		! 0x38-0x40 reserved
421tl0_intr_level:
422	tl0_intr_level			! 0x41-0x4f interrupt level 1 to 15
423	tl0_reserved	16		! 0x50-0x5f reserved
424tl0_intr_vector:
425	tl0_intr_vector			! 0x60 interrupt vector
426tl0_watch_phys:
427	tl0_gen		T_WATCH_PHYS	! 0x61 physical address watchpoint
428tl0_watch_virt:
429	tl0_gen		T_WATCH_VIRT	! 0x62 virtual address watchpoint
430tl0_ecc:
431	tl0_gen		T_ECC		! 0x63 corrected ecc error
432tl0_immu_miss:
433	tl0_immu_miss			! 0x64 fast instruction access mmu miss
434tl0_dmmu_miss:
435	tl0_dmmu_miss			! 0x68 fast data access mmu miss
436tl0_dmmu_prot:
437	tl0_dmmu_prot			! 0x6c fast data access protection
438	tl0_reserved	16		! 0x70-0x7f reserved
439tl0_spill_0_n:
440	tl0_spill_0_n			! 0x80 spill 0 normal
441tl0_spill_bad:
442	tl0_spill_bad	15		! 0x84-0xbf spill normal, other
443tl0_fill_0_n:
444	tl0_fill_0_n			! 0xc0 fill 0 normal
445tl0_fill_bad:
446	tl0_fill_bad	15		! 0xc4-0xff fill normal, other
447tl0_sun_syscall:
448	tl0_reserved	1		! 0x100 sun system call
449tl0_breakpoint:
450	tl0_gen		T_BREAKPOINT	! 0x101 breakpoint
451	tl0_soft	126		! 0x102-0x17f trap instruction
452	tl0_reserved	128		! 0x180-0x1ff reserved
453
454tl1_base:
455	tl1_reserved	1		! 0x200 unused
456tl1_power_on:
457	tl1_gen		T_POWER_ON	! 0x201 power on reset
458tl1_watchdog:
459	tl1_gen		T_WATCHDOG	! 0x202 watchdog rest
460tl1_reset_ext:
461	tl1_gen		T_RESET_EXT	! 0x203 externally initiated reset
462tl1_reset_soft:
463	tl1_gen		T_RESET_SOFT	! 0x204 software initiated reset
464tl1_red_state:
465	tl1_gen		T_RED_STATE	! 0x205 red state exception
466	tl1_reserved	2		! 0x206-0x207 reserved
467tl1_insn_excptn:
468	tl1_insn_excptn			! 0x208 instruction access exception
469	tl1_reserved	1		! 0x209 reserved
470tl1_insn_error:
471	tl1_gen		T_INSN_ERROR	! 0x20a instruction access error
472	tl1_reserved	5		! 0x20b-0x20f reserved
473tl1_insn_illegal:
474	tl1_gen		T_INSN_ILLEGAL	! 0x210 illegal instruction
475tl1_priv_opcode:
476	tl1_gen		T_PRIV_OPCODE	! 0x211 privileged opcode
477	tl1_reserved	14		! 0x212-0x21f reserved
478tl1_fp_disabled:
479	tl1_gen		T_FP_DISABLED	! 0x220 floating point disabled
480tl1_fp_ieee:
481	tl1_gen		T_FP_IEEE	! 0x221 floating point exception ieee
482tl1_fp_other:
483	tl1_gen		T_FP_OTHER	! 0x222 floating point exception other
484tl1_tag_ovflw:
485	tl1_gen		T_TAG_OVFLW	! 0x223 tag overflow
486tl1_clean_window:
487	clean_window			! 0x224 clean window
488tl1_divide:
489	tl1_gen		T_DIVIDE	! 0x228 division by zero
490	tl1_reserved	7		! 0x229-0x22f reserved
491tl1_data_excptn:
492	tl1_gen		T_DATA_EXCPTN	! 0x230 data access exception
493	tl1_reserved	1		! 0x231 reserved
494tl1_data_error:
495	tl1_gen		T_DATA_ERROR	! 0x232 data access error
496	tl1_reserved	1		! 0x233 reserved
497tl1_align:
498	tl1_align			! 0x234 memory address not aligned
499tl1_align_lddf:
500	tl1_gen		T_ALIGN_LDDF	! 0x235 lddf memory address not aligned
501tl1_align_stdf:
502	tl1_gen		T_ALIGN_STDF	! 0x236 stdf memory address not aligned
503tl1_priv_action:
504	tl1_gen		T_PRIV_ACTION	! 0x237 privileged action
505	tl1_reserved	9		! 0x238-0x240 reserved
506tl1_intr_level:
507	tl1_intr_level			! 0x241-0x24f interrupt level 1 to 15
508	tl1_reserved	16		! 0x250-0x25f reserved
509tl1_intr_vector:
510	tl1_intr_vector			! 0x260 interrupt vector
511tl1_watch_phys:
512	tl1_gen		T_WATCH_PHYS	! 0x261 physical address watchpoint
513tl1_watch_virt:
514	tl1_gen		T_WATCH_VIRT	! 0x262 virtual address watchpoint
515tl1_ecc:
516	tl1_gen		T_ECC		! 0x263 corrected ecc error
517tl1_immu_miss:
518	tl1_immu_miss			! 0x264 fast instruction access mmu miss
519tl1_dmmu_miss:
520	tl1_dmmu_miss			! 0x268 fast data access mmu miss
521tl1_dmmu_prot:
522	tl1_dmmu_prot			! 0x26c fast data access protection
523	tl1_reserved	16		! 0x270-0x27f reserved
524tl1_spill_0_n:
525	tl1_spill_0_n			! 0x280 spill 0 normal
526tl1_spill_bad:
527	tl1_spill_bad	15		! 0x284-0x2bf spill normal, other
528tl1_fill_0_n:
529	tl1_fill_0_n			! 0x2c0 fill 0 normal
530tl1_fill_bad:
531	tl1_fill_bad	15		! 0x2c4-0x2ff fill normal, other
532	tl1_reserved	1		! 0x300 trap instruction
533tl1_breakpoint:
534	tl1_breakpoint			! 0x301 breakpoint
535	tl1_soft	126		! 0x302-0x37f trap instruction
536	tl1_reserved	128		! 0x380-0x3ff reserved
537
538ENTRY(tl0_trap)
539	/* In every trap from tl0, we need to set PSTATE.PEF. */
540	illtrap
541END(tl0_trap)
542
543/*
544 * void tl1_trap(u_long o0, u_long o1, u_long o2, u_long type)
545 */
546ENTRY(tl1_trap)
547	sub	%sp, TF_SIZEOF, %sp
548	rdpr	%tstate, %l0
549	stx	%l0, [%sp + SPOFF + CCFSZ + TF_TSTATE]
550	rdpr	%tpc, %l1
551	stx	%l1, [%sp + SPOFF + CCFSZ + TF_TPC]
552	rdpr	%tnpc, %l2
553	stx	%l2, [%sp + SPOFF + CCFSZ + TF_TNPC]
554
555	wrpr	%g0, 1, %tl
556	rdpr	%pstate, %l7
557	wrpr	%l7, PSTATE_AG | PSTATE_IE, %pstate
558
559	stx	%o0, [%sp + SPOFF + CCFSZ + TF_TYPE]
560	stx	%o1, [%sp + SPOFF + CCFSZ + TF_ARG]
561
562	stx	%g1, [%sp + SPOFF + CCFSZ + TF_G1]
563	stx	%g2, [%sp + SPOFF + CCFSZ + TF_G2]
564	stx	%g3, [%sp + SPOFF + CCFSZ + TF_G3]
565	stx	%g4, [%sp + SPOFF + CCFSZ + TF_G4]
566	stx	%g5, [%sp + SPOFF + CCFSZ + TF_G5]
567	stx	%g6, [%sp + SPOFF + CCFSZ + TF_G6]
568	stx	%g7, [%sp + SPOFF + CCFSZ + TF_G7]
569
570	call	trap
571	 add	%sp, CCFSZ + SPOFF, %o0
572
573	ldx	[%sp + SPOFF + CCFSZ + TF_G1], %g1
574	ldx	[%sp + SPOFF + CCFSZ + TF_G2], %g2
575	ldx	[%sp + SPOFF + CCFSZ + TF_G3], %g3
576	ldx	[%sp + SPOFF + CCFSZ + TF_G4], %g4
577	ldx	[%sp + SPOFF + CCFSZ + TF_G5], %g5
578	ldx	[%sp + SPOFF + CCFSZ + TF_G6], %g6
579	ldx	[%sp + SPOFF + CCFSZ + TF_G7], %g7
580
581	ldx	[%sp + SPOFF + CCFSZ + TF_TSTATE], %l0
582	ldx	[%sp + SPOFF + CCFSZ + TF_TPC], %l1
583	ldx	[%sp + SPOFF + CCFSZ + TF_TNPC], %l2
584
585	rdpr	%pstate, %o0
586	wrpr	%o0, PSTATE_AG | PSTATE_IE, %pstate
587
588	wrpr	%g0, 2, %tl
589	wrpr	%l0, 0, %tstate
590	wrpr	%l1, 0, %tpc
591	wrpr	%l2, 0, %tnpc
592
593	restore
594	retry
595END(tl1_trap)
596
597ENTRY(fork_trampoline)
598	mov	%l0, %o0
599	mov	%l1, %o1
600	mov	%l2, %o2
601	call	fork_exit
602	 nop
603	DEBUGGER()
604END(fork_trampoline)
605