/*
 * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

/** @file
 *
 * Hyper-V driver
 *
 */

#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <byteswap.h>
#include <pic8259.h>
#include <ipxe/malloc.h>
#include <ipxe/device.h>
#include <ipxe/timer.h>
#include <ipxe/quiesce.h>
#include <ipxe/cpuid.h>
#include <ipxe/msr.h>
#include <ipxe/hyperv.h>
#include <ipxe/vmbus.h>
#include "hyperv.h"

/** Maximum time to wait for a message response
 *
 * This is a policy decision.
 */
#define HV_MESSAGE_MAX_WAIT_MS 1000

/** Hyper-V timer frequency (fixed 10Mhz) */
#define HV_TIMER_HZ 10000000

/** Hyper-V timer scale factor (used to avoid 64-bit division) */
#define HV_TIMER_SHIFT 18

/**
 * Convert a Hyper-V status code to an iPXE status code
 *
 * @v status		Hyper-V status code
 * @ret rc		iPXE status code (before negation)
 */
#define EHV( status ) EPLATFORM ( EINFO_EPLATFORM, (status) )

/**
 * Allocate zeroed pages
 *
 * @v hv		Hyper-V hypervisor
 * @v ...		Page addresses to fill in, terminated by NULL
 * @ret rc		Return status code
 */
__attribute__ (( sentinel )) int
hv_alloc_pages ( struct hv_hypervisor *hv, ... ) {
	va_list args;
	void **page;
	int i;

	/* Allocate and zero pages */
	va_start ( args, hv );
	for ( i = 0 ; ( ( page = va_arg ( args, void ** ) ) != NULL ); i++ ) {
		*page = malloc_phys ( PAGE_SIZE, PAGE_SIZE );
		if ( ! *page )
			goto err_alloc;
		memset ( *page, 0, PAGE_SIZE );
	}
	va_end ( args );

	return 0;

 err_alloc:
	va_end ( args );
	va_start ( args, hv );
	for ( ; i >= 0 ; i-- ) {
		page = va_arg ( args, void ** );
		free_phys ( *page, PAGE_SIZE );
	}
	va_end ( args );
	return -ENOMEM;
}

/**
 * Free pages
 *
 * @v hv		Hyper-V hypervisor
 * @v ...		Page addresses, terminated by NULL
 */
__attribute__ (( sentinel )) void
hv_free_pages ( struct hv_hypervisor *hv, ... ) {
	va_list args;
	void *page;

	va_start ( args, hv );
	while ( ( page = va_arg ( args, void * ) ) != NULL )
		free_phys ( page, PAGE_SIZE );
	va_end ( args );
}

/**
 * Allocate message buffer
 *
 * @v hv		Hyper-V hypervisor
 * @ret rc		Return status code
 */
static int hv_alloc_message ( struct hv_hypervisor *hv ) {

	/* Allocate buffer.  Must be aligned to at least 8 bytes and
	 * must not cross a page boundary, so align on its own size.
	 */
	hv->message = malloc_phys ( sizeof ( *hv->message ),
				    sizeof ( *hv->message ) );
	if ( ! hv->message )
		return -ENOMEM;

	return 0;
}

/**
 * Free message buffer
 *
 * @v hv		Hyper-V hypervisor
 */
static void hv_free_message ( struct hv_hypervisor *hv ) {

	/* Free buffer */
	free_phys ( hv->message, sizeof ( *hv->message ) );
}

/**
 * Check whether or not we are running in Hyper-V
 *
 * @ret rc		Return status code
 */
