xref: /illumos-gate/usr/src/uts/i86pc/ml/interrupt.S (revision 5d9d9091f564c198a760790b0bfa72c44e17912b)
1*5d9d9091SRichard Lowe/*
2*5d9d9091SRichard Lowe * CDDL HEADER START
3*5d9d9091SRichard Lowe *
4*5d9d9091SRichard Lowe * The contents of this file are subject to the terms of the
5*5d9d9091SRichard Lowe * Common Development and Distribution License (the "License").
6*5d9d9091SRichard Lowe * You may not use this file except in compliance with the License.
7*5d9d9091SRichard Lowe *
8*5d9d9091SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5d9d9091SRichard Lowe * or http://www.opensolaris.org/os/licensing.
10*5d9d9091SRichard Lowe * See the License for the specific language governing permissions
11*5d9d9091SRichard Lowe * and limitations under the License.
12*5d9d9091SRichard Lowe *
13*5d9d9091SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
14*5d9d9091SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5d9d9091SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
16*5d9d9091SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
17*5d9d9091SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
18*5d9d9091SRichard Lowe *
19*5d9d9091SRichard Lowe * CDDL HEADER END
20*5d9d9091SRichard Lowe */
21*5d9d9091SRichard Lowe/*
22*5d9d9091SRichard Lowe * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
23*5d9d9091SRichard Lowe * Copyright 2019 Joyent, Inc.
24*5d9d9091SRichard Lowe */
25*5d9d9091SRichard Lowe
26*5d9d9091SRichard Lowe/*	Copyright (c) 1990, 1991 UNIX System Laboratories, Inc.	*/
27*5d9d9091SRichard Lowe/*	Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T	*/
28*5d9d9091SRichard Lowe/*	  All Rights Reserved					*/
29*5d9d9091SRichard Lowe
30*5d9d9091SRichard Lowe/*	Copyright (c) 1987, 1988 Microsoft Corporation		*/
31*5d9d9091SRichard Lowe/*	  All Rights Reserved					*/
32*5d9d9091SRichard Lowe
33*5d9d9091SRichard Lowe#include <sys/asm_linkage.h>
34*5d9d9091SRichard Lowe#include <sys/asm_misc.h>
35*5d9d9091SRichard Lowe#include <sys/regset.h>
36*5d9d9091SRichard Lowe#include <sys/psw.h>
37*5d9d9091SRichard Lowe#include <sys/x86_archext.h>
38*5d9d9091SRichard Lowe
39*5d9d9091SRichard Lowe#include <sys/segments.h>
40*5d9d9091SRichard Lowe#include <sys/pcb.h>
41*5d9d9091SRichard Lowe#include <sys/trap.h>
42*5d9d9091SRichard Lowe#include <sys/ftrace.h>
43*5d9d9091SRichard Lowe#include <sys/traptrace.h>
44*5d9d9091SRichard Lowe#include <sys/clock.h>
45*5d9d9091SRichard Lowe#include <sys/panic.h>
46*5d9d9091SRichard Lowe#include "assym.h"
47*5d9d9091SRichard Lowe
48*5d9d9091SRichard Lowe	/*
49*5d9d9091SRichard Lowe	 * Common register usage:
50*5d9d9091SRichard Lowe	 *
51*5d9d9091SRichard Lowe	 * %r12		trap trace pointer
52*5d9d9091SRichard Lowe	 */
53*5d9d9091SRichard Lowe	ENTRY_NP2(cmnint, _interrupt)
54*5d9d9091SRichard Lowe
55*5d9d9091SRichard Lowe	INTR_PUSH
56*5d9d9091SRichard Lowe	INTGATE_INIT_KERNEL_FLAGS	/* (set kernel rflags values) */
57*5d9d9091SRichard Lowe
58*5d9d9091SRichard Lowe	/*
59*5d9d9091SRichard Lowe	 * At the end of TRACE_PTR %r12 points to the current TRAPTRACE entry
60*5d9d9091SRichard Lowe	 */
61*5d9d9091SRichard Lowe	TRACE_PTR(%r12, %rax, %eax, %rdx, $TT_INTERRUPT)
62*5d9d9091SRichard Lowe						/* Uses labels 8 and 9 */
63*5d9d9091SRichard Lowe	TRACE_REGS(%r12, %rsp, %rax, %rbx)	/* Uses label 9 */
64*5d9d9091SRichard Lowe	TRACE_STAMP(%r12)		/* Clobbers %eax, %edx, uses 9 */
65*5d9d9091SRichard Lowe
66*5d9d9091SRichard Lowe	movq	%rsp, %rbp
67*5d9d9091SRichard Lowe
68*5d9d9091SRichard Lowe	TRACE_STACK(%r12)
69*5d9d9091SRichard Lowe
70*5d9d9091SRichard Lowe#ifdef TRAPTRACE
71*5d9d9091SRichard Lowe	LOADCPU(%rbx)				/* &cpu */
72*5d9d9091SRichard Lowe	movl	CPU_PRI(%rbx), %r14d		/* old ipl */
73*5d9d9091SRichard Lowe	movl	$255, TTR_IPL(%r12)
74*5d9d9091SRichard Lowe	movl	%r14d, %edi
75*5d9d9091SRichard Lowe	movb	%dil, TTR_PRI(%r12)
76*5d9d9091SRichard Lowe	movl	CPU_BASE_SPL(%rbx), %edi
77*5d9d9091SRichard Lowe	movb	%dil, TTR_SPL(%r12)
78*5d9d9091SRichard Lowe	movb	$255, TTR_VECTOR(%r12)
79*5d9d9091SRichard Lowe	movq	%r12, %rsi		/* pass traptrace record pointer */
80*5d9d9091SRichard Lowe#endif
81*5d9d9091SRichard Lowe
82*5d9d9091SRichard Lowe	movq	%rsp, %rdi		/* pass struct regs pointer */
83*5d9d9091SRichard Lowe	movq	do_interrupt_common, %rax
84*5d9d9091SRichard Lowe	INDIRECT_CALL_REG(rax)
85*5d9d9091SRichard Lowe
86*5d9d9091SRichard Lowe	jmp	_sys_rtt_ints_disabled
87*5d9d9091SRichard Lowe	/*NOTREACHED*/
88*5d9d9091SRichard Lowe
89*5d9d9091SRichard Lowe	SET_SIZE(cmnint)
90*5d9d9091SRichard Lowe	SET_SIZE(_interrupt)
91*5d9d9091SRichard Lowe
92*5d9d9091SRichard Lowe/*
93*5d9d9091SRichard Lowe * Declare a uintptr_t which has the size of _interrupt to enable stack
94*5d9d9091SRichard Lowe * traceback code to know when a regs structure is on the stack.
95*5d9d9091SRichard Lowe */
96*5d9d9091SRichard Lowe	.globl	_interrupt_size
97*5d9d9091SRichard Lowe	.align	CLONGSIZE
98*5d9d9091SRichard Lowe_interrupt_size:
99*5d9d9091SRichard Lowe	.NWORD	. - _interrupt
100*5d9d9091SRichard Lowe	.type	_interrupt_size, @object
101*5d9d9091SRichard Lowe
102*5d9d9091SRichard Lowe	/*
103*5d9d9091SRichard Lowe	 * If we're here, we're being called from splx() to fake a soft
104*5d9d9091SRichard Lowe	 * interrupt (note that interrupts are still disabled from
105*5d9d9091SRichard Lowe	 * splx()).  We execute this code when a soft interrupt is
106*5d9d9091SRichard Lowe	 * posted at level higher than the CPU's current spl; when spl
107*5d9d9091SRichard Lowe	 * is lowered in splx(), it will see the softint and jump here.
108*5d9d9091SRichard Lowe	 * We'll do exactly what a trap would do:  push our flags, %cs,
109*5d9d9091SRichard Lowe	 * %rip, error code and trap number (T_SOFTINT).  The cmnint()
110*5d9d9091SRichard Lowe	 * code will see T_SOFTINT and branch to the dosoftint() code.
111*5d9d9091SRichard Lowe	 *
112*5d9d9091SRichard Lowe	 * iretq -always- pops all five regs. Imitate the 16-byte
113*5d9d9091SRichard Lowe	 * auto-align of the stack, and the zero-ed out %ss value.
114*5d9d9091SRichard Lowe	 */
115*5d9d9091SRichard Lowe
116*5d9d9091SRichard Lowe	ENTRY_NP(fakesoftint)
117*5d9d9091SRichard Lowe	movq	%rsp, %r11
118*5d9d9091SRichard Lowe	andq	$-16, %rsp
119*5d9d9091SRichard Lowe	pushq	$KDS_SEL	/* %ss */
120*5d9d9091SRichard Lowe	pushq	%r11		/* %rsp */
121*5d9d9091SRichard Lowe	pushf			/* rflags */
122*5d9d9091SRichard Lowe#if defined(__xpv)
123*5d9d9091SRichard Lowe	popq	%r11
124*5d9d9091SRichard Lowe	EVENT_MASK_TO_IE(%rdi, %r11)
125*5d9d9091SRichard Lowe	pushq	%r11
126*5d9d9091SRichard Lowe#endif
127*5d9d9091SRichard Lowe	pushq	$KCS_SEL	/* %cs */
128*5d9d9091SRichard Lowe	leaq	fakesoftint_return(%rip), %r11
129*5d9d9091SRichard Lowe	pushq	%r11		/* %rip */
130*5d9d9091SRichard Lowe	pushq	$0		/* err */
131*5d9d9091SRichard Lowe	pushq	$T_SOFTINT	/* trap */
132*5d9d9091SRichard Lowe	jmp	cmnint
133*5d9d9091SRichard Lowe	ALTENTRY(fakesoftint_return)
134*5d9d9091SRichard Lowe	ret
135*5d9d9091SRichard Lowe	SET_SIZE(fakesoftint_return)
136*5d9d9091SRichard Lowe	SET_SIZE(fakesoftint)
137*5d9d9091SRichard Lowe
138