Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167017699
D36467.id110216.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
29 KB
Referenced Files
None
Subscribers
None
D36467.id110216.diff
View Options
Index: share/mk/src.opts.mk
===================================================================
--- share/mk/src.opts.mk
+++ share/mk/src.opts.mk
@@ -331,8 +331,7 @@
BROKEN_OPTIONS+=MLX5TOOL
.endif
-# HyperV is currently x86-only
-.if ${__T} != "amd64" && ${__T} != "i386"
+.if ${__T} != "amd64" && ${__T} != "i386" && ${__T} != "aarch64"
BROKEN_OPTIONS+=HYPERV
.endif
Index: sys/arm64/conf/std.dev
===================================================================
--- sys/arm64/conf/std.dev
+++ sys/arm64/conf/std.dev
@@ -107,3 +107,6 @@
# HID support
options HID_DEBUG # enable debug msgs
device hid # Generic HID support
+
+#hyper-v support
+device hyperv
Index: sys/conf/files.arm64
===================================================================
--- sys/conf/files.arm64
+++ sys/conf/files.arm64
@@ -606,3 +606,25 @@
# Xilinx
arm/xilinx/uart_dev_cdnc.c optional uart soc_xilinx_zynq
+
+# Microsoft Hyper-V
+dev/hyperv/vmbus/hyperv.c optional hyperv
+dev/hyperv/vmbus/aarch64/hyperv_aarch64.c optional hyperv
+dev/hyperv/vmbus/vmbus.c optional hyperv pci
+dev/hyperv/vmbus/aarch64/vmbus_aarch64.c optional hyperv
+dev/hyperv/vmbus/vmbus_if.m optional hyperv
+dev/hyperv/vmbus/vmbus_res.c optional hyperv
+dev/hyperv/vmbus/vmbus_xact.c optional hyperv
+dev/hyperv/vmbus/aarch64/hyperv_machdep.c optional hyperv
+dev/hyperv/vmbus/vmbus_chan.c optional hyperv
+dev/hyperv/vmbus/hyperv_busdma.c optional hyperv
+dev/hyperv/vmbus/vmbus_br.c optional hyperv
+dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv
+dev/hyperv/utilities/vmbus_timesync.c optional hyperv
+dev/hyperv/utilities/vmbus_heartbeat.c optional hyperv
+dev/hyperv/utilities/vmbus_ic.c optional hyperv
+dev/hyperv/utilities/vmbus_shutdown.c optional hyperv
+dev/hyperv/utilities/hv_kvp.c optional hyperv
+dev/hyperv/netvsc/hn_nvs.c optional hyperv
+dev/hyperv/netvsc/hn_rndis.c optional hyperv
+dev/hyperv/netvsc/if_hn.c optional hyperv
Index: sys/conf/files.x86
===================================================================
--- sys/conf/files.x86
+++ sys/conf/files.x86
@@ -132,6 +132,8 @@
dev/hyperv/utilities/vmbus_shutdown.c optional hyperv
dev/hyperv/utilities/vmbus_timesync.c optional hyperv
dev/hyperv/vmbus/hyperv.c optional hyperv
+dev/hyperv/vmbus/x86/hyperv_x86.c optional hyperv
+dev/hyperv/vmbus/x86/vmbus_x86.c optional hyperv
dev/hyperv/vmbus/hyperv_busdma.c optional hyperv
dev/hyperv/vmbus/vmbus.c optional hyperv pci
dev/hyperv/vmbus/vmbus_br.c optional hyperv
Index: sys/dev/hyperv/include/hyperv.h
===================================================================
--- sys/dev/hyperv/include/hyperv.h
+++ sys/dev/hyperv/include/hyperv.h
@@ -86,6 +86,11 @@
int hyperv_guid2str(const struct hyperv_guid *, char *,
size_t);
+void hyperv_init_tc(void);
+int hypercall_page_setup(vm_paddr_t);
+void hypercall_disable(void);
+bool hyperv_identify_features(void);
+
/*
* hyperv_tc64 could be NULL, if there were no suitable Hyper-V
* specific timecounter.
Index: sys/dev/hyperv/vmbus/hyperv.c
===================================================================
--- sys/dev/hyperv/vmbus/hyperv.c
+++ sys/dev/hyperv/vmbus/hyperv.c
@@ -45,8 +45,13 @@
#include <dev/hyperv/include/hyperv.h>
#include <dev/hyperv/include/hyperv_busdma.h>
-#include <dev/hyperv/vmbus/hyperv_machdep.h>
-#include <dev/hyperv/vmbus/hyperv_reg.h>
+#if defined(__aarch64__)
+#include <dev/hyperv/vmbus/aarch64/hyperv_machdep.h>
+#include <dev/hyperv/vmbus/aarch64/hyperv_reg.h>
+#else
+#include <dev/hyperv/vmbus/x86/hyperv_machdep.h>
+#include <dev/hyperv/vmbus/x86/hyperv_reg.h>
+#endif
#include <dev/hyperv/vmbus/hyperv_var.h>
#define HYPERV_FREEBSD_BUILD 0ULL
@@ -68,51 +73,10 @@
MSR_HV_GUESTID_OSID_FREEBSD | \
MSR_HV_GUESTID_OSTYPE_FREEBSD)
-struct hypercall_ctx {
- void *hc_addr;
- vm_paddr_t hc_paddr;
-};
-
-static u_int hyperv_get_timecount(struct timecounter *);
static bool hyperv_identify(void);
static void hypercall_memfree(void);
-u_int hyperv_ver_major;
-
-u_int hyperv_features;
-u_int hyperv_recommends;
-
-static u_int hyperv_pm_features;
-static u_int hyperv_features3;
-
-hyperv_tc64_t hyperv_tc64;
-
-static struct timecounter hyperv_timecounter = {
- .tc_get_timecount = hyperv_get_timecount,
- .tc_poll_pps = NULL,
- .tc_counter_mask = 0xffffffff,
- .tc_frequency = HYPERV_TIMER_FREQ,
- .tc_name = "Hyper-V",
- .tc_quality = 2000,
- .tc_flags = 0,
- .tc_priv = NULL
-};
-
static struct hypercall_ctx hypercall_context;
-
-static u_int
-hyperv_get_timecount(struct timecounter *tc __unused)
-{
- return rdmsr(MSR_HV_TIME_REF_COUNT);
-}
-
-static uint64_t
-hyperv_tc64_rdmsr(void)
-{
-
- return (rdmsr(MSR_HV_TIME_REF_COUNT));
-}
-
uint64_t
hypercall_post_message(bus_addr_t msg_paddr)
{
@@ -143,97 +107,8 @@
static bool
hyperv_identify(void)
{
- u_int regs[4];
- unsigned int maxleaf;
-
- if (vm_guest != VM_GUEST_HV)
- return (false);
-
- do_cpuid(CPUID_LEAF_HV_MAXLEAF, regs);
- maxleaf = regs[0];
- if (maxleaf < CPUID_LEAF_HV_LIMITS)
- return (false);
-
- do_cpuid(CPUID_LEAF_HV_INTERFACE, regs);
- if (regs[0] != CPUID_HV_IFACE_HYPERV)
- return (false);
-
- do_cpuid(CPUID_LEAF_HV_FEATURES, regs);
- if ((regs[0] & CPUID_HV_MSR_HYPERCALL) == 0) {
- /*
- * Hyper-V w/o Hypercall is impossible; someone
- * is faking Hyper-V.
- */
- return (false);
- }
- hyperv_features = regs[0];
- hyperv_pm_features = regs[2];
- hyperv_features3 = regs[3];
-
- do_cpuid(CPUID_LEAF_HV_IDENTITY, regs);
- hyperv_ver_major = regs[1] >> 16;
- printf("Hyper-V Version: %d.%d.%d [SP%d]\n",
- hyperv_ver_major, regs[1] & 0xffff, regs[0], regs[2]);
-
- printf(" Features=0x%b\n", hyperv_features,
- "\020"
- "\001VPRUNTIME" /* MSR_HV_VP_RUNTIME */
- "\002TMREFCNT" /* MSR_HV_TIME_REF_COUNT */
- "\003SYNIC" /* MSRs for SynIC */
- "\004SYNTM" /* MSRs for SynTimer */
- "\005APIC" /* MSR_HV_{EOI,ICR,TPR} */
- "\006HYPERCALL" /* MSR_HV_{GUEST_OS_ID,HYPERCALL} */
- "\007VPINDEX" /* MSR_HV_VP_INDEX */
- "\010RESET" /* MSR_HV_RESET */
- "\011STATS" /* MSR_HV_STATS_ */
- "\012REFTSC" /* MSR_HV_REFERENCE_TSC */
- "\013IDLE" /* MSR_HV_GUEST_IDLE */
- "\014TMFREQ" /* MSR_HV_{TSC,APIC}_FREQUENCY */
- "\015DEBUG"); /* MSR_HV_SYNTH_DEBUG_ */
- printf(" PM Features=0x%b [C%u]\n",
- (hyperv_pm_features & ~CPUPM_HV_CSTATE_MASK),
- "\020"
- "\005C3HPET", /* HPET is required for C3 state */
- CPUPM_HV_CSTATE(hyperv_pm_features));
- printf(" Features3=0x%b\n", hyperv_features3,
- "\020"
- "\001MWAIT" /* MWAIT */
- "\002DEBUG" /* guest debug support */
- "\003PERFMON" /* performance monitor */
- "\004PCPUDPE" /* physical CPU dynamic partition event */
- "\005XMMHC" /* hypercall input through XMM regs */
- "\006IDLE" /* guest idle support */
- "\007SLEEP" /* hypervisor sleep support */
- "\010NUMA" /* NUMA distance query support */
- "\011TMFREQ" /* timer frequency query (TSC, LAPIC) */
- "\012SYNCMC" /* inject synthetic machine checks */
- "\013CRASH" /* MSRs for guest crash */
- "\014DEBUGMSR" /* MSRs for guest debug */
- "\015NPIEP" /* NPIEP */
- "\016HVDIS"); /* disabling hypervisor */
-
- do_cpuid(CPUID_LEAF_HV_RECOMMENDS, regs);
- hyperv_recommends = regs[0];
- if (bootverbose)
- printf(" Recommends: %08x %08x\n", regs[0], regs[1]);
-
- do_cpuid(CPUID_LEAF_HV_LIMITS, regs);
- if (bootverbose) {
- printf(" Limits: Vcpu:%d Lcpu:%d Int:%d\n",
- regs[0], regs[1], regs[2]);
- }
-
- if (maxleaf >= CPUID_LEAF_HV_HWFEATURES) {
- do_cpuid(CPUID_LEAF_HV_HWFEATURES, regs);
- if (bootverbose) {
- printf(" HW Features: %08x, AMD: %08x\n",
- regs[0], regs[3]);
- }
- }
-
- return (true);
+ return(hyperv_identify_features());
}
-
static void
hyperv_init(void *dummy __unused)
{
@@ -245,22 +120,8 @@
}
/* Set guest id */
- wrmsr(MSR_HV_GUEST_OS_ID, MSR_HV_GUESTID_FREEBSD);
-
- if (hyperv_features & CPUID_HV_MSR_TIME_REFCNT) {
- /*
- * Register Hyper-V timecounter. This should be done as early
- * as possible to let DELAY() work, since the 8254 PIT is not
- * reliably emulated or even available.
- */
- tc_init(&hyperv_timecounter);
-
- /*
- * Install 64 bits timecounter method for other modules
- * to use.
- */
- hyperv_tc64 = hyperv_tc64_rdmsr;
- }
+ WRMSR(MSR_HV_GUEST_OS_ID, MSR_HV_GUESTID_FREEBSD);
+ hyperv_init_tc();
}
SYSINIT(hyperv_initialize, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, hyperv_init,
NULL);
@@ -275,8 +136,8 @@
static void
hypercall_create(void *arg __unused)
{
- uint64_t hc, hc_orig;
+ int ret;
if (vm_guest != VM_GUEST_HV)
return;
@@ -289,30 +150,9 @@
hypercall_context.hc_addr = (void *)kmem_malloc(PAGE_SIZE, M_EXEC |
M_WAITOK);
hypercall_context.hc_paddr = vtophys(hypercall_context.hc_addr);
-
- /* Get the 'reserved' bits, which requires preservation. */
- hc_orig = rdmsr(MSR_HV_HYPERCALL);
-
- /*
- * Setup the Hypercall page.
- *
- * NOTE: 'reserved' bits MUST be preserved.
- */
- hc = ((hypercall_context.hc_paddr >> PAGE_SHIFT) <<
- MSR_HV_HYPERCALL_PGSHIFT) |
- (hc_orig & MSR_HV_HYPERCALL_RSVD_MASK) |
- MSR_HV_HYPERCALL_ENABLE;
- wrmsr(MSR_HV_HYPERCALL, hc);
-
- /*
- * Confirm that Hypercall page did get setup.
- */
- hc = rdmsr(MSR_HV_HYPERCALL);
- if ((hc & MSR_HV_HYPERCALL_ENABLE) == 0) {
- printf("hyperv: Hypercall setup failed\n");
+ ret = hypercall_page_setup(hypercall_context.hc_paddr);
+ if (ret) {
hypercall_memfree();
- /* Can't perform any Hyper-V specific actions */
- vm_guest = VM_GUEST_VM;
return;
}
if (bootverbose)
@@ -323,16 +163,11 @@
static void
hypercall_destroy(void *arg __unused)
{
- uint64_t hc;
if (hypercall_context.hc_addr == NULL)
return;
-
- /* Disable Hypercall */
- hc = rdmsr(MSR_HV_HYPERCALL);
- wrmsr(MSR_HV_HYPERCALL, (hc & MSR_HV_HYPERCALL_RSVD_MASK));
+ hypercall_disable();
hypercall_memfree();
-
if (bootverbose)
printf("hyperv: Hypercall destroyed\n");
}
Index: sys/dev/hyperv/vmbus/hyperv_var.h
===================================================================
--- sys/dev/hyperv/vmbus/hyperv_var.h
+++ sys/dev/hyperv/vmbus/hyperv_var.h
@@ -31,6 +31,10 @@
extern u_int hyperv_recommends;
+struct hypercall_ctx {
+ void *hc_addr;
+ vm_paddr_t hc_paddr;
+};
uint64_t hypercall_post_message(bus_addr_t msg_paddr);
uint64_t hypercall_signal_event(bus_addr_t monprm_paddr);
Index: sys/dev/hyperv/vmbus/vmbus.c
===================================================================
--- sys/dev/hyperv/vmbus/vmbus.c
+++ sys/dev/hyperv/vmbus/vmbus.c
@@ -51,23 +51,28 @@
#include <vm/pmap.h>
#include <machine/bus.h>
+#if defined(__aarch64__)
+#include <dev/psci/smccc.h>
+#include <dev/hyperv/vmbus/aarch64/hyperv_machdep.h>
+#include <dev/hyperv/vmbus/aarch64/hyperv_reg.h>
+#else
+#include <dev/hyperv/vmbus/x86/hyperv_machdep.h>
+#include <dev/hyperv/vmbus/x86/hyperv_reg.h>
#include <machine/intr_machdep.h>
+#include <x86/include/apicvar.h>
+#endif
#include <machine/metadata.h>
#include <machine/md_var.h>
#include <machine/resource.h>
-#include <x86/include/apicvar.h>
-
#include <contrib/dev/acpica/include/acpi.h>
#include <dev/acpica/acpivar.h>
#include <dev/hyperv/include/hyperv.h>
#include <dev/hyperv/include/vmbus_xact.h>
-#include <dev/hyperv/vmbus/hyperv_reg.h>
#include <dev/hyperv/vmbus/hyperv_var.h>
#include <dev/hyperv/vmbus/vmbus_reg.h>
#include <dev/hyperv/vmbus/vmbus_var.h>
#include <dev/hyperv/vmbus/vmbus_chanvar.h>
-
#include "acpi_if.h"
#include "pcib_if.h"
#include "vmbus_if.h"
@@ -107,7 +112,7 @@
device_t dev, int cpu);
static struct taskqueue *vmbus_get_eventtq_method(device_t, device_t,
int);
-#ifdef EARLY_AP_STARTUP
+#if defined(EARLY_AP_STARTUP) || defined(__aarch64__)
static void vmbus_intrhook(void *);
#endif
@@ -132,7 +137,6 @@
static int vmbus_doattach(struct vmbus_softc *);
static void vmbus_event_proc_dummy(struct vmbus_softc *,
int);
-
static struct vmbus_softc *vmbus_sc;
SYSCTL_NODE(_hw, OID_AUTO, vmbus, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
@@ -141,10 +145,6 @@
static int vmbus_pin_evttask = 1;
SYSCTL_INT(_hw_vmbus, OID_AUTO, pin_evttask, CTLFLAG_RDTUN,
&vmbus_pin_evttask, 0, "Pin event tasks to their respective CPU");
-
-extern inthand_t IDTVEC(vmbus_isr), IDTVEC(vmbus_isr_pti);
-#define VMBUS_ISR_ADDR trunc_page((uintptr_t)IDTVEC(vmbus_isr_pti))
-
uint32_t vmbus_current_version;
static const uint32_t vmbus_version[] = {
@@ -209,7 +209,11 @@
};
DRIVER_MODULE(vmbus, pcib, vmbus_driver, NULL, NULL);
+#if !defined(__aarch64__)
DRIVER_MODULE(vmbus, acpi_syscontainer, vmbus_driver, NULL, NULL);
+#else
+DRIVER_MODULE(vmbus, vmbus_res, vmbus_driver, NULL, NULL);
+#endif
MODULE_DEPEND(vmbus, acpi, 1, 1, 1);
MODULE_DEPEND(vmbus, pci, 1, 1, 1);
@@ -660,11 +664,10 @@
* This will cause message queue rescan to possibly
* deliver another msg from the hypervisor
*/
- wrmsr(MSR_HV_EOM, 0);
+ WRMSR(MSR_HV_EOM, 0);
}
}
}
-
static __inline int
vmbus_handle_intr1(struct vmbus_softc *sc, struct trapframe *frame, int cpu)
{
@@ -678,33 +681,7 @@
*
* TODO: move this to independent IDT vector.
*/
- msg = msg_base + VMBUS_SINT_TIMER;
- if (msg->msg_type == HYPERV_MSGTYPE_TIMER_EXPIRED) {
- msg->msg_type = HYPERV_MSGTYPE_NONE;
-
- vmbus_et_intr(frame);
-
- /*
- * Make sure the write to msg_type (i.e. set to
- * HYPERV_MSGTYPE_NONE) happens before we read the
- * msg_flags and EOMing. Otherwise, the EOMing will
- * not deliver any more messages since there is no
- * empty slot
- *
- * NOTE:
- * mb() is used here, since atomic_thread_fence_seq_cst()
- * will become compiler fence on UP kernel.
- */
- mb();
- if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
- /*
- * This will cause message queue rescan to possibly
- * deliver another msg from the hypervisor
- */
- wrmsr(MSR_HV_EOM, 0);
- }
- }
-
+ vmbus_handle_timer_intr1(msg_base, frame);
/*
* Check events. Hot path for network and storage I/O data; high rate.
*
@@ -738,10 +715,12 @@
critical_enter();
/*
- * Do a little interrupt counting.
+ * Do a little interrupt counting. This used x86 specific
+ * intrcnt_add function
*/
+#if !defined(__aarch64__)
(*VMBUS_PCPU_GET(sc, intr_cnt, cpu))++;
-
+#endif /* not for aarch64 */
vmbus_handle_intr1(sc, trap_frame, cpu);
/*
@@ -760,7 +739,7 @@
if (hyperv_features & CPUID_HV_MSR_VP_INDEX) {
/* Save virtual processor id. */
- VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(MSR_HV_VP_INDEX);
+ VMBUS_PCPU_GET(sc, vcpuid, cpu) = RDMSR(MSR_HV_VP_INDEX);
} else {
/* Set virtual processor id to 0 for compatibility. */
VMBUS_PCPU_GET(sc, vcpuid, cpu) = 0;
@@ -769,46 +748,39 @@
/*
* Setup the SynIC message.
*/
- orig = rdmsr(MSR_HV_SIMP);
+ 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);
-
+ ((VMBUS_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT)
+ << MSR_HV_SIMP_PGSHIFT);
+ WRMSR(MSR_HV_SIMP, val);
/*
* Setup the SynIC event flags.
*/
- orig = rdmsr(MSR_HV_SIEFP);
+ orig = RDMSR(MSR_HV_SIEFP);
val = MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK) |
- ((VMBUS_PCPU_GET(sc, event_flags_dma.hv_paddr, cpu)
- >> PAGE_SHIFT) << MSR_HV_SIEFP_PGSHIFT);
- wrmsr(MSR_HV_SIEFP, val);
-
+ ((VMBUS_PCPU_GET(sc, event_flags_dma.hv_paddr, cpu) >> PAGE_SHIFT)
+ << MSR_HV_SIEFP_PGSHIFT);
+ WRMSR(MSR_HV_SIEFP, val);
/*
* Configure and unmask SINT for message and event flags.
*/
sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE;
- orig = rdmsr(sint);
+ orig = RDMSR(sint);
val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
(orig & MSR_HV_SINT_RSVD_MASK);
- wrmsr(sint, val);
+ WRMSR(sint, val);
/*
* Configure and unmask SINT for timer.
*/
- sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER;
- orig = rdmsr(sint);
- val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
- (orig & MSR_HV_SINT_RSVD_MASK);
- wrmsr(sint, val);
-
+ vmbus_synic_setup1(sc);
/*
* All done; enable SynIC.
*/
- orig = rdmsr(MSR_HV_SCONTROL);
+ orig = RDMSR(MSR_HV_SCONTROL);
val = MSR_HV_SCTRL_ENABLE | (orig & MSR_HV_SCTRL_RSVD_MASK);
- wrmsr(MSR_HV_SCONTROL, val);
+ WRMSR(MSR_HV_SCONTROL, val);
}
static void
@@ -820,34 +792,31 @@
/*
* Disable SynIC.
*/
- orig = rdmsr(MSR_HV_SCONTROL);
- wrmsr(MSR_HV_SCONTROL, (orig & MSR_HV_SCTRL_RSVD_MASK));
+ orig = RDMSR(MSR_HV_SCONTROL);
+ WRMSR(MSR_HV_SCONTROL, (orig & MSR_HV_SCTRL_RSVD_MASK));
/*
* Mask message and event flags SINT.
*/
sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE;
- orig = rdmsr(sint);
- wrmsr(sint, orig | MSR_HV_SINT_MASKED);
+ orig = RDMSR(sint);
+ WRMSR(sint, orig | MSR_HV_SINT_MASKED);
/*
* Mask timer SINT.
*/
- sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER;
- orig = rdmsr(sint);
- wrmsr(sint, orig | MSR_HV_SINT_MASKED);
-
+ vmbus_synic_teardown1();
/*
* Teardown SynIC message.
*/
- orig = rdmsr(MSR_HV_SIMP);
- wrmsr(MSR_HV_SIMP, (orig & MSR_HV_SIMP_RSVD_MASK));
+ orig = RDMSR(MSR_HV_SIMP);
+ WRMSR(MSR_HV_SIMP, (orig & MSR_HV_SIMP_RSVD_MASK));
/*
* Teardown SynIC event flags.
*/
- orig = rdmsr(MSR_HV_SIEFP);
- wrmsr(MSR_HV_SIEFP, (orig & MSR_HV_SIEFP_RSVD_MASK));
+ orig = RDMSR(MSR_HV_SIEFP);
+ WRMSR(MSR_HV_SIEFP, (orig & MSR_HV_SIEFP_RSVD_MASK));
}
static int
@@ -948,8 +917,9 @@
/* Allocate an interrupt counter for Hyper-V interrupt */
snprintf(buf, sizeof(buf), "cpu%d:hyperv", cpu);
+#if !defined(__aarch64__)
intrcnt_add(buf, VMBUS_PCPU_PTR(sc, intr_cnt, cpu));
-
+#endif /* not for aarch64 */
/*
* Setup taskqueue to handle events. Task will be per-
* channel.
@@ -981,57 +951,12 @@
TASK_INIT(VMBUS_PCPU_PTR(sc, message_task, cpu), 0,
vmbus_msg_task, sc);
}
-
-#if defined(__amd64__) && defined(KLD_MODULE)
- pmap_pti_add_kva(VMBUS_ISR_ADDR, VMBUS_ISR_ADDR + PAGE_SIZE, true);
-#endif
-
- /*
- * All Hyper-V ISR required resources are setup, now let's find a
- * free IDT vector for Hyper-V ISR and set it up.
- */
- sc->vmbus_idtvec = lapic_ipi_alloc(pti ? IDTVEC(vmbus_isr_pti) :
- IDTVEC(vmbus_isr));
- if (sc->vmbus_idtvec < 0) {
-#if defined(__amd64__) && defined(KLD_MODULE)
- pmap_pti_remove_kva(VMBUS_ISR_ADDR, VMBUS_ISR_ADDR + PAGE_SIZE);
-#endif
- device_printf(sc->vmbus_dev, "cannot find free IDT vector\n");
- return ENXIO;
- }
- if (bootverbose) {
- device_printf(sc->vmbus_dev, "vmbus IDT vector %d\n",
- sc->vmbus_idtvec);
- }
- return 0;
+ return (vmbus_setup_intr1(sc));
}
-
static void
vmbus_intr_teardown(struct vmbus_softc *sc)
{
- int cpu;
-
- if (sc->vmbus_idtvec >= 0) {
- lapic_ipi_free(sc->vmbus_idtvec);
- sc->vmbus_idtvec = -1;
- }
-
-#if defined(__amd64__) && defined(KLD_MODULE)
- pmap_pti_remove_kva(VMBUS_ISR_ADDR, VMBUS_ISR_ADDR + PAGE_SIZE);
-#endif
-
- CPU_FOREACH(cpu) {
- if (VMBUS_PCPU_GET(sc, event_tq, cpu) != NULL) {
- taskqueue_free(VMBUS_PCPU_GET(sc, event_tq, cpu));
- VMBUS_PCPU_GET(sc, event_tq, cpu) = NULL;
- }
- if (VMBUS_PCPU_GET(sc, message_tq, cpu) != NULL) {
- taskqueue_drain(VMBUS_PCPU_GET(sc, message_tq, cpu),
- VMBUS_PCPU_PTR(sc, message_task, cpu));
- taskqueue_free(VMBUS_PCPU_GET(sc, message_tq, cpu));
- VMBUS_PCPU_GET(sc, message_tq, cpu) = NULL;
- }
- }
+ vmbus_intr_teardown1(sc);
}
static int
@@ -1358,7 +1283,9 @@
vmbus_fb_mmio_res(device_t dev)
{
struct efi_fb *efifb;
+#if !defined(__aarch64__)
struct vbe_fb *vbefb;
+#endif /* aarch64 */
rman_res_t fb_start, fb_end, fb_count;
int fb_height, fb_width;
caddr_t kmdp;
@@ -1371,28 +1298,34 @@
kmdp = preload_search_by_type("elf64 kernel");
efifb = (struct efi_fb *)preload_search_info(kmdp,
MODINFO_METADATA | MODINFOMD_EFI_FB);
+#if !defined(__aarch64__)
vbefb = (struct vbe_fb *)preload_search_info(kmdp,
MODINFO_METADATA | MODINFOMD_VBE_FB);
+#endif /* aarch64 */
if (efifb != NULL) {
fb_start = efifb->fb_addr;
fb_end = efifb->fb_addr + efifb->fb_size;
fb_count = efifb->fb_size;
fb_height = efifb->fb_height;
fb_width = efifb->fb_width;
- } else if (vbefb != NULL) {
+ }
+#if !defined(__aarch64__)
+ else if (vbefb != NULL) {
fb_start = vbefb->fb_addr;
fb_end = vbefb->fb_addr + vbefb->fb_size;
fb_count = vbefb->fb_size;
fb_height = vbefb->fb_height;
fb_width = vbefb->fb_width;
- } else {
+ }
+#endif /* aarch64 */
+ else {
if (bootverbose)
device_printf(dev,
"no preloaded kernel fb information\n");
/* We are on Gen1 VM, just return. */
return;
}
-
+
if (bootverbose)
device_printf(dev,
"fb: fb_addr: %#jx, size: %#jx, "
@@ -1560,7 +1493,7 @@
{
}
-#ifdef EARLY_AP_STARTUP
+#if defined(EARLY_AP_STARTUP) || defined(__aarch64__)
static void
vmbus_intrhook(void *xsc)
@@ -1573,7 +1506,7 @@
config_intrhook_disestablish(&sc->vmbus_intrhook);
}
-#endif /* EARLY_AP_STARTUP */
+#endif /* EARLY_AP_STARTUP aarch64 */
static int
vmbus_attach(device_t dev)
@@ -1589,7 +1522,7 @@
*/
vmbus_sc->vmbus_event_proc = vmbus_event_proc_dummy;
-#ifdef EARLY_AP_STARTUP
+#if defined(EARLY_AP_STARTUP) || defined(__aarch64__)
/*
* Defer the real attach until the pause(9) works as expected.
*/
@@ -1605,7 +1538,7 @@
*/
if (!cold)
vmbus_doattach(vmbus_sc);
-#endif /* EARLY_AP_STARTUP */
+#endif /* EARLY_AP_STARTUP and aarch64 */
return (0);
}
@@ -1643,10 +1576,14 @@
vmbus_free_mmio_res(dev);
#endif
+#if defined(__aarch64__)
+ bus_release_resource(device_get_parent(dev), SYS_RES_IRQ, sc->vector,
+ sc->ires);
+#endif
return (0);
}
-#ifndef EARLY_AP_STARTUP
+#if !defined(EARLY_AP_STARTUP) && !defined(__aarch64__)
static void
vmbus_sysinit(void *arg __unused)
@@ -1662,7 +1599,7 @@
* global cold set to zero, we just call the driver
* initialization directly.
*/
- if (!cold)
+ if (!cold)
vmbus_doattach(sc);
}
/*
@@ -1671,5 +1608,4 @@
* initialized.
*/
SYSINIT(vmbus_initialize, SI_SUB_SMP, SI_ORDER_ANY, vmbus_sysinit, NULL);
-
#endif /* !EARLY_AP_STARTUP */
Index: sys/dev/hyperv/vmbus/vmbus_et.c
===================================================================
--- sys/dev/hyperv/vmbus/vmbus_et.c
+++ sys/dev/hyperv/vmbus/vmbus_et.c
@@ -37,7 +37,11 @@
#include <sys/timeet.h>
#include <dev/hyperv/include/hyperv.h>
-#include <dev/hyperv/vmbus/hyperv_reg.h>
+#if defined(__aarch64__)
+#include <dev/hyperv/vmbus/aarch64/hyperv_reg.h>
+#else
+#include <dev/hyperv/vmbus/x86/hyperv_reg.h>
+#endif
#include <dev/hyperv/vmbus/hyperv_var.h>
#include <dev/hyperv/vmbus/vmbus_var.h>
Index: sys/dev/hyperv/vmbus/vmbus_reg.h
===================================================================
--- sys/dev/hyperv/vmbus/vmbus_reg.h
+++ sys/dev/hyperv/vmbus/vmbus_reg.h
@@ -32,7 +32,11 @@
#include <sys/param.h>
#include <dev/hyperv/include/hyperv.h> /* XXX for hyperv_guid */
#include <dev/hyperv/include/vmbus.h>
-#include <dev/hyperv/vmbus/hyperv_reg.h>
+#if defined(__aarch64__)
+#include <dev/hyperv/vmbus/aarch64/hyperv_reg.h>
+#else
+#include <dev/hyperv/vmbus/x86/hyperv_reg.h>
+#endif
/*
* Hyper-V SynIC message format.
Index: sys/dev/hyperv/vmbus/vmbus_res.c
===================================================================
--- sys/dev/hyperv/vmbus/vmbus_res.c
+++ sys/dev/hyperv/vmbus/vmbus_res.c
@@ -39,10 +39,23 @@
#include "acpi_if.h"
#include "bus_if.h"
+#include "pcib_if.h"
static int vmbus_res_probe(device_t);
static int vmbus_res_attach(device_t);
static int vmbus_res_detach(device_t);
+#if defined(__aarch64__)
+static int acpi_syscont_alloc_msi(device_t, device_t,
+ int count, int maxcount, int *irqs);
+static int acpi_syscont_release_msi(device_t bus, device_t dev,
+ int count, int *irqs);
+static int acpi_syscont_alloc_msix(device_t bus, device_t dev,
+ int *irq);
+static int acpi_syscont_release_msix(device_t bus, device_t dev,
+ int irq);
+static int acpi_syscont_map_msi(device_t bus, device_t dev,
+ int irq, uint64_t *addr, uint32_t *data);
+#endif /* aarch64 */
static device_method_t vmbus_res_methods[] = {
/* Device interface */
@@ -52,7 +65,18 @@
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
-
+#if defined(__aarch64__)
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ /* pcib interface */
+ DEVMETHOD(pcib_alloc_msi, acpi_syscont_alloc_msi),
+ DEVMETHOD(pcib_release_msi, acpi_syscont_release_msi),
+ DEVMETHOD(pcib_alloc_msix, acpi_syscont_alloc_msix),
+ DEVMETHOD(pcib_release_msix, acpi_syscont_release_msix),
+ DEVMETHOD(pcib_map_msi, acpi_syscont_map_msi),
+#endif /* aarch64 */
DEVMETHOD_END
};
@@ -84,13 +108,65 @@
static int
vmbus_res_attach(device_t dev __unused)
{
-
+#if defined(__aarch64__)
+ bus_generic_probe(dev);
+ return(bus_generic_attach(dev));
+#endif /* aarch64 */
return (0);
}
static int
vmbus_res_detach(device_t dev __unused)
{
-
+#if defined(__aarch64__)
+ int error;
+ error = bus_generic_detach(dev);
+ if (error)
+ return (error);
+#endif
return (0);
}
+#if defined(__aarch64__)
+static int
+acpi_syscont_alloc_msi(device_t bus, device_t dev, int count, int maxcount,
+ int *irqs)
+{
+ device_t parent = device_get_parent(bus);
+
+ return (PCIB_ALLOC_MSI(device_get_parent(parent), dev, count, maxcount,
+ irqs));
+}
+
+static int
+acpi_syscont_release_msi(device_t bus, device_t dev, int count, int *irqs)
+{
+ device_t parent = device_get_parent(bus);
+
+ return (PCIB_RELEASE_MSI(device_get_parent(parent), dev, count, irqs));
+}
+
+static int
+acpi_syscont_alloc_msix(device_t bus, device_t dev, int *irq)
+{
+ device_t parent = device_get_parent(bus);
+
+ return (PCIB_ALLOC_MSIX(device_get_parent(parent), dev, irq));
+}
+
+static int
+acpi_syscont_release_msix(device_t bus, device_t dev, int irq)
+{
+ device_t parent = device_get_parent(bus);
+
+ return (PCIB_RELEASE_MSIX(device_get_parent(parent), dev, irq));
+}
+
+static int
+acpi_syscont_map_msi(device_t bus, device_t dev, int irq, uint64_t *addr,
+ uint32_t *data)
+{
+ device_t parent = device_get_parent(bus);
+
+ return (PCIB_MAP_MSI(device_get_parent(parent), dev, irq, addr, data));
+}
+#endif /* aarch64 */
Index: sys/dev/hyperv/vmbus/vmbus_var.h
===================================================================
--- sys/dev/hyperv/vmbus/vmbus_var.h
+++ sys/dev/hyperv/vmbus/vmbus_var.h
@@ -135,6 +135,12 @@
/* The list of usable MMIO ranges for PCIe pass-through */
struct pcib_host_resources vmbus_mmio_res;
#endif
+
+#if defined(__aarch64__)
+ struct resource *ires;
+ void *icookie;
+ int vector;
+#endif
};
#define VMBUS_FLAG_ATTACHED 0x0001 /* vmbus was attached */
@@ -151,7 +157,9 @@
void vmbus_handle_intr(struct trapframe *);
int vmbus_add_child(struct vmbus_channel *);
int vmbus_delete_child(struct vmbus_channel *);
+#if !defined(__aarch64__)
void vmbus_et_intr(struct trapframe *);
+#endif
uint32_t vmbus_gpadl_alloc(struct vmbus_softc *);
struct vmbus_msghc *
@@ -172,4 +180,11 @@
const struct vmbus_message *);
void vmbus_msghc_reset(struct vmbus_msghc *, size_t);
+void vmbus_handle_timer_intr1(struct vmbus_message *msg_base,
+ struct trapframe *frame);
+
+void vmbus_synic_setup1(void *xsc);
+void vmbus_synic_teardown1(void);
+int vmbus_setup_intr1(struct vmbus_softc *sc);
+void vmbus_intr_teardown1(struct vmbus_softc *sc);
#endif /* !_VMBUS_VAR_H_ */
Index: sys/modules/Makefile
===================================================================
--- sys/modules/Makefile
+++ sys/modules/Makefile
@@ -650,6 +650,7 @@
_sdhci_fdt= sdhci_fdt
_e6000sw= e6000sw
_neta= neta
+_hyperv= hyperv
.endif
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
Index: sys/modules/hyperv/utilities/Makefile
===================================================================
--- sys/modules/hyperv/utilities/Makefile
+++ sys/modules/hyperv/utilities/Makefile
@@ -5,7 +5,6 @@
KMOD= hv_utils
SRCS= vmbus_ic.c
SRCS+= hv_kvp.c
-SRCS+= hv_snapshot.c
SRCS+= vmbus_heartbeat.c
SRCS+= vmbus_shutdown.c
SRCS+= vmbus_timesync.c
Index: sys/modules/hyperv/vmbus/Makefile
===================================================================
--- sys/modules/hyperv/vmbus/Makefile
+++ sys/modules/hyperv/vmbus/Makefile
@@ -1,7 +1,8 @@
# $FreeBSD$
.PATH: ${SRCTOP}/sys/dev/hyperv/vmbus \
- ${SRCTOP}/sys/dev/hyperv/vmbus/${MACHINE_CPUARCH}
+ ${SRCTOP}/sys/dev/hyperv/vmbus/${MACHINE_CPUARCH} \
+ ${SRCTOP}/sys/dev/hyperv/vmbus/x86
KMOD= hv_vmbus
SRCS= hyperv.c \
@@ -10,14 +11,18 @@
vmbus.c \
vmbus_br.c \
vmbus_chan.c \
- vmbus_et.c \
vmbus_if.c \
vmbus_res.c \
vmbus_xact.c
-.if ${MACHINE_CPUARCH} != "i386"
+.if ${MACHINE_CPUARCH} != "i386" && ${MACHINE_CPUARCH} != "aarch64"
SRCS+= vmbus_vector.S
.endif
+.if ${MACHINE_CPUARCH} != "aarch64"
+SRCS+= vmbus_et.c hyperv_x86.c vmbus_x86.c
+.else
+SRC+= hyperv_aarch64.c vmbus_aarch64.c
+.endif
SRCS+= acpi_if.h bus_if.h device_if.h opt_acpi.h pci_if.h pcib_if.h vmbus_if.h
# XXX: for assym.inc
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Aug 19, 2:58 PM (5 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36940605
Default Alt Text
D36467.id110216.diff (29 KB)
Attached To
Mode
D36467: FreeBSD enablement for ARM64 in Hyper-V
Attached
Detach File
Event Timeline
Log In to Comment