OpenGrok

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