#include <machine/asm.h>
#include "opt_ddb.h"
#include "opt_multiprocessor.h"
#include "opt_xen.h"
#include "opt_dtrace.h"
#define ALIGN_TEXT .align 16,0x90
#include <machine/i8259.h>
#include <machine/i82093reg.h>
#include <machine/i82489reg.h>
#include <machine/frameasm.h>
#include <machine/segments.h>
#include <machine/trap.h>
#include <machine/specialreg.h>
#include "ioapic.h"
#include "lapic.h"
#include "assym.h"
#ifndef XENPV
#include "hyperv.h"
#endif
.text
#ifndef XENPV
#if NLAPIC > 0
#ifdef MULTIPROCESSOR
IDTVEC(recurse_lapic_ipi)
INTR_RECURSE_HWFRAME
pushq $0
pushq $T_ASTFLT
INTR_RECURSE_ENTRY
jmp 1f
IDTVEC_END(recurse_lapic_ipi)
IDTVEC(handle_x2apic_ipi)
movl $(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
xorl %eax,%eax
xorl %edx,%edx
wrmsr
movzbl CPUVAR(ILEVEL),%ebx
cmpl $IPL_HIGH,%ebx
jae 2f
jmp 1f
IDTVEC_END(handle_x2apic_ipi)
IDTVEC(handle_lapic_ipi)
movq _C_LABEL(local_apic_va),%rbx
movl $0,LAPIC_EOI(%rbx)
movzbl CPUVAR(ILEVEL),%ebx
cmpl $IPL_HIGH,%ebx
jae 2f
jmp 1f
IDTVEC_END(handle_lapic_ipi)
IDTVEC(resume_lapic_ipi)
1:
incl CPUVAR(IDEPTH)
movb $IPL_HIGH,CPUVAR(ILEVEL)
sti
pushq %rbx
call _C_LABEL(x86_ipi_handler)
jmp _C_LABEL(Xdoreti)
2:
btsq $LIR_IPI,CPUVAR(IPENDING)
INTRFASTEXIT
IDTVEC_END(resume_lapic_ipi)
TEXT_USER_BEGIN
IDTVEC(intr_x2apic_ipi)
pushq $0
pushq $T_ASTFLT
INTRENTRY
jmp _C_LABEL(Xhandle_x2apic_ipi)
IDTVEC_END(intr_x2apic_ipi)
IDTVEC(intr_lapic_ipi)
pushq $0
pushq $T_ASTFLT
INTRENTRY
jmp _C_LABEL(Xhandle_lapic_ipi)
IDTVEC_END(intr_lapic_ipi)
TEXT_USER_END
#if defined(DDB)
IDTVEC(handle_ddbipi)
movl $0xf,%eax
movq %rax,%cr8
movq _C_LABEL(local_apic_va),%rbx
movl $0,LAPIC_EOI(%rbx)
sti
call _C_LABEL(ddb_ipi)
xorl %eax,%eax
movq %rax,%cr8
INTRFASTEXIT
IDTVEC_END(handle_ddbipi)
IDTVEC(handle_x2apic_ddbipi)
movl $0xf,%eax
movq %rax,%cr8
movl $(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
xorl %eax,%eax
xorl %edx,%edx
wrmsr
sti
call _C_LABEL(ddb_ipi)
xorl %eax,%eax
movq %rax,%cr8
INTRFASTEXIT
IDTVEC_END(handle_x2apic_ddbipi)
TEXT_USER_BEGIN
IDTVEC(intr_ddbipi)
pushq $0
pushq $T_BPTFLT
INTRENTRY
jmp _C_LABEL(Xhandle_ddbipi)
IDTVEC_END(intr_ddbipi)
IDTVEC(intr_x2apic_ddbipi)
pushq $0
pushq $T_BPTFLT
INTRENTRY
jmp _C_LABEL(Xhandle_x2apic_ddbipi)
IDTVEC_END(intr_x2apic_ddbipi)
TEXT_USER_END
#endif
#endif
IDTVEC(recurse_lapic_ltimer)
INTR_RECURSE_HWFRAME
pushq $0
pushq $T_ASTFLT
INTR_RECURSE_ENTRY
jmp 1f
IDTVEC_END(recurse_lapic_ltimer)
IDTVEC(handle_x2apic_ltimer)
movl $(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
xorl %eax,%eax
xorl %edx,%edx
wrmsr
movzbl CPUVAR(ILEVEL),%ebx
cmpl $IPL_CLOCK,%ebx
jae 2f
jmp 1f
IDTVEC_END(handle_x2apic_ltimer)
IDTVEC(handle_lapic_ltimer)
movq _C_LABEL(local_apic_va),%rbx
movl $0,LAPIC_EOI(%rbx)
movzbl CPUVAR(ILEVEL),%ebx
cmpl $IPL_CLOCK,%ebx
jae 2f
jmp 1f
IDTVEC_END(handle_lapic_ltimer)
IDTVEC(resume_lapic_ltimer)
1:
incl CPUVAR(IDEPTH)
movb $IPL_CLOCK,CPUVAR(ILEVEL)
sti
pushq %rbx
movq %rsp,%rsi
xorq %rdi,%rdi
call _C_LABEL(lapic_clockintr)
jmp _C_LABEL(Xdoreti)
2:
btsq $LIR_TIMER,CPUVAR(IPENDING)
INTRFASTEXIT
IDTVEC_END(resume_lapic_ltimer)
TEXT_USER_BEGIN
IDTVEC(intr_x2apic_ltimer)
pushq $0
pushq $T_ASTFLT
INTRENTRY
jmp _C_LABEL(Xhandle_x2apic_ltimer)
IDTVEC_END(intr_x2apic_ltimer)
IDTVEC(intr_lapic_ltimer)
pushq $0
pushq $T_ASTFLT
INTRENTRY
jmp _C_LABEL(Xhandle_lapic_ltimer)
IDTVEC_END(intr_lapic_ltimer)
TEXT_USER_END
#if NHYPERV > 0
IDTVEC(recurse_hyperv_hypercall)
INTR_RECURSE_HWFRAME
pushq $0
pushq $T_ASTFLT
INTR_RECURSE_ENTRY
jmp 1f
IDTVEC_END(recurse_hyperv_hypercall)
IDTVEC(handle_hyperv_hypercall)
movzbl CPUVAR(ILEVEL),%ebx
cmpl $IPL_NET,%ebx
jae 2f
jmp 1f
IDTVEC_END(handle_hyperv_hypercall)
IDTVEC(resume_hyperv_hypercall)
1:
incl CPUVAR(IDEPTH)
movb $IPL_NET,CPUVAR(ILEVEL)
sti
pushq %rbx
movq %rsp,%rsi
call _C_LABEL(hyperv_hypercall_intr)
jmp _C_LABEL(Xdoreti)
2:
btsq $LIR_HV,CPUVAR(IPENDING)
INTRFASTEXIT
IDTVEC_END(resume_hyperv_hypercall)
TEXT_USER_BEGIN
IDTVEC(intr_hyperv_hypercall)
pushq $0
pushq $T_ASTFLT
INTRENTRY
jmp _C_LABEL(Xhandle_hyperv_hypercall)
IDTVEC_END(intr_hyperv_hypercall)
TEXT_USER_END
#endif
#endif
IDTVEC(handle_lapic_tlb)
KCOV_DISABLE
callq _C_LABEL(pmap_tlb_intr)
KCOV_ENABLE
movq _C_LABEL(local_apic_va),%rax
movl $0,LAPIC_EOI(%rax)
INTRFASTEXIT
IDTVEC_END(handle_lapic_tlb)
IDTVEC(handle_x2apic_tlb)
KCOV_DISABLE
callq _C_LABEL(pmap_tlb_intr)
KCOV_ENABLE
movl $(MSR_X2APIC_BASE + MSR_X2APIC_EOI),%ecx
xorl %eax,%eax
xorl %edx,%edx
wrmsr
INTRFASTEXIT
IDTVEC_END(handle_x2apic_tlb)
TEXT_USER_BEGIN
IDTVEC(intr_lapic_tlb)
pushq $0
pushq $T_ASTFLT
INTRENTRY
jmp _C_LABEL(Xhandle_lapic_tlb)
IDTVEC_END(intr_lapic_tlb)
IDTVEC(intr_x2apic_tlb)
pushq $0
pushq $T_ASTFLT
INTRENTRY
jmp _C_LABEL(Xhandle_x2apic_tlb)
IDTVEC_END(intr_x2apic_tlb)
TEXT_USER_END
#endif
#define voidop(num)
#ifndef XENPV
#define INTRSTUB(name, num, early_ack, late_ack, mask, unmask, level_mask) \
IDTVEC(recurse_ ## name ## num) ;\
INTR_RECURSE_HWFRAME ;\
subq $8,%rsp ;\
pushq $T_ASTFLT ;\
INTR_RECURSE_ENTRY ;\
jmp 1f ;\
IDTVEC_END(recurse_ ## name ## num) ;\
IDTVEC(resume_ ## name ## num) \
1: movq $IREENT_MAGIC,TF_ERR(%rsp) ;\
movl %ebx,%r13d ;\
movq CPUVAR(ISOURCES) + (num) * 8,%r14 ;\
movl IS_MAXLEVEL(%r14),%ebx ;\
jmp 1f ;\
IDTVEC_END(resume_ ## name ## num) ;\
IDTVEC(handle_ ## name ## num) ;\
movq CPUVAR(ISOURCES) + (num) * 8,%r14 ;\
mask(num) ;\
early_ack(num) ;\
testq %r14,%r14 ;\
jz 9f ;\
movl IS_MAXLEVEL(%r14),%ebx ;\
movzbl CPUVAR(ILEVEL),%r13d ;\
cmpl %ebx,%r13d ;\
jae 10f ;\
incq CPUVAR(NINTR) ;\
incq IS_EVCNT(%r14) ;\
1: \
pushq %r13 ;\
movb %bl,CPUVAR(ILEVEL) ;\
sti ;\
incl CPUVAR(IDEPTH) ;\
movq IS_HANDLERS(%r14),%rbx ;\
cmpl $0,IS_MASK_COUNT(%r14) ;\
jne 12f ;\
6: \
movl IH_LEVEL(%rbx),%r12d ;\
cmpl %r13d,%r12d ;\
jle 7f ;\
movq %rsp,%rsi ;\
movq IH_ARG(%rbx),%rdi ;\
movb %r12b,CPUVAR(ILEVEL) ;\
call *IH_FUN(%rbx) ;\
movq IH_NEXT(%rbx),%rbx ;\
testq %rbx,%rbx ;\
jnz 6b ;\
5: \
cmpl $0,IS_MASK_COUNT(%r14) ;\
jne 12f ;\
cli ;\
unmask(num) ;\
late_ack(num) ;\
sti ;\
jmp _C_LABEL(Xdoreti) ;\
7: \
cli ;\
btsq $num,CPUVAR(IPENDING) ;\
8: level_mask(num) ;\
late_ack(num) ;\
sti ;\
jmp _C_LABEL(Xdoreti) ;\
12: \
cli ;\
btsq $num,CPUVAR(IMASKED) ;\
btrq $(num),CPUVAR(IPENDING) ;\
jmp 8b ;\
10: \
cli ;\
btsq $num,CPUVAR(IPENDING) ;\
level_mask(num) ;\
late_ack(num) ;\
INTRFASTEXIT ;\
9: \
unmask(num) ;\
late_ack(num) ;\
INTRFASTEXIT ;\
IDTVEC_END(handle_ ## name ## num) ;\
TEXT_USER_BEGIN ;\
IDTVEC(intr_ ## name ## num) ;\
pushq $0 ;\
pushq $T_ASTFLT ;\
INTRENTRY ;\
jmp _C_LABEL(Xhandle_ ## name ## num) ;\
IDTVEC_END(intr_ ## name ## num) ;\
TEXT_USER_END
#define ICUADDR IO_ICU1
INTRSTUB(legacy,0,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,1,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,2,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,3,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,4,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,5,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,6,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,7,i8259_asm_ack1,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
#undef ICUADDR
#define ICUADDR IO_ICU2
INTRSTUB(legacy,8,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,9,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,10,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,11,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,12,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,13,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,14,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
INTRSTUB(legacy,15,i8259_asm_ack2,voidop,i8259_asm_mask,i8259_asm_unmask,
voidop)
#if NIOAPIC > 0
#define INTRSTUB_56(name,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,0,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,1,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,2,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,3,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,4,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,5,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,6,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,7,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,8,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,9,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,10,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,11,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,12,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,13,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,14,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,15,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,16,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,17,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,18,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,19,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,20,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,21,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,22,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,23,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,24,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,25,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,26,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,27,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,28,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,29,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,30,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,31,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,32,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,33,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,34,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,35,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,36,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,37,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,38,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,39,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,40,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,41,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,42,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,43,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,44,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,45,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,46,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,47,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,48,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,49,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,50,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,51,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,52,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,53,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,54,early_ack,late_ack,mask,unmask,level_mask) ;\
INTRSTUB(name,55,early_ack,late_ack,mask,unmask,level_mask)
INTRSTUB_56(ioapic_edge,voidop,ioapic_asm_ack,voidop,voidop,voidop)
INTRSTUB_56(ioapic_level,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
INTRSTUB_56(x2apic_edge,voidop,x2apic_asm_ack,voidop,voidop,voidop)
INTRSTUB_56(x2apic_level,voidop,x2apic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
#endif
#define INTRSTUB_ENTRY(name) \
.quad _C_LABEL(Xintr_ ## name ), _C_LABEL(Xrecurse_ ## name ) ; \
.quad _C_LABEL(Xresume_ ## name ) ;
#define INTRSTUB_ARRAY_16(name) ; \
.type _C_LABEL(name ## _stubs), @object ; \
.align 8 ; \
LABEL(name ## _stubs) ; \
INTRSTUB_ENTRY(name ## 0) ; \
INTRSTUB_ENTRY(name ## 1) ; \
INTRSTUB_ENTRY(name ## 2) ; \
INTRSTUB_ENTRY(name ## 3) ; \
INTRSTUB_ENTRY(name ## 4) ; \
INTRSTUB_ENTRY(name ## 5) ; \
INTRSTUB_ENTRY(name ## 6) ; \
INTRSTUB_ENTRY(name ## 7) ; \
INTRSTUB_ENTRY(name ## 8) ; \
INTRSTUB_ENTRY(name ## 9) ; \
INTRSTUB_ENTRY(name ## 10) ; \
INTRSTUB_ENTRY(name ## 11) ; \
INTRSTUB_ENTRY(name ## 12) ; \
INTRSTUB_ENTRY(name ## 13) ; \
INTRSTUB_ENTRY(name ## 14) ; \
INTRSTUB_ENTRY(name ## 15) ; \
END(name ## _stubs)
#define INTRSTUB_ARRAY_56(name) ; \
.type _C_LABEL(name ## _stubs), @object ; \
.align 8 ; \
LABEL(name ## _stubs) ; \
INTRSTUB_ENTRY(name ## 0) ; \
INTRSTUB_ENTRY(name ## 1) ; \
INTRSTUB_ENTRY(name ## 2) ; \
INTRSTUB_ENTRY(name ## 3) ; \
INTRSTUB_ENTRY(name ## 4) ; \
INTRSTUB_ENTRY(name ## 5) ; \
INTRSTUB_ENTRY(name ## 6) ; \
INTRSTUB_ENTRY(name ## 7) ; \
INTRSTUB_ENTRY(name ## 8) ; \
INTRSTUB_ENTRY(name ## 9) ; \
INTRSTUB_ENTRY(name ## 10) ; \
INTRSTUB_ENTRY(name ## 11) ; \
INTRSTUB_ENTRY(name ## 12) ; \
INTRSTUB_ENTRY(name ## 13) ; \
INTRSTUB_ENTRY(name ## 14) ; \
INTRSTUB_ENTRY(name ## 15) ; \
INTRSTUB_ENTRY(name ## 16) ; \
INTRSTUB_ENTRY(name ## 17) ; \
INTRSTUB_ENTRY(name ## 18) ; \
INTRSTUB_ENTRY(name ## 19) ; \
INTRSTUB_ENTRY(name ## 20) ; \
INTRSTUB_ENTRY(name ## 21) ; \
INTRSTUB_ENTRY(name ## 22) ; \
INTRSTUB_ENTRY(name ## 23) ; \
INTRSTUB_ENTRY(name ## 24) ; \
INTRSTUB_ENTRY(name ## 25) ; \
INTRSTUB_ENTRY(name ## 26) ; \
INTRSTUB_ENTRY(name ## 27) ; \
INTRSTUB_ENTRY(name ## 28) ; \
INTRSTUB_ENTRY(name ## 29) ; \
INTRSTUB_ENTRY(name ## 30) ; \
INTRSTUB_ENTRY(name ## 31) ; \
INTRSTUB_ENTRY(name ## 32) ; \
INTRSTUB_ENTRY(name ## 33) ; \
INTRSTUB_ENTRY(name ## 34) ; \
INTRSTUB_ENTRY(name ## 35) ; \
INTRSTUB_ENTRY(name ## 36) ; \
INTRSTUB_ENTRY(name ## 37) ; \
INTRSTUB_ENTRY(name ## 38) ; \
INTRSTUB_ENTRY(name ## 39) ; \
INTRSTUB_ENTRY(name ## 40) ; \
INTRSTUB_ENTRY(name ## 41) ; \
INTRSTUB_ENTRY(name ## 42) ; \
INTRSTUB_ENTRY(name ## 43) ; \
INTRSTUB_ENTRY(name ## 44) ; \
INTRSTUB_ENTRY(name ## 45) ; \
INTRSTUB_ENTRY(name ## 46) ; \
INTRSTUB_ENTRY(name ## 47) ; \
INTRSTUB_ENTRY(name ## 48) ; \
INTRSTUB_ENTRY(name ## 49) ; \
INTRSTUB_ENTRY(name ## 50) ; \
INTRSTUB_ENTRY(name ## 51) ; \
INTRSTUB_ENTRY(name ## 52) ; \
INTRSTUB_ENTRY(name ## 53) ; \
INTRSTUB_ENTRY(name ## 54) ; \
INTRSTUB_ENTRY(name ## 55) ; \
END(name ## _stubs)
#endif
#if defined(XEN)
#define XENINTRSTUB(name, sir, level, unmask) \
IDTVEC(recurse_ ## name ## sir) ;\
INTR_RECURSE_HWFRAME ;\
subq $8,%rsp ;\
pushq $T_ASTFLT ;\
INTR_RECURSE_ENTRY ;\
IDTVEC(resume_ ## name ## sir) \
movq $IREENT_MAGIC,TF_ERR(%rsp) ;\
movl %ebx,%r13d ;\
movq CPUVAR(ISOURCES) + (sir) * 8,%r14 ;\
pushq %r13 ;\
movb $level,CPUVAR(ILEVEL) ;\
STI(si) ;\
incl CPUVAR(IDEPTH) ;\
movq IS_HANDLERS(%r14),%rbx ;\
6: \
cmpl $0, IH_PENDING(%rbx) ;\
je 7f ;\
movl $0, IH_PENDING(%rbx) ;\
movq IH_ARG(%rbx),%rdi ;\
movq %rsp,%rsi ;\
call *IH_FUN(%rbx) ;\
7: \
movq IH_NEXT(%rbx),%rbx ;\
testq %rbx,%rbx ;\
jnz 6b ;\
5: \
CLI(si) ;\
unmask(sir) ;\
STI(si) ;\
jmp _C_LABEL(Xdoreti) ;\
#define hypervisor_asm_unmask(sir) \
movq $sir,%rdi ;\
call _C_LABEL(hypervisor_enable_sir)
XENINTRSTUB(xenev,SIR_XENIPL_VM,IPL_VM,hypervisor_asm_unmask)
XENINTRSTUB(xenev,SIR_XENIPL_SCHED,IPL_SCHED,hypervisor_asm_unmask)
XENINTRSTUB(xenev,SIR_XENIPL_HIGH,IPL_HIGH,hypervisor_asm_unmask)
panicmsg: .ascii "vector Xen event entry path entered."
LABEL(entry_xenev)
movq $panicmsg, %rdi
callq _C_LABEL(panic)
END(entry_xenev)
#define XENINTRSTUB_ENTRY(name, sir) \
.quad entry_xenev , _C_LABEL(Xrecurse_ ## name ## sir); \
.quad _C_LABEL(Xresume_ ## name ## sir);
.align 8
LABEL(xenev_stubs)
XENINTRSTUB_ENTRY(xenev, SIR_XENIPL_VM) ;
XENINTRSTUB_ENTRY(xenev, SIR_XENIPL_SCHED) ;
XENINTRSTUB_ENTRY(xenev, SIR_XENIPL_HIGH) ;
END(xenev_stubs)
ENTRY(hypervisor_callback)
movq (%rsp),%rcx
movq 8(%rsp),%r11
addq $16,%rsp
pushq $0
pushq $T_ASTFLT
INTRENTRY
IDTVEC(handle_hypervisor_callback)
movzbl CPUVAR(ILEVEL),%edi
pushq %rdi
incl CPUVAR(IDEPTH)
movq %rsp,%rdi
call do_hypervisor_callback
#ifndef XENPV
movzbl _C_LABEL(xenhvm_use_percpu_callback),%edi
testl %edi, %edi
jz 1f
movq _C_LABEL(local_apic_va),%rdi
movl $0,LAPIC_EOI(%rdi)
1:
#endif
jmp _C_LABEL(Xdoreti)
IDTVEC_END(handle_hypervisor_callback)
END(hypervisor_callback)
TEXT_USER_BEGIN
IDTVEC(hypervisor_pvhvm_callback)
pushq $0
pushq $T_ASTFLT
INTRENTRY
jmp _C_LABEL(Xhandle_hypervisor_callback)
IDTVEC_END(hypervisor_pvhvm_callback)
TEXT_USER_END
#endif
#ifdef XENPV
ENTRY(failsafe_callback)
movq (%rsp),%rcx
movq 8(%rsp),%r11
addq $16,%rsp
pushq $0
pushq $T_ASTFLT
INTRENTRY
movq %rsp,%rdi
subq $8,%rdi;
call xen_failsafe_handler
INTRFASTEXIT
END(failsafe_callback)
#else
.section .rodata
INTRSTUB_ARRAY_16(legacy)
#if NIOAPIC > 0
INTRSTUB_ARRAY_56(ioapic_edge)
INTRSTUB_ARRAY_56(ioapic_level)
INTRSTUB_ARRAY_56(x2apic_edge)
INTRSTUB_ARRAY_56(x2apic_level)
#endif
#endif