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 */
51 as_lapic_eoi:
52 cmpl $0,x2apic_mode
53 jne 1f
54 movl lapic_map,%eax
55 movl $0,LA_EOI(%eax)
56 ret
57 1:
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
76 X\()\vec_name\()_pti:
77 X\()\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
87 2:
88 movl lapic_map, %edx /* pointer to local APIC */
89 movl LA_ISR + 16 * \index(%edx), %eax /* load ISR */
90 3:
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 */
99 4:
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
112 IDTVEC(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
131 IDTVEC(timerint_pti)
132 IDTVEC(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
148 IDTVEC(cmcint_pti)
149 IDTVEC(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
163 IDTVEC(errorint_pti)
164 IDTVEC(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
180 IDTVEC(xen_intr_upcall)
181 PUSH_FRAME
182 SET_KERNEL_SREGS
183 cld
184 KENTER
185 pushl %esp
186 movl $xen_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
198 invltlb_ret:
199 call as_lapic_eoi
200 jmp doreti
201
202 SUPERALIGN_TEXT
203 IDTVEC(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
217 IDTVEC(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
231 IDTVEC(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
245 IDTVEC(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
259 IDTVEC(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
274 IDTVEC(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
289 IDTVEC(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
304 IDTVEC(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
321 IDTVEC(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 */
Cache object: 0999aacb770efc91c4e36a134a9611d0
|