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 ; \
54 IDTVEC(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 ; \
62 1: ; \
63 movq %rsp, %rsi ; \
64 movl %eax, %edi ; /* pass the IRQ */ \
65 call lapic_handle_intr ; \
66 MEXITCOUNT ; \
67 jmp doreti ; \
68 2: 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
80 IDTVEC(spuriousint)
81
82 /* No EOI cycle used here */
83
84 iretq
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
99 IDTVEC(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 #ifdef SMP
108 /*
109 * Global address space TLB shootdown.
110 */
111 .text
112 SUPERALIGN_TEXT
113 IDTVEC(invltlb)
114 pushq %rax
115
116 movq %cr3, %rax /* invalidate the TLB */
117 movq %rax, %cr3
118
119 movq lapic, %rax
120 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */
121
122 lock
123 incl smp_tlb_wait
124
125 popq %rax
126 iretq
127
128 /*
129 * Single page TLB shootdown
130 */
131 .text
132 SUPERALIGN_TEXT
133 IDTVEC(invlpg)
134 pushq %rax
135
136 movq smp_tlb_addr1, %rax
137 invlpg (%rax) /* invalidate single page */
138
139 movq lapic, %rax
140 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */
141
142 lock
143 incl smp_tlb_wait
144
145 popq %rax
146 iretq
147
148 /*
149 * Page range TLB shootdown.
150 */
151 .text
152 SUPERALIGN_TEXT
153 IDTVEC(invlrng)
154 pushq %rax
155 pushq %rdx
156
157 movq smp_tlb_addr1, %rdx
158 movq smp_tlb_addr2, %rax
159 1: invlpg (%rdx) /* invalidate single page */
160 addq $PAGE_SIZE, %rdx
161 cmpq %rax, %rdx
162 jb 1b
163
164 movq lapic, %rax
165 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */
166
167 lock
168 incl smp_tlb_wait
169
170 popq %rdx
171 popq %rax
172 iretq
173
174 /*
175 * Invalidate cache.
176 */
177 .text
178 SUPERALIGN_TEXT
179 IDTVEC(invlcache)
180 pushq %rax
181
182 wbinvd
183
184 movq lapic, %rax
185 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */
186
187 lock
188 incl smp_tlb_wait
189
190 popq %rax
191 iretq
192
193 /*
194 * Handler for IPIs sent via the per-cpu IPI bitmap.
195 */
196 .text
197 SUPERALIGN_TEXT
198 IDTVEC(ipi_intr_bitmap_handler)
199 PUSH_FRAME
200
201 movq lapic, %rdx
202 movl $0, LA_EOI(%rdx) /* End Of Interrupt to APIC */
203
204 FAKE_MCOUNT(TF_RIP(%rsp))
205
206 call ipi_bitmap_handler
207 MEXITCOUNT
208 jmp doreti
209
210 /*
211 * Executed by a CPU when it receives an IPI_STOP from another CPU.
212 */
213 .text
214 SUPERALIGN_TEXT
215 IDTVEC(cpustop)
216 PUSH_FRAME
217
218 movq lapic, %rax
219 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */
220
221 call cpustop_handler
222
223 POP_FRAME
224 iretq
225
226 /*
227 * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU.
228 *
229 * - Calls the generic rendezvous action function.
230 */
231 .text
232 SUPERALIGN_TEXT
233 IDTVEC(rendezvous)
234 PUSH_FRAME
235 call smp_rendezvous_action
236 movq lapic, %rax
237 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */
238 POP_FRAME /* Why not doreti? */
239 iretq
240 #endif /* SMP */
Cache object: 7b15f0bb43b23349247d6686a4a7e2e4
|