xref: /illumos-gate/usr/src/uts/i86pc/ml/interrupt.S (revision e3ae4b35c024af1196582063ecee3ab79367227d)
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 * Copyright 2019 Joyent, Inc.
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#include <sys/asm_linkage.h>
34#include <sys/asm_misc.h>
35#include <sys/regset.h>
36#include <sys/psw.h>
37#include <sys/x86_archext.h>
38
39#include <sys/segments.h>
40#include <sys/pcb.h>
41#include <sys/trap.h>
42#include <sys/ftrace.h>
43#include <sys/traptrace.h>
44#include <sys/clock.h>
45#include <sys/panic.h>
46#include "assym.h"
47
48	/*
49	 * Common register usage:
50	 *
51	 * %r12		trap trace pointer
52	 */
53	ENTRY_NP2(cmnint, _interrupt)
54
55	INTR_PUSH
56	INTGATE_INIT_KERNEL_FLAGS	/* (set kernel rflags values) */
57
58	/*
59	 * At the end of TRACE_PTR %r12 points to the current TRAPTRACE entry
60	 */
61	TRACE_PTR(%r12, %rax, %eax, %rdx, $TT_INTERRUPT)
62						/* Uses labels 8 and 9 */
63	TRACE_REGS(%r12, %rsp, %rax, %rbx)	/* Uses label 9 */
64	TRACE_STAMP(%r12)		/* Clobbers %eax, %edx, uses 9 */
65
66	movq	%rsp, %rbp
67
68	TRACE_STACK(%r12)
69
70#ifdef TRAPTRACE
71	LOADCPU(%rbx)				/* &cpu */
72	movl	CPU_PRI(%rbx), %r14d		/* old ipl */
73	movl	$255, TTR_IPL(%r12)
74	movl	%r14d, %edi
75	movb	%dil, TTR_PRI(%r12)
76	movl	CPU_BASE_SPL(%rbx), %edi
77	movb	%dil, TTR_SPL(%r12)
78	movb	$255, TTR_VECTOR(%r12)
79	movq	%r12, %rsi		/* pass traptrace record pointer */
80#endif
81
82	movq	%rsp, %rdi		/* pass struct regs pointer */
83	movq	do_interrupt_common, %rax
84	INDIRECT_CALL_REG(rax)
85
86	jmp	_sys_rtt_ints_disabled
87	/*NOTREACHED*/
88
89	SET_SIZE(cmnint)
90	SET_SIZE(_interrupt)
91
92/*
93 * Declare a uintptr_t which has the size of _interrupt to enable stack
94 * traceback code to know when a regs structure is on the stack.
95 */
96	.globl	_interrupt_size
97	.align	CLONGSIZE
98_interrupt_size:
99	.NWORD	. - _interrupt
100	.type	_interrupt_size, @object
101
102	/*
103	 * If we're here, we're being called from splx() to fake a soft
104	 * interrupt (note that interrupts are still disabled from
105	 * splx()).  We execute this code when a soft interrupt is
106	 * posted at level higher than the CPU's current spl; when spl
107	 * is lowered in splx(), it will see the softint and jump here.
108	 * We'll do exactly what a trap would do:  push our flags, %cs,
109	 * %rip, error code and trap number (T_SOFTINT).  The cmnint()
110	 * code will see T_SOFTINT and branch to the dosoftint() code.
111	 *
112	 * iretq -always- pops all five regs. Imitate the 16-byte
113	 * auto-align of the stack, and the zero-ed out %ss value.
114	 */
115
116	ENTRY_NP(fakesoftint)
117	movq	%rsp, %r11
118	andq	$-16, %rsp
119	pushq	$KDS_SEL	/* %ss */
120	pushq	%r11		/* %rsp */
121	pushf			/* rflags */
122#if defined(__xpv)
123	popq	%r11
124	EVENT_MASK_TO_IE(%rdi, %r11)
125	pushq	%r11
126#endif
127	pushq	$KCS_SEL	/* %cs */
128	leaq	fakesoftint_return(%rip), %r11
129	pushq	%r11		/* %rip */
130	pushq	$0		/* err */
131	pushq	$T_SOFTINT	/* trap */
132	jmp	cmnint
133	ALTENTRY(fakesoftint_return)
134	ret
135	SET_SIZE(fakesoftint_return)
136	SET_SIZE(fakesoftint)
137
138