]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/amd64/amd64/apic_vector.S
zfs: merge openzfs/zfs@3522f57b6 (master)
[FreeBSD/FreeBSD.git] / sys / amd64 / amd64 / apic_vector.S
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  * Copyright (c) 2014-2018 The FreeBSD Foundation
6  * All rights reserved.
7  *
8  * Portions of this software were developed by
9  * Konstantin Belousov <kib@FreeBSD.org> under sponsorship from
10  * the FreeBSD Foundation.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  *      from: vector.s, 386BSD 0.1 unknown origin
37  * $FreeBSD$
38  */
39
40 /*
41  * Interrupt entry points for external interrupts triggered by I/O APICs
42  * as well as IPI handlers.
43  */
44
45 #include "opt_smp.h"
46
47 #include "assym.inc"
48
49 #include <machine/asmacros.h>
50 #include <machine/specialreg.h>
51 #include <x86/apicreg.h>
52
53 #ifdef SMP
54 #define LK      lock ;
55 #else
56 #define LK
57 #endif
58
59         .text
60         SUPERALIGN_TEXT
61         /* End Of Interrupt to APIC */
62 as_lapic_eoi:
63         cmpl    $0,x2apic_mode
64         jne     1f
65         movq    lapic_map,%rax
66         movl    $0,LA_EOI(%rax)
67         ret
68 1:
69         movl    $MSR_APIC_EOI,%ecx
70         xorl    %eax,%eax
71         xorl    %edx,%edx
72         wrmsr
73         ret
74
75 /*
76  * I/O Interrupt Entry Point.  Rather than having one entry point for
77  * each interrupt source, we use one entry point for each 32-bit word
78  * in the ISR.  The handler determines the highest bit set in the ISR,
79  * translates that into a vector, and passes the vector to the
80  * lapic_handle_intr() function.
81  */
82         .macro  ISR_VEC index, vec_name
83         INTR_HANDLER    \vec_name
84         cmpl    $0,x2apic_mode
85         je      1f
86         movl    $(MSR_APIC_ISR0 + \index),%ecx
87         rdmsr
88         jmp     2f
89 1:
90         movq    lapic_map, %rdx         /* pointer to local APIC */
91         movl    LA_ISR + 16 * (\index)(%rdx), %eax      /* load ISR */
92 2:
93         bsrl    %eax, %eax      /* index of highest set bit in ISR */
94         jz      3f
95         addl    $(32 * \index),%eax
96         movq    %rsp, %rsi
97         movl    %eax, %edi      /* pass the IRQ */
98         call    lapic_handle_intr
99 3:
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
112 IDTVEC(spuriousint)
113         /* No EOI cycle used here */
114         jmp     doreti_iret
115
116         ISR_VEC 1, apic_isr1
117         ISR_VEC 2, apic_isr2
118         ISR_VEC 3, apic_isr3
119         ISR_VEC 4, apic_isr4
120         ISR_VEC 5, apic_isr5
121         ISR_VEC 6, apic_isr6
122         ISR_VEC 7, apic_isr7
123
124 /*
125  * Local APIC periodic timer handler.
126  */
127         INTR_HANDLER    timerint
128         movq    %rsp, %rdi
129         call    lapic_handle_timer
130         jmp     doreti
131
132 /*
133  * Local APIC CMCI handler.
134  */
135         INTR_HANDLER cmcint
136         call    lapic_handle_cmc
137         jmp     doreti
138
139 /*
140  * Local APIC error interrupt handler.
141  */
142         INTR_HANDLER errorint
143         call    lapic_handle_error
144         jmp     doreti
145
146 #ifdef XENHVM
147 /*
148  * Xen event channel upcall interrupt handler.
149  * Only used when the hypervisor supports direct vector callbacks.
150  */
151         INTR_HANDLER xen_intr_upcall
152         movq    %rsp, %rdi
153         call    xen_intr_handle_upcall
154         jmp     doreti
155 #endif
156
157 #ifdef SMP
158 /*
159  * Global address space TLB shootdown.
160  */
161         .text
162
163         SUPERALIGN_TEXT
164 /*
165  * IPI handler for cache and TLB shootdown
166  */
167         INTR_HANDLER invlop
168         call    invlop_handler
169         call    as_lapic_eoi
170         jmp     ld_regs
171
172 /*
173  * Handler for IPIs sent via the per-cpu IPI bitmap.
174  */
175         INTR_HANDLER ipi_intr_bitmap_handler
176         call    as_lapic_eoi
177         call    ipi_bitmap_handler
178         jmp     doreti
179
180 /*
181  * Executed by a CPU when it receives an IPI_STOP from another CPU.
182  */
183         INTR_HANDLER cpustop
184         call    as_lapic_eoi
185         call    cpustop_handler
186         jmp     doreti
187
188 /*
189  * Executed by a CPU when it receives an IPI_SUSPEND from another CPU.
190  */
191         INTR_HANDLER cpususpend
192         call    cpususpend_handler
193         call    as_lapic_eoi
194         jmp     doreti
195
196 /*
197  * Executed by a CPU when it receives an IPI_SWI.
198  */
199         INTR_HANDLER ipi_swi
200         call    as_lapic_eoi
201         call    ipi_swi_handler
202         jmp     doreti
203
204 /*
205  * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU.
206  *
207  * - Calls the generic rendezvous action function.
208  */
209         INTR_HANDLER rendezvous
210 #ifdef COUNT_IPIS
211         movl    PCPU(CPUID), %eax
212         movq    ipi_rendezvous_counts(,%rax,8), %rax
213         incq    (%rax)
214 #endif
215         call    smp_rendezvous_action
216         call    as_lapic_eoi
217         jmp     doreti
218
219 /*
220  * IPI handler whose purpose is to interrupt the CPU with minimum overhead.
221  * This is used by bhyve to force a host cpu executing in guest context to
222  * trap into the hypervisor.
223  *
224  * This handler is different from other IPI handlers in the following aspects:
225  *
226  * 1. It doesn't push a trapframe on the stack.
227  *
228  * This implies that a DDB backtrace involving 'justreturn' will skip the
229  * function that was interrupted by this handler.
230  *
231  * 2. It doesn't 'swapgs' when userspace is interrupted.
232  *
233  * The 'justreturn' handler does not access any pcpu data so it is not an
234  * issue. Moreover the 'justreturn' handler can only be interrupted by an NMI
235  * whose handler already doesn't trust GS.base when kernel code is interrupted.
236  */
237         .text
238         SUPERALIGN_TEXT
239 IDTVEC(justreturn)
240         pushq   %rax
241         pushq   %rcx
242         pushq   %rdx
243         call    as_lapic_eoi
244         popq    %rdx
245         popq    %rcx
246         popq    %rax
247         jmp     doreti_iret
248
249         INTR_HANDLER    justreturn1
250         call    as_lapic_eoi
251         jmp     doreti
252
253 #endif /* SMP */