apic_vector.S revision 264118
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: stable/10/sys/amd64/amd64/apic_vector.S 264118 2014-04-04 14:54:54Z royger $ 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 <x86/apicreg.h> 43 44#include "assym.s" 45 46#ifdef SMP 47#define LK lock ; 48#else 49#define LK 50#endif 51 52/* 53 * I/O Interrupt Entry Point. Rather than having one entry point for 54 * each interrupt source, we use one entry point for each 32-bit word 55 * in the ISR. The handler determines the highest bit set in the ISR, 56 * translates that into a vector, and passes the vector to the 57 * lapic_handle_intr() function. 58 */ 59#define ISR_VEC(index, vec_name) \ 60 .text ; \ 61 SUPERALIGN_TEXT ; \ 62IDTVEC(vec_name) ; \ 63 PUSH_FRAME ; \ 64 FAKE_MCOUNT(TF_RIP(%rsp)) ; \ 65 movq lapic, %rdx ; /* pointer to local APIC */ \ 66 movl LA_ISR + 16 * (index)(%rdx), %eax ; /* load ISR */ \ 67 bsrl %eax, %eax ; /* index of highest set bit in ISR */ \ 68 jz 1f ; \ 69 addl $(32 * index),%eax ; \ 70 movq %rsp, %rsi ; \ 71 movl %eax, %edi ; /* pass the IRQ */ \ 72 call lapic_handle_intr ; \ 731: ; \ 74 MEXITCOUNT ; \ 75 jmp doreti 76 77/* 78 * Handle "spurious INTerrupts". 79 * Notes: 80 * This is different than the "spurious INTerrupt" generated by an 81 * 8259 PIC for missing INTs. See the APIC documentation for details. 82 * This routine should NOT do an 'EOI' cycle. 83 */ 84 .text 85 SUPERALIGN_TEXT 86IDTVEC(spuriousint) 87 88 /* No EOI cycle used here */ 89 90 jmp doreti_iret 91 92 ISR_VEC(1, apic_isr1) 93 ISR_VEC(2, apic_isr2) 94 ISR_VEC(3, apic_isr3) 95 ISR_VEC(4, apic_isr4) 96 ISR_VEC(5, apic_isr5) 97 ISR_VEC(6, apic_isr6) 98 ISR_VEC(7, apic_isr7) 99 100/* 101 * Local APIC periodic timer handler. 102 */ 103 .text 104 SUPERALIGN_TEXT 105IDTVEC(timerint) 106 PUSH_FRAME 107 FAKE_MCOUNT(TF_RIP(%rsp)) 108 movq %rsp, %rdi 109 call lapic_handle_timer 110 MEXITCOUNT 111 jmp doreti 112 113/* 114 * Local APIC CMCI handler. 115 */ 116 .text 117 SUPERALIGN_TEXT 118IDTVEC(cmcint) 119 PUSH_FRAME 120 FAKE_MCOUNT(TF_RIP(%rsp)) 121 call lapic_handle_cmc 122 MEXITCOUNT 123 jmp doreti 124 125/* 126 * Local APIC error interrupt handler. 127 */ 128 .text 129 SUPERALIGN_TEXT 130IDTVEC(errorint) 131 PUSH_FRAME 132 FAKE_MCOUNT(TF_RIP(%rsp)) 133 call lapic_handle_error 134 MEXITCOUNT 135 jmp doreti 136 137#ifdef XENHVM 138/* 139 * Xen event channel upcall interrupt handler. 140 * Only used when the hypervisor supports direct vector callbacks. 141 */ 142 .text 143 SUPERALIGN_TEXT 144IDTVEC(xen_intr_upcall) 145 PUSH_FRAME 146 FAKE_MCOUNT(TF_RIP(%rsp)) 147 movq %rsp, %rdi 148 call xen_intr_handle_upcall 149 MEXITCOUNT 150 jmp doreti 151#endif 152 153#ifdef SMP 154/* 155 * Global address space TLB shootdown. 156 */ 157 .text 158 159#define NAKE_INTR_CS 24 160 161 SUPERALIGN_TEXT 162invltlb_ret: 163 movq lapic, %rax 164 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ 165 POP_FRAME 166 jmp doreti_iret 167 168 SUPERALIGN_TEXT 169IDTVEC(invltlb_pcid) 170 PUSH_FRAME 171 172 call invltlb_pcid_handler 173 jmp invltlb_ret 174 175 176 SUPERALIGN_TEXT 177IDTVEC(invltlb) 178 PUSH_FRAME 179 180 call invltlb_handler 181 jmp invltlb_ret 182 183/* 184 * Single page TLB shootdown 185 */ 186 .text 187 SUPERALIGN_TEXT 188IDTVEC(invlpg_pcid) 189 PUSH_FRAME 190 191 call invlpg_pcid_handler 192 jmp invltlb_ret 193 194 SUPERALIGN_TEXT 195IDTVEC(invlpg) 196 PUSH_FRAME 197 198 call invlpg_handler 199 jmp invltlb_ret 200 201/* 202 * Page range TLB shootdown. 203 */ 204 .text 205 SUPERALIGN_TEXT 206IDTVEC(invlrng) 207 PUSH_FRAME 208 209 call invlrng_handler 210 jmp invltlb_ret 211 212/* 213 * Invalidate cache. 214 */ 215 .text 216 SUPERALIGN_TEXT 217IDTVEC(invlcache) 218 PUSH_FRAME 219 220 call invlcache_handler 221 jmp invltlb_ret 222 223/* 224 * Handler for IPIs sent via the per-cpu IPI bitmap. 225 */ 226 .text 227 SUPERALIGN_TEXT 228IDTVEC(ipi_intr_bitmap_handler) 229 PUSH_FRAME 230 231 movq lapic, %rdx 232 movl $0, LA_EOI(%rdx) /* End Of Interrupt to APIC */ 233 234 FAKE_MCOUNT(TF_RIP(%rsp)) 235 236 call ipi_bitmap_handler 237 MEXITCOUNT 238 jmp doreti 239 240/* 241 * Executed by a CPU when it receives an IPI_STOP from another CPU. 242 */ 243 .text 244 SUPERALIGN_TEXT 245IDTVEC(cpustop) 246 PUSH_FRAME 247 248 movq lapic, %rax 249 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ 250 251 call cpustop_handler 252 jmp doreti 253 254/* 255 * Executed by a CPU when it receives an IPI_SUSPEND from another CPU. 256 */ 257 .text 258 SUPERALIGN_TEXT 259IDTVEC(cpususpend) 260 PUSH_FRAME 261 262 call cpususpend_handler 263 movq lapic, %rax 264 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ 265 jmp doreti 266 267/* 268 * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU. 269 * 270 * - Calls the generic rendezvous action function. 271 */ 272 .text 273 SUPERALIGN_TEXT 274IDTVEC(rendezvous) 275 PUSH_FRAME 276#ifdef COUNT_IPIS 277 movl PCPU(CPUID), %eax 278 movq ipi_rendezvous_counts(,%rax,8), %rax 279 incq (%rax) 280#endif 281 call smp_rendezvous_action 282 movq lapic, %rax 283 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ 284 jmp doreti 285#endif /* SMP */ 286