apic_vector.s revision 298022
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 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 */ 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 SMP 185/* 186 * Global address space TLB shootdown. 187 */ 188 .text 189 SUPERALIGN_TEXT 190invltlb_ret: 191 call as_lapic_eoi 192 POP_FRAME 193 iret 194 195 SUPERALIGN_TEXT 196IDTVEC(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 210IDTVEC(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 224IDTVEC(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 238IDTVEC(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 252IDTVEC(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 270IDTVEC(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 286IDTVEC(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 304IDTVEC(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 */ 321