10Sstevel@tonic-gate/* 2*3446Smrj * 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> 51*3446Smrj#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 */ 75*3446Smrj 760Sstevel@tonic-gate#define TRAP_NOERR(trapno) \ 770Sstevel@tonic-gate push $0; \ 780Sstevel@tonic-gate push $trapno 790Sstevel@tonic-gate 80*3446Smrj#define NPTRAP_NOERR(trapno) TRAP_NOERR(trapno) 81*3446Smrj 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 89*3446Smrj 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 * 101*3446Smrj * Fetch %dr6 and clear it, handing off the value to the 102*3446Smrj * cmntrap code in %r15/%esi 103*3446Smrj */ 104*3446Smrj ENTRY_NP(dbgtrap) 105*3446Smrj TRAP_NOERR(T_SGLSTP) /* $1 */ 106*3446Smrj 107*3446Smrj#if defined(__amd64) 108*3446Smrj /* 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 */ 1190Sstevel@tonic-gate pushq %r11 1200Sstevel@tonic-gate leaq sys_sysenter(%rip), %r11 1210Sstevel@tonic-gate cmpq %r11, 8(%rsp) 1220Sstevel@tonic-gate jne 1f 123*3446Smrj SWAPGS 1240Sstevel@tonic-gate1: popq %r11 125*3446Smrj 126*3446Smrj INTR_PUSH 127*3446Smrj movq %db6, %r15 128*3446Smrj xorl %eax, %eax 129*3446Smrj movq %rax, %db6 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate#elif defined(__i386) 132*3446Smrj 133*3446Smrj INTR_PUSH 134*3446Smrj movl %db6, %esi 135*3446Smrj xorl %eax, %eax 136*3446Smrj movl %eax, %db6 137*3446Smrj#endif /* __i386 */ 138*3446Smrj 139*3446Smrj jmp cmntrap_pushed 1400Sstevel@tonic-gate SET_SIZE(dbgtrap) 1410Sstevel@tonic-gate 1420Sstevel@tonic-gate#if defined(__amd64) 1430Sstevel@tonic-gate 1440Sstevel@tonic-gate/* 1450Sstevel@tonic-gate * Macro to set the gsbase or kgsbase to the address of the struct cpu 146*3446Smrj * for this processor. If we came from userland, set kgsbase else 147*3446Smrj * set gsbase. We find the proper cpu struct by looping through 1480Sstevel@tonic-gate * the cpu structs for all processors till we find a match for the gdt 1490Sstevel@tonic-gate * of the trapping processor. The stack is expected to be pointing at 150*3446Smrj * the standard regs pushed by hardware on a trap (plus error code and trapno). 1510Sstevel@tonic-gate */ 1520Sstevel@tonic-gate#define SET_CPU_GSBASE \ 1530Sstevel@tonic-gate subq $REGOFF_TRAPNO, %rsp; /* save regs */ \ 1540Sstevel@tonic-gate movq %rax, REGOFF_RAX(%rsp); \ 1550Sstevel@tonic-gate movq %rbx, REGOFF_RBX(%rsp); \ 1560Sstevel@tonic-gate movq %rcx, REGOFF_RCX(%rsp); \ 1570Sstevel@tonic-gate movq %rdx, REGOFF_RDX(%rsp); \ 1580Sstevel@tonic-gate movq %rbp, REGOFF_RBP(%rsp); \ 1590Sstevel@tonic-gate movq %rsp, %rbp; \ 1600Sstevel@tonic-gate subq $16, %rsp; /* space for gdt */ \ 1610Sstevel@tonic-gate sgdt 6(%rsp); \ 1620Sstevel@tonic-gate movq 8(%rsp), %rcx; /* %rcx has gdt to match */ \ 1630Sstevel@tonic-gate xorl %ebx, %ebx; /* loop index */ \ 1640Sstevel@tonic-gate leaq cpu(%rip), %rdx; /* cpu pointer array */ \ 1650Sstevel@tonic-gate1: \ 1660Sstevel@tonic-gate movq (%rdx, %rbx, CLONGSIZE), %rax; /* get cpu[i] */ \ 1670Sstevel@tonic-gate cmpq $0x0, %rax; /* cpu[i] == NULL ? */ \ 1680Sstevel@tonic-gate je 2f; /* yes, continue */ \ 1690Sstevel@tonic-gate cmpq %rcx, CPU_GDT(%rax); /* gdt == cpu[i]->cpu_gdt ? */ \ 1700Sstevel@tonic-gate je 3f; /* yes, go set gsbase */ \ 1710Sstevel@tonic-gate2: \ 1720Sstevel@tonic-gate incl %ebx; /* i++ */ \ 1730Sstevel@tonic-gate cmpl $NCPU, %ebx; /* i < NCPU ? */ \ 1740Sstevel@tonic-gate jb 1b; /* yes, loop */ \ 1750Sstevel@tonic-gate/* XXX BIG trouble if we fall thru here. We didn't find a gdt match */ \ 1760Sstevel@tonic-gate3: \ 1770Sstevel@tonic-gate movl $MSR_AMD_KGSBASE, %ecx; \ 1780Sstevel@tonic-gate cmpw $KCS_SEL, REGOFF_CS(%rbp); /* trap from kernel? */ \ 1790Sstevel@tonic-gate jne 4f; /* no, go set KGSBASE */ \ 1800Sstevel@tonic-gate movl $MSR_AMD_GSBASE, %ecx; /* yes, set GSBASE */ \ 1810Sstevel@tonic-gate mfence; /* OPTERON_ERRATUM_88 */ \ 1820Sstevel@tonic-gate4: \ 1830Sstevel@tonic-gate movq %rax, %rdx; /* write base register */ \ 1840Sstevel@tonic-gate shrq $32, %rdx; \ 1850Sstevel@tonic-gate wrmsr; \ 1860Sstevel@tonic-gate movq REGOFF_RDX(%rbp), %rdx; /* restore regs */ \ 1870Sstevel@tonic-gate movq REGOFF_RCX(%rbp), %rcx; \ 1880Sstevel@tonic-gate movq REGOFF_RBX(%rbp), %rbx; \ 1890Sstevel@tonic-gate movq REGOFF_RAX(%rbp), %rax; \ 1900Sstevel@tonic-gate movq %rbp, %rsp; \ 1910Sstevel@tonic-gate movq REGOFF_RBP(%rsp), %rbp; \ 1920Sstevel@tonic-gate addq $REGOFF_TRAPNO, %rsp /* pop stack */ 193*3446Smrj 1940Sstevel@tonic-gate#endif /* __amd64 */ 195*3446Smrj 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate#if defined(__amd64) 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate /* 2000Sstevel@tonic-gate * #NMI 2010Sstevel@tonic-gate */ 2020Sstevel@tonic-gate ENTRY_NP(nmiint) 2030Sstevel@tonic-gate TRAP_NOERR(T_NMIFLT) /* $2 */ 2040Sstevel@tonic-gate 2050Sstevel@tonic-gate SET_CPU_GSBASE 2060Sstevel@tonic-gate 2070Sstevel@tonic-gate /* 2080Sstevel@tonic-gate * Save all registers and setup segment registers 2090Sstevel@tonic-gate * with kernel selectors. 2100Sstevel@tonic-gate */ 2110Sstevel@tonic-gate INTR_PUSH 212*3446Smrj INTGATE_INIT_KERNEL_FLAGS 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate TRACE_PTR(%r12, %rax, %eax, %rdx, $TT_TRAP) 2150Sstevel@tonic-gate TRACE_REGS(%r12, %rsp, %rax, %rbx) 2160Sstevel@tonic-gate TRACE_STAMP(%r12) 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate movq %rsp, %rbp 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate movq %rbp, %rdi 2210Sstevel@tonic-gate call av_dispatch_nmivect 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate INTR_POP 224*3446Smrj IRET 225*3446Smrj /*NOTREACHED*/ 2260Sstevel@tonic-gate SET_SIZE(nmiint) 2270Sstevel@tonic-gate 2280Sstevel@tonic-gate#elif defined(__i386) 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate /* 2310Sstevel@tonic-gate * #NMI 2320Sstevel@tonic-gate */ 2330Sstevel@tonic-gate ENTRY_NP(nmiint) 2340Sstevel@tonic-gate TRAP_NOERR(T_NMIFLT) /* $2 */ 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate /* 2370Sstevel@tonic-gate * Save all registers and setup segment registers 2380Sstevel@tonic-gate * with kernel selectors. 2390Sstevel@tonic-gate */ 2400Sstevel@tonic-gate INTR_PUSH 241*3446Smrj INTGATE_INIT_KERNEL_FLAGS 2420Sstevel@tonic-gate 243*3446Smrj TRACE_PTR(%edi, %ebx, %ebx, %ecx, $TT_TRAP) 244*3446Smrj TRACE_REGS(%edi, %esp, %ebx, %ecx) 245*3446Smrj TRACE_STAMP(%edi) 2460Sstevel@tonic-gate 247*3446Smrj movl %esp, %ebp 248*3446Smrj 249*3446Smrj pushl %ebp 250*3446Smrj call av_dispatch_nmivect 2510Sstevel@tonic-gate addl $4, %esp 2520Sstevel@tonic-gate 2530Sstevel@tonic-gate INTR_POP_USER 254*3446Smrj IRET 2550Sstevel@tonic-gate SET_SIZE(nmiint) 2560Sstevel@tonic-gate 2570Sstevel@tonic-gate#endif /* __i386 */ 2580Sstevel@tonic-gate 2590Sstevel@tonic-gate /* 2600Sstevel@tonic-gate * #BP 2610Sstevel@tonic-gate */ 2620Sstevel@tonic-gate ENTRY_NP(brktrap) 263*3446Smrj 2640Sstevel@tonic-gate#if defined(__amd64) 2650Sstevel@tonic-gate cmpw $KCS_SEL, 8(%rsp) 266*3446Smrj jne bp_user 2670Sstevel@tonic-gate 2680Sstevel@tonic-gate /* 2690Sstevel@tonic-gate * This is a breakpoint in the kernel -- it is very likely that this 2700Sstevel@tonic-gate * is DTrace-induced. To unify DTrace handling, we spoof this as an 2710Sstevel@tonic-gate * invalid opcode (#UD) fault. Note that #BP is a trap, not a fault -- 2720Sstevel@tonic-gate * we must decrement the trapping %rip to make it appear as a fault. 2730Sstevel@tonic-gate * We then push a non-zero error code to indicate that this is coming 2740Sstevel@tonic-gate * from #BP. 2750Sstevel@tonic-gate */ 2760Sstevel@tonic-gate decq (%rsp) 2770Sstevel@tonic-gate push $1 /* error code -- non-zero for #BP */ 2780Sstevel@tonic-gate jmp ud_kernel 279*3446Smrj 280*3446Smrjbp_user: 281*3446Smrj#endif /* __amd64 */ 282*3446Smrj 283*3446Smrj NPTRAP_NOERR(T_BPTFLT) /* $3 */ 284*3446Smrj jmp dtrace_trap 285*3446Smrj 2860Sstevel@tonic-gate SET_SIZE(brktrap) 2870Sstevel@tonic-gate 2880Sstevel@tonic-gate /* 2890Sstevel@tonic-gate * #OF 2900Sstevel@tonic-gate */ 2910Sstevel@tonic-gate ENTRY_NP(ovflotrap) 2920Sstevel@tonic-gate TRAP_NOERR(T_OVFLW) /* $4 */ 2930Sstevel@tonic-gate jmp cmntrap 2940Sstevel@tonic-gate SET_SIZE(ovflotrap) 2950Sstevel@tonic-gate 2960Sstevel@tonic-gate /* 2970Sstevel@tonic-gate * #BR 2980Sstevel@tonic-gate */ 2990Sstevel@tonic-gate ENTRY_NP(boundstrap) 3000Sstevel@tonic-gate TRAP_NOERR(T_BOUNDFLT) /* $5 */ 3010Sstevel@tonic-gate jmp cmntrap 3020Sstevel@tonic-gate SET_SIZE(boundstrap) 3030Sstevel@tonic-gate 3040Sstevel@tonic-gate#if defined(__amd64) 3050Sstevel@tonic-gate 3060Sstevel@tonic-gate ENTRY_NP(invoptrap) 307*3446Smrj 3080Sstevel@tonic-gate cmpw $KCS_SEL, 8(%rsp) 3090Sstevel@tonic-gate jne ud_user 3100Sstevel@tonic-gate 3110Sstevel@tonic-gate push $0 /* error code -- zero for #UD */ 3120Sstevel@tonic-gateud_kernel: 3130Sstevel@tonic-gate push $0xdddd /* a dummy trap number */ 314*3446Smrj INTR_PUSH 3150Sstevel@tonic-gate movq REGOFF_RIP(%rsp), %rdi 3160Sstevel@tonic-gate movq REGOFF_RSP(%rsp), %rsi 3170Sstevel@tonic-gate movq REGOFF_RAX(%rsp), %rdx 3180Sstevel@tonic-gate pushq (%rsi) 3190Sstevel@tonic-gate movq %rsp, %rsi 3200Sstevel@tonic-gate call dtrace_invop 3210Sstevel@tonic-gate ALTENTRY(dtrace_invop_callsite) 3220Sstevel@tonic-gate addq $8, %rsp 3230Sstevel@tonic-gate cmpl $DTRACE_INVOP_PUSHL_EBP, %eax 3240Sstevel@tonic-gate je ud_push 3250Sstevel@tonic-gate cmpl $DTRACE_INVOP_LEAVE, %eax 3260Sstevel@tonic-gate je ud_leave 3270Sstevel@tonic-gate cmpl $DTRACE_INVOP_NOP, %eax 3280Sstevel@tonic-gate je ud_nop 3290Sstevel@tonic-gate cmpl $DTRACE_INVOP_RET, %eax 3300Sstevel@tonic-gate je ud_ret 3310Sstevel@tonic-gate jmp ud_trap 3320Sstevel@tonic-gate 3330Sstevel@tonic-gateud_push: 3340Sstevel@tonic-gate /* 3350Sstevel@tonic-gate * We must emulate a "pushq %rbp". To do this, we pull the stack 3360Sstevel@tonic-gate * down 8 bytes, and then store the base pointer. 3370Sstevel@tonic-gate */ 3380Sstevel@tonic-gate INTR_POP 3390Sstevel@tonic-gate subq $16, %rsp /* make room for %rbp */ 3400Sstevel@tonic-gate pushq %rax /* push temp */ 3410Sstevel@tonic-gate movq 24(%rsp), %rax /* load calling RIP */ 3420Sstevel@tonic-gate addq $1, %rax /* increment over trapping instr */ 3430Sstevel@tonic-gate movq %rax, 8(%rsp) /* store calling RIP */ 3440Sstevel@tonic-gate movq 32(%rsp), %rax /* load calling CS */ 3450Sstevel@tonic-gate movq %rax, 16(%rsp) /* store calling CS */ 3460Sstevel@tonic-gate movq 40(%rsp), %rax /* load calling RFLAGS */ 3470Sstevel@tonic-gate movq %rax, 24(%rsp) /* store calling RFLAGS */ 3480Sstevel@tonic-gate movq 48(%rsp), %rax /* load calling RSP */ 3490Sstevel@tonic-gate subq $8, %rax /* make room for %rbp */ 3500Sstevel@tonic-gate movq %rax, 32(%rsp) /* store calling RSP */ 3510Sstevel@tonic-gate movq 56(%rsp), %rax /* load calling SS */ 3520Sstevel@tonic-gate movq %rax, 40(%rsp) /* store calling SS */ 3530Sstevel@tonic-gate movq 32(%rsp), %rax /* reload calling RSP */ 3540Sstevel@tonic-gate movq %rbp, (%rax) /* store %rbp there */ 3550Sstevel@tonic-gate popq %rax /* pop off temp */ 356*3446Smrj IRET /* return from interrupt */ 357*3446Smrj /*NOTREACHED*/ 3580Sstevel@tonic-gate 3590Sstevel@tonic-gateud_leave: 3600Sstevel@tonic-gate /* 3610Sstevel@tonic-gate * We must emulate a "leave", which is the same as a "movq %rbp, %rsp" 3620Sstevel@tonic-gate * followed by a "popq %rbp". This is quite a bit simpler on amd64 3630Sstevel@tonic-gate * than it is on i386 -- we can exploit the fact that the %rsp is 3640Sstevel@tonic-gate * explicitly saved to effect the pop without having to reshuffle 3650Sstevel@tonic-gate * the other data pushed for the trap. 3660Sstevel@tonic-gate */ 3670Sstevel@tonic-gate INTR_POP 3680Sstevel@tonic-gate pushq %rax /* push temp */ 3690Sstevel@tonic-gate movq 8(%rsp), %rax /* load calling RIP */ 3700Sstevel@tonic-gate addq $1, %rax /* increment over trapping instr */ 3710Sstevel@tonic-gate movq %rax, 8(%rsp) /* store calling RIP */ 3720Sstevel@tonic-gate movq (%rbp), %rax /* get new %rbp */ 3730Sstevel@tonic-gate addq $8, %rbp /* adjust new %rsp */ 3740Sstevel@tonic-gate movq %rbp, 32(%rsp) /* store new %rsp */ 3750Sstevel@tonic-gate movq %rax, %rbp /* set new %rbp */ 3760Sstevel@tonic-gate popq %rax /* pop off temp */ 377*3446Smrj IRET /* return from interrupt */ 378*3446Smrj /*NOTREACHED*/ 3790Sstevel@tonic-gate 3800Sstevel@tonic-gateud_nop: 3810Sstevel@tonic-gate /* 3820Sstevel@tonic-gate * We must emulate a "nop". This is obviously not hard: we need only 3830Sstevel@tonic-gate * advance the %rip by one. 3840Sstevel@tonic-gate */ 3850Sstevel@tonic-gate INTR_POP 3860Sstevel@tonic-gate incq (%rsp) 387*3446Smrj IRET 388*3446Smrj /*NOTREACHED*/ 3890Sstevel@tonic-gate 3900Sstevel@tonic-gateud_ret: 3910Sstevel@tonic-gate INTR_POP 3920Sstevel@tonic-gate pushq %rax /* push temp */ 3930Sstevel@tonic-gate movq 32(%rsp), %rax /* load %rsp */ 3940Sstevel@tonic-gate movq (%rax), %rax /* load calling RIP */ 3950Sstevel@tonic-gate movq %rax, 8(%rsp) /* store calling RIP */ 3960Sstevel@tonic-gate addq $8, 32(%rsp) /* adjust new %rsp */ 3970Sstevel@tonic-gate popq %rax /* pop off temp */ 398*3446Smrj IRET /* return from interrupt */ 399*3446Smrj /*NOTREACHED*/ 4000Sstevel@tonic-gate 4010Sstevel@tonic-gateud_trap: 4020Sstevel@tonic-gate /* 4030Sstevel@tonic-gate * We're going to let the kernel handle this as a normal #UD. If, 4040Sstevel@tonic-gate * however, we came through #BP and are spoofing #UD (in this case, 4050Sstevel@tonic-gate * the stored error value will be non-zero), we need to de-spoof 4060Sstevel@tonic-gate * the trap by incrementing %rip and pushing T_BPTFLT. 4070Sstevel@tonic-gate */ 4080Sstevel@tonic-gate cmpq $0, REGOFF_ERR(%rsp) 4090Sstevel@tonic-gate je ud_ud 4100Sstevel@tonic-gate incq REGOFF_RIP(%rsp) 4110Sstevel@tonic-gate addq $REGOFF_RIP, %rsp 412*3446Smrj NPTRAP_NOERR(T_BPTFLT) /* $3 */ 4130Sstevel@tonic-gate jmp cmntrap 4140Sstevel@tonic-gate 4150Sstevel@tonic-gateud_ud: 4160Sstevel@tonic-gate addq $REGOFF_RIP, %rsp 4170Sstevel@tonic-gateud_user: 418*3446Smrj NPTRAP_NOERR(T_ILLINST) 4190Sstevel@tonic-gate jmp cmntrap 4200Sstevel@tonic-gate SET_SIZE(invoptrap) 4210Sstevel@tonic-gate 4220Sstevel@tonic-gate#elif defined(__i386) 4230Sstevel@tonic-gate 4240Sstevel@tonic-gate /* 4250Sstevel@tonic-gate * #UD 4260Sstevel@tonic-gate */ 4270Sstevel@tonic-gate ENTRY_NP(invoptrap) 4280Sstevel@tonic-gate /* 4290Sstevel@tonic-gate * If we are taking an invalid opcode trap while in the kernel, this 4300Sstevel@tonic-gate * is likely an FBT probe point. 4310Sstevel@tonic-gate */ 4320Sstevel@tonic-gate pushl %gs 4330Sstevel@tonic-gate cmpw $KGS_SEL, (%esp) 4340Sstevel@tonic-gate jne 8f 435*3446Smrj 4360Sstevel@tonic-gate addl $4, %esp 4370Sstevel@tonic-gate pusha 4380Sstevel@tonic-gate pushl %eax /* push %eax -- may be return value */ 4390Sstevel@tonic-gate pushl %esp /* push stack pointer */ 4400Sstevel@tonic-gate addl $48, (%esp) /* adjust to incoming args */ 4410Sstevel@tonic-gate pushl 40(%esp) /* push calling EIP */ 4420Sstevel@tonic-gate call dtrace_invop 4430Sstevel@tonic-gate ALTENTRY(dtrace_invop_callsite) 4440Sstevel@tonic-gate addl $12, %esp 4450Sstevel@tonic-gate cmpl $DTRACE_INVOP_PUSHL_EBP, %eax 4460Sstevel@tonic-gate je 1f 4470Sstevel@tonic-gate cmpl $DTRACE_INVOP_POPL_EBP, %eax 4480Sstevel@tonic-gate je 2f 4490Sstevel@tonic-gate cmpl $DTRACE_INVOP_LEAVE, %eax 4500Sstevel@tonic-gate je 3f 4510Sstevel@tonic-gate cmpl $DTRACE_INVOP_NOP, %eax 4520Sstevel@tonic-gate je 4f 4530Sstevel@tonic-gate jmp 7f 4540Sstevel@tonic-gate1: 4550Sstevel@tonic-gate /* 4560Sstevel@tonic-gate * We must emulate a "pushl %ebp". To do this, we pull the stack 4570Sstevel@tonic-gate * down 4 bytes, and then store the base pointer. 4580Sstevel@tonic-gate */ 4590Sstevel@tonic-gate popa 4600Sstevel@tonic-gate subl $4, %esp /* make room for %ebp */ 4610Sstevel@tonic-gate pushl %eax /* push temp */ 4620Sstevel@tonic-gate movl 8(%esp), %eax /* load calling EIP */ 4630Sstevel@tonic-gate incl %eax /* increment over LOCK prefix */ 4640Sstevel@tonic-gate movl %eax, 4(%esp) /* store calling EIP */ 4650Sstevel@tonic-gate movl 12(%esp), %eax /* load calling CS */ 4660Sstevel@tonic-gate movl %eax, 8(%esp) /* store calling CS */ 4670Sstevel@tonic-gate movl 16(%esp), %eax /* load calling EFLAGS */ 4680Sstevel@tonic-gate movl %eax, 12(%esp) /* store calling EFLAGS */ 4690Sstevel@tonic-gate movl %ebp, 16(%esp) /* push %ebp */ 4700Sstevel@tonic-gate popl %eax /* pop off temp */ 471*3446Smrj jmp _emul_done 4720Sstevel@tonic-gate2: 4730Sstevel@tonic-gate /* 4740Sstevel@tonic-gate * We must emulate a "popl %ebp". To do this, we do the opposite of 4750Sstevel@tonic-gate * the above: we remove the %ebp from the stack, and squeeze up the 4760Sstevel@tonic-gate * saved state from the trap. 4770Sstevel@tonic-gate */ 4780Sstevel@tonic-gate popa 4790Sstevel@tonic-gate pushl %eax /* push temp */ 4800Sstevel@tonic-gate movl 16(%esp), %ebp /* pop %ebp */ 4810Sstevel@tonic-gate movl 12(%esp), %eax /* load calling EFLAGS */ 4820Sstevel@tonic-gate movl %eax, 16(%esp) /* store calling EFLAGS */ 4830Sstevel@tonic-gate movl 8(%esp), %eax /* load calling CS */ 4840Sstevel@tonic-gate movl %eax, 12(%esp) /* store calling CS */ 4850Sstevel@tonic-gate movl 4(%esp), %eax /* load calling EIP */ 4860Sstevel@tonic-gate incl %eax /* increment over LOCK prefix */ 4870Sstevel@tonic-gate movl %eax, 8(%esp) /* store calling EIP */ 4880Sstevel@tonic-gate popl %eax /* pop off temp */ 4890Sstevel@tonic-gate addl $4, %esp /* adjust stack pointer */ 490*3446Smrj jmp _emul_done 4910Sstevel@tonic-gate3: 4920Sstevel@tonic-gate /* 4930Sstevel@tonic-gate * We must emulate a "leave", which is the same as a "movl %ebp, %esp" 4940Sstevel@tonic-gate * followed by a "popl %ebp". This looks similar to the above, but 4950Sstevel@tonic-gate * requires two temporaries: one for the new base pointer, and one 4960Sstevel@tonic-gate * for the staging register. 4970Sstevel@tonic-gate */ 4980Sstevel@tonic-gate popa 4990Sstevel@tonic-gate pushl %eax /* push temp */ 5000Sstevel@tonic-gate pushl %ebx /* push temp */ 5010Sstevel@tonic-gate movl %ebp, %ebx /* set temp to old %ebp */ 5020Sstevel@tonic-gate movl (%ebx), %ebp /* pop %ebp */ 5030Sstevel@tonic-gate movl 16(%esp), %eax /* load calling EFLAGS */ 5040Sstevel@tonic-gate movl %eax, (%ebx) /* store calling EFLAGS */ 5050Sstevel@tonic-gate movl 12(%esp), %eax /* load calling CS */ 5060Sstevel@tonic-gate movl %eax, -4(%ebx) /* store calling CS */ 5070Sstevel@tonic-gate movl 8(%esp), %eax /* load calling EIP */ 5080Sstevel@tonic-gate incl %eax /* increment over LOCK prefix */ 5090Sstevel@tonic-gate movl %eax, -8(%ebx) /* store calling EIP */ 5100Sstevel@tonic-gate movl %ebx, -4(%esp) /* temporarily store new %esp */ 5110Sstevel@tonic-gate popl %ebx /* pop off temp */ 5120Sstevel@tonic-gate popl %eax /* pop off temp */ 5130Sstevel@tonic-gate movl -12(%esp), %esp /* set stack pointer */ 5140Sstevel@tonic-gate subl $8, %esp /* adjust for three pushes, one pop */ 515*3446Smrj jmp _emul_done 5160Sstevel@tonic-gate4: 5170Sstevel@tonic-gate /* 5180Sstevel@tonic-gate * We must emulate a "nop". This is obviously not hard: we need only 5190Sstevel@tonic-gate * advance the %eip by one. 5200Sstevel@tonic-gate */ 5210Sstevel@tonic-gate popa 5220Sstevel@tonic-gate incl (%esp) 523*3446Smrj_emul_done: 524*3446Smrj IRET /* return from interrupt */ 5250Sstevel@tonic-gate7: 5260Sstevel@tonic-gate popa 5270Sstevel@tonic-gate pushl $0 5280Sstevel@tonic-gate pushl $T_ILLINST /* $6 */ 5290Sstevel@tonic-gate jmp cmntrap 5300Sstevel@tonic-gate8: 5310Sstevel@tonic-gate addl $4, %esp 5320Sstevel@tonic-gate pushl $0 5330Sstevel@tonic-gate pushl $T_ILLINST /* $6 */ 5340Sstevel@tonic-gate jmp cmntrap 5350Sstevel@tonic-gate SET_SIZE(invoptrap) 5360Sstevel@tonic-gate 5370Sstevel@tonic-gate#endif /* __i386 */ 5380Sstevel@tonic-gate 5390Sstevel@tonic-gate#if defined(__amd64) 5400Sstevel@tonic-gate 5410Sstevel@tonic-gate /* 5420Sstevel@tonic-gate * #NM 5430Sstevel@tonic-gate */ 5440Sstevel@tonic-gate ENTRY_NP(ndptrap) 5450Sstevel@tonic-gate /* 5460Sstevel@tonic-gate * We want to do this quickly as every lwp using fp will take this 5470Sstevel@tonic-gate * after a context switch -- we do the frequent path in ndptrap_frstor 5480Sstevel@tonic-gate * below; for all other cases, we let the trap code handle it 5490Sstevel@tonic-gate */ 5500Sstevel@tonic-gate pushq %rax 5510Sstevel@tonic-gate pushq %rbx 5520Sstevel@tonic-gate cmpw $KCS_SEL, 24(%rsp) /* did we come from kernel mode? */ 5530Sstevel@tonic-gate jne 1f 5540Sstevel@tonic-gate LOADCPU(%rbx) /* if yes, don't swapgs */ 5550Sstevel@tonic-gate jmp 2f 5560Sstevel@tonic-gate1: 557*3446Smrj SWAPGS /* if from user, need swapgs */ 5580Sstevel@tonic-gate LOADCPU(%rbx) 559*3446Smrj SWAPGS 5600Sstevel@tonic-gate2: 5610Sstevel@tonic-gate cmpl $0, fpu_exists(%rip) 5620Sstevel@tonic-gate je .handle_in_trap /* let trap handle no fp case */ 5630Sstevel@tonic-gate movq CPU_THREAD(%rbx), %rax /* %rax = curthread */ 5640Sstevel@tonic-gate movl $FPU_EN, %ebx 5650Sstevel@tonic-gate movq T_LWP(%rax), %rax /* %rax = lwp */ 5660Sstevel@tonic-gate testq %rax, %rax 5670Sstevel@tonic-gate jz .handle_in_trap /* should not happen? */ 5680Sstevel@tonic-gate#if LWP_PCB_FPU != 0 5690Sstevel@tonic-gate addq $LWP_PCB_FPU, %rax /* &lwp->lwp_pcb.pcb_fpu */ 5700Sstevel@tonic-gate#endif 5710Sstevel@tonic-gate testl %ebx, PCB_FPU_FLAGS(%rax) 5720Sstevel@tonic-gate jz .handle_in_trap /* must be the first fault */ 5730Sstevel@tonic-gate clts 5740Sstevel@tonic-gate andl $_BITNOT(FPU_VALID), PCB_FPU_FLAGS(%rax) 5750Sstevel@tonic-gate#if FPU_CTX_FPU_REGS != 0 5760Sstevel@tonic-gate addq $FPU_CTX_FPU_REGS, %rax 5770Sstevel@tonic-gate#endif 5780Sstevel@tonic-gate /* 5790Sstevel@tonic-gate * the label below is used in trap.c to detect FP faults in 5800Sstevel@tonic-gate * kernel due to user fault. 5810Sstevel@tonic-gate */ 5820Sstevel@tonic-gate ALTENTRY(ndptrap_frstor) 5830Sstevel@tonic-gate fxrstor (%rax) 5840Sstevel@tonic-gate popq %rbx 5850Sstevel@tonic-gate popq %rax 586*3446Smrj IRET 587*3446Smrj /*NOTREACHED*/ 5880Sstevel@tonic-gate 5890Sstevel@tonic-gate.handle_in_trap: 5900Sstevel@tonic-gate popq %rbx 5910Sstevel@tonic-gate popq %rax 5920Sstevel@tonic-gate TRAP_NOERR(T_NOEXTFLT) /* $7 */ 5930Sstevel@tonic-gate jmp cmninttrap 5940Sstevel@tonic-gate SET_SIZE(ndptrap_frstor) 5950Sstevel@tonic-gate SET_SIZE(ndptrap) 5960Sstevel@tonic-gate 5970Sstevel@tonic-gate#elif defined(__i386) 5980Sstevel@tonic-gate 5990Sstevel@tonic-gate ENTRY_NP(ndptrap) 6000Sstevel@tonic-gate /* 6010Sstevel@tonic-gate * We want to do this quickly as every lwp using fp will take this 6020Sstevel@tonic-gate * after a context switch -- we do the frequent path in fpnoextflt 6030Sstevel@tonic-gate * below; for all other cases, we let the trap code handle it 6040Sstevel@tonic-gate */ 6050Sstevel@tonic-gate pushl %eax 6060Sstevel@tonic-gate pushl %ebx 6070Sstevel@tonic-gate pushl %ds 6080Sstevel@tonic-gate pushl %gs 6090Sstevel@tonic-gate movl $KDS_SEL, %ebx 6100Sstevel@tonic-gate movw %bx, %ds 6110Sstevel@tonic-gate movl $KGS_SEL, %eax 6120Sstevel@tonic-gate movw %ax, %gs 613*3446Smrj LOADCPU(%eax) 6140Sstevel@tonic-gate cmpl $0, fpu_exists 6150Sstevel@tonic-gate je .handle_in_trap /* let trap handle no fp case */ 616*3446Smrj movl CPU_THREAD(%eax), %ebx /* %ebx = curthread */ 617*3446Smrj movl $FPU_EN, %eax 618*3446Smrj movl T_LWP(%ebx), %ebx /* %ebx = lwp */ 619*3446Smrj testl %ebx, %ebx 6200Sstevel@tonic-gate jz .handle_in_trap /* should not happen? */ 6210Sstevel@tonic-gate#if LWP_PCB_FPU != 0 622*3446Smrj addl $LWP_PCB_FPU, %ebx /* &lwp->lwp_pcb.pcb_fpu */ 6230Sstevel@tonic-gate#endif 624*3446Smrj testl %eax, PCB_FPU_FLAGS(%ebx) 6250Sstevel@tonic-gate jz .handle_in_trap /* must be the first fault */ 626*3446Smrj CLTS 627*3446Smrj andl $_BITNOT(FPU_VALID), PCB_FPU_FLAGS(%ebx) 6280Sstevel@tonic-gate#if FPU_CTX_FPU_REGS != 0 629*3446Smrj addl $FPU_CTX_FPU_REGS, %ebx 6300Sstevel@tonic-gate#endif 6310Sstevel@tonic-gate /* 6320Sstevel@tonic-gate * the label below is used in trap.c to detect FP faults in kernel 6330Sstevel@tonic-gate * due to user fault. 6340Sstevel@tonic-gate */ 6350Sstevel@tonic-gate ALTENTRY(ndptrap_frstor) 636*3446Smrj .globl _patch_fxrstor_ebx 637*3446Smrj_patch_fxrstor_ebx: 638*3446Smrj frstor (%ebx) /* may be patched to fxrstor */ 6390Sstevel@tonic-gate nop /* (including this byte) */ 6400Sstevel@tonic-gate popl %gs 6410Sstevel@tonic-gate popl %ds 6420Sstevel@tonic-gate popl %ebx 6430Sstevel@tonic-gate popl %eax 644*3446Smrj IRET 6450Sstevel@tonic-gate 6460Sstevel@tonic-gate.handle_in_trap: 6470Sstevel@tonic-gate popl %gs 6480Sstevel@tonic-gate popl %ds 6490Sstevel@tonic-gate popl %ebx 6500Sstevel@tonic-gate popl %eax 651*3446Smrj TRAP_NOERR(T_NOEXTFLT) /* $7 */ 6520Sstevel@tonic-gate jmp cmninttrap 6530Sstevel@tonic-gate SET_SIZE(ndptrap_frstor) 6540Sstevel@tonic-gate SET_SIZE(ndptrap) 6550Sstevel@tonic-gate 6560Sstevel@tonic-gate#endif /* __i386 */ 6570Sstevel@tonic-gate 6580Sstevel@tonic-gate#if defined(__amd64) 6590Sstevel@tonic-gate 6600Sstevel@tonic-gate /* 6610Sstevel@tonic-gate * #DF 6620Sstevel@tonic-gate */ 6630Sstevel@tonic-gate ENTRY_NP(syserrtrap) 6640Sstevel@tonic-gate pushq $T_DBLFLT 6650Sstevel@tonic-gate 6660Sstevel@tonic-gate SET_CPU_GSBASE 6670Sstevel@tonic-gate 6680Sstevel@tonic-gate /* 6690Sstevel@tonic-gate * We share this handler with kmdb (if kmdb is loaded). As such, we may 6700Sstevel@tonic-gate * have reached this point after encountering a #df in kmdb. If that 6710Sstevel@tonic-gate * happens, we'll still be on kmdb's IDT. We need to switch back to this 6720Sstevel@tonic-gate * CPU's IDT before proceeding. Furthermore, if we did arrive here from 6730Sstevel@tonic-gate * kmdb, kmdb is probably in a very sickly state, and shouldn't be 6740Sstevel@tonic-gate * entered from the panic flow. We'll suppress that entry by setting 6750Sstevel@tonic-gate * nopanicdebug. 6760Sstevel@tonic-gate */ 6770Sstevel@tonic-gate pushq %rax 6780Sstevel@tonic-gate subq $DESCTBR_SIZE, %rsp 6790Sstevel@tonic-gate sidt (%rsp) 6800Sstevel@tonic-gate movq %gs:CPU_IDT, %rax 6810Sstevel@tonic-gate cmpq %rax, DTR_BASE(%rsp) 6820Sstevel@tonic-gate je 1f 6830Sstevel@tonic-gate 6840Sstevel@tonic-gate movq %rax, DTR_BASE(%rsp) 6850Sstevel@tonic-gate movw $_MUL(NIDT, GATE_DESC_SIZE), DTR_LIMIT(%rsp) 6860Sstevel@tonic-gate lidt (%rsp) 6870Sstevel@tonic-gate 6880Sstevel@tonic-gate movl $1, nopanicdebug 6890Sstevel@tonic-gate 6900Sstevel@tonic-gate1: addq $DESCTBR_SIZE, %rsp 6910Sstevel@tonic-gate popq %rax 6920Sstevel@tonic-gate 6930Sstevel@tonic-gate DFTRAP_PUSH 6940Sstevel@tonic-gate 6950Sstevel@tonic-gate /* 6960Sstevel@tonic-gate * freeze trap trace. 6970Sstevel@tonic-gate */ 6980Sstevel@tonic-gate#ifdef TRAPTRACE 6990Sstevel@tonic-gate leaq trap_trace_freeze(%rip), %r11 7000Sstevel@tonic-gate incl (%r11) 7010Sstevel@tonic-gate#endif 7020Sstevel@tonic-gate 7030Sstevel@tonic-gate ENABLE_INTR_FLAGS 7040Sstevel@tonic-gate 7050Sstevel@tonic-gate movq %rsp, %rdi /* ®s */ 7060Sstevel@tonic-gate xorl %esi, %esi /* clear address */ 7070Sstevel@tonic-gate xorl %edx, %edx /* cpuid = 0 */ 7080Sstevel@tonic-gate call trap 7090Sstevel@tonic-gate 7100Sstevel@tonic-gate SET_SIZE(syserrtrap) 7110Sstevel@tonic-gate 7120Sstevel@tonic-gate#elif defined(__i386) 7130Sstevel@tonic-gate 7140Sstevel@tonic-gate /* 7150Sstevel@tonic-gate * #DF 7160Sstevel@tonic-gate */ 7170Sstevel@tonic-gate ENTRY_NP(syserrtrap) 7180Sstevel@tonic-gate cli /* disable interrupts */ 7190Sstevel@tonic-gate 7200Sstevel@tonic-gate /* 7210Sstevel@tonic-gate * We share this handler with kmdb (if kmdb is loaded). As such, we may 7220Sstevel@tonic-gate * have reached this point after encountering a #df in kmdb. If that 7230Sstevel@tonic-gate * happens, we'll still be on kmdb's IDT. We need to switch back to this 7240Sstevel@tonic-gate * CPU's IDT before proceeding. Furthermore, if we did arrive here from 7250Sstevel@tonic-gate * kmdb, kmdb is probably in a very sickly state, and shouldn't be 7260Sstevel@tonic-gate * entered from the panic flow. We'll suppress that entry by setting 7270Sstevel@tonic-gate * nopanicdebug. 7280Sstevel@tonic-gate */ 7290Sstevel@tonic-gate subl $DESCTBR_SIZE, %esp 7300Sstevel@tonic-gate movl %gs:CPU_IDT, %eax 7310Sstevel@tonic-gate sidt (%esp) 7320Sstevel@tonic-gate cmpl DTR_BASE(%esp), %eax 7330Sstevel@tonic-gate je 1f 7340Sstevel@tonic-gate 7350Sstevel@tonic-gate movl %eax, DTR_BASE(%esp) 7360Sstevel@tonic-gate movw $_MUL(NIDT, GATE_DESC_SIZE), DTR_LIMIT(%esp) 7370Sstevel@tonic-gate lidt (%esp) 7380Sstevel@tonic-gate 7390Sstevel@tonic-gate movl $1, nopanicdebug 7400Sstevel@tonic-gate 7410Sstevel@tonic-gate1: addl $DESCTBR_SIZE, %esp 7420Sstevel@tonic-gate 7430Sstevel@tonic-gate /* 7440Sstevel@tonic-gate * Check the CPL in the TSS to see what mode 7450Sstevel@tonic-gate * (user or kernel) we took the fault in. At this 7460Sstevel@tonic-gate * point we are running in the context of the double 7470Sstevel@tonic-gate * fault task (dftss) but the CPU's task points to 7480Sstevel@tonic-gate * the previous task (ktss) where the process context 7490Sstevel@tonic-gate * has been saved as the result of the task switch. 7500Sstevel@tonic-gate */ 7510Sstevel@tonic-gate movl %gs:CPU_TSS, %eax /* get the TSS */ 7520Sstevel@tonic-gate movl TSS_SS(%eax), %ebx /* save the fault SS */ 7530Sstevel@tonic-gate movl TSS_ESP(%eax), %edx /* save the fault ESP */ 7540Sstevel@tonic-gate testw $CPL_MASK, TSS_CS(%eax) /* user mode ? */ 7550Sstevel@tonic-gate jz make_frame 7560Sstevel@tonic-gate movw TSS_SS0(%eax), %ss /* get on the kernel stack */ 7570Sstevel@tonic-gate movl TSS_ESP0(%eax), %esp 7580Sstevel@tonic-gate 7590Sstevel@tonic-gate /* 7600Sstevel@tonic-gate * Clear the NT flag to avoid a task switch when the process 7610Sstevel@tonic-gate * finally pops the EFL off the stack via an iret. Clear 7620Sstevel@tonic-gate * the TF flag since that is what the processor does for 7630Sstevel@tonic-gate * a normal exception. Clear the IE flag so that interrupts 7640Sstevel@tonic-gate * remain disabled. 7650Sstevel@tonic-gate */ 7660Sstevel@tonic-gate movl TSS_EFL(%eax), %ecx 7670Sstevel@tonic-gate andl $_BITNOT(PS_NT|PS_T|PS_IE), %ecx 7680Sstevel@tonic-gate pushl %ecx 7690Sstevel@tonic-gate popfl /* restore the EFL */ 7700Sstevel@tonic-gate movw TSS_LDT(%eax), %cx /* restore the LDT */ 7710Sstevel@tonic-gate lldt %cx 7720Sstevel@tonic-gate 7730Sstevel@tonic-gate /* 7740Sstevel@tonic-gate * Restore process segment selectors. 7750Sstevel@tonic-gate */ 7760Sstevel@tonic-gate movw TSS_DS(%eax), %ds 7770Sstevel@tonic-gate movw TSS_ES(%eax), %es 7780Sstevel@tonic-gate movw TSS_FS(%eax), %fs 7790Sstevel@tonic-gate movw TSS_GS(%eax), %gs 7800Sstevel@tonic-gate 7810Sstevel@tonic-gate /* 7820Sstevel@tonic-gate * Restore task segment selectors. 7830Sstevel@tonic-gate */ 7840Sstevel@tonic-gate movl $KDS_SEL, TSS_DS(%eax) 7850Sstevel@tonic-gate movl $KDS_SEL, TSS_ES(%eax) 7860Sstevel@tonic-gate movl $KDS_SEL, TSS_SS(%eax) 7870Sstevel@tonic-gate movl $KFS_SEL, TSS_FS(%eax) 7880Sstevel@tonic-gate movl $KGS_SEL, TSS_GS(%eax) 7890Sstevel@tonic-gate 7900Sstevel@tonic-gate /* 7910Sstevel@tonic-gate * Clear the TS bit, the busy bits in both task 7920Sstevel@tonic-gate * descriptors, and switch tasks. 7930Sstevel@tonic-gate */ 7940Sstevel@tonic-gate clts 7950Sstevel@tonic-gate leal gdt0, %ecx 7960Sstevel@tonic-gate movl DFTSS_SEL+4(%ecx), %esi 7970Sstevel@tonic-gate andl $_BITNOT(0x200), %esi 7980Sstevel@tonic-gate movl %esi, DFTSS_SEL+4(%ecx) 7990Sstevel@tonic-gate movl KTSS_SEL+4(%ecx), %esi 8000Sstevel@tonic-gate andl $_BITNOT(0x200), %esi 8010Sstevel@tonic-gate movl %esi, KTSS_SEL+4(%ecx) 8020Sstevel@tonic-gate movw $KTSS_SEL, %cx 8030Sstevel@tonic-gate ltr %cx 8040Sstevel@tonic-gate 8050Sstevel@tonic-gate /* 8060Sstevel@tonic-gate * Restore part of the process registers. 8070Sstevel@tonic-gate */ 8080Sstevel@tonic-gate movl TSS_EBP(%eax), %ebp 8090Sstevel@tonic-gate movl TSS_ECX(%eax), %ecx 8100Sstevel@tonic-gate movl TSS_ESI(%eax), %esi 8110Sstevel@tonic-gate movl TSS_EDI(%eax), %edi 8120Sstevel@tonic-gate 8130Sstevel@tonic-gatemake_frame: 8140Sstevel@tonic-gate /* 8150Sstevel@tonic-gate * Make a trap frame. Leave the error code (0) on 8160Sstevel@tonic-gate * the stack since the first word on a trap stack is 8170Sstevel@tonic-gate * unused anyway. 8180Sstevel@tonic-gate */ 8190Sstevel@tonic-gate pushl %ebx / fault SS 8200Sstevel@tonic-gate pushl %edx / fault ESP 8210Sstevel@tonic-gate pushl TSS_EFL(%eax) / fault EFL 8220Sstevel@tonic-gate pushl TSS_CS(%eax) / fault CS 8230Sstevel@tonic-gate pushl TSS_EIP(%eax) / fault EIP 8240Sstevel@tonic-gate pushl $0 / error code 8250Sstevel@tonic-gate pushl $T_DBLFLT / trap number 8 8260Sstevel@tonic-gate movl TSS_EBX(%eax), %ebx / restore EBX 8270Sstevel@tonic-gate movl TSS_EDX(%eax), %edx / restore EDX 8280Sstevel@tonic-gate movl TSS_EAX(%eax), %eax / restore EAX 8290Sstevel@tonic-gate sti / enable interrupts 8300Sstevel@tonic-gate jmp cmntrap 8310Sstevel@tonic-gate SET_SIZE(syserrtrap) 8320Sstevel@tonic-gate 8330Sstevel@tonic-gate#endif /* __i386 */ 8340Sstevel@tonic-gate 8350Sstevel@tonic-gate ENTRY_NP(overrun) 8360Sstevel@tonic-gate push $0 8370Sstevel@tonic-gate TRAP_NOERR(T_EXTOVRFLT) /* $9 i386 only - not generated */ 8380Sstevel@tonic-gate jmp cmninttrap 8390Sstevel@tonic-gate SET_SIZE(overrun) 8400Sstevel@tonic-gate 8410Sstevel@tonic-gate /* 8420Sstevel@tonic-gate * #TS 8430Sstevel@tonic-gate */ 8440Sstevel@tonic-gate ENTRY_NP(invtsstrap) 8450Sstevel@tonic-gate TRAP_ERR(T_TSSFLT) /* $10 already have error code on stack */ 8460Sstevel@tonic-gate jmp cmntrap 8470Sstevel@tonic-gate SET_SIZE(invtsstrap) 8480Sstevel@tonic-gate 8490Sstevel@tonic-gate /* 8500Sstevel@tonic-gate * #NP 8510Sstevel@tonic-gate */ 8520Sstevel@tonic-gate ENTRY_NP(segnptrap) 8530Sstevel@tonic-gate TRAP_ERR(T_SEGFLT) /* $11 already have error code on stack */ 8540Sstevel@tonic-gate#if defined(__amd64) 8550Sstevel@tonic-gate SET_CPU_GSBASE 8560Sstevel@tonic-gate#endif 8570Sstevel@tonic-gate jmp cmntrap 8580Sstevel@tonic-gate SET_SIZE(segnptrap) 8590Sstevel@tonic-gate 8600Sstevel@tonic-gate /* 8610Sstevel@tonic-gate * #SS 8620Sstevel@tonic-gate */ 8630Sstevel@tonic-gate ENTRY_NP(stktrap) 8640Sstevel@tonic-gate TRAP_ERR(T_STKFLT) /* $12 already have error code on stack */ 8650Sstevel@tonic-gate jmp cmntrap 8660Sstevel@tonic-gate SET_SIZE(stktrap) 8670Sstevel@tonic-gate 8680Sstevel@tonic-gate /* 8690Sstevel@tonic-gate * #GP 8700Sstevel@tonic-gate */ 8710Sstevel@tonic-gate ENTRY_NP(gptrap) 8720Sstevel@tonic-gate TRAP_ERR(T_GPFLT) /* $13 already have error code on stack */ 8730Sstevel@tonic-gate#if defined(__amd64) 8740Sstevel@tonic-gate SET_CPU_GSBASE 8750Sstevel@tonic-gate#endif 8760Sstevel@tonic-gate jmp cmntrap 8770Sstevel@tonic-gate SET_SIZE(gptrap) 8780Sstevel@tonic-gate 8790Sstevel@tonic-gate /* 8800Sstevel@tonic-gate * #PF 8810Sstevel@tonic-gate */ 8820Sstevel@tonic-gate ENTRY_NP(pftrap) 8830Sstevel@tonic-gate TRAP_ERR(T_PGFLT) /* $14 already have error code on stack */ 884*3446Smrj INTR_PUSH 885*3446Smrj 886*3446Smrj#if defined(__amd64) 887*3446Smrj movq %cr2, %r15 888*3446Smrj#elif defined(__i386) 889*3446Smrj movl %cr2, %esi 890*3446Smrj#endif /* __i386 */ 891*3446Smrj 892*3446Smrj jmp cmntrap_pushed 8930Sstevel@tonic-gate SET_SIZE(pftrap) 8940Sstevel@tonic-gate 8950Sstevel@tonic-gate#if !defined(__amd64) 8960Sstevel@tonic-gate 897*3446Smrj .globl idt0_default_r 898*3446Smrj 8990Sstevel@tonic-gate /* 9000Sstevel@tonic-gate * #PF pentium bug workaround 9010Sstevel@tonic-gate */ 9020Sstevel@tonic-gate ENTRY_NP(pentium_pftrap) 9030Sstevel@tonic-gate pushl %eax 9040Sstevel@tonic-gate movl %cr2, %eax 9050Sstevel@tonic-gate andl $MMU_STD_PAGEMASK, %eax 9060Sstevel@tonic-gate 9070Sstevel@tonic-gate cmpl %eax, %cs:idt0_default_r+2 /* fixme */ 9080Sstevel@tonic-gate 9090Sstevel@tonic-gate je check_for_user_address 9100Sstevel@tonic-gateuser_mode: 9110Sstevel@tonic-gate popl %eax 9120Sstevel@tonic-gate pushl $T_PGFLT /* $14 */ 9130Sstevel@tonic-gate jmp cmntrap 9140Sstevel@tonic-gatecheck_for_user_address: 9150Sstevel@tonic-gate /* 9160Sstevel@tonic-gate * Before we assume that we have an unmapped trap on our hands, 9170Sstevel@tonic-gate * check to see if this is a fault from user mode. If it is, 9180Sstevel@tonic-gate * we'll kick back into the page fault handler. 9190Sstevel@tonic-gate */ 9200Sstevel@tonic-gate movl 4(%esp), %eax /* error code */ 9210Sstevel@tonic-gate andl $PF_ERR_USER, %eax 9220Sstevel@tonic-gate jnz user_mode 9230Sstevel@tonic-gate 9240Sstevel@tonic-gate /* 9250Sstevel@tonic-gate * We now know that this is the invalid opcode trap. 9260Sstevel@tonic-gate */ 9270Sstevel@tonic-gate popl %eax 9280Sstevel@tonic-gate addl $4, %esp /* pop error code */ 9290Sstevel@tonic-gate jmp invoptrap 9300Sstevel@tonic-gate SET_SIZE(pentium_pftrap) 9310Sstevel@tonic-gate 9320Sstevel@tonic-gate#endif /* !__amd64 */ 9330Sstevel@tonic-gate 9340Sstevel@tonic-gate ENTRY_NP(resvtrap) 9350Sstevel@tonic-gate TRAP_NOERR(15) /* (reserved) */ 9360Sstevel@tonic-gate jmp cmntrap 9370Sstevel@tonic-gate SET_SIZE(resvtrap) 9380Sstevel@tonic-gate 9390Sstevel@tonic-gate /* 9400Sstevel@tonic-gate * #MF 9410Sstevel@tonic-gate */ 9420Sstevel@tonic-gate ENTRY_NP(ndperr) 9430Sstevel@tonic-gate TRAP_NOERR(T_EXTERRFLT) /* $16 */ 9440Sstevel@tonic-gate jmp cmninttrap 9450Sstevel@tonic-gate SET_SIZE(ndperr) 9460Sstevel@tonic-gate 9470Sstevel@tonic-gate /* 9480Sstevel@tonic-gate * #AC 9490Sstevel@tonic-gate */ 9500Sstevel@tonic-gate ENTRY_NP(achktrap) 9510Sstevel@tonic-gate TRAP_ERR(T_ALIGNMENT) /* $17 */ 9520Sstevel@tonic-gate jmp cmntrap 9530Sstevel@tonic-gate SET_SIZE(achktrap) 9540Sstevel@tonic-gate 9550Sstevel@tonic-gate /* 9560Sstevel@tonic-gate * #MC 9570Sstevel@tonic-gate */ 9581414Scindi .globl cmi_mca_trap /* see uts/i86pc/os/cmi.c */ 9591414Scindi 9601414Scindi#if defined(__amd64) 9611414Scindi 9620Sstevel@tonic-gate ENTRY_NP(mcetrap) 9630Sstevel@tonic-gate TRAP_NOERR(T_MCE) /* $18 */ 964*3446Smrj 96510Skucharsk SET_CPU_GSBASE 966*3446Smrj 9671414Scindi INTR_PUSH 968*3446Smrj INTGATE_INIT_KERNEL_FLAGS 9691414Scindi 9701414Scindi TRACE_PTR(%rdi, %rbx, %ebx, %rcx, $TT_TRAP) 9711414Scindi TRACE_REGS(%rdi, %rsp, %rbx, %rcx) 9721414Scindi TRACE_STAMP(%rdi) 9731414Scindi 9741414Scindi movq %rsp, %rbp 9751414Scindi 9761414Scindi movq %rsp, %rdi /* arg0 = struct regs *rp */ 9771414Scindi call cmi_mca_trap /* cmi_mca_trap(rp); */ 9781414Scindi 9791414Scindi jmp _sys_rtt 9801414Scindi SET_SIZE(mcetrap) 9811414Scindi 9821414Scindi#else 9831414Scindi 9841414Scindi ENTRY_NP(mcetrap) 9851414Scindi TRAP_NOERR(T_MCE) /* $18 */ 986*3446Smrj 9871414Scindi INTR_PUSH 988*3446Smrj INTGATE_INIT_KERNEL_FLAGS 9891414Scindi 990*3446Smrj TRACE_PTR(%edi, %ebx, %ebx, %ecx, $TT_TRAP) 991*3446Smrj TRACE_REGS(%edi, %esp, %ebx, %ecx) 992*3446Smrj TRACE_STAMP(%edi) 993*3446Smrj 9941414Scindi movl %esp, %ebp 9951414Scindi 9961414Scindi movl %esp, %ecx 9971414Scindi pushl %ecx /* arg0 = struct regs *rp */ 9981414Scindi call cmi_mca_trap /* cmi_mca_trap(rp) */ 9991414Scindi addl $4, %esp /* pop arg0 */ 10001414Scindi 10011414Scindi jmp _sys_rtt 10021414Scindi SET_SIZE(mcetrap) 10031414Scindi 100410Skucharsk#endif 10050Sstevel@tonic-gate 10060Sstevel@tonic-gate /* 10070Sstevel@tonic-gate * #XF 10080Sstevel@tonic-gate */ 10090Sstevel@tonic-gate ENTRY_NP(xmtrap) 10100Sstevel@tonic-gate TRAP_NOERR(T_SIMDFPE) /* $19 */ 10110Sstevel@tonic-gate jmp cmntrap 10120Sstevel@tonic-gate SET_SIZE(xmtrap) 10130Sstevel@tonic-gate 10140Sstevel@tonic-gate ENTRY_NP(invaltrap) 10150Sstevel@tonic-gate TRAP_NOERR(30) /* very invalid */ 10160Sstevel@tonic-gate jmp cmntrap 10170Sstevel@tonic-gate SET_SIZE(invaltrap) 10180Sstevel@tonic-gate 10190Sstevel@tonic-gate ENTRY_NP(invalint) 10200Sstevel@tonic-gate TRAP_NOERR(31) /* even more so */ 10210Sstevel@tonic-gate jmp cmnint 10220Sstevel@tonic-gate SET_SIZE(invalint) 10230Sstevel@tonic-gate 10240Sstevel@tonic-gate .globl fasttable 10250Sstevel@tonic-gate 10260Sstevel@tonic-gate#if defined(__amd64) 10270Sstevel@tonic-gate 10280Sstevel@tonic-gate ENTRY_NP(fasttrap) 10290Sstevel@tonic-gate cmpl $T_LASTFAST, %eax 10300Sstevel@tonic-gate ja 1f 10310Sstevel@tonic-gate orl %eax, %eax /* (zero extend top 32-bits) */ 10320Sstevel@tonic-gate leaq fasttable(%rip), %r11 10330Sstevel@tonic-gate leaq (%r11, %rax, CLONGSIZE), %r11 10340Sstevel@tonic-gate jmp *(%r11) 10350Sstevel@tonic-gate1: 10360Sstevel@tonic-gate /* 10370Sstevel@tonic-gate * Fast syscall number was illegal. Make it look 10380Sstevel@tonic-gate * as if the INT failed. Modify %rip to point before the 10390Sstevel@tonic-gate * INT, push the expected error code and fake a GP fault. 10400Sstevel@tonic-gate * 10410Sstevel@tonic-gate * XXX Why make the error code be offset into idt + 1? 10420Sstevel@tonic-gate * Instead we should push a real (soft?) error code 10430Sstevel@tonic-gate * on the stack and #gp handler could know about fasttraps? 10440Sstevel@tonic-gate */ 10450Sstevel@tonic-gate subq $2, (%rsp) /* XXX int insn 2-bytes */ 10460Sstevel@tonic-gate pushq $_CONST(_MUL(T_FASTTRAP, GATE_DESC_SIZE) + 2) 10470Sstevel@tonic-gate jmp gptrap 10480Sstevel@tonic-gate SET_SIZE(fasttrap) 10490Sstevel@tonic-gate 10500Sstevel@tonic-gate#elif defined(__i386) 10510Sstevel@tonic-gate 10520Sstevel@tonic-gate ENTRY_NP(fasttrap) 10530Sstevel@tonic-gate cmpl $T_LASTFAST, %eax 10540Sstevel@tonic-gate ja 1f 10550Sstevel@tonic-gate jmp *%cs:fasttable(, %eax, CLONGSIZE) 10560Sstevel@tonic-gate1: 10570Sstevel@tonic-gate /* 10580Sstevel@tonic-gate * Fast syscall number was illegal. Make it look 10590Sstevel@tonic-gate * as if the INT failed. Modify %eip to point before the 10600Sstevel@tonic-gate * INT, push the expected error code and fake a GP fault. 10610Sstevel@tonic-gate * 10620Sstevel@tonic-gate * XXX Why make the error code be offset into idt + 1? 10630Sstevel@tonic-gate * Instead we should push a real (soft?) error code 10640Sstevel@tonic-gate * on the stack and #gp handler could know about fasttraps? 10650Sstevel@tonic-gate */ 10660Sstevel@tonic-gate subl $2, (%esp) /* XXX int insn 2-bytes */ 10670Sstevel@tonic-gate pushl $_CONST(_MUL(T_FASTTRAP, GATE_DESC_SIZE) + 2) 10680Sstevel@tonic-gate jmp gptrap 10690Sstevel@tonic-gate SET_SIZE(fasttrap) 10700Sstevel@tonic-gate 10710Sstevel@tonic-gate#endif /* __i386 */ 10720Sstevel@tonic-gate 10730Sstevel@tonic-gate ENTRY_NP(dtrace_ret) 10740Sstevel@tonic-gate TRAP_NOERR(T_DTRACE_RET) 10750Sstevel@tonic-gate jmp dtrace_trap 10760Sstevel@tonic-gate SET_SIZE(dtrace_ret) 10770Sstevel@tonic-gate 10780Sstevel@tonic-gate#if defined(__amd64) 10790Sstevel@tonic-gate 10800Sstevel@tonic-gate /* 10810Sstevel@tonic-gate * RFLAGS 24 bytes up the stack from %rsp. 10820Sstevel@tonic-gate * XXX a constant would be nicer. 10830Sstevel@tonic-gate */ 10840Sstevel@tonic-gate ENTRY_NP(fast_null) 10850Sstevel@tonic-gate orq $PS_C, 24(%rsp) /* set carry bit in user flags */ 1086*3446Smrj IRET 1087*3446Smrj /*NOTREACHED*/ 10880Sstevel@tonic-gate SET_SIZE(fast_null) 10890Sstevel@tonic-gate 10900Sstevel@tonic-gate#elif defined(__i386) 10910Sstevel@tonic-gate 10920Sstevel@tonic-gate ENTRY_NP(fast_null) 10930Sstevel@tonic-gate orw $PS_C, 8(%esp) /* set carry bit in user flags */ 1094*3446Smrj IRET 10950Sstevel@tonic-gate SET_SIZE(fast_null) 10960Sstevel@tonic-gate 10970Sstevel@tonic-gate#endif /* __i386 */ 10980Sstevel@tonic-gate 10990Sstevel@tonic-gate /* 11000Sstevel@tonic-gate * Interrupts start at 32 11010Sstevel@tonic-gate */ 11020Sstevel@tonic-gate#define MKIVCT(n) \ 11030Sstevel@tonic-gate ENTRY_NP(ivct/**/n) \ 11040Sstevel@tonic-gate push $0; \ 11050Sstevel@tonic-gate push $n - 0x20; \ 11060Sstevel@tonic-gate jmp cmnint; \ 11070Sstevel@tonic-gate SET_SIZE(ivct/**/n) 11080Sstevel@tonic-gate 11090Sstevel@tonic-gate MKIVCT(32) 11100Sstevel@tonic-gate MKIVCT(33) 11110Sstevel@tonic-gate MKIVCT(34) 11120Sstevel@tonic-gate MKIVCT(35) 11130Sstevel@tonic-gate MKIVCT(36) 11140Sstevel@tonic-gate MKIVCT(37) 11150Sstevel@tonic-gate MKIVCT(38) 11160Sstevel@tonic-gate MKIVCT(39) 11170Sstevel@tonic-gate MKIVCT(40) 11180Sstevel@tonic-gate MKIVCT(41) 11190Sstevel@tonic-gate MKIVCT(42) 11200Sstevel@tonic-gate MKIVCT(43) 11210Sstevel@tonic-gate MKIVCT(44) 11220Sstevel@tonic-gate MKIVCT(45) 11230Sstevel@tonic-gate MKIVCT(46) 11240Sstevel@tonic-gate MKIVCT(47) 11250Sstevel@tonic-gate MKIVCT(48) 11260Sstevel@tonic-gate MKIVCT(49) 11270Sstevel@tonic-gate MKIVCT(50) 11280Sstevel@tonic-gate MKIVCT(51) 11290Sstevel@tonic-gate MKIVCT(52) 11300Sstevel@tonic-gate MKIVCT(53) 11310Sstevel@tonic-gate MKIVCT(54) 11320Sstevel@tonic-gate MKIVCT(55) 11330Sstevel@tonic-gate MKIVCT(56) 11340Sstevel@tonic-gate MKIVCT(57) 11350Sstevel@tonic-gate MKIVCT(58) 11360Sstevel@tonic-gate MKIVCT(59) 11370Sstevel@tonic-gate MKIVCT(60) 11380Sstevel@tonic-gate MKIVCT(61) 11390Sstevel@tonic-gate MKIVCT(62) 11400Sstevel@tonic-gate MKIVCT(63) 11410Sstevel@tonic-gate MKIVCT(64) 11420Sstevel@tonic-gate MKIVCT(65) 11430Sstevel@tonic-gate MKIVCT(66) 11440Sstevel@tonic-gate MKIVCT(67) 11450Sstevel@tonic-gate MKIVCT(68) 11460Sstevel@tonic-gate MKIVCT(69) 11470Sstevel@tonic-gate MKIVCT(70) 11480Sstevel@tonic-gate MKIVCT(71) 11490Sstevel@tonic-gate MKIVCT(72) 11500Sstevel@tonic-gate MKIVCT(73) 11510Sstevel@tonic-gate MKIVCT(74) 11520Sstevel@tonic-gate MKIVCT(75) 11530Sstevel@tonic-gate MKIVCT(76) 11540Sstevel@tonic-gate MKIVCT(77) 11550Sstevel@tonic-gate MKIVCT(78) 11560Sstevel@tonic-gate MKIVCT(79) 11570Sstevel@tonic-gate MKIVCT(80) 11580Sstevel@tonic-gate MKIVCT(81) 11590Sstevel@tonic-gate MKIVCT(82) 11600Sstevel@tonic-gate MKIVCT(83) 11610Sstevel@tonic-gate MKIVCT(84) 11620Sstevel@tonic-gate MKIVCT(85) 11630Sstevel@tonic-gate MKIVCT(86) 11640Sstevel@tonic-gate MKIVCT(87) 11650Sstevel@tonic-gate MKIVCT(88) 11660Sstevel@tonic-gate MKIVCT(89) 11670Sstevel@tonic-gate MKIVCT(90) 11680Sstevel@tonic-gate MKIVCT(91) 11690Sstevel@tonic-gate MKIVCT(92) 11700Sstevel@tonic-gate MKIVCT(93) 11710Sstevel@tonic-gate MKIVCT(94) 11720Sstevel@tonic-gate MKIVCT(95) 11730Sstevel@tonic-gate MKIVCT(96) 11740Sstevel@tonic-gate MKIVCT(97) 11750Sstevel@tonic-gate MKIVCT(98) 11760Sstevel@tonic-gate MKIVCT(99) 11770Sstevel@tonic-gate MKIVCT(100) 11780Sstevel@tonic-gate MKIVCT(101) 11790Sstevel@tonic-gate MKIVCT(102) 11800Sstevel@tonic-gate MKIVCT(103) 11810Sstevel@tonic-gate MKIVCT(104) 11820Sstevel@tonic-gate MKIVCT(105) 11830Sstevel@tonic-gate MKIVCT(106) 11840Sstevel@tonic-gate MKIVCT(107) 11850Sstevel@tonic-gate MKIVCT(108) 11860Sstevel@tonic-gate MKIVCT(109) 11870Sstevel@tonic-gate MKIVCT(110) 11880Sstevel@tonic-gate MKIVCT(111) 11890Sstevel@tonic-gate MKIVCT(112) 11900Sstevel@tonic-gate MKIVCT(113) 11910Sstevel@tonic-gate MKIVCT(114) 11920Sstevel@tonic-gate MKIVCT(115) 11930Sstevel@tonic-gate MKIVCT(116) 11940Sstevel@tonic-gate MKIVCT(117) 11950Sstevel@tonic-gate MKIVCT(118) 11960Sstevel@tonic-gate MKIVCT(119) 11970Sstevel@tonic-gate MKIVCT(120) 11980Sstevel@tonic-gate MKIVCT(121) 11990Sstevel@tonic-gate MKIVCT(122) 12000Sstevel@tonic-gate MKIVCT(123) 12010Sstevel@tonic-gate MKIVCT(124) 12020Sstevel@tonic-gate MKIVCT(125) 12030Sstevel@tonic-gate MKIVCT(126) 12040Sstevel@tonic-gate MKIVCT(127) 12050Sstevel@tonic-gate MKIVCT(128) 12060Sstevel@tonic-gate MKIVCT(129) 12070Sstevel@tonic-gate MKIVCT(130) 12080Sstevel@tonic-gate MKIVCT(131) 12090Sstevel@tonic-gate MKIVCT(132) 12100Sstevel@tonic-gate MKIVCT(133) 12110Sstevel@tonic-gate MKIVCT(134) 12120Sstevel@tonic-gate MKIVCT(135) 12130Sstevel@tonic-gate MKIVCT(136) 12140Sstevel@tonic-gate MKIVCT(137) 12150Sstevel@tonic-gate MKIVCT(138) 12160Sstevel@tonic-gate MKIVCT(139) 12170Sstevel@tonic-gate MKIVCT(140) 12180Sstevel@tonic-gate MKIVCT(141) 12190Sstevel@tonic-gate MKIVCT(142) 12200Sstevel@tonic-gate MKIVCT(143) 12210Sstevel@tonic-gate MKIVCT(144) 12220Sstevel@tonic-gate MKIVCT(145) 12230Sstevel@tonic-gate MKIVCT(146) 12240Sstevel@tonic-gate MKIVCT(147) 12250Sstevel@tonic-gate MKIVCT(148) 12260Sstevel@tonic-gate MKIVCT(149) 12270Sstevel@tonic-gate MKIVCT(150) 12280Sstevel@tonic-gate MKIVCT(151) 12290Sstevel@tonic-gate MKIVCT(152) 12300Sstevel@tonic-gate MKIVCT(153) 12310Sstevel@tonic-gate MKIVCT(154) 12320Sstevel@tonic-gate MKIVCT(155) 12330Sstevel@tonic-gate MKIVCT(156) 12340Sstevel@tonic-gate MKIVCT(157) 12350Sstevel@tonic-gate MKIVCT(158) 12360Sstevel@tonic-gate MKIVCT(159) 12370Sstevel@tonic-gate MKIVCT(160) 12380Sstevel@tonic-gate MKIVCT(161) 12390Sstevel@tonic-gate MKIVCT(162) 12400Sstevel@tonic-gate MKIVCT(163) 12410Sstevel@tonic-gate MKIVCT(164) 12420Sstevel@tonic-gate MKIVCT(165) 12430Sstevel@tonic-gate MKIVCT(166) 12440Sstevel@tonic-gate MKIVCT(167) 12450Sstevel@tonic-gate MKIVCT(168) 12460Sstevel@tonic-gate MKIVCT(169) 12470Sstevel@tonic-gate MKIVCT(170) 12480Sstevel@tonic-gate MKIVCT(171) 12490Sstevel@tonic-gate MKIVCT(172) 12500Sstevel@tonic-gate MKIVCT(173) 12510Sstevel@tonic-gate MKIVCT(174) 12520Sstevel@tonic-gate MKIVCT(175) 12530Sstevel@tonic-gate MKIVCT(176) 12540Sstevel@tonic-gate MKIVCT(177) 12550Sstevel@tonic-gate MKIVCT(178) 12560Sstevel@tonic-gate MKIVCT(179) 12570Sstevel@tonic-gate MKIVCT(180) 12580Sstevel@tonic-gate MKIVCT(181) 12590Sstevel@tonic-gate MKIVCT(182) 12600Sstevel@tonic-gate MKIVCT(183) 12610Sstevel@tonic-gate MKIVCT(184) 12620Sstevel@tonic-gate MKIVCT(185) 12630Sstevel@tonic-gate MKIVCT(186) 12640Sstevel@tonic-gate MKIVCT(187) 12650Sstevel@tonic-gate MKIVCT(188) 12660Sstevel@tonic-gate MKIVCT(189) 12670Sstevel@tonic-gate MKIVCT(190) 12680Sstevel@tonic-gate MKIVCT(191) 12690Sstevel@tonic-gate MKIVCT(192) 12700Sstevel@tonic-gate MKIVCT(193) 12710Sstevel@tonic-gate MKIVCT(194) 12720Sstevel@tonic-gate MKIVCT(195) 12730Sstevel@tonic-gate MKIVCT(196) 12740Sstevel@tonic-gate MKIVCT(197) 12750Sstevel@tonic-gate MKIVCT(198) 12760Sstevel@tonic-gate MKIVCT(199) 12770Sstevel@tonic-gate MKIVCT(200) 12780Sstevel@tonic-gate MKIVCT(201) 12790Sstevel@tonic-gate MKIVCT(202) 12800Sstevel@tonic-gate MKIVCT(203) 12810Sstevel@tonic-gate MKIVCT(204) 12820Sstevel@tonic-gate MKIVCT(205) 12830Sstevel@tonic-gate MKIVCT(206) 12840Sstevel@tonic-gate MKIVCT(207) 12850Sstevel@tonic-gate MKIVCT(208) 12860Sstevel@tonic-gate MKIVCT(209) 12870Sstevel@tonic-gate MKIVCT(210) 12880Sstevel@tonic-gate MKIVCT(211) 12890Sstevel@tonic-gate MKIVCT(212) 12900Sstevel@tonic-gate MKIVCT(213) 12910Sstevel@tonic-gate MKIVCT(214) 12920Sstevel@tonic-gate MKIVCT(215) 12930Sstevel@tonic-gate MKIVCT(216) 12940Sstevel@tonic-gate MKIVCT(217) 12950Sstevel@tonic-gate MKIVCT(218) 12960Sstevel@tonic-gate MKIVCT(219) 12970Sstevel@tonic-gate MKIVCT(220) 12980Sstevel@tonic-gate MKIVCT(221) 12990Sstevel@tonic-gate MKIVCT(222) 13000Sstevel@tonic-gate MKIVCT(223) 13010Sstevel@tonic-gate MKIVCT(224) 13020Sstevel@tonic-gate MKIVCT(225) 13030Sstevel@tonic-gate MKIVCT(226) 13040Sstevel@tonic-gate MKIVCT(227) 13050Sstevel@tonic-gate MKIVCT(228) 13060Sstevel@tonic-gate MKIVCT(229) 13070Sstevel@tonic-gate MKIVCT(230) 13080Sstevel@tonic-gate MKIVCT(231) 13090Sstevel@tonic-gate MKIVCT(232) 13100Sstevel@tonic-gate MKIVCT(233) 13110Sstevel@tonic-gate MKIVCT(234) 13120Sstevel@tonic-gate MKIVCT(235) 13130Sstevel@tonic-gate MKIVCT(236) 13140Sstevel@tonic-gate MKIVCT(237) 13150Sstevel@tonic-gate MKIVCT(238) 13160Sstevel@tonic-gate MKIVCT(239) 13170Sstevel@tonic-gate MKIVCT(240) 13180Sstevel@tonic-gate MKIVCT(241) 13190Sstevel@tonic-gate MKIVCT(242) 13200Sstevel@tonic-gate MKIVCT(243) 13210Sstevel@tonic-gate MKIVCT(244) 13220Sstevel@tonic-gate MKIVCT(245) 13230Sstevel@tonic-gate MKIVCT(246) 13240Sstevel@tonic-gate MKIVCT(247) 13250Sstevel@tonic-gate MKIVCT(248) 13260Sstevel@tonic-gate MKIVCT(249) 13270Sstevel@tonic-gate MKIVCT(250) 13280Sstevel@tonic-gate MKIVCT(251) 13290Sstevel@tonic-gate MKIVCT(252) 13300Sstevel@tonic-gate MKIVCT(253) 13310Sstevel@tonic-gate MKIVCT(254) 13320Sstevel@tonic-gate MKIVCT(255) 13330Sstevel@tonic-gate 13340Sstevel@tonic-gate#endif /* __lint */ 1335