Here is the list of specific changes: - where required by C++ compiler applied appropriate C++ cast (static_cast, reinterpret_cast, const_cast) - where necessary replaced FreeBSD headers with OSv BSD porting headers (like <bsd/porting/…>) - replaced *msr() calls with corresponding OSv processor::*msr() calls (for example rdmsr() with processor::rdmsr()) - replaced do_cpuid() with processor::cpuid() - temporarily disabled code that will eventually be used once VMBus based drivers are ported to OSv - commented out or disabled code that does not apply to OSv - added hyperv_is_timecount_available() to allow detection of time reference count mechanism - disabled all FreeBSD SYSCTL related code
Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com> --- Makefile | 2 + bsd/sys/dev/hyperv/include/hyperv.h | 3 + bsd/sys/dev/hyperv/include/vmbus.h | 2 +- bsd/sys/dev/hyperv/vmbus/hyperv.cc | 212 ++++++++++++++++++++-------------- bsd/sys/dev/hyperv/vmbus/hyperv_reg.h | 193 +++++++++++++++++++++++++++++++ 5 files changed, 323 insertions(+), 89 deletions(-) create mode 100644 bsd/sys/dev/hyperv/vmbus/hyperv_reg.h diff --git a/Makefile b/Makefile index ca80cea..504d5d1 100644 --- a/Makefile +++ b/Makefile @@ -618,6 +618,8 @@ bsd += bsd/sys/dev/xen/netfront/netfront.o bsd += bsd/sys/dev/xen/blkfront/blkfront.o endif +bsd += bsd/sys/dev/hyperv/vmbus/hyperv.o + bsd += bsd/sys/dev/random/hash.o bsd += bsd/sys/dev/random/randomdev_soft.o bsd += bsd/sys/dev/random/yarrow.o diff --git a/bsd/sys/dev/hyperv/include/hyperv.h b/bsd/sys/dev/hyperv/include/hyperv.h index 4d0f5b7..7b26380 100644 --- a/bsd/sys/dev/hyperv/include/hyperv.h +++ b/bsd/sys/dev/hyperv/include/hyperv.h @@ -91,6 +91,9 @@ int hyperv_guid2str(const struct hyperv_guid *, char *, extern hyperv_tc64_t hyperv_tc64; extern u_int hyperv_features; /* CPUID_HV_MSR_ */ +bool hyperv_identify(void); +bool hyperv_is_timecount_available(); + #endif /* _KERNEL */ #endif /* _HYPERV_H_ */ diff --git a/bsd/sys/dev/hyperv/include/vmbus.h b/bsd/sys/dev/hyperv/include/vmbus.h index 73c4561..c1db27f 100644 --- a/bsd/sys/dev/hyperv/include/vmbus.h +++ b/bsd/sys/dev/hyperv/include/vmbus.h @@ -130,7 +130,7 @@ typedef void (*vmbus_chan_callback_t)(struct vmbus_channel *, void *); static __inline struct vmbus_channel * vmbus_get_channel(device_t dev) { - return device_get_ivars(dev); + return static_cast<struct vmbus_channel *>(device_get_ivars(dev)); } /* diff --git a/bsd/sys/dev/hyperv/vmbus/hyperv.cc b/bsd/sys/dev/hyperv/vmbus/hyperv.cc index 757672a..8221d0c 100644 --- a/bsd/sys/dev/hyperv/vmbus/hyperv.cc +++ b/bsd/sys/dev/hyperv/vmbus/hyperv.cc @@ -32,17 +32,24 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <bsd/porting/netport.h> + #include <sys/param.h> #include <sys/kernel.h> #include <sys/systm.h> -#include <sys/timetc.h> +#include <sys/conf.h> #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> +#ifdef OSV_VMBUS_ENABLED // Temporarily disable the code until VMBus based drivers are ported to OSv +#include <dev/hyperv/vmbus/hyperv_machdep.h> #include <dev/hyperv/vmbus/hyperv_var.h> +#endif +#include <osv/debug.hh> + +/* #define HYPERV_FREEBSD_BUILD 0ULL #define HYPERV_FREEBSD_VERSION ((uint64_t)__FreeBSD_version) #define HYPERV_FREEBSD_OSID 0ULL @@ -61,15 +68,18 @@ __FBSDID("$FreeBSD$"); MSR_HV_GUESTID_VERSION_FREEBSD | \ MSR_HV_GUESTID_OSID_FREEBSD | \ MSR_HV_GUESTID_OSTYPE_FREEBSD) - +*/ struct hypercall_ctx { void *hc_addr; struct hyperv_dma hc_dma; }; +#if 0 static u_int hyperv_get_timecount(struct timecounter *); -static bool hyperv_identify(void); +#endif +#ifdef OSV_VMBUS_ENABLED static void hypercall_memfree(void); +#endif u_int hyperv_features; u_int hyperv_recommends; @@ -79,6 +89,7 @@ static u_int hyperv_features3; hyperv_tc64_t hyperv_tc64; +#if 0 // Used by tc_init() which does not apply to OSv static struct timecounter hyperv_timecounter = { .tc_get_timecount = hyperv_get_timecount, .tc_poll_pps = NULL, @@ -89,22 +100,32 @@ static struct timecounter hyperv_timecounter = { .tc_flags = 0, .tc_priv = NULL }; +#endif +#ifdef OSV_VMBUS_ENABLED static struct hypercall_ctx hypercall_context; +#endif +#if 0 static u_int hyperv_get_timecount(struct timecounter *tc __unused) { - return rdmsr(MSR_HV_TIME_REF_COUNT); + return processor::rdmsr(MSR_HV_TIME_REF_COUNT); } +#endif -static uint64_t +bool +hyperv_is_timecount_available() { + return (hyperv_features & CPUID_HV_MSR_TIME_REFCNT); +} + +uint64_t hyperv_tc64_rdmsr(void) { - - return (rdmsr(MSR_HV_TIME_REF_COUNT)); + return (processor::rdmsr(MSR_HV_TIME_REF_COUNT)); } +#ifdef OSV_VMBUS_ENABLED // Temporarily disable the code until VMBus based drivers are ported to OSv uint64_t hypercall_post_message(bus_addr_t msg_paddr) { @@ -131,116 +152,122 @@ hyperv_guid2str(const struct hyperv_guid *guid, char *buf, size_t sz) d[5], d[4], d[7], d[6], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); } +#endif -static bool +bool hyperv_identify(void) { - u_int regs[4]; + struct processor::cpuid_result regs; unsigned int maxleaf; + /* INVESTIGATE: How do I know that OSv is running on Hyper-V? if (vm_guest != VM_GUEST_HV) return (false); + */ - do_cpuid(CPUID_LEAF_HV_MAXLEAF, regs); - maxleaf = regs[0]; + regs = processor::cpuid(CPUID_LEAF_HV_MAXLEAF); + maxleaf = regs.a; if (maxleaf < CPUID_LEAF_HV_LIMITS) return (false); - do_cpuid(CPUID_LEAF_HV_INTERFACE, regs); - if (regs[0] != CPUID_HV_IFACE_HYPERV) + regs = processor::cpuid(CPUID_LEAF_HV_INTERFACE); + if (regs.a != CPUID_HV_IFACE_HYPERV) return (false); - do_cpuid(CPUID_LEAF_HV_FEATURES, regs); - if ((regs[0] & CPUID_HV_MSR_HYPERCALL) == 0) { + regs = processor::cpuid(CPUID_LEAF_HV_FEATURES); + if ((regs.a & 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); - printf("Hyper-V Version: %d.%d.%d [SP%d]\n", - regs[1] >> 16, 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]); - } - } + hyperv_features = regs.a; + hyperv_pm_features = regs.c; + hyperv_features3 = regs.d; + +// regs = processor::cpuid(CPUID_LEAF_HV_IDENTITY); +// printf("Hyper-V Version: %d.%d.%d [SP%d]\n", +// regs.b >> 16, regs.b & 0xffff, regs.a, regs.c); +// +// 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 */ + + regs = processor::cpuid(CPUID_LEAF_HV_RECOMMENDS); + hyperv_recommends = regs.a; +// if (bootverbose) +// printf(" Recommends: %08x %08x\n", regs.a, regs.b); +// +// regs = processor::cpuid(CPUID_LEAF_HV_LIMITS); +// if (bootverbose) { +// printf(" Limits: Vcpu:%d Lcpu:%d Int:%d\n", +// regs.a, regs.b, regs.c); +// } + +// if (maxleaf >= CPUID_LEAF_HV_HWFEATURES) { +// regs = processor::cpuid(CPUID_LEAF_HV_HWFEATURES); +// if (bootverbose) { +// printf(" HW Features: %08x, AMD: %08x\n", +// regs.a, regs.d); +// } +// } return (true); } -static void +#if 0 //The function hyperv_init() does not apply to OSv as is +void hyperv_init(void *dummy __unused) { if (!hyperv_identify()) { /* Not Hyper-V; reset guest id to the generic one. */ if (vm_guest == VM_GUEST_HV) vm_guest = VM_GUEST_VM; + return; } /* Set guest id */ - wrmsr(MSR_HV_GUEST_OS_ID, MSR_HV_GUESTID_FREEBSD); + processor::wrmsr(MSR_HV_GUEST_OS_ID, MSR_HV_GUESTID_FREEBSD); if (hyperv_features & CPUID_HV_MSR_TIME_REFCNT) { /* Register Hyper-V timecounter */ tc_init(&hyperv_timecounter); + hyperv_timecounter.tc_flags = 0; /* * Install 64 bits timecounter method for other modules @@ -251,7 +278,9 @@ hyperv_init(void *dummy __unused) } SYSINIT(hyperv_initialize, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, hyperv_init, NULL); +#endif +#ifdef OSV_VMBUS_ENABLED // Temporarily disable the code until VMBus based drivers are ported to OSv static void hypercall_memfree(void) { @@ -260,25 +289,29 @@ hypercall_memfree(void) hypercall_context.hc_addr = NULL; } -static void +void hypercall_create(void *arg __unused) { uint64_t hc, hc_orig; + /* INVESTIGATE: For now disable logic related to detecting if OSv is running on Hyper/V if (vm_guest != VM_GUEST_HV) return; + */ hypercall_context.hc_addr = hyperv_dmamem_alloc(NULL, PAGE_SIZE, 0, PAGE_SIZE, &hypercall_context.hc_dma, BUS_DMA_WAITOK); if (hypercall_context.hc_addr == NULL) { printf("hyperv: Hypercall page allocation failed\n"); /* Can't perform any Hyper-V specific actions */ + /* INVESTIGATE: For now disable logic related to detecting if OSv is running on Hyper/V vm_guest = VM_GUEST_VM; + */ return; } /* Get the 'reserved' bits, which requires preservation. */ - hc_orig = rdmsr(MSR_HV_HYPERCALL); + hc_orig = processor::rdmsr(MSR_HV_HYPERCALL); /* * Setup the Hypercall page. @@ -289,17 +322,19 @@ hypercall_create(void *arg __unused) MSR_HV_HYPERCALL_PGSHIFT) | (hc_orig & MSR_HV_HYPERCALL_RSVD_MASK) | MSR_HV_HYPERCALL_ENABLE; - wrmsr(MSR_HV_HYPERCALL, hc); + processor::wrmsr(MSR_HV_HYPERCALL, hc); /* * Confirm that Hypercall page did get setup. */ - hc = rdmsr(MSR_HV_HYPERCALL); + hc = processor::rdmsr(MSR_HV_HYPERCALL); if ((hc & MSR_HV_HYPERCALL_ENABLE) == 0) { printf("hyperv: Hypercall setup failed\n"); hypercall_memfree(); /* Can't perform any Hyper-V specific actions */ + /* INVESTIGATE: For now disable logic related to detecting if OSv is running on Hyper/V vm_guest = VM_GUEST_VM; + */ return; } if (bootverbose) @@ -307,7 +342,7 @@ hypercall_create(void *arg __unused) } SYSINIT(hypercall_ctor, SI_SUB_DRIVERS, SI_ORDER_FIRST, hypercall_create, NULL); -static void +void hypercall_destroy(void *arg __unused) { uint64_t hc; @@ -316,8 +351,8 @@ hypercall_destroy(void *arg __unused) return; /* Disable Hypercall */ - hc = rdmsr(MSR_HV_HYPERCALL); - wrmsr(MSR_HV_HYPERCALL, (hc & MSR_HV_HYPERCALL_RSVD_MASK)); + hc = processor::rdmsr(MSR_HV_HYPERCALL); + processor::wrmsr(MSR_HV_HYPERCALL, (hc & MSR_HV_HYPERCALL_RSVD_MASK)); hypercall_memfree(); if (bootverbose) @@ -325,3 +360,4 @@ hypercall_destroy(void *arg __unused) } SYSUNINIT(hypercall_dtor, SI_SUB_DRIVERS, SI_ORDER_FIRST, hypercall_destroy, NULL); +#endif \ No newline at end of file diff --git a/bsd/sys/dev/hyperv/vmbus/hyperv_reg.h b/bsd/sys/dev/hyperv/vmbus/hyperv_reg.h new file mode 100644 index 0000000..0987adc --- /dev/null +++ b/bsd/sys/dev/hyperv/vmbus/hyperv_reg.h @@ -0,0 +1,193 @@ +/*- + * Copyright (c) 2016 Microsoft Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _HYPERV_REG_H_ +#define _HYPERV_REG_H_ + +#include <sys/param.h> +#include <sys/systm.h> + +/* + * Hyper-V Synthetic MSRs + */ + +#define MSR_HV_GUEST_OS_ID 0x40000000 +#define MSR_HV_GUESTID_BUILD_MASK 0xffffULL +#define MSR_HV_GUESTID_VERSION_MASK 0x0000ffffffff0000ULL +#define MSR_HV_GUESTID_VERSION_SHIFT 16 +#define MSR_HV_GUESTID_OSID_MASK 0x00ff000000000000ULL +#define MSR_HV_GUESTID_OSID_SHIFT 48 +#define MSR_HV_GUESTID_OSTYPE_MASK 0x7f00000000000000ULL +#define MSR_HV_GUESTID_OSTYPE_SHIFT 56 +#define MSR_HV_GUESTID_OPENSRC 0x8000000000000000ULL +#define MSR_HV_GUESTID_OSTYPE_LINUX \ + ((0x01ULL << MSR_HV_GUESTID_OSTYPE_SHIFT) | MSR_HV_GUESTID_OPENSRC) +#define MSR_HV_GUESTID_OSTYPE_FREEBSD \ + ((0x02ULL << MSR_HV_GUESTID_OSTYPE_SHIFT) | MSR_HV_GUESTID_OPENSRC) + +#define MSR_HV_HYPERCALL 0x40000001 +#define MSR_HV_HYPERCALL_ENABLE 0x0001ULL +#define MSR_HV_HYPERCALL_RSVD_MASK 0x0ffeULL +#define MSR_HV_HYPERCALL_PGSHIFT 12 + +#define MSR_HV_VP_INDEX 0x40000002 + +#define MSR_HV_REFERENCE_TSC 0x40000021 +#define MSR_HV_REFTSC_ENABLE 0x0001ULL +#define MSR_HV_REFTSC_RSVD_MASK 0x0ffeULL +#define MSR_HV_REFTSC_PGSHIFT 12 + +#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_EOM 0x40000084 + +#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) + +#define MSR_HV_STIMER0_CONFIG 0x400000b0 +#define MSR_HV_STIMER_CFG_ENABLE 0x0001ULL +#define MSR_HV_STIMER_CFG_PERIODIC 0x0002ULL +#define MSR_HV_STIMER_CFG_LAZY 0x0004ULL +#define MSR_HV_STIMER_CFG_AUTOEN 0x0008ULL +#define MSR_HV_STIMER_CFG_SINT_MASK 0x000f0000ULL +#define MSR_HV_STIMER_CFG_SINT_SHIFT 16 + +#define MSR_HV_STIMER0_COUNT 0x400000b1 + +/* + * CPUID leaves + */ + +#define CPUID_LEAF_HV_MAXLEAF 0x40000000 + +#define CPUID_LEAF_HV_INTERFACE 0x40000001 +#define CPUID_HV_IFACE_HYPERV 0x31237648 /* HV#1 */ + +#define CPUID_LEAF_HV_IDENTITY 0x40000002 + +#define CPUID_LEAF_HV_FEATURES 0x40000003 +/* EAX: features include/hyperv.h CPUID_HV_MSR */ +/* ECX: power management features */ +#define CPUPM_HV_CSTATE_MASK 0x000f /* deepest C-state */ +#define CPUPM_HV_C3_HPET 0x0010 /* C3 requires HPET */ +#define CPUPM_HV_CSTATE(f) ((f) & CPUPM_HV_CSTATE_MASK) +/* EDX: features3 */ +#define CPUID3_HV_MWAIT 0x0001 /* MWAIT */ +#define CPUID3_HV_XMM_HYPERCALL 0x0010 /* Hypercall input through + * XMM regs */ +#define CPUID3_HV_GUEST_IDLE 0x0020 /* guest idle */ +#define CPUID3_HV_NUMA 0x0080 /* NUMA distance query */ +#define CPUID3_HV_TIME_FREQ 0x0100 /* timer frequency query + * (TSC, LAPIC) */ +#define CPUID3_HV_MSR_CRASH 0x0400 /* MSRs for guest crash */ + +#define CPUID_LEAF_HV_RECOMMENDS 0x40000004 +#define CPUID_LEAF_HV_LIMITS 0x40000005 +#define CPUID_LEAF_HV_HWFEATURES 0x40000006 + +/* + * Hyper-V Monitor Notification Facility + */ +struct hyperv_mon_param { + uint32_t mp_connid; + uint16_t mp_evtflag_ofs; + uint16_t mp_rsvd; +} __packed; + +/* + * Hyper-V message types + */ +#define HYPERV_MSGTYPE_NONE 0 +#define HYPERV_MSGTYPE_CHANNEL 1 +#define HYPERV_MSGTYPE_TIMER_EXPIRED 0x80000010 + +/* + * Hypercall status codes + */ +#define HYPERCALL_STATUS_SUCCESS 0x0000 + +/* + * Hypercall input values + */ +#define HYPERCALL_POST_MESSAGE 0x005c +#define HYPERCALL_SIGNAL_EVENT 0x005d + +/* + * Hypercall input parameters + */ +#define HYPERCALL_PARAM_ALIGN 8 +#if 0 +/* + * XXX + * <<Hypervisor Top Level Functional Specification 4.0b>> requires + * input parameters size to be multiple of 8, however, many post + * message input parameters do _not_ meet this requirement. + */ +#define HYPERCALL_PARAM_SIZE_ALIGN 8 +#endif + +/* + * HYPERCALL_POST_MESSAGE + */ +#define HYPERCALL_POSTMSGIN_DSIZE_MAX 240 +#define HYPERCALL_POSTMSGIN_SIZE 256 + +struct hypercall_postmsg_in { + uint32_t hc_connid; + uint32_t hc_rsvd; + uint32_t hc_msgtype; /* HYPERV_MSGTYPE_ */ + uint32_t hc_dsize; + uint8_t hc_data[HYPERCALL_POSTMSGIN_DSIZE_MAX]; +} __packed; +CTASSERT(sizeof(struct hypercall_postmsg_in) == HYPERCALL_POSTMSGIN_SIZE); + +/* + * HYPERCALL_SIGNAL_EVENT + * + * struct hyperv_mon_param. + */ + +#endif /* !_HYPERV_REG_H_ */ -- 2.7.4 -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to osv-dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.