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: releng/11.0/sys/i386/i386/apic_vector.s 298022 2016-04-15 02:20:18Z sephe $
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/specialreg.h>
43 #include <x86/apicreg.h>
44
45 #include "assym.s"
46
47 .text
48 SUPERALIGN_TEXT
49 /* End Of Interrupt to APIC */
50 as_lapic_eoi:
51 cmpl $0,x2apic_mode
52 jne 1f
53 movl lapic_map,%eax
54 movl $0,LA_EOI(%eax)
55 ret
56 1:
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 #define ISR_VEC(index, vec_name) \
71 .text ; \
72 SUPERALIGN_TEXT ; \
73 IDTVEC(vec_name) ; \
74 PUSH_FRAME ; \
75 SET_KERNEL_SREGS ; \
76 cld ; \
77 FAKE_MCOUNT(TF_EIP(%esp)) ; \
78 cmpl $0,x2apic_mode ; \
79 je 1f ; \
80 movl $(MSR_APIC_ISR0 + index),%ecx ; \
81 rdmsr ; \
82 jmp 2f ; \
83 1: ; \
84 movl lapic_map, %edx ;/* pointer to local APIC */ \
85 movl LA_ISR + 16 * (index)(%edx), %eax ; /* load ISR */ \
86 2: ; \
87 bsrl %eax, %eax ; /* index of highest set bit in ISR */ \
88 jz 3f ; \
89 addl $(32 * index),%eax ; \
90 pushl %esp ; \
91 pushl %eax ; /* pass the IRQ */ \
92 call lapic_handle_intr ; \
93 addl $8, %esp ; /* discard parameter */ \
94 3: ; \
95 MEXITCOUNT ; \
96 jmp doreti
97
98 /*
99 * Handle "spurious INTerrupts".
100 * Notes:
101 * This is different than the "spurious INTerrupt" generated by an
102 * 8259 PIC for missing INTs. See the APIC documentation for details.
103 * This routine should NOT do an 'EOI' cycle.
104 */
105 .text
106 SUPERALIGN_TEXT
107 IDTVEC(spuriousint)
108
109 /* No EOI cycle used here */
110
111 iret
112
113 ISR_VEC(1, apic_isr1)
114 ISR_VEC(2, apic_isr2)
115 ISR_VEC(3, apic_isr3)
116 ISR_VEC(4, apic_isr4)
117 ISR_VEC(5, apic_isr5)
118 ISR_VEC(6, apic_isr6)
119 ISR_VEC(7, apic_isr7)
120
121 /*
122 * Local APIC periodic timer handler.
123 */
124 .text
125 SUPERALIGN_TEXT
126 IDTVEC(timerint)
127 PUSH_FRAME
128 SET_KERNEL_SREGS
129 cld
130 FAKE_MCOUNT(TF_EIP(%esp))
131 pushl %esp
132 call lapic_handle_timer
133 add $4, %esp
134 MEXITCOUNT
135 jmp doreti
136
137 /*
138 * Local APIC CMCI handler.
139 */
140 .text
141 SUPERALIGN_TEXT
142 IDTVEC(cmcint)
143 PUSH_FRAME
144 SET_KERNEL_SREGS
145 cld
146 FAKE_MCOUNT(TF_EIP(%esp))
147 call lapic_handle_cmc
148 MEXITCOUNT
149 jmp doreti
150
151 /*
152 * Local APIC error interrupt handler.
153 */
154 .text
155 SUPERALIGN_TEXT
156 IDTVEC(errorint)
157 PUSH_FRAME
158 SET_KERNEL_SREGS
159 cld
160 FAKE_MCOUNT(TF_EIP(%esp))
161 call lapic_handle_error
162 MEXITCOUNT
163 jmp doreti
164
165 #ifdef XENHVM
166 /*
167 * Xen event channel upcall interrupt handler.
168 * Only used when the hypervisor supports direct vector callbacks.
169 */
170 .text
171 SUPERALIGN_TEXT
172 IDTVEC(xen_intr_upcall)
173 PUSH_FRAME
174 SET_KERNEL_SREGS
175 cld
176 FAKE_MCOUNT(TF_EIP(%esp))
177 pushl %esp
178 call xen_intr_handle_upcall
179 add $4, %esp
180 MEXITCOUNT
181 jmp doreti
182 #endif
183
184 #ifdef SMP
185 /*
186 * Global address space TLB shootdown.
187 */
188 .text
189 SUPERALIGN_TEXT
190 invltlb_ret:
191 call as_lapic_eoi
192 POP_FRAME
193 iret
194
195 SUPERALIGN_TEXT
196 IDTVEC(invltlb)
197 PUSH_FRAME
198 SET_KERNEL_SREGS
199 cld
200
201 call invltlb_handler
202
203 jmp invltlb_ret
204
205 /*
206 * Single page TLB shootdown
207 */
208 .text
209 SUPERALIGN_TEXT
210 IDTVEC(invlpg)
211 PUSH_FRAME
212 SET_KERNEL_SREGS
213 cld
214
215 call invlpg_handler
216
217 jmp invltlb_ret
218
219 /*
220 * Page range TLB shootdown.
221 */
222 .text
223 SUPERALIGN_TEXT
224 IDTVEC(invlrng)
225 PUSH_FRAME
226 SET_KERNEL_SREGS
227 cld
228
229 call invlrng_handler
230
231 jmp invltlb_ret
232
233 /*
234 * Invalidate cache.
235 */
236 .text
237 SUPERALIGN_TEXT
238 IDTVEC(invlcache)
239 PUSH_FRAME
240 SET_KERNEL_SREGS
241 cld
242
243 call invlcache_handler
244
245 jmp invltlb_ret
246
247 /*
248 * Handler for IPIs sent via the per-cpu IPI bitmap.
249 */
250 .text
251 SUPERALIGN_TEXT
252 IDTVEC(ipi_intr_bitmap_handler)
253 PUSH_FRAME
254 SET_KERNEL_SREGS
255 cld
256
257 call as_lapic_eoi
258
259 FAKE_MCOUNT(TF_EIP(%esp))
260
261 call ipi_bitmap_handler
262 MEXITCOUNT
263 jmp doreti
264
265 /*
266 * Executed by a CPU when it receives an IPI_STOP from another CPU.
267 */
268 .text
269 SUPERALIGN_TEXT
270 IDTVEC(cpustop)
271 PUSH_FRAME
272 SET_KERNEL_SREGS
273 cld
274
275 call as_lapic_eoi
276 call cpustop_handler
277
278 POP_FRAME
279 iret
280
281 /*
282 * Executed by a CPU when it receives an IPI_SUSPEND from another CPU.
283 */
284 .text
285 SUPERALIGN_TEXT
286 IDTVEC(cpususpend)
287 PUSH_FRAME
288 SET_KERNEL_SREGS
289 cld
290
291 call as_lapic_eoi
292 call cpususpend_handler
293
294 POP_FRAME
295 jmp doreti_iret
296
297 /*
298 * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU.
299 *
300 * - Calls the generic rendezvous action function.
301 */
302 .text
303 SUPERALIGN_TEXT
304 IDTVEC(rendezvous)
305 PUSH_FRAME
306 SET_KERNEL_SREGS
307 cld
308
309 #ifdef COUNT_IPIS
310 movl PCPU(CPUID), %eax
311 movl ipi_rendezvous_counts(,%eax,4), %eax
312 incl (%eax)
313 #endif
314 call smp_rendezvous_action
315
316 call as_lapic_eoi
317 POP_FRAME
318 iret
319
320 #endif /* SMP */
Cache object: f7647a246af4b606310b7fa840fcc7f8
|