iPXE
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...

Macros

#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)
 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.

Macro Definition Documentation

◆ HV_INTERFACE_ID

#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().

◆ HV_GUEST_OS_ID_IPXE

#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().

◆ HV_GUEST_OS_ID_UEFI

#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().

◆ HV_HYPERCALL_ENABLE

#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().

◆ HV_SCONTROL_ENABLE

#define HV_SCONTROL_ENABLE   0x00000001UL

Enable SynIC.

Definition at line 51 of file hyperv.h.

Referenced by hv_map_synic(), and hv_unmap_synic().

◆ HV_SIEFP_ENABLE

#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().

◆ HV_SIMP_ENABLE

#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().

◆ HV_SINT_AUTO_EOI

#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().

◆ HV_SINT_MASKED

#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().

◆ HV_SINT_VECTOR

#define HV_SINT_VECTOR ( x)
Value:
( (x) << 0 )
static unsigned int x
Definition pixbuf.h:63

Synthetic interrupt vector.

Definition at line 66 of file hyperv.h.

Referenced by hv_enable_sint().

◆ HV_SINT_VECTOR_MASK

#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().

◆ HV_SINT_MAX

#define HV_SINT_MAX   15

Maximum synthetic interrupt number.

Definition at line 72 of file hyperv.h.

Referenced by hv_quiesce().

◆ HV_POST_MESSAGE

#define HV_POST_MESSAGE   0x005c

Post message.

Definition at line 75 of file hyperv.h.

Referenced by hv_post_message().

◆ HV_SIGNAL_EVENT

#define HV_SIGNAL_EVENT   0x005d

Signal event.

Definition at line 116 of file hyperv.h.

Referenced by hv_signal_event().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ __attribute__() [1/2]

struct hv_post_message __attribute__ ( (packed) )

◆ hv_pfn_count()

unsigned int hv_pfn_count ( physaddr_t data,
size_t len )
inlinestatic

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.

223 {
224 unsigned int first_pfn = ( data / PAGE_SIZE );
225 unsigned int last_pfn = ( ( data + len - 1 ) / PAGE_SIZE );
226
227 return ( last_pfn - first_pfn + 1 );
228}
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define PAGE_SIZE
Page size.
Definition io.h:28

References data, len, and PAGE_SIZE.

Referenced by vmbus_establish_gpadl(), and vmbus_send_data().

◆ __attribute__() [2/2]

__attribute__ ( (sentinel) )
extern

References data, flag, len, and type.

◆ hv_enable_sint()

void hv_enable_sint ( struct hv_hypervisor * hv,
unsigned int sintx )
extern

Enable synthetic interrupt.

Parameters
hvHyper-V hypervisor
sintxSynthetic interrupt number

Definition at line 397 of file hyperv.c.

397 {
398 unsigned long msr = HV_X64_MSR_SINT ( sintx );
399 uint64_t sint;
400
401 /* Enable synthetic interrupt
402 *
403 * We have to enable the interrupt, otherwise messages will
404 * not be delivered (even though the documentation implies
405 * that polling for messages is possible). We enable AutoEOI
406 * and hook the interrupt to the obsolete IRQ13 (FPU
407 * exception) vector, which will be implemented as a no-op.
408 */
409 sint = rdmsr ( msr );
410 sint &= ~( HV_SINT_MASKED | HV_SINT_VECTOR_MASK );
411 sint |= ( HV_SINT_AUTO_EOI |
412 HV_SINT_VECTOR ( IRQ_INT ( 13 /* See comment above */ ) ) );
413 DBGC2 ( hv, "HV %p SINT%d MSR is %#08llx\n", hv, sintx, sint );
414 wrmsr ( msr, sint );
415}
unsigned long long uint64_t
Definition stdint.h:13
#define HV_X64_MSR_SINT(x)
SynIC interrupt source MSRs.
Definition hyperv.h:61
#define DBGC2(...)
Definition compiler.h:522
#define HV_SINT_VECTOR_MASK
Synthetic interrupt vector mask.
Definition hyperv.h:69
#define HV_SINT_AUTO_EOI
Perform implicit EOI upon synthetic interrupt delivery.
Definition hyperv.h:60
#define HV_SINT_VECTOR(x)
Synthetic interrupt vector.
Definition hyperv.h:66
#define HV_SINT_MASKED
Mask synthetic interrupt.
Definition hyperv.h:63
#define IRQ_INT(irq)
Definition pic8259.h:57

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

