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