Author: sephe
Date: Wed May 25 05:53:12 2016
New Revision: 300654
URL: https://svnweb.freebsd.org/changeset/base/300654

Log:
  hyperv/vmbus: Rework SynIC setup and teardown
  
  - Avoid bit fields.
  - Fix SINT setup (preserve required bits).
  
  MFC after:    1 week
  Sponsored by: Microsoft OSTC
  Differential Revision:        https://reviews.freebsd.org/D6529

Modified:
  head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
  head/sys/dev/hyperv/vmbus/hyperv_reg.h

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c    Wed May 25 05:45:43 
2016        (r300653)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c    Wed May 25 05:53:12 
2016        (r300654)
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/hyperv/include/hyperv.h>
 #include <dev/hyperv/vmbus/hv_vmbus_priv.h>
+#include <dev/hyperv/vmbus/hyperv_reg.h>
 #include <dev/hyperv/vmbus/vmbus_var.h>
 
 #include <contrib/dev/acpica/include/acpi.h>
@@ -210,100 +211,97 @@ static void
 vmbus_synic_setup(void *xsc)
 {
        struct vmbus_softc *sc = xsc;
-       int                     cpu;
-       hv_vmbus_synic_simp     simp;
-       hv_vmbus_synic_siefp    siefp;
-       hv_vmbus_synic_scontrol sctrl;
-       hv_vmbus_synic_sint     shared_sint;
-
-       cpu = PCPU_GET(cpuid);
+       int cpu = curcpu;
+       uint64_t val, orig;
+       uint32_t sint;
 
        /*
-        * Setup the Synic's message page
+        * Save virtual processor id.
         */
-       simp.as_uint64_t = rdmsr(HV_X64_MSR_SIMP);
-       simp.u.simp_enabled = 1;
-       simp.u.base_simp_gpa =
-           VMBUS_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT;
-
-       wrmsr(HV_X64_MSR_SIMP, simp.as_uint64_t);
+       VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(MSR_HV_VP_INDEX);
 
        /*
-        * Setup the Synic's event page
+        * Setup the SynIC message.
         */
-       siefp.as_uint64_t = rdmsr(HV_X64_MSR_SIEFP);
-       siefp.u.siefp_enabled = 1;
-       siefp.u.base_siefp_gpa =
-           VMBUS_PCPU_GET(sc, event_flag_dma.hv_paddr, cpu) >> PAGE_SHIFT;
+       orig = rdmsr(MSR_HV_SIMP);
+       val = MSR_HV_SIMP_ENABLE | (orig & MSR_HV_SIMP_RSVD_MASK) |
+           ((VMBUS_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT) <<
+            MSR_HV_SIMP_PGSHIFT);
+       wrmsr(MSR_HV_SIMP, val);
 
-       wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
-
-       /*HV_SHARED_SINT_IDT_VECTOR + 0x20; */
-       shared_sint.as_uint64_t = 0;
-       shared_sint.u.vector = sc->vmbus_idtvec;
-       shared_sint.u.masked = FALSE;
-       shared_sint.u.auto_eoi = TRUE;
-
-       wrmsr(HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT,
-           shared_sint.as_uint64_t);
+       /*
+        * Setup the SynIC event flags.
+        */
+       orig = rdmsr(MSR_HV_SIEFP);
+       val = MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK) |
+           ((VMBUS_PCPU_GET(sc, event_flag_dma.hv_paddr, cpu) >> PAGE_SHIFT) <<
+            MSR_HV_SIEFP_PGSHIFT);
+       wrmsr(MSR_HV_SIEFP, val);
 
-       wrmsr(HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT,
-           shared_sint.as_uint64_t);
 
-       /* Enable the global synic bit */
-       sctrl.as_uint64_t = rdmsr(HV_X64_MSR_SCONTROL);
-       sctrl.u.enable = 1;
+       /*
+        * Configure and unmask SINT for message and event flags.
+        */
+       sint = MSR_HV_SINT0 + HV_VMBUS_MESSAGE_SINT;
+       orig = rdmsr(sint);
+       val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
+           (orig & MSR_HV_SINT_RSVD_MASK);
+       wrmsr(sint, val);
 
-       wrmsr(HV_X64_MSR_SCONTROL, sctrl.as_uint64_t);
+       /*
+        * Configure and unmask SINT for timer.
+        */
+       sint = MSR_HV_SINT0 + HV_VMBUS_TIMER_SINT;
+       orig = rdmsr(sint);
+       val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
+           (orig & MSR_HV_SINT_RSVD_MASK);
+       wrmsr(sint, val);
 
        /*
-        * Set up the cpuid mapping from Hyper-V to FreeBSD.
-        * The array is indexed using FreeBSD cpuid.
+        * All done; enable SynIC.
         */