Referenced by vmbus_probe(), and vmbus_reset().

◆ hv_disable_sint()

void hv_disable_sint ( struct hv_hypervisor * hv,
unsigned int sintx )
extern

Disable synthetic interrupt.

Parameters
hvHyper-V hypervisor
sintxSynthetic interrupt number

Definition at line 423 of file hyperv.c.

423 {
424 unsigned long msr = HV_X64_MSR_SINT ( sintx );
425 uint64_t sint;
426
427 /* Do nothing if interrupt is already disabled */
428 sint = rdmsr ( msr );
429 if ( sint & HV_SINT_MASKED )
430 return;
431
432 /* Disable synthetic interrupt */
433 sint &= ~HV_SINT_AUTO_EOI;
434 sint |= HV_SINT_MASKED;
435 DBGC2 ( hv, "HV %p SINT%d MSR is %#08llx\n", hv, sintx, sint );
436 wrmsr ( msr, sint );
437}

References DBGC2, HV_SINT_AUTO_EOI, HV_SINT_MASKED, and HV_X64_MSR_SINT.

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

◆ hv_post_message()

int hv_post_message ( struct hv_hypervisor * hv,
unsigned int id,
unsigned int type,
const void * data,
size_t len )
extern

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.

450 {
451 struct hv_post_message *msg = &hv->message->posted;
452 int status;
453 int rc;
454
455 /* Sanity check */
456 assert ( len <= sizeof ( msg->data ) );
457
458 /* Construct message */
459 memset ( msg, 0, sizeof ( *msg ) );
460 msg->id = cpu_to_le32 ( id );
461 msg->type = cpu_to_le32 ( type );
462 msg->len = cpu_to_le32 ( len );
463 memcpy ( msg->data, data, len );
464 DBGC2 ( hv, "HV %p connection %d posting message type %#08x:\n",
465 hv, id, type );
466 DBGC2_HDA ( hv, 0, msg->data, len );
467
468 /* Post message */
469 if ( ( status = hv_call ( hv, HV_POST_MESSAGE, msg, NULL ) ) != 0 ) {
470 rc = -EHV ( status );
471 DBGC ( hv, "HV %p could not post message to %#08x: %s\n",
472 hv, id, strerror ( rc ) );
473 return rc;
474 }
475
476 return 0;
477}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
uint32_t type
Operating system type.
Definition ena.h:1
uint8_t status
Status.
Definition ena.h:5
#define DBGC2_HDA(...)
Definition compiler.h:523
#define DBGC(...)
Definition compiler.h:505
#define EHV(status)
Convert a Hyper-V status code to an iPXE status code.
Definition hyperv.c:68
#define cpu_to_le32(value)
Definition byteswap.h:108
#define HV_POST_MESSAGE
Post message.
Definition hyperv.h:75
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition message.c:62
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
union hv_message_buffer * message
Message buffer.
Definition hyperv.h:209
A posted message.
Definition hyperv.h:81
struct hv_post_message posted
Posted message.
Definition hyperv.h:195

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

◆ hv_wait_for_message()

int hv_wait_for_message ( struct hv_hypervisor * hv,
unsigned int sintx )
extern

Wait for received message.

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

Definition at line 486 of file hyperv.c.