static int hv_check_hv ( void ) {
	struct x86_features features;
	uint32_t interface_id;
	uint32_t discard_ebx;
	uint32_t discard_ecx;
	uint32_t discard_edx;

	/* Check for presence of a hypervisor (not necessarily Hyper-V) */
	x86_features ( &features );
	if ( ! ( features.intel.ecx & CPUID_FEATURES_INTEL_ECX_HYPERVISOR ) ) {
		DBGC ( HV_INTERFACE_ID, "HV not running in a hypervisor\n" );
		return -ENODEV;
	}

	/* Check that hypervisor is Hyper-V */
	cpuid ( HV_CPUID_INTERFACE_ID, 0, &interface_id, &discard_ebx,
		&discard_ecx, &discard_edx );
	if ( interface_id != HV_INTERFACE_ID ) {
		DBGC ( HV_INTERFACE_ID, "HV not running in Hyper-V (interface "
		       "ID %#08x)\n", interface_id );
		return -ENODEV;
	}

	return 0;
}

/**
 * Check required features
 *
 * @v hv		Hyper-V hypervisor
 * @ret rc		Return status code
 */
static int hv_check_features ( struct hv_hypervisor *hv ) {
	uint32_t available;
	uint32_t permissions;
	uint32_t discard_ecx;
	uint32_t discard_edx;

	/* Check that required features and privileges are available */
	cpuid ( HV_CPUID_FEATURES, 0, &available, &permissions, &discard_ecx,
		&discard_edx );
	if ( ! ( available & HV_FEATURES_AVAIL_HYPERCALL_MSR ) ) {
		DBGC ( hv, "HV %p has no hypercall MSRs (features %08x:%08x)\n",
		       hv, available, permissions );
		return -ENODEV;
	}
	if ( ! ( available & HV_FEATURES_AVAIL_SYNIC_MSR ) ) {
		DBGC ( hv, "HV %p has no SynIC MSRs (features %08x:%08x)\n",
		       hv, available, permissions );
		return -ENODEV;
	}
	if ( ! ( permissions & HV_FEATURES_PERM_POST_MESSAGES ) ) {
		DBGC ( hv, "HV %p cannot post messages (features %08x:%08x)\n",
		       hv, available, permissions );
		return -EACCES;
	}
	if ( ! ( permissions & HV_FEATURES_PERM_SIGNAL_EVENTS ) ) {
		DBGC ( hv, "HV %p cannot signal events (features %08x:%08x)",
		       hv, available, permissions );
		return -EACCES;
	}

	return 0;
}

/**
 * Check that Gen 2 UEFI firmware is not running
 *
 * @v hv		Hyper-V hypervisor
 * @ret rc		Return status code
 *
 * We must not steal ownership from the Gen 2 UEFI firmware, since
 * doing so will cause an immediate crash.  Avoid this by checking for
 * the guest OS identity known to be used by the Gen 2 UEFI firmware.
 */
static int hv_check_uefi ( struct hv_hypervisor *hv ) {
	uint64_t guest_os_id;

	/* Check for UEFI firmware's guest OS identity */
	guest_os_id = rdmsr ( HV_X64_MSR_GUEST_OS_ID );
	if ( guest_os_id == HV_GUEST_OS_ID_UEFI ) {
		DBGC ( hv, "HV %p is owned by UEFI firmware\n", hv );
		return -ENOTSUP;
	}

	return 0;
}

/**
 * Map hypercall page
 *
 * @v hv		Hyper-V hypervisor
 */
