xref: /titanic_44/usr/src/uts/sun4u/ml/trap_table.s (revision 023e71de9e5670cebc23dd51162833661d3d2d3b)
17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
541f63f87Spetede * Common Development and Distribution License (the "License").
641f63f87Spetede * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate/*
22b9e93c10SJonathan Haslam * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate#if !defined(lint)
277c478bd9Sstevel@tonic-gate#include "assym.h"
287c478bd9Sstevel@tonic-gate#endif /* !lint */
297c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
307c478bd9Sstevel@tonic-gate#include <sys/privregs.h>
317c478bd9Sstevel@tonic-gate#include <sys/sun4asi.h>
3225cf1a30Sjl139090#include <sys/spitregs.h>
337c478bd9Sstevel@tonic-gate#include <sys/cheetahregs.h>
347c478bd9Sstevel@tonic-gate#include <sys/machtrap.h>
357c478bd9Sstevel@tonic-gate#include <sys/machthread.h>
369acbbeafSnn35248#include <sys/machbrand.h>
377c478bd9Sstevel@tonic-gate#include <sys/pcb.h>
387c478bd9Sstevel@tonic-gate#include <sys/pte.h>
397c478bd9Sstevel@tonic-gate#include <sys/mmu.h>
407c478bd9Sstevel@tonic-gate#include <sys/machpcb.h>
417c478bd9Sstevel@tonic-gate#include <sys/async.h>
427c478bd9Sstevel@tonic-gate#include <sys/intreg.h>
437c478bd9Sstevel@tonic-gate#include <sys/scb.h>
447c478bd9Sstevel@tonic-gate#include <sys/psr_compat.h>
457c478bd9Sstevel@tonic-gate#include <sys/syscall.h>
467c478bd9Sstevel@tonic-gate#include <sys/machparam.h>
477c478bd9Sstevel@tonic-gate#include <sys/traptrace.h>
487c478bd9Sstevel@tonic-gate#include <vm/hat_sfmmu.h>
497c478bd9Sstevel@tonic-gate#include <sys/archsystm.h>
507c478bd9Sstevel@tonic-gate#include <sys/utrap.h>
517c478bd9Sstevel@tonic-gate#include <sys/clock.h>
527c478bd9Sstevel@tonic-gate#include <sys/intr.h>
537c478bd9Sstevel@tonic-gate#include <sys/fpu/fpu_simulator.h>
547c478bd9Sstevel@tonic-gate#include <vm/seg_spt.h>
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate/*
577c478bd9Sstevel@tonic-gate * WARNING: If you add a fast trap handler which can be invoked by a
587c478bd9Sstevel@tonic-gate * non-privileged user, you may have to use the FAST_TRAP_DONE macro
597c478bd9Sstevel@tonic-gate * instead of "done" instruction to return back to the user mode. See
607c478bd9Sstevel@tonic-gate * comments for the "fast_trap_done" entry point for more information.
617c478bd9Sstevel@tonic-gate *
627c478bd9Sstevel@tonic-gate * An alternate FAST_TRAP_DONE_CHK_INTR macro should be used for the
637c478bd9Sstevel@tonic-gate * cases where you always want to process any pending interrupts before
647c478bd9Sstevel@tonic-gate * returning back to the user mode.
657c478bd9Sstevel@tonic-gate */
667c478bd9Sstevel@tonic-gate#define	FAST_TRAP_DONE		\
677c478bd9Sstevel@tonic-gate	ba,a	fast_trap_done
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate#define	FAST_TRAP_DONE_CHK_INTR	\
707c478bd9Sstevel@tonic-gate	ba,a	fast_trap_done_chk_intr
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate/*
737c478bd9Sstevel@tonic-gate * SPARC V9 Trap Table
747c478bd9Sstevel@tonic-gate *
757c478bd9Sstevel@tonic-gate * Most of the trap handlers are made from common building
767c478bd9Sstevel@tonic-gate * blocks, and some are instantiated multiple times within
777c478bd9Sstevel@tonic-gate * the trap table. So, I build a bunch of macros, then
787c478bd9Sstevel@tonic-gate * populate the table using only the macros.
797c478bd9Sstevel@tonic-gate *
807c478bd9Sstevel@tonic-gate * Many macros branch to sys_trap.  Its calling convention is:
817c478bd9Sstevel@tonic-gate *	%g1		kernel trap handler
827c478bd9Sstevel@tonic-gate *	%g2, %g3	args for above
837c478bd9Sstevel@tonic-gate *	%g4		desire %pil
847c478bd9Sstevel@tonic-gate */
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate#ifdef	TRAPTRACE
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate/*
897c478bd9Sstevel@tonic-gate * Tracing macro. Adds two instructions if TRAPTRACE is defined.
907c478bd9Sstevel@tonic-gate */
917c478bd9Sstevel@tonic-gate#define	TT_TRACE(label)		\
927c478bd9Sstevel@tonic-gate	ba	label		;\
937c478bd9Sstevel@tonic-gate	rd	%pc, %g7
947c478bd9Sstevel@tonic-gate#define	TT_TRACE_INS	2
957c478bd9Sstevel@tonic-gate
967c478bd9Sstevel@tonic-gate#define	TT_TRACE_L(label)	\
977c478bd9Sstevel@tonic-gate	ba	label		;\
987c478bd9Sstevel@tonic-gate	rd	%pc, %l4	;\
997c478bd9Sstevel@tonic-gate	clr	%l4
1007c478bd9Sstevel@tonic-gate#define	TT_TRACE_L_INS	3
1017c478bd9Sstevel@tonic-gate
1027c478bd9Sstevel@tonic-gate#else
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate#define	TT_TRACE(label)
1057c478bd9Sstevel@tonic-gate#define	TT_TRACE_INS	0
1067c478bd9Sstevel@tonic-gate
1077c478bd9Sstevel@tonic-gate#define	TT_TRACE_L(label)
1087c478bd9Sstevel@tonic-gate#define	TT_TRACE_L_INS	0
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate#endif
1117c478bd9Sstevel@tonic-gate
1127c478bd9Sstevel@tonic-gate/*
1137c478bd9Sstevel@tonic-gate * This first set are funneled to trap() with %tt as the type.
1147c478bd9Sstevel@tonic-gate * Trap will then either panic or send the user a signal.
1157c478bd9Sstevel@tonic-gate */
1167c478bd9Sstevel@tonic-gate/*
1177c478bd9Sstevel@tonic-gate * NOT is used for traps that just shouldn't happen.
1187c478bd9Sstevel@tonic-gate * It comes in both single and quadruple flavors.
1197c478bd9Sstevel@tonic-gate */
1207c478bd9Sstevel@tonic-gate#if !defined(lint)
1217c478bd9Sstevel@tonic-gate	.global	trap
1227c478bd9Sstevel@tonic-gate#endif /* !lint */
1237c478bd9Sstevel@tonic-gate#define	NOT			\
1247c478bd9Sstevel@tonic-gate	TT_TRACE(trace_gen)	;\
1257c478bd9Sstevel@tonic-gate	set	trap, %g1	;\
1267c478bd9Sstevel@tonic-gate	rdpr	%tt, %g3	;\
1277c478bd9Sstevel@tonic-gate	ba,pt	%xcc, sys_trap	;\
1287c478bd9Sstevel@tonic-gate	sub	%g0, 1, %g4	;\
1297c478bd9Sstevel@tonic-gate	.align	32
1307c478bd9Sstevel@tonic-gate#define	NOT4	NOT; NOT; NOT; NOT
1317c478bd9Sstevel@tonic-gate/*
1327c478bd9Sstevel@tonic-gate * RED is for traps that use the red mode handler.
1337c478bd9Sstevel@tonic-gate * We should never see these either.
1347c478bd9Sstevel@tonic-gate */
1357c478bd9Sstevel@tonic-gate#define	RED	NOT
1367c478bd9Sstevel@tonic-gate/*
1377c478bd9Sstevel@tonic-gate * BAD is used for trap vectors we don't have a kernel
1387c478bd9Sstevel@tonic-gate * handler for.
1397c478bd9Sstevel@tonic-gate * It also comes in single and quadruple versions.
1407c478bd9Sstevel@tonic-gate */
1417c478bd9Sstevel@tonic-gate#define	BAD	NOT
1427c478bd9Sstevel@tonic-gate#define	BAD4	NOT4
1437c478bd9Sstevel@tonic-gate
1447c478bd9Sstevel@tonic-gate#define	DONE			\
1457c478bd9Sstevel@tonic-gate	done;			\
1467c478bd9Sstevel@tonic-gate	.align	32
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate/*
1497c478bd9Sstevel@tonic-gate * TRAP vectors to the trap() function.
1507c478bd9Sstevel@tonic-gate * It's main use is for user errors.
1517c478bd9Sstevel@tonic-gate */
1527c478bd9Sstevel@tonic-gate#if !defined(lint)
1537c478bd9Sstevel@tonic-gate	.global	trap
1547c478bd9Sstevel@tonic-gate#endif /* !lint */
1557c478bd9Sstevel@tonic-gate#define	TRAP(arg)		\
1567c478bd9Sstevel@tonic-gate	TT_TRACE(trace_gen)	;\
1577c478bd9Sstevel@tonic-gate	set	trap, %g1	;\
1587c478bd9Sstevel@tonic-gate	mov	arg, %g3	;\
1597c478bd9Sstevel@tonic-gate	ba,pt	%xcc, sys_trap	;\
1607c478bd9Sstevel@tonic-gate	sub	%g0, 1, %g4	;\
1617c478bd9Sstevel@tonic-gate	.align	32
1627c478bd9Sstevel@tonic-gate
1637c478bd9Sstevel@tonic-gate/*
16459f2ff5cSedp * SYSCALL is used for unsupported syscall interfaces (with 'which'
16559f2ff5cSedp * set to 'nosys') and legacy support of old SunOS 4.x syscalls (with
16659f2ff5cSedp * 'which' set to 'syscall_trap32').
16759f2ff5cSedp *
16859f2ff5cSedp * The SYSCALL_TRAP* macros are used for syscall entry points.
16959f2ff5cSedp * SYSCALL_TRAP is used to support LP64 syscalls and SYSCALL_TRAP32
17059f2ff5cSedp * is used to support ILP32.  Each macro can only be used once
17159f2ff5cSedp * since they each define a symbol.  The symbols are used as hot patch
17259f2ff5cSedp * points by the brand infrastructure to dynamically enable and disable
17359f2ff5cSedp * brand syscall interposition.  See the comments around BRAND_CALLBACK
17459f2ff5cSedp * and brand_plat_interposition_enable() for more information.
1757c478bd9Sstevel@tonic-gate */
1764a75c0c1Sedp#define	SYSCALL_NOTT(which)		\
1777c478bd9Sstevel@tonic-gate	set	(which), %g1		;\
1787c478bd9Sstevel@tonic-gate	ba,pt	%xcc, sys_trap		;\
1797c478bd9Sstevel@tonic-gate	sub	%g0, 1, %g4		;\
1807c478bd9Sstevel@tonic-gate	.align	32
1817c478bd9Sstevel@tonic-gate
18259f2ff5cSedp#define	SYSCALL(which)			\
18359f2ff5cSedp	TT_TRACE(trace_gen)		;\
18459f2ff5cSedp	SYSCALL_NOTT(which)
18559f2ff5cSedp
18659f2ff5cSedp#define	SYSCALL_TRAP32				\
18759f2ff5cSedp	TT_TRACE(trace_gen)			;\
18859f2ff5cSedp	ALTENTRY(syscall_trap32_patch_point)	\
18959f2ff5cSedp	SYSCALL_NOTT(syscall_trap32)
19059f2ff5cSedp
19159f2ff5cSedp#define	SYSCALL_TRAP				\
19259f2ff5cSedp	TT_TRACE(trace_gen)			;\
19359f2ff5cSedp	ALTENTRY(syscall_trap_patch_point)	\
19459f2ff5cSedp	SYSCALL_NOTT(syscall_trap)
19559f2ff5cSedp
19650eff769Smb158278#define	FLUSHW(h_name)			\
19750eff769Smb158278	.global h_name			;\
19850eff769Smb158278h_name:					;\
1997c478bd9Sstevel@tonic-gate	set	trap, %g1		;\
2007c478bd9Sstevel@tonic-gate	mov	T_FLUSHW, %g3		;\
2017c478bd9Sstevel@tonic-gate	sub	%g0, 1, %g4		;\
2027c478bd9Sstevel@tonic-gate	save				;\
2037c478bd9Sstevel@tonic-gate	flushw				;\
2047c478bd9Sstevel@tonic-gate	restore				;\
2057c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE			;\
2067c478bd9Sstevel@tonic-gate	.align	32
2077c478bd9Sstevel@tonic-gate
2087c478bd9Sstevel@tonic-gate/*
2097c478bd9Sstevel@tonic-gate * GOTO just jumps to a label.
2107c478bd9Sstevel@tonic-gate * It's used for things that can be fixed without going thru sys_trap.
2117c478bd9Sstevel@tonic-gate */
2127c478bd9Sstevel@tonic-gate#define	GOTO(label)		\
2137c478bd9Sstevel@tonic-gate	.global	label		;\
2147c478bd9Sstevel@tonic-gate	ba,a	label		;\
2157c478bd9Sstevel@tonic-gate	.empty			;\
2167c478bd9Sstevel@tonic-gate	.align	32
2177c478bd9Sstevel@tonic-gate
2187c478bd9Sstevel@tonic-gate/*
2197c478bd9Sstevel@tonic-gate * GOTO_TT just jumps to a label.
2207c478bd9Sstevel@tonic-gate * correctable ECC error traps at  level 0 and 1 will use this macro.
2217c478bd9Sstevel@tonic-gate * It's used for things that can be fixed without going thru sys_trap.
2227c478bd9Sstevel@tonic-gate */
2237c478bd9Sstevel@tonic-gate#define	GOTO_TT(label, ttlabel)		\
2247c478bd9Sstevel@tonic-gate	.global	label		;\
2257c478bd9Sstevel@tonic-gate	TT_TRACE(ttlabel)	;\
2267c478bd9Sstevel@tonic-gate	ba,a	label		;\
2277c478bd9Sstevel@tonic-gate	.empty			;\
2287c478bd9Sstevel@tonic-gate	.align	32
2297c478bd9Sstevel@tonic-gate
2307c478bd9Sstevel@tonic-gate/*
2317c478bd9Sstevel@tonic-gate * Privileged traps
2327c478bd9Sstevel@tonic-gate * Takes breakpoint if privileged, calls trap() if not.
2337c478bd9Sstevel@tonic-gate */
2347c478bd9Sstevel@tonic-gate#define	PRIV(label)			\
2357c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g1		;\
2367c478bd9Sstevel@tonic-gate	btst	TSTATE_PRIV, %g1	;\
2377c478bd9Sstevel@tonic-gate	bnz	label			;\
2387c478bd9Sstevel@tonic-gate	rdpr	%tt, %g3		;\
2397c478bd9Sstevel@tonic-gate	set	trap, %g1		;\
2407c478bd9Sstevel@tonic-gate	ba,pt	%xcc, sys_trap		;\
2417c478bd9Sstevel@tonic-gate	sub	%g0, 1, %g4		;\
2427c478bd9Sstevel@tonic-gate	.align	32
2437c478bd9Sstevel@tonic-gate
2447c478bd9Sstevel@tonic-gate
2457c478bd9Sstevel@tonic-gate/*
2467c478bd9Sstevel@tonic-gate * DTrace traps.
2477c478bd9Sstevel@tonic-gate */
2487c478bd9Sstevel@tonic-gate#define	DTRACE_PID			\
2497c478bd9Sstevel@tonic-gate	.global dtrace_pid_probe				;\
2507c478bd9Sstevel@tonic-gate	set	dtrace_pid_probe, %g1				;\
2517c478bd9Sstevel@tonic-gate	ba,pt	%xcc, user_trap					;\
2527c478bd9Sstevel@tonic-gate	sub	%g0, 1, %g4					;\
2537c478bd9Sstevel@tonic-gate	.align	32
2547c478bd9Sstevel@tonic-gate
2557c478bd9Sstevel@tonic-gate#define	DTRACE_RETURN			\
2567c478bd9Sstevel@tonic-gate	.global dtrace_return_probe				;\
2577c478bd9Sstevel@tonic-gate	set	dtrace_return_probe, %g1			;\
2587c478bd9Sstevel@tonic-gate	ba,pt	%xcc, user_trap					;\
2597c478bd9Sstevel@tonic-gate	sub	%g0, 1, %g4					;\
2607c478bd9Sstevel@tonic-gate	.align	32
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate/*
2637c478bd9Sstevel@tonic-gate * REGISTER WINDOW MANAGEMENT MACROS
2647c478bd9Sstevel@tonic-gate */
2657c478bd9Sstevel@tonic-gate
2667c478bd9Sstevel@tonic-gate/*
2677c478bd9Sstevel@tonic-gate * various convenient units of padding
2687c478bd9Sstevel@tonic-gate */
2697c478bd9Sstevel@tonic-gate#define	SKIP(n)	.skip 4*(n)
2707c478bd9Sstevel@tonic-gate
2717c478bd9Sstevel@tonic-gate/*
2727c478bd9Sstevel@tonic-gate * CLEAN_WINDOW is the simple handler for cleaning a register window.
2737c478bd9Sstevel@tonic-gate */
2747c478bd9Sstevel@tonic-gate#define	CLEAN_WINDOW						\
2757c478bd9Sstevel@tonic-gate	TT_TRACE_L(trace_win)					;\
2767c478bd9Sstevel@tonic-gate	rdpr %cleanwin, %l0; inc %l0; wrpr %l0, %cleanwin	;\
2777c478bd9Sstevel@tonic-gate	clr %l0; clr %l1; clr %l2; clr %l3			;\
2787c478bd9Sstevel@tonic-gate	clr %l4; clr %l5; clr %l6; clr %l7			;\
2797c478bd9Sstevel@tonic-gate	clr %o0; clr %o1; clr %o2; clr %o3			;\
2807c478bd9Sstevel@tonic-gate	clr %o4; clr %o5; clr %o6; clr %o7			;\
2817c478bd9Sstevel@tonic-gate	retry; .align 128
2827c478bd9Sstevel@tonic-gate
2837c478bd9Sstevel@tonic-gate#if !defined(lint)
2847c478bd9Sstevel@tonic-gate
2857c478bd9Sstevel@tonic-gate/*
2867c478bd9Sstevel@tonic-gate * If we get an unresolved tlb miss while in a window handler, the fault
2877c478bd9Sstevel@tonic-gate * handler will resume execution at the last instruction of the window
2887c478bd9Sstevel@tonic-gate * hander, instead of delivering the fault to the kernel.  Spill handlers
2897c478bd9Sstevel@tonic-gate * use this to spill windows into the wbuf.
2907c478bd9Sstevel@tonic-gate *
2917c478bd9Sstevel@tonic-gate * The mixed handler works by checking %sp, and branching to the correct
2927c478bd9Sstevel@tonic-gate * handler.  This is done by branching back to label 1: for 32b frames,
2937c478bd9Sstevel@tonic-gate * or label 2: for 64b frames; which implies the handler order is: 32b,
2947c478bd9Sstevel@tonic-gate * 64b, mixed.  The 1: and 2: labels are offset into the routines to
2957c478bd9Sstevel@tonic-gate * allow the branchs' delay slots to contain useful instructions.
2967c478bd9Sstevel@tonic-gate */
2977c478bd9Sstevel@tonic-gate
2987c478bd9Sstevel@tonic-gate/*
2997c478bd9Sstevel@tonic-gate * SPILL_32bit spills a 32-bit-wide kernel register window.  It
3007c478bd9Sstevel@tonic-gate * assumes that the kernel context and the nucleus context are the
3017c478bd9Sstevel@tonic-gate * same.  The stack pointer is required to be eight-byte aligned even
3027c478bd9Sstevel@tonic-gate * though this code only needs it to be four-byte aligned.
3037c478bd9Sstevel@tonic-gate */
3047c478bd9Sstevel@tonic-gate#define	SPILL_32bit(tail)					\
3057c478bd9Sstevel@tonic-gate	srl	%sp, 0, %sp					;\
3067c478bd9Sstevel@tonic-gate1:	st	%l0, [%sp + 0]					;\
3077c478bd9Sstevel@tonic-gate	st	%l1, [%sp + 4]					;\
3087c478bd9Sstevel@tonic-gate	st	%l2, [%sp + 8]					;\
3097c478bd9Sstevel@tonic-gate	st	%l3, [%sp + 12]					;\
3107c478bd9Sstevel@tonic-gate	st	%l4, [%sp + 16]					;\
3117c478bd9Sstevel@tonic-gate	st	%l5, [%sp + 20]					;\
3127c478bd9Sstevel@tonic-gate	st	%l6, [%sp + 24]					;\
3137c478bd9Sstevel@tonic-gate	st	%l7, [%sp + 28]					;\
3147c478bd9Sstevel@tonic-gate	st	%i0, [%sp + 32]					;\
3157c478bd9Sstevel@tonic-gate	st	%i1, [%sp + 36]					;\
3167c478bd9Sstevel@tonic-gate	st	%i2, [%sp + 40]					;\
3177c478bd9Sstevel@tonic-gate	st	%i3, [%sp + 44]					;\
3187c478bd9Sstevel@tonic-gate	st	%i4, [%sp + 48]					;\
3197c478bd9Sstevel@tonic-gate	st	%i5, [%sp + 52]					;\
3207c478bd9Sstevel@tonic-gate	st	%i6, [%sp + 56]					;\
3217c478bd9Sstevel@tonic-gate	st	%i7, [%sp + 60]					;\
3227c478bd9Sstevel@tonic-gate	TT_TRACE_L(trace_win)					;\
3237c478bd9Sstevel@tonic-gate	saved							;\
3247c478bd9Sstevel@tonic-gate	retry							;\
3257c478bd9Sstevel@tonic-gate	SKIP(31-19-TT_TRACE_L_INS)				;\
3267c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, fault_32bit_/**/tail			;\
3277c478bd9Sstevel@tonic-gate	.empty
3287c478bd9Sstevel@tonic-gate
3297c478bd9Sstevel@tonic-gate/*
3307c478bd9Sstevel@tonic-gate * SPILL_32bit_asi spills a 32-bit-wide register window into a 32-bit
3317c478bd9Sstevel@tonic-gate * wide address space via the designated asi.  It is used to spill
3327c478bd9Sstevel@tonic-gate * non-kernel windows.  The stack pointer is required to be eight-byte
3337c478bd9Sstevel@tonic-gate * aligned even though this code only needs it to be four-byte
3347c478bd9Sstevel@tonic-gate * aligned.
3357c478bd9Sstevel@tonic-gate */
3367c478bd9Sstevel@tonic-gate#define	SPILL_32bit_asi(asi_num, tail)				\
3377c478bd9Sstevel@tonic-gate	srl	%sp, 0, %sp					;\
3387c478bd9Sstevel@tonic-gate1:	sta	%l0, [%sp + %g0]asi_num				;\
3397c478bd9Sstevel@tonic-gate	mov	4, %g1						;\
3407c478bd9Sstevel@tonic-gate	sta	%l1, [%sp + %g1]asi_num				;\
3417c478bd9Sstevel@tonic-gate	mov	8, %g2						;\
3427c478bd9Sstevel@tonic-gate	sta	%l2, [%sp + %g2]asi_num				;\
3437c478bd9Sstevel@tonic-gate	mov	12, %g3						;\
3447c478bd9Sstevel@tonic-gate	sta	%l3, [%sp + %g3]asi_num				;\
3457c478bd9Sstevel@tonic-gate	add	%sp, 16, %g4					;\
3467c478bd9Sstevel@tonic-gate	sta	%l4, [%g4 + %g0]asi_num				;\
3477c478bd9Sstevel@tonic-gate	sta	%l5, [%g4 + %g1]asi_num				;\
3487c478bd9Sstevel@tonic-gate	sta	%l6, [%g4 + %g2]asi_num				;\
3497c478bd9Sstevel@tonic-gate	sta	%l7, [%g4 + %g3]asi_num				;\
3507c478bd9Sstevel@tonic-gate	add	%g4, 16, %g4					;\
3517c478bd9Sstevel@tonic-gate	sta	%i0, [%g4 + %g0]asi_num				;\
3527c478bd9Sstevel@tonic-gate	sta	%i1, [%g4 + %g1]asi_num				;\
3537c478bd9Sstevel@tonic-gate	sta	%i2, [%g4 + %g2]asi_num				;\
3547c478bd9Sstevel@tonic-gate	sta	%i3, [%g4 + %g3]asi_num				;\
3557c478bd9Sstevel@tonic-gate	add	%g4, 16, %g4					;\
3567c478bd9Sstevel@tonic-gate	sta	%i4, [%g4 + %g0]asi_num				;\
3577c478bd9Sstevel@tonic-gate	sta	%i5, [%g4 + %g1]asi_num				;\
3587c478bd9Sstevel@tonic-gate	sta	%i6, [%g4 + %g2]asi_num				;\
3597c478bd9Sstevel@tonic-gate	sta	%i7, [%g4 + %g3]asi_num				;\
3607c478bd9Sstevel@tonic-gate	TT_TRACE_L(trace_win)					;\
3617c478bd9Sstevel@tonic-gate	saved							;\
3627c478bd9Sstevel@tonic-gate	retry							;\
3637c478bd9Sstevel@tonic-gate	SKIP(31-25-TT_TRACE_L_INS)				;\
3647c478bd9Sstevel@tonic-gate	ba,a,pt %xcc, fault_32bit_/**/tail			;\
3657c478bd9Sstevel@tonic-gate	.empty
3667c478bd9Sstevel@tonic-gate
3677c478bd9Sstevel@tonic-gate/*
3687c478bd9Sstevel@tonic-gate * SPILL_32bit_tt1 spills a 32-bit-wide register window into a 32-bit
3697c478bd9Sstevel@tonic-gate * wide address space via the designated asi.  It is used to spill
3707c478bd9Sstevel@tonic-gate * windows at tl>1 where performance isn't the primary concern and
3717c478bd9Sstevel@tonic-gate * where we don't want to use unnecessary registers.  The stack
3727c478bd9Sstevel@tonic-gate * pointer is required to be eight-byte aligned even though this code
3737c478bd9Sstevel@tonic-gate * only needs it to be four-byte aligned.
3747c478bd9Sstevel@tonic-gate */
3757c478bd9Sstevel@tonic-gate#define	SPILL_32bit_tt1(asi_num, tail)				\
3767c478bd9Sstevel@tonic-gate	mov	asi_num, %asi					;\
3777c478bd9Sstevel@tonic-gate1:	srl	%sp, 0, %sp					;\
3787c478bd9Sstevel@tonic-gate	sta	%l0, [%sp + 0]%asi				;\
3797c478bd9Sstevel@tonic-gate	sta	%l1, [%sp + 4]%asi				;\
3807c478bd9Sstevel@tonic-gate	sta	%l2, [%sp + 8]%asi				;\
3817c478bd9Sstevel@tonic-gate	sta	%l3, [%sp + 12]%asi				;\
3827c478bd9Sstevel@tonic-gate	sta	%l4, [%sp + 16]%asi				;\
3837c478bd9Sstevel@tonic-gate	sta	%l5, [%sp + 20]%asi				;\
3847c478bd9Sstevel@tonic-gate	sta	%l6, [%sp + 24]%asi				;\
3857c478bd9Sstevel@tonic-gate	sta	%l7, [%sp + 28]%asi				;\
3867c478bd9Sstevel@tonic-gate	sta	%i0, [%sp + 32]%asi				;\
3877c478bd9Sstevel@tonic-gate	sta	%i1, [%sp + 36]%asi				;\
3887c478bd9Sstevel@tonic-gate	sta	%i2, [%sp + 40]%asi				;\
3897c478bd9Sstevel@tonic-gate	sta	%i3, [%sp + 44]%asi				;\
3907c478bd9Sstevel@tonic-gate	sta	%i4, [%sp + 48]%asi				;\
3917c478bd9Sstevel@tonic-gate	sta	%i5, [%sp + 52]%asi				;\
3927c478bd9Sstevel@tonic-gate	sta	%i6, [%sp + 56]%asi				;\
3937c478bd9Sstevel@tonic-gate	sta	%i7, [%sp + 60]%asi				;\
3947c478bd9Sstevel@tonic-gate	TT_TRACE_L(trace_win)					;\
3957c478bd9Sstevel@tonic-gate	saved							;\
3967c478bd9Sstevel@tonic-gate	retry							;\
3977c478bd9Sstevel@tonic-gate	SKIP(31-20-TT_TRACE_L_INS)				;\
3987c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, fault_32bit_/**/tail			;\
3997c478bd9Sstevel@tonic-gate	.empty
4007c478bd9Sstevel@tonic-gate
4017c478bd9Sstevel@tonic-gate
4027c478bd9Sstevel@tonic-gate/*
4037c478bd9Sstevel@tonic-gate * FILL_32bit fills a 32-bit-wide kernel register window.  It assumes
4047c478bd9Sstevel@tonic-gate * that the kernel context and the nucleus context are the same.  The
4057c478bd9Sstevel@tonic-gate * stack pointer is required to be eight-byte aligned even though this
4067c478bd9Sstevel@tonic-gate * code only needs it to be four-byte aligned.
4077c478bd9Sstevel@tonic-gate */
4087c478bd9Sstevel@tonic-gate#define	FILL_32bit(tail)					\
4097c478bd9Sstevel@tonic-gate	srl	%sp, 0, %sp					;\
4107c478bd9Sstevel@tonic-gate1:	TT_TRACE_L(trace_win)					;\
4117c478bd9Sstevel@tonic-gate	ld	[%sp + 0], %l0					;\
4127c478bd9Sstevel@tonic-gate	ld	[%sp + 4], %l1					;\
4137c478bd9Sstevel@tonic-gate	ld	[%sp + 8], %l2					;\
4147c478bd9Sstevel@tonic-gate	ld	[%sp + 12], %l3					;\
4157c478bd9Sstevel@tonic-gate	ld	[%sp + 16], %l4					;\
4167c478bd9Sstevel@tonic-gate	ld	[%sp + 20], %l5					;\
4177c478bd9Sstevel@tonic-gate	ld	[%sp + 24], %l6					;\
4187c478bd9Sstevel@tonic-gate	ld	[%sp + 28], %l7					;\
4197c478bd9Sstevel@tonic-gate	ld	[%sp + 32], %i0					;\
4207c478bd9Sstevel@tonic-gate	ld	[%sp + 36], %i1					;\
4217c478bd9Sstevel@tonic-gate	ld	[%sp + 40], %i2					;\
4227c478bd9Sstevel@tonic-gate	ld	[%sp + 44], %i3					;\
4237c478bd9Sstevel@tonic-gate	ld	[%sp + 48], %i4					;\
4247c478bd9Sstevel@tonic-gate	ld	[%sp + 52], %i5					;\
4257c478bd9Sstevel@tonic-gate	ld	[%sp + 56], %i6					;\
4267c478bd9Sstevel@tonic-gate	ld	[%sp + 60], %i7					;\
4277c478bd9Sstevel@tonic-gate	restored						;\
4287c478bd9Sstevel@tonic-gate	retry							;\
4297c478bd9Sstevel@tonic-gate	SKIP(31-19-TT_TRACE_L_INS)				;\
4307c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, fault_32bit_/**/tail			;\
4317c478bd9Sstevel@tonic-gate	.empty
4327c478bd9Sstevel@tonic-gate
4337c478bd9Sstevel@tonic-gate/*
4347c478bd9Sstevel@tonic-gate * FILL_32bit_asi fills a 32-bit-wide register window from a 32-bit
4357c478bd9Sstevel@tonic-gate * wide address space via the designated asi.  It is used to fill
4367c478bd9Sstevel@tonic-gate * non-kernel windows.  The stack pointer is required to be eight-byte
4377c478bd9Sstevel@tonic-gate * aligned even though this code only needs it to be four-byte
4387c478bd9Sstevel@tonic-gate * aligned.
4397c478bd9Sstevel@tonic-gate */
4407c478bd9Sstevel@tonic-gate#define	FILL_32bit_asi(asi_num, tail)				\
4417c478bd9Sstevel@tonic-gate	srl	%sp, 0, %sp					;\
4427c478bd9Sstevel@tonic-gate1:	TT_TRACE_L(trace_win)					;\
4437c478bd9Sstevel@tonic-gate	mov	4, %g1						;\
4447c478bd9Sstevel@tonic-gate	lda	[%sp + %g0]asi_num, %l0				;\
4457c478bd9Sstevel@tonic-gate	mov	8, %g2						;\
4467c478bd9Sstevel@tonic-gate	lda	[%sp + %g1]asi_num, %l1				;\
4477c478bd9Sstevel@tonic-gate	mov	12, %g3						;\
4487c478bd9Sstevel@tonic-gate	lda	[%sp + %g2]asi_num, %l2				;\
4497c478bd9Sstevel@tonic-gate	lda	[%sp + %g3]asi_num, %l3				;\
4507c478bd9Sstevel@tonic-gate	add	%sp, 16, %g4					;\
4517c478bd9Sstevel@tonic-gate	lda	[%g4 + %g0]asi_num, %l4				;\
4527c478bd9Sstevel@tonic-gate	lda	[%g4 + %g1]asi_num, %l5				;\
4537c478bd9Sstevel@tonic-gate	lda	[%g4 + %g2]asi_num, %l6				;\
4547c478bd9Sstevel@tonic-gate	lda	[%g4 + %g3]asi_num, %l7				;\
4557c478bd9Sstevel@tonic-gate	add	%g4, 16, %g4					;\
4567c478bd9Sstevel@tonic-gate	lda	[%g4 + %g0]asi_num, %i0				;\
4577c478bd9Sstevel@tonic-gate	lda	[%g4 + %g1]asi_num, %i1				;\
4587c478bd9Sstevel@tonic-gate	lda	[%g4 + %g2]asi_num, %i2				;\
4597c478bd9Sstevel@tonic-gate	lda	[%g4 + %g3]asi_num, %i3				;\
4607c478bd9Sstevel@tonic-gate	add	%g4, 16, %g4					;\
4617c478bd9Sstevel@tonic-gate	lda	[%g4 + %g0]asi_num, %i4				;\
4627c478bd9Sstevel@tonic-gate	lda	[%g4 + %g1]asi_num, %i5				;\
4637c478bd9Sstevel@tonic-gate	lda	[%g4 + %g2]asi_num, %i6				;\
4647c478bd9Sstevel@tonic-gate	lda	[%g4 + %g3]asi_num, %i7				;\
4657c478bd9Sstevel@tonic-gate	restored						;\
4667c478bd9Sstevel@tonic-gate	retry							;\
4677c478bd9Sstevel@tonic-gate	SKIP(31-25-TT_TRACE_L_INS)				;\
4687c478bd9Sstevel@tonic-gate	ba,a,pt %xcc, fault_32bit_/**/tail			;\
4697c478bd9Sstevel@tonic-gate	.empty
4707c478bd9Sstevel@tonic-gate
4717c478bd9Sstevel@tonic-gate/*
4727c478bd9Sstevel@tonic-gate * FILL_32bit_tt1 fills a 32-bit-wide register window from a 32-bit
4737c478bd9Sstevel@tonic-gate * wide address space via the designated asi.  It is used to fill
4747c478bd9Sstevel@tonic-gate * windows at tl>1 where performance isn't the primary concern and
4757c478bd9Sstevel@tonic-gate * where we don't want to use unnecessary registers.  The stack
4767c478bd9Sstevel@tonic-gate * pointer is required to be eight-byte aligned even though this code
4777c478bd9Sstevel@tonic-gate * only needs it to be four-byte aligned.
4787c478bd9Sstevel@tonic-gate */
4797c478bd9Sstevel@tonic-gate#define	FILL_32bit_tt1(asi_num, tail)				\
4807c478bd9Sstevel@tonic-gate	mov	asi_num, %asi					;\
4817c478bd9Sstevel@tonic-gate1:	srl	%sp, 0, %sp					;\
4827c478bd9Sstevel@tonic-gate	TT_TRACE_L(trace_win)					;\
4837c478bd9Sstevel@tonic-gate	lda	[%sp + 0]%asi, %l0				;\
4847c478bd9Sstevel@tonic-gate	lda	[%sp + 4]%asi, %l1				;\
4857c478bd9Sstevel@tonic-gate	lda	[%sp + 8]%asi, %l2				;\
4867c478bd9Sstevel@tonic-gate	lda	[%sp + 12]%asi, %l3				;\
4877c478bd9Sstevel@tonic-gate	lda	[%sp + 16]%asi, %l4				;\
4887c478bd9Sstevel@tonic-gate	lda	[%sp + 20]%asi, %l5				;\
4897c478bd9Sstevel@tonic-gate	lda	[%sp + 24]%asi, %l6				;\
4907c478bd9Sstevel@tonic-gate	lda	[%sp + 28]%asi, %l7				;\
4917c478bd9Sstevel@tonic-gate	lda	[%sp + 32]%asi, %i0				;\
4927c478bd9Sstevel@tonic-gate	lda	[%sp + 36]%asi, %i1				;\
4937c478bd9Sstevel@tonic-gate	lda	[%sp + 40]%asi, %i2				;\
4947c478bd9Sstevel@tonic-gate	lda	[%sp + 44]%asi, %i3				;\
4957c478bd9Sstevel@tonic-gate	lda	[%sp + 48]%asi, %i4				;\
4967c478bd9Sstevel@tonic-gate	lda	[%sp + 52]%asi, %i5				;\
4977c478bd9Sstevel@tonic-gate	lda	[%sp + 56]%asi, %i6				;\
4987c478bd9Sstevel@tonic-gate	lda	[%sp + 60]%asi, %i7				;\
4997c478bd9Sstevel@tonic-gate	restored						;\
5007c478bd9Sstevel@tonic-gate	retry							;\
5017c478bd9Sstevel@tonic-gate	SKIP(31-20-TT_TRACE_L_INS)				;\
5027c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, fault_32bit_/**/tail			;\
5037c478bd9Sstevel@tonic-gate	.empty
5047c478bd9Sstevel@tonic-gate
5057c478bd9Sstevel@tonic-gate
5067c478bd9Sstevel@tonic-gate/*
5077c478bd9Sstevel@tonic-gate * SPILL_64bit spills a 64-bit-wide kernel register window.  It
5087c478bd9Sstevel@tonic-gate * assumes that the kernel context and the nucleus context are the
5097c478bd9Sstevel@tonic-gate * same.  The stack pointer is required to be eight-byte aligned.
5107c478bd9Sstevel@tonic-gate */
5117c478bd9Sstevel@tonic-gate#define	SPILL_64bit(tail)					\
5127c478bd9Sstevel@tonic-gate2:	stx	%l0, [%sp + V9BIAS64 + 0]			;\
5137c478bd9Sstevel@tonic-gate	stx	%l1, [%sp + V9BIAS64 + 8]			;\
5147c478bd9Sstevel@tonic-gate	stx	%l2, [%sp + V9BIAS64 + 16]			;\
5157c478bd9Sstevel@tonic-gate	stx	%l3, [%sp + V9BIAS64 + 24]			;\
5167c478bd9Sstevel@tonic-gate	stx	%l4, [%sp + V9BIAS64 + 32]			;\
5177c478bd9Sstevel@tonic-gate	stx	%l5, [%sp + V9BIAS64 + 40]			;\
5187c478bd9Sstevel@tonic-gate	stx	%l6, [%sp + V9BIAS64 + 48]			;\
5197c478bd9Sstevel@tonic-gate	stx	%l7, [%sp + V9BIAS64 + 56]			;\
5207c478bd9Sstevel@tonic-gate	stx	%i0, [%sp + V9BIAS64 + 64]			;\
5217c478bd9Sstevel@tonic-gate	stx	%i1, [%sp + V9BIAS64 + 72]			;\
5227c478bd9Sstevel@tonic-gate	stx	%i2, [%sp + V9BIAS64 + 80]			;\
5237c478bd9Sstevel@tonic-gate	stx	%i3, [%sp + V9BIAS64 + 88]			;\
5247c478bd9Sstevel@tonic-gate	stx	%i4, [%sp + V9BIAS64 + 96]			;\
5257c478bd9Sstevel@tonic-gate	stx	%i5, [%sp + V9BIAS64 + 104]			;\
5267c478bd9Sstevel@tonic-gate	stx	%i6, [%sp + V9BIAS64 + 112]			;\
5277c478bd9Sstevel@tonic-gate	stx	%i7, [%sp + V9BIAS64 + 120]			;\
5287c478bd9Sstevel@tonic-gate	TT_TRACE_L(trace_win)					;\
5297c478bd9Sstevel@tonic-gate	saved							;\
5307c478bd9Sstevel@tonic-gate	retry							;\
5317c478bd9Sstevel@tonic-gate	SKIP(31-18-TT_TRACE_L_INS)				;\
5327c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, fault_64bit_/**/tail			;\
5337c478bd9Sstevel@tonic-gate	.empty
5347c478bd9Sstevel@tonic-gate
5357c478bd9Sstevel@tonic-gate/*
5367c478bd9Sstevel@tonic-gate * SPILL_64bit_asi spills a 64-bit-wide register window into a 64-bit
5377c478bd9Sstevel@tonic-gate * wide address space via the designated asi.  It is used to spill
5387c478bd9Sstevel@tonic-gate * non-kernel windows.  The stack pointer is required to be eight-byte
5397c478bd9Sstevel@tonic-gate * aligned.
5407c478bd9Sstevel@tonic-gate */
5417c478bd9Sstevel@tonic-gate#define	SPILL_64bit_asi(asi_num, tail)				\
5427c478bd9Sstevel@tonic-gate	mov	0 + V9BIAS64, %g1				;\
5437c478bd9Sstevel@tonic-gate2:	stxa	%l0, [%sp + %g1]asi_num				;\
5447c478bd9Sstevel@tonic-gate	mov	8 + V9BIAS64, %g2				;\
5457c478bd9Sstevel@tonic-gate	stxa	%l1, [%sp + %g2]asi_num				;\
5467c478bd9Sstevel@tonic-gate	mov	16 + V9BIAS64, %g3				;\
5477c478bd9Sstevel@tonic-gate	stxa	%l2, [%sp + %g3]asi_num				;\
5487c478bd9Sstevel@tonic-gate	mov	24 + V9BIAS64, %g4				;\
5497c478bd9Sstevel@tonic-gate	stxa	%l3, [%sp + %g4]asi_num				;\
5507c478bd9Sstevel@tonic-gate	add	%sp, 32, %g5					;\
5517c478bd9Sstevel@tonic-gate	stxa	%l4, [%g5 + %g1]asi_num				;\
5527c478bd9Sstevel@tonic-gate	stxa	%l5, [%g5 + %g2]asi_num				;\
5537c478bd9Sstevel@tonic-gate	stxa	%l6, [%g5 + %g3]asi_num				;\
5547c478bd9Sstevel@tonic-gate	stxa	%l7, [%g5 + %g4]asi_num				;\
5557c478bd9Sstevel@tonic-gate	add	%g5, 32, %g5					;\
5567c478bd9Sstevel@tonic-gate	stxa	%i0, [%g5 + %g1]asi_num				;\
5577c478bd9Sstevel@tonic-gate	stxa	%i1, [%g5 + %g2]asi_num				;\
5587c478bd9Sstevel@tonic-gate	stxa	%i2, [%g5 + %g3]asi_num				;\
5597c478bd9Sstevel@tonic-gate	stxa	%i3, [%g5 + %g4]asi_num				;\
5607c478bd9Sstevel@tonic-gate	add	%g5, 32, %g5					;\
5617c478bd9Sstevel@tonic-gate	stxa	%i4, [%g5 + %g1]asi_num				;\
5627c478bd9Sstevel@tonic-gate	stxa	%i5, [%g5 + %g2]asi_num				;\
5637c478bd9Sstevel@tonic-gate	stxa	%i6, [%g5 + %g3]asi_num				;\
5647c478bd9Sstevel@tonic-gate	stxa	%i7, [%g5 + %g4]asi_num				;\
5657c478bd9Sstevel@tonic-gate	TT_TRACE_L(trace_win)					;\
5667c478bd9Sstevel@tonic-gate	saved							;\
5677c478bd9Sstevel@tonic-gate	retry							;\
5687c478bd9Sstevel@tonic-gate	SKIP(31-25-TT_TRACE_L_INS)				;\
5697c478bd9Sstevel@tonic-gate	ba,a,pt %xcc, fault_64bit_/**/tail			;\
5707c478bd9Sstevel@tonic-gate	.empty
5717c478bd9Sstevel@tonic-gate
5727c478bd9Sstevel@tonic-gate/*
5737c478bd9Sstevel@tonic-gate * SPILL_64bit_tt1 spills a 64-bit-wide register window into a 64-bit
5747c478bd9Sstevel@tonic-gate * wide address space via the designated asi.  It is used to spill
5757c478bd9Sstevel@tonic-gate * windows at tl>1 where performance isn't the primary concern and
5767c478bd9Sstevel@tonic-gate * where we don't want to use unnecessary registers.  The stack
5777c478bd9Sstevel@tonic-gate * pointer is required to be eight-byte aligned.
5787c478bd9Sstevel@tonic-gate */
5797c478bd9Sstevel@tonic-gate#define	SPILL_64bit_tt1(asi_num, tail)				\
5807c478bd9Sstevel@tonic-gate	mov	asi_num, %asi					;\
5817c478bd9Sstevel@tonic-gate2:	stxa	%l0, [%sp + V9BIAS64 + 0]%asi			;\
5827c478bd9Sstevel@tonic-gate	stxa	%l1, [%sp + V9BIAS64 + 8]%asi			;\
5837c478bd9Sstevel@tonic-gate	stxa	%l2, [%sp + V9BIAS64 + 16]%asi			;\
5847c478bd9Sstevel@tonic-gate	stxa	%l3, [%sp + V9BIAS64 + 24]%asi			;\
5857c478bd9Sstevel@tonic-gate	stxa	%l4, [%sp + V9BIAS64 + 32]%asi			;\
5867c478bd9Sstevel@tonic-gate	stxa	%l5, [%sp + V9BIAS64 + 40]%asi			;\
5877c478bd9Sstevel@tonic-gate	stxa	%l6, [%sp + V9BIAS64 + 48]%asi			;\
5887c478bd9Sstevel@tonic-gate	stxa	%l7, [%sp + V9BIAS64 + 56]%asi			;\
5897c478bd9Sstevel@tonic-gate	stxa	%i0, [%sp + V9BIAS64 + 64]%asi			;\
5907c478bd9Sstevel@tonic-gate	stxa	%i1, [%sp + V9BIAS64 + 72]%asi			;\
5917c478bd9Sstevel@tonic-gate	stxa	%i2, [%sp + V9BIAS64 + 80]%asi			;\
5927c478bd9Sstevel@tonic-gate	stxa	%i3, [%sp + V9BIAS64 + 88]%asi			;\
5937c478bd9Sstevel@tonic-gate	stxa	%i4, [%sp + V9BIAS64 + 96]%asi			;\
5947c478bd9Sstevel@tonic-gate	stxa	%i5, [%sp + V9BIAS64 + 104]%asi			;\
5957c478bd9Sstevel@tonic-gate	stxa	%i6, [%sp + V9BIAS64 + 112]%asi			;\
5967c478bd9Sstevel@tonic-gate	stxa	%i7, [%sp + V9BIAS64 + 120]%asi			;\
5977c478bd9Sstevel@tonic-gate	TT_TRACE_L(trace_win)					;\
5987c478bd9Sstevel@tonic-gate	saved							;\
5997c478bd9Sstevel@tonic-gate	retry							;\
6007c478bd9Sstevel@tonic-gate	SKIP(31-19-TT_TRACE_L_INS)				;\
6017c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, fault_64bit_/**/tail			;\
6027c478bd9Sstevel@tonic-gate	.empty
6037c478bd9Sstevel@tonic-gate
6047c478bd9Sstevel@tonic-gate
6057c478bd9Sstevel@tonic-gate/*
6067c478bd9Sstevel@tonic-gate * FILL_64bit fills a 64-bit-wide kernel register window.  It assumes
6077c478bd9Sstevel@tonic-gate * that the kernel context and the nucleus context are the same.  The
6087c478bd9Sstevel@tonic-gate * stack pointer is required to be eight-byte aligned.
6097c478bd9Sstevel@tonic-gate */
6107c478bd9Sstevel@tonic-gate#define	FILL_64bit(tail)					\
6117c478bd9Sstevel@tonic-gate2:	TT_TRACE_L(trace_win)					;\
6127c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 0], %l0			;\
6137c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 8], %l1			;\
6147c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 16], %l2			;\
6157c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 24], %l3			;\
6167c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 32], %l4			;\
6177c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 40], %l5			;\
6187c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 48], %l6			;\
6197c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 56], %l7			;\
6207c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 64], %i0			;\
6217c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 72], %i1			;\
6227c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 80], %i2			;\
6237c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 88], %i3			;\
6247c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 96], %i4			;\
6257c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 104], %i5			;\
6267c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 112], %i6			;\
6277c478bd9Sstevel@tonic-gate	ldx	[%sp + V9BIAS64 + 120], %i7			;\
6287c478bd9Sstevel@tonic-gate	restored						;\
6297c478bd9Sstevel@tonic-gate	retry							;\
6307c478bd9Sstevel@tonic-gate	SKIP(31-18-TT_TRACE_L_INS)				;\
6317c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, fault_64bit_/**/tail			;\
6327c478bd9Sstevel@tonic-gate	.empty
6337c478bd9Sstevel@tonic-gate
6347c478bd9Sstevel@tonic-gate/*
6357c478bd9Sstevel@tonic-gate * FILL_64bit_asi fills a 64-bit-wide register window from a 64-bit
6367c478bd9Sstevel@tonic-gate * wide address space via the designated asi.  It is used to fill
6377c478bd9Sstevel@tonic-gate * non-kernel windows.  The stack pointer is required to be eight-byte
6387c478bd9Sstevel@tonic-gate * aligned.
6397c478bd9Sstevel@tonic-gate */
6407c478bd9Sstevel@tonic-gate#define	FILL_64bit_asi(asi_num, tail)				\
6417c478bd9Sstevel@tonic-gate	mov	V9BIAS64 + 0, %g1				;\
6427c478bd9Sstevel@tonic-gate2:	TT_TRACE_L(trace_win)					;\
6437c478bd9Sstevel@tonic-gate	ldxa	[%sp + %g1]asi_num, %l0				;\
6447c478bd9Sstevel@tonic-gate	mov	V9BIAS64 + 8, %g2				;\
6457c478bd9Sstevel@tonic-gate	ldxa	[%sp + %g2]asi_num, %l1				;\
6467c478bd9Sstevel@tonic-gate	mov	V9BIAS64 + 16, %g3				;\
6477c478bd9Sstevel@tonic-gate	ldxa	[%sp + %g3]asi_num, %l2				;\
6487c478bd9Sstevel@tonic-gate	mov	V9BIAS64 + 24, %g4				;\
6497c478bd9Sstevel@tonic-gate	ldxa	[%sp + %g4]asi_num, %l3				;\
6507c478bd9Sstevel@tonic-gate	add	%sp, 32, %g5					;\
6517c478bd9Sstevel@tonic-gate	ldxa	[%g5 + %g1]asi_num, %l4				;\
6527c478bd9Sstevel@tonic-gate	ldxa	[%g5 + %g2]asi_num, %l5				;\
6537c478bd9Sstevel@tonic-gate	ldxa	[%g5 + %g3]asi_num, %l6				;\
6547c478bd9Sstevel@tonic-gate	ldxa	[%g5 + %g4]asi_num, %l7				;\
6557c478bd9Sstevel@tonic-gate	add	%g5, 32, %g5					;\
6567c478bd9Sstevel@tonic-gate	ldxa	[%g5 + %g1]asi_num, %i0				;\
6577c478bd9Sstevel@tonic-gate	ldxa	[%g5 + %g2]asi_num, %i1				;\
6587c478bd9Sstevel@tonic-gate	ldxa	[%g5 + %g3]asi_num, %i2				;\
6597c478bd9Sstevel@tonic-gate	ldxa	[%g5 + %g4]asi_num, %i3				;\
6607c478bd9Sstevel@tonic-gate	add	%g5, 32, %g5					;\
6617c478bd9Sstevel@tonic-gate	ldxa	[%g5 + %g1]asi_num, %i4				;\
6627c478bd9Sstevel@tonic-gate	ldxa	[%g5 + %g2]asi_num, %i5				;\
6637c478bd9Sstevel@tonic-gate	ldxa	[%g5 + %g3]asi_num, %i6				;\
6647c478bd9Sstevel@tonic-gate	ldxa	[%g5 + %g4]asi_num, %i7				;\
6657c478bd9Sstevel@tonic-gate	restored						;\
6667c478bd9Sstevel@tonic-gate	retry							;\
6677c478bd9Sstevel@tonic-gate	SKIP(31-25-TT_TRACE_L_INS)				;\
6687c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, fault_64bit_/**/tail			;\
6697c478bd9Sstevel@tonic-gate	.empty
6707c478bd9Sstevel@tonic-gate
6717c478bd9Sstevel@tonic-gate/*
6727c478bd9Sstevel@tonic-gate * FILL_64bit_tt1 fills a 64-bit-wide register window from a 64-bit
6737c478bd9Sstevel@tonic-gate * wide address space via the designated asi.  It is used to fill
6747c478bd9Sstevel@tonic-gate * windows at tl>1 where performance isn't the primary concern and
6757c478bd9Sstevel@tonic-gate * where we don't want to use unnecessary registers.  The stack
6767c478bd9Sstevel@tonic-gate * pointer is required to be eight-byte aligned.
6777c478bd9Sstevel@tonic-gate */
6787c478bd9Sstevel@tonic-gate#define	FILL_64bit_tt1(asi_num, tail)				\
6797c478bd9Sstevel@tonic-gate	mov	asi_num, %asi					;\
6807c478bd9Sstevel@tonic-gate	TT_TRACE_L(trace_win)					;\
6817c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 0]%asi, %l0			;\
6827c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 8]%asi, %l1			;\
6837c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 16]%asi, %l2			;\
6847c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 24]%asi, %l3			;\
6857c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 32]%asi, %l4			;\
6867c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 40]%asi, %l5			;\
6877c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 48]%asi, %l6			;\
6887c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 56]%asi, %l7			;\
6897c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 64]%asi, %i0			;\
6907c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 72]%asi, %i1			;\
6917c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 80]%asi, %i2			;\
6927c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 88]%asi, %i3			;\
6937c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 96]%asi, %i4			;\
6947c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 104]%asi, %i5			;\
6957c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 112]%asi, %i6			;\
6967c478bd9Sstevel@tonic-gate	ldxa	[%sp + V9BIAS64 + 120]%asi, %i7			;\
6977c478bd9Sstevel@tonic-gate	restored						;\
6987c478bd9Sstevel@tonic-gate	retry							;\
6997c478bd9Sstevel@tonic-gate	SKIP(31-19-TT_TRACE_L_INS)				;\
7007c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, fault_64bit_/**/tail			;\
7017c478bd9Sstevel@tonic-gate	.empty
7027c478bd9Sstevel@tonic-gate
7037c478bd9Sstevel@tonic-gate#endif /* !lint */
7047c478bd9Sstevel@tonic-gate
7057c478bd9Sstevel@tonic-gate/*
7067c478bd9Sstevel@tonic-gate * SPILL_mixed spills either size window, depending on
7077c478bd9Sstevel@tonic-gate * whether %sp is even or odd, to a 32-bit address space.
7087c478bd9Sstevel@tonic-gate * This may only be used in conjunction with SPILL_32bit/
7097c478bd9Sstevel@tonic-gate * SPILL_64bit. New versions of SPILL_mixed_{tt1,asi} would be
7107c478bd9Sstevel@tonic-gate * needed for use with SPILL_{32,64}bit_{tt1,asi}.  Particular
7117c478bd9Sstevel@tonic-gate * attention should be paid to the instructions that belong
7127c478bd9Sstevel@tonic-gate * in the delay slots of the branches depending on the type
7137c478bd9Sstevel@tonic-gate * of spill handler being branched to.
7147c478bd9Sstevel@tonic-gate * Clear upper 32 bits of %sp if it is odd.
7157c478bd9Sstevel@tonic-gate * We won't need to clear them in 64 bit kernel.
7167c478bd9Sstevel@tonic-gate */
7177c478bd9Sstevel@tonic-gate#define	SPILL_mixed						\
7187c478bd9Sstevel@tonic-gate	btst	1, %sp						;\
7197c478bd9Sstevel@tonic-gate	bz,a,pt	%xcc, 1b					;\
7207c478bd9Sstevel@tonic-gate	srl	%sp, 0, %sp					;\
7217c478bd9Sstevel@tonic-gate	ba,pt	%xcc, 2b					;\
7227c478bd9Sstevel@tonic-gate	nop							;\
7237c478bd9Sstevel@tonic-gate	.align	128
7247c478bd9Sstevel@tonic-gate
7257c478bd9Sstevel@tonic-gate/*
7267c478bd9Sstevel@tonic-gate * FILL_mixed(ASI) fills either size window, depending on
7277c478bd9Sstevel@tonic-gate * whether %sp is even or odd, from a 32-bit address space.
7287c478bd9Sstevel@tonic-gate * This may only be used in conjunction with FILL_32bit/
7297c478bd9Sstevel@tonic-gate * FILL_64bit. New versions of FILL_mixed_{tt1,asi} would be
7307c478bd9Sstevel@tonic-gate * needed for use with FILL_{32,64}bit_{tt1,asi}. Particular
7317c478bd9Sstevel@tonic-gate * attention should be paid to the instructions that belong
7327c478bd9Sstevel@tonic-gate * in the delay slots of the branches depending on the type
7337c478bd9Sstevel@tonic-gate * of fill handler being branched to.
7347c478bd9Sstevel@tonic-gate * Clear upper 32 bits of %sp if it is odd.
7357c478bd9Sstevel@tonic-gate * We won't need to clear them in 64 bit kernel.
7367c478bd9Sstevel@tonic-gate */
7377c478bd9Sstevel@tonic-gate#define	FILL_mixed						\
7387c478bd9Sstevel@tonic-gate	btst	1, %sp						;\
7397c478bd9Sstevel@tonic-gate	bz,a,pt	%xcc, 1b					;\
7407c478bd9Sstevel@tonic-gate	srl	%sp, 0, %sp					;\
7417c478bd9Sstevel@tonic-gate	ba,pt	%xcc, 2b					;\
7427c478bd9Sstevel@tonic-gate	nop							;\
7437c478bd9Sstevel@tonic-gate	.align	128
7447c478bd9Sstevel@tonic-gate
7457c478bd9Sstevel@tonic-gate
7467c478bd9Sstevel@tonic-gate/*
7477c478bd9Sstevel@tonic-gate * SPILL_32clean/SPILL_64clean spill 32-bit and 64-bit register windows,
7487c478bd9Sstevel@tonic-gate * respectively, into the address space via the designated asi.  The
7497c478bd9Sstevel@tonic-gate * unbiased stack pointer is required to be eight-byte aligned (even for
7507c478bd9Sstevel@tonic-gate * the 32-bit case even though this code does not require such strict
7517c478bd9Sstevel@tonic-gate * alignment).
7527c478bd9Sstevel@tonic-gate *
7537c478bd9Sstevel@tonic-gate * With SPARC v9 the spill trap takes precedence over the cleanwin trap
7547c478bd9Sstevel@tonic-gate * so when cansave == 0, canrestore == 6, and cleanwin == 6 the next save
7557c478bd9Sstevel@tonic-gate * will cause cwp + 2 to be spilled but will not clean cwp + 1.  That
7567c478bd9Sstevel@tonic-gate * window may contain kernel data so in user_rtt we set wstate to call
7577c478bd9Sstevel@tonic-gate * these spill handlers on the first user spill trap.  These handler then
7587c478bd9Sstevel@tonic-gate * spill the appropriate window but also back up a window and clean the
7597c478bd9Sstevel@tonic-gate * window that didn't get a cleanwin trap.
7607c478bd9Sstevel@tonic-gate */
7617c478bd9Sstevel@tonic-gate#define	SPILL_32clean(asi_num, tail)				\
7627c478bd9Sstevel@tonic-gate	srl	%sp, 0, %sp					;\
7637c478bd9Sstevel@tonic-gate	sta	%l0, [%sp + %g0]asi_num				;\
7647c478bd9Sstevel@tonic-gate	mov	4, %g1						;\
7657c478bd9Sstevel@tonic-gate	sta	%l1, [%sp + %g1]asi_num				;\
7667c478bd9Sstevel@tonic-gate	mov	8, %g2						;\
7677c478bd9Sstevel@tonic-gate	sta	%l2, [%sp + %g2]asi_num				;\
7687c478bd9Sstevel@tonic-gate	mov	12, %g3						;\
7697c478bd9Sstevel@tonic-gate	sta	%l3, [%sp + %g3]asi_num				;\
7707c478bd9Sstevel@tonic-gate	add	%sp, 16, %g4					;\
7717c478bd9Sstevel@tonic-gate	sta	%l4, [%g4 + %g0]asi_num				;\
7727c478bd9Sstevel@tonic-gate	sta	%l5, [%g4 + %g1]asi_num				;\
7737c478bd9Sstevel@tonic-gate	sta	%l6, [%g4 + %g2]asi_num				;\
7747c478bd9Sstevel@tonic-gate	sta	%l7, [%g4 + %g3]asi_num				;\
7757c478bd9Sstevel@tonic-gate	add	%g4, 16, %g4					;\
7767c478bd9Sstevel@tonic-gate	sta	%i0, [%g4 + %g0]asi_num				;\
7777c478bd9Sstevel@tonic-gate	sta	%i1, [%g4 + %g1]asi_num				;\
7787c478bd9Sstevel@tonic-gate	sta	%i2, [%g4 + %g2]asi_num				;\
7797c478bd9Sstevel@tonic-gate	sta	%i3, [%g4 + %g3]asi_num				;\
7807c478bd9Sstevel@tonic-gate	add	%g4, 16, %g4					;\
7817c478bd9Sstevel@tonic-gate	sta	%i4, [%g4 + %g0]asi_num				;\
7827c478bd9Sstevel@tonic-gate	sta	%i5, [%g4 + %g1]asi_num				;\
7837c478bd9Sstevel@tonic-gate	sta	%i6, [%g4 + %g2]asi_num				;\
7847c478bd9Sstevel@tonic-gate	sta	%i7, [%g4 + %g3]asi_num				;\
7857c478bd9Sstevel@tonic-gate	TT_TRACE_L(trace_win)					;\
7867c478bd9Sstevel@tonic-gate	b	.spill_clean					;\
7877c478bd9Sstevel@tonic-gate	  mov	WSTATE_USER32, %g7				;\
7887c478bd9Sstevel@tonic-gate	SKIP(31-25-TT_TRACE_L_INS)				;\
7897c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, fault_32bit_/**/tail			;\
7907c478bd9Sstevel@tonic-gate	.empty
7917c478bd9Sstevel@tonic-gate
7927c478bd9Sstevel@tonic-gate#define	SPILL_64clean(asi_num, tail)				\
7937c478bd9Sstevel@tonic-gate	mov	0 + V9BIAS64, %g1				;\
7947c478bd9Sstevel@tonic-gate	stxa	%l0, [%sp + %g1]asi_num				;\
7957c478bd9Sstevel@tonic-gate	mov	8 + V9BIAS64, %g2				;\
7967c478bd9Sstevel@tonic-gate	stxa	%l1, [%sp + %g2]asi_num				;\
7977c478bd9Sstevel@tonic-gate	mov	16 + V9BIAS64, %g3				;\
7987c478bd9Sstevel@tonic-gate	stxa	%l2, [%sp + %g3]asi_num				;\
7997c478bd9Sstevel@tonic-gate	mov	24 + V9BIAS64, %g4				;\
8007c478bd9Sstevel@tonic-gate	stxa	%l3, [%sp + %g4]asi_num				;\
8017c478bd9Sstevel@tonic-gate	add	%sp, 32, %g5					;\
8027c478bd9Sstevel@tonic-gate	stxa	%l4, [%g5 + %g1]asi_num				;\
8037c478bd9Sstevel@tonic-gate	stxa	%l5, [%g5 + %g2]asi_num				;\
8047c478bd9Sstevel@tonic-gate	stxa	%l6, [%g5 + %g3]asi_num				;\
8057c478bd9Sstevel@tonic-gate	stxa	%l7, [%g5 + %g4]asi_num				;\
8067c478bd9Sstevel@tonic-gate	add	%g5, 32, %g5					;\
8077c478bd9Sstevel@tonic-gate	stxa	%i0, [%g5 + %g1]asi_num				;\
8087c478bd9Sstevel@tonic-gate	stxa	%i1, [%g5 + %g2]asi_num				;\
8097c478bd9Sstevel@tonic-gate	stxa	%i2, [%g5 + %g3]asi_num				;\
8107c478bd9Sstevel@tonic-gate	stxa	%i3, [%g5 + %g4]asi_num				;\
8117c478bd9Sstevel@tonic-gate	add	%g5, 32, %g5					;\
8127c478bd9Sstevel@tonic-gate	stxa	%i4, [%g5 + %g1]asi_num				;\
8137c478bd9Sstevel@tonic-gate	stxa	%i5, [%g5 + %g2]asi_num				;\
8147c478bd9Sstevel@tonic-gate	stxa	%i6, [%g5 + %g3]asi_num				;\
8157c478bd9Sstevel@tonic-gate	stxa	%i7, [%g5 + %g4]asi_num				;\
8167c478bd9Sstevel@tonic-gate	TT_TRACE_L(trace_win)					;\
8177c478bd9Sstevel@tonic-gate	b	.spill_clean					;\
8187c478bd9Sstevel@tonic-gate	  mov	WSTATE_USER64, %g7				;\
8197c478bd9Sstevel@tonic-gate	SKIP(31-25-TT_TRACE_L_INS)				;\
8207c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, fault_64bit_/**/tail			;\
8217c478bd9Sstevel@tonic-gate	.empty
8227c478bd9Sstevel@tonic-gate
8237c478bd9Sstevel@tonic-gate
8247c478bd9Sstevel@tonic-gate/*
8257c478bd9Sstevel@tonic-gate * Floating point disabled.
8267c478bd9Sstevel@tonic-gate */
8277c478bd9Sstevel@tonic-gate#define	FP_DISABLED_TRAP		\
8287c478bd9Sstevel@tonic-gate	TT_TRACE(trace_gen)		;\
8297c478bd9Sstevel@tonic-gate	ba,pt	%xcc,.fp_disabled	;\
8307c478bd9Sstevel@tonic-gate	nop				;\
8317c478bd9Sstevel@tonic-gate	.align	32
8327c478bd9Sstevel@tonic-gate
8337c478bd9Sstevel@tonic-gate/*
8347c478bd9Sstevel@tonic-gate * Floating point exceptions.
8357c478bd9Sstevel@tonic-gate */
8367c478bd9Sstevel@tonic-gate#define	FP_IEEE_TRAP			\
8377c478bd9Sstevel@tonic-gate	TT_TRACE(trace_gen)		;\
8387c478bd9Sstevel@tonic-gate	ba,pt	%xcc,.fp_ieee_exception	;\
8397c478bd9Sstevel@tonic-gate	nop				;\
8407c478bd9Sstevel@tonic-gate	.align	32
8417c478bd9Sstevel@tonic-gate
8427c478bd9Sstevel@tonic-gate#define	FP_TRAP				\
8437c478bd9Sstevel@tonic-gate	TT_TRACE(trace_gen)		;\
8447c478bd9Sstevel@tonic-gate	ba,pt	%xcc,.fp_exception	;\
8457c478bd9Sstevel@tonic-gate	nop				;\
8467c478bd9Sstevel@tonic-gate	.align	32
8477c478bd9Sstevel@tonic-gate
8487c478bd9Sstevel@tonic-gate#if !defined(lint)
8497c478bd9Sstevel@tonic-gate/*
8507c478bd9Sstevel@tonic-gate * asynchronous traps at level 0 and level 1
8517c478bd9Sstevel@tonic-gate *
8527c478bd9Sstevel@tonic-gate * The first instruction must be a membar for UltraSPARC-III
8537c478bd9Sstevel@tonic-gate * to stop RED state entry if the store queue has many
8547c478bd9Sstevel@tonic-gate * pending bad stores (PRM, Chapter 11).
8557c478bd9Sstevel@tonic-gate */
85625cf1a30Sjl139090#define ASYNC_TRAP(ttype, ttlabel, table_name)\
85725cf1a30Sjl139090	.global	table_name	;\
85825cf1a30Sjl139090table_name:			;\
8597c478bd9Sstevel@tonic-gate	membar	#Sync		;\
8607c478bd9Sstevel@tonic-gate	TT_TRACE(ttlabel)	;\
8617c478bd9Sstevel@tonic-gate	ba	async_err	;\
8627c478bd9Sstevel@tonic-gate	mov	ttype, %g5	;\
8637c478bd9Sstevel@tonic-gate	.align	32
8647c478bd9Sstevel@tonic-gate
8657c478bd9Sstevel@tonic-gate/*
8667c478bd9Sstevel@tonic-gate * Defaults to BAD entry, but establishes label to be used for
8677c478bd9Sstevel@tonic-gate * architecture-specific overwrite of trap table entry.
8687c478bd9Sstevel@tonic-gate */
8697c478bd9Sstevel@tonic-gate#define	LABELED_BAD(table_name)		\
8707c478bd9Sstevel@tonic-gate	.global	table_name		;\
8717c478bd9Sstevel@tonic-gatetable_name:				;\
8727c478bd9Sstevel@tonic-gate	BAD
8737c478bd9Sstevel@tonic-gate
8747c478bd9Sstevel@tonic-gate#endif /* !lint */
8757c478bd9Sstevel@tonic-gate
8767c478bd9Sstevel@tonic-gate/*
8777c478bd9Sstevel@tonic-gate * illegal instruction trap
8787c478bd9Sstevel@tonic-gate */
8797c478bd9Sstevel@tonic-gate#define	ILLTRAP_INSTR			  \
8807c478bd9Sstevel@tonic-gate	membar	#Sync			  ;\
8817c478bd9Sstevel@tonic-gate	TT_TRACE(trace_gen)		  ;\
8827c478bd9Sstevel@tonic-gate	or	%g0, P_UTRAP4, %g2	  ;\
8837c478bd9Sstevel@tonic-gate	or	%g0, T_UNIMP_INSTR, %g3   ;\
8847c478bd9Sstevel@tonic-gate	sethi	%hi(.check_v9utrap), %g4  ;\
8857c478bd9Sstevel@tonic-gate	jmp	%g4 + %lo(.check_v9utrap) ;\
8867c478bd9Sstevel@tonic-gate	nop				  ;\
8877c478bd9Sstevel@tonic-gate	.align	32
8887c478bd9Sstevel@tonic-gate
8897c478bd9Sstevel@tonic-gate/*
8907c478bd9Sstevel@tonic-gate * tag overflow trap
8917c478bd9Sstevel@tonic-gate */
8927c478bd9Sstevel@tonic-gate#define	TAG_OVERFLOW			  \
8937c478bd9Sstevel@tonic-gate	TT_TRACE(trace_gen)		  ;\
8947c478bd9Sstevel@tonic-gate	or	%g0, P_UTRAP10, %g2	  ;\
8957c478bd9Sstevel@tonic-gate	or	%g0, T_TAG_OVERFLOW, %g3  ;\
8967c478bd9Sstevel@tonic-gate	sethi	%hi(.check_v9utrap), %g4  ;\
8977c478bd9Sstevel@tonic-gate	jmp	%g4 + %lo(.check_v9utrap) ;\
8987c478bd9Sstevel@tonic-gate	nop				  ;\
8997c478bd9Sstevel@tonic-gate	.align	32
9007c478bd9Sstevel@tonic-gate
9017c478bd9Sstevel@tonic-gate/*
9027c478bd9Sstevel@tonic-gate * divide by zero trap
9037c478bd9Sstevel@tonic-gate */
9047c478bd9Sstevel@tonic-gate#define	DIV_BY_ZERO			  \
9057c478bd9Sstevel@tonic-gate	TT_TRACE(trace_gen)		  ;\
9067c478bd9Sstevel@tonic-gate	or	%g0, P_UTRAP11, %g2	  ;\
9077c478bd9Sstevel@tonic-gate	or	%g0, T_IDIV0, %g3	  ;\
9087c478bd9Sstevel@tonic-gate	sethi	%hi(.check_v9utrap), %g4  ;\
9097c478bd9Sstevel@tonic-gate	jmp	%g4 + %lo(.check_v9utrap) ;\
9107c478bd9Sstevel@tonic-gate	nop				  ;\
9117c478bd9Sstevel@tonic-gate	.align	32
9127c478bd9Sstevel@tonic-gate
9137c478bd9Sstevel@tonic-gate/*
9147c478bd9Sstevel@tonic-gate * trap instruction for V9 user trap handlers
9157c478bd9Sstevel@tonic-gate */
9167c478bd9Sstevel@tonic-gate#define	TRAP_INSTR			  \
9177c478bd9Sstevel@tonic-gate	TT_TRACE(trace_gen)		  ;\
9187c478bd9Sstevel@tonic-gate	or	%g0, T_SOFTWARE_TRAP, %g3 ;\
9197c478bd9Sstevel@tonic-gate	sethi	%hi(.check_v9utrap), %g4  ;\
9207c478bd9Sstevel@tonic-gate	jmp	%g4 + %lo(.check_v9utrap) ;\
9217c478bd9Sstevel@tonic-gate	nop				  ;\
9227c478bd9Sstevel@tonic-gate	.align	32
9237c478bd9Sstevel@tonic-gate#define	TRP4	TRAP_INSTR; TRAP_INSTR; TRAP_INSTR; TRAP_INSTR
9247c478bd9Sstevel@tonic-gate
9257c478bd9Sstevel@tonic-gate/*
9267c478bd9Sstevel@tonic-gate * LEVEL_INTERRUPT is for level N interrupts.
9277c478bd9Sstevel@tonic-gate * VECTOR_INTERRUPT is for the vector trap.
9287c478bd9Sstevel@tonic-gate */
9297c478bd9Sstevel@tonic-gate#define	LEVEL_INTERRUPT(level)		\
9307c478bd9Sstevel@tonic-gate	.global	tt_pil/**/level		;\
9317c478bd9Sstevel@tonic-gatett_pil/**/level:			;\
9327c478bd9Sstevel@tonic-gate	ba,pt	%xcc, pil_interrupt	;\
9337c478bd9Sstevel@tonic-gate	mov	level, %g4		;\
9347c478bd9Sstevel@tonic-gate	.align	32
9357c478bd9Sstevel@tonic-gate
9367c478bd9Sstevel@tonic-gate#define	LEVEL14_INTERRUPT			\
9377c478bd9Sstevel@tonic-gate	ba	pil14_interrupt			;\
9387c478bd9Sstevel@tonic-gate	mov	PIL_14, %g4			;\
9397c478bd9Sstevel@tonic-gate	.align	32
9407c478bd9Sstevel@tonic-gate
941b9e93c10SJonathan Haslam#define        LEVEL15_INTERRUPT                       \
942b9e93c10SJonathan Haslam       ba      pil15_interrupt                 ;\
943b9e93c10SJonathan Haslam       mov     PIL_15, %g4                     ;\
944b9e93c10SJonathan Haslam       .align  32
945b9e93c10SJonathan Haslam
9467c478bd9Sstevel@tonic-gate#define	VECTOR_INTERRUPT				\
9477c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_INTR_RECEIVE_STATUS, %g1	;\
9487c478bd9Sstevel@tonic-gate	btst	IRSR_BUSY, %g1				;\
9497c478bd9Sstevel@tonic-gate	bnz,pt	%xcc, vec_interrupt			;\
9507c478bd9Sstevel@tonic-gate	nop						;\
9517c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, vec_intr_spurious			;\
9527c478bd9Sstevel@tonic-gate	.empty						;\
9537c478bd9Sstevel@tonic-gate	.align	32
9547c478bd9Sstevel@tonic-gate
9557c478bd9Sstevel@tonic-gate/*
9567c478bd9Sstevel@tonic-gate * MMU Trap Handlers.
9577c478bd9Sstevel@tonic-gate */
9587c478bd9Sstevel@tonic-gate#define	SWITCH_GLOBALS	/* mmu->alt, alt->mmu */			\
9597c478bd9Sstevel@tonic-gate	rdpr	%pstate, %g5						;\
9607c478bd9Sstevel@tonic-gate	wrpr	%g5, PSTATE_MG | PSTATE_AG, %pstate
9617c478bd9Sstevel@tonic-gate
9627c478bd9Sstevel@tonic-gate#define	IMMU_EXCEPTION							\
9637c478bd9Sstevel@tonic-gate	membar	#Sync							;\
9647c478bd9Sstevel@tonic-gate	SWITCH_GLOBALS							;\
9657c478bd9Sstevel@tonic-gate	wr	%g0, ASI_IMMU, %asi					;\
9667c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g2						;\
9677c478bd9Sstevel@tonic-gate	ldxa	[MMU_SFSR]%asi, %g3					;\
9687c478bd9Sstevel@tonic-gate	ba,pt	%xcc, .mmu_exception_end				;\
9697c478bd9Sstevel@tonic-gate	mov	T_INSTR_EXCEPTION, %g1					;\
9707c478bd9Sstevel@tonic-gate	.align	32
9717c478bd9Sstevel@tonic-gate
9727c478bd9Sstevel@tonic-gate#define	DMMU_EXCEPTION							\
9737c478bd9Sstevel@tonic-gate	SWITCH_GLOBALS							;\
9747c478bd9Sstevel@tonic-gate	wr	%g0, ASI_DMMU, %asi					;\
9757c478bd9Sstevel@tonic-gate	ldxa	[MMU_TAG_ACCESS]%asi, %g2				;\
9767c478bd9Sstevel@tonic-gate	ldxa	[MMU_SFSR]%asi, %g3					;\
9777c478bd9Sstevel@tonic-gate	ba,pt	%xcc, .mmu_exception_end				;\
9787c478bd9Sstevel@tonic-gate	mov	T_DATA_EXCEPTION, %g1					;\
9797c478bd9Sstevel@tonic-gate	.align	32
9807c478bd9Sstevel@tonic-gate
9817c478bd9Sstevel@tonic-gate#define	DMMU_EXC_AG_PRIV						\
9827c478bd9Sstevel@tonic-gate	wr	%g0, ASI_DMMU, %asi					;\
9837c478bd9Sstevel@tonic-gate	ldxa	[MMU_SFAR]%asi, %g2					;\
9847c478bd9Sstevel@tonic-gate	ba,pt	%xcc, .mmu_priv_exception				;\
9857c478bd9Sstevel@tonic-gate	ldxa	[MMU_SFSR]%asi, %g3					;\
9867c478bd9Sstevel@tonic-gate	.align	32
9877c478bd9Sstevel@tonic-gate
9887c478bd9Sstevel@tonic-gate#define	DMMU_EXC_AG_NOT_ALIGNED						\
9897c478bd9Sstevel@tonic-gate	wr	%g0, ASI_DMMU, %asi					;\
9907c478bd9Sstevel@tonic-gate	ldxa	[MMU_SFAR]%asi, %g2					;\
9917c478bd9Sstevel@tonic-gate	ba,pt	%xcc, .mmu_exception_not_aligned			;\
9927c478bd9Sstevel@tonic-gate	ldxa	[MMU_SFSR]%asi, %g3					;\
9937c478bd9Sstevel@tonic-gate	.align	32
9947c478bd9Sstevel@tonic-gate
9957c478bd9Sstevel@tonic-gate/*
9967c478bd9Sstevel@tonic-gate * SPARC V9 IMPL. DEP. #109(1) and (2) and #110(1) and (2)
9977c478bd9Sstevel@tonic-gate */
9987c478bd9Sstevel@tonic-gate#define	DMMU_EXC_LDDF_NOT_ALIGNED					\
9997c478bd9Sstevel@tonic-gate	btst	1, %sp							;\
10007c478bd9Sstevel@tonic-gate	bnz,pt	%xcc, .lddf_exception_not_aligned			;\
10017c478bd9Sstevel@tonic-gate	wr	%g0, ASI_DMMU, %asi					;\
10027c478bd9Sstevel@tonic-gate	ldxa	[MMU_SFAR]%asi, %g2					;\
10037c478bd9Sstevel@tonic-gate	ba,pt	%xcc, .mmu_exception_not_aligned			;\
10047c478bd9Sstevel@tonic-gate	ldxa	[MMU_SFSR]%asi, %g3					;\
10057c478bd9Sstevel@tonic-gate	.align	32
10067c478bd9Sstevel@tonic-gate
10077c478bd9Sstevel@tonic-gate#define	DMMU_EXC_STDF_NOT_ALIGNED					\
10087c478bd9Sstevel@tonic-gate	btst	1, %sp							;\
10097c478bd9Sstevel@tonic-gate	bnz,pt	%xcc, .stdf_exception_not_aligned			;\
10107c478bd9Sstevel@tonic-gate	wr	%g0, ASI_DMMU, %asi					;\
10117c478bd9Sstevel@tonic-gate	ldxa	[MMU_SFAR]%asi, %g2					;\
10127c478bd9Sstevel@tonic-gate	ba,pt	%xcc, .mmu_exception_not_aligned			;\
10137c478bd9Sstevel@tonic-gate	ldxa	[MMU_SFSR]%asi, %g3					;\
10147c478bd9Sstevel@tonic-gate	.align	32
10157c478bd9Sstevel@tonic-gate
10167c478bd9Sstevel@tonic-gate/*
10177c478bd9Sstevel@tonic-gate * Flush the TLB using either the primary, secondary, or nucleus flush
10187c478bd9Sstevel@tonic-gate * operation based on whether the ctx from the tag access register matches
10197c478bd9Sstevel@tonic-gate * the primary or secondary context (flush the nucleus if neither matches).
10207c478bd9Sstevel@tonic-gate *
10217c478bd9Sstevel@tonic-gate * Requires a membar #Sync before next ld/st.
10227c478bd9Sstevel@tonic-gate * exits with:
10237c478bd9Sstevel@tonic-gate * g2 = tag access register
10247c478bd9Sstevel@tonic-gate * g3 = ctx number
10257c478bd9Sstevel@tonic-gate */
10267c478bd9Sstevel@tonic-gate#if TAGACC_CTX_MASK != CTXREG_CTX_MASK
10277c478bd9Sstevel@tonic-gate#error "TAGACC_CTX_MASK != CTXREG_CTX_MASK"
10287c478bd9Sstevel@tonic-gate#endif
10297c478bd9Sstevel@tonic-gate#define	DTLB_DEMAP_ENTRY						\
10307c478bd9Sstevel@tonic-gate	mov	MMU_TAG_ACCESS, %g1					;\
10317c478bd9Sstevel@tonic-gate	mov	MMU_PCONTEXT, %g5					;\
10327c478bd9Sstevel@tonic-gate	ldxa	[%g1]ASI_DMMU, %g2					;\
10337c478bd9Sstevel@tonic-gate	sethi	%hi(TAGACC_CTX_MASK), %g4				;\
10347c478bd9Sstevel@tonic-gate	or	%g4, %lo(TAGACC_CTX_MASK), %g4				;\
10357c478bd9Sstevel@tonic-gate	and	%g2, %g4, %g3			/* g3 = ctx */		;\
10367c478bd9Sstevel@tonic-gate	ldxa	[%g5]ASI_DMMU, %g6		/* g6 = primary ctx */	;\
10377c478bd9Sstevel@tonic-gate	and	%g6, %g4, %g6			/* &= CTXREG_CTX_MASK */ ;\
10387c478bd9Sstevel@tonic-gate	cmp	%g3, %g6						;\
10397c478bd9Sstevel@tonic-gate	be,pt	%xcc, 1f						;\
10407c478bd9Sstevel@tonic-gate	andn	%g2, %g4, %g1			/* ctx = primary */	;\
10417c478bd9Sstevel@tonic-gate	mov	MMU_SCONTEXT, %g5					;\
10427c478bd9Sstevel@tonic-gate	ldxa	[%g5]ASI_DMMU, %g6		/* g6 = secondary ctx */ ;\
10437c478bd9Sstevel@tonic-gate	and	%g6, %g4, %g6			/* &= CTXREG_CTX_MASK */ ;\
10447c478bd9Sstevel@tonic-gate	cmp	%g3, %g6						;\
10457c478bd9Sstevel@tonic-gate	be,a,pt	%xcc, 1f						;\
10467c478bd9Sstevel@tonic-gate	  or	%g1, DEMAP_SECOND, %g1					;\
10477c478bd9Sstevel@tonic-gate	or	%g1, DEMAP_NUCLEUS, %g1					;\
10487c478bd9Sstevel@tonic-gate1:	stxa	%g0, [%g1]ASI_DTLB_DEMAP	/* MMU_DEMAP_PAGE */	;\
10497c478bd9Sstevel@tonic-gate	membar	#Sync
10507c478bd9Sstevel@tonic-gate
10517c478bd9Sstevel@tonic-gate#if defined(cscope)
10527c478bd9Sstevel@tonic-gate/*
10537c478bd9Sstevel@tonic-gate * Define labels to direct cscope quickly to labels that
10547c478bd9Sstevel@tonic-gate * are generated by macro expansion of DTLB_MISS().
10557c478bd9Sstevel@tonic-gate */
10567c478bd9Sstevel@tonic-gate	.global	tt0_dtlbmiss
10577c478bd9Sstevel@tonic-gatett0_dtlbmiss:
10587c478bd9Sstevel@tonic-gate	.global	tt1_dtlbmiss
10597c478bd9Sstevel@tonic-gatett1_dtlbmiss:
10607c478bd9Sstevel@tonic-gate	nop
10617c478bd9Sstevel@tonic-gate#endif
10627c478bd9Sstevel@tonic-gate
10637c478bd9Sstevel@tonic-gate/*
10647c478bd9Sstevel@tonic-gate * Needs to be exactly 32 instructions
10657c478bd9Sstevel@tonic-gate *
10667c478bd9Sstevel@tonic-gate * UTLB NOTE: If we don't hit on the 8k pointer then we branch
10677c478bd9Sstevel@tonic-gate * to a special 4M tsb handler. It would be nice if that handler
10687c478bd9Sstevel@tonic-gate * could live in this file but currently it seems better to allow
10697c478bd9Sstevel@tonic-gate * it to fall thru to sfmmu_tsb_miss.
10707c478bd9Sstevel@tonic-gate */
107125cf1a30Sjl139090#ifdef UTSB_PHYS
107225cf1a30Sjl139090#define	DTLB_MISS(table_name)						;\
107325cf1a30Sjl139090	.global	table_name/**/_dtlbmiss					;\
107425cf1a30Sjl139090table_name/**/_dtlbmiss:						;\
107525cf1a30Sjl139090	mov	MMU_TAG_ACCESS, %g6		/* select tag acc */	;\
107625cf1a30Sjl139090	ldxa	[%g0]ASI_DMMU_TSB_8K, %g1	/* g1 = tsbe ptr */	;\
107725cf1a30Sjl139090	ldxa	[%g6]ASI_DMMU, %g2		/* g2 = tag access */	;\
107825cf1a30Sjl139090	sllx	%g2, TAGACC_CTX_LSHIFT, %g3				;\
107925cf1a30Sjl139090	srlx	%g3, TAGACC_CTX_LSHIFT, %g3	/* g3 = ctx */		;\
108025cf1a30Sjl139090	cmp	%g3, INVALID_CONTEXT					;\
108125cf1a30Sjl139090	ble,pn	%xcc, sfmmu_kdtlb_miss					;\
10821426d65aSsm142603	  srax	%g2, PREDISM_BASESHIFT, %g6  /* g6 > 0 ISM predicted */ ;\
10831426d65aSsm142603	brgz,pn %g6, sfmmu_udtlb_slowpath_ismpred			;\
108425cf1a30Sjl139090	  srlx	%g2, TAG_VALO_SHIFT, %g7	/* g7 = tsb tag */	;\
108525cf1a30Sjl139090	ldda	[%g1]ASI_QUAD_LDD_PHYS, %g4	/* g4 = tag, %g5 data */;\
108625cf1a30Sjl139090	cmp	%g4, %g7						;\
10871426d65aSsm142603	bne,pn %xcc, sfmmu_udtlb_slowpath_noismpred			;\
10881426d65aSsm142603	  nop								;\
108925cf1a30Sjl139090	TT_TRACE(trace_tsbhit)		/* 2 instr ifdef TRAPTRACE */	;\
109025cf1a30Sjl139090	stxa	%g5, [%g0]ASI_DTLB_IN	/* trapstat expects TTE */	;\
109125cf1a30Sjl139090	retry				/* in %g5 */			;\
109225cf1a30Sjl139090	unimp	0							;\
109325cf1a30Sjl139090	unimp	0							;\
109425cf1a30Sjl139090	unimp	0							;\
109525cf1a30Sjl139090	unimp	0							;\
109625cf1a30Sjl139090	unimp	0							;\
109725cf1a30Sjl139090	unimp	0							;\
109825cf1a30Sjl139090	unimp	0							;\
109925cf1a30Sjl139090	unimp	0							;\
110025cf1a30Sjl139090	unimp	0							;\
110105d3dc4bSpaulsan	unimp	0							;\
110205d3dc4bSpaulsan	unimp	0							;\
110305d3dc4bSpaulsan	unimp	0							;\
11041426d65aSsm142603	unimp	0							;\
11051426d65aSsm142603	unimp	0							;\
110625cf1a30Sjl139090	.align 128
11071426d65aSsm142603
110825cf1a30Sjl139090#else /* UTSB_PHYS */
11097c478bd9Sstevel@tonic-gate#define	DTLB_MISS(table_name)						;\
11107c478bd9Sstevel@tonic-gate	.global	table_name/**/_dtlbmiss					;\
11117c478bd9Sstevel@tonic-gatetable_name/**/_dtlbmiss:						;\
11127c478bd9Sstevel@tonic-gate	mov	MMU_TAG_ACCESS, %g6		/* select tag acc */	;\
11137c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_DMMU_TSB_8K, %g1	/* g1 = tsbe ptr */	;\
11147c478bd9Sstevel@tonic-gate	ldxa	[%g6]ASI_DMMU, %g2		/* g2 = tag access */	;\
11157c478bd9Sstevel@tonic-gate	sllx	%g2, TAGACC_CTX_LSHIFT, %g3				;\
11167c478bd9Sstevel@tonic-gate	srlx	%g3, TAGACC_CTX_LSHIFT, %g3	/* g3 = ctx */		;\
11177c478bd9Sstevel@tonic-gate	cmp	%g3, INVALID_CONTEXT					;\
11187c478bd9Sstevel@tonic-gate	ble,pn	%xcc, sfmmu_kdtlb_miss					;\
11197c478bd9Sstevel@tonic-gate	  srlx	%g2, TAG_VALO_SHIFT, %g7	/* g7 = tsb tag */	;\
11207c478bd9Sstevel@tonic-gate	brlz,pn %g1, sfmmu_udtlb_slowpath				;\
11217c478bd9Sstevel@tonic-gate	  nop								;\
11227c478bd9Sstevel@tonic-gate	ldda	[%g1]ASI_NQUAD_LD, %g4	/* g4 = tag, %g5 data */	;\
11237c478bd9Sstevel@tonic-gate	cmp	%g4, %g7						;\
11247c478bd9Sstevel@tonic-gate	bne,pn	%xcc, sfmmu_tsb_miss_tt		/* no 4M TSB, miss */	;\
112505d3dc4bSpaulsan	  mov	-1, %g3		/* set 4M tsbe ptr to -1 */		;\
11267c478bd9Sstevel@tonic-gate	TT_TRACE(trace_tsbhit)		/* 2 instr ifdef TRAPTRACE */	;\
11277c478bd9Sstevel@tonic-gate	stxa	%g5, [%g0]ASI_DTLB_IN	/* trapstat expects TTE */	;\
11287c478bd9Sstevel@tonic-gate	retry				/* in %g5 */			;\
11297c478bd9Sstevel@tonic-gate	unimp	0							;\
11307c478bd9Sstevel@tonic-gate	unimp	0							;\
11317c478bd9Sstevel@tonic-gate	unimp	0							;\
11327c478bd9Sstevel@tonic-gate	unimp	0							;\
11337c478bd9Sstevel@tonic-gate	unimp	0							;\
11347c478bd9Sstevel@tonic-gate        unimp   0                                                       ;\
11357c478bd9Sstevel@tonic-gate        unimp   0                                                       ;\
11367c478bd9Sstevel@tonic-gate        unimp   0                                                       ;\
11377c478bd9Sstevel@tonic-gate        unimp   0                                                       ;\
11387c478bd9Sstevel@tonic-gate        unimp   0                                                       ;\
11397c478bd9Sstevel@tonic-gate        unimp   0                                                       ;\
114005d3dc4bSpaulsan        unimp   0                                                       ;\
114105d3dc4bSpaulsan        unimp   0                                                       ;\
114205d3dc4bSpaulsan        unimp   0                                                       ;\
11437c478bd9Sstevel@tonic-gate	.align 128
114425cf1a30Sjl139090#endif /* UTSB_PHYS */
11457c478bd9Sstevel@tonic-gate
11467c478bd9Sstevel@tonic-gate#if defined(cscope)
11477c478bd9Sstevel@tonic-gate/*
11487c478bd9Sstevel@tonic-gate * Define labels to direct cscope quickly to labels that
11497c478bd9Sstevel@tonic-gate * are generated by macro expansion of ITLB_MISS().
11507c478bd9Sstevel@tonic-gate */
11517c478bd9Sstevel@tonic-gate	.global	tt0_itlbmiss
11527c478bd9Sstevel@tonic-gatett0_itlbmiss:
11537c478bd9Sstevel@tonic-gate	.global	tt1_itlbmiss
11547c478bd9Sstevel@tonic-gatett1_itlbmiss:
11557c478bd9Sstevel@tonic-gate	nop
11567c478bd9Sstevel@tonic-gate#endif
11577c478bd9Sstevel@tonic-gate
11587c478bd9Sstevel@tonic-gate/*
11597c478bd9Sstevel@tonic-gate * Instruction miss handler.
11607c478bd9Sstevel@tonic-gate * ldda instructions will have their ASI patched
11617c478bd9Sstevel@tonic-gate * by sfmmu_patch_ktsb at runtime.
11627c478bd9Sstevel@tonic-gate * MUST be EXACTLY 32 instructions or we'll break.
11637c478bd9Sstevel@tonic-gate */
116425cf1a30Sjl139090#ifdef UTSB_PHYS
116525cf1a30Sjl139090#define ITLB_MISS(table_name)                                            \
116625cf1a30Sjl139090        .global table_name/**/_itlbmiss                                 ;\
116725cf1a30Sjl139090table_name/**/_itlbmiss:                                                ;\
116825cf1a30Sjl139090        mov     MMU_TAG_ACCESS, %g6             /* select tag acc */    ;\
116925cf1a30Sjl139090        ldxa    [%g0]ASI_IMMU_TSB_8K, %g1       /* g1 = tsbe ptr */     ;\
117025cf1a30Sjl139090        ldxa    [%g6]ASI_IMMU, %g2              /* g2 = tag access */   ;\
117125cf1a30Sjl139090        sllx    %g2, TAGACC_CTX_LSHIFT, %g3                             ;\
117225cf1a30Sjl139090        srlx    %g3, TAGACC_CTX_LSHIFT, %g3     /* g3 = ctx */          ;\
117325cf1a30Sjl139090        cmp     %g3, INVALID_CONTEXT                                    ;\
117425cf1a30Sjl139090        ble,pn  %xcc, sfmmu_kitlb_miss                                  ;\
117525cf1a30Sjl139090          srlx  %g2, TAG_VALO_SHIFT, %g7        /* g7 = tsb tag */      ;\
117625cf1a30Sjl139090        ldda    [%g1]ASI_QUAD_LDD_PHYS, %g4 /* g4 = tag, g5 = data */   ;\
117725cf1a30Sjl139090        cmp     %g4, %g7                                                ;\
11781426d65aSsm142603        bne,pn  %xcc, sfmmu_uitlb_slowpath                              ;\
117925cf1a30Sjl139090          andcc %g5, TTE_EXECPRM_INT, %g0 /* check execute bit */       ;\
118025cf1a30Sjl139090        bz,pn   %icc, exec_fault                                        ;\
118125cf1a30Sjl139090          nop                                                           ;\
118225cf1a30Sjl139090        TT_TRACE(trace_tsbhit)          /* 2 instr ifdef TRAPTRACE */   ;\
118325cf1a30Sjl139090        stxa    %g5, [%g0]ASI_ITLB_IN   /* trapstat expects %g5 */      ;\
118425cf1a30Sjl139090        retry                                                           ;\
118525cf1a30Sjl139090        unimp   0                                                       ;\
118625cf1a30Sjl139090        unimp   0                                                       ;\
118725cf1a30Sjl139090        unimp   0                                                       ;\
118825cf1a30Sjl139090        unimp   0                                                       ;\
118925cf1a30Sjl139090        unimp   0                                                       ;\
119025cf1a30Sjl139090        unimp   0                                                       ;\
119105d3dc4bSpaulsan        unimp   0                                                       ;\
119205d3dc4bSpaulsan        unimp   0                                                       ;\
119305d3dc4bSpaulsan        unimp   0                                                       ;\
11941426d65aSsm142603        unimp   0                                                       ;\
11951426d65aSsm142603        unimp   0                                                       ;\
11961426d65aSsm142603        unimp   0                                                       ;\
11971426d65aSsm142603        unimp   0                                                       ;\
11981426d65aSsm142603        unimp   0                                                       ;\
119925cf1a30Sjl139090        .align 128
12001426d65aSsm142603
120125cf1a30Sjl139090#else /* UTSB_PHYS */
12027c478bd9Sstevel@tonic-gate#define	ITLB_MISS(table_name)						 \
12037c478bd9Sstevel@tonic-gate	.global	table_name/**/_itlbmiss					;\
12047c478bd9Sstevel@tonic-gatetable_name/**/_itlbmiss:						;\
12057c478bd9Sstevel@tonic-gate	mov	MMU_TAG_ACCESS, %g6		/* select tag acc */	;\
12067c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_IMMU_TSB_8K, %g1	/* g1 = tsbe ptr */	;\
12077c478bd9Sstevel@tonic-gate	ldxa	[%g6]ASI_IMMU, %g2		/* g2 = tag access */	;\
12087c478bd9Sstevel@tonic-gate	sllx	%g2, TAGACC_CTX_LSHIFT, %g3				;\
12097c478bd9Sstevel@tonic-gate	srlx	%g3, TAGACC_CTX_LSHIFT, %g3	/* g3 = ctx */		;\
12107c478bd9Sstevel@tonic-gate	cmp	%g3, INVALID_CONTEXT					;\
12117c478bd9Sstevel@tonic-gate	ble,pn	%xcc, sfmmu_kitlb_miss					;\
12127c478bd9Sstevel@tonic-gate	  srlx	%g2, TAG_VALO_SHIFT, %g7	/* g7 = tsb tag */	;\
12137c478bd9Sstevel@tonic-gate	brlz,pn	%g1, sfmmu_uitlb_slowpath	/* if >1 TSB branch */	;\
12147c478bd9Sstevel@tonic-gate	  nop								;\
12157c478bd9Sstevel@tonic-gate	ldda	[%g1]ASI_NQUAD_LD, %g4	/* g4 = tag, g5 = data */	;\
12167c478bd9Sstevel@tonic-gate	cmp	%g4, %g7						;\
12177c478bd9Sstevel@tonic-gate	bne,pn	%xcc, sfmmu_tsb_miss_tt	/* br if 8k ptr miss */		;\
121805d3dc4bSpaulsan	  mov	-1, %g3		/* set 4M TSB ptr to -1 */		;\
12197c478bd9Sstevel@tonic-gate	andcc	%g5, TTE_EXECPRM_INT, %g0 /* check execute bit */	;\
12207c478bd9Sstevel@tonic-gate	bz,pn	%icc, exec_fault					;\
12217c478bd9Sstevel@tonic-gate	  nop								;\
12227c478bd9Sstevel@tonic-gate	TT_TRACE(trace_tsbhit)		/* 2 instr ifdef TRAPTRACE */	;\
12237c478bd9Sstevel@tonic-gate	stxa	%g5, [%g0]ASI_ITLB_IN	/* trapstat expects %g5 */	;\
12247c478bd9Sstevel@tonic-gate	retry								;\
12257c478bd9Sstevel@tonic-gate	unimp	0							;\
12267c478bd9Sstevel@tonic-gate	unimp	0							;\
12277c478bd9Sstevel@tonic-gate	unimp	0							;\
12287c478bd9Sstevel@tonic-gate	unimp	0							;\
12297c478bd9Sstevel@tonic-gate	unimp	0							;\
12307c478bd9Sstevel@tonic-gate        unimp   0                                                       ;\
12317c478bd9Sstevel@tonic-gate        unimp   0                                                       ;\
12327c478bd9Sstevel@tonic-gate        unimp   0                                                       ;\
123305d3dc4bSpaulsan        unimp   0                                                       ;\
123405d3dc4bSpaulsan        unimp   0                                                       ;\
123505d3dc4bSpaulsan        unimp   0                                                       ;\
12367c478bd9Sstevel@tonic-gate	.align 128
123725cf1a30Sjl139090#endif /* UTSB_PHYS */
12387c478bd9Sstevel@tonic-gate
12397c478bd9Sstevel@tonic-gate
12407c478bd9Sstevel@tonic-gate/*
12417c478bd9Sstevel@tonic-gate * This macro is the first level handler for fast protection faults.
12427c478bd9Sstevel@tonic-gate * It first demaps the tlb entry which generated the fault and then
12437c478bd9Sstevel@tonic-gate * attempts to set the modify bit on the hash.  It needs to be
12447c478bd9Sstevel@tonic-gate * exactly 32 instructions.
12457c478bd9Sstevel@tonic-gate */
12467c478bd9Sstevel@tonic-gate#define	DTLB_PROT							 \
12477c478bd9Sstevel@tonic-gate	DTLB_DEMAP_ENTRY		/* 20 instructions */		;\
12487c478bd9Sstevel@tonic-gate	/*								;\
12497c478bd9Sstevel@tonic-gate	 * At this point:						;\
12507c478bd9Sstevel@tonic-gate	 *   g1 = ????							;\
12517c478bd9Sstevel@tonic-gate	 *   g2 = tag access register					;\
12527c478bd9Sstevel@tonic-gate	 *   g3 = ctx number						;\
12537c478bd9Sstevel@tonic-gate	 *   g4 = ????							;\
12547c478bd9Sstevel@tonic-gate	 */								;\
12557c478bd9Sstevel@tonic-gate	TT_TRACE(trace_dataprot)	/* 2 instr ifdef TRAPTRACE */	;\
12567c478bd9Sstevel@tonic-gate					/* clobbers g1 and g6 */	;\
12577c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_DMMU_TSB_8K, %g1	/* g1 = tsbe ptr */	;\
12587c478bd9Sstevel@tonic-gate	brnz,pt %g3, sfmmu_uprot_trap		/* user trap */		;\
12597c478bd9Sstevel@tonic-gate	  nop								;\
12607c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, sfmmu_kprot_trap		/* kernel trap */	;\
12617c478bd9Sstevel@tonic-gate	unimp	0							;\
12627c478bd9Sstevel@tonic-gate	unimp	0							;\
12637c478bd9Sstevel@tonic-gate	unimp	0							;\
12647c478bd9Sstevel@tonic-gate	unimp	0							;\
12657c478bd9Sstevel@tonic-gate	unimp	0							;\
12667c478bd9Sstevel@tonic-gate	unimp	0							;\
12677c478bd9Sstevel@tonic-gate	.align 128
12687c478bd9Sstevel@tonic-gate
12697c478bd9Sstevel@tonic-gate#define	DMMU_EXCEPTION_TL1						;\
12707c478bd9Sstevel@tonic-gate	SWITCH_GLOBALS							;\
12717c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, mmu_trap_tl1					;\
12727c478bd9Sstevel@tonic-gate	  nop								;\
12737c478bd9Sstevel@tonic-gate	.align 32
12747c478bd9Sstevel@tonic-gate
12757c478bd9Sstevel@tonic-gate#define	MISALIGN_ADDR_TL1						;\
12767c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, mmu_trap_tl1					;\
12777c478bd9Sstevel@tonic-gate	  nop								;\
12787c478bd9Sstevel@tonic-gate	.align 32
12797c478bd9Sstevel@tonic-gate
12807c478bd9Sstevel@tonic-gate/*
12817c478bd9Sstevel@tonic-gate * Trace a tsb hit
12827c478bd9Sstevel@tonic-gate * g1 = tsbe pointer (in/clobbered)
12837c478bd9Sstevel@tonic-gate * g2 = tag access register (in)
12847c478bd9Sstevel@tonic-gate * g3 - g4 = scratch (clobbered)
12857c478bd9Sstevel@tonic-gate * g5 = tsbe data (in)
12867c478bd9Sstevel@tonic-gate * g6 = scratch (clobbered)
12877c478bd9Sstevel@tonic-gate * g7 = pc we jumped here from (in)
12887c478bd9Sstevel@tonic-gate * ttextra = value to OR in to trap type (%tt) (in)
12897c478bd9Sstevel@tonic-gate */
12907c478bd9Sstevel@tonic-gate#ifdef TRAPTRACE
12917c478bd9Sstevel@tonic-gate#define TRACE_TSBHIT(ttextra)						 \
12927c478bd9Sstevel@tonic-gate	membar	#Sync							;\
12937c478bd9Sstevel@tonic-gate	sethi	%hi(FLUSH_ADDR), %g6					;\
12947c478bd9Sstevel@tonic-gate	flush	%g6							;\
12957c478bd9Sstevel@tonic-gate	TRACE_PTR(%g3, %g6)						;\
1296*023e71deSHaik Aftandilian	GET_TRACE_TICK(%g6, %g4)					;\
12977c478bd9Sstevel@tonic-gate	stxa	%g6, [%g3 + TRAP_ENT_TICK]%asi				;\
12987c478bd9Sstevel@tonic-gate	stxa	%g2, [%g3 + TRAP_ENT_SP]%asi	/* tag access */	;\
12997c478bd9Sstevel@tonic-gate	stxa	%g5, [%g3 + TRAP_ENT_F1]%asi	/* tsb data */		;\
13007c478bd9Sstevel@tonic-gate	rdpr	%tnpc, %g6						;\
13017c478bd9Sstevel@tonic-gate	stxa	%g6, [%g3 + TRAP_ENT_F2]%asi				;\
13027c478bd9Sstevel@tonic-gate	stxa	%g1, [%g3 + TRAP_ENT_F3]%asi	/* tsb pointer */	;\
13037c478bd9Sstevel@tonic-gate	stxa	%g0, [%g3 + TRAP_ENT_F4]%asi				;\
13047c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g6						;\
13057c478bd9Sstevel@tonic-gate	stxa	%g6, [%g3 + TRAP_ENT_TPC]%asi				;\
13067c478bd9Sstevel@tonic-gate	rdpr	%tl, %g6						;\
13077c478bd9Sstevel@tonic-gate	stha	%g6, [%g3 + TRAP_ENT_TL]%asi				;\
13087c478bd9Sstevel@tonic-gate	rdpr	%tt, %g6						;\
13097c478bd9Sstevel@tonic-gate	or	%g6, (ttextra), %g6					;\
13107c478bd9Sstevel@tonic-gate	stha	%g6, [%g3 + TRAP_ENT_TT]%asi				;\
13117c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_IMMU, %g1		/* tag target */	;\
13127c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_DMMU, %g4					;\
13137c478bd9Sstevel@tonic-gate	cmp	%g6, FAST_IMMU_MISS_TT					;\
13147c478bd9Sstevel@tonic-gate	movne	%icc, %g4, %g1						;\
13157c478bd9Sstevel@tonic-gate	stxa	%g1, [%g3 + TRAP_ENT_TSTATE]%asi /* tsb tag */		;\
13167c478bd9Sstevel@tonic-gate	stxa	%g0, [%g3 + TRAP_ENT_TR]%asi				;\
13177c478bd9Sstevel@tonic-gate	TRACE_NEXT(%g3, %g4, %g6)
13187c478bd9Sstevel@tonic-gate#else
13197c478bd9Sstevel@tonic-gate#define TRACE_TSBHIT(ttextra)
13207c478bd9Sstevel@tonic-gate#endif
13217c478bd9Sstevel@tonic-gate
13227c478bd9Sstevel@tonic-gate#if defined(lint)
13237c478bd9Sstevel@tonic-gate
13247c478bd9Sstevel@tonic-gatestruct scb	trap_table;
13257c478bd9Sstevel@tonic-gatestruct scb	scb;		/* trap_table/scb are the same object */
13267c478bd9Sstevel@tonic-gate
13277c478bd9Sstevel@tonic-gate#else /* lint */
13287c478bd9Sstevel@tonic-gate
13297c478bd9Sstevel@tonic-gate/*
13307c478bd9Sstevel@tonic-gate * =======================================================================
13317c478bd9Sstevel@tonic-gate *		SPARC V9 TRAP TABLE
13327c478bd9Sstevel@tonic-gate *
13337c478bd9Sstevel@tonic-gate * The trap table is divided into two halves: the first half is used when
13347c478bd9Sstevel@tonic-gate * taking traps when TL=0; the second half is used when taking traps from
13357c478bd9Sstevel@tonic-gate * TL>0. Note that handlers in the second half of the table might not be able
13367c478bd9Sstevel@tonic-gate * to make the same assumptions as handlers in the first half of the table.
13377c478bd9Sstevel@tonic-gate *
13387c478bd9Sstevel@tonic-gate * Worst case trap nesting so far:
13397c478bd9Sstevel@tonic-gate *
13407c478bd9Sstevel@tonic-gate *	at TL=0 client issues software trap requesting service
13417c478bd9Sstevel@tonic-gate *	at TL=1 nucleus wants a register window
13427c478bd9Sstevel@tonic-gate *	at TL=2 register window clean/spill/fill takes a TLB miss
13437c478bd9Sstevel@tonic-gate *	at TL=3 processing TLB miss
13447c478bd9Sstevel@tonic-gate *	at TL=4 handle asynchronous error
13457c478bd9Sstevel@tonic-gate *
13467c478bd9Sstevel@tonic-gate * Note that a trap from TL=4 to TL=5 places Spitfire in "RED mode".
13477c478bd9Sstevel@tonic-gate *
13487c478bd9Sstevel@tonic-gate * =======================================================================
13497c478bd9Sstevel@tonic-gate */
13507c478bd9Sstevel@tonic-gate	.section ".text"
13517c478bd9Sstevel@tonic-gate	.align	4
13527c478bd9Sstevel@tonic-gate	.global trap_table, scb, trap_table0, trap_table1, etrap_table
135341f63f87Spetede	.type	trap_table, #object
135441f63f87Spetede	.type	scb, #object
13557c478bd9Sstevel@tonic-gatetrap_table:
13567c478bd9Sstevel@tonic-gatescb:
13577c478bd9Sstevel@tonic-gatetrap_table0:
13587c478bd9Sstevel@tonic-gate	/* hardware traps */
13597c478bd9Sstevel@tonic-gate	NOT;				/* 000	reserved */
13607c478bd9Sstevel@tonic-gate	RED;				/* 001	power on reset */
13617c478bd9Sstevel@tonic-gate	RED;				/* 002	watchdog reset */
13627c478bd9Sstevel@tonic-gate	RED;				/* 003	externally initiated reset */
13637c478bd9Sstevel@tonic-gate	RED;				/* 004	software initiated reset */
13647c478bd9Sstevel@tonic-gate	RED;				/* 005	red mode exception */
13657c478bd9Sstevel@tonic-gate	NOT; NOT;			/* 006 - 007 reserved */
13667c478bd9Sstevel@tonic-gate	IMMU_EXCEPTION;			/* 008	instruction access exception */
13677c478bd9Sstevel@tonic-gate	NOT;				/* 009	instruction access MMU miss */
136825cf1a30Sjl139090	ASYNC_TRAP(T_INSTR_ERROR, trace_gen, tt0_iae);
13697c478bd9Sstevel@tonic-gate					/* 00A	instruction access error */
13707c478bd9Sstevel@tonic-gate	NOT; NOT4;			/* 00B - 00F reserved */
13717c478bd9Sstevel@tonic-gate	ILLTRAP_INSTR;			/* 010	illegal instruction */
13727c478bd9Sstevel@tonic-gate	TRAP(T_PRIV_INSTR);		/* 011	privileged opcode */
13737c478bd9Sstevel@tonic-gate	NOT;				/* 012	unimplemented LDD */
13747c478bd9Sstevel@tonic-gate	NOT;				/* 013	unimplemented STD */
13757c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4;		/* 014 - 01F reserved */
13767c478bd9Sstevel@tonic-gate	FP_DISABLED_TRAP;		/* 020	fp disabled */
13777c478bd9Sstevel@tonic-gate	FP_IEEE_TRAP;			/* 021	fp exception ieee 754 */
13787c478bd9Sstevel@tonic-gate	FP_TRAP;			/* 022	fp exception other */
13797c478bd9Sstevel@tonic-gate	TAG_OVERFLOW;			/* 023	tag overflow */
13807c478bd9Sstevel@tonic-gate	CLEAN_WINDOW;			/* 024 - 027 clean window */
13817c478bd9Sstevel@tonic-gate	DIV_BY_ZERO;			/* 028	division by zero */
13827c478bd9Sstevel@tonic-gate	NOT;				/* 029	internal processor error */
13837c478bd9Sstevel@tonic-gate	NOT; NOT; NOT4;			/* 02A - 02F reserved */
13847c478bd9Sstevel@tonic-gate	DMMU_EXCEPTION;			/* 030	data access exception */
13857c478bd9Sstevel@tonic-gate	NOT;				/* 031	data access MMU miss */
138625cf1a30Sjl139090	ASYNC_TRAP(T_DATA_ERROR, trace_gen, tt0_dae);
13877c478bd9Sstevel@tonic-gate					/* 032	data access error */
13887c478bd9Sstevel@tonic-gate	NOT;				/* 033	data access protection */
13897c478bd9Sstevel@tonic-gate	DMMU_EXC_AG_NOT_ALIGNED;	/* 034	mem address not aligned */
13907c478bd9Sstevel@tonic-gate	DMMU_EXC_LDDF_NOT_ALIGNED;	/* 035	LDDF mem address not aligned */
13917c478bd9Sstevel@tonic-gate	DMMU_EXC_STDF_NOT_ALIGNED;	/* 036	STDF mem address not aligned */
13927c478bd9Sstevel@tonic-gate	DMMU_EXC_AG_PRIV;		/* 037	privileged action */
13937c478bd9Sstevel@tonic-gate	NOT;				/* 038	LDQF mem address not aligned */
13947c478bd9Sstevel@tonic-gate	NOT;				/* 039	STQF mem address not aligned */
13957c478bd9Sstevel@tonic-gate	NOT; NOT; NOT4;			/* 03A - 03F reserved */
139625cf1a30Sjl139090	LABELED_BAD(tt0_asdat);		/* 040	async data error */
13977c478bd9Sstevel@tonic-gate	LEVEL_INTERRUPT(1);		/* 041	interrupt level 1 */
13987c478bd9Sstevel@tonic-gate	LEVEL_INTERRUPT(2);		/* 042	interrupt level 2 */
13997c478bd9Sstevel@tonic-gate	LEVEL_INTERRUPT(3);		/* 043	interrupt level 3 */
14007c478bd9Sstevel@tonic-gate	LEVEL_INTERRUPT(4);		/* 044	interrupt level 4 */
14017c478bd9Sstevel@tonic-gate	LEVEL_INTERRUPT(5);		/* 045	interrupt level 5 */
14027c478bd9Sstevel@tonic-gate	LEVEL_INTERRUPT(6);		/* 046	interrupt level 6 */
14037c478bd9Sstevel@tonic-gate	LEVEL_INTERRUPT(7);		/* 047	interrupt level 7 */
14047c478bd9Sstevel@tonic-gate	LEVEL_INTERRUPT(8);		/* 048	interrupt level 8 */
14057c478bd9Sstevel@tonic-gate	LEVEL_INTERRUPT(9);		/* 049	interrupt level 9 */
14067c478bd9Sstevel@tonic-gate	LEVEL_INTERRUPT(10);		/* 04A	interrupt level 10 */
14077c478bd9Sstevel@tonic-gate	LEVEL_INTERRUPT(11);		/* 04B	interrupt level 11 */
14087c478bd9Sstevel@tonic-gate	LEVEL_INTERRUPT(12);		/* 04C	interrupt level 12 */
14097c478bd9Sstevel@tonic-gate	LEVEL_INTERRUPT(13);		/* 04D	interrupt level 13 */
14107c478bd9Sstevel@tonic-gate	LEVEL14_INTERRUPT;		/* 04E	interrupt level 14 */
1411b9e93c10SJonathan Haslam	LEVEL15_INTERRUPT;		/* 04F	interrupt level 15 */
14127c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4; NOT4;		/* 050 - 05F reserved */
14137c478bd9Sstevel@tonic-gate	VECTOR_INTERRUPT;		/* 060	interrupt vector */
14147c478bd9Sstevel@tonic-gate	GOTO(kmdb_trap);		/* 061	PA watchpoint */
14157c478bd9Sstevel@tonic-gate	GOTO(kmdb_trap);		/* 062	VA watchpoint */
14167c478bd9Sstevel@tonic-gate	GOTO_TT(ce_err, trace_gen);	/* 063	corrected ECC error */
14177c478bd9Sstevel@tonic-gate	ITLB_MISS(tt0);			/* 064	instruction access MMU miss */
14187c478bd9Sstevel@tonic-gate	DTLB_MISS(tt0);			/* 068	data access MMU miss */
14197c478bd9Sstevel@tonic-gate	DTLB_PROT;			/* 06C	data access protection */
14207c478bd9Sstevel@tonic-gate	LABELED_BAD(tt0_fecc);		/* 070  fast ecache ECC error */
14217c478bd9Sstevel@tonic-gate	LABELED_BAD(tt0_dperr);		/* 071  Cheetah+ dcache parity error */
14227c478bd9Sstevel@tonic-gate	LABELED_BAD(tt0_iperr);		/* 072  Cheetah+ icache parity error */
14237c478bd9Sstevel@tonic-gate	NOT;				/* 073  reserved */
14247c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4;		/* 074 - 07F reserved */
14257c478bd9Sstevel@tonic-gate	NOT4;				/* 080	spill 0 normal */
14267c478bd9Sstevel@tonic-gate	SPILL_32bit_asi(ASI_AIUP,sn0);	/* 084	spill 1 normal */
14277c478bd9Sstevel@tonic-gate	SPILL_64bit_asi(ASI_AIUP,sn0);	/* 088	spill 2 normal */
14287c478bd9Sstevel@tonic-gate	SPILL_32clean(ASI_AIUP,sn0);	/* 08C	spill 3 normal */
14297c478bd9Sstevel@tonic-gate	SPILL_64clean(ASI_AIUP,sn0);	/* 090	spill 4 normal */
14307c478bd9Sstevel@tonic-gate	SPILL_32bit(not);		/* 094	spill 5 normal */
14317c478bd9Sstevel@tonic-gate	SPILL_64bit(not);		/* 098	spill 6 normal */
14327c478bd9Sstevel@tonic-gate	SPILL_mixed;			/* 09C	spill 7 normal */
14337c478bd9Sstevel@tonic-gate	NOT4;				/* 0A0	spill 0 other */
14347c478bd9Sstevel@tonic-gate	SPILL_32bit_asi(ASI_AIUS,so0);	/* 0A4	spill 1 other */
14357c478bd9Sstevel@tonic-gate	SPILL_64bit_asi(ASI_AIUS,so0);	/* 0A8	spill 2 other */
14367c478bd9Sstevel@tonic-gate	SPILL_32bit_asi(ASI_AIUS,so0);	/* 0AC	spill 3 other */
14377c478bd9Sstevel@tonic-gate	SPILL_64bit_asi(ASI_AIUS,so0);	/* 0B0	spill 4 other */
14387c478bd9Sstevel@tonic-gate	NOT4;				/* 0B4	spill 5 other */
14397c478bd9Sstevel@tonic-gate	NOT4;				/* 0B8	spill 6 other */
14407c478bd9Sstevel@tonic-gate	NOT4;				/* 0BC	spill 7 other */
14417c478bd9Sstevel@tonic-gate	NOT4;				/* 0C0	fill 0 normal */
14427c478bd9Sstevel@tonic-gate	FILL_32bit_asi(ASI_AIUP,fn0);	/* 0C4	fill 1 normal */
14437c478bd9Sstevel@tonic-gate	FILL_64bit_asi(ASI_AIUP,fn0);	/* 0C8	fill 2 normal */
14447c478bd9Sstevel@tonic-gate	FILL_32bit_asi(ASI_AIUP,fn0);	/* 0CC	fill 3 normal */
14457c478bd9Sstevel@tonic-gate	FILL_64bit_asi(ASI_AIUP,fn0);	/* 0D0	fill 4 normal */
14467c478bd9Sstevel@tonic-gate	FILL_32bit(not);		/* 0D4	fill 5 normal */
14477c478bd9Sstevel@tonic-gate	FILL_64bit(not);		/* 0D8	fill 6 normal */
14487c478bd9Sstevel@tonic-gate	FILL_mixed;			/* 0DC	fill 7 normal */
14497c478bd9Sstevel@tonic-gate	NOT4;				/* 0E0	fill 0 other */
14507c478bd9Sstevel@tonic-gate	NOT4;				/* 0E4	fill 1 other */
14517c478bd9Sstevel@tonic-gate	NOT4;				/* 0E8	fill 2 other */
14527c478bd9Sstevel@tonic-gate	NOT4;				/* 0EC	fill 3 other */
14537c478bd9Sstevel@tonic-gate	NOT4;				/* 0F0	fill 4 other */
14547c478bd9Sstevel@tonic-gate	NOT4;				/* 0F4	fill 5 other */
14557c478bd9Sstevel@tonic-gate	NOT4;				/* 0F8	fill 6 other */
14567c478bd9Sstevel@tonic-gate	NOT4;				/* 0FC	fill 7 other */
14577c478bd9Sstevel@tonic-gate	/* user traps */
14587c478bd9Sstevel@tonic-gate	GOTO(syscall_trap_4x);		/* 100	old system call */
14597c478bd9Sstevel@tonic-gate	TRAP(T_BREAKPOINT);		/* 101	user breakpoint */
14607c478bd9Sstevel@tonic-gate	TRAP(T_DIV0);			/* 102	user divide by zero */
146150eff769Smb158278	FLUSHW(tt0_flushw);		/* 103	flush windows */
14627c478bd9Sstevel@tonic-gate	GOTO(.clean_windows);		/* 104	clean windows */
14637c478bd9Sstevel@tonic-gate	BAD;				/* 105	range check ?? */
14647c478bd9Sstevel@tonic-gate	GOTO(.fix_alignment);		/* 106	do unaligned references */
14657c478bd9Sstevel@tonic-gate	BAD;				/* 107	unused */
146659f2ff5cSedp	SYSCALL_TRAP32;			/* 108	ILP32 system call on LP64 */
14677c478bd9Sstevel@tonic-gate	GOTO(set_trap0_addr);		/* 109	set trap0 address */
14687c478bd9Sstevel@tonic-gate	BAD; BAD; BAD4;			/* 10A - 10F unused */
14697c478bd9Sstevel@tonic-gate	TRP4; TRP4; TRP4; TRP4;		/* 110 - 11F V9 user trap handlers */
14707c478bd9Sstevel@tonic-gate	GOTO(.getcc);			/* 120	get condition codes */
14717c478bd9Sstevel@tonic-gate	GOTO(.setcc);			/* 121	set condition codes */
14727c478bd9Sstevel@tonic-gate	GOTO(.getpsr);			/* 122	get psr */
14737c478bd9Sstevel@tonic-gate	GOTO(.setpsr);			/* 123	set psr (some fields) */
14747c478bd9Sstevel@tonic-gate	GOTO(get_timestamp);		/* 124	get timestamp */
14757c478bd9Sstevel@tonic-gate	GOTO(get_virtime);		/* 125	get lwp virtual time */
14767c478bd9Sstevel@tonic-gate	PRIV(self_xcall);		/* 126	self xcall */
14777c478bd9Sstevel@tonic-gate	GOTO(get_hrestime);		/* 127	get hrestime */
14787c478bd9Sstevel@tonic-gate	BAD;				/* 128	ST_SETV9STACK */
14797c478bd9Sstevel@tonic-gate	GOTO(.getlgrp);			/* 129  get lgrpid */
14807c478bd9Sstevel@tonic-gate	BAD; BAD; BAD4;			/* 12A - 12F unused */
14817c478bd9Sstevel@tonic-gate	BAD4; BAD4; 			/* 130 - 137 unused */
14827c478bd9Sstevel@tonic-gate	DTRACE_PID;			/* 138  dtrace pid tracing provider */
1483f498645aSahl	BAD;				/* 139  unused */
14847c478bd9Sstevel@tonic-gate	DTRACE_RETURN;			/* 13A	dtrace pid return probe */
14857c478bd9Sstevel@tonic-gate	BAD; BAD4;			/* 13B - 13F unused */
148659f2ff5cSedp	SYSCALL_TRAP;			/* 140  LP64 system call */
1487af3c157aSrscott	SYSCALL(nosys);			/* 141  unused system call trap */
14887c478bd9Sstevel@tonic-gate#ifdef DEBUG_USER_TRAPTRACECTL
14897c478bd9Sstevel@tonic-gate	GOTO(.traptrace_freeze);	/* 142  freeze traptrace */
14907c478bd9Sstevel@tonic-gate	GOTO(.traptrace_unfreeze);	/* 143  unfreeze traptrace */
14917c478bd9Sstevel@tonic-gate#else
1492af3c157aSrscott	SYSCALL(nosys);			/* 142  unused system call trap */
1493af3c157aSrscott	SYSCALL(nosys);			/* 143  unused system call trap */
14947c478bd9Sstevel@tonic-gate#endif
14957c478bd9Sstevel@tonic-gate	BAD4; BAD4; BAD4;		/* 144 - 14F unused */
14967c478bd9Sstevel@tonic-gate	BAD4; BAD4; BAD4; BAD4;		/* 150 - 15F unused */
14977c478bd9Sstevel@tonic-gate	BAD4; BAD4; BAD4; BAD4;		/* 160 - 16F unused */
14987c478bd9Sstevel@tonic-gate	BAD;				/* 170 - unused */
14997c478bd9Sstevel@tonic-gate	BAD;				/* 171 - unused */
15007c478bd9Sstevel@tonic-gate	BAD; BAD;			/* 172 - 173 unused */
15017c478bd9Sstevel@tonic-gate	BAD4; BAD4;			/* 174 - 17B unused */
15027c478bd9Sstevel@tonic-gate#ifdef	PTL1_PANIC_DEBUG
15037c478bd9Sstevel@tonic-gate	mov PTL1_BAD_DEBUG, %g1; GOTO(ptl1_panic);
15047c478bd9Sstevel@tonic-gate					/* 17C	test ptl1_panic */
15057c478bd9Sstevel@tonic-gate#else
15067c478bd9Sstevel@tonic-gate	BAD;				/* 17C  unused */
15077c478bd9Sstevel@tonic-gate#endif	/* PTL1_PANIC_DEBUG */
15087c478bd9Sstevel@tonic-gate	PRIV(kmdb_trap);		/* 17D	kmdb enter (L1-A) */
15097c478bd9Sstevel@tonic-gate	PRIV(kmdb_trap);		/* 17E	kmdb breakpoint */
15107c478bd9Sstevel@tonic-gate	PRIV(kctx_obp_bpt);		/* 17F	obp breakpoint */
15117c478bd9Sstevel@tonic-gate	/* reserved */
15127c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4; NOT4;		/* 180 - 18F reserved */
15137c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4; NOT4;		/* 190 - 19F reserved */
15147c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4; NOT4;		/* 1A0 - 1AF reserved */
15157c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4; NOT4;		/* 1B0 - 1BF reserved */
15167c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4; NOT4;		/* 1C0 - 1CF reserved */
15177c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4; NOT4;		/* 1D0 - 1DF reserved */
15187c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4; NOT4;		/* 1E0 - 1EF reserved */
15197c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4; NOT4;		/* 1F0 - 1FF reserved */
15207c478bd9Sstevel@tonic-gatetrap_table1:
15217c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT; NOT;		/* 000 - 009 unused */
152225cf1a30Sjl139090	ASYNC_TRAP(T_INSTR_ERROR + T_TL1, trace_gen, tt1_iae);
15237c478bd9Sstevel@tonic-gate					/* 00A	instruction access error */
15247c478bd9Sstevel@tonic-gate	NOT; NOT4;			/* 00B - 00F unused */
15257c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4; NOT4;		/* 010 - 01F unused */
15267c478bd9Sstevel@tonic-gate	NOT4;				/* 020 - 023 unused */
15277c478bd9Sstevel@tonic-gate	CLEAN_WINDOW;			/* 024 - 027 clean window */
15287c478bd9Sstevel@tonic-gate	NOT4; NOT4;			/* 028 - 02F unused */
15297c478bd9Sstevel@tonic-gate	DMMU_EXCEPTION_TL1;		/* 030 	data access exception */
15307c478bd9Sstevel@tonic-gate	NOT;				/* 031 unused */
153125cf1a30Sjl139090	ASYNC_TRAP(T_DATA_ERROR + T_TL1, trace_gen, tt1_dae);
15327c478bd9Sstevel@tonic-gate					/* 032	data access error */
15337c478bd9Sstevel@tonic-gate	NOT;				/* 033	unused */
15347c478bd9Sstevel@tonic-gate	MISALIGN_ADDR_TL1;		/* 034	mem address not aligned */
15357c478bd9Sstevel@tonic-gate	NOT; NOT; NOT; NOT4; NOT4	/* 035 - 03F unused */
153625cf1a30Sjl139090	LABELED_BAD(tt1_asdat);		/* 040	async data error */
153725cf1a30Sjl139090	NOT; NOT; NOT;			/* 041 - 043 unused */
153825cf1a30Sjl139090	NOT4; NOT4; NOT4;		/* 044 - 04F unused */
15397c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4; NOT4;		/* 050 - 05F unused */
15407c478bd9Sstevel@tonic-gate	NOT;				/* 060	unused */
15417c478bd9Sstevel@tonic-gate	GOTO(kmdb_trap_tl1);		/* 061	PA watchpoint */
15427c478bd9Sstevel@tonic-gate	GOTO(kmdb_trap_tl1);		/* 062	VA watchpoint */
15437c478bd9Sstevel@tonic-gate	GOTO_TT(ce_err_tl1, trace_gen);	/* 063	corrected ECC error */
15447c478bd9Sstevel@tonic-gate	ITLB_MISS(tt1);			/* 064	instruction access MMU miss */
15457c478bd9Sstevel@tonic-gate	DTLB_MISS(tt1);			/* 068	data access MMU miss */
15467c478bd9Sstevel@tonic-gate	DTLB_PROT;			/* 06C	data access protection */
15477c478bd9Sstevel@tonic-gate	LABELED_BAD(tt1_fecc);		/* 070  fast ecache ECC error */
15487c478bd9Sstevel@tonic-gate	LABELED_BAD(tt1_dperr);		/* 071  Cheetah+ dcache parity error */
15497c478bd9Sstevel@tonic-gate	LABELED_BAD(tt1_iperr);		/* 072  Cheetah+ icache parity error */
15507c478bd9Sstevel@tonic-gate	NOT;				/* 073  reserved */
15517c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4;		/* 074 - 07F reserved */
15527c478bd9Sstevel@tonic-gate	NOT4;				/* 080	spill 0 normal */
15537c478bd9Sstevel@tonic-gate	SPILL_32bit_tt1(ASI_AIUP,sn1);	/* 084	spill 1 normal */
15547c478bd9Sstevel@tonic-gate	SPILL_64bit_tt1(ASI_AIUP,sn1);	/* 088	spill 2 normal */
15557c478bd9Sstevel@tonic-gate	SPILL_32bit_tt1(ASI_AIUP,sn1);	/* 08C	spill 3 normal */
15567c478bd9Sstevel@tonic-gate	SPILL_64bit_tt1(ASI_AIUP,sn1);	/* 090	spill 4 normal */
15577c478bd9Sstevel@tonic-gate	SPILL_32bit(not);		/* 094	spill 5 normal */
15587c478bd9Sstevel@tonic-gate	SPILL_64bit(not);		/* 098	spill 6 normal */
15597c478bd9Sstevel@tonic-gate	SPILL_mixed;			/* 09C	spill 7 normal */
15607c478bd9Sstevel@tonic-gate	NOT4;				/* 0A0	spill 0 other */
15617c478bd9Sstevel@tonic-gate	SPILL_32bit_tt1(ASI_AIUS,so1);	/* 0A4	spill 1 other */
15627c478bd9Sstevel@tonic-gate	SPILL_64bit_tt1(ASI_AIUS,so1);	/* 0A8	spill 2 other */
15637c478bd9Sstevel@tonic-gate	SPILL_32bit_tt1(ASI_AIUS,so1);	/* 0AC	spill 3 other */
15647c478bd9Sstevel@tonic-gate	SPILL_64bit_tt1(ASI_AIUS,so1);	/* 0B0  spill 4 other */
15657c478bd9Sstevel@tonic-gate	NOT4;				/* 0B4  spill 5 other */
15667c478bd9Sstevel@tonic-gate	NOT4;				/* 0B8  spill 6 other */
15677c478bd9Sstevel@tonic-gate	NOT4;				/* 0BC  spill 7 other */
15687c478bd9Sstevel@tonic-gate	NOT4;				/* 0C0	fill 0 normal */
15697c478bd9Sstevel@tonic-gate	FILL_32bit_tt1(ASI_AIUP,fn1);	/* 0C4	fill 1 normal */
15707c478bd9Sstevel@tonic-gate	FILL_64bit_tt1(ASI_AIUP,fn1);	/* 0C8	fill 2 normal */
15717c478bd9Sstevel@tonic-gate	FILL_32bit_tt1(ASI_AIUP,fn1);	/* 0CC	fill 3 normal */
15727c478bd9Sstevel@tonic-gate	FILL_64bit_tt1(ASI_AIUP,fn1);	/* 0D0	fill 4 normal */
15737c478bd9Sstevel@tonic-gate	FILL_32bit(not);		/* 0D4	fill 5 normal */
15747c478bd9Sstevel@tonic-gate	FILL_64bit(not);		/* 0D8	fill 6 normal */
15757c478bd9Sstevel@tonic-gate	FILL_mixed;			/* 0DC	fill 7 normal */
15767c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4; NOT4;		/* 0E0 - 0EF unused */
15777c478bd9Sstevel@tonic-gate	NOT4; NOT4; NOT4; NOT4;		/* 0F0 - 0FF unused */
15787c478bd9Sstevel@tonic-gate	LABELED_BAD(tt1_swtrap0);	/* 100  fast ecache ECC error (cont) */
15797c478bd9Sstevel@tonic-gate	LABELED_BAD(tt1_swtrap1);	/* 101  Ch+ D$ parity error (cont) */
15807c478bd9Sstevel@tonic-gate	LABELED_BAD(tt1_swtrap2);	/* 102  Ch+ I$ parity error (cont) */
15817c478bd9Sstevel@tonic-gate	NOT;				/* 103  reserved */
15827c478bd9Sstevel@tonic-gate/*
15837c478bd9Sstevel@tonic-gate * We only reserve the above four special case soft traps for code running
15847c478bd9Sstevel@tonic-gate * at TL>0, so we can truncate the trap table here.
15857c478bd9Sstevel@tonic-gate */
15867c478bd9Sstevel@tonic-gateetrap_table:
15877c478bd9Sstevel@tonic-gate	.size	trap_table, (.-trap_table)
15887c478bd9Sstevel@tonic-gate	.size	scb, (.-scb)
15897c478bd9Sstevel@tonic-gate
15907c478bd9Sstevel@tonic-gate/*
15917c478bd9Sstevel@tonic-gate * We get to exec_fault in the case of an instruction miss and tte
15927c478bd9Sstevel@tonic-gate * has no execute bit set.  We go to tl0 to handle it.
15937c478bd9Sstevel@tonic-gate *
15947c478bd9Sstevel@tonic-gate * g1 = tsbe pointer (in/clobbered)
15957c478bd9Sstevel@tonic-gate * g2 = tag access register (in)
15967c478bd9Sstevel@tonic-gate * g3 - g4 = scratch (clobbered)
15977c478bd9Sstevel@tonic-gate * g5 = tsbe data (in)
15987c478bd9Sstevel@tonic-gate * g6 = scratch (clobbered)
15997c478bd9Sstevel@tonic-gate */
16007c478bd9Sstevel@tonic-gate	ALTENTRY(exec_fault)
16017c478bd9Sstevel@tonic-gate	TRACE_TSBHIT(0x200)
16027c478bd9Sstevel@tonic-gate	SWITCH_GLOBALS
16037c478bd9Sstevel@tonic-gate	mov	MMU_TAG_ACCESS, %g4
16047c478bd9Sstevel@tonic-gate	ldxa	[%g4]ASI_IMMU, %g2			! arg1 = addr
16057c478bd9Sstevel@tonic-gate	mov	T_INSTR_MMU_MISS, %g3			! arg2 = traptype
16067c478bd9Sstevel@tonic-gate	set	trap, %g1
16077c478bd9Sstevel@tonic-gate	ba,pt	%xcc, sys_trap
16087c478bd9Sstevel@tonic-gate	  mov	-1, %g4
16097c478bd9Sstevel@tonic-gate
16107c478bd9Sstevel@tonic-gate.mmu_exception_not_aligned:
16117c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g1
16127c478bd9Sstevel@tonic-gate	btst	TSTATE_PRIV, %g1
16137c478bd9Sstevel@tonic-gate	bnz,pn	%icc, 2f
16147c478bd9Sstevel@tonic-gate	nop
16157c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)				! load CPU struct addr
16167c478bd9Sstevel@tonic-gate	ldn	[%g1 + CPU_THREAD], %g1			! load thread pointer
16177c478bd9Sstevel@tonic-gate	ldn	[%g1 + T_PROCP], %g1			! load proc pointer
16187c478bd9Sstevel@tonic-gate	ldn	[%g1 + P_UTRAPS], %g5			! are there utraps?
16197c478bd9Sstevel@tonic-gate	brz,pt	%g5, 2f
16207c478bd9Sstevel@tonic-gate	nop
16217c478bd9Sstevel@tonic-gate	ldn	[%g5 + P_UTRAP15], %g5			! unaligned utrap?
16227c478bd9Sstevel@tonic-gate	brz,pn	%g5, 2f
16237c478bd9Sstevel@tonic-gate	nop
16247c478bd9Sstevel@tonic-gate	btst	1, %sp
16257c478bd9Sstevel@tonic-gate	bz,pt	%xcc, 1f				! 32 bit user program
16267c478bd9Sstevel@tonic-gate	nop
16277c478bd9Sstevel@tonic-gate	ba,pt	%xcc, .setup_v9utrap			! 64 bit user program
16287c478bd9Sstevel@tonic-gate	nop
16297c478bd9Sstevel@tonic-gate1:
16307c478bd9Sstevel@tonic-gate	ba,pt	%xcc, .setup_utrap
16317c478bd9Sstevel@tonic-gate	or	%g2, %g0, %g7
16327c478bd9Sstevel@tonic-gate2:
16337c478bd9Sstevel@tonic-gate	ba,pt	%xcc, .mmu_exception_end
16347c478bd9Sstevel@tonic-gate	mov	T_ALIGNMENT, %g1
16357c478bd9Sstevel@tonic-gate
16367c478bd9Sstevel@tonic-gate.mmu_priv_exception:
16377c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g1
16387c478bd9Sstevel@tonic-gate	btst	TSTATE_PRIV, %g1
16397c478bd9Sstevel@tonic-gate	bnz,pn	%icc, 1f
16407c478bd9Sstevel@tonic-gate	nop
16417c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)				! load CPU struct addr
16427c478bd9Sstevel@tonic-gate	ldn	[%g1 + CPU_THREAD], %g1			! load thread pointer
16437c478bd9Sstevel@tonic-gate	ldn	[%g1 + T_PROCP], %g1			! load proc pointer
16447c478bd9Sstevel@tonic-gate	ldn	[%g1 + P_UTRAPS], %g5			! are there utraps?
16457c478bd9Sstevel@tonic-gate	brz,pt	%g5, 1f
16467c478bd9Sstevel@tonic-gate	nop
16477c478bd9Sstevel@tonic-gate	ldn	[%g5 + P_UTRAP16], %g5
16487c478bd9Sstevel@tonic-gate	brnz,pt	%g5, .setup_v9utrap
16497c478bd9Sstevel@tonic-gate	nop
16507c478bd9Sstevel@tonic-gate1:
16517c478bd9Sstevel@tonic-gate	mov	T_PRIV_INSTR, %g1
16527c478bd9Sstevel@tonic-gate
16537c478bd9Sstevel@tonic-gate.mmu_exception_end:
16547c478bd9Sstevel@tonic-gate	CPU_INDEX(%g4, %g5)
16557c478bd9Sstevel@tonic-gate	set	cpu_core, %g5
16567c478bd9Sstevel@tonic-gate	sllx	%g4, CPU_CORE_SHIFT, %g4
16577c478bd9Sstevel@tonic-gate	add	%g4, %g5, %g4
16587c478bd9Sstevel@tonic-gate	lduh	[%g4 + CPUC_DTRACE_FLAGS], %g5
16597c478bd9Sstevel@tonic-gate	andcc	%g5, CPU_DTRACE_NOFAULT, %g0
16607c478bd9Sstevel@tonic-gate	bz	%xcc, .mmu_exception_tlb_chk
16617c478bd9Sstevel@tonic-gate	or	%g5, CPU_DTRACE_BADADDR, %g5
16627c478bd9Sstevel@tonic-gate	stuh	%g5, [%g4 + CPUC_DTRACE_FLAGS]
16637c478bd9Sstevel@tonic-gate	done
16647c478bd9Sstevel@tonic-gate
16657c478bd9Sstevel@tonic-gate.mmu_exception_tlb_chk:
16667c478bd9Sstevel@tonic-gate	GET_CPU_IMPL(%g5)			! check SFSR.FT to see if this
16677c478bd9Sstevel@tonic-gate	cmp	%g5, PANTHER_IMPL		! is a TLB parity error. But
16687c478bd9Sstevel@tonic-gate	bne	2f				! we only do this check while
16697c478bd9Sstevel@tonic-gate	mov	1, %g4				! running on Panther CPUs
16707c478bd9Sstevel@tonic-gate	sllx	%g4, PN_SFSR_PARITY_SHIFT, %g4	! since US-I/II use the same
16717c478bd9Sstevel@tonic-gate	andcc	%g3, %g4, %g0			! bit for something else which
16727c478bd9Sstevel@tonic-gate	bz	2f				! will be handled later.
16737c478bd9Sstevel@tonic-gate	nop
16747c478bd9Sstevel@tonic-gate.mmu_exception_is_tlb_parity:
16757c478bd9Sstevel@tonic-gate	.weak itlb_parity_trap
16767c478bd9Sstevel@tonic-gate	.weak dtlb_parity_trap
16777c478bd9Sstevel@tonic-gate	set	itlb_parity_trap, %g4
16787c478bd9Sstevel@tonic-gate	cmp	%g1, T_INSTR_EXCEPTION		! branch to the itlb or
16797c478bd9Sstevel@tonic-gate	be	3f				! dtlb parity handler
16807c478bd9Sstevel@tonic-gate	nop					! if this trap is due
16817c478bd9Sstevel@tonic-gate	set	dtlb_parity_trap, %g4
16827c478bd9Sstevel@tonic-gate	cmp	%g1, T_DATA_EXCEPTION		! to a IMMU exception
16837c478bd9Sstevel@tonic-gate	be	3f				! or DMMU exception.
16847c478bd9Sstevel@tonic-gate	nop
16857c478bd9Sstevel@tonic-gate2:
16867c478bd9Sstevel@tonic-gate	sllx	%g3, 32, %g3
16877c478bd9Sstevel@tonic-gate	or	%g3, %g1, %g3
16887c478bd9Sstevel@tonic-gate	set	trap, %g1
16897c478bd9Sstevel@tonic-gate	ba,pt	%xcc, sys_trap
16907c478bd9Sstevel@tonic-gate	sub	%g0, 1, %g4
16917c478bd9Sstevel@tonic-gate3:
16927c478bd9Sstevel@tonic-gate	jmp	%g4				! off to the appropriate
16937c478bd9Sstevel@tonic-gate	nop					! TLB parity handler
16947c478bd9Sstevel@tonic-gate
16957c478bd9Sstevel@tonic-gate.fp_disabled:
16967c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)				! load CPU struct addr
16977c478bd9Sstevel@tonic-gate	ldn	[%g1 + CPU_THREAD], %g1			! load thread pointer
16987c478bd9Sstevel@tonic-gate#ifdef SF_ERRATA_30 /* call causes fp-disabled */
16997c478bd9Sstevel@tonic-gate	brz,a,pn %g1, 2f
17007c478bd9Sstevel@tonic-gate	  nop
17017c478bd9Sstevel@tonic-gate#endif
17027c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g4
17037c478bd9Sstevel@tonic-gate	btst	TSTATE_PRIV, %g4
17047c478bd9Sstevel@tonic-gate#ifdef SF_ERRATA_30 /* call causes fp-disabled */
17057c478bd9Sstevel@tonic-gate	bnz,pn %icc, 2f
17067c478bd9Sstevel@tonic-gate	  nop
17077c478bd9Sstevel@tonic-gate#else
17087c478bd9Sstevel@tonic-gate	bnz,a,pn %icc, ptl1_panic
17097c478bd9Sstevel@tonic-gate	  mov	PTL1_BAD_FPTRAP, %g1
17107c478bd9Sstevel@tonic-gate#endif
17117c478bd9Sstevel@tonic-gate	ldn	[%g1 + T_PROCP], %g1			! load proc pointer
17127c478bd9Sstevel@tonic-gate	ldn	[%g1 + P_UTRAPS], %g5			! are there utraps?
17137c478bd9Sstevel@tonic-gate	brz,a,pt %g5, 2f
17147c478bd9Sstevel@tonic-gate	  nop
17157c478bd9Sstevel@tonic-gate	ldn	[%g5 + P_UTRAP7], %g5			! fp_disabled utrap?
17167c478bd9Sstevel@tonic-gate	brz,a,pn %g5, 2f
17177c478bd9Sstevel@tonic-gate	  nop
17187c478bd9Sstevel@tonic-gate	btst	1, %sp
17197c478bd9Sstevel@tonic-gate	bz,a,pt	%xcc, 1f				! 32 bit user program
17207c478bd9Sstevel@tonic-gate	  nop
17217c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, .setup_v9utrap			! 64 bit user program
17227c478bd9Sstevel@tonic-gate	  nop
17237c478bd9Sstevel@tonic-gate1:
17247c478bd9Sstevel@tonic-gate	ba,pt	%xcc, .setup_utrap
17257c478bd9Sstevel@tonic-gate	  or	%g0, %g0, %g7
17267c478bd9Sstevel@tonic-gate2:
17277c478bd9Sstevel@tonic-gate	set	fp_disabled, %g1
17287c478bd9Sstevel@tonic-gate	ba,pt	%xcc, sys_trap
17297c478bd9Sstevel@tonic-gate	  sub	%g0, 1, %g4
17307c478bd9Sstevel@tonic-gate
17317c478bd9Sstevel@tonic-gate.fp_ieee_exception:
17327c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g1
17337c478bd9Sstevel@tonic-gate	btst	TSTATE_PRIV, %g1
17347c478bd9Sstevel@tonic-gate	bnz,a,pn %icc, ptl1_panic
17357c478bd9Sstevel@tonic-gate	  mov	PTL1_BAD_FPTRAP, %g1
17367c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)				! load CPU struct addr
17377c478bd9Sstevel@tonic-gate	stx	%fsr, [%g1 + CPU_TMP1]
17387c478bd9Sstevel@tonic-gate	ldx	[%g1 + CPU_TMP1], %g2
17397c478bd9Sstevel@tonic-gate	ldn	[%g1 + CPU_THREAD], %g1			! load thread pointer
17407c478bd9Sstevel@tonic-gate	ldn	[%g1 + T_PROCP], %g1			! load proc pointer
17417c478bd9Sstevel@tonic-gate	ldn	[%g1 + P_UTRAPS], %g5			! are there utraps?
17427c478bd9Sstevel@tonic-gate	brz,a,pt %g5, 1f
17437c478bd9Sstevel@tonic-gate	  nop
17447c478bd9Sstevel@tonic-gate	ldn	[%g5 + P_UTRAP8], %g5
17457c478bd9Sstevel@tonic-gate	brnz,a,pt %g5, .setup_v9utrap
17467c478bd9Sstevel@tonic-gate	  nop
17477c478bd9Sstevel@tonic-gate1:
17487c478bd9Sstevel@tonic-gate	set	_fp_ieee_exception, %g1
17497c478bd9Sstevel@tonic-gate	ba,pt	%xcc, sys_trap
17507c478bd9Sstevel@tonic-gate	  sub	%g0, 1, %g4
17517c478bd9Sstevel@tonic-gate
17527c478bd9Sstevel@tonic-gate/*
17537c478bd9Sstevel@tonic-gate * Register Inputs:
17547c478bd9Sstevel@tonic-gate *	%g5		user trap handler
17557c478bd9Sstevel@tonic-gate *	%g7		misaligned addr - for alignment traps only
17567c478bd9Sstevel@tonic-gate */
17577c478bd9Sstevel@tonic-gate.setup_utrap:
17587c478bd9Sstevel@tonic-gate	set	trap, %g1			! setup in case we go
17597c478bd9Sstevel@tonic-gate	mov	T_FLUSH_PCB, %g3		! through sys_trap on
17607c478bd9Sstevel@tonic-gate	sub	%g0, 1, %g4			! the save instruction below
17617c478bd9Sstevel@tonic-gate
17627c478bd9Sstevel@tonic-gate	/*
17637c478bd9Sstevel@tonic-gate	 * If the DTrace pid provider is single stepping a copied-out
17647c478bd9Sstevel@tonic-gate	 * instruction, t->t_dtrace_step will be set. In that case we need
17657c478bd9Sstevel@tonic-gate	 * to abort the single-stepping (since execution of the instruction
17667c478bd9Sstevel@tonic-gate	 * was interrupted) and use the value of t->t_dtrace_npc as the %npc.
17677c478bd9Sstevel@tonic-gate	 */
17687c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME32), %sp	! window for trap handler
17697c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)			! load CPU struct addr
17707c478bd9Sstevel@tonic-gate	ldn	[%g1 + CPU_THREAD], %g1		! load thread pointer
17717c478bd9Sstevel@tonic-gate	ldub	[%g1 + T_DTRACE_STEP], %g2	! load t->t_dtrace_step
17727c478bd9Sstevel@tonic-gate	rdpr	%tnpc, %l2			! arg1 == tnpc
17737c478bd9Sstevel@tonic-gate	brz,pt	%g2, 1f
17747c478bd9Sstevel@tonic-gate	rdpr	%tpc, %l1			! arg0 == tpc
17757c478bd9Sstevel@tonic-gate
17767c478bd9Sstevel@tonic-gate	ldub	[%g1 + T_DTRACE_AST], %g2	! load t->t_dtrace_ast
17777c478bd9Sstevel@tonic-gate	ldn	[%g1 + T_DTRACE_NPC], %l2	! arg1 = t->t_dtrace_npc (step)
17787c478bd9Sstevel@tonic-gate	brz,pt	%g2, 1f
17797c478bd9Sstevel@tonic-gate	st	%g0, [%g1 + T_DTRACE_FT]	! zero all pid provider flags
17807c478bd9Sstevel@tonic-gate	stub	%g2, [%g1 + T_ASTFLAG]		! aston(t) if t->t_dtrace_ast
17817c478bd9Sstevel@tonic-gate1:
17827c478bd9Sstevel@tonic-gate	mov	%g7, %l3			! arg2 == misaligned address
17837c478bd9Sstevel@tonic-gate
17847c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g1			! cwp for trap handler
17857c478bd9Sstevel@tonic-gate	rdpr	%cwp, %g4
17867c478bd9Sstevel@tonic-gate	bclr	TSTATE_CWP_MASK, %g1
17877c478bd9Sstevel@tonic-gate	wrpr	%g1, %g4, %tstate
17887c478bd9Sstevel@tonic-gate	wrpr	%g0, %g5, %tnpc			! trap handler address
17897c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
17907c478bd9Sstevel@tonic-gate	/* NOTREACHED */
17917c478bd9Sstevel@tonic-gate
17927c478bd9Sstevel@tonic-gate.check_v9utrap:
17937c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g1
17947c478bd9Sstevel@tonic-gate	btst	TSTATE_PRIV, %g1
17957c478bd9Sstevel@tonic-gate	bnz,a,pn %icc, 3f
17967c478bd9Sstevel@tonic-gate	  nop
17977c478bd9Sstevel@tonic-gate	CPU_ADDR(%g4, %g1)				! load CPU struct addr
17987c478bd9Sstevel@tonic-gate	ldn	[%g4 + CPU_THREAD], %g5			! load thread pointer
17997c478bd9Sstevel@tonic-gate	ldn	[%g5 + T_PROCP], %g5			! load proc pointer
18007c478bd9Sstevel@tonic-gate	ldn	[%g5 + P_UTRAPS], %g5			! are there utraps?
18017c478bd9Sstevel@tonic-gate
18027c478bd9Sstevel@tonic-gate	cmp	%g3, T_SOFTWARE_TRAP
18037c478bd9Sstevel@tonic-gate	bne,a,pt %icc, 1f
18047c478bd9Sstevel@tonic-gate	  nop
18057c478bd9Sstevel@tonic-gate
18067c478bd9Sstevel@tonic-gate	brz,pt %g5, 3f			! if p_utraps == NULL goto trap()
18077c478bd9Sstevel@tonic-gate	  rdpr	%tt, %g3		! delay - get actual hw trap type
18087c478bd9Sstevel@tonic-gate
18097c478bd9Sstevel@tonic-gate	sub	%g3, 254, %g1		! UT_TRAP_INSTRUCTION_16 = p_utraps[18]
18107c478bd9Sstevel@tonic-gate	ba,pt	%icc, 2f
18117c478bd9Sstevel@tonic-gate	  smul	%g1, CPTRSIZE, %g2
18127c478bd9Sstevel@tonic-gate1:
18137c478bd9Sstevel@tonic-gate	brz,a,pt %g5, 3f		! if p_utraps == NULL goto trap()
18147c478bd9Sstevel@tonic-gate	  nop
18157c478bd9Sstevel@tonic-gate
18167c478bd9Sstevel@tonic-gate	cmp	%g3, T_UNIMP_INSTR
18177c478bd9Sstevel@tonic-gate	bne,a,pt %icc, 2f
18187c478bd9Sstevel@tonic-gate	  nop
18197c478bd9Sstevel@tonic-gate
18207c478bd9Sstevel@tonic-gate	mov	1, %g1
18217c478bd9Sstevel@tonic-gate	st	%g1, [%g4 + CPU_TL1_HDLR] ! set CPU_TL1_HDLR
18227c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g1		! ld trapping instruction using
18237c478bd9Sstevel@tonic-gate	lduwa	[%g1]ASI_AIUP, %g1	! "AS IF USER" ASI which could fault
18247c478bd9Sstevel@tonic-gate	st	%g0, [%g4 + CPU_TL1_HDLR] ! clr CPU_TL1_HDLR
18257c478bd9Sstevel@tonic-gate
18267c478bd9Sstevel@tonic-gate	sethi	%hi(0xc1c00000), %g4	! setup mask for illtrap instruction
18277c478bd9Sstevel@tonic-gate	andcc	%g1, %g4, %g4		! and instruction with mask
18287c478bd9Sstevel@tonic-gate	bnz,a,pt %icc, 3f		! if %g4 == zero, %g1 is an ILLTRAP
18297c478bd9Sstevel@tonic-gate	  nop				! fall thru to setup
18307c478bd9Sstevel@tonic-gate2:
18317c478bd9Sstevel@tonic-gate	ldn	[%g5 + %g2], %g5
18327c478bd9Sstevel@tonic-gate	brnz,a,pt %g5, .setup_v9utrap
18337c478bd9Sstevel@tonic-gate	  nop
18347c478bd9Sstevel@tonic-gate3:
18357c478bd9Sstevel@tonic-gate	set	trap, %g1
18367c478bd9Sstevel@tonic-gate	ba,pt	%xcc, sys_trap
18377c478bd9Sstevel@tonic-gate	  sub	%g0, 1, %g4
18387c478bd9Sstevel@tonic-gate	/* NOTREACHED */
18397c478bd9Sstevel@tonic-gate
18407c478bd9Sstevel@tonic-gate/*
18417c478bd9Sstevel@tonic-gate * Register Inputs:
18427c478bd9Sstevel@tonic-gate *	%g5		user trap handler
18437c478bd9Sstevel@tonic-gate */
18447c478bd9Sstevel@tonic-gate.setup_v9utrap:
18457c478bd9Sstevel@tonic-gate	set	trap, %g1			! setup in case we go
18467c478bd9Sstevel@tonic-gate	mov	T_FLUSH_PCB, %g3		! through sys_trap on
18477c478bd9Sstevel@tonic-gate	sub	%g0, 1, %g4			! the save instruction below
18487c478bd9Sstevel@tonic-gate
18497c478bd9Sstevel@tonic-gate	/*
18507c478bd9Sstevel@tonic-gate	 * If the DTrace pid provider is single stepping a copied-out
18517c478bd9Sstevel@tonic-gate	 * instruction, t->t_dtrace_step will be set. In that case we need
18527c478bd9Sstevel@tonic-gate	 * to abort the single-stepping (since execution of the instruction
18537c478bd9Sstevel@tonic-gate	 * was interrupted) and use the value of t->t_dtrace_npc as the %npc.
18547c478bd9Sstevel@tonic-gate	 */
18557c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME64), %sp	! window for trap handler
18567c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)			! load CPU struct addr
18577c478bd9Sstevel@tonic-gate	ldn	[%g1 + CPU_THREAD], %g1		! load thread pointer
18587c478bd9Sstevel@tonic-gate	ldub	[%g1 + T_DTRACE_STEP], %g2	! load t->t_dtrace_step
18597c478bd9Sstevel@tonic-gate	rdpr	%tnpc, %l7			! arg1 == tnpc
18607c478bd9Sstevel@tonic-gate	brz,pt	%g2, 1f
18617c478bd9Sstevel@tonic-gate	rdpr	%tpc, %l6			! arg0 == tpc
18627c478bd9Sstevel@tonic-gate
18637c478bd9Sstevel@tonic-gate	ldub	[%g1 + T_DTRACE_AST], %g2	! load t->t_dtrace_ast
18647c478bd9Sstevel@tonic-gate	ldn	[%g1 + T_DTRACE_NPC], %l7	! arg1 == t->t_dtrace_npc (step)
18657c478bd9Sstevel@tonic-gate	brz,pt	%g2, 1f
18667c478bd9Sstevel@tonic-gate	st	%g0, [%g1 + T_DTRACE_FT]	! zero all pid provider flags
18677c478bd9Sstevel@tonic-gate	stub	%g2, [%g1 + T_ASTFLAG]		! aston(t) if t->t_dtrace_ast
18687c478bd9Sstevel@tonic-gate1:
18697c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g2			! cwp for trap handler
18707c478bd9Sstevel@tonic-gate	rdpr	%cwp, %g4
18717c478bd9Sstevel@tonic-gate	bclr	TSTATE_CWP_MASK, %g2
18727c478bd9Sstevel@tonic-gate	wrpr	%g2, %g4, %tstate
18737c478bd9Sstevel@tonic-gate
18747c478bd9Sstevel@tonic-gate	ldn	[%g1 + T_PROCP], %g4		! load proc pointer
18757c478bd9Sstevel@tonic-gate	ldn	[%g4 + P_AS], %g4		! load as pointer
18767c478bd9Sstevel@tonic-gate	ldn	[%g4 + A_USERLIMIT], %g4	! load as userlimit
18777c478bd9Sstevel@tonic-gate	cmp	%l7, %g4			! check for single-step set
18787c478bd9Sstevel@tonic-gate	bne,pt	%xcc, 4f
18797c478bd9Sstevel@tonic-gate	  nop
18807c478bd9Sstevel@tonic-gate	ldn	[%g1 + T_LWP], %g1		! load klwp pointer
18817c478bd9Sstevel@tonic-gate	ld	[%g1 + PCB_STEP], %g4		! load single-step flag
18827c478bd9Sstevel@tonic-gate	cmp	%g4, STEP_ACTIVE		! step flags set in pcb?
18837c478bd9Sstevel@tonic-gate	bne,pt	%icc, 4f
18847c478bd9Sstevel@tonic-gate	  nop
18857c478bd9Sstevel@tonic-gate	stn	%g5, [%g1 + PCB_TRACEPC]	! save trap handler addr in pcb
18867c478bd9Sstevel@tonic-gate	mov	%l7, %g4			! on entry to precise user trap
18877c478bd9Sstevel@tonic-gate	add	%l6, 4, %l7			! handler, %l6 == pc, %l7 == npc
18887c478bd9Sstevel@tonic-gate						! at time of trap
18897c478bd9Sstevel@tonic-gate	wrpr	%g0, %g4, %tnpc			! generate FLTBOUNDS,
18907c478bd9Sstevel@tonic-gate						! %g4 == userlimit
18917c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
18927c478bd9Sstevel@tonic-gate	/* NOTREACHED */
18937c478bd9Sstevel@tonic-gate4:
18947c478bd9Sstevel@tonic-gate	wrpr	%g0, %g5, %tnpc			! trap handler address
18957c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE_CHK_INTR
18967c478bd9Sstevel@tonic-gate	/* NOTREACHED */
18977c478bd9Sstevel@tonic-gate
18987c478bd9Sstevel@tonic-gate.fp_exception:
18997c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)
19007c478bd9Sstevel@tonic-gate	stx	%fsr, [%g1 + CPU_TMP1]
19017c478bd9Sstevel@tonic-gate	ldx	[%g1 + CPU_TMP1], %g2
19027c478bd9Sstevel@tonic-gate
19037c478bd9Sstevel@tonic-gate	/*
19047c478bd9Sstevel@tonic-gate	 * Cheetah takes unfinished_FPop trap for certain range of operands
19057c478bd9Sstevel@tonic-gate	 * to the "fitos" instruction. Instead of going through the slow
19067c478bd9Sstevel@tonic-gate	 * software emulation path, we try to simulate the "fitos" instruction
19077c478bd9Sstevel@tonic-gate	 * via "fitod" and "fdtos" provided the following conditions are met:
19087c478bd9Sstevel@tonic-gate	 *
19097c478bd9Sstevel@tonic-gate	 *	fpu_exists is set (if DEBUG)
19107c478bd9Sstevel@tonic-gate	 *	not in privileged mode
19117c478bd9Sstevel@tonic-gate	 *	ftt is unfinished_FPop
19127c478bd9Sstevel@tonic-gate	 *	NXM IEEE trap is not enabled
19137c478bd9Sstevel@tonic-gate	 *	instruction at %tpc is "fitos"
19147c478bd9Sstevel@tonic-gate	 *
19157c478bd9Sstevel@tonic-gate	 *  Usage:
19167c478bd9Sstevel@tonic-gate	 *	%g1	per cpu address
19177c478bd9Sstevel@tonic-gate	 *	%g2	%fsr
19187c478bd9Sstevel@tonic-gate	 *	%g6	user instruction
19197c478bd9Sstevel@tonic-gate	 *
19207c478bd9Sstevel@tonic-gate	 * Note that we can take a memory access related trap while trying
19217c478bd9Sstevel@tonic-gate	 * to fetch the user instruction. Therefore, we set CPU_TL1_HDLR
19227c478bd9Sstevel@tonic-gate	 * flag to catch those traps and let the SFMMU code deal with page
19237c478bd9Sstevel@tonic-gate	 * fault and data access exception.
19247c478bd9Sstevel@tonic-gate	 */
19257c478bd9Sstevel@tonic-gate#if defined(DEBUG) || defined(NEED_FPU_EXISTS)
19267c478bd9Sstevel@tonic-gate	sethi	%hi(fpu_exists), %g7
19277c478bd9Sstevel@tonic-gate	ld	[%g7 + %lo(fpu_exists)], %g7
19287c478bd9Sstevel@tonic-gate	brz,pn %g7, .fp_exception_cont
19297c478bd9Sstevel@tonic-gate	  nop
19307c478bd9Sstevel@tonic-gate#endif
19317c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g7			! branch if in privileged mode
19327c478bd9Sstevel@tonic-gate	btst	TSTATE_PRIV, %g7
19337c478bd9Sstevel@tonic-gate	bnz,pn	%xcc, .fp_exception_cont
19347c478bd9Sstevel@tonic-gate	srl	%g2, FSR_FTT_SHIFT, %g7		! extract ftt from %fsr
19357c478bd9Sstevel@tonic-gate	and	%g7, (FSR_FTT>>FSR_FTT_SHIFT), %g7
19367c478bd9Sstevel@tonic-gate	cmp	%g7, FTT_UNFIN
19377c478bd9Sstevel@tonic-gate	set	FSR_TEM_NX, %g5
19387c478bd9Sstevel@tonic-gate	bne,pn	%xcc, .fp_exception_cont	! branch if NOT unfinished_FPop
19397c478bd9Sstevel@tonic-gate	  andcc	%g2, %g5, %g0
19407c478bd9Sstevel@tonic-gate	bne,pn	%xcc, .fp_exception_cont	! branch if FSR_TEM_NX enabled
19417c478bd9Sstevel@tonic-gate	  rdpr	%tpc, %g5			! get faulting PC
19427c478bd9Sstevel@tonic-gate
19437c478bd9Sstevel@tonic-gate	or	%g0, 1, %g7
19447c478bd9Sstevel@tonic-gate	st	%g7, [%g1 + CPU_TL1_HDLR]	! set tl1_hdlr flag
19457c478bd9Sstevel@tonic-gate	lda	[%g5]ASI_USER, %g6		! get user's instruction
19467c478bd9Sstevel@tonic-gate	st	%g0, [%g1 + CPU_TL1_HDLR]	! clear tl1_hdlr flag
19477c478bd9Sstevel@tonic-gate
19487c478bd9Sstevel@tonic-gate	set	FITOS_INSTR_MASK, %g7
19497c478bd9Sstevel@tonic-gate	and	%g6, %g7, %g7
19507c478bd9Sstevel@tonic-gate	set	FITOS_INSTR, %g5
19517c478bd9Sstevel@tonic-gate	cmp	%g7, %g5
19527c478bd9Sstevel@tonic-gate	bne,pn	%xcc, .fp_exception_cont	! branch if not FITOS_INSTR
19537c478bd9Sstevel@tonic-gate	 nop
19547c478bd9Sstevel@tonic-gate
19557c478bd9Sstevel@tonic-gate	/*
19567c478bd9Sstevel@tonic-gate	 * This is unfinished FPops trap for "fitos" instruction. We
19577c478bd9Sstevel@tonic-gate	 * need to simulate "fitos" via "fitod" and "fdtos" instruction
19587c478bd9Sstevel@tonic-gate	 * sequence.
19597c478bd9Sstevel@tonic-gate	 *
19607c478bd9Sstevel@tonic-gate	 * We need a temporary FP register to do the conversion. Since
19617c478bd9Sstevel@tonic-gate	 * both source and destination operands for the "fitos" instruction
19627c478bd9Sstevel@tonic-gate	 * have to be within %f0-%f31, we use an FP register from the upper
19637c478bd9Sstevel@tonic-gate	 * half to guarantee that it won't collide with the source or the
19647c478bd9Sstevel@tonic-gate	 * dest operand. However, we do have to save and restore its value.
19657c478bd9Sstevel@tonic-gate	 *
19667c478bd9Sstevel@tonic-gate	 * We use %d62 as a temporary FP register for the conversion and
19677c478bd9Sstevel@tonic-gate	 * branch to appropriate instruction within the conversion tables
19687c478bd9Sstevel@tonic-gate	 * based upon the rs2 and rd values.
19697c478bd9Sstevel@tonic-gate	 */
19707c478bd9Sstevel@tonic-gate
19717c478bd9Sstevel@tonic-gate	std	%d62, [%g1 + CPU_TMP1]		! save original value
19727c478bd9Sstevel@tonic-gate
19737c478bd9Sstevel@tonic-gate	srl	%g6, FITOS_RS2_SHIFT, %g7
19747c478bd9Sstevel@tonic-gate	and	%g7, FITOS_REG_MASK, %g7
19757c478bd9Sstevel@tonic-gate	set	_fitos_fitod_table, %g4
19767c478bd9Sstevel@tonic-gate	sllx	%g7, 2, %g7
19777c478bd9Sstevel@tonic-gate	jmp	%g4 + %g7
19787c478bd9Sstevel@tonic-gate	  ba,pt	%xcc, _fitos_fitod_done
19797c478bd9Sstevel@tonic-gate	.empty
19807c478bd9Sstevel@tonic-gate
19817c478bd9Sstevel@tonic-gate_fitos_fitod_table:
19827c478bd9Sstevel@tonic-gate	  fitod	%f0, %d62
19837c478bd9Sstevel@tonic-gate	  fitod	%f1, %d62
19847c478bd9Sstevel@tonic-gate	  fitod	%f2, %d62
19857c478bd9Sstevel@tonic-gate	  fitod	%f3, %d62
19867c478bd9Sstevel@tonic-gate	  fitod	%f4, %d62
19877c478bd9Sstevel@tonic-gate	  fitod	%f5, %d62
19887c478bd9Sstevel@tonic-gate	  fitod	%f6, %d62
19897c478bd9Sstevel@tonic-gate	  fitod	%f7, %d62
19907c478bd9Sstevel@tonic-gate	  fitod	%f8, %d62
19917c478bd9Sstevel@tonic-gate	  fitod	%f9, %d62
19927c478bd9Sstevel@tonic-gate	  fitod	%f10, %d62
19937c478bd9Sstevel@tonic-gate	  fitod	%f11, %d62
19947c478bd9Sstevel@tonic-gate	  fitod	%f12, %d62
19957c478bd9Sstevel@tonic-gate	  fitod	%f13, %d62
19967c478bd9Sstevel@tonic-gate	  fitod	%f14, %d62
19977c478bd9Sstevel@tonic-gate	  fitod	%f15, %d62
19987c478bd9Sstevel@tonic-gate	  fitod	%f16, %d62
19997c478bd9Sstevel@tonic-gate	  fitod	%f17, %d62
20007c478bd9Sstevel@tonic-gate	  fitod	%f18, %d62
20017c478bd9Sstevel@tonic-gate	  fitod	%f19, %d62
20027c478bd9Sstevel@tonic-gate	  fitod	%f20, %d62
20037c478bd9Sstevel@tonic-gate	  fitod	%f21, %d62
20047c478bd9Sstevel@tonic-gate	  fitod	%f22, %d62
20057c478bd9Sstevel@tonic-gate	  fitod	%f23, %d62
20067c478bd9Sstevel@tonic-gate	  fitod	%f24, %d62
20077c478bd9Sstevel@tonic-gate	  fitod	%f25, %d62
20087c478bd9Sstevel@tonic-gate	  fitod	%f26, %d62
20097c478bd9Sstevel@tonic-gate	  fitod	%f27, %d62
20107c478bd9Sstevel@tonic-gate	  fitod	%f28, %d62
20117c478bd9Sstevel@tonic-gate	  fitod	%f29, %d62
20127c478bd9Sstevel@tonic-gate	  fitod	%f30, %d62
20137c478bd9Sstevel@tonic-gate	  fitod	%f31, %d62
20147c478bd9Sstevel@tonic-gate_fitos_fitod_done:
20157c478bd9Sstevel@tonic-gate
20167c478bd9Sstevel@tonic-gate	/*
20177c478bd9Sstevel@tonic-gate	 * Now convert data back into single precision
20187c478bd9Sstevel@tonic-gate	 */
20197c478bd9Sstevel@tonic-gate	srl	%g6, FITOS_RD_SHIFT, %g7
20207c478bd9Sstevel@tonic-gate	and	%g7, FITOS_REG_MASK, %g7
20217c478bd9Sstevel@tonic-gate	set	_fitos_fdtos_table, %g4
20227c478bd9Sstevel@tonic-gate	sllx	%g7, 2, %g7
20237c478bd9Sstevel@tonic-gate	jmp	%g4 + %g7
20247c478bd9Sstevel@tonic-gate	  ba,pt	%xcc, _fitos_fdtos_done
20257c478bd9Sstevel@tonic-gate	.empty
20267c478bd9Sstevel@tonic-gate
20277c478bd9Sstevel@tonic-gate_fitos_fdtos_table:
20287c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f0
20297c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f1
20307c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f2
20317c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f3
20327c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f4
20337c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f5
20347c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f6
20357c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f7
20367c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f8
20377c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f9
20387c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f10
20397c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f11
20407c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f12
20417c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f13
20427c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f14
20437c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f15
20447c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f16
20457c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f17
20467c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f18
20477c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f19
20487c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f20
20497c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f21
20507c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f22
20517c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f23
20527c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f24
20537c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f25
20547c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f26
20557c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f27
20567c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f28
20577c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f29
20587c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f30
20597c478bd9Sstevel@tonic-gate	  fdtos	%d62, %f31
20607c478bd9Sstevel@tonic-gate_fitos_fdtos_done:
20617c478bd9Sstevel@tonic-gate
20627c478bd9Sstevel@tonic-gate	ldd	[%g1 + CPU_TMP1], %d62		! restore %d62
20637c478bd9Sstevel@tonic-gate
20647c478bd9Sstevel@tonic-gate#if DEBUG
20657c478bd9Sstevel@tonic-gate	/*
20667c478bd9Sstevel@tonic-gate	 * Update FPop_unfinished trap kstat
20677c478bd9Sstevel@tonic-gate	 */
20687c478bd9Sstevel@tonic-gate	set	fpustat+FPUSTAT_UNFIN_KSTAT, %g7
20697c478bd9Sstevel@tonic-gate	ldx	[%g7], %g5
20707c478bd9Sstevel@tonic-gate1:
20717c478bd9Sstevel@tonic-gate	add	%g5, 1, %g6
20727c478bd9Sstevel@tonic-gate
20737c478bd9Sstevel@tonic-gate	casxa	[%g7] ASI_N, %g5, %g6
20747c478bd9Sstevel@tonic-gate	cmp	%g5, %g6
20757c478bd9Sstevel@tonic-gate	bne,a,pn %xcc, 1b
20767c478bd9Sstevel@tonic-gate	  or	%g0, %g6, %g5
20777c478bd9Sstevel@tonic-gate
20787c478bd9Sstevel@tonic-gate	/*
20797c478bd9Sstevel@tonic-gate	 * Update fpu_sim_fitos kstat
20807c478bd9Sstevel@tonic-gate	 */
20817c478bd9Sstevel@tonic-gate	set	fpuinfo+FPUINFO_FITOS_KSTAT, %g7
20827c478bd9Sstevel@tonic-gate	ldx	[%g7], %g5
20837c478bd9Sstevel@tonic-gate1:
20847c478bd9Sstevel@tonic-gate	add	%g5, 1, %g6
20857c478bd9Sstevel@tonic-gate
20867c478bd9Sstevel@tonic-gate	casxa	[%g7] ASI_N, %g5, %g6
20877c478bd9Sstevel@tonic-gate	cmp	%g5, %g6
20887c478bd9Sstevel@tonic-gate	bne,a,pn %xcc, 1b
20897c478bd9Sstevel@tonic-gate	  or	%g0, %g6, %g5
20907c478bd9Sstevel@tonic-gate#endif /* DEBUG */
20917c478bd9Sstevel@tonic-gate
20927c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
20937c478bd9Sstevel@tonic-gate
20947c478bd9Sstevel@tonic-gate.fp_exception_cont:
20957c478bd9Sstevel@tonic-gate	/*
20967c478bd9Sstevel@tonic-gate	 * Let _fp_exception deal with simulating FPop instruction.
20977c478bd9Sstevel@tonic-gate	 * Note that we need to pass %fsr in %g2 (already read above).
20987c478bd9Sstevel@tonic-gate	 */
20997c478bd9Sstevel@tonic-gate
21007c478bd9Sstevel@tonic-gate	set	_fp_exception, %g1
21017c478bd9Sstevel@tonic-gate	ba,pt	%xcc, sys_trap
21027c478bd9Sstevel@tonic-gate	sub	%g0, 1, %g4
21037c478bd9Sstevel@tonic-gate
210450eff769Smb158278	.global opl_cleanw_patch
210550eff769Smb158278opl_cleanw_patch:
21067c478bd9Sstevel@tonic-gate.clean_windows:
21077c478bd9Sstevel@tonic-gate	set	trap, %g1
21087c478bd9Sstevel@tonic-gate	mov	T_FLUSH_PCB, %g3
21097c478bd9Sstevel@tonic-gate	sub	%g0, 1, %g4
21107c478bd9Sstevel@tonic-gate	save
21117c478bd9Sstevel@tonic-gate	flushw
21127c478bd9Sstevel@tonic-gate	restore
21137c478bd9Sstevel@tonic-gate	wrpr	%g0, %g0, %cleanwin	! no clean windows
21147c478bd9Sstevel@tonic-gate
21157c478bd9Sstevel@tonic-gate	CPU_ADDR(%g4, %g5)
21167c478bd9Sstevel@tonic-gate	ldn	[%g4 + CPU_MPCB], %g4
21177c478bd9Sstevel@tonic-gate	brz,a,pn %g4, 1f
21187c478bd9Sstevel@tonic-gate	  nop
21197c478bd9Sstevel@tonic-gate	ld	[%g4 + MPCB_WSTATE], %g5
21207c478bd9Sstevel@tonic-gate	add	%g5, WSTATE_CLEAN_OFFSET, %g5
21217c478bd9Sstevel@tonic-gate	wrpr	%g0, %g5, %wstate
21227c478bd9Sstevel@tonic-gate1:	FAST_TRAP_DONE
21237c478bd9Sstevel@tonic-gate
21247c478bd9Sstevel@tonic-gate/*
21257c478bd9Sstevel@tonic-gate * .spill_clean: clean the previous window, restore the wstate, and
21267c478bd9Sstevel@tonic-gate * "done".
21277c478bd9Sstevel@tonic-gate *
21287c478bd9Sstevel@tonic-gate * Entry: %g7 contains new wstate
21297c478bd9Sstevel@tonic-gate */
21307c478bd9Sstevel@tonic-gate.spill_clean:
21317c478bd9Sstevel@tonic-gate	sethi	%hi(nwin_minus_one), %g5
21327c478bd9Sstevel@tonic-gate	ld	[%g5 + %lo(nwin_minus_one)], %g5 ! %g5 = nwin - 1
21337c478bd9Sstevel@tonic-gate	rdpr	%cwp, %g6			! %g6 = %cwp
21347c478bd9Sstevel@tonic-gate	deccc	%g6				! %g6--
21357c478bd9Sstevel@tonic-gate	movneg	%xcc, %g5, %g6			! if (%g6<0) %g6 = nwin-1
21367c478bd9Sstevel@tonic-gate	wrpr	%g6, %cwp
21377c478bd9Sstevel@tonic-gate	TT_TRACE_L(trace_win)
21387c478bd9Sstevel@tonic-gate	clr	%l0
21397c478bd9Sstevel@tonic-gate	clr	%l1
21407c478bd9Sstevel@tonic-gate	clr	%l2
21417c478bd9Sstevel@tonic-gate	clr	%l3
21427c478bd9Sstevel@tonic-gate	clr	%l4
21437c478bd9Sstevel@tonic-gate	clr	%l5
21447c478bd9Sstevel@tonic-gate	clr	%l6
21457c478bd9Sstevel@tonic-gate	clr	%l7
21467c478bd9Sstevel@tonic-gate	wrpr	%g0, %g7, %wstate
21477c478bd9Sstevel@tonic-gate	saved
21487c478bd9Sstevel@tonic-gate	retry			! restores correct %cwp
21497c478bd9Sstevel@tonic-gate
21507c478bd9Sstevel@tonic-gate.fix_alignment:
21517c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g2)		! load CPU struct addr to %g1 using %g2
21527c478bd9Sstevel@tonic-gate	ldn	[%g1 + CPU_THREAD], %g1	! load thread pointer
21537c478bd9Sstevel@tonic-gate	ldn	[%g1 + T_PROCP], %g1
21547c478bd9Sstevel@tonic-gate	mov	1, %g2
21557c478bd9Sstevel@tonic-gate	stb	%g2, [%g1 + P_FIXALIGNMENT]
21567c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
21577c478bd9Sstevel@tonic-gate
21587c478bd9Sstevel@tonic-gate#define	STDF_REG(REG, ADDR, TMP)		\
21597c478bd9Sstevel@tonic-gate	sll	REG, 3, REG			;\
21607c478bd9Sstevel@tonic-gatemark1:	set	start1, TMP			;\
21617c478bd9Sstevel@tonic-gate	jmp	REG + TMP			;\
21627c478bd9Sstevel@tonic-gate	  nop					;\
21637c478bd9Sstevel@tonic-gatestart1:	ba,pt	%xcc, done1			;\
21647c478bd9Sstevel@tonic-gate	  std	%f0, [ADDR + CPU_TMP1]		;\
21657c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21667c478bd9Sstevel@tonic-gate	  std	%f32, [ADDR + CPU_TMP1]		;\
21677c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21687c478bd9Sstevel@tonic-gate	  std	%f2, [ADDR + CPU_TMP1]		;\
21697c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21707c478bd9Sstevel@tonic-gate	  std	%f34, [ADDR + CPU_TMP1]		;\
21717c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21727c478bd9Sstevel@tonic-gate	  std	%f4, [ADDR + CPU_TMP1]		;\
21737c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21747c478bd9Sstevel@tonic-gate	  std	%f36, [ADDR + CPU_TMP1]		;\
21757c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21767c478bd9Sstevel@tonic-gate	  std	%f6, [ADDR + CPU_TMP1]		;\
21777c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21787c478bd9Sstevel@tonic-gate	  std	%f38, [ADDR + CPU_TMP1]		;\
21797c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21807c478bd9Sstevel@tonic-gate	  std	%f8, [ADDR + CPU_TMP1]		;\
21817c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21827c478bd9Sstevel@tonic-gate	  std	%f40, [ADDR + CPU_TMP1]		;\
21837c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21847c478bd9Sstevel@tonic-gate	  std	%f10, [ADDR + CPU_TMP1]		;\
21857c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21867c478bd9Sstevel@tonic-gate	  std	%f42, [ADDR + CPU_TMP1]		;\
21877c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21887c478bd9Sstevel@tonic-gate	  std	%f12, [ADDR + CPU_TMP1]		;\
21897c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21907c478bd9Sstevel@tonic-gate	  std	%f44, [ADDR + CPU_TMP1]		;\
21917c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21927c478bd9Sstevel@tonic-gate	  std	%f14, [ADDR + CPU_TMP1]		;\
21937c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21947c478bd9Sstevel@tonic-gate	  std	%f46, [ADDR + CPU_TMP1]		;\
21957c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21967c478bd9Sstevel@tonic-gate	  std	%f16, [ADDR + CPU_TMP1]		;\
21977c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
21987c478bd9Sstevel@tonic-gate	  std	%f48, [ADDR + CPU_TMP1]		;\
21997c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
22007c478bd9Sstevel@tonic-gate	  std	%f18, [ADDR + CPU_TMP1]		;\
22017c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
22027c478bd9Sstevel@tonic-gate	  std	%f50, [ADDR + CPU_TMP1]		;\
22037c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
22047c478bd9Sstevel@tonic-gate	  std	%f20, [ADDR + CPU_TMP1]		;\
22057c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
22067c478bd9Sstevel@tonic-gate	  std	%f52, [ADDR + CPU_TMP1]		;\
22077c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
22087c478bd9Sstevel@tonic-gate	  std	%f22, [ADDR + CPU_TMP1]		;\
22097c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
22107c478bd9Sstevel@tonic-gate	  std	%f54, [ADDR + CPU_TMP1]		;\
22117c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
22127c478bd9Sstevel@tonic-gate	  std	%f24, [ADDR + CPU_TMP1]		;\
22137c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
22147c478bd9Sstevel@tonic-gate	  std	%f56, [ADDR + CPU_TMP1]		;\
22157c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
22167c478bd9Sstevel@tonic-gate	  std	%f26, [ADDR + CPU_TMP1]		;\
22177c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
22187c478bd9Sstevel@tonic-gate	  std	%f58, [ADDR + CPU_TMP1]		;\
22197c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
22207c478bd9Sstevel@tonic-gate	  std	%f28, [ADDR + CPU_TMP1]		;\
22217c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
22227c478bd9Sstevel@tonic-gate	  std	%f60, [ADDR + CPU_TMP1]		;\
22237c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
22247c478bd9Sstevel@tonic-gate	  std	%f30, [ADDR + CPU_TMP1]		;\
22257c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done1			;\
22267c478bd9Sstevel@tonic-gate	  std	%f62, [ADDR + CPU_TMP1]		;\
22277c478bd9Sstevel@tonic-gatedone1:
22287c478bd9Sstevel@tonic-gate
22297c478bd9Sstevel@tonic-gate#define	LDDF_REG(REG, ADDR, TMP)		\
22307c478bd9Sstevel@tonic-gate	sll	REG, 3, REG			;\
22317c478bd9Sstevel@tonic-gatemark2:	set	start2, TMP			;\
22327c478bd9Sstevel@tonic-gate	jmp	REG + TMP			;\
22337c478bd9Sstevel@tonic-gate	  nop					;\
22347c478bd9Sstevel@tonic-gatestart2:	ba,pt	%xcc, done2			;\
22357c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f0		;\
22367c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22377c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f32		;\
22387c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22397c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f2		;\
22407c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22417c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f34		;\
22427c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22437c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f4		;\
22447c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22457c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f36		;\
22467c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22477c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f6		;\
22487c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22497c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f38		;\
22507c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22517c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f8		;\
22527c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22537c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f40		;\
22547c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22557c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f10		;\
22567c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22577c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f42		;\
22587c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22597c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f12		;\
22607c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22617c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f44		;\
22627c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22637c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f14		;\
22647c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22657c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f46		;\
22667c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22677c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f16		;\
22687c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22697c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f48		;\
22707c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22717c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f18		;\
22727c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22737c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f50		;\
22747c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22757c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f20		;\
22767c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22777c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f52		;\
22787c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22797c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f22		;\
22807c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22817c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f54		;\
22827c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22837c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f24		;\
22847c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22857c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f56		;\
22867c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22877c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f26		;\
22887c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22897c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f58		;\
22907c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22917c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f28		;\
22927c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22937c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f60		;\
22947c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22957c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f30		;\
22967c478bd9Sstevel@tonic-gate	ba,pt	%xcc, done2			;\
22977c478bd9Sstevel@tonic-gate	  ldd	[ADDR + CPU_TMP1], %f62		;\
22987c478bd9Sstevel@tonic-gatedone2:
22997c478bd9Sstevel@tonic-gate
23007c478bd9Sstevel@tonic-gate.lddf_exception_not_aligned:
23017c478bd9Sstevel@tonic-gate	/*
23027c478bd9Sstevel@tonic-gate	 * Cheetah overwrites SFAR on a DTLB miss, hence read it now.
23037c478bd9Sstevel@tonic-gate	 */
23047c478bd9Sstevel@tonic-gate	ldxa	[MMU_SFAR]%asi, %g5	! misaligned vaddr in %g5
23057c478bd9Sstevel@tonic-gate
23067c478bd9Sstevel@tonic-gate#if defined(DEBUG) || defined(NEED_FPU_EXISTS)
23077c478bd9Sstevel@tonic-gate	sethi	%hi(fpu_exists), %g2		! check fpu_exists
23087c478bd9Sstevel@tonic-gate	ld	[%g2 + %lo(fpu_exists)], %g2
23097c478bd9Sstevel@tonic-gate	brz,a,pn %g2, 4f
23107c478bd9Sstevel@tonic-gate	  nop
23117c478bd9Sstevel@tonic-gate#endif
23127c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)
23137c478bd9Sstevel@tonic-gate	or	%g0, 1, %g4
23147c478bd9Sstevel@tonic-gate	st	%g4, [%g1 + CPU_TL1_HDLR] ! set tl1_hdlr flag
23157c478bd9Sstevel@tonic-gate
23167c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g2
23177c478bd9Sstevel@tonic-gate	lda	[%g2]ASI_AIUP, %g6	! get the user's lddf instruction
23187c478bd9Sstevel@tonic-gate	srl	%g6, 23, %g1		! using ldda or not?
23197c478bd9Sstevel@tonic-gate	and	%g1, 1, %g1
23207c478bd9Sstevel@tonic-gate	brz,a,pt %g1, 2f		! check for ldda instruction
23217c478bd9Sstevel@tonic-gate	  nop
23227c478bd9Sstevel@tonic-gate	srl	%g6, 13, %g1		! check immflag
23237c478bd9Sstevel@tonic-gate	and	%g1, 1, %g1
23247c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g2		! %tstate in %g2
23257c478bd9Sstevel@tonic-gate	brnz,a,pn %g1, 1f
23267c478bd9Sstevel@tonic-gate	  srl	%g2, 31, %g1		! get asi from %tstate
23277c478bd9Sstevel@tonic-gate	srl	%g6, 5, %g1		! get asi from instruction
23287c478bd9Sstevel@tonic-gate	and	%g1, 0xFF, %g1		! imm_asi field
23297c478bd9Sstevel@tonic-gate1:
23307c478bd9Sstevel@tonic-gate	cmp	%g1, ASI_P		! primary address space
23317c478bd9Sstevel@tonic-gate	be,a,pt %icc, 2f
23327c478bd9Sstevel@tonic-gate	  nop
23337c478bd9Sstevel@tonic-gate	cmp	%g1, ASI_PNF		! primary no fault address space
23347c478bd9Sstevel@tonic-gate	be,a,pt %icc, 2f
23357c478bd9Sstevel@tonic-gate	  nop
23367c478bd9Sstevel@tonic-gate	cmp	%g1, ASI_S		! secondary address space
23377c478bd9Sstevel@tonic-gate	be,a,pt %icc, 2f
23387c478bd9Sstevel@tonic-gate	  nop
23397c478bd9Sstevel@tonic-gate	cmp	%g1, ASI_SNF		! secondary no fault address space
23407c478bd9Sstevel@tonic-gate	bne,a,pn %icc, 3f
23417c478bd9Sstevel@tonic-gate	  nop
23427c478bd9Sstevel@tonic-gate2:
23437c478bd9Sstevel@tonic-gate	lduwa	[%g5]ASI_USER, %g7	! get first half of misaligned data
23447c478bd9Sstevel@tonic-gate	add	%g5, 4, %g5		! increment misaligned data address
23457c478bd9Sstevel@tonic-gate	lduwa	[%g5]ASI_USER, %g5	! get second half of misaligned data
23467c478bd9Sstevel@tonic-gate
23477c478bd9Sstevel@tonic-gate	sllx	%g7, 32, %g7
23487c478bd9Sstevel@tonic-gate	or	%g5, %g7, %g5		! combine data
23497c478bd9Sstevel@tonic-gate	CPU_ADDR(%g7, %g1)		! save data on a per-cpu basis
23507c478bd9Sstevel@tonic-gate	stx	%g5, [%g7 + CPU_TMP1]	! save in cpu_tmp1
23517c478bd9Sstevel@tonic-gate
23527c478bd9Sstevel@tonic-gate	srl	%g6, 25, %g3		! %g6 has the instruction
23537c478bd9Sstevel@tonic-gate	and	%g3, 0x1F, %g3		! %g3 has rd
23547c478bd9Sstevel@tonic-gate	LDDF_REG(%g3, %g7, %g4)
23557c478bd9Sstevel@tonic-gate
23567c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)
23577c478bd9Sstevel@tonic-gate	st	%g0, [%g1 + CPU_TL1_HDLR] ! clear tl1_hdlr flag
23587c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
23597c478bd9Sstevel@tonic-gate3:
23607c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)
23617c478bd9Sstevel@tonic-gate	st	%g0, [%g1 + CPU_TL1_HDLR] ! clear tl1_hdlr flag
23627c478bd9Sstevel@tonic-gate4:
23637c478bd9Sstevel@tonic-gate	set	T_USER, %g3		! trap type in %g3
23647c478bd9Sstevel@tonic-gate	or	%g3, T_LDDF_ALIGN, %g3
23657c478bd9Sstevel@tonic-gate	mov	%g5, %g2		! misaligned vaddr in %g2
23667c478bd9Sstevel@tonic-gate	set	fpu_trap, %g1		! goto C for the little and
23677c478bd9Sstevel@tonic-gate	ba,pt	%xcc, sys_trap		! no fault little asi's
23687c478bd9Sstevel@tonic-gate	  sub	%g0, 1, %g4
23697c478bd9Sstevel@tonic-gate
23707c478bd9Sstevel@tonic-gate.stdf_exception_not_aligned:
23717c478bd9Sstevel@tonic-gate	/*
23727c478bd9Sstevel@tonic-gate	 * Cheetah overwrites SFAR on a DTLB miss, hence read it now.
23737c478bd9Sstevel@tonic-gate	 */
23747c478bd9Sstevel@tonic-gate	ldxa	[MMU_SFAR]%asi, %g5	! misaligned vaddr in %g5
23757c478bd9Sstevel@tonic-gate
23767c478bd9Sstevel@tonic-gate#if defined(DEBUG) || defined(NEED_FPU_EXISTS)
23777c478bd9Sstevel@tonic-gate	sethi	%hi(fpu_exists), %g7		! check fpu_exists
23787c478bd9Sstevel@tonic-gate	ld	[%g7 + %lo(fpu_exists)], %g3
23797c478bd9Sstevel@tonic-gate	brz,a,pn %g3, 4f
23807c478bd9Sstevel@tonic-gate	  nop
23817c478bd9Sstevel@tonic-gate#endif
23827c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)
23837c478bd9Sstevel@tonic-gate	or	%g0, 1, %g4
23847c478bd9Sstevel@tonic-gate	st	%g4, [%g1 + CPU_TL1_HDLR] ! set tl1_hdlr flag
23857c478bd9Sstevel@tonic-gate
23867c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g2
23877c478bd9Sstevel@tonic-gate	lda	[%g2]ASI_AIUP, %g6	! get the user's stdf instruction
23887c478bd9Sstevel@tonic-gate
23897c478bd9Sstevel@tonic-gate	srl	%g6, 23, %g1		! using stda or not?
23907c478bd9Sstevel@tonic-gate	and	%g1, 1, %g1
23917c478bd9Sstevel@tonic-gate	brz,a,pt %g1, 2f		! check for stda instruction
23927c478bd9Sstevel@tonic-gate	  nop
23937c478bd9Sstevel@tonic-gate	srl	%g6, 13, %g1		! check immflag
23947c478bd9Sstevel@tonic-gate	and	%g1, 1, %g1
23957c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g2		! %tstate in %g2
23967c478bd9Sstevel@tonic-gate	brnz,a,pn %g1, 1f
23977c478bd9Sstevel@tonic-gate	  srl	%g2, 31, %g1		! get asi from %tstate
23987c478bd9Sstevel@tonic-gate	srl	%g6, 5, %g1		! get asi from instruction
23997c478bd9Sstevel@tonic-gate	and	%g1, 0xFF, %g1		! imm_asi field
24007c478bd9Sstevel@tonic-gate1:
24017c478bd9Sstevel@tonic-gate	cmp	%g1, ASI_P		! primary address space
24027c478bd9Sstevel@tonic-gate	be,a,pt %icc, 2f
24037c478bd9Sstevel@tonic-gate	  nop
24047c478bd9Sstevel@tonic-gate	cmp	%g1, ASI_S		! secondary address space
24057c478bd9Sstevel@tonic-gate	bne,a,pn %icc, 3f
24067c478bd9Sstevel@tonic-gate	  nop
24077c478bd9Sstevel@tonic-gate2:
24087c478bd9Sstevel@tonic-gate	srl	%g6, 25, %g6
24097c478bd9Sstevel@tonic-gate	and	%g6, 0x1F, %g6		! %g6 has rd
24107c478bd9Sstevel@tonic-gate	CPU_ADDR(%g7, %g1)
24117c478bd9Sstevel@tonic-gate	STDF_REG(%g6, %g7, %g4)		! STDF_REG(REG, ADDR, TMP)
24127c478bd9Sstevel@tonic-gate
24137c478bd9Sstevel@tonic-gate	ldx	[%g7 + CPU_TMP1], %g6
24147c478bd9Sstevel@tonic-gate	srlx	%g6, 32, %g7
24157c478bd9Sstevel@tonic-gate	stuwa	%g7, [%g5]ASI_USER	! first half
24167c478bd9Sstevel@tonic-gate	add	%g5, 4, %g5		! increment misaligned data address
24177c478bd9Sstevel@tonic-gate	stuwa	%g6, [%g5]ASI_USER	! second half
24187c478bd9Sstevel@tonic-gate
24197c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)
24207c478bd9Sstevel@tonic-gate	st	%g0, [%g1 + CPU_TL1_HDLR] ! clear tl1_hdlr flag
24217c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
24227c478bd9Sstevel@tonic-gate3:
24237c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g4)
24247c478bd9Sstevel@tonic-gate	st	%g0, [%g1 + CPU_TL1_HDLR] ! clear tl1_hdlr flag
24257c478bd9Sstevel@tonic-gate4:
24267c478bd9Sstevel@tonic-gate	set	T_USER, %g3		! trap type in %g3
24277c478bd9Sstevel@tonic-gate	or	%g3, T_STDF_ALIGN, %g3
24287c478bd9Sstevel@tonic-gate	mov	%g5, %g2		! misaligned vaddr in %g2
24297c478bd9Sstevel@tonic-gate	set	fpu_trap, %g1		! goto C for the little and
24307c478bd9Sstevel@tonic-gate	ba,pt	%xcc, sys_trap		! nofault little asi's
24317c478bd9Sstevel@tonic-gate	  sub	%g0, 1, %g4
24327c478bd9Sstevel@tonic-gate
24337c478bd9Sstevel@tonic-gate#ifdef DEBUG_USER_TRAPTRACECTL
24347c478bd9Sstevel@tonic-gate
24357c478bd9Sstevel@tonic-gate.traptrace_freeze:
24367c478bd9Sstevel@tonic-gate	mov	%l0, %g1 ; mov	%l1, %g2 ; mov	%l2, %g3 ; mov	%l4, %g4
24377c478bd9Sstevel@tonic-gate	TT_TRACE_L(trace_win)
24387c478bd9Sstevel@tonic-gate	mov	%g4, %l4 ; mov	%g3, %l2 ; mov	%g2, %l1 ; mov	%g1, %l0
24397c478bd9Sstevel@tonic-gate	set	trap_freeze, %g1
24407c478bd9Sstevel@tonic-gate	mov	1, %g2
24417c478bd9Sstevel@tonic-gate	st	%g2, [%g1]
24427c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
24437c478bd9Sstevel@tonic-gate
24447c478bd9Sstevel@tonic-gate.traptrace_unfreeze:
24457c478bd9Sstevel@tonic-gate	set	trap_freeze, %g1
24467c478bd9Sstevel@tonic-gate	st	%g0, [%g1]
24477c478bd9Sstevel@tonic-gate	mov	%l0, %g1 ; mov	%l1, %g2 ; mov	%l2, %g3 ; mov	%l4, %g4
24487c478bd9Sstevel@tonic-gate	TT_TRACE_L(trace_win)
24497c478bd9Sstevel@tonic-gate	mov	%g4, %l4 ; mov	%g3, %l2 ; mov	%g2, %l1 ; mov	%g1, %l0
24507c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
24517c478bd9Sstevel@tonic-gate
24527c478bd9Sstevel@tonic-gate#endif /* DEBUG_USER_TRAPTRACECTL */
24537c478bd9Sstevel@tonic-gate
24547c478bd9Sstevel@tonic-gate.getcc:
24557c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g2)
24567c478bd9Sstevel@tonic-gate	stx	%o0, [%g1 + CPU_TMP1]		! save %o0
24577c478bd9Sstevel@tonic-gate	stx	%o1, [%g1 + CPU_TMP2]		! save %o1
24587c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g3			! get tstate
24597c478bd9Sstevel@tonic-gate	srlx	%g3, PSR_TSTATE_CC_SHIFT, %o0	! shift ccr to V8 psr
24607c478bd9Sstevel@tonic-gate	set	PSR_ICC, %g2
24617c478bd9Sstevel@tonic-gate	and	%o0, %g2, %o0			! mask out the rest
24627c478bd9Sstevel@tonic-gate	srl	%o0, PSR_ICC_SHIFT, %o0		! right justify
24637c478bd9Sstevel@tonic-gate	rdpr	%pstate, %o1
24647c478bd9Sstevel@tonic-gate	wrpr	%o1, PSTATE_AG, %pstate		! get into normal globals
24657c478bd9Sstevel@tonic-gate	mov	%o0, %g1			! move ccr to normal %g1
24667c478bd9Sstevel@tonic-gate	wrpr	%g0, %o1, %pstate		! back into alternate globals
24677c478bd9Sstevel@tonic-gate	ldx	[%g1 + CPU_TMP1], %o0		! restore %o0
24687c478bd9Sstevel@tonic-gate	ldx	[%g1 + CPU_TMP2], %o1		! restore %o1
24697c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
24707c478bd9Sstevel@tonic-gate
24717c478bd9Sstevel@tonic-gate.setcc:
24727c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g2)
24737c478bd9Sstevel@tonic-gate	stx	%o0, [%g1 + CPU_TMP1]		! save %o0
24747c478bd9Sstevel@tonic-gate	stx	%o1, [%g1 + CPU_TMP2]		! save %o1
24757c478bd9Sstevel@tonic-gate	rdpr	%pstate, %o0
24767c478bd9Sstevel@tonic-gate	wrpr	%o0, PSTATE_AG, %pstate		! get into normal globals
24777c478bd9Sstevel@tonic-gate	mov	%g1, %o1
24787c478bd9Sstevel@tonic-gate	wrpr	%g0, %o0, %pstate		! back to alternates
24797c478bd9Sstevel@tonic-gate	sll	%o1, PSR_ICC_SHIFT, %g2
24807c478bd9Sstevel@tonic-gate	set	PSR_ICC, %g3
24817c478bd9Sstevel@tonic-gate	and	%g2, %g3, %g2			! mask out rest
24827c478bd9Sstevel@tonic-gate	sllx	%g2, PSR_TSTATE_CC_SHIFT, %g2
24837c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g3			! get tstate
24847c478bd9Sstevel@tonic-gate	srl	%g3, 0, %g3			! clear upper word
24857c478bd9Sstevel@tonic-gate	or	%g3, %g2, %g3			! or in new bits
24867c478bd9Sstevel@tonic-gate	wrpr	%g3, %tstate
24877c478bd9Sstevel@tonic-gate	ldx	[%g1 + CPU_TMP1], %o0		! restore %o0
24887c478bd9Sstevel@tonic-gate	ldx	[%g1 + CPU_TMP2], %o1		! restore %o1
24897c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
24907c478bd9Sstevel@tonic-gate
24917c478bd9Sstevel@tonic-gate/*
24927c478bd9Sstevel@tonic-gate * getpsr(void)
24937c478bd9Sstevel@tonic-gate * Note that the xcc part of the ccr is not provided.
24947c478bd9Sstevel@tonic-gate * The V8 code shows why the V9 trap is not faster:
24957c478bd9Sstevel@tonic-gate * #define GETPSR_TRAP() \
24967c478bd9Sstevel@tonic-gate *      mov %psr, %i0; jmp %l2; rett %l2+4; nop;
24977c478bd9Sstevel@tonic-gate */
24987c478bd9Sstevel@tonic-gate
24997c478bd9Sstevel@tonic-gate	.type	.getpsr, #function
25007c478bd9Sstevel@tonic-gate.getpsr:
25017c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g1			! get tstate
25027c478bd9Sstevel@tonic-gate	srlx	%g1, PSR_TSTATE_CC_SHIFT, %o0	! shift ccr to V8 psr
25037c478bd9Sstevel@tonic-gate	set	PSR_ICC, %g2
25047c478bd9Sstevel@tonic-gate	and	%o0, %g2, %o0			! mask out the rest
25057c478bd9Sstevel@tonic-gate
25067c478bd9Sstevel@tonic-gate	rd	%fprs, %g1			! get fprs
25077c478bd9Sstevel@tonic-gate	and	%g1, FPRS_FEF, %g2		! mask out dirty upper/lower
25087c478bd9Sstevel@tonic-gate	sllx	%g2, PSR_FPRS_FEF_SHIFT, %g2	! shift fef to V8 psr.ef
25097c478bd9Sstevel@tonic-gate	or	%o0, %g2, %o0			! or result into psr.ef
25107c478bd9Sstevel@tonic-gate
25117c478bd9Sstevel@tonic-gate	set	V9_PSR_IMPLVER, %g2		! SI assigned impl/ver: 0xef
25127c478bd9Sstevel@tonic-gate	or	%o0, %g2, %o0			! or psr.impl/ver
25137c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
25147c478bd9Sstevel@tonic-gate	SET_SIZE(.getpsr)
25157c478bd9Sstevel@tonic-gate
25167c478bd9Sstevel@tonic-gate/*
25177c478bd9Sstevel@tonic-gate * setpsr(newpsr)
25187c478bd9Sstevel@tonic-gate * Note that there is no support for ccr.xcc in the V9 code.
25197c478bd9Sstevel@tonic-gate */
25207c478bd9Sstevel@tonic-gate
25217c478bd9Sstevel@tonic-gate	.type	.setpsr, #function
25227c478bd9Sstevel@tonic-gate.setpsr:
25237c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g1			! get tstate
25247c478bd9Sstevel@tonic-gate!	setx	TSTATE_V8_UBITS, %g2
25257c478bd9Sstevel@tonic-gate	or 	%g0, CCR_ICC, %g3
25267c478bd9Sstevel@tonic-gate	sllx	%g3, TSTATE_CCR_SHIFT, %g2
25277c478bd9Sstevel@tonic-gate
25287c478bd9Sstevel@tonic-gate	andn	%g1, %g2, %g1			! zero current user bits
25297c478bd9Sstevel@tonic-gate	set	PSR_ICC, %g2
25307c478bd9Sstevel@tonic-gate	and	%g2, %o0, %g2			! clear all but psr.icc bits
25317c478bd9Sstevel@tonic-gate	sllx	%g2, PSR_TSTATE_CC_SHIFT, %g3	! shift to tstate.ccr.icc
25327c478bd9Sstevel@tonic-gate	wrpr	%g1, %g3, %tstate		! write tstate
25337c478bd9Sstevel@tonic-gate
25347c478bd9Sstevel@tonic-gate	set	PSR_EF, %g2
25357c478bd9Sstevel@tonic-gate	and	%g2, %o0, %g2			! clear all but fp enable bit
25367c478bd9Sstevel@tonic-gate	srlx	%g2, PSR_FPRS_FEF_SHIFT, %g4	! shift ef to V9 fprs.fef
25377c478bd9Sstevel@tonic-gate	wr	%g0, %g4, %fprs			! write fprs
25387c478bd9Sstevel@tonic-gate
25397c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g2)			! load CPU struct addr to %g1
25407c478bd9Sstevel@tonic-gate	ldn	[%g1 + CPU_THREAD], %g2		! load thread pointer
25417c478bd9Sstevel@tonic-gate	ldn	[%g2 + T_LWP], %g3		! load klwp pointer
25427c478bd9Sstevel@tonic-gate	ldn	[%g3 + LWP_FPU], %g2		! get lwp_fpu pointer
25437c478bd9Sstevel@tonic-gate	stuw	%g4, [%g2 + FPU_FPRS]		! write fef value to fpu_fprs
25447c478bd9Sstevel@tonic-gate	srlx	%g4, 2, %g4			! shift fef value to bit 0
25457c478bd9Sstevel@tonic-gate	stub	%g4, [%g2 + FPU_EN]		! write fef value to fpu_en
25467c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
25477c478bd9Sstevel@tonic-gate	SET_SIZE(.setpsr)
25487c478bd9Sstevel@tonic-gate
25497c478bd9Sstevel@tonic-gate/*
25507c478bd9Sstevel@tonic-gate * getlgrp
25517c478bd9Sstevel@tonic-gate * get home lgrpid on which the calling thread is currently executing.
25527c478bd9Sstevel@tonic-gate */
25537c478bd9Sstevel@tonic-gate	.type	.getlgrp, #function
25547c478bd9Sstevel@tonic-gate.getlgrp:
25557c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g2)		! load CPU struct addr to %g1 using %g2
25567c478bd9Sstevel@tonic-gate	ld	[%g1 + CPU_ID], %o0	! load cpu_id
25577c478bd9Sstevel@tonic-gate	ldn	[%g1 + CPU_THREAD], %g2	! load thread pointer
25587c478bd9Sstevel@tonic-gate	ldn	[%g2 + T_LPL], %g2	! load lpl pointer
25597c478bd9Sstevel@tonic-gate	ld	[%g2 + LPL_LGRPID], %g1	! load lpl_lgrpid
25607c478bd9Sstevel@tonic-gate	sra	%g1, 0, %o1
25617c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
25627c478bd9Sstevel@tonic-gate	SET_SIZE(.getlgrp)
25637c478bd9Sstevel@tonic-gate
25647c478bd9Sstevel@tonic-gate/*
25657c478bd9Sstevel@tonic-gate * Entry for old 4.x trap (trap 0).
25667c478bd9Sstevel@tonic-gate */
25677c478bd9Sstevel@tonic-gate	ENTRY_NP(syscall_trap_4x)
25687c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g2)		! load CPU struct addr to %g1 using %g2
25697c478bd9Sstevel@tonic-gate	ldn	[%g1 + CPU_THREAD], %g2	! load thread pointer
25707c478bd9Sstevel@tonic-gate	ldn	[%g2 + T_LWP], %g2	! load klwp pointer
25717c478bd9Sstevel@tonic-gate	ld	[%g2 + PCB_TRAP0], %g2	! lwp->lwp_pcb.pcb_trap0addr
25727c478bd9Sstevel@tonic-gate	brz,pn	%g2, 1f			! has it been set?
25737c478bd9Sstevel@tonic-gate	st	%l0, [%g1 + CPU_TMP1]	! delay - save some locals
25747c478bd9Sstevel@tonic-gate	st	%l1, [%g1 + CPU_TMP2]
25757c478bd9Sstevel@tonic-gate	rdpr	%tnpc, %l1		! save old tnpc
25767c478bd9Sstevel@tonic-gate	wrpr	%g0, %g2, %tnpc		! setup tnpc
25777c478bd9Sstevel@tonic-gate
25787c478bd9Sstevel@tonic-gate	rdpr	%pstate, %l0
25797c478bd9Sstevel@tonic-gate	wrpr	%l0, PSTATE_AG, %pstate	! switch to normal globals
25807c478bd9Sstevel@tonic-gate	mov	%l1, %g6		! pass tnpc to user code in %g6
25817c478bd9Sstevel@tonic-gate	wrpr	%l0, %g0, %pstate	! switch back to alternate globals
25827c478bd9Sstevel@tonic-gate
25837c478bd9Sstevel@tonic-gate	! Note that %g1 still contains CPU struct addr
25847c478bd9Sstevel@tonic-gate	ld	[%g1 + CPU_TMP2], %l1	! restore locals
25857c478bd9Sstevel@tonic-gate	ld	[%g1 + CPU_TMP1], %l0
25867c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE_CHK_INTR
25877c478bd9Sstevel@tonic-gate1:
25887c478bd9Sstevel@tonic-gate	mov	%g1, %l0
25897c478bd9Sstevel@tonic-gate	st	%l1, [%g1 + CPU_TMP2]
25907c478bd9Sstevel@tonic-gate	rdpr	%pstate, %l1
25917c478bd9Sstevel@tonic-gate	wrpr	%l1, PSTATE_AG, %pstate
25927c478bd9Sstevel@tonic-gate	!
25937c478bd9Sstevel@tonic-gate	! check for old syscall mmap which is the only different one which
25947c478bd9Sstevel@tonic-gate	! must be the same.  Others are handled in the compatibility library.
25957c478bd9Sstevel@tonic-gate	!
25967c478bd9Sstevel@tonic-gate	cmp	%g1, OSYS_mmap	! compare to old 4.x mmap
25977c478bd9Sstevel@tonic-gate	movz	%icc, SYS_mmap, %g1
25987c478bd9Sstevel@tonic-gate	wrpr	%g0, %l1, %pstate
25997c478bd9Sstevel@tonic-gate	ld	[%l0 + CPU_TMP2], %l1	! restore locals
26007c478bd9Sstevel@tonic-gate	ld	[%l0 + CPU_TMP1], %l0
26017c478bd9Sstevel@tonic-gate	SYSCALL(syscall_trap32)
26027c478bd9Sstevel@tonic-gate	SET_SIZE(syscall_trap_4x)
26037c478bd9Sstevel@tonic-gate
26047c478bd9Sstevel@tonic-gate/*
26057c478bd9Sstevel@tonic-gate * Handler for software trap 9.
26067c478bd9Sstevel@tonic-gate * Set trap0 emulation address for old 4.x system call trap.
26077c478bd9Sstevel@tonic-gate * XXX - this should be a system call.
26087c478bd9Sstevel@tonic-gate */
26097c478bd9Sstevel@tonic-gate	ENTRY_NP(set_trap0_addr)
26107c478bd9Sstevel@tonic-gate	CPU_ADDR(%g1, %g2)		! load CPU struct addr to %g1 using %g2
26117c478bd9Sstevel@tonic-gate	ldn	[%g1 + CPU_THREAD], %g2	! load thread pointer
26127c478bd9Sstevel@tonic-gate	ldn	[%g2 + T_LWP], %g2	! load klwp pointer
26137c478bd9Sstevel@tonic-gate	st	%l0, [%g1 + CPU_TMP1]	! save some locals
26147c478bd9Sstevel@tonic-gate	st	%l1, [%g1 + CPU_TMP2]
26157c478bd9Sstevel@tonic-gate	rdpr	%pstate, %l0
26167c478bd9Sstevel@tonic-gate	wrpr	%l0, PSTATE_AG, %pstate
26177c478bd9Sstevel@tonic-gate	mov	%g1, %l1
26187c478bd9Sstevel@tonic-gate	wrpr	%g0, %l0, %pstate
26197c478bd9Sstevel@tonic-gate	andn	%l1, 3, %l1		! force alignment
26207c478bd9Sstevel@tonic-gate	st	%l1, [%g2 + PCB_TRAP0]	! lwp->lwp_pcb.pcb_trap0addr
26217c478bd9Sstevel@tonic-gate	ld	[%g1 + CPU_TMP1], %l0	! restore locals
26227c478bd9Sstevel@tonic-gate	ld	[%g1 + CPU_TMP2], %l1
26237c478bd9Sstevel@tonic-gate	FAST_TRAP_DONE
26247c478bd9Sstevel@tonic-gate	SET_SIZE(set_trap0_addr)
26257c478bd9Sstevel@tonic-gate
26267c478bd9Sstevel@tonic-gate/*
26277c478bd9Sstevel@tonic-gate * mmu_trap_tl1
26287c478bd9Sstevel@tonic-gate * trap handler for unexpected mmu traps.
26297c478bd9Sstevel@tonic-gate * simply checks if the trap was a user lddf/stdf alignment trap, in which
26307c478bd9Sstevel@tonic-gate * case we go to fpu_trap or a user trap from the window handler, in which
26317c478bd9Sstevel@tonic-gate * case we go save the state on the pcb.  Otherwise, we go to ptl1_panic.
26327c478bd9Sstevel@tonic-gate */
26337c478bd9Sstevel@tonic-gate	.type	mmu_trap_tl1, #function
26347c478bd9Sstevel@tonic-gatemmu_trap_tl1:
26357c478bd9Sstevel@tonic-gate#ifdef	TRAPTRACE
26367c478bd9Sstevel@tonic-gate	TRACE_PTR(%g5, %g6)
2637*023e71deSHaik Aftandilian	GET_TRACE_TICK(%g6, %g7)
26387c478bd9Sstevel@tonic-gate	stxa	%g6, [%g5 + TRAP_ENT_TICK]%asi
26397c478bd9Sstevel@tonic-gate	rdpr	%tl, %g6
26407c478bd9Sstevel@tonic-gate	stha	%g6, [%g5 + TRAP_ENT_TL]%asi
26417c478bd9Sstevel@tonic-gate	rdpr	%tt, %g6
26427c478bd9Sstevel@tonic-gate	stha	%g6, [%g5 + TRAP_ENT_TT]%asi
26437c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g6
26447c478bd9Sstevel@tonic-gate	stxa	%g6, [%g5 + TRAP_ENT_TSTATE]%asi
26457c478bd9Sstevel@tonic-gate	stna	%sp, [%g5 + TRAP_ENT_SP]%asi
26467c478bd9Sstevel@tonic-gate	stna	%g0, [%g5 + TRAP_ENT_TR]%asi
26477c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g6
26487c478bd9Sstevel@tonic-gate	stna	%g6, [%g5 + TRAP_ENT_TPC]%asi
26497c478bd9Sstevel@tonic-gate	set	MMU_SFAR, %g6
26507c478bd9Sstevel@tonic-gate	ldxa	[%g6]ASI_DMMU, %g6
26517c478bd9Sstevel@tonic-gate	stxa	%g6, [%g5 + TRAP_ENT_F1]%asi
26527c478bd9Sstevel@tonic-gate	CPU_PADDR(%g7, %g6);
26537c478bd9Sstevel@tonic-gate	add	%g7, CPU_TL1_HDLR, %g7
26547c478bd9Sstevel@tonic-gate	lda	[%g7]ASI_MEM, %g6
26557c478bd9Sstevel@tonic-gate	stxa	%g6, [%g5 + TRAP_ENT_F2]%asi
26567c478bd9Sstevel@tonic-gate	set	0xdeadbeef, %g6
26577c478bd9Sstevel@tonic-gate	stna	%g6, [%g5 + TRAP_ENT_F3]%asi
26587c478bd9Sstevel@tonic-gate	stna	%g6, [%g5 + TRAP_ENT_F4]%asi
26597c478bd9Sstevel@tonic-gate	TRACE_NEXT(%g5, %g6, %g7)
26607c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */
26617c478bd9Sstevel@tonic-gate
26627c478bd9Sstevel@tonic-gate	GET_CPU_IMPL(%g5)
26637c478bd9Sstevel@tonic-gate	cmp	%g5, PANTHER_IMPL
26647c478bd9Sstevel@tonic-gate	bne	mmu_trap_tl1_4
26657c478bd9Sstevel@tonic-gate	  nop
26667c478bd9Sstevel@tonic-gate	rdpr	%tt, %g5
26677c478bd9Sstevel@tonic-gate	cmp	%g5, T_DATA_EXCEPTION
26687c478bd9Sstevel@tonic-gate	bne	mmu_trap_tl1_4
26697c478bd9Sstevel@tonic-gate	  nop
26707c478bd9Sstevel@tonic-gate	wr	%g0, ASI_DMMU, %asi
26717c478bd9Sstevel@tonic-gate	ldxa	[MMU_SFSR]%asi, %g5
26727c478bd9Sstevel@tonic-gate	mov	1, %g6
26737c478bd9Sstevel@tonic-gate	sllx	%g6, PN_SFSR_PARITY_SHIFT, %g6
26747c478bd9Sstevel@tonic-gate	andcc	%g5, %g6, %g0
26757c478bd9Sstevel@tonic-gate	bz	mmu_trap_tl1_4
26767c478bd9Sstevel@tonic-gate
26777c478bd9Sstevel@tonic-gate	/*
26787c478bd9Sstevel@tonic-gate	 * We are running on a Panther and have hit a DTLB parity error.
26797c478bd9Sstevel@tonic-gate	 */
26807c478bd9Sstevel@tonic-gate	ldxa	[MMU_TAG_ACCESS]%asi, %g2
26817c478bd9Sstevel@tonic-gate	mov	%g5, %g3
26827c478bd9Sstevel@tonic-gate	ba,pt	%xcc, .mmu_exception_is_tlb_parity
26837c478bd9Sstevel@tonic-gate	mov	T_DATA_EXCEPTION, %g1
26847c478bd9Sstevel@tonic-gate
26857c478bd9Sstevel@tonic-gatemmu_trap_tl1_4:
26867c478bd9Sstevel@tonic-gate	CPU_PADDR(%g7, %g6);
26877c478bd9Sstevel@tonic-gate	add     %g7, CPU_TL1_HDLR, %g7		! %g7 = &cpu_m.tl1_hdlr (PA)
26887c478bd9Sstevel@tonic-gate	/*
26897c478bd9Sstevel@tonic-gate	 * AM is cleared on trap, so addresses are 64 bit
26907c478bd9Sstevel@tonic-gate	 */
26917c478bd9Sstevel@tonic-gate	lda     [%g7]ASI_MEM, %g6
26927c478bd9Sstevel@tonic-gate	brz,a,pt %g6, 1f
26937c478bd9Sstevel@tonic-gate	  nop
26947c478bd9Sstevel@tonic-gate	/*
26957c478bd9Sstevel@tonic-gate	 * We are going to update cpu_m.tl1_hdlr using physical address.
26967c478bd9Sstevel@tonic-gate	 * Flush the D$ line, so that stale data won't be accessed later.
26977c478bd9Sstevel@tonic-gate	 */
26987c478bd9Sstevel@tonic-gate	CPU_ADDR(%g6, %g5)
26997c478bd9Sstevel@tonic-gate	add     %g6, CPU_TL1_HDLR, %g6		! %g6 = &cpu_m.tl1_hdlr (VA)
27007c478bd9Sstevel@tonic-gate	GET_CPU_IMPL(%g5)
27017c478bd9Sstevel@tonic-gate	cmp	%g5, CHEETAH_IMPL
270225cf1a30Sjl139090	bl,pt	%icc, 3f
270325cf1a30Sjl139090	 cmp	%g5, SPITFIRE_IMPL
27047c478bd9Sstevel@tonic-gate	stxa	%g0, [%g7]ASI_DC_INVAL
27057c478bd9Sstevel@tonic-gate	membar	#Sync
27067c478bd9Sstevel@tonic-gate	ba,pt	%xcc, 2f
27077c478bd9Sstevel@tonic-gate	 nop
27087c478bd9Sstevel@tonic-gate3:
270925cf1a30Sjl139090	bl,pt	%icc, 2f
271025cf1a30Sjl139090	 sethi	%hi(dcache_line_mask), %g5
27117c478bd9Sstevel@tonic-gate	ld	[%g5 + %lo(dcache_line_mask)], %g5
27127c478bd9Sstevel@tonic-gate	and	%g6, %g5, %g5
27137c478bd9Sstevel@tonic-gate	stxa	%g0, [%g5]ASI_DC_TAG
27147c478bd9Sstevel@tonic-gate	membar	#Sync
27157c478bd9Sstevel@tonic-gate2:
27167c478bd9Sstevel@tonic-gate	sta     %g0, [%g7]ASI_MEM
27177c478bd9Sstevel@tonic-gate	SWITCH_GLOBALS				! back to mmu globals
27187c478bd9Sstevel@tonic-gate	ba,a,pt	%xcc, sfmmu_mmu_trap		! handle page faults
27197c478bd9Sstevel@tonic-gate1:
27207c478bd9Sstevel@tonic-gate	rdpr	%tt, %g5
27217c478bd9Sstevel@tonic-gate	rdpr	%tl, %g7
27227c478bd9Sstevel@tonic-gate	sub	%g7, 1, %g6
27237c478bd9Sstevel@tonic-gate	wrpr	%g6, %tl
27247c478bd9Sstevel@tonic-gate	rdpr	%tt, %g6
27257c478bd9Sstevel@tonic-gate	wrpr	%g7, %tl
27267c478bd9Sstevel@tonic-gate	and	%g6, WTRAP_TTMASK, %g6
27277c478bd9Sstevel@tonic-gate	cmp	%g6, WTRAP_TYPE
27287c478bd9Sstevel@tonic-gate	bne,a,pn %xcc, ptl1_panic
27297c478bd9Sstevel@tonic-gate	mov	PTL1_BAD_MMUTRAP, %g1
27307c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g7
27317c478bd9Sstevel@tonic-gate	/* tpc should be in the trap table */
27327c478bd9Sstevel@tonic-gate	set	trap_table, %g6
27337c478bd9Sstevel@tonic-gate	cmp	%g7, %g6
27347c478bd9Sstevel@tonic-gate	blt,a,pn %xcc, ptl1_panic
27357c478bd9Sstevel@tonic-gate	  mov	PTL1_BAD_MMUTRAP, %g1
27367c478bd9Sstevel@tonic-gate	set	etrap_table, %g6
27377c478bd9Sstevel@tonic-gate	cmp	%g7, %g6
27387c478bd9Sstevel@tonic-gate	bge,a,pn %xcc, ptl1_panic
27397c478bd9Sstevel@tonic-gate	  mov	PTL1_BAD_MMUTRAP, %g1
27407c478bd9Sstevel@tonic-gate	cmp	%g5, T_ALIGNMENT
27417c478bd9Sstevel@tonic-gate	move	%icc, MMU_SFAR, %g6
27427c478bd9Sstevel@tonic-gate	movne	%icc, MMU_TAG_ACCESS, %g6
27437c478bd9Sstevel@tonic-gate	ldxa	[%g6]ASI_DMMU, %g6
27447c478bd9Sstevel@tonic-gate	andn	%g7, WTRAP_ALIGN, %g7	/* 128 byte aligned */
27457c478bd9Sstevel@tonic-gate	add	%g7, WTRAP_FAULTOFF, %g7
27467c478bd9Sstevel@tonic-gate	wrpr	%g0, %g7, %tnpc
27477c478bd9Sstevel@tonic-gate	done
27487c478bd9Sstevel@tonic-gate	SET_SIZE(mmu_trap_tl1)
27497c478bd9Sstevel@tonic-gate
27507c478bd9Sstevel@tonic-gate/*
27517c478bd9Sstevel@tonic-gate * Several traps use kmdb_trap and kmdb_trap_tl1 as their handlers.  These
27527c478bd9Sstevel@tonic-gate * traps are valid only when kmdb is loaded.  When the debugger is active,
27537c478bd9Sstevel@tonic-gate * the code below is rewritten to transfer control to the appropriate
27547c478bd9Sstevel@tonic-gate * debugger entry points.
27557c478bd9Sstevel@tonic-gate */
27567c478bd9Sstevel@tonic-gate	.global	kmdb_trap
27577c478bd9Sstevel@tonic-gate	.align	8
27587c478bd9Sstevel@tonic-gatekmdb_trap:
27597c478bd9Sstevel@tonic-gate	ba,a	trap_table0
27607c478bd9Sstevel@tonic-gate	jmp	%g1 + 0
27617c478bd9Sstevel@tonic-gate	nop
27627c478bd9Sstevel@tonic-gate
27637c478bd9Sstevel@tonic-gate	.global	kmdb_trap_tl1
27647c478bd9Sstevel@tonic-gate	.align	8
27657c478bd9Sstevel@tonic-gatekmdb_trap_tl1:
27667c478bd9Sstevel@tonic-gate	ba,a	trap_table0
27677c478bd9Sstevel@tonic-gate	jmp	%g1 + 0
27687c478bd9Sstevel@tonic-gate	nop
27697c478bd9Sstevel@tonic-gate
27707c478bd9Sstevel@tonic-gate/*
27717c478bd9Sstevel@tonic-gate * This entry is copied from OBP's trap table during boot.
27727c478bd9Sstevel@tonic-gate */
27737c478bd9Sstevel@tonic-gate	.global	obp_bpt
27747c478bd9Sstevel@tonic-gate	.align	8
27757c478bd9Sstevel@tonic-gateobp_bpt:
27767c478bd9Sstevel@tonic-gate	NOT
27777c478bd9Sstevel@tonic-gate
27787c478bd9Sstevel@tonic-gate/*
27797c478bd9Sstevel@tonic-gate * if kernel, set PCONTEXT to 0 for debuggers
27807c478bd9Sstevel@tonic-gate * if user, clear nucleus page sizes
27817c478bd9Sstevel@tonic-gate */
27827c478bd9Sstevel@tonic-gate	.global kctx_obp_bpt
27837c478bd9Sstevel@tonic-gatekctx_obp_bpt:
27847c478bd9Sstevel@tonic-gate	set	obp_bpt, %g2
27857c478bd9Sstevel@tonic-gate1:
2786febcc4a5Sjimand#ifndef _OPL
27877c478bd9Sstevel@tonic-gate	mov	MMU_PCONTEXT, %g1
27887c478bd9Sstevel@tonic-gate	ldxa	[%g1]ASI_DMMU, %g1
27897c478bd9Sstevel@tonic-gate	srlx	%g1, CTXREG_NEXT_SHIFT, %g3
27907c478bd9Sstevel@tonic-gate	brz,pt	%g3, 3f			! nucleus pgsz is 0, no problem
27917c478bd9Sstevel@tonic-gate	  sllx	%g3, CTXREG_NEXT_SHIFT, %g3
27927c478bd9Sstevel@tonic-gate	set	CTXREG_CTX_MASK, %g4	! check Pcontext
27937c478bd9Sstevel@tonic-gate	btst	%g4, %g1
27947c478bd9Sstevel@tonic-gate	bz,a,pt	%xcc, 2f
27957c478bd9Sstevel@tonic-gate	  clr	%g3			! kernel:  PCONTEXT=0
27967c478bd9Sstevel@tonic-gate	xor	%g3, %g1, %g3		! user:	clr N_pgsz0/1 bits
27977c478bd9Sstevel@tonic-gate2:
27987c478bd9Sstevel@tonic-gate	set	DEMAP_ALL_TYPE, %g1
27997c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_DTLB_DEMAP
28007c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1]ASI_ITLB_DEMAP
28017c478bd9Sstevel@tonic-gate	mov	MMU_PCONTEXT, %g1
28027c478bd9Sstevel@tonic-gate	stxa	%g3, [%g1]ASI_DMMU
28037c478bd9Sstevel@tonic-gate        membar  #Sync
28047c478bd9Sstevel@tonic-gate	sethi	%hi(FLUSH_ADDR), %g1
28057c478bd9Sstevel@tonic-gate	flush	%g1			! flush required by immu
2806febcc4a5Sjimand#endif /* _OPL */
28077c478bd9Sstevel@tonic-gate3:
28087c478bd9Sstevel@tonic-gate	jmp	%g2
28097c478bd9Sstevel@tonic-gate	  nop
28107c478bd9Sstevel@tonic-gate
28117c478bd9Sstevel@tonic-gate
28127c478bd9Sstevel@tonic-gate#ifdef	TRAPTRACE
28137c478bd9Sstevel@tonic-gate/*
28147c478bd9Sstevel@tonic-gate * TRAPTRACE support.
28157c478bd9Sstevel@tonic-gate * labels here are branched to with "rd %pc, %g7" in the delay slot.
28167c478bd9Sstevel@tonic-gate * Return is done by "jmp %g7 + 4".
28177c478bd9Sstevel@tonic-gate */
28187c478bd9Sstevel@tonic-gate
28197c478bd9Sstevel@tonic-gatetrace_gen:
28207c478bd9Sstevel@tonic-gate	TRACE_PTR(%g3, %g6)
2821*023e71deSHaik Aftandilian	GET_TRACE_TICK(%g6, %g4)
28227c478bd9Sstevel@tonic-gate	stxa	%g6, [%g3 + TRAP_ENT_TICK]%asi
28237c478bd9Sstevel@tonic-gate	rdpr	%tl, %g6
28247c478bd9Sstevel@tonic-gate	stha	%g6, [%g3 + TRAP_ENT_TL]%asi
28257c478bd9Sstevel@tonic-gate	rdpr	%tt, %g6
28267c478bd9Sstevel@tonic-gate	stha	%g6, [%g3 + TRAP_ENT_TT]%asi
28277c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g6
28287c478bd9Sstevel@tonic-gate	stxa	%g6, [%g3 + TRAP_ENT_TSTATE]%asi
28297c478bd9Sstevel@tonic-gate	stna	%sp, [%g3 + TRAP_ENT_SP]%asi
28307c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g6
28317c478bd9Sstevel@tonic-gate	stna	%g6, [%g3 + TRAP_ENT_TPC]%asi
28327c478bd9Sstevel@tonic-gate	TRACE_NEXT(%g3, %g4, %g5)
28337c478bd9Sstevel@tonic-gate	jmp	%g7 + 4
28347c478bd9Sstevel@tonic-gate	nop
28357c478bd9Sstevel@tonic-gate
28367c478bd9Sstevel@tonic-gatetrace_win:
28377c478bd9Sstevel@tonic-gate	TRACE_WIN_INFO(0, %l0, %l1, %l2)
28387c478bd9Sstevel@tonic-gate	! Keep the locals as clean as possible, caller cleans %l4
28397c478bd9Sstevel@tonic-gate	clr	%l2
28407c478bd9Sstevel@tonic-gate	clr	%l1
28417c478bd9Sstevel@tonic-gate	jmp	%l4 + 4
28427c478bd9Sstevel@tonic-gate	  clr	%l0
28437c478bd9Sstevel@tonic-gate
28447c478bd9Sstevel@tonic-gate/*
28457c478bd9Sstevel@tonic-gate * Trace a tsb hit
28467c478bd9Sstevel@tonic-gate * g1 = tsbe pointer (in/clobbered)
28477c478bd9Sstevel@tonic-gate * g2 = tag access register (in)
28487c478bd9Sstevel@tonic-gate * g3 - g4 = scratch (clobbered)
28497c478bd9Sstevel@tonic-gate * g5 = tsbe data (in)
28507c478bd9Sstevel@tonic-gate * g6 = scratch (clobbered)
28517c478bd9Sstevel@tonic-gate * g7 = pc we jumped here from (in)
28527c478bd9Sstevel@tonic-gate */
28537c478bd9Sstevel@tonic-gate
28547c478bd9Sstevel@tonic-gate	! Do not disturb %g5, it will be used after the trace
28557c478bd9Sstevel@tonic-gate	ALTENTRY(trace_tsbhit)
28567c478bd9Sstevel@tonic-gate	TRACE_TSBHIT(0)
28577c478bd9Sstevel@tonic-gate	jmp	%g7 + 4
28587c478bd9Sstevel@tonic-gate	nop
28597c478bd9Sstevel@tonic-gate
28607c478bd9Sstevel@tonic-gate/*
28617c478bd9Sstevel@tonic-gate * Trace a TSB miss
28627c478bd9Sstevel@tonic-gate *
28637c478bd9Sstevel@tonic-gate * g1 = tsb8k pointer (in)
28647c478bd9Sstevel@tonic-gate * g2 = tag access register (in)
28657c478bd9Sstevel@tonic-gate * g3 = tsb4m pointer (in)
28667c478bd9Sstevel@tonic-gate * g4 = tsbe tag (in/clobbered)
28677c478bd9Sstevel@tonic-gate * g5 - g6 = scratch (clobbered)
28687c478bd9Sstevel@tonic-gate * g7 = pc we jumped here from (in)
28697c478bd9Sstevel@tonic-gate */
28707c478bd9Sstevel@tonic-gate	.global	trace_tsbmiss
28717c478bd9Sstevel@tonic-gatetrace_tsbmiss:
28727c478bd9Sstevel@tonic-gate	membar	#Sync
28737c478bd9Sstevel@tonic-gate	sethi	%hi(FLUSH_ADDR), %g6
28747c478bd9Sstevel@tonic-gate	flush	%g6
28757c478bd9Sstevel@tonic-gate	TRACE_PTR(%g5, %g6)
28767c478bd9Sstevel@tonic-gate	stxa	%g2, [%g5 + TRAP_ENT_SP]%asi		! tag access
28777c478bd9Sstevel@tonic-gate	stxa	%g4, [%g5 + TRAP_ENT_F1]%asi		! tsb tag
2878*023e71deSHaik Aftandilian	GET_TRACE_TICK(%g6, %g4)
2879*023e71deSHaik Aftandilian	stxa	%g6, [%g5 + TRAP_ENT_TICK]%asi
28807c478bd9Sstevel@tonic-gate	rdpr	%tnpc, %g6
28817c478bd9Sstevel@tonic-gate	stxa	%g6, [%g5 + TRAP_ENT_F2]%asi
28827c478bd9Sstevel@tonic-gate	stna	%g1, [%g5 + TRAP_ENT_F3]%asi		! tsb8k pointer
28837c478bd9Sstevel@tonic-gate	srlx	%g1, 32, %g6
28847c478bd9Sstevel@tonic-gate	stna	%g6, [%g5 + TRAP_ENT_F4]%asi		! huh?
28857c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g6
28867c478bd9Sstevel@tonic-gate	stna	%g6, [%g5 + TRAP_ENT_TPC]%asi
28877c478bd9Sstevel@tonic-gate	rdpr	%tl, %g6
28887c478bd9Sstevel@tonic-gate	stha	%g6, [%g5 + TRAP_ENT_TL]%asi
28897c478bd9Sstevel@tonic-gate	rdpr	%tt, %g6
28907c478bd9Sstevel@tonic-gate	or	%g6, TT_MMU_MISS, %g4
28917c478bd9Sstevel@tonic-gate	stha	%g4, [%g5 + TRAP_ENT_TT]%asi
28927c478bd9Sstevel@tonic-gate	cmp	%g6, FAST_IMMU_MISS_TT
28937c478bd9Sstevel@tonic-gate	be,a	%icc, 1f
28947c478bd9Sstevel@tonic-gate	  ldxa	[%g0]ASI_IMMU, %g6
28957c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_DMMU, %g6
28967c478bd9Sstevel@tonic-gate1:	stxa	%g6, [%g5 + TRAP_ENT_TSTATE]%asi	! tag target
28977c478bd9Sstevel@tonic-gate	stxa	%g3, [%g5 + TRAP_ENT_TR]%asi		! tsb4m pointer
28987c478bd9Sstevel@tonic-gate	TRACE_NEXT(%g5, %g4, %g6)
28997c478bd9Sstevel@tonic-gate	jmp	%g7 + 4
29007c478bd9Sstevel@tonic-gate	nop
29017c478bd9Sstevel@tonic-gate
29027c478bd9Sstevel@tonic-gate/*
29037c478bd9Sstevel@tonic-gate * g2 = tag access register (in)
29047c478bd9Sstevel@tonic-gate * g3 = ctx number (in)
29057c478bd9Sstevel@tonic-gate */
29067c478bd9Sstevel@tonic-gatetrace_dataprot:
29077c478bd9Sstevel@tonic-gate	membar	#Sync
29087c478bd9Sstevel@tonic-gate	sethi	%hi(FLUSH_ADDR), %g6
29097c478bd9Sstevel@tonic-gate	flush	%g6
29107c478bd9Sstevel@tonic-gate	TRACE_PTR(%g1, %g6)
2911*023e71deSHaik Aftandilian	GET_TRACE_TICK(%g6, %g5)
29127c478bd9Sstevel@tonic-gate	stxa	%g6, [%g1 + TRAP_ENT_TICK]%asi
29137c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g6
29147c478bd9Sstevel@tonic-gate	stna	%g6, [%g1 + TRAP_ENT_TPC]%asi
29157c478bd9Sstevel@tonic-gate	rdpr	%tstate, %g6
29167c478bd9Sstevel@tonic-gate	stxa	%g6, [%g1 + TRAP_ENT_TSTATE]%asi
29177c478bd9Sstevel@tonic-gate	stxa	%g2, [%g1 + TRAP_ENT_SP]%asi		! tag access reg
29187c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1 + TRAP_ENT_TR]%asi
29197c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1 + TRAP_ENT_F1]%asi
29207c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1 + TRAP_ENT_F2]%asi
29217c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1 + TRAP_ENT_F3]%asi
29227c478bd9Sstevel@tonic-gate	stxa	%g0, [%g1 + TRAP_ENT_F4]%asi
29237c478bd9Sstevel@tonic-gate	rdpr	%tl, %g6
29247c478bd9Sstevel@tonic-gate	stha	%g6, [%g1 + TRAP_ENT_TL]%asi
29257c478bd9Sstevel@tonic-gate	rdpr	%tt, %g6
29267c478bd9Sstevel@tonic-gate	stha	%g6, [%g1 + TRAP_ENT_TT]%asi
29277c478bd9Sstevel@tonic-gate	TRACE_NEXT(%g1, %g4, %g5)
29287c478bd9Sstevel@tonic-gate	jmp	%g7 + 4
29297c478bd9Sstevel@tonic-gate	nop
29307c478bd9Sstevel@tonic-gate
29317c478bd9Sstevel@tonic-gate#endif /* TRAPTRACE */
29327c478bd9Sstevel@tonic-gate
2933b9e93c10SJonathan Haslam       .align  32
2934b9e93c10SJonathan Haslam       .global pil15_epilogue
2935b9e93c10SJonathan Haslampil15_epilogue:
2936b9e93c10SJonathan Haslam       ba      pil_interrupt_common
2937b9e93c10SJonathan Haslam       nop
2938b9e93c10SJonathan Haslam       .align  32
2939b9e93c10SJonathan Haslam
29407c478bd9Sstevel@tonic-gate/*
29417c478bd9Sstevel@tonic-gate * fast_trap_done, fast_trap_done_chk_intr:
29427c478bd9Sstevel@tonic-gate *
29437c478bd9Sstevel@tonic-gate * Due to the design of UltraSPARC pipeline, pending interrupts are not
29447c478bd9Sstevel@tonic-gate * taken immediately after a RETRY or DONE instruction which causes IE to
29457c478bd9Sstevel@tonic-gate * go from 0 to 1. Instead, the instruction at %tpc or %tnpc is allowed
29467c478bd9Sstevel@tonic-gate * to execute first before taking any interrupts. If that instruction
29477c478bd9Sstevel@tonic-gate * results in other traps, and if the corresponding trap handler runs
29487c478bd9Sstevel@tonic-gate * entirely at TL=1 with interrupts disabled, then pending interrupts
29497c478bd9Sstevel@tonic-gate * won't be taken until after yet another instruction following the %tpc
29507c478bd9Sstevel@tonic-gate * or %tnpc.
29517c478bd9Sstevel@tonic-gate *
29527c478bd9Sstevel@tonic-gate * A malicious user program can use this feature to block out interrupts
29537c478bd9Sstevel@tonic-gate * for extended durations, which can result in send_mondo_timeout kernel
29547c478bd9Sstevel@tonic-gate * panic.
29557c478bd9Sstevel@tonic-gate *
29567c478bd9Sstevel@tonic-gate * This problem is addressed by servicing any pending interrupts via
29577c478bd9Sstevel@tonic-gate * sys_trap before returning back to the user mode from a fast trap
29587c478bd9Sstevel@tonic-gate * handler. The "done" instruction within a fast trap handler, which
29597c478bd9Sstevel@tonic-gate * runs entirely at TL=1 with interrupts disabled, is replaced with the
29607c478bd9Sstevel@tonic-gate * FAST_TRAP_DONE macro, which branches control to this fast_trap_done
29617c478bd9Sstevel@tonic-gate * entry point.
29627c478bd9Sstevel@tonic-gate *
29637c478bd9Sstevel@tonic-gate * We check for any pending interrupts here and force a sys_trap to
29647c478bd9Sstevel@tonic-gate * service those interrupts, if any. To minimize overhead, pending
29657c478bd9Sstevel@tonic-gate * interrupts are checked if the %tpc happens to be at 16K boundary,
29667c478bd9Sstevel@tonic-gate * which allows a malicious program to execute at most 4K consecutive
29677c478bd9Sstevel@tonic-gate * instructions before we service any pending interrupts. If a worst
29687c478bd9Sstevel@tonic-gate * case fast trap handler takes about 2 usec, then interrupts will be
29697c478bd9Sstevel@tonic-gate * blocked for at most 8 msec, less than a clock tick.
29707c478bd9Sstevel@tonic-gate *
29717c478bd9Sstevel@tonic-gate * For the cases where we don't know if the %tpc will cross a 16K
29727c478bd9Sstevel@tonic-gate * boundary, we can't use the above optimization and always process
29737c478bd9Sstevel@tonic-gate * any pending interrupts via fast_frap_done_chk_intr entry point.
29747c478bd9Sstevel@tonic-gate *
29757c478bd9Sstevel@tonic-gate * Entry Conditions:
29767c478bd9Sstevel@tonic-gate * 	%pstate		am:0 priv:1 ie:0
29777c478bd9Sstevel@tonic-gate * 			globals are AG (not normal globals)
29787c478bd9Sstevel@tonic-gate */
29797c478bd9Sstevel@tonic-gate
29807c478bd9Sstevel@tonic-gate	.global	fast_trap_done, fast_trap_done_chk_intr
29817c478bd9Sstevel@tonic-gatefast_trap_done:
29827c478bd9Sstevel@tonic-gate	rdpr	%tpc, %g5
29837c478bd9Sstevel@tonic-gate	sethi	%hi(0xffffc000), %g6	! 1's complement of 0x3fff
29847c478bd9Sstevel@tonic-gate	andncc	%g5, %g6, %g0		! check lower 14 bits of %tpc
29857c478bd9Sstevel@tonic-gate	bz,a,pn	%icc, 1f		! branch if zero (lower 32 bits only)
29867c478bd9Sstevel@tonic-gate	  ldxa	[%g0]ASI_INTR_RECEIVE_STATUS, %g5
29877c478bd9Sstevel@tonic-gate	done
29887c478bd9Sstevel@tonic-gate
29899acbbeafSnn35248	ALTENTRY(fast_trap_done_check_interrupts)
29907c478bd9Sstevel@tonic-gatefast_trap_done_chk_intr:
29917c478bd9Sstevel@tonic-gate	ldxa	[%g0]ASI_INTR_RECEIVE_STATUS, %g5
29927c478bd9Sstevel@tonic-gate
29937c478bd9Sstevel@tonic-gate1:	rd	SOFTINT, %g6
29947c478bd9Sstevel@tonic-gate	and	%g5, IRSR_BUSY, %g5
29957c478bd9Sstevel@tonic-gate	orcc	%g5, %g6, %g0
29967c478bd9Sstevel@tonic-gate	bnz,pn	%xcc, 2f		! branch if any pending intr
29977c478bd9Sstevel@tonic-gate	nop
29987c478bd9Sstevel@tonic-gate	done
29997c478bd9Sstevel@tonic-gate
30007c478bd9Sstevel@tonic-gate2:
30017c478bd9Sstevel@tonic-gate	/*
30027c478bd9Sstevel@tonic-gate	 * We get here if there are any pending interrupts.
30037c478bd9Sstevel@tonic-gate	 * Adjust %tpc/%tnpc as we'll be resuming via "retry"
30047c478bd9Sstevel@tonic-gate	 * instruction.
30057c478bd9Sstevel@tonic-gate	 */
30067c478bd9Sstevel@tonic-gate	rdpr	%tnpc, %g5
30077c478bd9Sstevel@tonic-gate	wrpr	%g0, %g5, %tpc
30087c478bd9Sstevel@tonic-gate	add	%g5, 4, %g5
30097c478bd9Sstevel@tonic-gate	wrpr	%g0, %g5, %tnpc
30107c478bd9Sstevel@tonic-gate
30117c478bd9Sstevel@tonic-gate	/*
30127c478bd9Sstevel@tonic-gate	 * Force a dummy sys_trap call so that interrupts can be serviced.
30137c478bd9Sstevel@tonic-gate	 */
30147c478bd9Sstevel@tonic-gate	set	fast_trap_dummy_call, %g1
30157c478bd9Sstevel@tonic-gate	ba,pt	%xcc, sys_trap
30167c478bd9Sstevel@tonic-gate	  mov	-1, %g4
30177c478bd9Sstevel@tonic-gate
30187c478bd9Sstevel@tonic-gatefast_trap_dummy_call:
30197c478bd9Sstevel@tonic-gate	retl
30207c478bd9Sstevel@tonic-gate	nop
30217c478bd9Sstevel@tonic-gate
30229acbbeafSnn35248/*
302359f2ff5cSedp * Currently the brand syscall interposition code is not enabled by
302459f2ff5cSedp * default.  Instead, when a branded zone is first booted the brand
302559f2ff5cSedp * infrastructure will patch the trap table so that the syscall
302659f2ff5cSedp * entry points are redirected to syscall_wrapper32 and syscall_wrapper
302759f2ff5cSedp * for ILP32 and LP64 syscalls respectively.  this is done in
302859f2ff5cSedp * brand_plat_interposition_enable().  Note that the syscall wrappers
302959f2ff5cSedp * below do not collect any trap trace data since the syscall hot patch
303059f2ff5cSedp * points are reached after trap trace data has already been collected.
30319acbbeafSnn35248 */
30329acbbeafSnn35248#define	BRAND_CALLBACK(callback_id)					    \
30334a75c0c1Sedp	CPU_ADDR(%g2, %g1)		/* load CPU struct addr to %g2	*/ ;\
30344a75c0c1Sedp	ldn	[%g2 + CPU_THREAD], %g3	/* load thread pointer		*/ ;\
30354a75c0c1Sedp	ldn	[%g3 + T_PROCP], %g3	/* get proc pointer		*/ ;\
30364a75c0c1Sedp	ldn	[%g3 + P_BRAND], %g3	/* get brand pointer		*/ ;\
30374a75c0c1Sedp	brz	%g3, 1f			/* No brand?  No callback. 	*/ ;\
30389acbbeafSnn35248	nop 								   ;\
30394a75c0c1Sedp	ldn	[%g3 + B_MACHOPS], %g3	/* get machops list		*/ ;\
30404a75c0c1Sedp	ldn	[%g3 + (callback_id << 3)], %g3 			   ;\
30414a75c0c1Sedp	brz	%g3, 1f							   ;\
30429acbbeafSnn35248	/*								    \
30439acbbeafSnn35248	 * This isn't pretty.  We want a low-latency way for the callback   \
30449acbbeafSnn35248	 * routine to decline to do anything.  We just pass in an address   \
30459acbbeafSnn35248	 * the routine can directly jmp back to, pretending that nothing    \
30469acbbeafSnn35248	 * has happened.						    \
30474a75c0c1Sedp	 * 								    \
30484a75c0c1Sedp	 * %g1: return address (where the brand handler jumps back to)	    \
30494a75c0c1Sedp	 * %g2: address of CPU structure				    \
30504a75c0c1Sedp	 * %g3: address of brand handler (where we will jump to)	    \
30519acbbeafSnn35248	 */								    \
30529acbbeafSnn35248	mov	%pc, %g1						   ;\
30539acbbeafSnn35248	add	%g1, 16, %g1						   ;\
30544a75c0c1Sedp	jmp	%g3							   ;\
30559acbbeafSnn35248	nop								   ;\
30569acbbeafSnn352481:
30579acbbeafSnn35248
30589acbbeafSnn35248	ENTRY_NP(syscall_wrapper32)
30599acbbeafSnn35248	BRAND_CALLBACK(BRAND_CB_SYSCALL32)
30604a75c0c1Sedp	SYSCALL_NOTT(syscall_trap32)
30619acbbeafSnn35248	SET_SIZE(syscall_wrapper32)
30629acbbeafSnn35248
30639acbbeafSnn35248	ENTRY_NP(syscall_wrapper)
30649acbbeafSnn35248	BRAND_CALLBACK(BRAND_CB_SYSCALL)
30654a75c0c1Sedp	SYSCALL_NOTT(syscall_trap)
30669acbbeafSnn35248	SET_SIZE(syscall_wrapper)
30679acbbeafSnn35248
30687c478bd9Sstevel@tonic-gate#endif	/* lint */
3069