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