-       VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(HV_X64_MSR_VP_INDEX);
+       orig = rdmsr(MSR_HV_SCONTROL);
+       val = MSR_HV_SCTRL_ENABLE | (orig & MSR_HV_SCTRL_RSVD_MASK);
+       wrmsr(MSR_HV_SCONTROL, val);
 }
 
 static void
 vmbus_synic_teardown(void *arg)
 {
-       hv_vmbus_synic_sint     shared_sint;
-       hv_vmbus_synic_simp     simp;
-       hv_vmbus_synic_siefp    siefp;
-
-       shared_sint.as_uint64_t = rdmsr(
-           HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT);
-
-       shared_sint.u.masked = 1;
+       uint64_t orig;
+       uint32_t sint;
 
        /*
-        * Disable the interrupt 0
+        * Disable SynIC.
         */
-       wrmsr(
-           HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT,
-           shared_sint.as_uint64_t);
-
-       shared_sint.as_uint64_t = rdmsr(
-           HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT);
-
-       shared_sint.u.masked = 1;
+       orig = rdmsr(MSR_HV_SCONTROL);
+       wrmsr(MSR_HV_SCONTROL, (orig & MSR_HV_SCTRL_RSVD_MASK));
 
        /*
-        * Disable the interrupt 1
+        * Mask message and event flags SINT.
         */
-       wrmsr(
-           HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT,
-           shared_sint.as_uint64_t);
-       simp.as_uint64_t = rdmsr(HV_X64_MSR_SIMP);
-       simp.u.simp_enabled = 0;
-       simp.u.base_simp_gpa = 0;
+       sint = MSR_HV_SINT0 + HV_VMBUS_MESSAGE_SINT;
+       orig = rdmsr(sint);
+       wrmsr(sint, orig | MSR_HV_SINT_MASKED);
 
-       wrmsr(HV_X64_MSR_SIMP, simp.as_uint64_t);
+       /*
+        * Mask timer SINT.
+        */
+       sint = MSR_HV_SINT0 + HV_VMBUS_TIMER_SINT;
+       orig = rdmsr(sint);
+       wrmsr(sint, orig | MSR_HV_SINT_MASKED);
 
-       siefp.as_uint64_t = rdmsr(HV_X64_MSR_SIEFP);
-       siefp.u.siefp_enabled = 0;
-       siefp.u.base_siefp_gpa = 0;
+       /*
+        * Teardown SynIC message.
+        */
+       orig = rdmsr(MSR_HV_SIMP);
+       wrmsr(MSR_HV_SIMP, (orig & MSR_HV_SIMP_RSVD_MASK));
 
-       wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
+       /*
+        * Teardown SynIC event flags.
+        */
+       orig = rdmsr(MSR_HV_SIEFP);
+       wrmsr(MSR_HV_SIEFP, (orig & MSR_HV_SIEFP_RSVD_MASK));
 }
 
 static int

Modified: head/sys/dev/hyperv/vmbus/hyperv_reg.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hyperv_reg.h      Wed May 25 05:45:43 2016        
(r300653)
+++ head/sys/dev/hyperv/vmbus/hyperv_reg.h      Wed May 25 05:53:12 2016        
(r300654)
@@ -34,4 +34,29 @@
 #define MSR_HV_HYPERCALL_RSVD_MASK     0x0ffeULL
 #define MSR_HV_HYPERCALL_PGSHIFT       12
 
+#define MSR_HV_VP_INDEX                        0x40000002
+
+#define MSR_HV_SCONTROL                        0x40000080
+#define MSR_HV_SCTRL_ENABLE            0x0001ULL
+#define MSR_HV_SCTRL_RSVD_MASK         0xfffffffffffffffeULL
+
+#define MSR_HV_SIEFP                   0x40000082
+#define MSR_HV_SIEFP_ENABLE            0x0001ULL
+#define MSR_HV_SIEFP_RSVD_MASK         0x0ffeULL
+#define MSR_HV_SIEFP_PGSHIFT           12
+
+#define MSR_HV_SIMP                    0x40000083
+#define MSR_HV_SIMP_ENABLE             0x0001ULL
+#define MSR_HV_SIMP_RSVD_MASK          0x0ffeULL
+#define MSR_HV_SIMP_PGSHIFT            12
+
+#define MSR_HV_SINT0                   0x40000090
+#define MSR_HV_SINT_VECTOR_MASK                0x00ffULL
+#define MSR_HV_SINT_RSVD1_MASK         0xff00ULL
+#define MSR_HV_SINT_MASKED             0x00010000ULL
+#define MSR_HV_SINT_AUTOEOI            0x00020000ULL
+#define MSR_HV_SINT_RSVD2_MASK         0xfffffffffffc0000ULL
+#define MSR_HV_SINT_RSVD_MASK          (MSR_HV_SINT_RSVD1_MASK |       \
+                                        MSR_HV_SINT_RSVD2_MASK)
+
 #endif /* !_HYPERV_REG_H_ */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to