xref: /freebsd/sys/amd64/amd64/apic_vector.S (revision 3157ba21)
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 * 4. 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 <machine/asmacros.h>
40#include <machine/apicreg.h>
41
42#include "assym.s"
43
44/*
45 * I/O Interrupt Entry Point.  Rather than having one entry point for
46 * each interrupt source, we use one entry point for each 32-bit word
47 * in the ISR.  The handler determines the highest bit set in the ISR,
48 * translates that into a vector, and passes the vector to the
49 * lapic_handle_intr() function.
50 */
51#define	ISR_VEC(index, vec_name)					\
52	.text ;								\
53	SUPERALIGN_TEXT ;						\
54IDTVEC(vec_name) ;							\
55	PUSH_FRAME ;							\
56	FAKE_MCOUNT(TF_RIP(%rsp)) ;					\
57	movq	lapic, %rdx ;	/* pointer to local APIC */		\
58	movl	LA_ISR + 16 * (index)(%rdx), %eax ;	/* load ISR */	\
59	bsrl	%eax, %eax ;	/* index of highset set bit in ISR */	\
60	jz	2f ;							\
61	addl	$(32 * index),%eax ;					\
621: ;									\
63	movq	%rsp, %rsi	;                                       \
64	movl	%eax, %edi ;	/* pass the IRQ */			\
65	call	lapic_handle_intr ;					\
66	MEXITCOUNT ;							\
67	jmp	doreti ;						\
682:	movl	$-1, %eax ;	/* send a vector of -1 */		\
69	jmp	1b
70
71/*
72 * Handle "spurious INTerrupts".
73 * Notes:
74 *  This is different than the "spurious INTerrupt" generated by an
75 *   8259 PIC for missing INTs.  See the APIC documentation for details.
76 *  This routine should NOT do an 'EOI' cycle.
77 */
78	.text
79	SUPERALIGN_TEXT
80IDTVEC(spuriousint)
81
82	/* No EOI cycle used here */
83
84	jmp	doreti_iret
85
86	ISR_VEC(1, apic_isr1)
87	ISR_VEC(2, apic_isr2)
88	ISR_VEC(3, apic_isr3)
89	ISR_VEC(4, apic_isr4)
90	ISR_VEC(5, apic_isr5)
91	ISR_VEC(6, apic_isr6)
92	ISR_VEC(7, apic_isr7)
93
94/*
95 * Local APIC periodic timer handler.
96 */
97	.text
98	SUPERALIGN_TEXT
99IDTVEC(timerint)
100	PUSH_FRAME
101	FAKE_MCOUNT(TF_RIP(%rsp))
102	movq	%rsp, %rdi
103	call	lapic_handle_timer
104	MEXITCOUNT
105	jmp	doreti
106
107/*
108 * Local APIC CMCI handler.
109 */
110	.text
111	SUPERALIGN_TEXT
112IDTVEC(cmcint)
113	PUSH_FRAME
114	FAKE_MCOUNT(TF_RIP(%rsp))
115	call	lapic_handle_cmc
116	MEXITCOUNT
117	jmp	doreti
118
119/*
120 * Local APIC error interrupt handler.
121 */
122	.text
123	SUPERALIGN_TEXT
124IDTVEC(errorint)
125	PUSH_FRAME
126	FAKE_MCOUNT(TF_RIP(%rsp))
127	call	lapic_handle_error
128	MEXITCOUNT
129	jmp	doreti
130
131#ifdef SMP
132/*
133 * Global address space TLB shootdown.
134 */
135	.text
136	SUPERALIGN_TEXT
137IDTVEC(invltlb)
138	pushq	%rax
139
140	movq	%cr3, %rax		/* invalidate the TLB */
141	movq	%rax, %cr3
142
143	movq	lapic, %rax
144	movl	$0, LA_EOI(%rax)	/* End Of Interrupt to APIC */
145
146	lock
147	incl	smp_tlb_wait
148
149	popq	%rax
150	jmp	doreti_iret
151
152/*
153 * Single page TLB shootdown
154 */
155	.text
156	SUPERALIGN_TEXT
157IDTVEC(invlpg)
158	pushq	%rax
159
160	movq	smp_tlb_addr1, %rax
161	invlpg	(%rax)			/* invalidate single page */
162
163	movq	lapic, %rax
164	movl	$0, LA_EOI(%rax)	/* End Of Interrupt to APIC */
165
166	lock
167	incl	smp_tlb_wait
168
169	popq	%rax
170	jmp	doreti_iret
171
172/*
173 * Page range TLB shootdown.
174 */
175	.text
176	SUPERALIGN_TEXT
177IDTVEC(invlrng)
178	pushq	%rax
179	pushq	%rdx
180
181	movq	smp_tlb_addr1, %rdx
182	movq	smp_tlb_addr2, %rax
1831:	invlpg	(%rdx)			/* invalidate single page */
184	addq	$PAGE_SIZE, %rdx
185	cmpq	%rax, %rdx
186	jb	1b
187
188	movq	lapic, %rax
189	movl	$0, LA_EOI(%rax)	/* End Of Interrupt to APIC */
190
191	lock
192	incl	smp_tlb_wait
193
194	popq	%rdx
195	popq	%rax
196	jmp	doreti_iret
197
198/*
199 * Invalidate cache.
200 */
201	.text
202	SUPERALIGN_TEXT
203IDTVEC(invlcache)
204	pushq	%rax
205
206	wbinvd
207
208	movq	lapic, %rax
209	movl	$0, LA_EOI(%rax)	/* End Of Interrupt to APIC */
210
211	lock
212	incl	smp_tlb_wait
213
214	popq	%rax
215	jmp	doreti_iret
216
217/*
218 * Handler for IPIs sent via the per-cpu IPI bitmap.
219 */
220	.text
221	SUPERALIGN_TEXT
222IDTVEC(ipi_intr_bitmap_handler)
223	PUSH_FRAME
224
225	movq	lapic, %rdx
226	movl	$0, LA_EOI(%rdx)	/* End Of Interrupt to APIC */
227
228	FAKE_MCOUNT(TF_RIP(%rsp))
229
230	call	ipi_bitmap_handler
231	MEXITCOUNT
232	jmp	doreti
233
234/*
235 * Executed by a CPU when it receives an IPI_STOP from another CPU.
236 */
237	.text
238	SUPERALIGN_TEXT
239IDTVEC(cpustop)
240	PUSH_FRAME
241
242	movq	lapic, %rax
243	movl	$0, LA_EOI(%rax)	/* End Of Interrupt to APIC */
244
245	call	cpustop_handler
246	jmp	doreti
247
248/*
249 * Executed by a CPU when it receives an IPI_SUSPEND from another CPU.
250 */
251	.text
252	SUPERALIGN_TEXT
253IDTVEC(cpususpend)
254	PUSH_FRAME
255
256	movq	lapic, %rax
257	movl	$0, LA_EOI(%rax)	/* End Of Interrupt to APIC */
258
259	call	cpususpend_handler
260
261	POP_FRAME
262	jmp	doreti_iret
263
264/*
265 * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU.
266 *
267 * - Calls the generic rendezvous action function.
268 */
269	.text
270	SUPERALIGN_TEXT
271IDTVEC(rendezvous)
272	PUSH_FRAME
273	call	smp_rendezvous_action
274	movq	lapic, %rax
275	movl	$0, LA_EOI(%rax)	/* End Of Interrupt to APIC */
276	jmp	doreti
277#endif /* SMP */
278