aboutsummaryrefslogtreecommitdiff
path: root/sys/i386/i386/apic_vector.s
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/i386/apic_vector.s')
-rw-r--r--sys/i386/i386/apic_vector.s50
1 files changed, 33 insertions, 17 deletions
diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s
index 3d1999e4a916..7cae22013a4d 100644
--- a/sys/i386/i386/apic_vector.s
+++ b/sys/i386/i386/apic_vector.s
@@ -39,10 +39,27 @@
#include "opt_smp.h"
#include <machine/asmacros.h>
+#include <machine/specialreg.h>
#include <x86/apicreg.h>
#include "assym.s"
+ .text
+ SUPERALIGN_TEXT
+ /* End Of Interrupt to APIC */
+as_lapic_eoi:
+ cmpl $0,x2apic_mode
+ jne 1f
+ movl lapic_map,%eax
+ movl $0,LA_EOI(%eax)
+ ret
+1:
+ movl $MSR_APIC_EOI,%ecx
+ xorl %eax,%eax
+ xorl %edx,%edx
+ wrmsr
+ ret
+
/*
* I/O Interrupt Entry Point. Rather than having one entry point for
* each interrupt source, we use one entry point for each 32-bit word
@@ -58,16 +75,23 @@ IDTVEC(vec_name) ; \
SET_KERNEL_SREGS ; \
cld ; \
FAKE_MCOUNT(TF_EIP(%esp)) ; \
- movl lapic, %edx ; /* pointer to local APIC */ \
+ cmpl $0,x2apic_mode ; \
+ je 1f ; \
+ movl $(MSR_APIC_ISR0 + index),%ecx ; \
+ rdmsr ; \
+ jmp 2f ; \
+1: ; \
+ movl lapic_map, %edx ;/* pointer to local APIC */ \
movl LA_ISR + 16 * (index)(%edx), %eax ; /* load ISR */ \
+2: ; \
bsrl %eax, %eax ; /* index of highest set bit in ISR */ \
- jz 1f ; \
+ jz 3f ; \
addl $(32 * index),%eax ; \
pushl %esp ; \
pushl %eax ; /* pass the IRQ */ \
call lapic_handle_intr ; \
addl $8, %esp ; /* discard parameter */ \
-1: ; \
+3: ; \
MEXITCOUNT ; \
jmp doreti
@@ -164,8 +188,7 @@ IDTVEC(xen_intr_upcall)
.text
SUPERALIGN_TEXT
invltlb_ret:
- movl lapic, %eax
- movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */
+ call as_lapic_eoi
POP_FRAME
iret
@@ -232,8 +255,7 @@ IDTVEC(ipi_intr_bitmap_handler)
SET_KERNEL_SREGS
cld
- movl lapic, %edx
- movl $0, LA_EOI(%edx) /* End Of Interrupt to APIC */
+ call as_lapic_eoi
FAKE_MCOUNT(TF_EIP(%esp))
@@ -251,9 +273,7 @@ IDTVEC(cpustop)
SET_KERNEL_SREGS
cld
- movl lapic, %eax
- movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */
-
+ call as_lapic_eoi
call cpustop_handler
POP_FRAME
@@ -270,9 +290,7 @@ IDTVEC(cpususpend)
SET_KERNEL_SREGS
cld
- movl lapic, %eax
- movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */
-
+ call as_lapic_eoi
call cpususpend_handler
POP_FRAME
@@ -298,8 +316,7 @@ IDTVEC(rendezvous)
#endif
call smp_rendezvous_action
- movl lapic, %eax
- movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */
+ call as_lapic_eoi
POP_FRAME
iret
@@ -315,8 +332,7 @@ IDTVEC(lazypmap)
call pmap_lazyfix_action
- movl lapic, %eax
- movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */
+ call as_lapic_eoi
POP_FRAME
iret
#endif /* SMP */