static void hv_map_hypercall ( struct hv_hypervisor *hv ) {
	union {
		struct {
			uint32_t ebx;
			uint32_t ecx;
			uint32_t edx;
		} __attribute__ (( packed ));
		char text[ 13 /* "bbbbccccdddd" + NUL */ ];
	} vendor_id;
	uint32_t build;
	uint32_t version;
	uint32_t discard_eax;
	uint32_t discard_ecx;
	uint32_t discard_edx;
	uint64_t guest_os_id;
	uint64_t hypercall;

	/* Report guest OS identity */
	guest_os_id = rdmsr ( HV_X64_MSR_GUEST_OS_ID );
	if ( guest_os_id != 0 ) {
		DBGC ( hv, "HV %p guest OS ID MSR was %#08llx\n",
		       hv, guest_os_id );
	}
	guest_os_id = HV_GUEST_OS_ID_IPXE;
	DBGC2 ( hv, "HV %p guest OS ID MSR is %#08llx\n", hv, guest_os_id );
	wrmsr ( HV_X64_MSR_GUEST_OS_ID, guest_os_id );

	/* Get hypervisor system identity (for debugging) */
	cpuid ( HV_CPUID_VENDOR_ID, 0, &discard_eax, &vendor_id.ebx,
		&vendor_id.ecx, &vendor_id.edx );
	vendor_id.text[ sizeof ( vendor_id.text ) - 1 ] = '\0';
	cpuid ( HV_CPUID_HYPERVISOR_ID, 0, &build, &version, &discard_ecx,
		&discard_edx );
	DBGC ( hv, "HV %p detected \"%s\" version %d.%d build %d\n", hv,
	       vendor_id.text, ( version >> 16 ), ( version & 0xffff ), build );

	/* Map hypercall page */
	hypercall = rdmsr ( HV_X64_MSR_HYPERCALL );
	hypercall &= ( PAGE_SIZE - 1 );
	hypercall |= ( virt_to_phys ( hv->hypercall ) | HV_HYPERCALL_ENABLE );
	DBGC2 ( hv, "HV %p hypercall MSR is %#08llx\n", hv, hypercall );
	wrmsr ( HV_X64_MSR_HYPERCALL, hypercall );
}

/**
 * Unmap hypercall page
 *
 * @v hv		Hyper-V hypervisor
 */
static void hv_unmap_hypercall ( struct hv_hypervisor *hv ) {
	uint64_t hypercall;
	uint64_t guest_os_id;

	/* Unmap the hypercall page */
	hypercall = rdmsr ( HV_X64_MSR_HYPERCALL );
	hypercall &= ( ( PAGE_SIZE - 1 ) & ~HV_HYPERCALL_ENABLE );
	DBGC2 ( hv, "HV %p hypercall MSR is %#08llx\n", hv, hypercall );
	wrmsr ( HV_X64_MSR_HYPERCALL, hypercall );

	/* Reset the guest OS identity */
	guest_os_id = 0;
	DBGC2 ( hv, "HV %p guest OS ID MSR is %#08llx\n", hv, guest_os_id );
	wrmsr ( HV_X64_MSR_GUEST_OS_ID, guest_os_id );
}

/**
 * Map synthetic interrupt controller
 *
 * @v hv		Hyper-V hypervisor
 */
static void hv_map_synic ( struct hv_hypervisor *hv ) {
	uint64_t simp;
	uint64_t siefp;
	uint64_t scontrol;

	/* Zero SynIC message and event pages */
	memset ( hv->synic.message, 0, PAGE_SIZE );
	memset ( hv->synic.event, 0, PAGE_SIZE );

	/* Map SynIC message page */
	simp = rdmsr ( HV_X64_MSR_SIMP );
	simp &= ( PAGE_SIZE - 1 );
	simp |= ( virt_to_phys ( hv->synic.message ) | HV_SIMP_ENABLE );
	DBGC2 ( hv, "HV %p SIMP MSR is %#08llx\n", hv, simp );
	wrmsr ( HV_X64_MSR_SIMP, simp );

	/* Map SynIC event page */
	siefp = rdmsr ( HV_X64_MSR_SIEFP );
	siefp &= ( PAGE_SIZE - 1 );
	siefp |= ( virt_to_phys ( hv->synic.event ) | HV_SIEFP_ENABLE );
	DBGC2 ( hv, "HV %p SIEFP MSR is %#08llx\n", hv, siefp );
	wrmsr ( HV_X64_MSR_SIEFP, siefp );

	/* Enable SynIC */
	scontrol = rdmsr ( HV_X64_MSR_SCONTROL );
	scontrol |= HV_SCONTROL_ENABLE;
	DBGC2 ( hv, "HV %p SCONTROL MSR is %#08llx\n", hv, scontrol );
	wrmsr ( HV_X64_MSR_SCONTROL, scontrol );
}