486 {
487 struct hv_message *msg = &hv->message->received;
488 struct hv_message *src = &hv->synic.message[sintx];
489 unsigned int retries;
490 size_t len;
491
492 /* Wait for message to arrive */
493 for ( retries = 0 ; retries < HV_MESSAGE_MAX_WAIT_MS ; retries++ ) {
494
495 /* Check for message */
496 if ( src->type ) {
497
498 /* Copy message */
499 memset ( msg, 0, sizeof ( *msg ) );
500 len = src->len;
501 assert ( len <= sizeof ( *msg ) );
502 memcpy ( msg, src,
503 ( offsetof ( typeof ( *msg ), data ) + len ) );
504 DBGC2 ( hv, "HV %p SINT%d received message type "
505 "%#08x:\n", hv, sintx,
506 le32_to_cpu ( msg->type ) );
507 DBGC2_HDA ( hv, 0, msg->data, len );
508
509 /* Consume message */
510 src->type = 0;
511
512 return 0;
513 }
514
515 /* Trigger message delivery */
516 wrmsr ( HV_X64_MSR_EOM, 0 );
517
518 /* Delay */
519 mdelay ( 1 );
520 }
521
522 DBGC ( hv, "HV %p SINT%d timed out waiting for message\n",
523 hv, sintx );
524 return -ETIMEDOUT;
525}
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
#define HV_X64_MSR_EOM
SynIC end of message MSR.
Definition hyperv.h:58
static const void * src
Definition string.h:48
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
#define HV_MESSAGE_MAX_WAIT_MS
Maximum time to wait for a message response.
Definition hyperv.c:54
#define le32_to_cpu(value)
Definition byteswap.h:114
#define offsetof(type, field)
Get offset of a field within a structure.
Definition stddef.h:25
struct hv_synic synic
Synthetic interrupt controller (SynIC)
Definition hyperv.h:207
A received message.
Definition hyperv.h:100
struct hv_message * message
Message page.
Definition hyperv.h:187
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition timer.c:79
struct hv_message received
Received message.
Definition hyperv.h:197

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

Referenced by vmbus_wait_for_any_message().

◆ hv_signal_event()

int hv_signal_event ( struct hv_hypervisor * hv,
unsigned int id,
unsigned int flag )
extern

Signal event.

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

Definition at line 535 of file hyperv.c.

536 {
537 struct hv_signal_event *event = &hv->message->signalled;
538 int status;
539 int rc;
540
541 /* Construct event */
542 memset ( event, 0, sizeof ( *event ) );
543 event->id = cpu_to_le32 ( id );
544 event->flag = cpu_to_le16 ( flag );
545
546 /* Signal event */
547 if ( ( status = hv_call ( hv, HV_SIGNAL_EVENT, event, NULL ) ) != 0 ) {
548 rc = -EHV ( status );
549 DBGC ( hv, "HV %p could not signal event to %#08x: %s\n",
550 hv, id, strerror ( rc ) );
551 return rc;
552 }
553
554 return 0;
555}
uint32_t flag
Flag number.
Definition aqc1xx.h:2
#define cpu_to_le16(value)
Definition byteswap.h:107
#define HV_SIGNAL_EVENT
Signal event.
Definition hyperv.h:116
A signalled event.
Definition hyperv.h:119
struct hv_signal_event signalled
Signalled event.
Definition hyperv.h:199

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

Variable Documentation

◆ id

Connection ID.

Definition at line 1 of file hyperv.h.

◆ reserved

uint16_t reserved

Padding.

Reserved.

Definition at line 3 of file hyperv.h.

◆ type

uint32_t type

Type.

Definition at line 5 of file hyperv.h.

◆ len

uint8_t len

Length of message.

Definition at line 7 of file hyperv.h.

◆ data

uint8_t data[240]

Message.

Definition at line 9 of file hyperv.h.

◆ flags

uint32_t flags

Flags.

Event flags.

Definition at line 5 of file hyperv.h.

◆ origin

◆ flag

uint16_t flag

Flag number.

Definition at line 3 of file hyperv.h.

◆ pending

◆ armed

uint32_t armed

Armed events.

Definition at line 3 of file hyperv.h.

◆ reserved_a

uint8_t reserved_a[4]

Reserved.

Definition at line 3 of file hyperv.h.

◆ trigger

struct hv_monitor_trigger trigger[4]

Trigger groups.

Definition at line 5 of file hyperv.h.

Referenced by vmbus_signal_monitor().

◆ reserved_b

uint8_t reserved_b[536]

Reserved.

Definition at line 7 of file hyperv.h.

◆ latency

uint16 latency[4][32]

Latencies.

Definition at line 9 of file hyperv.h.

◆ reserved_c

uint8_t reserved_c[256]

Reserved.

Definition at line 11 of file hyperv.h.

◆ param

◆ reserved_d

uint8_t reserved_d[1984]

Reserved.

Definition at line 15 of file hyperv.h.