xref: /freebsd/sys/i386/i386/apic_vector.S (revision d411c1d6)
1/*-
2 * Copyright (c) 1989, 1990 William F. Jolitz.
3 * Copyright (c) 1990 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the University nor the names of its contributors
15 *    may be used to endorse or promote products derived from this software
16 *    without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 *	from: vector.s, 386BSD 0.1 unknown origin
31 * $FreeBSD$
32 */
33
34/*
35 * Interrupt entry points for external interrupts triggered by I/O APICs
36 * as well as IPI handlers.
37 */
38
39#include "opt_smp.h"
40
41#include <machine/asmacros.h>
42#include <machine/psl.h>
43#include <machine/specialreg.h>
44#include <x86/apicreg.h>
45
46#include "assym.inc"
47
48	.text
49	SUPERALIGN_TEXT
50	/* End Of Interrupt to APIC */
51as_lapic_eoi:
52	cmpl	$0,x2apic_mode
53	jne	1f
54	movl	lapic_map,%eax
55	movl	$0,LA_EOI(%eax)
56	ret
571:
58	movl	$MSR_APIC_EOI,%ecx
59	xorl	%eax,%eax
60	xorl	%edx,%edx
61	wrmsr
62	ret
63
64/*
65 * I/O Interrupt Entry Point.  Rather than having one entry point for
66 * each interrupt source, we use one entry point for each 32-bit word
67 * in the ISR.  The handler determines the highest bit set in the ISR,
68 * translates that into a vector, and passes the vector to the
69 * lapic_handle_intr() function.
70 */
71	.macro	ISR_VEC	index, vec_name
72	.text
73	SUPERALIGN_TEXT
74	.globl	X\()\vec_name\()_pti, X\()\vec_name
75
76X\()\vec_name\()_pti:
77X\()\vec_name:
78	PUSH_FRAME
79	SET_KERNEL_SREGS
80	cld
81	KENTER
82	cmpl	$0,x2apic_mode
83	je	2f
84	movl	$(MSR_APIC_ISR0 + \index),%ecx
85	rdmsr
86	jmp	3f
872:
88	movl	lapic_map, %edx		/* pointer to local APIC */
89	movl	LA_ISR + 16 * \index(%edx), %eax	/* load ISR */
903:
91	bsrl	%eax, %eax	/* index of highest set bit in ISR */
92	jz	4f
93	addl	$(32 * \index),%eax
94	pushl	%esp
95	pushl	%eax		/* pass the IRQ */
96	movl	$lapic_handle_intr, %eax
97	call	*%eax
98	addl	$8, %esp	/* discard parameter */
994:
100	jmp	doreti
101	.endm
102
103/*
104 * Handle "spurious INTerrupts".
105 * Notes:
106 *  This is different than the "spurious INTerrupt" generated by an
107 *   8259 PIC for missing INTs.  See the APIC documentation for details.
108 *  This routine should NOT do an 'EOI' cycle.
109 */
110	.text
111	SUPERALIGN_TEXT
112IDTVEC(spuriousint)
113
114	/* No EOI cycle used here */
115
116	iret
117
118	ISR_VEC	1, apic_isr1
119	ISR_VEC	2, apic_isr2
120	ISR_VEC	3, apic_isr3
121	ISR_VEC	4, apic_isr4
122	ISR_VEC	5, apic_isr5
123	ISR_VEC	6, apic_isr6
124	ISR_VEC	7, apic_isr7
125
126/*
127 * Local APIC periodic timer handler.
128 */
129	.text
130	SUPERALIGN_TEXT
131IDTVEC(timerint_pti)
132IDTVEC(timerint)
133	PUSH_FRAME
134	SET_KERNEL_SREGS
135	cld
136	KENTER
137	pushl	%esp
138	movl	$lapic_handle_timer, %eax
139	call	*%eax
140	add	$4, %esp
141	jmp	doreti
142
143/*
144 * Local APIC CMCI handler.
145 */
146	.text
147	SUPERALIGN_TEXT
148IDTVEC(cmcint_pti)
149IDTVEC(cmcint)
150	PUSH_FRAME
151	SET_KERNEL_SREGS
152	cld
153	KENTER
154	movl	$lapic_handle_cmc, %eax
155	call	*%eax
156	jmp	doreti
157
158/*
159 * Local APIC error interrupt handler.
160 */
161	.text
162	SUPERALIGN_TEXT
163IDTVEC(errorint_pti)
164IDTVEC(errorint)
165	PUSH_FRAME
166	SET_KERNEL_SREGS
167	cld
168	KENTER
169	movl	$lapic_handle_error, %eax
170	call	*%eax
171	jmp	doreti
172
173#ifdef XENHVM
174/*
175 * Xen event channel upcall interrupt handler.
176 * Only used when the hypervisor supports direct vector callbacks.
177 */
178	.text
179	SUPERALIGN_TEXT
180IDTVEC(xen_intr_upcall)
181	PUSH_FRAME
182	SET_KERNEL_SREGS
183	cld
184	KENTER
185	pushl	%esp
186	movl	$xen_arch_intr_handle_upcall, %eax
187	call	*%eax
188	add	$4, %esp
189	jmp	doreti
190#endif
191
192#ifdef SMP
193/*
194 * Global address space TLB shootdown.
195 */
196	.text
197	SUPERALIGN_TEXT
198invltlb_ret:
199	call	as_lapic_eoi
200	jmp	doreti
201
202	SUPERALIGN_TEXT
203IDTVEC(invltlb)
204	PUSH_FRAME
205	SET_KERNEL_SREGS
206	cld
207	KENTER
208	movl	$invltlb_handler, %eax
209	call	*%eax
210	jmp	invltlb_ret
211
212/*
213 * Single page TLB shootdown
214 */
215	.text
216	SUPERALIGN_TEXT
217IDTVEC(invlpg)
218	PUSH_FRAME
219	SET_KERNEL_SREGS
220	cld
221	KENTER
222	movl	$invlpg_handler, %eax
223	call	*%eax
224	jmp	invltlb_ret
225
226/*
227 * Page range TLB shootdown.
228 */
229	.text
230	SUPERALIGN_TEXT
231IDTVEC(invlrng)
232	PUSH_FRAME
233	SET_KERNEL_SREGS
234	cld
235	KENTER
236	movl	$invlrng_handler, %eax
237	call	*%eax
238	jmp	invltlb_ret
239
240/*
241 * Invalidate cache.
242 */
243	.text
244	SUPERALIGN_TEXT
245IDTVEC(invlcache)
246	PUSH_FRAME
247	SET_KERNEL_SREGS
248	cld
249	KENTER
250	movl	$invlcache_handler, %eax
251	call	*%eax
252	jmp	invltlb_ret
253
254/*
255 * Handler for IPIs sent via the per-cpu IPI bitmap.
256 */
257	.text
258	SUPERALIGN_TEXT
259IDTVEC(ipi_intr_bitmap_handler)
260	PUSH_FRAME
261	SET_KERNEL_SREGS
262	cld
263	KENTER
264	call	as_lapic_eoi
265	movl	$ipi_bitmap_handler, %eax
266	call	*%eax
267	jmp	doreti
268
269/*
270 * Executed by a CPU when it receives an IPI_STOP from another CPU.
271 */
272	.text
273	SUPERALIGN_TEXT
274IDTVEC(cpustop)
275	PUSH_FRAME
276	SET_KERNEL_SREGS
277	cld
278	KENTER
279	call	as_lapic_eoi
280	movl	$cpustop_handler, %eax
281	call	*%eax
282	jmp	doreti
283
284/*
285 * Executed by a CPU when it receives an IPI_SUSPEND from another CPU.
286 */
287	.text
288	SUPERALIGN_TEXT
289IDTVEC(cpususpend)
290	PUSH_FRAME
291	SET_KERNEL_SREGS
292	cld
293	KENTER
294	call	as_lapic_eoi
295	movl	$cpususpend_handler, %eax
296	call	*%eax
297	jmp	doreti
298
299/*
300 * Executed by a CPU when it receives an IPI_SWI.
301 */
302	.text
303	SUPERALIGN_TEXT
304IDTVEC(ipi_swi)
305	PUSH_FRAME
306	SET_KERNEL_SREGS
307	cld
308	KENTER
309	call	as_lapic_eoi
310	movl	$ipi_swi_handler, %eax
311	call	*%eax
312	jmp	doreti
313
314/*
315 * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU.
316 *
317 * - Calls the generic rendezvous action function.
318 */
319	.text
320	SUPERALIGN_TEXT
321IDTVEC(rendezvous)
322	PUSH_FRAME
323	SET_KERNEL_SREGS
324	cld
325	KENTER
326#ifdef COUNT_IPIS
327	movl	PCPU(CPUID), %eax
328	movl	ipi_rendezvous_counts(,%eax,4), %eax
329	incl	(%eax)
330#endif
331	movl	$smp_rendezvous_action, %eax
332	call	*%eax
333	call	as_lapic_eoi
334	jmp	doreti
335
336#endif /* SMP */
337