/**
 * Unmap synthetic interrupt controller, leaving SCONTROL untouched
 *
 * @v hv		Hyper-V hypervisor
 */
static void hv_unmap_synic_no_scontrol ( struct hv_hypervisor *hv ) {
	uint64_t siefp;
	uint64_t simp;

	/* Unmap SynIC event page */
	siefp = rdmsr ( HV_X64_MSR_SIEFP );
	siefp &= ( ( PAGE_SIZE - 1 ) & ~HV_SIEFP_ENABLE );
	DBGC2 ( hv, "HV %p SIEFP MSR is %#08llx\n", hv, siefp );
	wrmsr ( HV_X64_MSR_SIEFP, siefp );

	/* Unmap SynIC message page */
	simp = rdmsr ( HV_X64_MSR_SIMP );
	simp &= ( ( PAGE_SIZE - 1 ) & ~HV_SIMP_ENABLE );
	DBGC2 ( hv, "HV %p SIMP MSR is %#08llx\n", hv, simp );
	wrmsr ( HV_X64_MSR_SIMP, simp );
}

/**
 * Unmap synthetic interrupt controller
 *
 * @v hv		Hyper-V hypervisor
 */
static void hv_unmap_synic ( struct hv_hypervisor *hv ) {
	uint64_t scontrol;

	/* Disable SynIC */
	scontrol = rdmsr ( HV_X64_MSR_SCONTROL );
	scontrol &= ~HV_SCONTROL_ENABLE;
	DBGC2 ( hv, "HV %p SCONTROL MSR is %#08llx\n", hv, scontrol );
	wrmsr ( HV_X64_MSR_SCONTROL, scontrol );

	/* Unmap SynIC event and message pages */
	hv_unmap_synic_no_scontrol ( hv );
}

/**
 * Enable synthetic interrupt
 *
 * @v hv		Hyper-V hypervisor
 * @v sintx		Synthetic interrupt number
 */
void hv_enable_sint ( struct hv_hypervisor *hv, unsigned int sintx ) {
	unsigned long msr = HV_X64_MSR_SINT ( sintx );
	uint64_t sint;

	/* Enable synthetic interrupt
	 *
	 * We have to enable the interrupt, otherwise messages will
	 * not be delivered (even though the documentation implies
	 * that polling for messages is possible).  We enable AutoEOI
	 * and hook the interrupt to the obsolete IRQ13 (FPU
	 * exception) vector, which will be implemented as a no-op.
	 */
	sint = rdmsr ( msr );
	sint &= ~( HV_SINT_MASKED | HV_SINT_VECTOR_MASK );
	sint |= ( HV_SINT_AUTO_EOI |
		  HV_SINT_VECTOR ( IRQ_INT ( 13 /* See comment above */ ) ) );
	DBGC2 ( hv, "HV %p SINT%d MSR is %#08llx\n", hv, sintx, sint );
	wrmsr ( msr, sint );
}

/**
 * Disable synthetic interrupt
 *
 * @v hv		Hyper-V hypervisor
 * @v sintx		Synthetic interrupt number
 */
void hv_disable_sint ( struct hv_hypervisor *hv, unsigned int sintx ) {
	unsigned long msr = HV_X64_MSR_SINT ( sintx );
	uint64_t sint;

	/* Do nothing if interrupt is already disabled */
	sint = rdmsr ( msr );
	if ( sint & HV_SINT_MASKED )
		return;

	/* Disable synthetic interrupt */
	sint &= ~HV_SINT_AUTO_EOI;
	sint |= HV_SINT_MASKED;
	DBGC2 ( hv, "HV %p SINT%d MSR is %#08llx\n", hv, sintx, sint );
	wrmsr ( msr, sint );
}

/**
 * Post message
 *
 * @v hv		Hyper-V hypervisor
 * @v id		Connection ID
 * @v type		Message type
 * @v data		Message
 * @v len		Length of message
 * @ret rc		Return status code
 */
