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/8.1/sys/i386/i386/apic_vector.s 206598 2010-04-14 15:00:46Z jhb $
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/apicreg.h>
43
44 #include "assym.s"
45
46 /*
47 * I/O Interrupt Entry Point. Rather than having one entry point for
48 * each interrupt source, we use one entry point for each 32-bit word
49 * in the ISR. The handler determines the highest bit set in the ISR,
50 * translates that into a vector, and passes the vector to the
51 * lapic_handle_intr() function.
52 */
53 #define ISR_VEC(index, vec_name) \
54 .text ; \
55 SUPERALIGN_TEXT ; \
56 IDTVEC(vec_name) ; \
57 PUSH_FRAME ; \
58 SET_KERNEL_SREGS ; \
59 FAKE_MCOUNT(TF_EIP(%esp)) ; \
60 movl lapic, %edx ; /* pointer to local APIC */ \
61 movl LA_ISR + 16 * (index)(%edx), %eax ; /* load ISR */ \
62 bsrl %eax, %eax ; /* index of highset set bit in ISR */ \
63 jz 2f ; \
64 addl $(32 * index),%eax ; \
65 1: ; \
66 pushl %esp ; \
67 pushl %eax ; /* pass the IRQ */ \
68 call lapic_handle_intr ; \
69 addl $8, %esp ; /* discard parameter */ \
70 MEXITCOUNT ; \
71 jmp doreti ; \
72 2: movl $-1, %eax ; /* send a vector of -1 */ \
73 jmp 1b
74
75 /*
76 * Handle "spurious INTerrupts".
77 * Notes:
78 * This is different than the "spurious INTerrupt" generated by an
79 * 8259 PIC for missing INTs. See the APIC documentation for details.
80 * This routine should NOT do an 'EOI' cycle.
81 */
82 .text
83 SUPERALIGN_TEXT
84 IDTVEC(spuriousint)
85
86 /* No EOI cycle used here */
87
88 iret
89
90 ISR_VEC(1, apic_isr1)
91 ISR_VEC(2, apic_isr2)
92 ISR_VEC(3, apic_isr3)
93 ISR_VEC(4, apic_isr4)
94 ISR_VEC(5, apic_isr5)
95 ISR_VEC(6, apic_isr6)
96 ISR_VEC(7, apic_isr7)
97
98 /*
99 * Local APIC periodic timer handler.
100 */
101 .text
102 SUPERALIGN_TEXT
103 IDTVEC(timerint)
104 PUSH_FRAME
105 SET_KERNEL_SREGS
106 FAKE_MCOUNT(TF_EIP(%esp))
107 pushl %esp
108 call lapic_handle_timer
109 add $4, %esp
110 MEXITCOUNT
111 jmp doreti
112
113 /*
114 * Local APIC error interrupt handler.
115 */
116 .text
117 SUPERALIGN_TEXT
118 IDTVEC(errorint)
119 PUSH_FRAME
120 SET_KERNEL_SREGS
121 FAKE_MCOUNT(TF_EIP(%esp))
122 call lapic_handle_error
123 MEXITCOUNT
124 jmp doreti
125
126 #ifdef SMP
127 /*
128 * Global address space TLB shootdown.
129 */
130 .text
131 SUPERALIGN_TEXT
132 IDTVEC(invltlb)
133 pushl %eax
134 pushl %ds
135 movl $KDSEL, %eax /* Kernel data selector */
136 movl %eax, %ds
137
138 #if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS)
139 pushl %fs
140 movl $KPSEL, %eax /* Private space selector */
141 movl %eax, %fs
142 movl PCPU(CPUID), %eax
143 popl %fs
144 #ifdef COUNT_XINVLTLB_HITS
145 incl xhits_gbl(,%eax,4)
146 #endif
147 #ifdef COUNT_IPIS
148 movl ipi_invltlb_counts(,%eax,4),%eax
149 incl (%eax)
150 #endif
151 #endif
152
153 movl %cr3, %eax /* invalidate the TLB */
154 movl %eax, %cr3
155
156 movl lapic, %eax
157 movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */
158
159 lock
160 incl smp_tlb_wait
161
162 popl %ds
163 popl %eax
164 iret
165
166 /*
167 * Single page TLB shootdown
168 */
169 .text
170 SUPERALIGN_TEXT
171 IDTVEC(invlpg)
172 pushl %eax
173 pushl %ds
174 movl $KDSEL, %eax /* Kernel data selector */
175 movl %eax, %ds
176
177 #if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS)
178 pushl %fs
179 movl $KPSEL, %eax /* Private space selector */
180 movl %eax, %fs
181 movl PCPU(CPUID), %eax
182 popl %fs
183 #ifdef COUNT_XINVLTLB_HITS
184 incl xhits_pg(,%eax,4)
185 #endif
186 #ifdef COUNT_IPIS
187 movl ipi_invlpg_counts(,%eax,4),%eax
188 incl (%eax)
189 #endif
190 #endif
191
192 movl smp_tlb_addr1, %eax
193 invlpg (%eax) /* invalidate single page */
194
195 movl lapic, %eax
196 movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */
197
198 lock
199 incl smp_tlb_wait
200
201 popl %ds
202 popl %eax
203 iret
204
205 /*
206 * Page range TLB shootdown.
207 */
208 .text
209 SUPERALIGN_TEXT
210 IDTVEC(invlrng)
211 pushl %eax
212 pushl %edx
213 pushl %ds
214 movl $KDSEL, %eax /* Kernel data selector */
215 movl %eax, %ds
216
217 #if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS)
218 pushl %fs
219 movl $KPSEL, %eax /* Private space selector */
220 movl %eax, %fs
221 movl PCPU(CPUID), %eax
222 popl %fs
223 #ifdef COUNT_XINVLTLB_HITS
224 incl xhits_rng(,%eax,4)
225 #endif
226 #ifdef COUNT_IPIS
227 movl ipi_invlrng_counts(,%eax,4),%eax
228 incl (%eax)
229 #endif
230 #endif
231
232 movl smp_tlb_addr1, %edx
233 movl smp_tlb_addr2, %eax
234 1: invlpg (%edx) /* invalidate single page */
235 addl $PAGE_SIZE, %edx
236 cmpl %eax, %edx
237 jb 1b
238
239 movl lapic, %eax
240 movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */
241
242 lock
243 incl smp_tlb_wait
244
245 popl %ds
246 popl %edx
247 popl %eax
248 iret
249
250 /*
251 * Invalidate cache.
252 */
253 .text
254 SUPERALIGN_TEXT
255 IDTVEC(invlcache)
256 pushl %eax
257 pushl %ds
258 movl $KDSEL, %eax /* Kernel data selector */
259 movl %eax, %ds
260
261 #ifdef COUNT_IPIS
262 pushl %fs
263 movl $KPSEL, %eax /* Private space selector */
264 movl %eax, %fs
265 movl PCPU(CPUID), %eax
266 popl %fs
267 movl ipi_invlcache_counts(,%eax,4),%eax
268 incl (%eax)
269 #endif
270
271 wbinvd
272
273 movl lapic, %eax
274 movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */
275
276 lock
277 incl smp_tlb_wait
278
279 popl %ds
280 popl %eax
281 iret
282
283 /*
284 * Handler for IPIs sent via the per-cpu IPI bitmap.
285 */
286 #ifndef XEN
287 .text
288 SUPERALIGN_TEXT
289 IDTVEC(ipi_intr_bitmap_handler)
290 PUSH_FRAME
291 SET_KERNEL_SREGS
292
293 movl lapic, %edx
294 movl $0, LA_EOI(%edx) /* End Of Interrupt to APIC */
295
296 FAKE_MCOUNT(TF_EIP(%esp))
297
298 call ipi_bitmap_handler
299 MEXITCOUNT
300 jmp doreti
301 #endif
302 /*
303 * Executed by a CPU when it receives an IPI_STOP from another CPU.
304 */
305 .text
306 SUPERALIGN_TEXT
307 IDTVEC(cpustop)
308 PUSH_FRAME
309 SET_KERNEL_SREGS
310
311 movl lapic, %eax
312 movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */
313
314 call cpustop_handler
315
316 POP_FRAME
317 iret
318
319 /*
320 * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU.
321 *
322 * - Calls the generic rendezvous action function.
323 */
324 .text
325 SUPERALIGN_TEXT
326 IDTVEC(rendezvous)
327 PUSH_FRAME
328 SET_KERNEL_SREGS
329
330 #ifdef COUNT_IPIS
331 movl PCPU(CPUID), %eax
332 movl ipi_rendezvous_counts(,%eax,4), %eax
333 incl (%eax)
334 #endif
335 call smp_rendezvous_action
336
337 movl lapic, %eax
338 movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */
339 POP_FRAME
340 iret
341
342 /*
343 * Clean up when we lose out on the lazy context switch optimization.
344 * ie: when we are about to release a PTD but a cpu is still borrowing it.
345 */
346 SUPERALIGN_TEXT
347 IDTVEC(lazypmap)
348 PUSH_FRAME
349 SET_KERNEL_SREGS
350
351 call pmap_lazyfix_action
352
353 movl lapic, %eax
354 movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */
355 POP_FRAME
356 iret
357 #endif /* SMP */
Cache object: a61a8cc13df73d4bbe5cad539f190645
|