iPXE
Data Structures | Defines | Functions | Variables
hyperv.h File Reference

Hyper-V interface. More...

#include <stdint.h>
#include <ipxe/io.h>
#include <bits/hyperv.h>

Go to the source code of this file.

Data Structures

struct  hv_post_message
 A posted message. More...
struct  hv_message
 A received message. More...
struct  hv_signal_event
 A signalled event. More...
struct  hv_event
 A received event. More...
struct  hv_monitor_trigger
 A monitor trigger group. More...
struct  hv_monitor_parameter
 A monitor parameter set. More...
struct  hv_monitor
 A monitor page. More...
struct  hv_synic
 A synthetic interrupt controller. More...
union  hv_message_buffer
 A message buffer. More...
struct  hv_hypervisor
 A Hyper-V hypervisor. More...

Defines

#define HV_INTERFACE_ID   0x31237648 /* "Hv#1" */
 Hyper-V interface identification.
#define HV_GUEST_OS_ID_IPXE   ( ( 1ULL << 63 ) | ( 0x18aeULL << 48 ) )
 Guest OS identity for iPXE.
#define HV_GUEST_OS_ID_UEFI   ( 1ULL << 40 )
 Guest OS identity for Gen 2 UEFI firmware.
#define HV_HYPERCALL_ENABLE   0x00000001UL
 Enable hypercall page.
#define HV_SCONTROL_ENABLE   0x00000001UL
 Enable SynIC.
#define HV_SIEFP_ENABLE   0x00000001UL
 Enable SynIC event flags.
#define HV_SIMP_ENABLE   0x00000001UL
 Enable SynIC messages.
#define HV_SINT_AUTO_EOI   0x00020000UL
 Perform implicit EOI upon synthetic interrupt delivery.
#define HV_SINT_MASKED   0x00010000UL
 Mask synthetic interrupt.
#define HV_SINT_VECTOR(x)   ( (x) << 0 )
 Synthetic interrupt vector.
#define HV_SINT_VECTOR_MASK   HV_SINT_VECTOR ( 0xff )
 Synthetic interrupt vector mask.
#define HV_SINT_MAX   15
 Maximum synthetic interrupt number.
#define HV_POST_MESSAGE   0x005c
 Post message.
#define HV_SIGNAL_EVENT   0x005d
 Signal event.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
