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$ 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 <machine/asmacros.h> 40#include <machine/apicreg.h> 41 42#include "assym.s" 43 44/* 45 * I/O Interrupt Entry Point. Rather than having one entry point for 46 * each interrupt source, we use one entry point for each 32-bit word 47 * in the ISR. The handler determines the highest bit set in the ISR, 48 * translates that into a vector, and passes the vector to the 49 * lapic_handle_intr() function. 50 */ 51#define ISR_VEC(index, vec_name) \ 52 .text ; \ 53 SUPERALIGN_TEXT ; \ 54IDTVEC(vec_name) ; \ 55 PUSH_FRAME ; \ 56 FAKE_MCOUNT(TF_RIP(%rsp)) ; \ 57 movq lapic, %rdx ; /* pointer to local APIC */ \ 58 movl LA_ISR + 16 * (index)(%rdx), %eax ; /* load ISR */ \ 59 bsrl %eax, %eax ; /* index of highset set bit in ISR */ \ 60 jz 2f ; \ 61 addl $(32 * index),%eax ; \ 621: ; \ 63 movq %rsp, %rsi ; \ 64 movl %eax, %edi ; /* pass the IRQ */ \ 65 call lapic_handle_intr ; \ 66 MEXITCOUNT ; \ 67 jmp doreti ; \ 682: movl $-1, %eax ; /* send a vector of -1 */ \ 69 jmp 1b 70 71/* 72 * Handle "spurious INTerrupts". 73 * Notes: 74 * This is different than the "spurious INTerrupt" generated by an 75 * 8259 PIC for missing INTs. See the APIC documentation for details. 76 * This routine should NOT do an 'EOI' cycle. 77 */ 78 .text 79 SUPERALIGN_TEXT 80IDTVEC(spuriousint) 81 82 /* No EOI cycle used here */ 83 84 jmp doreti_iret 85 86 ISR_VEC(1, apic_isr1) 87 ISR_VEC(2, apic_isr2) 88 ISR_VEC(3, apic_isr3) 89 ISR_VEC(4, apic_isr4) 90 ISR_VEC(5, apic_isr5) 91 ISR_VEC(6, apic_isr6) 92 ISR_VEC(7, apic_isr7) 93 94/* 95 * Local APIC periodic timer handler. 96 */ 97 .text 98 SUPERALIGN_TEXT 99IDTVEC(timerint) 100 PUSH_FRAME 101 FAKE_MCOUNT(TF_RIP(%rsp)) 102 movq %rsp, %rdi 103 call lapic_handle_timer 104 MEXITCOUNT 105 jmp doreti 106 107/* 108 * Local APIC CMCI handler. 109 */ 110 .text 111 SUPERALIGN_TEXT 112IDTVEC(cmcint) 113 PUSH_FRAME 114 FAKE_MCOUNT(TF_RIP(%rsp)) 115 call lapic_handle_cmc 116 MEXITCOUNT 117 jmp doreti 118 119/* 120 * Local APIC error interrupt handler. 121 */ 122 .text 123 SUPERALIGN_TEXT 124IDTVEC(errorint) 125 PUSH_FRAME 126 FAKE_MCOUNT(TF_RIP(%rsp)) 127 call lapic_handle_error 128 MEXITCOUNT 129 jmp doreti 130 131#ifdef SMP 132/* 133 * Global address space TLB shootdown. 134 */ 135 .text 136 SUPERALIGN_TEXT 137IDTVEC(invltlb) 138 pushq %rax 139 140 movq %cr3, %rax /* invalidate the TLB */ 141 movq %rax, %cr3 142 143 movq lapic, %rax 144 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ 145 146 lock 147 incl smp_tlb_wait 148 149 popq %rax 150 jmp doreti_iret 151 152/* 153 * Single page TLB shootdown 154 */ 155 .text 156 SUPERALIGN_TEXT 157IDTVEC(invlpg) 158 pushq %rax 159 160 movq smp_tlb_addr1, %rax 161 invlpg (%rax) /* invalidate single page */ 162 163 movq lapic, %rax 164 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ 165 166 lock 167 incl smp_tlb_wait 168 169 popq %rax 170 jmp doreti_iret 171 172/* 173 * Page range TLB shootdown. 174 */ 175 .text 176 SUPERALIGN_TEXT 177IDTVEC(invlrng) 178 pushq %rax 179 pushq %rdx 180 181 movq smp_tlb_addr1, %rdx 182 movq smp_tlb_addr2, %rax 1831: invlpg (%rdx) /* invalidate single page */ 184 addq $PAGE_SIZE, %rdx 185 cmpq %rax, %rdx 186 jb 1b 187 188 movq lapic, %rax 189 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ 190 191 lock 192 incl smp_tlb_wait 193 194 popq %rdx 195 popq %rax 196 jmp doreti_iret 197 198/* 199 * Invalidate cache. 200 */ 201 .text 202 SUPERALIGN_TEXT 203IDTVEC(invlcache) 204 pushq %rax 205 206 wbinvd 207 208 movq lapic, %rax 209 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ 210 211 lock 212 incl smp_tlb_wait 213 214 popq %rax 215 jmp doreti_iret 216 217/* 218 * Handler for IPIs sent via the per-cpu IPI bitmap. 219 */ 220 .text 221 SUPERALIGN_TEXT 222IDTVEC(ipi_intr_bitmap_handler) 223 PUSH_FRAME 224 225 movq lapic, %rdx 226 movl $0, LA_EOI(%rdx) /* End Of Interrupt to APIC */ 227 228 FAKE_MCOUNT(TF_RIP(%rsp)) 229 230 call ipi_bitmap_handler 231 MEXITCOUNT 232 jmp doreti 233 234/* 235 * Executed by a CPU when it receives an IPI_STOP from another CPU. 236 */ 237 .text 238 SUPERALIGN_TEXT 239IDTVEC(cpustop) 240 PUSH_FRAME 241 242 movq lapic, %rax 243 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ 244 245 call cpustop_handler 246 jmp doreti 247 248/* 249 * Executed by a CPU when it receives an IPI_SUSPEND from another CPU. 250 */ 251 .text 252 SUPERALIGN_TEXT 253IDTVEC(cpususpend) 254 PUSH_FRAME 255 256 movq lapic, %rax 257 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ 258 259 call cpususpend_handler 260 261 POP_FRAME 262 jmp doreti_iret 263 264/* 265 * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU. 266 * 267 * - Calls the generic rendezvous action function. 268 */ 269 .text 270 SUPERALIGN_TEXT 271IDTVEC(rendezvous) 272 PUSH_FRAME 273 call smp_rendezvous_action 274 movq lapic, %rax 275 movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ 276 jmp doreti 277#endif /* SMP */ 278