apic_vector.s revision 153426
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: head/sys/i386/i386/apic_vector.s 153426 2005-12-14 21:47:02Z jhb $ 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/apicreg.h> 43 44#include "assym.s" 45 46/* 47 * I/O Interrupt Entry Point. Rather than having one entry point for 48 * each interrupt source, we use one entry point for each 32-bit word 49 * in the ISR. The handler determines the highest bit set in the ISR, 50 * translates that into a vector, and passes the vector to the 51 * lapic_handle_intr() function. 52 */ 53#define ISR_VEC(index, vec_name) \ 54 .text ; \ 55 SUPERALIGN_TEXT ; \ 56IDTVEC(vec_name) ; \ 57 PUSH_FRAME ; \ 58 SET_KERNEL_SREGS ; \ 59 FAKE_MCOUNT(TF_EIP(%esp)) ; \ 60 movl lapic, %edx ; /* pointer to local APIC */ \ 61 movl LA_ISR + 16 * (index)(%edx), %eax ; /* load ISR */ \ 62 bsrl %eax, %eax ; /* index of highset set bit in ISR */ \ 63 jz 2f ; \ 64 addl $(32 * index),%eax ; \ 651: ; \ 66 pushl %eax ; /* pass the IRQ */ \ 67 call lapic_handle_intr ; \ 68 addl $4, %esp ; /* discard parameter */ \ 69 MEXITCOUNT ; \ 70 jmp doreti ; \ 712: movl $-1, %eax ; /* send a vector of -1 */ \ 72 jmp 1b 73 74/* 75 * Handle "spurious INTerrupts". 76 * Notes: 77 * This is different than the "spurious INTerrupt" generated by an 78 * 8259 PIC for missing INTs. See the APIC documentation for details. 79 * This routine should NOT do an 'EOI' cycle. 80 */ 81 .text 82 SUPERALIGN_TEXT 83IDTVEC(spuriousint) 84 85 /* No EOI cycle used here */ 86 87 iret 88 89 ISR_VEC(1, apic_isr1) 90 ISR_VEC(2, apic_isr2) 91 ISR_VEC(3, apic_isr3) 92 ISR_VEC(4, apic_isr4) 93 ISR_VEC(5, apic_isr5) 94 ISR_VEC(6, apic_isr6) 95 ISR_VEC(7, apic_isr7) 96 97/* 98 * Local APIC periodic timer handler. 99 */ 100 .text 101 SUPERALIGN_TEXT 102IDTVEC(timerint) 103 PUSH_FRAME 104 SET_KERNEL_SREGS 105 FAKE_MCOUNT(TF_EIP(%esp)) 106 107 call lapic_handle_timer 108 MEXITCOUNT 109 jmp doreti 110 111#ifdef SMP 112/* 113 * Global address space TLB shootdown. 114 */ 115 .text 116 SUPERALIGN_TEXT 117IDTVEC(invltlb) 118 pushl %eax 119 pushl %ds 120 movl $KDSEL, %eax /* Kernel data selector */ 121 movl %eax, %ds 122 123#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) 124 pushl %fs 125 movl $KPSEL, %eax /* Private space selector */ 126 movl %eax, %fs 127 movl PCPU(CPUID), %eax 128 popl %fs 129#ifdef COUNT_XINVLTLB_HITS 130 incl xhits_gbl(,%eax,4) 131#endif 132#ifdef COUNT_IPIS 133 movl ipi_invltlb_counts(,%eax,4),%eax 134 incl (%eax) 135#endif 136#endif 137 138 movl %cr3, %eax /* invalidate the TLB */ 139 movl %eax, %cr3 140 141 movl lapic, %eax 142 movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ 143 144 lock 145 incl smp_tlb_wait 146 147 popl %ds 148 popl %eax 149 iret 150 151/* 152 * Single page TLB shootdown 153 */ 154 .text 155 SUPERALIGN_TEXT 156IDTVEC(invlpg) 157 pushl %eax 158 pushl %ds 159 movl $KDSEL, %eax /* Kernel data selector */ 160 movl %eax, %ds 161 162#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) 163 pushl %fs 164 movl $KPSEL, %eax /* Private space selector */ 165 movl %eax, %fs 166 movl PCPU(CPUID), %eax 167 popl %fs 168#ifdef COUNT_XINVLTLB_HITS 169 incl xhits_pg(,%eax,4) 170#endif 171#ifdef COUNT_IPIS 172 movl ipi_invlpg_counts(,%eax,4),%eax 173 incl (%eax) 174#endif 175#endif 176 177 movl smp_tlb_addr1, %eax 178 invlpg (%eax) /* invalidate single page */ 179 180 movl lapic, %eax 181 movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ 182 183 lock 184 incl smp_tlb_wait 185 186 popl %ds 187 popl %eax 188 iret 189 190/* 191 * Page range TLB shootdown. 192 */ 193 .text 194 SUPERALIGN_TEXT 195IDTVEC(invlrng) 196 pushl %eax 197 pushl %edx 198 pushl %ds 199 movl $KDSEL, %eax /* Kernel data selector */ 200 movl %eax, %ds 201 202#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) 203 pushl %fs 204 movl $KPSEL, %eax /* Private space selector */ 205 movl %eax, %fs 206 movl PCPU(CPUID), %eax 207 popl %fs 208#ifdef COUNT_XINVLTLB_HITS 209 incl xhits_rng(,%eax,4) 210#endif 211#ifdef COUNT_IPIS 212 movl ipi_invlrng_counts(,%eax,4),%eax 213 incl (%eax) 214#endif 215#endif 216 217 movl smp_tlb_addr1, %edx 218 movl smp_tlb_addr2, %eax 2191: invlpg (%edx) /* invalidate single page */ 220 addl $PAGE_SIZE, %edx 221 cmpl %eax, %edx 222 jb 1b 223 224 movl lapic, %eax 225 movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ 226 227 lock 228 incl smp_tlb_wait 229 230 popl %ds 231 popl %edx 232 popl %eax 233 iret 234 235/* 236 * Handler for IPIs sent via the per-cpu IPI bitmap. 237 */ 238 .text 239 SUPERALIGN_TEXT 240IDTVEC(ipi_intr_bitmap_handler) 241 PUSH_FRAME 242 SET_KERNEL_SREGS 243 244 movl lapic, %edx 245 movl $0, LA_EOI(%edx) /* End Of Interrupt to APIC */ 246 247 FAKE_MCOUNT(TF_EIP(%esp)) 248 249 call ipi_bitmap_handler 250 MEXITCOUNT 251 jmp doreti 252 253/* 254 * Executed by a CPU when it receives an IPI_STOP from another CPU. 255 */ 256 .text 257 SUPERALIGN_TEXT 258IDTVEC(cpustop) 259 PUSH_FRAME 260 SET_KERNEL_SREGS 261 262 movl lapic, %eax 263 movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ 264 265 call cpustop_handler 266 267 POP_FRAME 268 iret 269 270/* 271 * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU. 272 * 273 * - Calls the generic rendezvous action function. 274 */ 275 .text 276 SUPERALIGN_TEXT 277IDTVEC(rendezvous) 278 PUSH_FRAME 279 SET_KERNEL_SREGS 280 281#ifdef COUNT_IPIS 282 movl PCPU(CPUID), %eax 283 movl ipi_rendezvous_counts(,%eax,4), %eax 284 incl (%eax) 285#endif 286 call smp_rendezvous_action 287 288 movl lapic, %eax 289 movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ 290 POP_FRAME 291 iret 292 293/* 294 * Clean up when we lose out on the lazy context switch optimization. 295 * ie: when we are about to release a PTD but a cpu is still borrowing it. 296 */ 297 SUPERALIGN_TEXT 298IDTVEC(lazypmap) 299 PUSH_FRAME 300 SET_KERNEL_SREGS 301 302 call pmap_lazyfix_action 303 304 movl lapic, %eax 305 movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ 306 POP_FRAME 307 iret 308#endif /* SMP */ 309