123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- #ifndef _IPXE_HYPERV_H
- #define _IPXE_HYPERV_H
-
- /** @file
- *
- * Hyper-V interface
- *
- */
-
- FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
- #include <stdint.h>
- #include <ipxe/io.h>
-
- /** Hyper-V interface identification */
- #define HV_INTERFACE_ID 0x31237648 /* "Hv#1" */
-
- /** 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.
- */
- #define HV_GUEST_OS_ID_IPXE ( ( 1ULL << 63 ) | ( 0x18aeULL << 48 ) )
-
- /** Guest OS identity for Gen 2 UEFI firmware
- *
- * This does not conform to the documented structure for guest OS
- * identities.
- */
- #define HV_GUEST_OS_ID_UEFI ( 1ULL << 40 )
-
- /** Enable hypercall page */
- #define HV_HYPERCALL_ENABLE 0x00000001UL
-
- /** Enable SynIC */
- #define HV_SCONTROL_ENABLE 0x00000001UL
-
- /** Enable SynIC event flags */
- #define HV_SIEFP_ENABLE 0x00000001UL
-
- /** Enable SynIC messages */
- #define HV_SIMP_ENABLE 0x00000001UL
-
- /** Perform implicit EOI upon synthetic interrupt delivery */
- #define HV_SINT_AUTO_EOI 0x00020000UL
-
- /** Mask synthetic interrupt */
- #define HV_SINT_MASKED 0x00010000UL
-
- /** Synthetic interrupt vector */
- #define HV_SINT_VECTOR(x) ( (x) << 0 )
-
- /** Synthetic interrupt vector mask */
- #define HV_SINT_VECTOR_MASK HV_SINT_VECTOR ( 0xff )
-
- /** Maximum synthetic interrupt number */
- #define HV_SINT_MAX 15
-
- /** Post message */
- #define HV_POST_MESSAGE 0x005c
-
- /** A posted message
- *
- * This is the input parameter list for the HvPostMessage hypercall.
- */
- struct hv_post_message {
- /** Connection ID */
- uint32_t id;
- /** Padding */
- uint32_t reserved;
- /** Type */
- uint32_t type;
- /** Length of message */
- uint32_t len;
- /** Message */
- uint8_t data[240];
- } __attribute__ (( packed ));
-
- /** A received message
- *
- * This is the HV_MESSAGE structure from the Hypervisor Top-Level
- * Functional Specification. The field order given in the
- * documentation is incorrect.
- */
- struct hv_message {
- /** Type */
- uint32_t type;
- /** Length of message */
- uint8_t len;
- /** Flags */
- uint8_t flags;
- /** Padding */
- uint16_t reserved;
- /** Origin */
- uint64_t origin;
- /** Message */
- uint8_t data[240];
- } __attribute__ (( packed ));
-
- /** Signal event */
- #define HV_SIGNAL_EVENT 0x005d
-
- /** A signalled event */
- struct hv_signal_event {
- /** Connection ID */
- uint32_t id;
- /** Flag number */
- uint16_t flag;
- /** Reserved */
- uint16_t reserved;
- } __attribute__ (( packed ));
-
- /** A received event */
- struct hv_event {
- /** Event flags */
- uint8_t flags[256];
- } __attribute__ (( packed ));
-
- /** A monitor trigger group
- *
- * This is the HV_MONITOR_TRIGGER_GROUP structure from the Hypervisor
- * Top-Level Functional Specification.
- */
- struct hv_monitor_trigger {
- /** Pending events */
- uint32_t pending;
- /** Armed events */
- uint32_t armed;
- } __attribute__ (( packed ));
-
- /** A monitor parameter set
- *
- * This is the HV_MONITOR_PARAMETER structure from the Hypervisor
- * Top-Level Functional Specification.
- */
- struct hv_monitor_parameter {
- /** Connection ID */
- uint32_t id;
- /** Flag number */
- uint16_t flag;
- /** Reserved */
- uint16_t reserved;
- } __attribute__ (( packed ));
-
- /** A monitor page
- *
- * This is the HV_MONITOR_PAGE structure from the Hypervisor Top-Level
- * Functional Specification.
- */
- struct hv_monitor {
- /** Flags */
- uint32_t flags;
- /** Reserved */
- uint8_t reserved_a[4];
- /** Trigger groups */
- struct hv_monitor_trigger trigger[4];
- /** Reserved */
- uint8_t reserved_b[536];
- /** Latencies */
- uint16 latency[4][32];
- /** Reserved */
- uint8_t reserved_c[256];
- /** Parameters */
- struct hv_monitor_parameter param[4][32];
- /** Reserved */
- uint8_t reserved_d[1984];
- } __attribute__ (( packed ));
-
- /** A synthetic interrupt controller */
- struct hv_synic {
- /** Message page */
- struct hv_message *message;
- /** Event flag page */
- struct hv_event *event;
- };
-
- /** A message buffer */
- union hv_message_buffer {
- /** Posted message */
- struct hv_post_message posted;
- /** Received message */
- struct hv_message received;
- /** Signalled event */
- struct hv_signal_event signalled;
- };
-
- /** A Hyper-V hypervisor */
- struct hv_hypervisor {
- /** Hypercall page */
- void *hypercall;
- /** Synthetic interrupt controller (SynIC) */
- struct hv_synic synic;
- /** Message buffer */
- union hv_message_buffer *message;
- /** Virtual machine bus */
- struct vmbus *vmbus;
- };
-
- #include <bits/hyperv.h>
-
- /**
- * Calculate the number of pages covering an address range
- *
- * @v data Start of data
- * @v len Length of data (must be non-zero)
- * @ret pfn_count Number of pages covered
- */
- static inline unsigned int hv_pfn_count ( physaddr_t data, size_t len ) {
- unsigned int first_pfn = ( data / PAGE_SIZE );
- unsigned int last_pfn = ( ( data + len - 1 ) / PAGE_SIZE );
-
- return ( last_pfn - first_pfn + 1 );
- }
-
- extern __attribute__ (( sentinel )) int
- hv_alloc_pages ( struct hv_hypervisor *hv, ... );
- extern __attribute__ (( sentinel )) void
- hv_free_pages ( struct hv_hypervisor *hv, ... );
- extern void hv_enable_sint ( struct hv_hypervisor *hv, unsigned int sintx );
- extern void hv_disable_sint ( struct hv_hypervisor *hv, unsigned int sintx );
- extern int hv_post_message ( struct hv_hypervisor *hv, unsigned int id,
- unsigned int type, const void *data, size_t len );
- extern int hv_wait_for_message ( struct hv_hypervisor *hv, unsigned int sintx );
- extern int hv_signal_event ( struct hv_hypervisor *hv, unsigned int id,
- unsigned int flag );
-
- #endif /* _IPXE_HYPERV_H */
|