x86_64/lapic: Use function pointer for EOI.
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Mon, 14 May 2018 14:35:04 +0000 (22:35 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Mon, 14 May 2018 14:47:40 +0000 (22:47 +0800)
This helps upcoming X2APIC support and virtualization EOI optmization,
e.g. Hyper-V can be configured to do auto-EOI.

Discussed-with: Imre Vadasz

sys/conf/options
sys/platform/pc64/apic/apic_vector.s
sys/platform/pc64/apic/lapic.c
sys/platform/pc64/apic/lapic.h
sys/platform/pc64/x86_64/genassym.c
sys/platform/pc64/x86_64/msi_vector.s

index db30ea7..257dca2 100644 (file)
@@ -535,6 +535,7 @@ KTR_IF_EMX                  opt_ktr.h
 KTR_IF_START                   opt_ktr.h
 KTR_IPIQ                       opt_ktr.h
 KTR_KERNENTRY                  opt_ktr.h
+KTR_LAPIC                      opt_ktr.h
 KTR_MEMORY                     opt_ktr.h
 KTR_SERIALIZER                 opt_ktr.h
 KTR_SPIN_CONTENTION            opt_ktr.h
index c7ef77e..5372432 100644 (file)
@@ -121,8 +121,8 @@ IDTVEC(ioapic_intr##irq_num) ;                                              \
        APIC_PUSH_FRAME_TFRIP ;                                         \
        FAKE_MCOUNT(TF_RIP(%rsp)) ;                                     \
        MASK_LEVEL_IRQ(irq_num) ;                                       \
-       movq    lapic, %rax ;                                           \
-       movl    $0, LA_EOI(%rax) ;                                      \
+       movq    lapic_eoi, %rax ;                                       \
+       callq   *%rax ;                                                 \
        movq    PCPU(curthread),%rbx ;                                  \
        testl   $-1,TD_NEST_COUNT(%rbx) ;                               \
        jne     1f ;                                                    \
@@ -188,8 +188,8 @@ Xspuriousint:
        .globl  Xinvltlb
 Xinvltlb:
        APIC_PUSH_FRAME_TFRIP
-       movq    lapic, %rax
-       movl    $0, LA_EOI(%rax)        /* End Of Interrupt to APIC */
+       movq    lapic_eoi, %rax
+       callq   *%rax                   /* End Of Interrupt to APIC */
        FAKE_MCOUNT(TF_RIP(%rsp))
        incl    PCPU(cnt) + V_IPI
        movq    PCPU(curthread),%rbx
@@ -213,8 +213,8 @@ Xinvltlb:
        .globl  Xsniff
 Xsniff:
        APIC_PUSH_FRAME_TFRIP
-       movq    lapic, %rax
-       movl    $0, LA_EOI(%rax)        /* End Of Interrupt to APIC */
+       movq    lapic_eoi, %rax
+       callq   *%rax                   /* End Of Interrupt to APIC */
        FAKE_MCOUNT(TF_RIP(%rsp))
        incl    PCPU(cnt) + V_IPI
        movq    TF_RIP(%rsp),%rax
@@ -239,8 +239,8 @@ Xsniff:
        .globl Xcpustop
 Xcpustop:
        APIC_PUSH_FRAME_TFRIP
-       movq    lapic, %rax
-       movl    $0, LA_EOI(%rax)        /* End Of Interrupt to APIC */
+       movq    lapic_eoi, %rax
+       callq   *%rax                   /* End Of Interrupt to APIC */
 
        movl    PCPU(cpuid), %eax
        imull   $PCB_SIZE, %eax
@@ -337,8 +337,8 @@ Xcpustop:
        .globl Xipiq
 Xipiq:
        APIC_PUSH_FRAME_TFRIP
-       movq    lapic, %rax
-       movl    $0, LA_EOI(%rax)        /* End Of Interrupt to APIC */
+       movq    lapic_eoi, %rax
+       callq   *%rax                   /* End Of Interrupt to APIC */
        FAKE_MCOUNT(TF_RIP(%rsp))
 
        incl    PCPU(cnt) + V_IPI
@@ -369,8 +369,8 @@ Xipiq:
        .globl Xtimer
 Xtimer:
        APIC_PUSH_FRAME_TFRIP
-       movq    lapic, %rax
-       movl    $0, LA_EOI(%rax)        /* End Of Interrupt to APIC */
+       movq    lapic_eoi, %rax
+       callq   *%rax                   /* End Of Interrupt to APIC */
        FAKE_MCOUNT(TF_RIP(%rsp))
 
        subq    $8,%rsp                 /* make same as interrupt frame */
index e7b7cdb..9d8b166 100644 (file)
@@ -28,6 +28,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/ktr.h>
 #include <sys/bus.h>
 #include <sys/machintr.h>
 #include <machine/globaldata.h>
 #include <machine/cputypes.h>
 #include <machine/intr_machdep.h>
 
+#if !defined(KTR_LAPIC)
+#define KTR_LAPIC      KTR_ALL
+#endif
+KTR_INFO_MASTER(lapic);
+KTR_INFO(KTR_LAPIC, lapic, eoi, 0, "eoi");
+#define log_lapic(name)     KTR_LOG(lapic_ ## name)
+
 extern int naps;
 
 volatile lapic_t *lapic;
@@ -120,6 +128,10 @@ struct deadlines {
 };
 struct deadlines *tsc_deadlines = NULL;
 
+static void    lapic_eoi_func(void);
+
+void           (*lapic_eoi)(void);
+
 /*
  * Enable LAPIC, configure interrupts.
  */
@@ -1117,12 +1129,21 @@ lapic_fixup_noioapic(void)
        lapic->lvt_lint1 = temp;
 }
 
+static void
+lapic_eoi_func(void)
+{
+       log_lapic(eoi);
+       lapic->eoi = 0;
+}
+
 static void
 lapic_sysinit(void *dummy __unused)
 {
        if (lapic_enable) {
                int error;
 
+               lapic_eoi = lapic_eoi_func;
+
                error = lapic_config();
                if (error)
                        lapic_enable = 0;
index 7e01aef..41055c1 100644 (file)
@@ -55,6 +55,7 @@ extern volatile lapic_t               *lapic;
 extern int                     cpu_id_to_apic_id[];
 extern int                     apic_id_to_cpu_id[];
 extern int                     lapic_enable;
+extern void                    (*lapic_eoi)(void);
 
 void   apic_dump(char*);
 void   lapic_init(boolean_t);
index fbdae28..d559453 100644 (file)
@@ -257,8 +257,6 @@ ASSYM(RQF_TIMER, RQF_TIMER);
 ASSYM(RQF_AST_MASK, RQF_AST_MASK);
 ASSYM(RQF_QUICKRET, RQF_QUICKRET);
 
-ASSYM(LA_EOI, offsetof(struct LAPIC, eoi));
-
 ASSYM(KCSEL, GSEL(GCODE_SEL, SEL_KPL));
 ASSYM(KDSEL, GSEL(GDATA_SEL, SEL_KPL));
 ASSYM(KUCSEL, GSEL(GUCODE_SEL, SEL_UPL));
index 853b975..b2e8f9e 100644 (file)
@@ -48,8 +48,8 @@
 IDTVEC(msi_intr##irq_num) ;                                            \
        MSI_PUSH_FRAME ;                                                \
        FAKE_MCOUNT(TF_RIP(%rsp)) ;                                     \
-       movq    lapic, %rax ;                                           \
-       movl    $0, LA_EOI(%rax) ;                                      \
+       movq    lapic_eoi, %rax ;                                       \
+       callq   *%rax ;                                                 \
        movq    PCPU(curthread),%rbx ;                                  \
        testl   $-1,TD_NEST_COUNT(%rbx) ;                               \
        jne     1f ;                                                    \