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 * 3. 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 "opt_smp.h" 40 41#include <machine/asmacros.h> 42#include <machine/psl.h> 43#include <machine/specialreg.h> 44#include <x86/apicreg.h> 45 46#include "assym.inc" 47 48 .text 49 SUPERALIGN_TEXT 50 /* End Of Interrupt to APIC */ 51as_lapic_eoi: 52 cmpl $0,x2apic_mode 53 jne 1f 54 movl lapic_map,%eax 55 movl $0,LA_EOI(%eax) 56 ret 571: 58 movl $MSR_APIC_EOI,%ecx 59 xorl %eax,%eax 60 xorl %edx,%edx 61 wrmsr 62 ret 63 64/* 65 * I/O Interrupt Entry Point. Rather than having one entry point for 66 * each interrupt source, we use one entry point for each 32-bit word 67 * in the ISR. The handler determines the highest bit set in the ISR, 68 * translates that into a vector, and passes the vector to the 69 * lapic_handle_intr() function. 70 */ 71 .macro ISR_VEC index, vec_name 72 .text 73 SUPERALIGN_TEXT 74 .globl X\()\vec_name\()_pti, X\()\vec_name 75 76X\()\vec_name\()_pti: 77X\()\vec_name: 78 PUSH_FRAME 79 SET_KERNEL_SREGS 80 cld 81 KENTER 82 FAKE_MCOUNT(TF_EIP(%esp)) 83 cmpl $0,x2apic_mode 84 je 2f 85 movl $(MSR_APIC_ISR0 + \index),%ecx 86 rdmsr 87 jmp 3f 882: 89 movl lapic_map, %edx /* pointer to local APIC */ 90 movl LA_ISR + 16 * \index(%edx), %eax /* load ISR */ 913: 92 bsrl %eax, %eax /* index of highest set bit in ISR */ 93 jz 4f 94 addl $(32 * \index),%eax 95 pushl %esp 96 pushl %eax /* pass the IRQ */ 97 movl $lapic_handle_intr, %eax 98 call *%eax 99 addl $8, %esp /* discard parameter */ 1004: 101 MEXITCOUNT 102 jmp doreti 103 .endm 104 105/* 106 * Handle "spurious INTerrupts". 107 * Notes: 108 * This is different than the "spurious INTerrupt" generated by an 109 * 8259 PIC for missing INTs. See the APIC documentation for details. 110 * This routine should NOT do an 'EOI' cycle. 111 */ 112 .text 113 SUPERALIGN_TEXT 114IDTVEC(spuriousint) 115 116 /* No EOI cycle used here */ 117 118 iret 119 120 ISR_VEC 1, apic_isr1 121 ISR_VEC 2, apic_isr2 122 ISR_VEC 3, apic_isr3 123 ISR_VEC 4, apic_isr4 124 ISR_VEC 5, apic_isr5 125 ISR_VEC 6, apic_isr6 126 ISR_VEC 7, apic_isr7 127 128/* 129 * Local APIC periodic timer handler. 130 */ 131 .text 132 SUPERALIGN_TEXT 133IDTVEC(timerint_pti) 134IDTVEC(timerint) 135 PUSH_FRAME 136 SET_KERNEL_SREGS 137 cld 138 KENTER 139 FAKE_MCOUNT(TF_EIP(%esp)) 140 pushl %esp 141 movl $lapic_handle_timer, %eax 142 call *%eax 143 add $4, %esp 144 MEXITCOUNT 145 jmp doreti 146 147/* 148 * Local APIC CMCI handler. 149 */ 150 .text 151 SUPERALIGN_TEXT 152IDTVEC(cmcint_pti) 153IDTVEC(cmcint) 154 PUSH_FRAME 155 SET_KERNEL_SREGS 156 cld 157 KENTER 158 FAKE_MCOUNT(TF_EIP(%esp)) 159 movl $lapic_handle_cmc, %eax 160 call *%eax 161 MEXITCOUNT 162 jmp doreti 163 164/* 165 * Local APIC error interrupt handler. 166 */ 167 .text 168 SUPERALIGN_TEXT 169IDTVEC(errorint_pti) 170IDTVEC(errorint) 171 PUSH_FRAME 172 SET_KERNEL_SREGS 173 cld 174 KENTER 175 FAKE_MCOUNT(TF_EIP(%esp)) 176 movl $lapic_handle_error, %eax 177 call *%eax 178 MEXITCOUNT 179 jmp doreti 180 181#ifdef XENHVM 182/* 183 * Xen event channel upcall interrupt handler. 184 * Only used when the hypervisor supports direct vector callbacks. 185 */ 186 .text 187 SUPERALIGN_TEXT 188IDTVEC(xen_intr_upcall) 189 PUSH_FRAME 190 SET_KERNEL_SREGS 191 cld 192 KENTER 193 FAKE_MCOUNT(TF_EIP(%esp)) 194 pushl %esp 195 movl $xen_intr_handle_upcall, %eax 196 call *%eax 197 add $4, %esp 198 MEXITCOUNT 199 jmp doreti 200#endif 201 202#ifdef SMP 203/* 204 * Global address space TLB shootdown. 205 */ 206 .text 207 SUPERALIGN_TEXT 208invltlb_ret: 209 call as_lapic_eoi 210 jmp doreti 211 212 SUPERALIGN_TEXT 213IDTVEC(invltlb) 214 PUSH_FRAME 215 SET_KERNEL_SREGS 216 cld 217 KENTER 218 movl $invltlb_handler, %eax 219 call *%eax 220 jmp invltlb_ret 221 222/* 223 * Single page TLB shootdown 224 */ 225 .text 226 SUPERALIGN_TEXT 227IDTVEC(invlpg) 228 PUSH_FRAME 229 SET_KERNEL_SREGS 230 cld 231 KENTER 232 movl $invlpg_handler, %eax 233 call *%eax 234 jmp invltlb_ret 235 236/* 237 * Page range TLB shootdown. 238 */ 239 .text 240 SUPERALIGN_TEXT 241IDTVEC(invlrng) 242 PUSH_FRAME 243 SET_KERNEL_SREGS 244 cld 245 KENTER 246 movl $invlrng_handler, %eax 247 call *%eax 248 jmp invltlb_ret 249 250/* 251 * Invalidate cache. 252 */ 253 .text 254 SUPERALIGN_TEXT 255IDTVEC(invlcache) 256 PUSH_FRAME 257 SET_KERNEL_SREGS 258 cld 259 KENTER 260 movl $invlcache_handler, %eax 261 call *%eax 262 jmp invltlb_ret 263 264/* 265 * Handler for IPIs sent via the per-cpu IPI bitmap. 266 */ 267 .text 268 SUPERALIGN_TEXT 269IDTVEC(ipi_intr_bitmap_handler) 270 PUSH_FRAME 271 SET_KERNEL_SREGS 272 cld 273 KENTER 274 call as_lapic_eoi 275 FAKE_MCOUNT(TF_EIP(%esp)) 276 movl $ipi_bitmap_handler, %eax 277 call *%eax 278 MEXITCOUNT 279 jmp doreti 280 281/* 282 * Executed by a CPU when it receives an IPI_STOP from another CPU. 283 */ 284 .text 285 SUPERALIGN_TEXT 286IDTVEC(cpustop) 287 PUSH_FRAME 288 SET_KERNEL_SREGS 289 cld 290 KENTER 291 call as_lapic_eoi 292 movl $cpustop_handler, %eax 293 call *%eax 294 jmp doreti 295 296/* 297 * Executed by a CPU when it receives an IPI_SUSPEND from another CPU. 298 */ 299 .text 300 SUPERALIGN_TEXT 301IDTVEC(cpususpend) 302 PUSH_FRAME 303 SET_KERNEL_SREGS 304 cld 305 KENTER 306 call as_lapic_eoi 307 movl $cpususpend_handler, %eax 308 call *%eax 309 jmp doreti 310 311/* 312 * Executed by a CPU when it receives an IPI_SWI. 313 */ 314 .text 315 SUPERALIGN_TEXT 316IDTVEC(ipi_swi) 317 PUSH_FRAME 318 SET_KERNEL_SREGS 319 cld 320 KENTER 321 call as_lapic_eoi 322 FAKE_MCOUNT(TF_EIP(%esp)) 323 movl $ipi_swi_handler, %eax 324 call *%eax 325 MEXITCOUNT 326 jmp doreti 327 328/* 329 * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU. 330 * 331 * - Calls the generic rendezvous action function. 332 */ 333 .text 334 SUPERALIGN_TEXT 335IDTVEC(rendezvous) 336 PUSH_FRAME 337 SET_KERNEL_SREGS 338 cld 339 KENTER 340#ifdef COUNT_IPIS 341 movl PCPU(CPUID), %eax 342 movl ipi_rendezvous_counts(,%eax,4), %eax 343 incl (%eax) 344#endif 345 movl $smp_rendezvous_action, %eax 346 call *%eax 347 call as_lapic_eoi 348 jmp doreti 349 350#endif /* SMP */ 351