apic_vector.s revision 282274
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: head/sys/i386/i386/apic_vector.s 282274 2015-04-30 15:48:48Z 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/specialreg.h> 43#include <x86/apicreg.h> 44 45#include "assym.s" 46 47 .text 48 SUPERALIGN_TEXT 49 /* End Of Interrupt to APIC */ 50as_lapic_eoi: 51 cmpl $0,x2apic_mode 52 jne 1f 53 movl lapic_map,%eax 54 movl $0,LA_EOI(%eax) 55 ret 561: 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 ; \ 73IDTVEC(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 ; \ 831: ; \ 84 movl lapic_map, %edx ;/* pointer to local APIC */ \ 85 movl LA_ISR + 16 * (index)(%edx), %eax ; /* load ISR */ \ 862: ; \ 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 */ \ 943: ; \ 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 107IDTVEC(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 126IDTVEC(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 142IDTVEC(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 156IDTVEC(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 172IDTVEC(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 HYPERV 185/* 186 * This is the Hyper-V vmbus channel direct callback interrupt. 187 * Only used when it is running on Hyper-V. 188 */ 189 .text 190 SUPERALIGN_TEXT 191IDTVEC(hv_vmbus_callback) 192 PUSH_FRAME 193 SET_KERNEL_SREGS 194 cld 195 FAKE_MCOUNT(TF_EIP(%esp)) 196 pushl %esp 197 call hv_vector_handler 198 add $4, %esp 199 MEXITCOUNT 200 jmp doreti 201#endif 202 203#ifdef SMP 204/* 205 * Global address space TLB shootdown. 206 */ 207 .text 208 SUPERALIGN_TEXT 209invltlb_ret: 210 call as_lapic_eoi 211 POP_FRAME 212 iret 213 214 SUPERALIGN_TEXT 215IDTVEC(invltlb) 216 PUSH_FRAME 217 SET_KERNEL_SREGS 218 cld 219 220 call invltlb_handler 221 222 jmp invltlb_ret 223 224/* 225 * Single page TLB shootdown 226 */ 227 .text 228 SUPERALIGN_TEXT 229IDTVEC(invlpg) 230 PUSH_FRAME 231 SET_KERNEL_SREGS 232 cld 233 234 call invlpg_handler 235 236 jmp invltlb_ret 237 238/* 239 * Page range TLB shootdown. 240 */ 241 .text 242 SUPERALIGN_TEXT 243IDTVEC(invlrng) 244 PUSH_FRAME 245 SET_KERNEL_SREGS 246 cld 247 248 call invlrng_handler 249 250 jmp invltlb_ret 251 252/* 253 * Invalidate cache. 254 */ 255 .text 256 SUPERALIGN_TEXT 257IDTVEC(invlcache) 258 PUSH_FRAME 259 SET_KERNEL_SREGS 260 cld 261 262 call invlcache_handler 263 264 jmp invltlb_ret 265 266/* 267 * Handler for IPIs sent via the per-cpu IPI bitmap. 268 */ 269 .text 270 SUPERALIGN_TEXT 271IDTVEC(ipi_intr_bitmap_handler) 272 PUSH_FRAME 273 SET_KERNEL_SREGS 274 cld 275 276 call as_lapic_eoi 277 278 FAKE_MCOUNT(TF_EIP(%esp)) 279 280 call ipi_bitmap_handler 281 MEXITCOUNT 282 jmp doreti 283 284/* 285 * Executed by a CPU when it receives an IPI_STOP from another CPU. 286 */ 287 .text 288 SUPERALIGN_TEXT 289IDTVEC(cpustop) 290 PUSH_FRAME 291 SET_KERNEL_SREGS 292 cld 293 294 call as_lapic_eoi 295 call cpustop_handler 296 297 POP_FRAME 298 iret 299 300/* 301 * Executed by a CPU when it receives an IPI_SUSPEND from another CPU. 302 */ 303 .text 304 SUPERALIGN_TEXT 305IDTVEC(cpususpend) 306 PUSH_FRAME 307 SET_KERNEL_SREGS 308 cld 309 310 call as_lapic_eoi 311 call cpususpend_handler 312 313 POP_FRAME 314 jmp doreti_iret 315 316/* 317 * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU. 318 * 319 * - Calls the generic rendezvous action function. 320 */ 321 .text 322 SUPERALIGN_TEXT 323IDTVEC(rendezvous) 324 PUSH_FRAME 325 SET_KERNEL_SREGS 326 cld 327 328#ifdef COUNT_IPIS 329 movl PCPU(CPUID), %eax 330 movl ipi_rendezvous_counts(,%eax,4), %eax 331 incl (%eax) 332#endif 333 call smp_rendezvous_action 334 335 call as_lapic_eoi 336 POP_FRAME 337 iret 338 339#endif /* SMP */ 340