Home | History | Annotate | Download | only in ml
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 /*	Copyright (c) 1990, 1991 UNIX System Laboratories, Inc.	*/
     27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T	*/
     28 /*	  All Rights Reserved					*/
     29 
     30 /*	Copyright (c) 1987, 1988 Microsoft Corporation		*/
     31 /*	  All Rights Reserved					*/
     32 
     33 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     34 
     35 #include <sys/asm_linkage.h>
     36 #include <sys/asm_misc.h>
     37 #include <sys/regset.h>
     38 #include <sys/psw.h>
     39 #include <sys/x86_archext.h>
     40 
     41 #if defined(__lint)
     42 
     43 #include <sys/types.h>
     44 #include <sys/thread.h>
     45 #include <sys/systm.h>
     46 
     47 #else   /* __lint */
     48 
     49 #include <sys/segments.h>
     50 #include <sys/pcb.h>
     51 #include <sys/trap.h>
     52 #include <sys/ftrace.h>
     53 #include <sys/traptrace.h>
     54 #include <sys/clock.h>
     55 #include <sys/panic.h>
     56 #include "assym.h"
     57 
     58 #endif	/* lint */
     59 
     60 #if defined(__lint)
     61 
     62 void
     63 _interrupt(void)
     64 {}
     65 
     66 #else	/* __lint */
     67 
     68 #if defined(__amd64)
     69 
     70 	/*
     71 	 * Common register usage:
     72 	 *
     73 	 * %r12		trap trace pointer
     74 	 */
     75 	ENTRY_NP2(cmnint, _interrupt)
     76 
     77 	INTR_PUSH
     78 	INTGATE_INIT_KERNEL_FLAGS	/* (set kernel rflags values) */
     79 
     80 	/*
     81 	 * At the end of TRACE_PTR %r12 points to the current TRAPTRACE entry
     82 	 */
     83 	TRACE_PTR(%r12, %rax, %eax, %rdx, $TT_INTERRUPT)
     84 						/* Uses labels 8 and 9 */
     85 	TRACE_REGS(%r12, %rsp, %rax, %rbx)	/* Uses label 9 */
     86 	TRACE_STAMP(%r12)		/* Clobbers %eax, %edx, uses 9 */
     87 
     88 	movq	%rsp, %rbp
     89 
     90 	TRACE_STACK(%r12)
     91 
     92 #ifdef TRAPTRACE
     93 	LOADCPU(%rbx)				/* &cpu */
     94 	movl	CPU_PRI(%rbx), %r14d		/* old ipl */
     95 	movl	$255, TTR_IPL(%r12)
     96 	movl	%r14d, %edi
     97 	movb	%dil, TTR_PRI(%r12)
     98 	movl	CPU_BASE_SPL(%rbx), %edi
     99 	movb	%dil, TTR_SPL(%r12)
    100 	movb	$255, TTR_VECTOR(%r12)
    101 	movq	%r12, %rsi		/* pass traptrace record pointer */
    102 #endif
    103 
    104 	movq	%rsp, %rdi		/* pass struct regs pointer */
    105 	call	do_interrupt
    106 
    107 	jmp	_sys_rtt_ints_disabled
    108 	/*NOTREACHED*/
    109 
    110 	SET_SIZE(cmnint)
    111 	SET_SIZE(_interrupt)
    112 
    113 #elif defined(__i386)
    114 
    115 	ENTRY_NP2(cmnint, _interrupt)
    116 
    117 	INTR_PUSH
    118 	INTGATE_INIT_KERNEL_FLAGS
    119 
    120 	/*
    121 	 * At the end of TRACE_PTR %esi points to the current TRAPTRACE entry
    122 	 */
    123 	TRACE_PTR(%esi, %eax, %eax, %edx, $TT_INTERRUPT)
    124 						/* Uses labels 8 and 9 */
    125 	TRACE_REGS(%esi, %esp, %eax, %ebx)	/* Uses label 9 */
    126 	TRACE_STAMP(%esi)		/* Clobbers %eax, %edx, uses 9 */
    127 
    128 	movl	%esp, %ebp
    129 
    130 	TRACE_STACK(%esi)
    131 
    132 	pushl	%esi			/* pass traptrace record pointer */
    133 	pushl	%ebp			/* pass struct regs pointer */
    134 	call	do_interrupt		/* interrupt service routine */
    135 	addl	$8, %esp		/* pop args off of stack */
    136 
    137 	jmp	_sys_rtt_ints_disabled
    138 	/*NOTREACHED*/
    139 
    140 	SET_SIZE(cmnint)
    141 	SET_SIZE(_interrupt)
    142 
    143 #endif	/* __i386 */
    144 
    145 /*
    146  * Declare a uintptr_t which has the size of _interrupt to enable stack
    147  * traceback code to know when a regs structure is on the stack.
    148  */
    149 	.globl	_interrupt_size
    150 	.align	CLONGSIZE
    151 _interrupt_size:
    152 	.NWORD	. - _interrupt
    153 	.type	_interrupt_size, @object
    154 
    155 #endif	/* __lint */
    156 
    157 #if defined(__lint)
    158 
    159 void
    160 fakesoftint(void)
    161 {}
    162 
    163 #else	/* __lint */
    164 
    165 	/
    166 	/ If we're here, we're being called from splx() to fake a soft
    167 	/ interrupt (note that interrupts are still disabled from splx()).
    168 	/ We execute this code when a soft interrupt is posted at
    169 	/ level higher than the CPU's current spl; when spl is lowered in
    170 	/ splx(), it will see the softint and jump here.  We'll do exactly
    171 	/ what a trap would do:  push our flags, %cs, %eip, error code
    172 	/ and trap number (T_SOFTINT).  The cmnint() code will see T_SOFTINT
    173 	/ and branch to the dosoftint() code.
    174 	/
    175 #if defined(__amd64)
    176 
    177 	/*
    178 	 * In 64-bit mode, iretq -always- pops all five regs
    179 	 * Imitate the 16-byte auto-align of the stack, and the
    180 	 * zero-ed out %ss value.
    181 	 */
    182 	ENTRY_NP(fakesoftint)
    183 	movq	%rsp, %r11
    184 	andq	$-16, %rsp
    185 	pushq	$KDS_SEL	/* %ss */
    186 	pushq	%r11		/* %rsp */
    187 	pushf			/* rflags */
    188 #if defined(__xpv)
    189 	popq	%r11
    190 	EVENT_MASK_TO_IE(%rdi, %r11)
    191 	pushq	%r11
    192 #endif
    193 	pushq	$KCS_SEL	/* %cs */
    194 	leaq	fakesoftint_return(%rip), %r11
    195 	pushq	%r11		/* %rip */
    196 	pushq	$0		/* err */
    197 	pushq	$T_SOFTINT	/* trap */
    198 	jmp	cmnint
    199 	ALTENTRY(fakesoftint_return)
    200 	ret
    201 	SET_SIZE(fakesoftint_return)
    202 	SET_SIZE(fakesoftint)
    203 
    204 #elif defined(__i386)
    205 
    206 	ENTRY_NP(fakesoftint)
    207 	pushfl
    208 #if defined(__xpv)
    209 	popl	%eax
    210 	EVENT_MASK_TO_IE(%edx, %eax)
    211 	pushl	%eax
    212 #endif
    213 	pushl	%cs
    214 	pushl	$fakesoftint_return
    215 	pushl	$0
    216 	pushl	$T_SOFTINT
    217 	jmp	cmnint
    218 	ALTENTRY(fakesoftint_return)
    219 	ret
    220 	SET_SIZE(fakesoftint_return)
    221 	SET_SIZE(fakesoftint)
    222 
    223 #endif	/* __i386 */
    224 #endif	/* __lint */
    225