struct hv_post_message __attribute__ ((packed))
static unsigned int hv_pfn_count (physaddr_t data, size_t len)
 Calculate the number of pages covering an address range.
 __attribute__ ((sentinel)) int hv_alloc_pages(struct hv_hypervisor *hv
void hv_enable_sint (struct hv_hypervisor *hv, unsigned int sintx)
 Enable synthetic interrupt.
void hv_disable_sint (struct hv_hypervisor *hv, unsigned int sintx)
 Disable synthetic interrupt.
int hv_post_message (struct hv_hypervisor *hv, unsigned int id, unsigned int type, const void *data, size_t len)
 Post message.
int hv_wait_for_message (struct hv_hypervisor *hv, unsigned int sintx)
 Wait for received message.
int hv_signal_event (struct hv_hypervisor *hv, unsigned int id, unsigned int flag)
 Signal event.

Variables

uint32_t id
 Connection ID.
uint32_t reserved
 Padding.
uint32_t type
 Type.
uint32_t len
 Length of message.
uint8_t data [240]
 Message.
uint8_t flags
 Flags.
uint64_t origin
 Origin.
uint16_t flag
 Flag number.
uint32_t pending
 Pending events.
uint32_t armed
 Armed events.
uint8_t reserved_a [4]
 Reserved.
struct hv_monitor_trigger trigger [4]
 Trigger groups.
uint8_t reserved_b [536]
 Reserved.
uint16 latency [4][32]
 Latencies.
uint8_t reserved_c [256]
 Reserved.
struct hv_monitor_parameter param [4][32]
 Parameters.
uint8_t reserved_d [1984]
 Reserved.
struct hv_synic __attribute__

Detailed Description

Hyper-V interface.

Definition in file hyperv.h.


Define Documentation

#define HV_INTERFACE_ID   0x31237648 /* "Hv#1" */

Hyper-V interface identification.

Definition at line 16 of file hyperv.h.

Referenced by hv_check_hv(), and hv_timer_probe().

#define HV_GUEST_OS_ID_IPXE   ( ( 1ULL << 63 ) | ( 0x18aeULL << 48 ) )

Guest OS identity for iPXE.

This field comprises:

Bit 63 : set to 1 to indicate an open source OS Bits 62:56 : OS Type Bits 55:48 : OS ID Bits 47:16 : Version Bits 15:0 : Build number

There appears to be no central registry for the "OS Type". The specification states that "Linux is 0x100", and the FreeBSD source states that "FreeBSD is 0x200". Both of these statements are actually referring to the combined "OS Type" and "OS ID" field.

We choose to use 0x98ae: this is generated by setting bit 63 (to indicate an open source OS) and setting the OS Type+ID equal to the PnP vendor ID used in romprefix.S. No version information or build number is included.

Definition at line 38 of file hyperv.h.

Referenced by hv_map_hypercall().

#define HV_GUEST_OS_ID_UEFI   ( 1ULL << 40 )

Guest OS identity for Gen 2 UEFI firmware.

This does not conform to the documented structure for guest OS identities.

Definition at line 45 of file hyperv.h.

Referenced by hv_check_uefi().

#define HV_HYPERCALL_ENABLE   0x00000001UL

Enable hypercall page.

Definition at line 48 of file hyperv.h.

Referenced by hv_map_hypercall(), and hv_unmap_hypercall().

#define HV_SCONTROL_ENABLE   0x00000001UL

Enable SynIC.

Definition at line 51 of file hyperv.h.

Referenced by hv_map_synic(), and hv_unmap_synic().

#define HV_SIEFP_ENABLE   0x00000001UL

Enable SynIC event flags.

Definition at line 54 of file hyperv.h.

Referenced by hv_map_synic(), and hv_unmap_synic_no_scontrol().

#define HV_SIMP_ENABLE   0x00000001UL

Enable SynIC messages.

Definition at line 57 of file hyperv.h.

Referenced by hv_map_synic(), hv_unmap_synic_no_scontrol(), and hv_unquiesce().

#define HV_SINT_AUTO_EOI   0x00020000UL

Perform implicit EOI upon synthetic interrupt delivery.

Definition at line 60 of file hyperv.h.

Referenced by hv_disable_sint(), and hv_enable_sint().

#define HV_SINT_MASKED   0x00010000UL

Mask synthetic interrupt.

Definition at line 63 of file hyperv.h.

Referenced by hv_disable_sint(), and hv_enable_sint().

#define HV_SINT_VECTOR (   x)    ( (x) << 0 )

Synthetic interrupt vector.

Definition at line 66 of file hyperv.h.

Referenced by hv_enable_sint().

#define HV_SINT_VECTOR_MASK   HV_SINT_VECTOR ( 0xff )

Synthetic interrupt vector mask.

Definition at line 69 of file hyperv.h.

Referenced by hv_enable_sint().

#define HV_SINT_MAX   15

Maximum synthetic interrupt number.

Definition at line 72 of file hyperv.h.

Referenced by hv_quiesce().

#define HV_POST_MESSAGE   0x005c

Post message.

Definition at line 75 of file hyperv.h.

Referenced by hv_post_message().

#define HV_SIGNAL_EVENT   0x005d

Signal event.

Definition at line 116 of file hyperv.h.

Referenced by hv_signal_event().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
struct hv_post_message __attribute__ ( (packed)  )
static unsigned int hv_pfn_count ( physaddr_t  data,
size_t  len 
) [inline, static]

Calculate the number of pages covering an address range.

Parameters:
dataStart of data
lenLength of data (must be non-zero)
Return values:
pfn_countNumber of pages covered

Definition at line 223 of file hyperv.h.

References PAGE_SIZE.

Referenced by vmbus_establish_gpadl(), and vmbus_send_data().

                                                                        {
        unsigned int first_pfn = ( data / PAGE_SIZE );
        unsigned int last_pfn = ( ( data + len - 1 ) / PAGE_SIZE );

        return ( last_pfn - first_pfn + 1 );
}
__attribute__ ( (sentinel)  )
void hv_enable_sint ( struct hv_hypervisor hv,
unsigned int  sintx 
)

Enable synthetic interrupt.

Parameters:
hvHyper-V hypervisor
sintxSynthetic interrupt number

Definition at line 397 of file hyperv.c.

References DBGC2, HV_SINT_AUTO_EOI, HV_SINT_MASKED, HV_SINT_VECTOR, HV_SINT_VECTOR_MASK, and HV_X64_MSR_SINT.

Referenced by vmbus_probe(), and vmbus_reset().

                                                                     {
        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 );
}
void hv_disable_sint ( struct hv_hypervisor hv,
unsigned int  sintx 
)

