apic_vector.s revision 324299
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/11/sys/i386/i386/apic_vector.s 324299 2017-10-05 11:00:04Z kib $ 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 jmp doreti 193 194 SUPERALIGN_TEXT 195IDTVEC(invltlb) 196 PUSH_FRAME 197 SET_KERNEL_SREGS 198 cld 199 200 call invltlb_handler 201 202 jmp invltlb_ret 203 204/* 205 * Single page TLB shootdown 206 */ 207 .text 208 SUPERALIGN_TEXT 209IDTVEC(invlpg) 210 PUSH_FRAME 211 SET_KERNEL_SREGS 212 cld 213 214 call invlpg_handler 215 216 jmp invltlb_ret 217 218/* 219 * Page range TLB shootdown. 220 */ 221 .text 222 SUPERALIGN_TEXT 223IDTVEC(invlrng) 224 PUSH_FRAME 225 SET_KERNEL_SREGS 226 cld 227 228 call invlrng_handler 229 230 jmp invltlb_ret 231 232/* 233 * Invalidate cache. 234 */ 235 .text 236 SUPERALIGN_TEXT 237IDTVEC(invlcache) 238 PUSH_FRAME 239 SET_KERNEL_SREGS 240 cld 241 242 call invlcache_handler 243 244 jmp invltlb_ret 245 246/* 247 * Handler for IPIs sent via the per-cpu IPI bitmap. 248 */ 249 .text 250 SUPERALIGN_TEXT 251IDTVEC(ipi_intr_bitmap_handler) 252 PUSH_FRAME 253 SET_KERNEL_SREGS 254 cld 255 256 call as_lapic_eoi 257 258 FAKE_MCOUNT(TF_EIP(%esp)) 259 260 call ipi_bitmap_handler 261 MEXITCOUNT 262 jmp doreti 263 264/* 265 * Executed by a CPU when it receives an IPI_STOP from another CPU. 266 */ 267 .text 268 SUPERALIGN_TEXT 269IDTVEC(cpustop) 270 PUSH_FRAME 271 SET_KERNEL_SREGS 272 cld 273 274 call as_lapic_eoi 275 call cpustop_handler 276 jmp doreti 277 278/* 279 * Executed by a CPU when it receives an IPI_SUSPEND from another CPU. 280 */ 281 .text 282 SUPERALIGN_TEXT 283IDTVEC(cpususpend) 284 PUSH_FRAME 285 SET_KERNEL_SREGS 286 cld 287 288 call as_lapic_eoi 289 call cpususpend_handler 290 jmp doreti 291 292/* 293 * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU. 294 * 295 * - Calls the generic rendezvous action function. 296 */ 297 .text 298 SUPERALIGN_TEXT 299IDTVEC(rendezvous) 300 PUSH_FRAME 301 SET_KERNEL_SREGS 302 cld 303 304#ifdef COUNT_IPIS 305 movl PCPU(CPUID), %eax 306 movl ipi_rendezvous_counts(,%eax,4), %eax 307 incl (%eax) 308#endif 309 call smp_rendezvous_action 310 311 call as_lapic_eoi 312 jmp doreti 313 314#endif /* SMP */ 315