xref: /netbsd/sys/arch/amd64/amd64/vector.S (revision 77f69257)
1/*	$NetBSD: vector.S,v 1.73 2019/12/30 23:32:29 thorpej Exp $	*/
2
3/*
4 * Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum and by Andrew Doran.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*
33 * Copyright (c) 2001 Wasabi Systems, Inc.
34 * All rights reserved.
35 *
36 * Written by Frank van der Linden for Wasabi Systems, Inc.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 *    notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 *    notice, this list of conditions and the following disclaimer in the
45 *    documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 *    must display the following acknowledgement:
48 *      This product includes software developed for the NetBSD Project by
49 *      Wasabi Systems, Inc.
50 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
51 *    or promote products derived from this software without specific prior
52 *    written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
64 * POSSIBILITY OF SUCH DAMAGE.
65 */
66
67#include <machine/asm.h>
68
69#include "opt_ddb.h"
70#include "opt_multiprocessor.h"
71#include "opt_xen.h"
72#include "opt_dtrace.h"
73
74#define ALIGN_TEXT	.align 16,0x90
75
76#include <machine/i8259.h>
77#include <machine/i82093reg.h>
78#include <machine/i82489reg.h>
79#include <machine/frameasm.h>
80#include <machine/segments.h>
81#include <machine/trap.h>
82#include <machine/specialreg.h>
83
84#include "ioapic.h"
85#include "lapic.h"
86#include "assym.h"
87#ifndef XEN
88#include "hyperv.h"
89#endif
90
91	.text
92
93/*
94 * Macros for interrupt entry, call to handler, and exit.
95 *
96 * XXX
97 * The interrupt frame is set up to look like a trap frame.  This may be a
98 * waste.  The only handler which needs a frame is the clock handler, and it
99 * only needs a few bits.  Xdoreti() needs a trap frame for handling ASTs, but
100 * it could easily convert the frame on demand.
101 *
102 * The direct costs of setting up a trap frame are two pushq's (error code and
103 * trap number), an addl to get rid of these, and pushing and popping the
104 * callee-saved registers %esi, %edi, %ebx, and %ebp twice.
105 *
106 * If the interrupt frame is made more flexible,  INTR can push %eax first and
107 * decide the ipending case with less overhead, e.g., by avoiding loading the
108 * segment registers.
109 */
110
111#if NLAPIC > 0
112#ifdef MULTIPROCESSOR
113IDTVEC(recurse_lapic_ipi)
114	INTR_RECURSE_HWFRAME
115	pushq	$0
116	pushq	$T_ASTFLT
117	INTR_RECURSE_ENTRY
118	jmp	1f
119IDTVEC_END(recurse_lapic_ipi)
120IDTVEC(handle_x2apic_ipi)
121	movl	$(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
122	xorl	%eax,%eax
123	xorl	%edx,%edx
124	wrmsr
125	movl	CPUVAR(ILEVEL),%ebx
126	cmpl	$IPL_HIGH,%ebx
127	jae	2f
128	jmp	1f
129IDTVEC_END(handle_x2apic_ipi)
130IDTVEC(handle_lapic_ipi)
131	movq	_C_LABEL(local_apic_va),%rbx
132	movl	$0,LAPIC_EOI(%rbx)
133	movl	CPUVAR(ILEVEL),%ebx
134	cmpl	$IPL_HIGH,%ebx
135	jae	2f
136	jmp	1f
137IDTVEC_END(handle_lapic_ipi)
138IDTVEC(resume_lapic_ipi)
1391:
140	incl	CPUVAR(IDEPTH)
141	movl	$IPL_HIGH,CPUVAR(ILEVEL)
142	sti
143	pushq	%rbx
144	call	_C_LABEL(x86_ipi_handler)
145	jmp	_C_LABEL(Xdoreti)
1462:
147	orl	$(1 << LIR_IPI),CPUVAR(IPENDING)
148	INTRFASTEXIT
149IDTVEC_END(resume_lapic_ipi)
150
151	TEXT_USER_BEGIN
152IDTVEC(intr_x2apic_ipi)
153	pushq	$0
154	pushq	$T_ASTFLT
155	INTRENTRY
156	jmp	_C_LABEL(Xhandle_x2apic_ipi)
157IDTVEC_END(intr_x2apic_ipi)
158IDTVEC(intr_lapic_ipi)
159	pushq	$0
160	pushq	$T_ASTFLT
161	INTRENTRY
162	jmp	_C_LABEL(Xhandle_lapic_ipi)
163IDTVEC_END(intr_lapic_ipi)
164	TEXT_USER_END
165
166#if defined(DDB)
167IDTVEC(handle_ddbipi)
168	movl	$0xf,%eax
169	movq	%rax,%cr8
170	movq	_C_LABEL(local_apic_va),%rbx
171	movl	$0,LAPIC_EOI(%rbx)
172	sti
173	call	_C_LABEL(ddb_ipi)
174	xorl	%eax,%eax
175	movq	%rax,%cr8
176	INTRFASTEXIT
177IDTVEC_END(handle_ddbipi)
178IDTVEC(handle_x2apic_ddbipi)
179	movl	$0xf,%eax
180	movq	%rax,%cr8
181	movl	$(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
182	xorl	%eax,%eax
183	xorl	%edx,%edx
184	wrmsr
185	sti
186	call	_C_LABEL(ddb_ipi)
187	xorl	%eax,%eax
188	movq	%rax,%cr8
189	INTRFASTEXIT
190IDTVEC_END(handle_x2apic_ddbipi)
191
192	TEXT_USER_BEGIN
193IDTVEC(intr_ddbipi)
194	pushq	$0
195	pushq	$T_BPTFLT
196	INTRENTRY
197	jmp	_C_LABEL(Xhandle_ddbipi)
198IDTVEC_END(intr_ddbipi)
199IDTVEC(intr_x2apic_ddbipi)
200	pushq	$0
201	pushq	$T_BPTFLT
202	INTRENTRY
203	jmp	_C_LABEL(Xhandle_x2apic_ddbipi)
204IDTVEC_END(intr_x2apic_ddbipi)
205	TEXT_USER_END
206
207#endif /* DDB */
208#endif /* MULTIPROCESSOR */
209
210	/*
211	 * Interrupt from the local APIC timer.
212	 */
213IDTVEC(recurse_lapic_ltimer)
214	INTR_RECURSE_HWFRAME
215	pushq	$0
216	pushq	$T_ASTFLT
217	INTR_RECURSE_ENTRY
218	jmp	1f
219IDTVEC_END(recurse_lapic_ltimer)
220IDTVEC(handle_x2apic_ltimer)
221	movl	$(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
222	xorl	%eax,%eax
223	xorl	%edx,%edx
224	wrmsr
225	movl	CPUVAR(ILEVEL),%ebx
226	cmpl	$IPL_CLOCK,%ebx
227	jae	2f
228	jmp	1f
229IDTVEC_END(handle_x2apic_ltimer)
230IDTVEC(handle_lapic_ltimer)
231	movq	_C_LABEL(local_apic_va),%rbx
232	movl	$0,LAPIC_EOI(%rbx)
233	movl	CPUVAR(ILEVEL),%ebx
234	cmpl	$IPL_CLOCK,%ebx
235	jae	2f
236	jmp	1f
237IDTVEC_END(handle_lapic_ltimer)
238IDTVEC(resume_lapic_ltimer)
2391:
240	incl	CPUVAR(IDEPTH)
241	movl	$IPL_CLOCK,CPUVAR(ILEVEL)
242	sti
243	pushq	%rbx
244	movq	%rsp,%rsi
245	xorq	%rdi,%rdi
246	call	_C_LABEL(lapic_clockintr)
247	jmp	_C_LABEL(Xdoreti)
2482:
249	orl	$(1 << LIR_TIMER),CPUVAR(IPENDING)
250	INTRFASTEXIT
251IDTVEC_END(resume_lapic_ltimer)
252
253	TEXT_USER_BEGIN
254IDTVEC(intr_x2apic_ltimer)
255	pushq	$0
256	pushq	$T_ASTFLT
257	INTRENTRY
258	jmp	_C_LABEL(Xhandle_x2apic_ltimer)
259IDTVEC_END(intr_x2apic_ltimer)
260IDTVEC(intr_lapic_ltimer)
261	pushq	$0
262	pushq	$T_ASTFLT
263	INTRENTRY
264	jmp	_C_LABEL(Xhandle_lapic_ltimer)
265IDTVEC_END(intr_lapic_ltimer)
266	TEXT_USER_END
267
268#if NHYPERV > 0
269	/*
270	 * Hyper-V event channel upcall interrupt handler.
271	 * Only used when the hypervisor supports direct vector callbacks.
272	 */
273IDTVEC(recurse_hyperv_hypercall)
274	INTR_RECURSE_HWFRAME
275	pushq	$0
276	pushq	$T_ASTFLT
277	INTR_RECURSE_ENTRY
278	jmp	1f
279IDTVEC_END(recurse_hyperv_hypercall)
280IDTVEC(handle_hyperv_hypercall)
281	movl	CPUVAR(ILEVEL),%ebx
282	cmpl	$IPL_NET,%ebx
283	jae	2f
284	jmp	1f
285IDTVEC_END(handle_hyperv_hypercall)
286IDTVEC(resume_hyperv_hypercall)
2871:
288	incl	CPUVAR(IDEPTH)
289	movl	$IPL_NET,CPUVAR(ILEVEL)
290	sti
291	pushq	%rbx
292	movq	%rsp,%rsi
293	call	_C_LABEL(hyperv_hypercall_intr)
294	jmp	_C_LABEL(Xdoreti)
2952:
296	orl	$(1 << LIR_HV),CPUVAR(IPENDING)
297	INTRFASTEXIT
298IDTVEC_END(resume_hyperv_hypercall)
299
300	TEXT_USER_BEGIN
301IDTVEC(intr_hyperv_hypercall)
302	pushq	$0
303	pushq	$T_ASTFLT
304	INTRENTRY
305	jmp	_C_LABEL(Xhandle_hyperv_hypercall)
306IDTVEC_END(intr_hyperv_hypercall)
307	TEXT_USER_END
308#endif	/* NHYPERV > 0 */
309
310#endif /* NLAPIC > 0 */
311
312#ifndef XENPV
313/*
314 * TLB shootdown handler.
315 */
316IDTVEC(handle_lapic_tlb)
317	movq	_C_LABEL(local_apic_va),%rax
318	movl	$0,LAPIC_EOI(%rax)
319	KCOV_DISABLE
320	callq	_C_LABEL(pmap_tlb_intr)
321	KCOV_ENABLE
322	INTRFASTEXIT
323IDTVEC_END(handle_lapic_tlb)
324IDTVEC(handle_x2apic_tlb)
325	movl	$(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
326	xorl	%eax,%eax
327	xorl	%edx,%edx
328	wrmsr
329	KCOV_DISABLE
330	callq	_C_LABEL(pmap_tlb_intr)
331	KCOV_ENABLE
332	INTRFASTEXIT
333IDTVEC_END(handle_x2apic_tlb)
334
335	TEXT_USER_BEGIN
336IDTVEC(intr_lapic_tlb)
337	pushq	$0
338	pushq	$T_ASTFLT
339	INTRENTRY
340	jmp	_C_LABEL(Xhandle_lapic_tlb)
341IDTVEC_END(intr_lapic_tlb)
342IDTVEC(intr_x2apic_tlb)
343	pushq	$0
344	pushq	$T_ASTFLT
345	INTRENTRY
346	jmp	_C_LABEL(Xhandle_x2apic_tlb)
347IDTVEC_END(intr_x2apic_tlb)
348	TEXT_USER_END
349
350#endif /* !XENPV */
351
352#define voidop(num)
353
354#ifndef XENPV
355
356/*
357 * This macro defines the generic stub code. Its arguments modify it
358 * for specific PICs.
359 */
360
361#define	INTRSTUB(name, num, early_ack, late_ack, mask, unmask, level_mask) \
362IDTVEC(recurse_ ## name ## num)						;\
363	INTR_RECURSE_HWFRAME						;\
364	subq	$8,%rsp							;\
365	pushq	$T_ASTFLT		/* trap # for doing ASTs */	;\
366	INTR_RECURSE_ENTRY						;\
367	jmp	1f							;\
368IDTVEC_END(recurse_ ## name ## num)					;\
369IDTVEC(resume_ ## name ## num)						\
3701:	movq	$IREENT_MAGIC,TF_ERR(%rsp)				;\
371	movl	%ebx,%r13d						;\
372	movq	CPUVAR(ISOURCES) + (num) * 8,%r14			;\
373	movl	IS_MAXLEVEL(%r14),%ebx					;\
374	jmp	1f							;\
375IDTVEC_END(resume_ ## name ## num)					;\
376IDTVEC(handle_ ## name ## num)						;\
377	movq	CPUVAR(ISOURCES) + (num) * 8,%r14			;\
378	mask(num)			/* mask it in hardware */	;\
379	early_ack(num)			/* and allow other intrs */	;\
380	testq	%r14,%r14						;\
381	jz	9f			/* stray */			;\
382	movl	IS_MAXLEVEL(%r14),%ebx					;\
383	movl	CPUVAR(ILEVEL),%r13d					;\
384	cmpl	%ebx,%r13d						;\
385	jae	10f			/* currently masked; hold it */	;\
386	incq	CPUVAR(NINTR)		/* statistical info */		;\
387	incq	IS_EVCNT(%r14)						;\
3881:									\
389	pushq	%r13			/* save for Xdoreti */		;\
390	movl	%ebx,CPUVAR(ILEVEL)					;\
391	sti								;\
392	incl	CPUVAR(IDEPTH)						;\
393	movq	IS_HANDLERS(%r14),%rbx					;\
394	cmpl	$0,IS_MASK_COUNT(%r14)	/* source currently masked? */	;\
395	jne	12f			/* yes, hold it */		;\
3966:									\
397	movl	IH_LEVEL(%rbx),%r12d					;\
398	cmpl	%r13d,%r12d						;\
399	jle	7f							;\
400	movq	%rsp,%rsi						;\
401	movq	IH_ARG(%rbx),%rdi					;\
402	movl	%r12d,CPUVAR(ILEVEL)					;\
403	call	*IH_FUN(%rbx)		/* call it */			;\
404	movq	IH_NEXT(%rbx),%rbx	/* next handler in chain */	;\
405	testq	%rbx,%rbx						;\
406	jnz	6b							;\
4075:									\
408	cmpl	$0,IS_MASK_COUNT(%r14)	/* source now masked? */	;\
409	jne	12f			/* yes, deal */			;\
410	cli								;\
411	unmask(num)			/* unmask it in hardware */	;\
412	late_ack(num)							;\
413	sti								;\
414	jmp	_C_LABEL(Xdoreti)	/* lower spl and do ASTs */	;\
4157:									\
416	cli								;\
417	orl	$(1 << num),CPUVAR(IPENDING)				;\
4188:	level_mask(num)							;\
419	late_ack(num)							;\
420	sti								;\
421	jmp	_C_LABEL(Xdoreti)	/* lower spl and do ASTs */	;\
42212:									\
423	cli								;\
424	orl	$(1 << num),CPUVAR(IMASKED)				;\
425	btrl	$(num),CPUVAR(IPENDING)					;\
426	jmp	8b							;\
42710:									\
428	cli								;\
429	orl	$(1 << num),CPUVAR(IPENDING)				;\
430	level_mask(num)							;\
431	late_ack(num)							;\
432	INTRFASTEXIT							;\
4339:									\
434	unmask(num)							;\
435	late_ack(num)							;\
436	INTRFASTEXIT							;\
437IDTVEC_END(handle_ ## name ## num)					;\
438	TEXT_USER_BEGIN							;\
439IDTVEC(intr_ ## name ## num)						;\
440	pushq	$0			/* dummy error code */		;\
441	pushq	$T_ASTFLT		/* trap # for doing ASTs */	;\
442	INTRENTRY							;\
443	jmp	_C_LABEL(Xhandle_ ## name ## num)			;\
444IDTVEC_END(intr_ ## name ## num)					;\
445	TEXT_USER_END
446
447#define ICUADDR IO_ICU1
448
449INTRSTUB(legacy,0,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
450    voidop)
451INTRSTUB(legacy,1,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
452    voidop)
453INTRSTUB(legacy,2,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
454    voidop)
455INTRSTUB(legacy,3,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
456    voidop)
457INTRSTUB(legacy,4,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
458    voidop)
459INTRSTUB(legacy,5,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
460    voidop)
461INTRSTUB(legacy,6,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
462    voidop)
463INTRSTUB(legacy,7,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
464    voidop)
465#undef ICUADDR
466#define ICUADDR IO_ICU2
467
468INTRSTUB(legacy,8,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
469    voidop)
470INTRSTUB(legacy,9,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
471    voidop)
472INTRSTUB(legacy,10,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
473    voidop)
474INTRSTUB(legacy,11,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
475    voidop)
476INTRSTUB(legacy,12,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
477    voidop)
478INTRSTUB(legacy,13,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
479    voidop)
480INTRSTUB(legacy,14,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
481    voidop)
482INTRSTUB(legacy,15,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
483    voidop)
484
485#if NIOAPIC > 0
486
487INTRSTUB(ioapic_edge,0,voidop,ioapic_asm_ack,voidop,voidop,voidop)
488INTRSTUB(ioapic_edge,1,voidop,ioapic_asm_ack,voidop,voidop,voidop)
489INTRSTUB(ioapic_edge,2,voidop,ioapic_asm_ack,voidop,voidop,voidop)
490INTRSTUB(ioapic_edge,3,voidop,ioapic_asm_ack,voidop,voidop,voidop)
491INTRSTUB(ioapic_edge,4,voidop,ioapic_asm_ack,voidop,voidop,voidop)
492INTRSTUB(ioapic_edge,5,voidop,ioapic_asm_ack,voidop,voidop,voidop)
493INTRSTUB(ioapic_edge,6,voidop,ioapic_asm_ack,voidop,voidop,voidop)
494INTRSTUB(ioapic_edge,7,voidop,ioapic_asm_ack,voidop,voidop,voidop)
495INTRSTUB(ioapic_edge,8,voidop,ioapic_asm_ack,voidop,voidop,voidop)
496INTRSTUB(ioapic_edge,9,voidop,ioapic_asm_ack,voidop,voidop,voidop)
497INTRSTUB(ioapic_edge,10,voidop,ioapic_asm_ack,voidop,voidop,voidop)
498INTRSTUB(ioapic_edge,11,voidop,ioapic_asm_ack,voidop,voidop,voidop)
499INTRSTUB(ioapic_edge,12,voidop,ioapic_asm_ack,voidop,voidop,voidop)
500INTRSTUB(ioapic_edge,13,voidop,ioapic_asm_ack,voidop,voidop,voidop)
501INTRSTUB(ioapic_edge,14,voidop,ioapic_asm_ack,voidop,voidop,voidop)
502INTRSTUB(ioapic_edge,15,voidop,ioapic_asm_ack,voidop,voidop,voidop)
503INTRSTUB(ioapic_edge,16,voidop,ioapic_asm_ack,voidop,voidop,voidop)
504INTRSTUB(ioapic_edge,17,voidop,ioapic_asm_ack,voidop,voidop,voidop)
505INTRSTUB(ioapic_edge,18,voidop,ioapic_asm_ack,voidop,voidop,voidop)
506INTRSTUB(ioapic_edge,19,voidop,ioapic_asm_ack,voidop,voidop,voidop)
507INTRSTUB(ioapic_edge,20,voidop,ioapic_asm_ack,voidop,voidop,voidop)
508INTRSTUB(ioapic_edge,21,voidop,ioapic_asm_ack,voidop,voidop,voidop)
509INTRSTUB(ioapic_edge,22,voidop,ioapic_asm_ack,voidop,voidop,voidop)
510INTRSTUB(ioapic_edge,23,voidop,ioapic_asm_ack,voidop,voidop,voidop)
511INTRSTUB(ioapic_edge,24,voidop,ioapic_asm_ack,voidop,voidop,voidop)
512INTRSTUB(ioapic_edge,25,voidop,ioapic_asm_ack,voidop,voidop,voidop)
513INTRSTUB(ioapic_edge,26,voidop,ioapic_asm_ack,voidop,voidop,voidop)
514INTRSTUB(ioapic_edge,27,voidop,ioapic_asm_ack,voidop,voidop,voidop)
515INTRSTUB(ioapic_edge,28,voidop,ioapic_asm_ack,voidop,voidop,voidop)
516INTRSTUB(ioapic_edge,29,voidop,ioapic_asm_ack,voidop,voidop,voidop)
517INTRSTUB(ioapic_edge,30,voidop,ioapic_asm_ack,voidop,voidop,voidop)
518INTRSTUB(ioapic_edge,31,voidop,ioapic_asm_ack,voidop,voidop,voidop)
519
520INTRSTUB(ioapic_level,0,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
521INTRSTUB(ioapic_level,1,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
522INTRSTUB(ioapic_level,2,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
523INTRSTUB(ioapic_level,3,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
524INTRSTUB(ioapic_level,4,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
525INTRSTUB(ioapic_level,5,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
526INTRSTUB(ioapic_level,6,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
527INTRSTUB(ioapic_level,7,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
528INTRSTUB(ioapic_level,8,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
529INTRSTUB(ioapic_level,9,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
530INTRSTUB(ioapic_level,10,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
531INTRSTUB(ioapic_level,11,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
532INTRSTUB(ioapic_level,12,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
533INTRSTUB(ioapic_level,13,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
534INTRSTUB(ioapic_level,14,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
535INTRSTUB(ioapic_level,15,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
536INTRSTUB(ioapic_level,16,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
537INTRSTUB(ioapic_level,17,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
538INTRSTUB(ioapic_level,18,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
539INTRSTUB(ioapic_level,19,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
540INTRSTUB(ioapic_level,20,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
541INTRSTUB(ioapic_level,21,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
542INTRSTUB(ioapic_level,22,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
543INTRSTUB(ioapic_level,23,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
544INTRSTUB(ioapic_level,24,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
545INTRSTUB(ioapic_level,25,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
546INTRSTUB(ioapic_level,26,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
547INTRSTUB(ioapic_level,27,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
548INTRSTUB(ioapic_level,28,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
549INTRSTUB(ioapic_level,29,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
550INTRSTUB(ioapic_level,30,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
551INTRSTUB(ioapic_level,31,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
552
553INTRSTUB(x2apic_edge,0,voidop,x2apic_asm_ack,voidop,voidop,voidop)
554INTRSTUB(x2apic_edge,1,voidop,x2apic_asm_ack,voidop,voidop,voidop)
555INTRSTUB(x2apic_edge,2,voidop,x2apic_asm_ack,voidop,voidop,voidop)
556INTRSTUB(x2apic_edge,3,voidop,x2apic_asm_ack,voidop,voidop,voidop)
557INTRSTUB(x2apic_edge,4,voidop,x2apic_asm_ack,voidop,voidop,voidop)
558INTRSTUB(x2apic_edge,5,voidop,x2apic_asm_ack,voidop,voidop,voidop)
559INTRSTUB(x2apic_edge,6,voidop,x2apic_asm_ack,voidop,voidop,voidop)
560INTRSTUB(x2apic_edge,7,voidop,x2apic_asm_ack,voidop,voidop,voidop)
561INTRSTUB(x2apic_edge,8,voidop,x2apic_asm_ack,voidop,voidop,voidop)
562INTRSTUB(x2apic_edge,9,voidop,x2apic_asm_ack,voidop,voidop,voidop)
563INTRSTUB(x2apic_edge,10,voidop,x2apic_asm_ack,voidop,voidop,voidop)
564INTRSTUB(x2apic_edge,11,voidop,x2apic_asm_ack,voidop,voidop,voidop)
565INTRSTUB(x2apic_edge,12,voidop,x2apic_asm_ack,voidop,voidop,voidop)
566INTRSTUB(x2apic_edge,13,voidop,x2apic_asm_ack,voidop,voidop,voidop)
567INTRSTUB(x2apic_edge,14,voidop,x2apic_asm_ack,voidop,voidop,voidop)
568INTRSTUB(x2apic_edge,15,voidop,x2apic_asm_ack,voidop,voidop,voidop)
569INTRSTUB(x2apic_edge,16,voidop,x2apic_asm_ack,voidop,voidop,voidop)
570INTRSTUB(x2apic_edge,17,voidop,x2apic_asm_ack,voidop,voidop,voidop)
571INTRSTUB(x2apic_edge,18,voidop,x2apic_asm_ack,voidop,voidop,voidop)
572INTRSTUB(x2apic_edge,19,voidop,x2apic_asm_ack,voidop,voidop,voidop)
573INTRSTUB(x2apic_edge,20,voidop,x2apic_asm_ack,voidop,voidop,voidop)
574INTRSTUB(x2apic_edge,21,voidop,x2apic_asm_ack,voidop,voidop,voidop)
575INTRSTUB(x2apic_edge,22,voidop,x2apic_asm_ack,voidop,voidop,voidop)
576INTRSTUB(x2apic_edge,23,voidop,x2apic_asm_ack,voidop,voidop,voidop)
577INTRSTUB(x2apic_edge,24,voidop,x2apic_asm_ack,voidop,voidop,voidop)
578INTRSTUB(x2apic_edge,25,voidop,x2apic_asm_ack,voidop,voidop,voidop)
579INTRSTUB(x2apic_edge,26,voidop,x2apic_asm_ack,voidop,voidop,voidop)
580INTRSTUB(x2apic_edge,27,voidop,x2apic_asm_ack,voidop,voidop,voidop)
581INTRSTUB(x2apic_edge,28,voidop,x2apic_asm_ack,voidop,voidop,voidop)
582INTRSTUB(x2apic_edge,29,voidop,x2apic_asm_ack,voidop,voidop,voidop)
583INTRSTUB(x2apic_edge,30,voidop,x2apic_asm_ack,voidop,voidop,voidop)
584INTRSTUB(x2apic_edge,31,voidop,x2apic_asm_ack,voidop,voidop,voidop)
585
586INTRSTUB(x2apic_level,0,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
587INTRSTUB(x2apic_level,1,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
588INTRSTUB(x2apic_level,2,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
589INTRSTUB(x2apic_level,3,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
590INTRSTUB(x2apic_level,4,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
591INTRSTUB(x2apic_level,5,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
592INTRSTUB(x2apic_level,6,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
593INTRSTUB(x2apic_level,7,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
594INTRSTUB(x2apic_level,8,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
595INTRSTUB(x2apic_level,9,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
596INTRSTUB(x2apic_level,10,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
597INTRSTUB(x2apic_level,11,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
598INTRSTUB(x2apic_level,12,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
599INTRSTUB(x2apic_level,13,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
600INTRSTUB(x2apic_level,14,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
601INTRSTUB(x2apic_level,15,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
602INTRSTUB(x2apic_level,16,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
603INTRSTUB(x2apic_level,17,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
604INTRSTUB(x2apic_level,18,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
605INTRSTUB(x2apic_level,19,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
606INTRSTUB(x2apic_level,20,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
607INTRSTUB(x2apic_level,21,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
608INTRSTUB(x2apic_level,22,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
609INTRSTUB(x2apic_level,23,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
610INTRSTUB(x2apic_level,24,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
611INTRSTUB(x2apic_level,25,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
612INTRSTUB(x2apic_level,26,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
613INTRSTUB(x2apic_level,27,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
614INTRSTUB(x2apic_level,28,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
615INTRSTUB(x2apic_level,29,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
616INTRSTUB(x2apic_level,30,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
617INTRSTUB(x2apic_level,31,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
618
619#endif
620
621/*
622 * Create a struct intrstub.
623 */
624#define INTRSTUB_ENTRY(name) \
625	.quad _C_LABEL(Xintr_ ## name ), _C_LABEL(Xrecurse_ ## name ) ; \
626	.quad _C_LABEL(Xresume_ ## name ) ;
627
628/*
629 * Create an array of structs intrstub (16 entries).
630 */
631#define INTRSTUB_ARRAY_16(name) 		; \
632	.type _C_LABEL(name ## _stubs), @object	; \
633LABEL(name ## _stubs)				; \
634	INTRSTUB_ENTRY(name ## 0)		; \
635	INTRSTUB_ENTRY(name ## 1)		; \
636	INTRSTUB_ENTRY(name ## 2)		; \
637	INTRSTUB_ENTRY(name ## 3)		; \
638	INTRSTUB_ENTRY(name ## 4)		; \
639	INTRSTUB_ENTRY(name ## 5)		; \
640	INTRSTUB_ENTRY(name ## 6)		; \
641	INTRSTUB_ENTRY(name ## 7)		; \
642	INTRSTUB_ENTRY(name ## 8)		; \
643	INTRSTUB_ENTRY(name ## 9)		; \
644	INTRSTUB_ENTRY(name ## 10)		; \
645	INTRSTUB_ENTRY(name ## 11)		; \
646	INTRSTUB_ENTRY(name ## 12)		; \
647	INTRSTUB_ENTRY(name ## 13)		; \
648	INTRSTUB_ENTRY(name ## 14)		; \
649	INTRSTUB_ENTRY(name ## 15)		; \
650END(name ## _stubs)
651
652/*
653 * Create an array of structs intrstub (32 entries).
654 */
655#define INTRSTUB_ARRAY_32(name) 		; \
656	.type _C_LABEL(name ## _stubs), @object	; \
657LABEL(name ## _stubs)				; \
658	INTRSTUB_ENTRY(name ## 0)		; \
659	INTRSTUB_ENTRY(name ## 1)		; \
660	INTRSTUB_ENTRY(name ## 2)		; \
661	INTRSTUB_ENTRY(name ## 3)		; \
662	INTRSTUB_ENTRY(name ## 4)		; \
663	INTRSTUB_ENTRY(name ## 5)		; \
664	INTRSTUB_ENTRY(name ## 6)		; \
665	INTRSTUB_ENTRY(name ## 7)		; \
666	INTRSTUB_ENTRY(name ## 8)		; \
667	INTRSTUB_ENTRY(name ## 9)		; \
668	INTRSTUB_ENTRY(name ## 10)		; \
669	INTRSTUB_ENTRY(name ## 11)		; \
670	INTRSTUB_ENTRY(name ## 12)		; \
671	INTRSTUB_ENTRY(name ## 13)		; \
672	INTRSTUB_ENTRY(name ## 14)		; \
673	INTRSTUB_ENTRY(name ## 15)		; \
674	INTRSTUB_ENTRY(name ## 16)		; \
675	INTRSTUB_ENTRY(name ## 17)		; \
676	INTRSTUB_ENTRY(name ## 18)		; \
677	INTRSTUB_ENTRY(name ## 19)		; \
678	INTRSTUB_ENTRY(name ## 20)		; \
679	INTRSTUB_ENTRY(name ## 21)		; \
680	INTRSTUB_ENTRY(name ## 22)		; \
681	INTRSTUB_ENTRY(name ## 23)		; \
682	INTRSTUB_ENTRY(name ## 24)		; \
683	INTRSTUB_ENTRY(name ## 25)		; \
684	INTRSTUB_ENTRY(name ## 26)		; \
685	INTRSTUB_ENTRY(name ## 27)		; \
686	INTRSTUB_ENTRY(name ## 28)		; \
687	INTRSTUB_ENTRY(name ## 29)		; \
688	INTRSTUB_ENTRY(name ## 30)		; \
689	INTRSTUB_ENTRY(name ## 31)		; \
690END(name ## _stubs)
691
692#endif /* !XENPV */
693
694#if defined(XEN)
695/* Resume/recurse procedures for spl() */
696#define	XENINTRSTUB(name, num, early_ack, late_ack, mask, unmask, level_mask) \
697IDTVEC(recurse_ ## name ## num)						;\
698	INTR_RECURSE_HWFRAME						;\
699	subq	$8,%rsp							;\
700	pushq	$T_ASTFLT		/* trap # for doing ASTs */	;\
701	INTR_RECURSE_ENTRY						;\
702IDTVEC(resume_ ## name ## num)						\
703	movq	$IREENT_MAGIC,TF_ERR(%rsp)				;\
704	movl	%ebx,%r13d						;\
705	movq	CPUVAR(XSOURCES) + (num) * 8,%r14			;\
7061:									\
707	pushq	%r13							;\
708	movl	$num,CPUVAR(ILEVEL)					;\
709	STI(si)								;\
710	incl	CPUVAR(IDEPTH)						;\
711	movq	IS_HANDLERS(%r14),%rbx					;\
7126:									\
713	movq	IH_ARG(%rbx),%rdi					;\
714	movq	%rsp,%rsi						;\
715	call	*IH_FUN(%rbx)		/* call it */			;\
716	movq	IH_NEXT(%rbx),%rbx	/* next handler in chain */	;\
717	testq	%rbx,%rbx						;\
718	jnz	6b							;\
7195:									\
720	CLI(si)								;\
721	unmask(num)			/* unmask it in hardware */	;\
722	late_ack(num)							;\
723	STI(si)								;\
724	jmp	_C_LABEL(Xdoreti)	/* lower spl and do ASTs */	;\
725
726/* The unmask func for Xen events */
727#define hypervisor_asm_unmask(num)			\
728	movq	$num,%rdi				;\
729	call	_C_LABEL(hypervisor_enable_ipl)
730
731XENINTRSTUB(xenev,0,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
732XENINTRSTUB(xenev,1,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
733XENINTRSTUB(xenev,2,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
734XENINTRSTUB(xenev,3,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
735XENINTRSTUB(xenev,4,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
736XENINTRSTUB(xenev,5,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
737XENINTRSTUB(xenev,6,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
738XENINTRSTUB(xenev,7,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
739XENINTRSTUB(xenev,8,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
740XENINTRSTUB(xenev,9,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
741XENINTRSTUB(xenev,10,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
742XENINTRSTUB(xenev,11,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
743XENINTRSTUB(xenev,12,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
744XENINTRSTUB(xenev,13,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
745XENINTRSTUB(xenev,14,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
746XENINTRSTUB(xenev,15,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
747XENINTRSTUB(xenev,16,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
748XENINTRSTUB(xenev,17,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
749XENINTRSTUB(xenev,18,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
750XENINTRSTUB(xenev,19,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
751XENINTRSTUB(xenev,20,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
752XENINTRSTUB(xenev,21,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
753XENINTRSTUB(xenev,22,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
754XENINTRSTUB(xenev,23,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
755XENINTRSTUB(xenev,24,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
756XENINTRSTUB(xenev,25,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
757XENINTRSTUB(xenev,26,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
758XENINTRSTUB(xenev,27,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
759XENINTRSTUB(xenev,28,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
760XENINTRSTUB(xenev,29,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
761XENINTRSTUB(xenev,30,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
762XENINTRSTUB(xenev,31,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
763
764/* On Xen, the xenev_stubs are purely for spl entry, since there is no
765 * vector based mechanism. We however provide the entrypoint to ensure
766 * that native and Xen struct intrstub ; definitions are uniform.
767 */
768panicmsg:	.ascii "vector Xen event entry path entered."
769LABEL(entry_xenev)
770	movq $panicmsg, %rdi
771	callq _C_LABEL(panic)
772END(entry_xenev)
773
774LABEL(xenev_stubs)
775	.quad entry_xenev, _C_LABEL(Xrecurse_xenev0), _C_LABEL(Xresume_xenev0)
776	.quad entry_xenev, _C_LABEL(Xrecurse_xenev1) ,_C_LABEL(Xresume_xenev1)
777	.quad entry_xenev, _C_LABEL(Xrecurse_xenev2) ,_C_LABEL(Xresume_xenev2)
778	.quad entry_xenev, _C_LABEL(Xrecurse_xenev3) ,_C_LABEL(Xresume_xenev3)
779	.quad entry_xenev, _C_LABEL(Xrecurse_xenev4) ,_C_LABEL(Xresume_xenev4)
780	.quad entry_xenev, _C_LABEL(Xrecurse_xenev5) ,_C_LABEL(Xresume_xenev5)
781	.quad entry_xenev, _C_LABEL(Xrecurse_xenev6) ,_C_LABEL(Xresume_xenev6)
782	.quad entry_xenev, _C_LABEL(Xrecurse_xenev7) ,_C_LABEL(Xresume_xenev7)
783	.quad entry_xenev, _C_LABEL(Xrecurse_xenev8) ,_C_LABEL(Xresume_xenev8)
784	.quad entry_xenev, _C_LABEL(Xrecurse_xenev9) ,_C_LABEL(Xresume_xenev9)
785	.quad entry_xenev, _C_LABEL(Xrecurse_xenev10), _C_LABEL(Xresume_xenev10)
786	.quad entry_xenev, _C_LABEL(Xrecurse_xenev11), _C_LABEL(Xresume_xenev11)
787	.quad entry_xenev, _C_LABEL(Xrecurse_xenev12), _C_LABEL(Xresume_xenev12)
788	.quad entry_xenev, _C_LABEL(Xrecurse_xenev13), _C_LABEL(Xresume_xenev13)
789	.quad entry_xenev, _C_LABEL(Xrecurse_xenev14), _C_LABEL(Xresume_xenev14)
790	.quad entry_xenev, _C_LABEL(Xrecurse_xenev15), _C_LABEL(Xresume_xenev15)
791	.quad entry_xenev, _C_LABEL(Xrecurse_xenev16), _C_LABEL(Xresume_xenev16)
792	.quad entry_xenev, _C_LABEL(Xrecurse_xenev17), _C_LABEL(Xresume_xenev17)
793	.quad entry_xenev, _C_LABEL(Xrecurse_xenev18), _C_LABEL(Xresume_xenev18)
794	.quad entry_xenev, _C_LABEL(Xrecurse_xenev19), _C_LABEL(Xresume_xenev19)
795	.quad entry_xenev, _C_LABEL(Xrecurse_xenev20), _C_LABEL(Xresume_xenev20)
796	.quad entry_xenev, _C_LABEL(Xrecurse_xenev21), _C_LABEL(Xresume_xenev21)
797	.quad entry_xenev, _C_LABEL(Xrecurse_xenev22), _C_LABEL(Xresume_xenev22)
798	.quad entry_xenev, _C_LABEL(Xrecurse_xenev23), _C_LABEL(Xresume_xenev23)
799	.quad entry_xenev, _C_LABEL(Xrecurse_xenev24), _C_LABEL(Xresume_xenev24)
800	.quad entry_xenev, _C_LABEL(Xrecurse_xenev25), _C_LABEL(Xresume_xenev25)
801	.quad entry_xenev, _C_LABEL(Xrecurse_xenev26), _C_LABEL(Xresume_xenev26)
802	.quad entry_xenev, _C_LABEL(Xrecurse_xenev27), _C_LABEL(Xresume_xenev27)
803	.quad entry_xenev, _C_LABEL(Xrecurse_xenev28), _C_LABEL(Xresume_xenev28)
804	.quad entry_xenev, _C_LABEL(Xrecurse_xenev29), _C_LABEL(Xresume_xenev29)
805	.quad entry_xenev, _C_LABEL(Xrecurse_xenev30), _C_LABEL(Xresume_xenev30)
806	.quad entry_xenev, _C_LABEL(Xrecurse_xenev31), _C_LABEL(Xresume_xenev31)
807END(xenev_stubs)
808
809/*
810 * Xen callbacks
811 */
812
813/* Hypervisor callback */
814ENTRY(hypervisor_callback)
815	movq	(%rsp),%rcx
816	movq	8(%rsp),%r11
817	addq	$16,%rsp
818IDTVEC(hypervisor_pvhvm_callback)
819	pushq	$0		/* Dummy error code */
820	pushq	$T_ASTFLT
821	INTRENTRY
822	/* sti?? */
823	movq	%rsp,%rdi
824	subq	$8,%rdi;	/* don't forget if_ppl */
825	call	do_hypervisor_callback
826	testb	$SEL_RPL,TF_CS(%rsp)
827	jnz	doreti_checkast
8281:
829	INTRFASTEXIT
830IDTVEC_END(hypervisor_pvhvm_callback)
831END(hypervisor_callback)
832#endif /* XEN */
833
834#ifdef XENPV
835/* Panic? */
836ENTRY(failsafe_callback)
837	movq	(%rsp),%rcx
838	movq	8(%rsp),%r11
839	addq	$16,%rsp
840	pushq	$0
841	pushq	$T_ASTFLT
842	INTRENTRY
843	movq	%rsp,%rdi
844	subq	$8,%rdi;	/* don't forget if_ppl */
845	call	xen_failsafe_handler
846	INTRFASTEXIT
847/*	jmp	HYPERVISOR_iret */
848END(failsafe_callback)
849
850#else	/* XENPV */
851
852	.section .rodata
853
854INTRSTUB_ARRAY_16(legacy)
855
856#if NIOAPIC > 0
857INTRSTUB_ARRAY_32(ioapic_edge)
858INTRSTUB_ARRAY_32(ioapic_level)
859
860INTRSTUB_ARRAY_32(x2apic_edge)
861INTRSTUB_ARRAY_32(x2apic_level)
862#endif
863#endif /* !XENPV */
864