xref: /onnv-gate/usr/src/uts/intel/ia32/ml/exception.s (revision 4257:95c0f96d3d7a)
10Sstevel@tonic-gate/*
23446Smrj * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate * Use is subject to license terms.
40Sstevel@tonic-gate */
50Sstevel@tonic-gate
60Sstevel@tonic-gate/*
70Sstevel@tonic-gate * Copyright (c) 1989, 1990 William F. Jolitz.
80Sstevel@tonic-gate * Copyright (c) 1990 The Regents of the University of California.
90Sstevel@tonic-gate * All rights reserved.
100Sstevel@tonic-gate *
110Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
120Sstevel@tonic-gate * modification, are permitted provided that the following conditions
130Sstevel@tonic-gate * are met:
140Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
150Sstevel@tonic-gate *    notice, this list of conditions and the following disclaimer.
160Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
170Sstevel@tonic-gate *    notice, this list of conditions and the following disclaimer in the
180Sstevel@tonic-gate *    documentation and/or other materials provided with the distribution.
190Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
200Sstevel@tonic-gate *    must display the following acknowledgement:
210Sstevel@tonic-gate *	This product includes software developed by the University of
220Sstevel@tonic-gate *	California, Berkeley and its contributors.
230Sstevel@tonic-gate * 4. Neither the name of the University nor the names of its contributors
240Sstevel@tonic-gate *    may be used to endorse or promote products derived from this software
250Sstevel@tonic-gate *    without specific prior written permission.
260Sstevel@tonic-gate *
270Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
280Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
290Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
300Sstevel@tonic-gate * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
310Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
320Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
330Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
340Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
350Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
360Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
370Sstevel@tonic-gate * SUCH DAMAGE.
380Sstevel@tonic-gate *
390Sstevel@tonic-gate * $FreeBSD: src/sys/amd64/amd64/exception.S,v 1.113 2003/10/15 02:04:52 peter Exp $
400Sstevel@tonic-gate */
410Sstevel@tonic-gate
420Sstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
430Sstevel@tonic-gate
440Sstevel@tonic-gate#include <sys/asm_linkage.h>
450Sstevel@tonic-gate#include <sys/asm_misc.h>
460Sstevel@tonic-gate#include <sys/trap.h>
470Sstevel@tonic-gate#include <sys/psw.h>
480Sstevel@tonic-gate#include <sys/regset.h>
490Sstevel@tonic-gate#include <sys/privregs.h>
500Sstevel@tonic-gate#include <sys/dtrace.h>
513446Smrj#include <sys/x86_archext.h>
520Sstevel@tonic-gate#include <sys/traptrace.h>
532006Sandrei#include <sys/machparam.h>
540Sstevel@tonic-gate
550Sstevel@tonic-gate/*
560Sstevel@tonic-gate * only one routine in this file is interesting to lint
570Sstevel@tonic-gate */
580Sstevel@tonic-gate
590Sstevel@tonic-gate#if defined(__lint)
600Sstevel@tonic-gate
610Sstevel@tonic-gatevoid
620Sstevel@tonic-gatendptrap_frstor(void)
630Sstevel@tonic-gate{}
640Sstevel@tonic-gate
650Sstevel@tonic-gate#else
660Sstevel@tonic-gate
670Sstevel@tonic-gate#include "assym.h"
680Sstevel@tonic-gate
690Sstevel@tonic-gate/*
700Sstevel@tonic-gate * push $0 on stack for traps that do not
710Sstevel@tonic-gate * generate an error code. This is so the rest
720Sstevel@tonic-gate * of the kernel can expect a consistent stack
730Sstevel@tonic-gate * from from any exception.
740Sstevel@tonic-gate */
753446Smrj
760Sstevel@tonic-gate#define	TRAP_NOERR(trapno)	\
770Sstevel@tonic-gate	push	$0;		\
780Sstevel@tonic-gate	push	$trapno
790Sstevel@tonic-gate
803446Smrj#define	NPTRAP_NOERR(trapno) TRAP_NOERR(trapno)
813446Smrj
820Sstevel@tonic-gate/*
830Sstevel@tonic-gate * error code already pushed by hw
840Sstevel@tonic-gate * onto stack.
850Sstevel@tonic-gate */
860Sstevel@tonic-gate#define	TRAP_ERR(trapno)	\
870Sstevel@tonic-gate	push	$trapno
880Sstevel@tonic-gate
893446Smrj
900Sstevel@tonic-gate	/*
910Sstevel@tonic-gate	 * #DE
920Sstevel@tonic-gate	 */
930Sstevel@tonic-gate	ENTRY_NP(div0trap)
940Sstevel@tonic-gate	TRAP_NOERR(T_ZERODIV)	/* $0 */
950Sstevel@tonic-gate	jmp	cmntrap
960Sstevel@tonic-gate	SET_SIZE(div0trap)
970Sstevel@tonic-gate
980Sstevel@tonic-gate	/*
990Sstevel@tonic-gate	 * #DB
1000Sstevel@tonic-gate	 *
1013446Smrj	 * Fetch %dr6 and clear it, handing off the value to the
1023446Smrj	 * cmntrap code in %r15/%esi
1033446Smrj	 */
1043446Smrj	ENTRY_NP(dbgtrap)
1053446Smrj	TRAP_NOERR(T_SGLSTP)	/* $1 */
1063446Smrj
1073446Smrj#if defined(__amd64)
1083446Smrj	/*
1090Sstevel@tonic-gate	 * If we get here as a result of single-stepping a sysenter
1100Sstevel@tonic-gate	 * instruction, we suddenly find ourselves taking a #db
1110Sstevel@tonic-gate	 * in kernel mode -before- we've swapgs'ed.  So before we can
1120Sstevel@tonic-gate	 * take the trap, we do the swapgs here, and fix the return
1130Sstevel@tonic-gate	 * %rip in trap() so that we return immediately after the
1140Sstevel@tonic-gate	 * swapgs in the sysenter handler to avoid doing the swapgs again.
1150Sstevel@tonic-gate	 *
1160Sstevel@tonic-gate	 * Nobody said that the design of sysenter was particularly
1170Sstevel@tonic-gate	 * elegant, did they?
1180Sstevel@tonic-gate	 */
119*4257Ssherrym
1200Sstevel@tonic-gate	pushq	%r11
121*4257Ssherrym
122*4257Ssherrym	/*
123*4257Ssherrym	 * At this point the stack looks like this:
124*4257Ssherrym	 *
125*4257Ssherrym	 * (high address) 	r_ss
126*4257Ssherrym	 *			r_rsp
127*4257Ssherrym	 *			r_rfl
128*4257Ssherrym	 *			r_cs
129*4257Ssherrym	 *			r_rip		<-- %rsp + 24
130*4257Ssherrym	 *			r_err		<-- %rsp + 16
131*4257Ssherrym	 *			r_trapno	<-- %rsp + 8
132*4257Ssherrym	 * (low address)	%r11		<-- %rsp
133*4257Ssherrym	 */
1340Sstevel@tonic-gate	leaq	sys_sysenter(%rip), %r11
135*4257Ssherrym	cmpq	%r11, 24(%rsp)	/* Compare to saved r_rip on the stack */
1360Sstevel@tonic-gate	jne	1f
1373446Smrj	SWAPGS
1380Sstevel@tonic-gate1:	popq	%r11
1393446Smrj
1403446Smrj	INTR_PUSH
1413446Smrj	movq	%db6, %r15
1423446Smrj	xorl	%eax, %eax
1433446Smrj	movq	%rax, %db6
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate#elif defined(__i386)
1463446Smrj
1473446Smrj	INTR_PUSH
1483446Smrj	movl	%db6, %esi
1493446Smrj	xorl	%eax, %eax
1503446Smrj	movl	%eax, %db6
1513446Smrj#endif	/* __i386 */
1523446Smrj
1533446Smrj	jmp	cmntrap_pushed
1540Sstevel@tonic-gate	SET_SIZE(dbgtrap)
1550Sstevel@tonic-gate
1560Sstevel@tonic-gate#if defined(__amd64)
1570Sstevel@tonic-gate
1580Sstevel@tonic-gate/*
1590Sstevel@tonic-gate * Macro to set the gsbase or kgsbase to the address of the struct cpu
1603446Smrj * for this processor.  If we came from userland, set kgsbase else
1613446Smrj * set gsbase.  We find the proper cpu struct by looping through
1620Sstevel@tonic-gate * the cpu structs for all processors till we find a match for the gdt
1630Sstevel@tonic-gate * of the trapping processor.  The stack is expected to be pointing at
1643446Smrj * the standard regs pushed by hardware on a trap (plus error code and trapno).
1650Sstevel@tonic-gate */
1660Sstevel@tonic-gate#define	SET_CPU_GSBASE							\
1670Sstevel@tonic-gate	subq	$REGOFF_TRAPNO, %rsp;	/* save regs */			\
1680Sstevel@tonic-gate	movq	%rax, REGOFF_RAX(%rsp);					\
1690Sstevel@tonic-gate	movq	%rbx, REGOFF_RBX(%rsp);					\
1700Sstevel@tonic-gate	movq	%rcx, REGOFF_RCX(%rsp);					\
1710Sstevel@tonic-gate	movq	%rdx, REGOFF_RDX(%rsp);					\
1720Sstevel@tonic-gate	movq	%rbp, REGOFF_RBP(%rsp);					\
1730Sstevel@tonic-gate	movq	%rsp, %rbp;						\
1740Sstevel@tonic-gate	subq	$16, %rsp;		/* space for gdt */		\
1750Sstevel@tonic-gate	sgdt	6(%rsp);						\
1760Sstevel@tonic-gate	movq	8(%rsp), %rcx;		/* %rcx has gdt to match */	\
1770Sstevel@tonic-gate	xorl	%ebx, %ebx;		/* loop index */		\
1780Sstevel@tonic-gate	leaq	cpu(%rip), %rdx;	/* cpu pointer array */		\
1790Sstevel@tonic-gate1:									\
1800Sstevel@tonic-gate	movq	(%rdx, %rbx, CLONGSIZE), %rax;	/* get cpu[i] */	\
1810Sstevel@tonic-gate	cmpq	$0x0, %rax;		/* cpu[i] == NULL ? */		\
1820Sstevel@tonic-gate	je	2f;			/* yes, continue */		\
1830Sstevel@tonic-gate	cmpq	%rcx, CPU_GDT(%rax);	/* gdt == cpu[i]->cpu_gdt ? */	\
1840Sstevel@tonic-gate	je	3f;			/* yes, go set gsbase */	\
1850Sstevel@tonic-gate2:									\
1860Sstevel@tonic-gate	incl	%ebx;			/* i++ */			\
1870Sstevel@tonic-gate	cmpl	$NCPU, %ebx;		/* i < NCPU ? */		\
1880Sstevel@tonic-gate	jb	1b;			/* yes, loop */			\
1890Sstevel@tonic-gate/* XXX BIG trouble if we fall thru here.  We didn't find a gdt match */	\
1900Sstevel@tonic-gate3:									\
1910Sstevel@tonic-gate	movl	$MSR_AMD_KGSBASE, %ecx;					\
1920Sstevel@tonic-gate	cmpw	$KCS_SEL, REGOFF_CS(%rbp); /* trap from kernel? */	\
1930Sstevel@tonic-gate	jne	4f;			/* no, go set KGSBASE */	\
1940Sstevel@tonic-gate	movl	$MSR_AMD_GSBASE, %ecx;	/* yes, set GSBASE */		\
1950Sstevel@tonic-gate        mfence;				/* OPTERON_ERRATUM_88 */	\
1960Sstevel@tonic-gate4:									\
1970Sstevel@tonic-gate	movq	%rax, %rdx;		/* write base register */	\
1980Sstevel@tonic-gate	shrq	$32, %rdx;						\
1990Sstevel@tonic-gate	wrmsr;								\
2000Sstevel@tonic-gate	movq	REGOFF_RDX(%rbp), %rdx;	/* restore regs */		\
2010Sstevel@tonic-gate	movq	REGOFF_RCX(%rbp), %rcx;					\
2020Sstevel@tonic-gate	movq	REGOFF_RBX(%rbp), %rbx;					\
2030Sstevel@tonic-gate	movq	REGOFF_RAX(%rbp), %rax;					\
2040Sstevel@tonic-gate	movq	%rbp, %rsp;						\
2050Sstevel@tonic-gate	movq	REGOFF_RBP(%rsp), %rbp;					\
2060Sstevel@tonic-gate	addq	$REGOFF_TRAPNO, %rsp	/* pop stack */
2073446Smrj
2080Sstevel@tonic-gate#endif	/* __amd64 */
2093446Smrj
2100Sstevel@tonic-gate
2110Sstevel@tonic-gate#if defined(__amd64)
2120Sstevel@tonic-gate
2130Sstevel@tonic-gate	/*
2140Sstevel@tonic-gate	 * #NMI
2150Sstevel@tonic-gate	 */
2160Sstevel@tonic-gate	ENTRY_NP(nmiint)
2170Sstevel@tonic-gate	TRAP_NOERR(T_NMIFLT)	/* $2 */
2180Sstevel@tonic-gate
2190Sstevel@tonic-gate	SET_CPU_GSBASE
2200Sstevel@tonic-gate
2210Sstevel@tonic-gate	/*
2220Sstevel@tonic-gate	 * Save all registers and setup segment registers
2230Sstevel@tonic-gate	 * with kernel selectors.
2240Sstevel@tonic-gate	 */
2250Sstevel@tonic-gate	INTR_PUSH
2263446Smrj	INTGATE_INIT_KERNEL_FLAGS
2270Sstevel@tonic-gate
2280Sstevel@tonic-gate	TRACE_PTR(%r12, %rax, %eax, %rdx, $TT_TRAP)
2290Sstevel@tonic-gate	TRACE_REGS(%r12, %rsp, %rax, %rbx)
2300Sstevel@tonic-gate	TRACE_STAMP(%r12)
2310Sstevel@tonic-gate
2320Sstevel@tonic-gate	movq	%rsp, %rbp
2330Sstevel@tonic-gate
2340Sstevel@tonic-gate	movq	%rbp, %rdi
2350Sstevel@tonic-gate	call	av_dispatch_nmivect
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate	INTR_POP
2383446Smrj	IRET
2393446Smrj	/*NOTREACHED*/
2400Sstevel@tonic-gate	SET_SIZE(nmiint)
2410Sstevel@tonic-gate
2420Sstevel@tonic-gate#elif defined(__i386)
2430Sstevel@tonic-gate
2440Sstevel@tonic-gate	/*
2450Sstevel@tonic-gate	 * #NMI
2460Sstevel@tonic-gate	 */
2470Sstevel@tonic-gate	ENTRY_NP(nmiint)
2480Sstevel@tonic-gate	TRAP_NOERR(T_NMIFLT)	/* $2 */
2490Sstevel@tonic-gate
2500Sstevel@tonic-gate	/*
2510Sstevel@tonic-gate	 * Save all registers and setup segment registers
2520Sstevel@tonic-gate	 * with kernel selectors.
2530Sstevel@tonic-gate	 */
2540Sstevel@tonic-gate	INTR_PUSH
2553446Smrj	INTGATE_INIT_KERNEL_FLAGS
2560Sstevel@tonic-gate
2573446Smrj	TRACE_PTR(%edi, %ebx, %ebx, %ecx, $TT_TRAP)
2583446Smrj	TRACE_REGS(%edi, %esp, %ebx, %ecx)
2593446Smrj	TRACE_STAMP(%edi)
2600Sstevel@tonic-gate
2613446Smrj	movl	%esp, %ebp
2623446Smrj
2633446Smrj	pushl	%ebp
2643446Smrj	call	av_dispatch_nmivect
2650Sstevel@tonic-gate	addl	$4, %esp
2660Sstevel@tonic-gate
2670Sstevel@tonic-gate	INTR_POP_USER
2683446Smrj	IRET
2690Sstevel@tonic-gate	SET_SIZE(nmiint)
2700Sstevel@tonic-gate
2710Sstevel@tonic-gate#endif	/* __i386 */
2720Sstevel@tonic-gate
2730Sstevel@tonic-gate	/*
2740Sstevel@tonic-gate	 * #BP
2750Sstevel@tonic-gate	 */
2760Sstevel@tonic-gate	ENTRY_NP(brktrap)
2773446Smrj
2780Sstevel@tonic-gate#if defined(__amd64)
2790Sstevel@tonic-gate	cmpw	$KCS_SEL, 8(%rsp)
2803446Smrj	jne	bp_user
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate	/*
2830Sstevel@tonic-gate	 * This is a breakpoint in the kernel -- it is very likely that this
2840Sstevel@tonic-gate	 * is DTrace-induced.  To unify DTrace handling, we spoof this as an
2850Sstevel@tonic-gate	 * invalid opcode (#UD) fault.  Note that #BP is a trap, not a fault --
2860Sstevel@tonic-gate	 * we must decrement the trapping %rip to make it appear as a fault.
2870Sstevel@tonic-gate	 * We then push a non-zero error code to indicate that this is coming
2880Sstevel@tonic-gate	 * from #BP.
2890Sstevel@tonic-gate	 */
2900Sstevel@tonic-gate	decq	(%rsp)
2910Sstevel@tonic-gate	push	$1			/* error code -- non-zero for #BP */
2920Sstevel@tonic-gate	jmp	ud_kernel
2933446Smrj
2943446Smrjbp_user:
2953446Smrj#endif /* __amd64 */
2963446Smrj
2973446Smrj	NPTRAP_NOERR(T_BPTFLT)	/* $3 */
2983446Smrj	jmp	dtrace_trap
2993446Smrj
3000Sstevel@tonic-gate	SET_SIZE(brktrap)
3010Sstevel@tonic-gate
3020Sstevel@tonic-gate	/*
3030Sstevel@tonic-gate	 * #OF
3040Sstevel@tonic-gate	 */
3050Sstevel@tonic-gate	ENTRY_NP(ovflotrap)
3060Sstevel@tonic-gate	TRAP_NOERR(T_OVFLW)	/* $4 */
3070Sstevel@tonic-gate	jmp	cmntrap
3080Sstevel@tonic-gate	SET_SIZE(ovflotrap)
3090Sstevel@tonic-gate
3100Sstevel@tonic-gate	/*
3110Sstevel@tonic-gate	 * #BR
3120Sstevel@tonic-gate	 */
3130Sstevel@tonic-gate	ENTRY_NP(boundstrap)
3140Sstevel@tonic-gate	TRAP_NOERR(T_BOUNDFLT)	/* $5 */
3150Sstevel@tonic-gate	jmp	cmntrap
3160Sstevel@tonic-gate	SET_SIZE(boundstrap)
3170Sstevel@tonic-gate
3180Sstevel@tonic-gate#if defined(__amd64)
3190Sstevel@tonic-gate
3200Sstevel@tonic-gate	ENTRY_NP(invoptrap)
3213446Smrj
3220Sstevel@tonic-gate	cmpw	$KCS_SEL, 8(%rsp)
3230Sstevel@tonic-gate	jne	ud_user
3240Sstevel@tonic-gate
3250Sstevel@tonic-gate	push	$0			/* error code -- zero for #UD */
3260Sstevel@tonic-gateud_kernel:
3270Sstevel@tonic-gate	push	$0xdddd			/* a dummy trap number */
3283446Smrj	INTR_PUSH
3290Sstevel@tonic-gate	movq	REGOFF_RIP(%rsp), %rdi
3300Sstevel@tonic-gate	movq	REGOFF_RSP(%rsp), %rsi
3310Sstevel@tonic-gate	movq	REGOFF_RAX(%rsp), %rdx
3320Sstevel@tonic-gate	pushq	(%rsi)
3330Sstevel@tonic-gate	movq	%rsp, %rsi
3340Sstevel@tonic-gate	call	dtrace_invop
3350Sstevel@tonic-gate	ALTENTRY(dtrace_invop_callsite)
3360Sstevel@tonic-gate	addq	$8, %rsp
3370Sstevel@tonic-gate	cmpl	$DTRACE_INVOP_PUSHL_EBP, %eax
3380Sstevel@tonic-gate	je	ud_push
3390Sstevel@tonic-gate	cmpl	$DTRACE_INVOP_LEAVE, %eax
3400Sstevel@tonic-gate	je	ud_leave
3410Sstevel@tonic-gate	cmpl	$DTRACE_INVOP_NOP, %eax
3420Sstevel@tonic-gate	je	ud_nop
3430Sstevel@tonic-gate	cmpl	$DTRACE_INVOP_RET, %eax
3440Sstevel@tonic-gate	je	ud_ret
3450Sstevel@tonic-gate	jmp	ud_trap
3460Sstevel@tonic-gate
3470Sstevel@tonic-gateud_push:
3480Sstevel@tonic-gate	/*
3490Sstevel@tonic-gate	 * We must emulate a "pushq %rbp".  To do this, we pull the stack
3500Sstevel@tonic-gate	 * down 8 bytes, and then store the base pointer.
3510Sstevel@tonic-gate	 */
3520Sstevel@tonic-gate	INTR_POP
3530Sstevel@tonic-gate	subq	$16, %rsp		/* make room for %rbp */
3540Sstevel@tonic-gate	pushq	%rax			/* push temp */
3550Sstevel@tonic-gate	movq	24(%rsp), %rax		/* load calling RIP */
3560Sstevel@tonic-gate	addq	$1, %rax		/* increment over trapping instr */
3570Sstevel@tonic-gate	movq	%rax, 8(%rsp)		/* store calling RIP */
3580Sstevel@tonic-gate	movq	32(%rsp), %rax		/* load calling CS */
3590Sstevel@tonic-gate	movq	%rax, 16(%rsp)		/* store calling CS */
3600Sstevel@tonic-gate	movq	40(%rsp), %rax		/* load calling RFLAGS */
3610Sstevel@tonic-gate	movq	%rax, 24(%rsp)		/* store calling RFLAGS */
3620Sstevel@tonic-gate	movq	48(%rsp), %rax		/* load calling RSP */
3630Sstevel@tonic-gate	subq	$8, %rax		/* make room for %rbp */
3640Sstevel@tonic-gate	movq	%rax, 32(%rsp)		/* store calling RSP */
3650Sstevel@tonic-gate	movq	56(%rsp), %rax		/* load calling SS */
3660Sstevel@tonic-gate	movq	%rax, 40(%rsp)		/* store calling SS */
3670Sstevel@tonic-gate	movq	32(%rsp), %rax		/* reload calling RSP */
3680Sstevel@tonic-gate	movq	%rbp, (%rax)		/* store %rbp there */
3690Sstevel@tonic-gate	popq	%rax			/* pop off temp */
3703446Smrj	IRET				/* return from interrupt */
3713446Smrj	/*NOTREACHED*/
3720Sstevel@tonic-gate
3730Sstevel@tonic-gateud_leave:
3740Sstevel@tonic-gate	/*
3750Sstevel@tonic-gate	 * We must emulate a "leave", which is the same as a "movq %rbp, %rsp"
3760Sstevel@tonic-gate	 * followed by a "popq %rbp".  This is quite a bit simpler on amd64
3770Sstevel@tonic-gate	 * than it is on i386 -- we can exploit the fact that the %rsp is
3780Sstevel@tonic-gate	 * explicitly saved to effect the pop without having to reshuffle
3790Sstevel@tonic-gate	 * the other data pushed for the trap.
3800Sstevel@tonic-gate	 */
3810Sstevel@tonic-gate	INTR_POP
3820Sstevel@tonic-gate	pushq	%rax			/* push temp */
3830Sstevel@tonic-gate	movq	8(%rsp), %rax		/* load calling RIP */
3840Sstevel@tonic-gate	addq	$1, %rax		/* increment over trapping instr */
3850Sstevel@tonic-gate	movq	%rax, 8(%rsp)		/* store calling RIP */
3860Sstevel@tonic-gate	movq	(%rbp), %rax		/* get new %rbp */
3870Sstevel@tonic-gate	addq	$8, %rbp		/* adjust new %rsp */
3880Sstevel@tonic-gate	movq	%rbp, 32(%rsp)		/* store new %rsp */
3890Sstevel@tonic-gate	movq	%rax, %rbp		/* set new %rbp */
3900Sstevel@tonic-gate	popq	%rax			/* pop off temp */
3913446Smrj	IRET				/* return from interrupt */
3923446Smrj	/*NOTREACHED*/
3930Sstevel@tonic-gate
3940Sstevel@tonic-gateud_nop:
3950Sstevel@tonic-gate	/*
3960Sstevel@tonic-gate	 * We must emulate a "nop".  This is obviously not hard:  we need only
3970Sstevel@tonic-gate	 * advance the %rip by one.
3980Sstevel@tonic-gate	 */
3990Sstevel@tonic-gate	INTR_POP
4000Sstevel@tonic-gate	incq	(%rsp)
4013446Smrj	IRET
4023446Smrj	/*NOTREACHED*/
4030Sstevel@tonic-gate
4040Sstevel@tonic-gateud_ret:
4050Sstevel@tonic-gate	INTR_POP
4060Sstevel@tonic-gate	pushq	%rax			/* push temp */
4070Sstevel@tonic-gate	movq	32(%rsp), %rax		/* load %rsp */
4080Sstevel@tonic-gate	movq	(%rax), %rax		/* load calling RIP */
4090Sstevel@tonic-gate	movq	%rax, 8(%rsp)		/* store calling RIP */
4100Sstevel@tonic-gate	addq	$8, 32(%rsp)		/* adjust new %rsp */
4110Sstevel@tonic-gate	popq	%rax			/* pop off temp */
4123446Smrj	IRET				/* return from interrupt */
4133446Smrj	/*NOTREACHED*/
4140Sstevel@tonic-gate
4150Sstevel@tonic-gateud_trap:
4160Sstevel@tonic-gate	/*
4170Sstevel@tonic-gate	 * We're going to let the kernel handle this as a normal #UD.  If,
4180Sstevel@tonic-gate	 * however, we came through #BP and are spoofing #UD (in this case,
4190Sstevel@tonic-gate	 * the stored error value will be non-zero), we need to de-spoof
4200Sstevel@tonic-gate	 * the trap by incrementing %rip and pushing T_BPTFLT.
4210Sstevel@tonic-gate	 */
4220Sstevel@tonic-gate	cmpq	$0, REGOFF_ERR(%rsp)
4230Sstevel@tonic-gate	je	ud_ud
4240Sstevel@tonic-gate	incq	REGOFF_RIP(%rsp)
4250Sstevel@tonic-gate	addq	$REGOFF_RIP, %rsp
4263446Smrj	NPTRAP_NOERR(T_BPTFLT)	/* $3 */
4270Sstevel@tonic-gate	jmp	cmntrap
4280Sstevel@tonic-gate
4290Sstevel@tonic-gateud_ud:
4300Sstevel@tonic-gate	addq	$REGOFF_RIP, %rsp
4310Sstevel@tonic-gateud_user:
4323446Smrj	NPTRAP_NOERR(T_ILLINST)
4330Sstevel@tonic-gate	jmp	cmntrap
4340Sstevel@tonic-gate	SET_SIZE(invoptrap)
4350Sstevel@tonic-gate
4360Sstevel@tonic-gate#elif defined(__i386)
4370Sstevel@tonic-gate
4380Sstevel@tonic-gate	/*
4390Sstevel@tonic-gate	 * #UD
4400Sstevel@tonic-gate	 */
4410Sstevel@tonic-gate	ENTRY_NP(invoptrap)
4420Sstevel@tonic-gate	/*
4430Sstevel@tonic-gate	 * If we are taking an invalid opcode trap while in the kernel, this
4440Sstevel@tonic-gate	 * is likely an FBT probe point.
4450Sstevel@tonic-gate	 */
4460Sstevel@tonic-gate	pushl   %gs
4470Sstevel@tonic-gate	cmpw	$KGS_SEL, (%esp)
4480Sstevel@tonic-gate	jne	8f
4493446Smrj
4500Sstevel@tonic-gate	addl	$4, %esp
4510Sstevel@tonic-gate	pusha
4520Sstevel@tonic-gate	pushl	%eax			/* push %eax -- may be return value */
4530Sstevel@tonic-gate	pushl	%esp			/* push stack pointer */
4540Sstevel@tonic-gate	addl	$48, (%esp)		/* adjust to incoming args */
4550Sstevel@tonic-gate	pushl	40(%esp)		/* push calling EIP */
4560Sstevel@tonic-gate	call	dtrace_invop
4570Sstevel@tonic-gate	ALTENTRY(dtrace_invop_callsite)
4580Sstevel@tonic-gate	addl	$12, %esp
4590Sstevel@tonic-gate	cmpl	$DTRACE_INVOP_PUSHL_EBP, %eax
4600Sstevel@tonic-gate	je	1f
4610Sstevel@tonic-gate	cmpl	$DTRACE_INVOP_POPL_EBP, %eax
4620Sstevel@tonic-gate	je	2f
4630Sstevel@tonic-gate	cmpl	$DTRACE_INVOP_LEAVE, %eax
4640Sstevel@tonic-gate	je	3f
4650Sstevel@tonic-gate	cmpl	$DTRACE_INVOP_NOP, %eax
4660Sstevel@tonic-gate	je	4f
4670Sstevel@tonic-gate	jmp	7f
4680Sstevel@tonic-gate1:
4690Sstevel@tonic-gate	/*
4700Sstevel@tonic-gate	 * We must emulate a "pushl %ebp".  To do this, we pull the stack
4710Sstevel@tonic-gate	 * down 4 bytes, and then store the base pointer.
4720Sstevel@tonic-gate	 */
4730Sstevel@tonic-gate	popa
4740Sstevel@tonic-gate	subl	$4, %esp		/* make room for %ebp */
4750Sstevel@tonic-gate	pushl	%eax			/* push temp */
4760Sstevel@tonic-gate	movl	8(%esp), %eax		/* load calling EIP */
4770Sstevel@tonic-gate	incl	%eax			/* increment over LOCK prefix */
4780Sstevel@tonic-gate	movl	%eax, 4(%esp)		/* store calling EIP */
4790Sstevel@tonic-gate	movl	12(%esp), %eax		/* load calling CS */
4800Sstevel@tonic-gate	movl	%eax, 8(%esp)		/* store calling CS */
4810Sstevel@tonic-gate	movl	16(%esp), %eax		/* load calling EFLAGS */
4820Sstevel@tonic-gate	movl	%eax, 12(%esp)		/* store calling EFLAGS */
4830Sstevel@tonic-gate	movl	%ebp, 16(%esp)		/* push %ebp */
4840Sstevel@tonic-gate	popl	%eax			/* pop off temp */
4853446Smrj	jmp	_emul_done
4860Sstevel@tonic-gate2:
4870Sstevel@tonic-gate	/*
4880Sstevel@tonic-gate	 * We must emulate a "popl %ebp".  To do this, we do the opposite of
4890Sstevel@tonic-gate	 * the above:  we remove the %ebp from the stack, and squeeze up the
4900Sstevel@tonic-gate	 * saved state from the trap.
4910Sstevel@tonic-gate	 */
4920Sstevel@tonic-gate	popa
4930Sstevel@tonic-gate	pushl	%eax			/* push temp */
4940Sstevel@tonic-gate	movl	16(%esp), %ebp		/* pop %ebp */
4950Sstevel@tonic-gate	movl	12(%esp), %eax		/* load calling EFLAGS */
4960Sstevel@tonic-gate	movl	%eax, 16(%esp)		/* store calling EFLAGS */
4970Sstevel@tonic-gate	movl	8(%esp), %eax		/* load calling CS */
4980Sstevel@tonic-gate	movl	%eax, 12(%esp)		/* store calling CS */
4990Sstevel@tonic-gate	movl	4(%esp), %eax		/* load calling EIP */
5000Sstevel@tonic-gate	incl	%eax			/* increment over LOCK prefix */
5010Sstevel@tonic-gate	movl	%eax, 8(%esp)		/* store calling EIP */
5020Sstevel@tonic-gate	popl	%eax			/* pop off temp */
5030Sstevel@tonic-gate	addl	$4, %esp		/* adjust stack pointer */
5043446Smrj	jmp	_emul_done
5050Sstevel@tonic-gate3:
5060Sstevel@tonic-gate	/*
5070Sstevel@tonic-gate	 * We must emulate a "leave", which is the same as a "movl %ebp, %esp"
5080Sstevel@tonic-gate	 * followed by a "popl %ebp".  This looks similar to the above, but
5090Sstevel@tonic-gate	 * requires two temporaries:  one for the new base pointer, and one
5100Sstevel@tonic-gate	 * for the staging register.
5110Sstevel@tonic-gate	 */
5120Sstevel@tonic-gate	popa
5130Sstevel@tonic-gate	pushl	%eax			/* push temp */
5140Sstevel@tonic-gate	pushl	%ebx			/* push temp */
5150Sstevel@tonic-gate	movl	%ebp, %ebx		/* set temp to old %ebp */
5160Sstevel@tonic-gate	movl	(%ebx), %ebp		/* pop %ebp */
5170Sstevel@tonic-gate	movl	16(%esp), %eax		/* load calling EFLAGS */
5180Sstevel@tonic-gate	movl	%eax, (%ebx)		/* store calling EFLAGS */
5190Sstevel@tonic-gate	movl	12(%esp), %eax		/* load calling CS */
5200Sstevel@tonic-gate	movl	%eax, -4(%ebx)		/* store calling CS */
5210Sstevel@tonic-gate	movl	8(%esp), %eax		/* load calling EIP */
5220Sstevel@tonic-gate	incl	%eax			/* increment over LOCK prefix */
5230Sstevel@tonic-gate	movl	%eax, -8(%ebx)		/* store calling EIP */
5240Sstevel@tonic-gate	movl	%ebx, -4(%esp)		/* temporarily store new %esp */
5250Sstevel@tonic-gate	popl	%ebx			/* pop off temp */
5260Sstevel@tonic-gate	popl	%eax			/* pop off temp */
5270Sstevel@tonic-gate	movl	-12(%esp), %esp		/* set stack pointer */
5280Sstevel@tonic-gate	subl	$8, %esp		/* adjust for three pushes, one pop */
5293446Smrj	jmp	_emul_done
5300Sstevel@tonic-gate4:
5310Sstevel@tonic-gate	/*
5320Sstevel@tonic-gate	 * We must emulate a "nop".  This is obviously not hard:  we need only
5330Sstevel@tonic-gate	 * advance the %eip by one.
5340Sstevel@tonic-gate	 */
5350Sstevel@tonic-gate	popa
5360Sstevel@tonic-gate	incl	(%esp)
5373446Smrj_emul_done:
5383446Smrj	IRET				/* return from interrupt */
5390Sstevel@tonic-gate7:
5400Sstevel@tonic-gate	popa
5410Sstevel@tonic-gate	pushl	$0
5420Sstevel@tonic-gate	pushl	$T_ILLINST	/* $6 */
5430Sstevel@tonic-gate	jmp	cmntrap
5440Sstevel@tonic-gate8:
5450Sstevel@tonic-gate	addl	$4, %esp
5460Sstevel@tonic-gate	pushl	$0
5470Sstevel@tonic-gate	pushl	$T_ILLINST	/* $6 */
5480Sstevel@tonic-gate	jmp	cmntrap
5490Sstevel@tonic-gate	SET_SIZE(invoptrap)
5500Sstevel@tonic-gate
5510Sstevel@tonic-gate#endif	/* __i386 */
5520Sstevel@tonic-gate
5530Sstevel@tonic-gate#if defined(__amd64)
5540Sstevel@tonic-gate
5550Sstevel@tonic-gate	/*
5560Sstevel@tonic-gate	 * #NM
5570Sstevel@tonic-gate	 */
5580Sstevel@tonic-gate	ENTRY_NP(ndptrap)
5590Sstevel@tonic-gate	/*
5600Sstevel@tonic-gate	 * We want to do this quickly as every lwp using fp will take this
5610Sstevel@tonic-gate	 * after a context switch -- we do the frequent path in ndptrap_frstor
5620Sstevel@tonic-gate	 * below; for all other cases, we let the trap code handle it
5630Sstevel@tonic-gate	 */
5640Sstevel@tonic-gate	pushq	%rax
5650Sstevel@tonic-gate	pushq	%rbx
5660Sstevel@tonic-gate	cmpw    $KCS_SEL, 24(%rsp)	/* did we come from kernel mode? */
5670Sstevel@tonic-gate	jne     1f
5680Sstevel@tonic-gate	LOADCPU(%rbx)			/* if yes, don't swapgs */
5690Sstevel@tonic-gate	jmp	2f
5700Sstevel@tonic-gate1:
5713446Smrj	SWAPGS				/* if from user, need swapgs */
5720Sstevel@tonic-gate	LOADCPU(%rbx)
5733446Smrj	SWAPGS
5740Sstevel@tonic-gate2:
5750Sstevel@tonic-gate	cmpl	$0, fpu_exists(%rip)
5760Sstevel@tonic-gate	je	.handle_in_trap		/* let trap handle no fp case */
5770Sstevel@tonic-gate	movq	CPU_THREAD(%rbx), %rax	/* %rax = curthread */
5780Sstevel@tonic-gate	movl	$FPU_EN, %ebx
5790Sstevel@tonic-gate	movq	T_LWP(%rax), %rax	/* %rax = lwp */
5800Sstevel@tonic-gate	testq	%rax, %rax
5810Sstevel@tonic-gate	jz	.handle_in_trap		/* should not happen? */
5820Sstevel@tonic-gate#if LWP_PCB_FPU	!= 0
5830Sstevel@tonic-gate	addq	$LWP_PCB_FPU, %rax	/* &lwp->lwp_pcb.pcb_fpu */
5840Sstevel@tonic-gate#endif
5850Sstevel@tonic-gate	testl	%ebx, PCB_FPU_FLAGS(%rax)
5860Sstevel@tonic-gate	jz	.handle_in_trap		/* must be the first fault */
5870Sstevel@tonic-gate	clts
5880Sstevel@tonic-gate	andl	$_BITNOT(FPU_VALID), PCB_FPU_FLAGS(%rax)
5890Sstevel@tonic-gate#if FPU_CTX_FPU_REGS != 0
5900Sstevel@tonic-gate	addq	$FPU_CTX_FPU_REGS, %rax
5910Sstevel@tonic-gate#endif
5920Sstevel@tonic-gate	/*
5930Sstevel@tonic-gate	 * the label below is used in trap.c to detect FP faults in
5940Sstevel@tonic-gate	 * kernel due to user fault.
5950Sstevel@tonic-gate	 */
5960Sstevel@tonic-gate	ALTENTRY(ndptrap_frstor)
5970Sstevel@tonic-gate	fxrstor	(%rax)
5980Sstevel@tonic-gate	popq	%rbx
5990Sstevel@tonic-gate	popq	%rax
6003446Smrj	IRET
6013446Smrj	/*NOTREACHED*/
6020Sstevel@tonic-gate
6030Sstevel@tonic-gate.handle_in_trap:
6040Sstevel@tonic-gate	popq	%rbx
6050Sstevel@tonic-gate	popq	%rax
6060Sstevel@tonic-gate	TRAP_NOERR(T_NOEXTFLT)	/* $7 */
6070Sstevel@tonic-gate	jmp	cmninttrap
6080Sstevel@tonic-gate	SET_SIZE(ndptrap_frstor)
6090Sstevel@tonic-gate	SET_SIZE(ndptrap)
6100Sstevel@tonic-gate
6110Sstevel@tonic-gate#elif defined(__i386)
6120Sstevel@tonic-gate
6130Sstevel@tonic-gate	ENTRY_NP(ndptrap)
6140Sstevel@tonic-gate	/*
6150Sstevel@tonic-gate	 * We want to do this quickly as every lwp using fp will take this
6160Sstevel@tonic-gate	 * after a context switch -- we do the frequent path in fpnoextflt
6170Sstevel@tonic-gate	 * below; for all other cases, we let the trap code handle it
6180Sstevel@tonic-gate	 */
6190Sstevel@tonic-gate	pushl	%eax
6200Sstevel@tonic-gate	pushl	%ebx
6210Sstevel@tonic-gate	pushl	%ds
6220Sstevel@tonic-gate	pushl	%gs
6230Sstevel@tonic-gate	movl	$KDS_SEL, %ebx
6240Sstevel@tonic-gate	movw	%bx, %ds
6250Sstevel@tonic-gate	movl	$KGS_SEL, %eax
6260Sstevel@tonic-gate	movw	%ax, %gs
6273446Smrj	LOADCPU(%eax)
6280Sstevel@tonic-gate	cmpl	$0, fpu_exists
6290Sstevel@tonic-gate	je	.handle_in_trap		/* let trap handle no fp case */
6303446Smrj	movl	CPU_THREAD(%eax), %ebx	/* %ebx = curthread */
6313446Smrj	movl	$FPU_EN, %eax
6323446Smrj	movl	T_LWP(%ebx), %ebx	/* %ebx = lwp */
6333446Smrj	testl	%ebx, %ebx
6340Sstevel@tonic-gate	jz	.handle_in_trap		/* should not happen? */
6350Sstevel@tonic-gate#if LWP_PCB_FPU != 0
6363446Smrj	addl	$LWP_PCB_FPU, %ebx 	/* &lwp->lwp_pcb.pcb_fpu */
6370Sstevel@tonic-gate#endif
6383446Smrj	testl	%eax, PCB_FPU_FLAGS(%ebx)
6390Sstevel@tonic-gate	jz	.handle_in_trap		/* must be the first fault */
6403446Smrj	CLTS
6413446Smrj	andl	$_BITNOT(FPU_VALID), PCB_FPU_FLAGS(%ebx)
6420Sstevel@tonic-gate#if FPU_CTX_FPU_REGS != 0
6433446Smrj	addl	$FPU_CTX_FPU_REGS, %ebx
6440Sstevel@tonic-gate#endif
6450Sstevel@tonic-gate	/*
6460Sstevel@tonic-gate	 * the label below is used in trap.c to detect FP faults in kernel
6470Sstevel@tonic-gate	 * due to user fault.
6480Sstevel@tonic-gate	 */
6490Sstevel@tonic-gate	ALTENTRY(ndptrap_frstor)
6503446Smrj	.globl	_patch_fxrstor_ebx
6513446Smrj_patch_fxrstor_ebx:
6523446Smrj	frstor	(%ebx)		/* may be patched to fxrstor */
6530Sstevel@tonic-gate	nop			/* (including this byte) */
6540Sstevel@tonic-gate	popl	%gs
6550Sstevel@tonic-gate	popl	%ds
6560Sstevel@tonic-gate	popl	%ebx
6570Sstevel@tonic-gate	popl	%eax
6583446Smrj	IRET
6590Sstevel@tonic-gate
6600Sstevel@tonic-gate.handle_in_trap:
6610Sstevel@tonic-gate	popl	%gs
6620Sstevel@tonic-gate	popl	%ds
6630Sstevel@tonic-gate	popl	%ebx
6640Sstevel@tonic-gate	popl	%eax
6653446Smrj	TRAP_NOERR(T_NOEXTFLT)	/* $7 */
6660Sstevel@tonic-gate	jmp	cmninttrap
6670Sstevel@tonic-gate	SET_SIZE(ndptrap_frstor)
6680Sstevel@tonic-gate	SET_SIZE(ndptrap)
6690Sstevel@tonic-gate
6700Sstevel@tonic-gate#endif	/* __i386 */
6710Sstevel@tonic-gate
6720Sstevel@tonic-gate#if defined(__amd64)
6730Sstevel@tonic-gate
6740Sstevel@tonic-gate	/*
6750Sstevel@tonic-gate	 * #DF
6760Sstevel@tonic-gate	 */
6770Sstevel@tonic-gate	ENTRY_NP(syserrtrap)
6780Sstevel@tonic-gate	pushq	$T_DBLFLT
6790Sstevel@tonic-gate
6800Sstevel@tonic-gate	SET_CPU_GSBASE
6810Sstevel@tonic-gate
6820Sstevel@tonic-gate	/*
6830Sstevel@tonic-gate	 * We share this handler with kmdb (if kmdb is loaded).  As such, we may
6840Sstevel@tonic-gate	 * have reached this point after encountering a #df in kmdb.  If that
6850Sstevel@tonic-gate	 * happens, we'll still be on kmdb's IDT.  We need to switch back to this
6860Sstevel@tonic-gate	 * CPU's IDT before proceeding.  Furthermore, if we did arrive here from
6870Sstevel@tonic-gate	 * kmdb, kmdb is probably in a very sickly state, and shouldn't be
6880Sstevel@tonic-gate	 * entered from the panic flow.  We'll suppress that entry by setting
6890Sstevel@tonic-gate	 * nopanicdebug.
6900Sstevel@tonic-gate	 */
6910Sstevel@tonic-gate	pushq	%rax
6920Sstevel@tonic-gate	subq	$DESCTBR_SIZE, %rsp
6930Sstevel@tonic-gate	sidt	(%rsp)
6940Sstevel@tonic-gate	movq	%gs:CPU_IDT, %rax
6950Sstevel@tonic-gate	cmpq	%rax, DTR_BASE(%rsp)
6960Sstevel@tonic-gate	je	1f
6970Sstevel@tonic-gate
6980Sstevel@tonic-gate	movq	%rax, DTR_BASE(%rsp)
6990Sstevel@tonic-gate	movw	$_MUL(NIDT, GATE_DESC_SIZE), DTR_LIMIT(%rsp)
7000Sstevel@tonic-gate	lidt	(%rsp)
7010Sstevel@tonic-gate
7020Sstevel@tonic-gate	movl	$1, nopanicdebug
7030Sstevel@tonic-gate
7040Sstevel@tonic-gate1:	addq	$DESCTBR_SIZE, %rsp
7050Sstevel@tonic-gate	popq	%rax
7060Sstevel@tonic-gate
7070Sstevel@tonic-gate	DFTRAP_PUSH
7080Sstevel@tonic-gate
7090Sstevel@tonic-gate	/*
7100Sstevel@tonic-gate	 * freeze trap trace.
7110Sstevel@tonic-gate	 */
7120Sstevel@tonic-gate#ifdef TRAPTRACE
7130Sstevel@tonic-gate	leaq	trap_trace_freeze(%rip), %r11
7140Sstevel@tonic-gate	incl	(%r11)
7150Sstevel@tonic-gate#endif
7160Sstevel@tonic-gate
7170Sstevel@tonic-gate	ENABLE_INTR_FLAGS
7180Sstevel@tonic-gate
7190Sstevel@tonic-gate	movq	%rsp, %rdi	/* &regs */
7200Sstevel@tonic-gate	xorl	%esi, %esi	/* clear address */
7210Sstevel@tonic-gate	xorl	%edx, %edx	/* cpuid = 0 */
7220Sstevel@tonic-gate	call	trap
7230Sstevel@tonic-gate
7240Sstevel@tonic-gate	SET_SIZE(syserrtrap)
7250Sstevel@tonic-gate
7260Sstevel@tonic-gate#elif defined(__i386)
7270Sstevel@tonic-gate
7280Sstevel@tonic-gate	/*
7290Sstevel@tonic-gate	 * #DF
7300Sstevel@tonic-gate	 */
7310Sstevel@tonic-gate	ENTRY_NP(syserrtrap)
7320Sstevel@tonic-gate	cli				/* disable interrupts */
7330Sstevel@tonic-gate
7340Sstevel@tonic-gate	/*
7350Sstevel@tonic-gate	 * We share this handler with kmdb (if kmdb is loaded).  As such, we may
7360Sstevel@tonic-gate	 * have reached this point after encountering a #df in kmdb.  If that
7370Sstevel@tonic-gate	 * happens, we'll still be on kmdb's IDT.  We need to switch back to this
7380Sstevel@tonic-gate	 * CPU's IDT before proceeding.  Furthermore, if we did arrive here from
7390Sstevel@tonic-gate	 * kmdb, kmdb is probably in a very sickly state, and shouldn't be
7400Sstevel@tonic-gate	 * entered from the panic flow.  We'll suppress that entry by setting
7410Sstevel@tonic-gate	 * nopanicdebug.
7420Sstevel@tonic-gate	 */
7430Sstevel@tonic-gate	subl	$DESCTBR_SIZE, %esp
7440Sstevel@tonic-gate	movl	%gs:CPU_IDT, %eax
7450Sstevel@tonic-gate	sidt	(%esp)
7460Sstevel@tonic-gate	cmpl	DTR_BASE(%esp), %eax
7470Sstevel@tonic-gate	je	1f
7480Sstevel@tonic-gate
7490Sstevel@tonic-gate	movl	%eax, DTR_BASE(%esp)
7500Sstevel@tonic-gate	movw	$_MUL(NIDT, GATE_DESC_SIZE), DTR_LIMIT(%esp)
7510Sstevel@tonic-gate	lidt	(%esp)
7520Sstevel@tonic-gate
7530Sstevel@tonic-gate	movl	$1, nopanicdebug
7540Sstevel@tonic-gate
7550Sstevel@tonic-gate1:	addl	$DESCTBR_SIZE, %esp
7560Sstevel@tonic-gate
7570Sstevel@tonic-gate	/*
7580Sstevel@tonic-gate	 * Check the CPL in the TSS to see what mode
7590Sstevel@tonic-gate	 * (user or kernel) we took the fault in.  At this
7600Sstevel@tonic-gate	 * point we are running in the context of the double
7610Sstevel@tonic-gate	 * fault task (dftss) but the CPU's task points to
7620Sstevel@tonic-gate	 * the previous task (ktss) where the process context
7630Sstevel@tonic-gate	 * has been saved as the result of the task switch.
7640Sstevel@tonic-gate	 */
7650Sstevel@tonic-gate	movl	%gs:CPU_TSS, %eax	/* get the TSS */
7660Sstevel@tonic-gate	movl	TSS_SS(%eax), %ebx	/* save the fault SS */
7670Sstevel@tonic-gate	movl	TSS_ESP(%eax), %edx	/* save the fault ESP */
7680Sstevel@tonic-gate	testw	$CPL_MASK, TSS_CS(%eax)	/* user mode ? */
7690Sstevel@tonic-gate	jz	make_frame
7700Sstevel@tonic-gate	movw	TSS_SS0(%eax), %ss	/* get on the kernel stack */
7710Sstevel@tonic-gate	movl	TSS_ESP0(%eax), %esp
7720Sstevel@tonic-gate
7730Sstevel@tonic-gate	/*
7740Sstevel@tonic-gate	 * Clear the NT flag to avoid a task switch when the process
7750Sstevel@tonic-gate	 * finally pops the EFL off the stack via an iret.  Clear
7760Sstevel@tonic-gate	 * the TF flag since that is what the processor does for
7770Sstevel@tonic-gate	 * a normal exception. Clear the IE flag so that interrupts
7780Sstevel@tonic-gate	 * remain disabled.
7790Sstevel@tonic-gate	 */
7800Sstevel@tonic-gate	movl	TSS_EFL(%eax), %ecx
7810Sstevel@tonic-gate	andl	$_BITNOT(PS_NT|PS_T|PS_IE), %ecx
7820Sstevel@tonic-gate	pushl	%ecx
7830Sstevel@tonic-gate	popfl				/* restore the EFL */
7840Sstevel@tonic-gate	movw	TSS_LDT(%eax), %cx	/* restore the LDT */
7850Sstevel@tonic-gate	lldt	%cx
7860Sstevel@tonic-gate
7870Sstevel@tonic-gate	/*
7880Sstevel@tonic-gate	 * Restore process segment selectors.
7890Sstevel@tonic-gate	 */
7900Sstevel@tonic-gate	movw	TSS_DS(%eax), %ds
7910Sstevel@tonic-gate	movw	TSS_ES(%eax), %es
7920Sstevel@tonic-gate	movw	TSS_FS(%eax), %fs
7930Sstevel@tonic-gate	movw	TSS_GS(%eax), %gs
7940Sstevel@tonic-gate
7950Sstevel@tonic-gate	/*
7960Sstevel@tonic-gate	 * Restore task segment selectors.
7970Sstevel@tonic-gate	 */
7980Sstevel@tonic-gate	movl	$KDS_SEL, TSS_DS(%eax)
7990Sstevel@tonic-gate	movl	$KDS_SEL, TSS_ES(%eax)
8000Sstevel@tonic-gate	movl	$KDS_SEL, TSS_SS(%eax)
8010Sstevel@tonic-gate	movl	$KFS_SEL, TSS_FS(%eax)
8020Sstevel@tonic-gate	movl	$KGS_SEL, TSS_GS(%eax)
8030Sstevel@tonic-gate
8040Sstevel@tonic-gate	/*
8050Sstevel@tonic-gate	 * Clear the TS bit, the busy bits in both task
8060Sstevel@tonic-gate	 * descriptors, and switch tasks.
8070Sstevel@tonic-gate	 */
8080Sstevel@tonic-gate	clts
8090Sstevel@tonic-gate	leal	gdt0, %ecx
8100Sstevel@tonic-gate	movl	DFTSS_SEL+4(%ecx), %esi
8110Sstevel@tonic-gate	andl	$_BITNOT(0x200), %esi
8120Sstevel@tonic-gate	movl	%esi, DFTSS_SEL+4(%ecx)
8130Sstevel@tonic-gate	movl	KTSS_SEL+4(%ecx), %esi
8140Sstevel@tonic-gate	andl	$_BITNOT(0x200), %esi
8150Sstevel@tonic-gate	movl	%esi, KTSS_SEL+4(%ecx)
8160Sstevel@tonic-gate	movw	$KTSS_SEL, %cx
8170Sstevel@tonic-gate	ltr	%cx
8180Sstevel@tonic-gate
8190Sstevel@tonic-gate	/*
8200Sstevel@tonic-gate	 * Restore part of the process registers.
8210Sstevel@tonic-gate	 */
8220Sstevel@tonic-gate	movl	TSS_EBP(%eax), %ebp
8230Sstevel@tonic-gate	movl	TSS_ECX(%eax), %ecx
8240Sstevel@tonic-gate	movl	TSS_ESI(%eax), %esi
8250Sstevel@tonic-gate	movl	TSS_EDI(%eax), %edi
8260Sstevel@tonic-gate
8270Sstevel@tonic-gatemake_frame:
8280Sstevel@tonic-gate	/*
8290Sstevel@tonic-gate	 * Make a trap frame.  Leave the error code (0) on
8300Sstevel@tonic-gate	 * the stack since the first word on a trap stack is
8310Sstevel@tonic-gate	 * unused anyway.
8320Sstevel@tonic-gate	 */
8330Sstevel@tonic-gate	pushl	%ebx			/ fault SS
8340Sstevel@tonic-gate	pushl	%edx			/ fault ESP
8350Sstevel@tonic-gate	pushl	TSS_EFL(%eax)		/ fault EFL
8360Sstevel@tonic-gate	pushl	TSS_CS(%eax)		/ fault CS
8370Sstevel@tonic-gate	pushl	TSS_EIP(%eax)		/ fault EIP
8380Sstevel@tonic-gate	pushl	$0			/ error code
8390Sstevel@tonic-gate	pushl	$T_DBLFLT		/ trap number 8
8400Sstevel@tonic-gate	movl	TSS_EBX(%eax), %ebx	/ restore EBX
8410Sstevel@tonic-gate	movl	TSS_EDX(%eax), %edx	/ restore EDX
8420Sstevel@tonic-gate	movl	TSS_EAX(%eax), %eax	/ restore EAX
8430Sstevel@tonic-gate	sti				/ enable interrupts
8440Sstevel@tonic-gate	jmp	cmntrap
8450Sstevel@tonic-gate	SET_SIZE(syserrtrap)
8460Sstevel@tonic-gate
8470Sstevel@tonic-gate#endif	/* __i386 */
8480Sstevel@tonic-gate
8490Sstevel@tonic-gate	ENTRY_NP(overrun)
8500Sstevel@tonic-gate	push	$0
8510Sstevel@tonic-gate	TRAP_NOERR(T_EXTOVRFLT)	/* $9 i386 only - not generated */
8520Sstevel@tonic-gate	jmp	cmninttrap
8530Sstevel@tonic-gate	SET_SIZE(overrun)
8540Sstevel@tonic-gate
8550Sstevel@tonic-gate	/*
8560Sstevel@tonic-gate	 * #TS
8570Sstevel@tonic-gate	 */
8580Sstevel@tonic-gate	ENTRY_NP(invtsstrap)
8590Sstevel@tonic-gate	TRAP_ERR(T_TSSFLT)	/* $10 already have error code on stack */
8600Sstevel@tonic-gate	jmp	cmntrap
8610Sstevel@tonic-gate	SET_SIZE(invtsstrap)
8620Sstevel@tonic-gate
8630Sstevel@tonic-gate	/*
8640Sstevel@tonic-gate	 * #NP
8650Sstevel@tonic-gate	 */
8660Sstevel@tonic-gate	ENTRY_NP(segnptrap)
8670Sstevel@tonic-gate	TRAP_ERR(T_SEGFLT)	/* $11 already have error code on stack */
8680Sstevel@tonic-gate#if defined(__amd64)
8690Sstevel@tonic-gate	SET_CPU_GSBASE
8700Sstevel@tonic-gate#endif
8710Sstevel@tonic-gate	jmp	cmntrap
8720Sstevel@tonic-gate	SET_SIZE(segnptrap)
8730Sstevel@tonic-gate
8740Sstevel@tonic-gate	/*
8750Sstevel@tonic-gate	 * #SS
8760Sstevel@tonic-gate	 */
8770Sstevel@tonic-gate	ENTRY_NP(stktrap)
8780Sstevel@tonic-gate	TRAP_ERR(T_STKFLT)	/* $12 already have error code on stack */
8790Sstevel@tonic-gate	jmp	cmntrap
8800Sstevel@tonic-gate	SET_SIZE(stktrap)
8810Sstevel@tonic-gate
8820Sstevel@tonic-gate	/*
8830Sstevel@tonic-gate	 * #GP
8840Sstevel@tonic-gate	 */
8850Sstevel@tonic-gate	ENTRY_NP(gptrap)
8860Sstevel@tonic-gate	TRAP_ERR(T_GPFLT)	/* $13 already have error code on stack */
8870Sstevel@tonic-gate#if defined(__amd64)
8880Sstevel@tonic-gate	SET_CPU_GSBASE
8890Sstevel@tonic-gate#endif
8900Sstevel@tonic-gate	jmp	cmntrap
8910Sstevel@tonic-gate	SET_SIZE(gptrap)
8920Sstevel@tonic-gate
8930Sstevel@tonic-gate	/*
8940Sstevel@tonic-gate	 * #PF
8950Sstevel@tonic-gate	 */
8960Sstevel@tonic-gate	ENTRY_NP(pftrap)
8970Sstevel@tonic-gate	TRAP_ERR(T_PGFLT)	/* $14 already have error code on stack */
8983446Smrj	INTR_PUSH
8993446Smrj
9003446Smrj#if defined(__amd64)
9013446Smrj	movq	%cr2, %r15
9023446Smrj#elif defined(__i386)
9033446Smrj	movl	%cr2, %esi
9043446Smrj#endif	/* __i386 */
9053446Smrj
9063446Smrj	jmp	cmntrap_pushed
9070Sstevel@tonic-gate	SET_SIZE(pftrap)
9080Sstevel@tonic-gate
9090Sstevel@tonic-gate#if !defined(__amd64)
9100Sstevel@tonic-gate
9113446Smrj	.globl	idt0_default_r
9123446Smrj
9130Sstevel@tonic-gate	/*
9140Sstevel@tonic-gate	 * #PF pentium bug workaround
9150Sstevel@tonic-gate	 */
9160Sstevel@tonic-gate	ENTRY_NP(pentium_pftrap)
9170Sstevel@tonic-gate	pushl	%eax
9180Sstevel@tonic-gate	movl	%cr2, %eax
9190Sstevel@tonic-gate	andl	$MMU_STD_PAGEMASK, %eax
9200Sstevel@tonic-gate
9210Sstevel@tonic-gate	cmpl	%eax, %cs:idt0_default_r+2	/* fixme */
9220Sstevel@tonic-gate
9230Sstevel@tonic-gate	je	check_for_user_address
9240Sstevel@tonic-gateuser_mode:
9250Sstevel@tonic-gate	popl	%eax
9260Sstevel@tonic-gate	pushl	$T_PGFLT	/* $14 */
9270Sstevel@tonic-gate	jmp	cmntrap
9280Sstevel@tonic-gatecheck_for_user_address:
9290Sstevel@tonic-gate	/*
9300Sstevel@tonic-gate	 * Before we assume that we have an unmapped trap on our hands,
9310Sstevel@tonic-gate	 * check to see if this is a fault from user mode.  If it is,
9320Sstevel@tonic-gate	 * we'll kick back into the page fault handler.
9330Sstevel@tonic-gate	 */
9340Sstevel@tonic-gate	movl	4(%esp), %eax	/* error code */
9350Sstevel@tonic-gate	andl	$PF_ERR_USER, %eax
9360Sstevel@tonic-gate	jnz	user_mode
9370Sstevel@tonic-gate
9380Sstevel@tonic-gate	/*
9390Sstevel@tonic-gate	 * We now know that this is the invalid opcode trap.
9400Sstevel@tonic-gate	 */
9410Sstevel@tonic-gate	popl	%eax
9420Sstevel@tonic-gate	addl	$4, %esp	/* pop error code */
9430Sstevel@tonic-gate	jmp	invoptrap
9440Sstevel@tonic-gate	SET_SIZE(pentium_pftrap)
9450Sstevel@tonic-gate
9460Sstevel@tonic-gate#endif	/* !__amd64 */
9470Sstevel@tonic-gate
9480Sstevel@tonic-gate	ENTRY_NP(resvtrap)
9490Sstevel@tonic-gate	TRAP_NOERR(15)		/* (reserved)  */
9500Sstevel@tonic-gate	jmp	cmntrap
9510Sstevel@tonic-gate	SET_SIZE(resvtrap)
9520Sstevel@tonic-gate
9530Sstevel@tonic-gate	/*
9540Sstevel@tonic-gate	 * #MF
9550Sstevel@tonic-gate	 */
9560Sstevel@tonic-gate	ENTRY_NP(ndperr)
9570Sstevel@tonic-gate	TRAP_NOERR(T_EXTERRFLT)	/* $16 */
9580Sstevel@tonic-gate	jmp	cmninttrap
9590Sstevel@tonic-gate	SET_SIZE(ndperr)
9600Sstevel@tonic-gate
9610Sstevel@tonic-gate	/*
9620Sstevel@tonic-gate	 * #AC
9630Sstevel@tonic-gate	 */
9640Sstevel@tonic-gate	ENTRY_NP(achktrap)
9650Sstevel@tonic-gate	TRAP_ERR(T_ALIGNMENT)	/* $17 */
9660Sstevel@tonic-gate	jmp	cmntrap
9670Sstevel@tonic-gate	SET_SIZE(achktrap)
9680Sstevel@tonic-gate
9690Sstevel@tonic-gate	/*
9700Sstevel@tonic-gate	 * #MC
9710Sstevel@tonic-gate	 */
9721414Scindi	.globl	cmi_mca_trap	/* see uts/i86pc/os/cmi.c */
9731414Scindi
9741414Scindi#if defined(__amd64)
9751414Scindi
9760Sstevel@tonic-gate	ENTRY_NP(mcetrap)
9770Sstevel@tonic-gate	TRAP_NOERR(T_MCE)	/* $18 */
9783446Smrj
97910Skucharsk	SET_CPU_GSBASE
9803446Smrj
9811414Scindi	INTR_PUSH
9823446Smrj	INTGATE_INIT_KERNEL_FLAGS
9831414Scindi
9841414Scindi	TRACE_PTR(%rdi, %rbx, %ebx, %rcx, $TT_TRAP)
9851414Scindi	TRACE_REGS(%rdi, %rsp, %rbx, %rcx)
9861414Scindi	TRACE_STAMP(%rdi)
9871414Scindi
9881414Scindi	movq	%rsp, %rbp
9891414Scindi
9901414Scindi	movq	%rsp, %rdi	/* arg0 = struct regs *rp */
9911414Scindi	call	cmi_mca_trap	/* cmi_mca_trap(rp); */
9921414Scindi
9931414Scindi	jmp	_sys_rtt
9941414Scindi	SET_SIZE(mcetrap)
9951414Scindi
9961414Scindi#else
9971414Scindi
9981414Scindi	ENTRY_NP(mcetrap)
9991414Scindi	TRAP_NOERR(T_MCE)	/* $18 */
10003446Smrj
10011414Scindi	INTR_PUSH
10023446Smrj	INTGATE_INIT_KERNEL_FLAGS
10031414Scindi
10043446Smrj	TRACE_PTR(%edi, %ebx, %ebx, %ecx, $TT_TRAP)
10053446Smrj	TRACE_REGS(%edi, %esp, %ebx, %ecx)
10063446Smrj	TRACE_STAMP(%edi)
10073446Smrj
10081414Scindi	movl	%esp, %ebp
10091414Scindi
10101414Scindi	movl	%esp, %ecx
10111414Scindi	pushl	%ecx		/* arg0 = struct regs *rp */
10121414Scindi	call	cmi_mca_trap	/* cmi_mca_trap(rp) */
10131414Scindi	addl	$4, %esp	/* pop arg0 */
10141414Scindi
10151414Scindi	jmp	_sys_rtt
10161414Scindi	SET_SIZE(mcetrap)
10171414Scindi
101810Skucharsk#endif
10190Sstevel@tonic-gate
10200Sstevel@tonic-gate	/*
10210Sstevel@tonic-gate	 * #XF
10220Sstevel@tonic-gate	 */
10230Sstevel@tonic-gate	ENTRY_NP(xmtrap)
10240Sstevel@tonic-gate	TRAP_NOERR(T_SIMDFPE)	/* $19 */
10250Sstevel@tonic-gate	jmp	cmntrap
10260Sstevel@tonic-gate	SET_SIZE(xmtrap)
10270Sstevel@tonic-gate
10280Sstevel@tonic-gate	ENTRY_NP(invaltrap)
10290Sstevel@tonic-gate	TRAP_NOERR(30)		/* very invalid */
10300Sstevel@tonic-gate	jmp	cmntrap
10310Sstevel@tonic-gate	SET_SIZE(invaltrap)
10320Sstevel@tonic-gate
10330Sstevel@tonic-gate	ENTRY_NP(invalint)
10340Sstevel@tonic-gate	TRAP_NOERR(31)		/* even more so */
10350Sstevel@tonic-gate	jmp	cmnint
10360Sstevel@tonic-gate	SET_SIZE(invalint)
10370Sstevel@tonic-gate
10380Sstevel@tonic-gate	.globl	fasttable
10390Sstevel@tonic-gate
10400Sstevel@tonic-gate#if defined(__amd64)
10410Sstevel@tonic-gate
10420Sstevel@tonic-gate	ENTRY_NP(fasttrap)
10430Sstevel@tonic-gate	cmpl	$T_LASTFAST, %eax
10440Sstevel@tonic-gate	ja	1f
10450Sstevel@tonic-gate	orl	%eax, %eax	/* (zero extend top 32-bits) */
10460Sstevel@tonic-gate	leaq	fasttable(%rip), %r11
10470Sstevel@tonic-gate	leaq	(%r11, %rax, CLONGSIZE), %r11
10480Sstevel@tonic-gate	jmp	*(%r11)
10490Sstevel@tonic-gate1:
10500Sstevel@tonic-gate	/*
10510Sstevel@tonic-gate	 * Fast syscall number was illegal.  Make it look
10520Sstevel@tonic-gate	 * as if the INT failed.  Modify %rip to point before the
10530Sstevel@tonic-gate	 * INT, push the expected error code and fake a GP fault.
10540Sstevel@tonic-gate	 *
10550Sstevel@tonic-gate	 * XXX Why make the error code be offset into idt + 1?
10560Sstevel@tonic-gate	 * Instead we should push a real (soft?) error code
10570Sstevel@tonic-gate	 * on the stack and #gp handler could know about fasttraps?
10580Sstevel@tonic-gate	 */
10590Sstevel@tonic-gate	subq	$2, (%rsp)	/* XXX int insn 2-bytes */
10600Sstevel@tonic-gate	pushq	$_CONST(_MUL(T_FASTTRAP, GATE_DESC_SIZE) + 2)
10610Sstevel@tonic-gate	jmp	gptrap
10620Sstevel@tonic-gate	SET_SIZE(fasttrap)
10630Sstevel@tonic-gate
10640Sstevel@tonic-gate#elif defined(__i386)
10650Sstevel@tonic-gate
10660Sstevel@tonic-gate	ENTRY_NP(fasttrap)
10670Sstevel@tonic-gate	cmpl	$T_LASTFAST, %eax
10680Sstevel@tonic-gate	ja	1f
10690Sstevel@tonic-gate	jmp	*%cs:fasttable(, %eax, CLONGSIZE)
10700Sstevel@tonic-gate1:
10710Sstevel@tonic-gate	/*
10720Sstevel@tonic-gate	 * Fast syscall number was illegal.  Make it look
10730Sstevel@tonic-gate	 * as if the INT failed.  Modify %eip to point before the
10740Sstevel@tonic-gate	 * INT, push the expected error code and fake a GP fault.
10750Sstevel@tonic-gate	 *
10760Sstevel@tonic-gate	 * XXX Why make the error code be offset into idt + 1?
10770Sstevel@tonic-gate	 * Instead we should push a real (soft?) error code
10780Sstevel@tonic-gate	 * on the stack and #gp handler could know about fasttraps?
10790Sstevel@tonic-gate	 */
10800Sstevel@tonic-gate	subl	$2, (%esp)	/* XXX int insn 2-bytes */
10810Sstevel@tonic-gate	pushl	$_CONST(_MUL(T_FASTTRAP, GATE_DESC_SIZE) + 2)
10820Sstevel@tonic-gate	jmp	gptrap
10830Sstevel@tonic-gate	SET_SIZE(fasttrap)
10840Sstevel@tonic-gate
10850Sstevel@tonic-gate#endif	/* __i386 */
10860Sstevel@tonic-gate
10870Sstevel@tonic-gate	ENTRY_NP(dtrace_ret)
10880Sstevel@tonic-gate	TRAP_NOERR(T_DTRACE_RET)
10890Sstevel@tonic-gate	jmp	dtrace_trap
10900Sstevel@tonic-gate	SET_SIZE(dtrace_ret)
10910Sstevel@tonic-gate
10920Sstevel@tonic-gate#if defined(__amd64)
10930Sstevel@tonic-gate
10940Sstevel@tonic-gate	/*
10950Sstevel@tonic-gate	 * RFLAGS 24 bytes up the stack from %rsp.
10960Sstevel@tonic-gate	 * XXX a constant would be nicer.
10970Sstevel@tonic-gate	 */
10980Sstevel@tonic-gate	ENTRY_NP(fast_null)
10990Sstevel@tonic-gate	orq	$PS_C, 24(%rsp)	/* set carry bit in user flags */
11003446Smrj	IRET
11013446Smrj	/*NOTREACHED*/
11020Sstevel@tonic-gate	SET_SIZE(fast_null)
11030Sstevel@tonic-gate
11040Sstevel@tonic-gate#elif defined(__i386)
11050Sstevel@tonic-gate
11060Sstevel@tonic-gate	ENTRY_NP(fast_null)
11070Sstevel@tonic-gate	orw	$PS_C, 8(%esp)	/* set carry bit in user flags */
11083446Smrj	IRET
11090Sstevel@tonic-gate	SET_SIZE(fast_null)
11100Sstevel@tonic-gate
11110Sstevel@tonic-gate#endif	/* __i386 */
11120Sstevel@tonic-gate
11130Sstevel@tonic-gate	/*
11140Sstevel@tonic-gate	 * Interrupts start at 32
11150Sstevel@tonic-gate	 */
11160Sstevel@tonic-gate#define MKIVCT(n)			\
11170Sstevel@tonic-gate	ENTRY_NP(ivct/**/n)		\
11180Sstevel@tonic-gate	push	$0;			\
11190Sstevel@tonic-gate	push	$n - 0x20;		\
11200Sstevel@tonic-gate	jmp	cmnint;			\
11210Sstevel@tonic-gate	SET_SIZE(ivct/**/n)
11220Sstevel@tonic-gate
11230Sstevel@tonic-gate	MKIVCT(32)
11240Sstevel@tonic-gate	MKIVCT(33)
11250Sstevel@tonic-gate	MKIVCT(34)
11260Sstevel@tonic-gate	MKIVCT(35)
11270Sstevel@tonic-gate	MKIVCT(36)
11280Sstevel@tonic-gate	MKIVCT(37)
11290Sstevel@tonic-gate	MKIVCT(38)
11300Sstevel@tonic-gate	MKIVCT(39)
11310Sstevel@tonic-gate	MKIVCT(40)
11320Sstevel@tonic-gate	MKIVCT(41)
11330Sstevel@tonic-gate	MKIVCT(42)
11340Sstevel@tonic-gate	MKIVCT(43)
11350Sstevel@tonic-gate	MKIVCT(44)
11360Sstevel@tonic-gate	MKIVCT(45)
11370Sstevel@tonic-gate	MKIVCT(46)
11380Sstevel@tonic-gate	MKIVCT(47)
11390Sstevel@tonic-gate	MKIVCT(48)
11400Sstevel@tonic-gate	MKIVCT(49)
11410Sstevel@tonic-gate	MKIVCT(50)
11420Sstevel@tonic-gate	MKIVCT(51)
11430Sstevel@tonic-gate	MKIVCT(52)
11440Sstevel@tonic-gate	MKIVCT(53)
11450Sstevel@tonic-gate	MKIVCT(54)
11460Sstevel@tonic-gate	MKIVCT(55)
11470Sstevel@tonic-gate	MKIVCT(56)
11480Sstevel@tonic-gate	MKIVCT(57)
11490Sstevel@tonic-gate	MKIVCT(58)
11500Sstevel@tonic-gate	MKIVCT(59)
11510Sstevel@tonic-gate	MKIVCT(60)
11520Sstevel@tonic-gate	MKIVCT(61)
11530Sstevel@tonic-gate	MKIVCT(62)
11540Sstevel@tonic-gate	MKIVCT(63)
11550Sstevel@tonic-gate	MKIVCT(64)
11560Sstevel@tonic-gate	MKIVCT(65)
11570Sstevel@tonic-gate	MKIVCT(66)
11580Sstevel@tonic-gate	MKIVCT(67)
11590Sstevel@tonic-gate	MKIVCT(68)
11600Sstevel@tonic-gate	MKIVCT(69)
11610Sstevel@tonic-gate	MKIVCT(70)
11620Sstevel@tonic-gate	MKIVCT(71)
11630Sstevel@tonic-gate	MKIVCT(72)
11640Sstevel@tonic-gate	MKIVCT(73)
11650Sstevel@tonic-gate	MKIVCT(74)
11660Sstevel@tonic-gate	MKIVCT(75)
11670Sstevel@tonic-gate	MKIVCT(76)
11680Sstevel@tonic-gate	MKIVCT(77)
11690Sstevel@tonic-gate	MKIVCT(78)
11700Sstevel@tonic-gate	MKIVCT(79)
11710Sstevel@tonic-gate	MKIVCT(80)
11720Sstevel@tonic-gate	MKIVCT(81)
11730Sstevel@tonic-gate	MKIVCT(82)
11740Sstevel@tonic-gate	MKIVCT(83)
11750Sstevel@tonic-gate	MKIVCT(84)
11760Sstevel@tonic-gate	MKIVCT(85)
11770Sstevel@tonic-gate	MKIVCT(86)
11780Sstevel@tonic-gate	MKIVCT(87)
11790Sstevel@tonic-gate	MKIVCT(88)
11800Sstevel@tonic-gate	MKIVCT(89)
11810Sstevel@tonic-gate	MKIVCT(90)
11820Sstevel@tonic-gate	MKIVCT(91)
11830Sstevel@tonic-gate	MKIVCT(92)
11840Sstevel@tonic-gate	MKIVCT(93)
11850Sstevel@tonic-gate	MKIVCT(94)
11860Sstevel@tonic-gate	MKIVCT(95)
11870Sstevel@tonic-gate	MKIVCT(96)
11880Sstevel@tonic-gate	MKIVCT(97)
11890Sstevel@tonic-gate	MKIVCT(98)
11900Sstevel@tonic-gate	MKIVCT(99)
11910Sstevel@tonic-gate	MKIVCT(100)
11920Sstevel@tonic-gate	MKIVCT(101)
11930Sstevel@tonic-gate	MKIVCT(102)
11940Sstevel@tonic-gate	MKIVCT(103)
11950Sstevel@tonic-gate	MKIVCT(104)
11960Sstevel@tonic-gate	MKIVCT(105)
11970Sstevel@tonic-gate	MKIVCT(106)
11980Sstevel@tonic-gate	MKIVCT(107)
11990Sstevel@tonic-gate	MKIVCT(108)
12000Sstevel@tonic-gate	MKIVCT(109)
12010Sstevel@tonic-gate	MKIVCT(110)
12020Sstevel@tonic-gate	MKIVCT(111)
12030Sstevel@tonic-gate	MKIVCT(112)
12040Sstevel@tonic-gate	MKIVCT(113)
12050Sstevel@tonic-gate	MKIVCT(114)
12060Sstevel@tonic-gate	MKIVCT(115)
12070Sstevel@tonic-gate	MKIVCT(116)
12080Sstevel@tonic-gate	MKIVCT(117)
12090Sstevel@tonic-gate	MKIVCT(118)
12100Sstevel@tonic-gate	MKIVCT(119)
12110Sstevel@tonic-gate	MKIVCT(120)
12120Sstevel@tonic-gate	MKIVCT(121)
12130Sstevel@tonic-gate	MKIVCT(122)
12140Sstevel@tonic-gate	MKIVCT(123)
12150Sstevel@tonic-gate	MKIVCT(124)
12160Sstevel@tonic-gate	MKIVCT(125)
12170Sstevel@tonic-gate	MKIVCT(126)
12180Sstevel@tonic-gate	MKIVCT(127)
12190Sstevel@tonic-gate	MKIVCT(128)
12200Sstevel@tonic-gate	MKIVCT(129)
12210Sstevel@tonic-gate	MKIVCT(130)
12220Sstevel@tonic-gate	MKIVCT(131)
12230Sstevel@tonic-gate	MKIVCT(132)
12240Sstevel@tonic-gate	MKIVCT(133)
12250Sstevel@tonic-gate	MKIVCT(134)
12260Sstevel@tonic-gate	MKIVCT(135)
12270Sstevel@tonic-gate	MKIVCT(136)
12280Sstevel@tonic-gate	MKIVCT(137)
12290Sstevel@tonic-gate	MKIVCT(138)
12300Sstevel@tonic-gate	MKIVCT(139)
12310Sstevel@tonic-gate	MKIVCT(140)
12320Sstevel@tonic-gate	MKIVCT(141)
12330Sstevel@tonic-gate	MKIVCT(142)
12340Sstevel@tonic-gate	MKIVCT(143)
12350Sstevel@tonic-gate	MKIVCT(144)
12360Sstevel@tonic-gate	MKIVCT(145)
12370Sstevel@tonic-gate	MKIVCT(146)
12380Sstevel@tonic-gate	MKIVCT(147)
12390Sstevel@tonic-gate	MKIVCT(148)
12400Sstevel@tonic-gate	MKIVCT(149)
12410Sstevel@tonic-gate	MKIVCT(150)
12420Sstevel@tonic-gate	MKIVCT(151)
12430Sstevel@tonic-gate	MKIVCT(152)
12440Sstevel@tonic-gate	MKIVCT(153)
12450Sstevel@tonic-gate	MKIVCT(154)
12460Sstevel@tonic-gate	MKIVCT(155)
12470Sstevel@tonic-gate	MKIVCT(156)
12480Sstevel@tonic-gate	MKIVCT(157)
12490Sstevel@tonic-gate	MKIVCT(158)
12500Sstevel@tonic-gate	MKIVCT(159)
12510Sstevel@tonic-gate	MKIVCT(160)
12520Sstevel@tonic-gate	MKIVCT(161)
12530Sstevel@tonic-gate	MKIVCT(162)
12540Sstevel@tonic-gate	MKIVCT(163)
12550Sstevel@tonic-gate	MKIVCT(164)
12560Sstevel@tonic-gate	MKIVCT(165)
12570Sstevel@tonic-gate	MKIVCT(166)
12580Sstevel@tonic-gate	MKIVCT(167)
12590Sstevel@tonic-gate	MKIVCT(168)
12600Sstevel@tonic-gate	MKIVCT(169)
12610Sstevel@tonic-gate	MKIVCT(170)
12620Sstevel@tonic-gate	MKIVCT(171)
12630Sstevel@tonic-gate	MKIVCT(172)
12640Sstevel@tonic-gate	MKIVCT(173)
12650Sstevel@tonic-gate	MKIVCT(174)
12660Sstevel@tonic-gate	MKIVCT(175)
12670Sstevel@tonic-gate	MKIVCT(176)
12680Sstevel@tonic-gate	MKIVCT(177)
12690Sstevel@tonic-gate	MKIVCT(178)
12700Sstevel@tonic-gate	MKIVCT(179)
12710Sstevel@tonic-gate	MKIVCT(180)
12720Sstevel@tonic-gate	MKIVCT(181)
12730Sstevel@tonic-gate	MKIVCT(182)
12740Sstevel@tonic-gate	MKIVCT(183)
12750Sstevel@tonic-gate	MKIVCT(184)
12760Sstevel@tonic-gate	MKIVCT(185)
12770Sstevel@tonic-gate	MKIVCT(186)
12780Sstevel@tonic-gate	MKIVCT(187)
12790Sstevel@tonic-gate	MKIVCT(188)
12800Sstevel@tonic-gate	MKIVCT(189)
12810Sstevel@tonic-gate	MKIVCT(190)
12820Sstevel@tonic-gate	MKIVCT(191)
12830Sstevel@tonic-gate	MKIVCT(192)
12840Sstevel@tonic-gate	MKIVCT(193)
12850Sstevel@tonic-gate	MKIVCT(194)
12860Sstevel@tonic-gate	MKIVCT(195)
12870Sstevel@tonic-gate	MKIVCT(196)
12880Sstevel@tonic-gate	MKIVCT(197)
12890Sstevel@tonic-gate	MKIVCT(198)
12900Sstevel@tonic-gate	MKIVCT(199)
12910Sstevel@tonic-gate	MKIVCT(200)
12920Sstevel@tonic-gate	MKIVCT(201)
12930Sstevel@tonic-gate	MKIVCT(202)
12940Sstevel@tonic-gate	MKIVCT(203)
12950Sstevel@tonic-gate	MKIVCT(204)
12960Sstevel@tonic-gate	MKIVCT(205)
12970Sstevel@tonic-gate	MKIVCT(206)
12980Sstevel@tonic-gate	MKIVCT(207)
12990Sstevel@tonic-gate	MKIVCT(208)
13000Sstevel@tonic-gate	MKIVCT(209)
13010Sstevel@tonic-gate	MKIVCT(210)
13020Sstevel@tonic-gate	MKIVCT(211)
13030Sstevel@tonic-gate	MKIVCT(212)
13040Sstevel@tonic-gate	MKIVCT(213)
13050Sstevel@tonic-gate	MKIVCT(214)
13060Sstevel@tonic-gate	MKIVCT(215)
13070Sstevel@tonic-gate	MKIVCT(216)
13080Sstevel@tonic-gate	MKIVCT(217)
13090Sstevel@tonic-gate	MKIVCT(218)
13100Sstevel@tonic-gate	MKIVCT(219)
13110Sstevel@tonic-gate	MKIVCT(220)
13120Sstevel@tonic-gate	MKIVCT(221)
13130Sstevel@tonic-gate	MKIVCT(222)
13140Sstevel@tonic-gate	MKIVCT(223)
13150Sstevel@tonic-gate	MKIVCT(224)
13160Sstevel@tonic-gate	MKIVCT(225)
13170Sstevel@tonic-gate	MKIVCT(226)
13180Sstevel@tonic-gate	MKIVCT(227)
13190Sstevel@tonic-gate	MKIVCT(228)
13200Sstevel@tonic-gate	MKIVCT(229)
13210Sstevel@tonic-gate	MKIVCT(230)
13220Sstevel@tonic-gate	MKIVCT(231)
13230Sstevel@tonic-gate	MKIVCT(232)
13240Sstevel@tonic-gate	MKIVCT(233)
13250Sstevel@tonic-gate	MKIVCT(234)
13260Sstevel@tonic-gate	MKIVCT(235)
13270Sstevel@tonic-gate	MKIVCT(236)
13280Sstevel@tonic-gate	MKIVCT(237)
13290Sstevel@tonic-gate	MKIVCT(238)
13300Sstevel@tonic-gate	MKIVCT(239)
13310Sstevel@tonic-gate	MKIVCT(240)
13320Sstevel@tonic-gate	MKIVCT(241)
13330Sstevel@tonic-gate	MKIVCT(242)
13340Sstevel@tonic-gate	MKIVCT(243)
13350Sstevel@tonic-gate	MKIVCT(244)
13360Sstevel@tonic-gate	MKIVCT(245)
13370Sstevel@tonic-gate	MKIVCT(246)
13380Sstevel@tonic-gate	MKIVCT(247)
13390Sstevel@tonic-gate	MKIVCT(248)
13400Sstevel@tonic-gate	MKIVCT(249)
13410Sstevel@tonic-gate	MKIVCT(250)
13420Sstevel@tonic-gate	MKIVCT(251)
13430Sstevel@tonic-gate	MKIVCT(252)
13440Sstevel@tonic-gate	MKIVCT(253)
13450Sstevel@tonic-gate	MKIVCT(254)
13460Sstevel@tonic-gate	MKIVCT(255)
13470Sstevel@tonic-gate
13480Sstevel@tonic-gate#endif	/* __lint */
1349