Disable synthetic interrupt.

Parameters:
hvHyper-V hypervisor
sintxSynthetic interrupt number

Definition at line 423 of file hyperv.c.

References DBGC2, HV_SINT_AUTO_EOI, HV_SINT_MASKED, and HV_X64_MSR_SINT.

Referenced by hv_quiesce(), vmbus_probe(), and vmbus_remove().

                                                                      {
        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 );
}
int hv_post_message ( struct hv_hypervisor hv,
unsigned int  id,
unsigned int  type,
const void *  data,
size_t  len 
)

Post message.

Parameters:
hvHyper-V hypervisor
idConnection ID
typeMessage type
dataMessage
lenLength of message
Return values:
rcReturn status code

Definition at line 449 of file hyperv.c.

References assert, cpu_to_le32, hv_post_message::data, DBGC, DBGC2, DBGC2_HDA, EHV, HV_POST_MESSAGE, hv_post_message::id, hv_post_message::len, memcpy(), memset(), hv_hypervisor::message, msg(), NULL, hv_message_buffer::posted, rc, status, strerror(), and hv_post_message::type.

                                                                        {
        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;
}
int hv_wait_for_message ( struct hv_hypervisor hv,
unsigned int  sintx 
)

Wait for received message.

Parameters:
hvHyper-V hypervisor
sintxSynthetic interrupt number
Return values:
rcReturn status code

Definition at line 486 of file hyperv.c.

References assert, hv_message::data, data, DBGC, DBGC2, DBGC2_HDA, ETIMEDOUT, HV_MESSAGE_MAX_WAIT_MS, HV_X64_MSR_EOM, le32_to_cpu, hv_message::len, len, mdelay(), memcpy(), memset(), hv_synic::message, hv_hypervisor::message, msg(), offsetof, hv_message_buffer::received, src, hv_hypervisor::synic, and hv_message::type.

Referenced by vmbus_wait_for_any_message().

                                                                         {
        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;
}
int hv_signal_event ( struct hv_hypervisor hv,
unsigned int  id,
unsigned int  flag 
)

Signal event.

Parameters:
hvHyper-V hypervisor
idConnection ID
flagFlag number
Return values:
rcReturn status code

Definition at line 535 of file hyperv.c.

References cpu_to_le16, cpu_to_le32, DBGC, EHV, HV_SIGNAL_EVENT, memset(), hv_hypervisor::message, NULL, rc, hv_message_buffer::signalled, status, and strerror().

                                          {
        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;
}

Variable Documentation

Connection ID.

Definition at line 94 of file hyperv.h.

Padding.

Reserved.

Definition at line 96 of file hyperv.h.

Type.

Definition at line 98 of file hyperv.h.

Length of message.

Definition at line 100 of file hyperv.h.

uint8_t data[240]

Message.

Definition at line 102 of file hyperv.h.

Flags.

Event flags.

Definition at line 119 of file hyperv.h.

Flag number.

Definition at line 130 of file hyperv.h.

Referenced by bios_reboot(), mlx_pci_gw_wait_for_flag_value(), pci_vpd_read_dword(), and pci_vpd_write_dword().

Pending events.

Definition at line 146 of file hyperv.h.

Referenced by ath5k_hw_stop_tx_dma(), b44_process_rx_packets(), pending_rx_index(), pending_tx_index(), and sis190_process_tx().

Armed events.

Definition at line 148 of file hyperv.h.

Reserved.

Definition at line 186 of file hyperv.h.

Trigger groups.

Definition at line 188 of file hyperv.h.

Referenced by vmbus_signal_monitor().

Reserved.

Definition at line 190 of file hyperv.h.

uint16 latency[4][32]

Latencies.

Definition at line 192 of file hyperv.h.

Reserved.

Definition at line 194 of file hyperv.h.

struct hv_monitor_parameter param[4][32]

Reserved.

Definition at line 198 of file hyperv.h.