int hv_post_message ( struct hv_hypervisor *hv, unsigned int id,
		      unsigned int type, const void *data, size_t len ) {
	struct hv_post_message *msg = &hv->message->posted;
	int status;
	int rc;

	/* Sanity check */
	assert ( len <= sizeof ( msg->data ) );

	/* Construct message */
	memset ( msg, 0, sizeof ( *msg ) );
	msg->id = cpu_to_le32 ( id );
	msg->type = cpu_to_le32 ( type );
	msg->len = cpu_to_le32 ( len );
	memcpy ( msg->data, data, len );
	DBGC2 ( hv, "HV %p connection %d posting message type %#08x:\n",
		hv, id, type );
	DBGC2_HDA ( hv, 0, msg->data, len );

	/* Post message */
	if ( ( status = hv_call ( hv, HV_POST_MESSAGE, msg, NULL ) ) != 0 ) {
		rc = -EHV ( status );
		DBGC ( hv, "HV %p could not post message to %#08x: %s\n",
		       hv, id, strerror ( rc ) );
		return rc;
	}

	return 0;
}

/**
 * Wait for received message
 *
 * @v hv		Hyper-V hypervisor
 * @v sintx		Synthetic interrupt number
 * @ret rc		Return status code
 */
int hv_wait_for_message ( struct hv_hypervisor *hv, unsigned int sintx ) {
	struct hv_message *msg = &hv->message->received;
	struct hv_message *src = &hv->synic.message[sintx];
	unsigned int retries;
	size_t len;

	/* Wait for message to arrive */
	for ( retries = 0 ; retries < HV_MESSAGE_MAX_WAIT_MS ; retries++ ) {

		/* Check for message */
		if ( src->type ) {

			/* Copy message */
			memset ( msg, 0, sizeof ( *msg ) );
			len = src->len;
			assert ( len <= sizeof ( *msg ) );
			memcpy ( msg, src,
				 ( offsetof ( typeof ( *msg ), data ) + len ) );
			DBGC2 ( hv, "HV %p SINT%d received message type "
				"%#08x:\n", hv, sintx,
				le32_to_cpu ( msg->type ) );
			DBGC2_HDA ( hv, 0, msg->data, len );

			/* Consume message */
			src->type = 0;

			return 0;
		}

		/* Trigger message delivery */
		wrmsr ( HV_X64_MSR_EOM, 0 );

		/* Delay */
		mdelay ( 1 );
	}

	DBGC ( hv, "HV %p SINT%d timed out waiting for message\n",
	       hv, sintx );
	return -ETIMEDOUT;
}

/**
 * Signal event
 *
 * @v hv		Hyper-V hypervisor
 * @v id		Connection ID
 * @v flag		Flag number
 * @ret rc		Return status code
 */
int hv_signal_event ( struct hv_hypervisor *hv, unsigned int id,
		      unsigned int flag ) {
	struct hv_signal_event *event = &hv->message->signalled;
	int status;
	int rc;

	/* Construct event */
	memset ( event, 0, sizeof ( *event ) );
	event->id = cpu_to_le32 ( id );
	event->flag = cpu_to_le16 ( flag );

	/* Signal event */
	if ( ( status = hv_call ( hv, HV_SIGNAL_EVENT, event, NULL ) ) != 0 ) {
		rc = -EHV ( status );
		DBGC ( hv, "HV %p could not signal event to %#08x: %s\n",
		       hv, id, strerror ( rc ) );
		return rc;
	}

	return 0;
}

/**
 * Probe root device
 *
 * @v rootdev		Root device
 * @ret rc		Return status code
 */
