xref: /freebsd/sys/i386/i386/apic_vector.S (revision 069ac184)
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 */
32
33/*
34 * Interrupt entry points for external interrupts triggered by I/O APICs
35 * as well as IPI handlers.
36 */
37
38#include "opt_smp.h"
39
40#include <machine/asmacros.h>
41#include <machine/psl.h>
42#include <machine/specialreg.h>
43#include <x86/apicreg.h>
44
45#include "assym.inc"
46
47	.text
48	SUPERALIGN_TEXT
49	/* End Of Interrupt to APIC */
50as_lapic_eoi:
51	cmpl	$0,x2apic_mode
52	jne	1f
53	movl	lapic_map,%eax
54	movl	$0,LA_EOI(%eax)
55	ret
561:
57	movl	$MSR_APIC_EOI,%ecx
58	xorl	%eax,%eax
59	xorl	%edx,%edx
60	wrmsr
61	ret
62
63/*
64 * I/O Interrupt Entry Point.  Rather than having one entry point for
65 * each interrupt source, we use one entry point for each 32-bit word
66 * in the ISR.  The handler determines the highest bit set in the ISR,
67 * translates that into a vector, and passes the vector to the
68 * lapic_handle_intr() function.
69 */
70	.macro	ISR_VEC	index, vec_name
71	.text
72	SUPERALIGN_TEXT
73	.globl	X\()\vec_name\()_pti, X\()\vec_name
74
75X\()\vec_name\()_pti:
76X\()\vec_name:
77	PUSH_FRAME
78	SET_KERNEL_SREGS
79	cld
80	KENTER
81	cmpl	$0,x2apic_mode
82	je	2f
83	movl	$(MSR_APIC_ISR0 + \index),%ecx
84	rdmsr
85	jmp	3f
862:
87	movl	lapic_map, %edx		/* pointer to local APIC */
88	movl	LA_ISR + 16 * \index(%edx), %eax	/* load ISR */
893:
90	bsrl	%eax, %eax	/* index of highest set bit in ISR */
91	jz	4f
92	addl	$(32 * \index),%eax
93	pushl	%esp
94	pushl	%eax		/* pass the IRQ */
95	movl	$lapic_handle_intr, %eax
96	call	*%eax
97	addl	$8, %esp	/* discard parameter */
984:
99	jmp	doreti
100	.endm
101
102/*
103 * Handle "spurious INTerrupts".
104 * Notes:
105 *  This is different than the "spurious INTerrupt" generated by an
106 *   8259 PIC for missing INTs.  See the APIC documentation for details.
107 *  This routine should NOT do an 'EOI' cycle.
108 */
109	.text
110	SUPERALIGN_TEXT
111IDTVEC(spuriousint)
112
113	/* No EOI cycle used here */
114
115	iret
116
117	ISR_VEC	1, apic_isr1
118	ISR_VEC	2, apic_isr2
119	ISR_VEC	3, apic_isr3
120	ISR_VEC	4, apic_isr4
121	ISR_VEC	5, apic_isr5
122	ISR_VEC	6, apic_isr6
123	ISR_VEC	7, apic_isr7
124
125/*
126 * Local APIC periodic timer handler.
127 */
128	.text
129	SUPERALIGN_TEXT
130IDTVEC(timerint_pti)
131IDTVEC(timerint)
132	PUSH_FRAME
133	SET_KERNEL_SREGS
134	cld
135	KENTER
136	pushl	%esp
137	movl	$lapic_handle_timer, %eax
138	call	*%eax
139	add	$4, %esp
140	jmp	doreti
141
142/*
143 * Local APIC CMCI handler.
144 */
145	.text
146	SUPERALIGN_TEXT
147IDTVEC(cmcint_pti)
148IDTVEC(cmcint)
149	PUSH_FRAME
150	SET_KERNEL_SREGS
151	cld
152	KENTER
153	movl	$lapic_handle_cmc, %eax
154	call	*%eax
155	jmp	doreti
156
157/*
158 * Local APIC error interrupt handler.
159 */
160	.text
161	SUPERALIGN_TEXT
162IDTVEC(errorint_pti)
163IDTVEC(errorint)
164	PUSH_FRAME
165	SET_KERNEL_SREGS
166	cld
167	KENTER
168	movl	$lapic_handle_error, %eax
169	call	*%eax
170	jmp	doreti
171
172#ifdef XENHVM
173/*
174 * Xen event channel upcall interrupt handler.
175 * Only used when the hypervisor supports direct vector callbacks.
176 */
177	.text
178	SUPERALIGN_TEXT
179IDTVEC(xen_intr_upcall)
180	PUSH_FRAME
181	SET_KERNEL_SREGS
182	cld
183	KENTER
184	pushl	%esp
185	movl	$xen_arch_intr_handle_upcall, %eax
186	call	*%eax
187	add	$4, %esp
188	jmp	doreti
189#endif
190
191#ifdef SMP
192/*
193 * Global address space TLB shootdown.
194 */
195	.text
196	SUPERALIGN_TEXT
197invltlb_ret:
198	call	as_lapic_eoi
199	jmp	doreti
200
201	SUPERALIGN_TEXT
202IDTVEC(invltlb)
203	PUSH_FRAME
204	SET_KERNEL_SREGS
205	cld
206	KENTER
207	movl	$invltlb_handler, %eax
208	call	*%eax
209	jmp	invltlb_ret
210
211/*
212 * Single page TLB shootdown
213 */
214	.text
215	SUPERALIGN_TEXT
216IDTVEC(invlpg)
217	PUSH_FRAME
218	SET_KERNEL_SREGS
219	cld
220	KENTER
221	movl	$invlpg_handler, %eax
222	call	*%eax
223	jmp	invltlb_ret
224
225/*
226 * Page range TLB shootdown.
227 */
228	.text
229	SUPERALIGN_TEXT
230IDTVEC(invlrng)
231	PUSH_FRAME
232	SET_KERNEL_SREGS
233	cld
234	KENTER
235	movl	$invlrng_handler, %eax
236	call	*%eax
237	jmp	invltlb_ret
238
239/*
240 * Invalidate cache.
241 */
242	.text
243	SUPERALIGN_TEXT
244IDTVEC(invlcache)
245	PUSH_FRAME
246	SET_KERNEL_SREGS
247	cld
248	KENTER
249	movl	$invlcache_handler, %eax
250	call	*%eax
251	jmp	invltlb_ret
252
253/*
254 * Handler for IPIs sent via the per-cpu IPI bitmap.
255 */
256	.text
257	SUPERALIGN_TEXT
258IDTVEC(ipi_intr_bitmap_handler)
259	PUSH_FRAME
260	SET_KERNEL_SREGS
261	cld
262	KENTER
263	call	as_lapic_eoi
264	movl	$ipi_bitmap_handler, %eax
265	call	*%eax
266	jmp	doreti
267
268/*
269 * Executed by a CPU when it receives an IPI_STOP from another CPU.
270 */
271	.text
272	SUPERALIGN_TEXT
273IDTVEC(cpustop)
274	PUSH_FRAME
275	SET_KERNEL_SREGS
276	cld
277	KENTER
278	call	as_lapic_eoi
279	movl	$cpustop_handler, %eax
280	call	*%eax
281	jmp	doreti
282
283/*
284 * Executed by a CPU when it receives an IPI_SUSPEND from another CPU.
285 */
286	.text
287	SUPERALIGN_TEXT
288IDTVEC(cpususpend)
289	PUSH_FRAME
290	SET_KERNEL_SREGS
291	cld
292	KENTER
293	call	as_lapic_eoi
294	movl	$cpususpend_handler, %eax
295	call	*%eax
296	jmp	doreti
297
298/*
299 * Executed by a CPU when it receives an IPI_SWI.
300 */
301	.text
302	SUPERALIGN_TEXT
303IDTVEC(ipi_swi)
304	PUSH_FRAME
305	SET_KERNEL_SREGS
306	cld
307	KENTER
308	call	as_lapic_eoi
309	movl	$ipi_swi_handler, %eax
310	call	*%eax
311	jmp	doreti
312
313/*
314 * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU.
315 *
316 * - Calls the generic rendezvous action function.
317 */
318	.text
319	SUPERALIGN_TEXT
320IDTVEC(rendezvous)
321	PUSH_FRAME
322	SET_KERNEL_SREGS
323	cld
324	KENTER
325#ifdef COUNT_IPIS
326	movl	PCPU(CPUID), %eax
327	movl	ipi_rendezvous_counts(,%eax,4), %eax
328	incl	(%eax)
329#endif
330	movl	$smp_rendezvous_action, %eax
331	call	*%eax
332	call	as_lapic_eoi
333	jmp	doreti
334
335#endif /* SMP */
336