xref: /netbsd/sys/arch/amd64/amd64/vector.S (revision bf5abc14)
1/*	$NetBSD: vector.S,v 1.66 2019/02/11 14:59:32 cherry 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
88	.text
89
90/*
91 * Macros for interrupt entry, call to handler, and exit.
92 *
93 * XXX
94 * The interrupt frame is set up to look like a trap frame.  This may be a
95 * waste.  The only handler which needs a frame is the clock handler, and it
96 * only needs a few bits.  Xdoreti() needs a trap frame for handling ASTs, but
97 * it could easily convert the frame on demand.
98 *
99 * The direct costs of setting up a trap frame are two pushq's (error code and
100 * trap number), an addl to get rid of these, and pushing and popping the
101 * callee-saved registers %esi, %edi, %ebx, and %ebp twice.
102 *
103 * If the interrupt frame is made more flexible,  INTR can push %eax first and
104 * decide the ipending case with less overhead, e.g., by avoiding loading the
105 * segment registers.
106 */
107
108#if NLAPIC > 0
109#ifdef MULTIPROCESSOR
110IDTVEC(recurse_lapic_ipi)
111	INTR_RECURSE_HWFRAME
112	pushq	$0
113	pushq	$T_ASTFLT
114	INTR_RECURSE_ENTRY
115	jmp	1f
116IDTVEC_END(recurse_lapic_ipi)
117IDTVEC(handle_x2apic_ipi)
118	movl	$(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
119	xorl	%eax,%eax
120	xorl	%edx,%edx
121	wrmsr
122	movl	CPUVAR(ILEVEL),%ebx
123	cmpl	$IPL_HIGH,%ebx
124	jae	2f
125	jmp	1f
126IDTVEC_END(handle_x2apic_ipi)
127IDTVEC(handle_lapic_ipi)
128	movq	_C_LABEL(local_apic_va),%rbx
129	movl	$0,LAPIC_EOI(%rbx)
130	movl	CPUVAR(ILEVEL),%ebx
131	cmpl	$IPL_HIGH,%ebx
132	jae	2f
133	jmp	1f
134IDTVEC_END(handle_lapic_ipi)
135IDTVEC(resume_lapic_ipi)
1361:
137	incl	CPUVAR(IDEPTH)
138	movl	$IPL_HIGH,CPUVAR(ILEVEL)
139	sti
140	pushq	%rbx
141	call	_C_LABEL(x86_ipi_handler)
142	jmp	_C_LABEL(Xdoreti)
1432:
144	orl	$(1 << LIR_IPI),CPUVAR(IPENDING)
145	INTRFASTEXIT
146IDTVEC_END(resume_lapic_ipi)
147
148	TEXT_USER_BEGIN
149IDTVEC(intr_x2apic_ipi)
150	pushq	$0
151	pushq	$T_ASTFLT
152	INTRENTRY
153	jmp	_C_LABEL(Xhandle_x2apic_ipi)
154IDTVEC_END(intr_x2apic_ipi)
155IDTVEC(intr_lapic_ipi)
156	pushq	$0
157	pushq	$T_ASTFLT
158	INTRENTRY
159	jmp	_C_LABEL(Xhandle_lapic_ipi)
160IDTVEC_END(intr_lapic_ipi)
161	TEXT_USER_END
162
163#if defined(DDB)
164IDTVEC(handle_ddbipi)
165	movl	$0xf,%eax
166	movq	%rax,%cr8
167	movq	_C_LABEL(local_apic_va),%rbx
168	movl	$0,LAPIC_EOI(%rbx)
169	sti
170	call	_C_LABEL(ddb_ipi)
171	xorl	%eax,%eax
172	movq	%rax,%cr8
173	INTRFASTEXIT
174IDTVEC_END(handle_ddbipi)
175IDTVEC(handle_x2apic_ddbipi)
176	movl	$0xf,%eax
177	movq	%rax,%cr8
178	movl	$(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
179	xorl	%eax,%eax
180	xorl	%edx,%edx
181	wrmsr
182	sti
183	call	_C_LABEL(ddb_ipi)
184	xorl	%eax,%eax
185	movq	%rax,%cr8
186	INTRFASTEXIT
187IDTVEC_END(handle_x2apic_ddbipi)
188
189	TEXT_USER_BEGIN
190IDTVEC(intr_ddbipi)
191	pushq	$0
192	pushq	$T_BPTFLT
193	INTRENTRY
194	jmp	_C_LABEL(Xhandle_ddbipi)
195IDTVEC_END(intr_ddbipi)
196IDTVEC(intr_x2apic_ddbipi)
197	pushq	$0
198	pushq	$T_BPTFLT
199	INTRENTRY
200	jmp	_C_LABEL(Xhandle_x2apic_ddbipi)
201IDTVEC_END(intr_x2apic_ddbipi)
202	TEXT_USER_END
203
204#endif /* DDB */
205#endif /* MULTIPROCESSOR */
206
207	/*
208	 * Interrupt from the local APIC timer.
209	 */
210IDTVEC(recurse_lapic_ltimer)
211	INTR_RECURSE_HWFRAME
212	pushq	$0
213	pushq	$T_ASTFLT
214	INTR_RECURSE_ENTRY
215	jmp	1f
216IDTVEC_END(recurse_lapic_ltimer)
217IDTVEC(handle_x2apic_ltimer)
218	movl	$(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
219	xorl	%eax,%eax
220	xorl	%edx,%edx
221	wrmsr
222	movl	CPUVAR(ILEVEL),%ebx
223	cmpl	$IPL_CLOCK,%ebx
224	jae	2f
225	jmp	1f
226IDTVEC_END(handle_x2apic_ltimer)
227IDTVEC(handle_lapic_ltimer)
228	movq	_C_LABEL(local_apic_va),%rbx
229	movl	$0,LAPIC_EOI(%rbx)
230	movl	CPUVAR(ILEVEL),%ebx
231	cmpl	$IPL_CLOCK,%ebx
232	jae	2f
233	jmp	1f
234IDTVEC_END(handle_lapic_ltimer)
235IDTVEC(resume_lapic_ltimer)
2361:
237	incl	CPUVAR(IDEPTH)
238	movl	$IPL_CLOCK,CPUVAR(ILEVEL)
239	sti
240	pushq	%rbx
241	movq	%rsp,%rsi
242	xorq	%rdi,%rdi
243	call	_C_LABEL(lapic_clockintr)
244	jmp	_C_LABEL(Xdoreti)
2452:
246	orl	$(1 << LIR_TIMER),CPUVAR(IPENDING)
247	INTRFASTEXIT
248IDTVEC_END(resume_lapic_ltimer)
249
250	TEXT_USER_BEGIN
251IDTVEC(intr_x2apic_ltimer)
252	pushq	$0
253	pushq	$T_ASTFLT
254	INTRENTRY
255	jmp	_C_LABEL(Xhandle_x2apic_ltimer)
256IDTVEC_END(intr_x2apic_ltimer)
257IDTVEC(intr_lapic_ltimer)
258	pushq	$0
259	pushq	$T_ASTFLT
260	INTRENTRY
261	jmp	_C_LABEL(Xhandle_lapic_ltimer)
262IDTVEC_END(intr_lapic_ltimer)
263	TEXT_USER_END
264
265#endif /* NLAPIC > 0 */
266
267#ifndef XENPV
268/*
269 * TLB shootdown handler.
270 */
271IDTVEC(handle_lapic_tlb)
272	movq	_C_LABEL(local_apic_va),%rax
273	movl	$0,LAPIC_EOI(%rax)
274	callq	_C_LABEL(pmap_tlb_intr)
275	INTRFASTEXIT
276IDTVEC_END(handle_lapic_tlb)
277IDTVEC(handle_x2apic_tlb)
278	movl	$(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
279	xorl	%eax,%eax
280	xorl	%edx,%edx
281	wrmsr
282	callq	_C_LABEL(pmap_tlb_intr)
283	INTRFASTEXIT
284IDTVEC_END(handle_x2apic_tlb)
285
286	TEXT_USER_BEGIN
287IDTVEC(intr_lapic_tlb)
288	pushq	$0
289	pushq	$T_ASTFLT
290	INTRENTRY
291	jmp	_C_LABEL(Xhandle_lapic_tlb)
292IDTVEC_END(intr_lapic_tlb)
293IDTVEC(intr_x2apic_tlb)
294	pushq	$0
295	pushq	$T_ASTFLT
296	INTRENTRY
297	jmp	_C_LABEL(Xhandle_x2apic_tlb)
298IDTVEC_END(intr_x2apic_tlb)
299	TEXT_USER_END
300
301#endif /* !XENPV */
302
303#define voidop(num)
304
305#ifndef XENPV
306
307/*
308 * This macro defines the generic stub code. Its arguments modify it
309 * for specific PICs.
310 */
311
312#define	INTRSTUB(name, num, early_ack, late_ack, mask, unmask, level_mask) \
313IDTVEC(recurse_ ## name ## num)						;\
314	INTR_RECURSE_HWFRAME						;\
315	subq	$8,%rsp							;\
316	pushq	$T_ASTFLT		/* trap # for doing ASTs */	;\
317	INTR_RECURSE_ENTRY						;\
318	jmp	1f							;\
319IDTVEC_END(recurse_ ## name ## num)					;\
320IDTVEC(resume_ ## name ## num)						\
3211:	movq	$IREENT_MAGIC,TF_ERR(%rsp)				;\
322	movl	%ebx,%r13d						;\
323	movq	CPUVAR(ISOURCES) + (num) * 8,%r14			;\
324	movl	IS_MAXLEVEL(%r14),%ebx					;\
325	jmp	1f							;\
326IDTVEC_END(resume_ ## name ## num)					;\
327IDTVEC(handle_ ## name ## num)						;\
328	movq	CPUVAR(ISOURCES) + (num) * 8,%r14			;\
329	mask(num)			/* mask it in hardware */	;\
330	early_ack(num)			/* and allow other intrs */	;\
331	testq	%r14,%r14						;\
332	jz	9f			/* stray */			;\
333	movl	IS_MAXLEVEL(%r14),%ebx					;\
334	movl	CPUVAR(ILEVEL),%r13d					;\
335	cmpl	%ebx,%r13d						;\
336	jae	10f			/* currently masked; hold it */	;\
337	incq	CPUVAR(NINTR)		/* statistical info */		;\
338	incq	IS_EVCNT(%r14)						;\
3391:									\
340	pushq	%r13			/* save for Xdoreti */		;\
341	movl	%ebx,CPUVAR(ILEVEL)					;\
342	sti								;\
343	incl	CPUVAR(IDEPTH)						;\
344	movq	IS_HANDLERS(%r14),%rbx					;\
3456:									\
346	movl	IH_LEVEL(%rbx),%r12d					;\
347	cmpl	%r13d,%r12d						;\
348	jle	7f							;\
349	movq	%rsp,%rsi						;\
350	movq	IH_ARG(%rbx),%rdi					;\
351	movl	%r12d,CPUVAR(ILEVEL)					;\
352	call	*IH_FUN(%rbx)		/* call it */			;\
353	movq	IH_NEXT(%rbx),%rbx	/* next handler in chain */	;\
354	testq	%rbx,%rbx						;\
355	jnz	6b							;\
3565:									\
357	cli								;\
358	unmask(num)			/* unmask it in hardware */	;\
359	late_ack(num)							;\
360	sti								;\
361	jmp	_C_LABEL(Xdoreti)	/* lower spl and do ASTs */	;\
3627:									\
363	cli								;\
364	orl	$(1 << num),CPUVAR(IPENDING)				;\
365	level_mask(num)							;\
366	late_ack(num)							;\
367	sti								;\
368	jmp	_C_LABEL(Xdoreti)	/* lower spl and do ASTs */	;\
36910:									\
370	cli								;\
371	orl	$(1 << num),CPUVAR(IPENDING)				;\
372	level_mask(num)							;\
373	late_ack(num)							;\
374	INTRFASTEXIT							;\
3759:									\
376	unmask(num)							;\
377	late_ack(num)							;\
378	INTRFASTEXIT							;\
379IDTVEC_END(handle_ ## name ## num)					;\
380	TEXT_USER_BEGIN							;\
381IDTVEC(intr_ ## name ## num)						;\
382	pushq	$0			/* dummy error code */		;\
383	pushq	$T_ASTFLT		/* trap # for doing ASTs */	;\
384	INTRENTRY							;\
385	jmp	_C_LABEL(Xhandle_ ## name ## num)			;\
386IDTVEC_END(intr_ ## name ## num)					;\
387	TEXT_USER_END
388
389#define ICUADDR IO_ICU1
390
391INTRSTUB(legacy,0,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
392    voidop)
393INTRSTUB(legacy,1,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
394    voidop)
395INTRSTUB(legacy,2,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
396    voidop)
397INTRSTUB(legacy,3,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
398    voidop)
399INTRSTUB(legacy,4,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
400    voidop)
401INTRSTUB(legacy,5,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
402    voidop)
403INTRSTUB(legacy,6,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
404    voidop)
405INTRSTUB(legacy,7,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
406    voidop)
407#undef ICUADDR
408#define ICUADDR IO_ICU2
409
410INTRSTUB(legacy,8,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
411    voidop)
412INTRSTUB(legacy,9,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
413    voidop)
414INTRSTUB(legacy,10,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
415    voidop)
416INTRSTUB(legacy,11,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
417    voidop)
418INTRSTUB(legacy,12,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
419    voidop)
420INTRSTUB(legacy,13,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
421    voidop)
422INTRSTUB(legacy,14,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
423    voidop)
424INTRSTUB(legacy,15,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
425    voidop)
426
427#if NIOAPIC > 0
428
429INTRSTUB(ioapic_edge,0,voidop,ioapic_asm_ack,voidop,voidop,voidop)
430INTRSTUB(ioapic_edge,1,voidop,ioapic_asm_ack,voidop,voidop,voidop)
431INTRSTUB(ioapic_edge,2,voidop,ioapic_asm_ack,voidop,voidop,voidop)
432INTRSTUB(ioapic_edge,3,voidop,ioapic_asm_ack,voidop,voidop,voidop)
433INTRSTUB(ioapic_edge,4,voidop,ioapic_asm_ack,voidop,voidop,voidop)
434INTRSTUB(ioapic_edge,5,voidop,ioapic_asm_ack,voidop,voidop,voidop)
435INTRSTUB(ioapic_edge,6,voidop,ioapic_asm_ack,voidop,voidop,voidop)
436INTRSTUB(ioapic_edge,7,voidop,ioapic_asm_ack,voidop,voidop,voidop)
437INTRSTUB(ioapic_edge,8,voidop,ioapic_asm_ack,voidop,voidop,voidop)
438INTRSTUB(ioapic_edge,9,voidop,ioapic_asm_ack,voidop,voidop,voidop)
439INTRSTUB(ioapic_edge,10,voidop,ioapic_asm_ack,voidop,voidop,voidop)
440INTRSTUB(ioapic_edge,11,voidop,ioapic_asm_ack,voidop,voidop,voidop)
441INTRSTUB(ioapic_edge,12,voidop,ioapic_asm_ack,voidop,voidop,voidop)
442INTRSTUB(ioapic_edge,13,voidop,ioapic_asm_ack,voidop,voidop,voidop)
443INTRSTUB(ioapic_edge,14,voidop,ioapic_asm_ack,voidop,voidop,voidop)
444INTRSTUB(ioapic_edge,15,voidop,ioapic_asm_ack,voidop,voidop,voidop)
445INTRSTUB(ioapic_edge,16,voidop,ioapic_asm_ack,voidop,voidop,voidop)
446INTRSTUB(ioapic_edge,17,voidop,ioapic_asm_ack,voidop,voidop,voidop)
447INTRSTUB(ioapic_edge,18,voidop,ioapic_asm_ack,voidop,voidop,voidop)
448INTRSTUB(ioapic_edge,19,voidop,ioapic_asm_ack,voidop,voidop,voidop)
449INTRSTUB(ioapic_edge,20,voidop,ioapic_asm_ack,voidop,voidop,voidop)
450INTRSTUB(ioapic_edge,21,voidop,ioapic_asm_ack,voidop,voidop,voidop)
451INTRSTUB(ioapic_edge,22,voidop,ioapic_asm_ack,voidop,voidop,voidop)
452INTRSTUB(ioapic_edge,23,voidop,ioapic_asm_ack,voidop,voidop,voidop)
453INTRSTUB(ioapic_edge,24,voidop,ioapic_asm_ack,voidop,voidop,voidop)
454INTRSTUB(ioapic_edge,25,voidop,ioapic_asm_ack,voidop,voidop,voidop)
455INTRSTUB(ioapic_edge,26,voidop,ioapic_asm_ack,voidop,voidop,voidop)
456INTRSTUB(ioapic_edge,27,voidop,ioapic_asm_ack,voidop,voidop,voidop)
457INTRSTUB(ioapic_edge,28,voidop,ioapic_asm_ack,voidop,voidop,voidop)
458INTRSTUB(ioapic_edge,29,voidop,ioapic_asm_ack,voidop,voidop,voidop)
459INTRSTUB(ioapic_edge,30,voidop,ioapic_asm_ack,voidop,voidop,voidop)
460INTRSTUB(ioapic_edge,31,voidop,ioapic_asm_ack,voidop,voidop,voidop)
461
462INTRSTUB(ioapic_level,0,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
463INTRSTUB(ioapic_level,1,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
464INTRSTUB(ioapic_level,2,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
465INTRSTUB(ioapic_level,3,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
466INTRSTUB(ioapic_level,4,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
467INTRSTUB(ioapic_level,5,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
468INTRSTUB(ioapic_level,6,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
469INTRSTUB(ioapic_level,7,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
470INTRSTUB(ioapic_level,8,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
471INTRSTUB(ioapic_level,9,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
472INTRSTUB(ioapic_level,10,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
473INTRSTUB(ioapic_level,11,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
474INTRSTUB(ioapic_level,12,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
475INTRSTUB(ioapic_level,13,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
476INTRSTUB(ioapic_level,14,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
477INTRSTUB(ioapic_level,15,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
478INTRSTUB(ioapic_level,16,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
479INTRSTUB(ioapic_level,17,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
480INTRSTUB(ioapic_level,18,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
481INTRSTUB(ioapic_level,19,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
482INTRSTUB(ioapic_level,20,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
483INTRSTUB(ioapic_level,21,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
484INTRSTUB(ioapic_level,22,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
485INTRSTUB(ioapic_level,23,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
486INTRSTUB(ioapic_level,24,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
487INTRSTUB(ioapic_level,25,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
488INTRSTUB(ioapic_level,26,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
489INTRSTUB(ioapic_level,27,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
490INTRSTUB(ioapic_level,28,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
491INTRSTUB(ioapic_level,29,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
492INTRSTUB(ioapic_level,30,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
493INTRSTUB(ioapic_level,31,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
494
495INTRSTUB(x2apic_edge,0,voidop,x2apic_asm_ack,voidop,voidop,voidop)
496INTRSTUB(x2apic_edge,1,voidop,x2apic_asm_ack,voidop,voidop,voidop)
497INTRSTUB(x2apic_edge,2,voidop,x2apic_asm_ack,voidop,voidop,voidop)
498INTRSTUB(x2apic_edge,3,voidop,x2apic_asm_ack,voidop,voidop,voidop)
499INTRSTUB(x2apic_edge,4,voidop,x2apic_asm_ack,voidop,voidop,voidop)
500INTRSTUB(x2apic_edge,5,voidop,x2apic_asm_ack,voidop,voidop,voidop)
501INTRSTUB(x2apic_edge,6,voidop,x2apic_asm_ack,voidop,voidop,voidop)
502INTRSTUB(x2apic_edge,7,voidop,x2apic_asm_ack,voidop,voidop,voidop)
503INTRSTUB(x2apic_edge,8,voidop,x2apic_asm_ack,voidop,voidop,voidop)
504INTRSTUB(x2apic_edge,9,voidop,x2apic_asm_ack,voidop,voidop,voidop)
505INTRSTUB(x2apic_edge,10,voidop,x2apic_asm_ack,voidop,voidop,voidop)
506INTRSTUB(x2apic_edge,11,voidop,x2apic_asm_ack,voidop,voidop,voidop)
507INTRSTUB(x2apic_edge,12,voidop,x2apic_asm_ack,voidop,voidop,voidop)
508INTRSTUB(x2apic_edge,13,voidop,x2apic_asm_ack,voidop,voidop,voidop)
509INTRSTUB(x2apic_edge,14,voidop,x2apic_asm_ack,voidop,voidop,voidop)
510INTRSTUB(x2apic_edge,15,voidop,x2apic_asm_ack,voidop,voidop,voidop)
511INTRSTUB(x2apic_edge,16,voidop,x2apic_asm_ack,voidop,voidop,voidop)
512INTRSTUB(x2apic_edge,17,voidop,x2apic_asm_ack,voidop,voidop,voidop)
513INTRSTUB(x2apic_edge,18,voidop,x2apic_asm_ack,voidop,voidop,voidop)
514INTRSTUB(x2apic_edge,19,voidop,x2apic_asm_ack,voidop,voidop,voidop)
515INTRSTUB(x2apic_edge,20,voidop,x2apic_asm_ack,voidop,voidop,voidop)
516INTRSTUB(x2apic_edge,21,voidop,x2apic_asm_ack,voidop,voidop,voidop)
517INTRSTUB(x2apic_edge,22,voidop,x2apic_asm_ack,voidop,voidop,voidop)
518INTRSTUB(x2apic_edge,23,voidop,x2apic_asm_ack,voidop,voidop,voidop)
519INTRSTUB(x2apic_edge,24,voidop,x2apic_asm_ack,voidop,voidop,voidop)
520INTRSTUB(x2apic_edge,25,voidop,x2apic_asm_ack,voidop,voidop,voidop)
521INTRSTUB(x2apic_edge,26,voidop,x2apic_asm_ack,voidop,voidop,voidop)
522INTRSTUB(x2apic_edge,27,voidop,x2apic_asm_ack,voidop,voidop,voidop)
523INTRSTUB(x2apic_edge,28,voidop,x2apic_asm_ack,voidop,voidop,voidop)
524INTRSTUB(x2apic_edge,29,voidop,x2apic_asm_ack,voidop,voidop,voidop)
525INTRSTUB(x2apic_edge,30,voidop,x2apic_asm_ack,voidop,voidop,voidop)
526INTRSTUB(x2apic_edge,31,voidop,x2apic_asm_ack,voidop,voidop,voidop)
527
528INTRSTUB(x2apic_level,0,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
529INTRSTUB(x2apic_level,1,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
530INTRSTUB(x2apic_level,2,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
531INTRSTUB(x2apic_level,3,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
532INTRSTUB(x2apic_level,4,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
533INTRSTUB(x2apic_level,5,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
534INTRSTUB(x2apic_level,6,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
535INTRSTUB(x2apic_level,7,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
536INTRSTUB(x2apic_level,8,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
537INTRSTUB(x2apic_level,9,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
538INTRSTUB(x2apic_level,10,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
539INTRSTUB(x2apic_level,11,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
540INTRSTUB(x2apic_level,12,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
541INTRSTUB(x2apic_level,13,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
542INTRSTUB(x2apic_level,14,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
543INTRSTUB(x2apic_level,15,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
544INTRSTUB(x2apic_level,16,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
545INTRSTUB(x2apic_level,17,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
546INTRSTUB(x2apic_level,18,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
547INTRSTUB(x2apic_level,19,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
548INTRSTUB(x2apic_level,20,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
549INTRSTUB(x2apic_level,21,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
550INTRSTUB(x2apic_level,22,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
551INTRSTUB(x2apic_level,23,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
552INTRSTUB(x2apic_level,24,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
553INTRSTUB(x2apic_level,25,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
554INTRSTUB(x2apic_level,26,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
555INTRSTUB(x2apic_level,27,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
556INTRSTUB(x2apic_level,28,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
557INTRSTUB(x2apic_level,29,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
558INTRSTUB(x2apic_level,30,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
559INTRSTUB(x2apic_level,31,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
560
561#endif
562
563/*
564 * Create a struct intrstub.
565 */
566#define INTRSTUB_ENTRY(name) \
567	.quad _C_LABEL(Xintr_ ## name ), _C_LABEL(Xrecurse_ ## name ) ; \
568	.quad _C_LABEL(Xresume_ ## name ) ;
569
570/*
571 * Create an array of structs intrstub (16 entries).
572 */
573#define INTRSTUB_ARRAY_16(name) 		; \
574	.type _C_LABEL(name ## _stubs), @object	; \
575LABEL(name ## _stubs)				; \
576	INTRSTUB_ENTRY(name ## 0)		; \
577	INTRSTUB_ENTRY(name ## 1)		; \
578	INTRSTUB_ENTRY(name ## 2)		; \
579	INTRSTUB_ENTRY(name ## 3)		; \
580	INTRSTUB_ENTRY(name ## 4)		; \
581	INTRSTUB_ENTRY(name ## 5)		; \
582	INTRSTUB_ENTRY(name ## 6)		; \
583	INTRSTUB_ENTRY(name ## 7)		; \
584	INTRSTUB_ENTRY(name ## 8)		; \
585	INTRSTUB_ENTRY(name ## 9)		; \
586	INTRSTUB_ENTRY(name ## 10)		; \
587	INTRSTUB_ENTRY(name ## 11)		; \
588	INTRSTUB_ENTRY(name ## 12)		; \
589	INTRSTUB_ENTRY(name ## 13)		; \
590	INTRSTUB_ENTRY(name ## 14)		; \
591	INTRSTUB_ENTRY(name ## 15)		; \
592END(name ## _stubs)
593
594/*
595 * Create an array of structs intrstub (32 entries).
596 */
597#define INTRSTUB_ARRAY_32(name) 		; \
598	.type _C_LABEL(name ## _stubs), @object	; \
599LABEL(name ## _stubs)				; \
600	INTRSTUB_ENTRY(name ## 0)		; \
601	INTRSTUB_ENTRY(name ## 1)		; \
602	INTRSTUB_ENTRY(name ## 2)		; \
603	INTRSTUB_ENTRY(name ## 3)		; \
604	INTRSTUB_ENTRY(name ## 4)		; \
605	INTRSTUB_ENTRY(name ## 5)		; \
606	INTRSTUB_ENTRY(name ## 6)		; \
607	INTRSTUB_ENTRY(name ## 7)		; \
608	INTRSTUB_ENTRY(name ## 8)		; \
609	INTRSTUB_ENTRY(name ## 9)		; \
610	INTRSTUB_ENTRY(name ## 10)		; \
611	INTRSTUB_ENTRY(name ## 11)		; \
612	INTRSTUB_ENTRY(name ## 12)		; \
613	INTRSTUB_ENTRY(name ## 13)		; \
614	INTRSTUB_ENTRY(name ## 14)		; \
615	INTRSTUB_ENTRY(name ## 15)		; \
616	INTRSTUB_ENTRY(name ## 16)		; \
617	INTRSTUB_ENTRY(name ## 17)		; \
618	INTRSTUB_ENTRY(name ## 18)		; \
619	INTRSTUB_ENTRY(name ## 19)		; \
620	INTRSTUB_ENTRY(name ## 20)		; \
621	INTRSTUB_ENTRY(name ## 21)		; \
622	INTRSTUB_ENTRY(name ## 22)		; \
623	INTRSTUB_ENTRY(name ## 23)		; \
624	INTRSTUB_ENTRY(name ## 24)		; \
625	INTRSTUB_ENTRY(name ## 25)		; \
626	INTRSTUB_ENTRY(name ## 26)		; \
627	INTRSTUB_ENTRY(name ## 27)		; \
628	INTRSTUB_ENTRY(name ## 28)		; \
629	INTRSTUB_ENTRY(name ## 29)		; \
630	INTRSTUB_ENTRY(name ## 30)		; \
631	INTRSTUB_ENTRY(name ## 31)		; \
632END(name ## _stubs)
633
634	.section .rodata
635
636INTRSTUB_ARRAY_16(legacy)
637
638#if NIOAPIC > 0
639INTRSTUB_ARRAY_32(ioapic_edge)
640INTRSTUB_ARRAY_32(ioapic_level)
641
642INTRSTUB_ARRAY_32(x2apic_edge)
643INTRSTUB_ARRAY_32(x2apic_level)
644#endif
645
646#endif /* !defined(XENPV) */
647
648#if defined(XEN)
649/* Resume/recurse procedures for spl() */
650#define	XENINTRSTUB(name, num, early_ack, late_ack, mask, unmask, level_mask) \
651IDTVEC(recurse_ ## name ## num)						;\
652	INTR_RECURSE_HWFRAME						;\
653	subq	$8,%rsp							;\
654	pushq	$T_ASTFLT		/* trap # for doing ASTs */	;\
655	INTR_RECURSE_ENTRY						;\
656IDTVEC(resume_ ## name ## num)						\
657	movq	$IREENT_MAGIC,TF_ERR(%rsp)				;\
658	movl	%ebx,%r13d						;\
659	movq	CPUVAR(XSOURCES) + (num) * 8,%r14			;\
6601:									\
661	pushq	%r13							;\
662	movl	$num,CPUVAR(ILEVEL)					;\
663	STI(si)								;\
664	incl	CPUVAR(IDEPTH)						;\
665	movq	IS_HANDLERS(%r14),%rbx					;\
6666:									\
667	movq	IH_ARG(%rbx),%rdi					;\
668	movq	%rsp,%rsi						;\
669	call	*IH_FUN(%rbx)		/* call it */			;\
670	movq	IH_NEXT(%rbx),%rbx	/* next handler in chain */	;\
671	testq	%rbx,%rbx						;\
672	jnz	6b							;\
6735:									\
674	CLI(si)								;\
675	unmask(num)			/* unmask it in hardware */	;\
676	late_ack(num)							;\
677	STI(si)								;\
678	jmp	_C_LABEL(Xdoreti)	/* lower spl and do ASTs */	;\
679
680/* The unmask func for Xen events */
681#define hypervisor_asm_unmask(num)			\
682	movq	$num,%rdi				;\
683	call	_C_LABEL(hypervisor_enable_ipl)
684
685XENINTRSTUB(xenev,0,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
686XENINTRSTUB(xenev,1,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
687XENINTRSTUB(xenev,2,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
688XENINTRSTUB(xenev,3,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
689XENINTRSTUB(xenev,4,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
690XENINTRSTUB(xenev,5,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
691XENINTRSTUB(xenev,6,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
692XENINTRSTUB(xenev,7,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
693XENINTRSTUB(xenev,8,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
694XENINTRSTUB(xenev,9,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
695XENINTRSTUB(xenev,10,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
696XENINTRSTUB(xenev,11,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
697XENINTRSTUB(xenev,12,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
698XENINTRSTUB(xenev,13,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
699XENINTRSTUB(xenev,14,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
700XENINTRSTUB(xenev,15,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
701XENINTRSTUB(xenev,16,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
702XENINTRSTUB(xenev,17,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
703XENINTRSTUB(xenev,18,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
704XENINTRSTUB(xenev,19,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
705XENINTRSTUB(xenev,20,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
706XENINTRSTUB(xenev,21,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
707XENINTRSTUB(xenev,22,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
708XENINTRSTUB(xenev,23,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
709XENINTRSTUB(xenev,24,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
710XENINTRSTUB(xenev,25,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
711XENINTRSTUB(xenev,26,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
712XENINTRSTUB(xenev,27,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
713XENINTRSTUB(xenev,28,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
714XENINTRSTUB(xenev,29,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
715XENINTRSTUB(xenev,30,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
716XENINTRSTUB(xenev,31,voidop,voidop,voidop,hypervisor_asm_unmask,voidop)
717
718LABEL(xenev_stubs)
719	.quad _C_LABEL(Xrecurse_xenev0), _C_LABEL(Xresume_xenev0)
720	.quad _C_LABEL(Xrecurse_xenev1) ,_C_LABEL(Xresume_xenev1)
721	.quad _C_LABEL(Xrecurse_xenev2) ,_C_LABEL(Xresume_xenev2)
722	.quad _C_LABEL(Xrecurse_xenev3) ,_C_LABEL(Xresume_xenev3)
723	.quad _C_LABEL(Xrecurse_xenev4) ,_C_LABEL(Xresume_xenev4)
724	.quad _C_LABEL(Xrecurse_xenev5) ,_C_LABEL(Xresume_xenev5)
725	.quad _C_LABEL(Xrecurse_xenev6) ,_C_LABEL(Xresume_xenev6)
726	.quad _C_LABEL(Xrecurse_xenev7) ,_C_LABEL(Xresume_xenev7)
727	.quad _C_LABEL(Xrecurse_xenev8) ,_C_LABEL(Xresume_xenev8)
728	.quad _C_LABEL(Xrecurse_xenev9) ,_C_LABEL(Xresume_xenev9)
729	.quad _C_LABEL(Xrecurse_xenev10), _C_LABEL(Xresume_xenev10)
730	.quad _C_LABEL(Xrecurse_xenev11), _C_LABEL(Xresume_xenev11)
731	.quad _C_LABEL(Xrecurse_xenev12), _C_LABEL(Xresume_xenev12)
732	.quad _C_LABEL(Xrecurse_xenev13), _C_LABEL(Xresume_xenev13)
733	.quad _C_LABEL(Xrecurse_xenev14), _C_LABEL(Xresume_xenev14)
734	.quad _C_LABEL(Xrecurse_xenev15), _C_LABEL(Xresume_xenev15)
735	.quad _C_LABEL(Xrecurse_xenev16), _C_LABEL(Xresume_xenev16)
736	.quad _C_LABEL(Xrecurse_xenev17), _C_LABEL(Xresume_xenev17)
737	.quad _C_LABEL(Xrecurse_xenev18), _C_LABEL(Xresume_xenev18)
738	.quad _C_LABEL(Xrecurse_xenev19), _C_LABEL(Xresume_xenev19)
739	.quad _C_LABEL(Xrecurse_xenev20), _C_LABEL(Xresume_xenev20)
740	.quad _C_LABEL(Xrecurse_xenev21), _C_LABEL(Xresume_xenev21)
741	.quad _C_LABEL(Xrecurse_xenev22), _C_LABEL(Xresume_xenev22)
742	.quad _C_LABEL(Xrecurse_xenev23), _C_LABEL(Xresume_xenev23)
743	.quad _C_LABEL(Xrecurse_xenev24), _C_LABEL(Xresume_xenev24)
744	.quad _C_LABEL(Xrecurse_xenev25), _C_LABEL(Xresume_xenev25)
745	.quad _C_LABEL(Xrecurse_xenev26), _C_LABEL(Xresume_xenev26)
746	.quad _C_LABEL(Xrecurse_xenev27), _C_LABEL(Xresume_xenev27)
747	.quad _C_LABEL(Xrecurse_xenev28), _C_LABEL(Xresume_xenev28)
748	.quad _C_LABEL(Xrecurse_xenev29), _C_LABEL(Xresume_xenev29)
749	.quad _C_LABEL(Xrecurse_xenev30), _C_LABEL(Xresume_xenev30)
750	.quad _C_LABEL(Xrecurse_xenev31), _C_LABEL(Xresume_xenev31)
751END(xenev_stubs)
752
753/*
754 * Xen callbacks
755 */
756
757/* Hypervisor callback */
758ENTRY(hypervisor_callback)
759	movq	(%rsp),%rcx
760	movq	8(%rsp),%r11
761	addq	$16,%rsp
762	pushq	$0		/* Dummy error code */
763	pushq	$T_ASTFLT
764	INTRENTRY
765	/* sti?? */
766	movq	%rsp,%rdi
767	subq	$8,%rdi;	/* don't forget if_ppl */
768	call	do_hypervisor_callback
769	testb	$SEL_RPL,TF_CS(%rsp)
770	jnz	doreti_checkast
7711:
772	INTRFASTEXIT
773END(hypervisor_callback)
774
775/* Panic? */
776ENTRY(failsafe_callback)
777	movq	(%rsp),%rcx
778	movq	8(%rsp),%r11
779	addq	$16,%rsp
780	pushq	$0
781	pushq	$T_ASTFLT
782	INTRENTRY
783	movq	%rsp,%rdi
784	subq	$8,%rdi;	/* don't forget if_ppl */
785	call	xen_failsafe_handler
786	INTRFASTEXIT
787/*	jmp	HYPERVISOR_iret */
788END(failsafe_callback)
789
790#endif	/* !XEN */
791