static int hv_probe ( struct root_device *rootdev ) {
	struct hv_hypervisor *hv;
	int rc;

	/* Check we are running in Hyper-V */
	if ( ( rc = hv_check_hv() ) != 0 )
		goto err_check_hv;

	/* Allocate and initialise structure */
	hv = zalloc ( sizeof ( *hv ) );
	if ( ! hv ) {
		rc = -ENOMEM;
		goto err_alloc;
	}

	/* Check features */
	if ( ( rc = hv_check_features ( hv ) ) != 0 )
		goto err_check_features;

	/* Check that Gen 2 UEFI firmware is not running */
	if ( ( rc = hv_check_uefi ( hv ) ) != 0 )
		goto err_check_uefi;

	/* Allocate pages */
	if ( ( rc = hv_alloc_pages ( hv, &hv->hypercall, &hv->synic.message,
				     &hv->synic.event, NULL ) ) != 0 )
		goto err_alloc_pages;

	/* Allocate message buffer */
	if ( ( rc = hv_alloc_message ( hv ) ) != 0 )
		goto err_alloc_message;

	/* Map hypercall page */
	hv_map_hypercall ( hv );

	/* Map synthetic interrupt controller */
	hv_map_synic ( hv );

	/* Probe Hyper-V devices */
	if ( ( rc = vmbus_probe ( hv, &rootdev->dev ) ) != 0 )
		goto err_vmbus_probe;

	rootdev_set_drvdata ( rootdev, hv );
	return 0;

	vmbus_remove ( hv, &rootdev->dev );
 err_vmbus_probe:
	hv_unmap_synic ( hv );
	hv_unmap_hypercall ( hv );
	hv_free_message ( hv );
 err_alloc_message:
	hv_free_pages ( hv, hv->hypercall, hv->synic.message, hv->synic.event,
			NULL );
 err_alloc_pages:
 err_check_uefi:
 err_check_features:
	free ( hv );
 err_alloc:
 err_check_hv:
	return rc;
}

/**
 * Remove root device
 *
 * @v rootdev		Root device
 */
static void hv_remove ( struct root_device *rootdev ) {
	struct hv_hypervisor *hv = rootdev_get_drvdata ( rootdev );

	vmbus_remove ( hv, &rootdev->dev );
	hv_unmap_synic ( hv );
	hv_unmap_hypercall ( hv );
	hv_free_message ( hv );
	hv_free_pages ( hv, hv->hypercall, hv->synic.message, hv->synic.event,
			NULL );
	free ( hv );
	rootdev_set_drvdata ( rootdev, NULL );
}

/** Hyper-V root device driver */
static struct root_driver hv_root_driver = {
	.probe = hv_probe,
	.remove = hv_remove,
};

/** Hyper-V root device */
struct root_device hv_root_device __root_device = {
	.dev = { .name = "Hyper-V" },
	.driver = &hv_root_driver,
};

/**
 * Quiesce system
 *
 */
static void hv_quiesce ( void ) {
	struct hv_hypervisor *hv = rootdev_get_drvdata ( &hv_root_device );
	unsigned int i;

	/* Do nothing if we are not running in Hyper-V */
	if ( ! hv )
		return;

	/* The "enlightened" portions of the Windows Server 2016 boot
	 * process will not cleanly take ownership of an active
	 * Hyper-V connection.  Experimentation shows that the minimum
	 * requirement is that we disable the SynIC message page
	 * (i.e. zero the SIMP MSR).
	 *
	 * We cannot perform a full shutdown of the Hyper-V
	 * connection.  Experimentation shows that if we disable the
	 * SynIC (i.e. zero the SCONTROL MSR) then Windows Server 2016
	 * will enter an indefinite wait loop.
	 *
	 * Attempt to create a safe handover environment by resetting
	 * all MSRs except for SCONTROL.
	 *
	 * Note that we do not shut down our VMBus devices, since we
	 * may need to unquiesce the system and continue operation.
	 */

	/* Disable all synthetic interrupts */
	for ( i = 0 ; i <= HV_SINT_MAX ; i++ )
		hv_disable_sint ( hv, i );

	/* Unmap synthetic interrupt controller, leaving SCONTROL
	 * enabled (see above).
	 */
	hv_unmap_synic_no_scontrol ( hv );

	/* Unmap hypercall page */
	hv_unmap_hypercall ( hv );

	DBGC ( hv, "HV %p quiesced\n", hv );
}

/**
 * Unquiesce system
 *
 */
static void hv_unquiesce ( void ) {
	struct hv_hypervisor *hv = rootdev_get_drvdata ( &hv_root_device );
	uint64_t simp;
	int rc;

	/* Do nothing if we are not running in Hyper-V */
	if ( ! hv )
		return;

	/* Experimentation shows that the "enlightened" portions of
	 * Windows Server 2016 will break our Hyper-V connection at
	 * some point during a SAN boot.  Surprisingly it does not
	 * change the guest OS ID MSR, but it does leave the SynIC
	 * message page disabled.
	 *
	 * Our own explicit quiescing procedure will also disable the
	 * SynIC message page.  We can therefore use the SynIC message
	 * page enable bit as a heuristic to determine when we need to
	 * reestablish our Hyper-V connection.
	 */
	simp = rdmsr ( HV_X64_MSR_SIMP );
	if ( simp & HV_SIMP_ENABLE )
		return;

	/* Remap hypercall page */
	hv_map_hypercall ( hv );

	/* Remap synthetic interrupt controller */
	hv_map_synic ( hv );

	/* Reset Hyper-V devices */
	if ( ( rc = vmbus_reset ( hv, &hv_root_device.dev ) ) != 0 ) {
		DBGC ( hv, "HV %p could not unquiesce: %s\n",
		       hv, strerror ( rc ) );
		/* Nothing we can do */
		return;
	}
}

/** Hyper-V quiescer */
struct quiescer hv_quiescer __quiescer = {
	.quiesce = hv_quiesce,
	.unquiesce = hv_unquiesce,
};

/**
 * Probe timer
 *
 * @ret rc		Return status code
 */
static int hv_timer_probe ( void ) {
	uint32_t available;
	uint32_t discard_ebx;
	uint32_t discard_ecx;
	uint32_t discard_edx;
	int rc;

	/* Check we are running in Hyper-V */
	if ( ( rc = hv_check_hv() ) != 0 )
		return rc;

	/* Check for available reference counter */
	cpuid ( HV_CPUID_FEATURES, 0, &available, &discard_ebx, &discard_ecx,
		&discard_edx );
	if ( ! ( available & HV_FEATURES_AVAIL_TIME_REF_COUNT_MSR ) ) {
		DBGC ( HV_INTERFACE_ID, "HV has no time reference counter\n" );
		return -ENODEV;
	}

	return 0;
}

/**
 * Get current system time in ticks
 *
 * @ret ticks		Current time, in ticks
 */
static unsigned long hv_currticks ( void ) {

	/* Calculate time using a combination of bit shifts and
	 * multiplication (to avoid a 64-bit division).
	 */
	return ( ( rdmsr ( HV_X64_MSR_TIME_REF_COUNT ) >> HV_TIMER_SHIFT ) *
		 ( TICKS_PER_SEC / ( HV_TIMER_HZ >> HV_TIMER_SHIFT ) ) );
}

/**
 * Delay for a fixed number of microseconds
 *
 * @v usecs		Number of microseconds for which to delay
 */
static void hv_udelay ( unsigned long usecs ) {
	uint32_t start;
	uint32_t elapsed;
	uint32_t threshold;

	/* Spin until specified number of 10MHz ticks have elapsed */
	start = rdmsr ( HV_X64_MSR_TIME_REF_COUNT );
	threshold = ( usecs * ( HV_TIMER_HZ / 1000000 ) );
	do {
		elapsed = ( rdmsr ( HV_X64_MSR_TIME_REF_COUNT ) - start );
	} while ( elapsed < threshold );
}

/** Hyper-V timer */
struct timer hv_timer __timer ( TIMER_PREFERRED ) = {
	.name = "Hyper-V",
	.probe = hv_timer_probe,
	.currticks = hv_currticks,
	.udelay = hv_udelay,
};

/* Drag in objects via hv_root_device */
REQUIRING_SYMBOL ( hv_root_device );

/* Drag in netvsc driver */
REQUIRE_OBJECT ( netvsc );
