10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
15 /** Hyper-V interface identification */
16 #define HV_INTERFACE_ID 0x31237648 /* "Hv#1" */
18 /** Guest OS identity for iPXE
20 * This field comprises:
22 * Bit 63 : set to 1 to indicate an open source OS
23 * Bits 62:56 : OS Type
25 * Bits 47:16 : Version
26 * Bits 15:0 : Build number
28 * There appears to be no central registry for the "OS Type". The
29 * specification states that "Linux is 0x100", and the FreeBSD source
30 * states that "FreeBSD is 0x200". Both of these statements are
31 * actually referring to the combined "OS Type" and "OS ID" field.
33 * We choose to use 0x98ae: this is generated by setting bit 63 (to
34 * indicate an open source OS) and setting the OS Type+ID equal to the
35 * PnP vendor ID used in romprefix.S. No version information or build
38 #define HV_GUEST_OS_ID_IPXE ( ( 1ULL << 63 ) | ( 0x18aeULL << 48 ) )
40 /** Enable hypercall page */
41 #define HV_HYPERCALL_ENABLE 0x00000001UL
44 #define HV_SCONTROL_ENABLE 0x00000001UL
46 /** Enable SynIC event flags */
47 #define HV_SIEFP_ENABLE 0x00000001UL
49 /** Enable SynIC messages */
50 #define HV_SIMP_ENABLE 0x00000001UL
52 /** Perform implicit EOI upon synthetic interrupt delivery */
53 #define HV_SINT_AUTO_EOI 0x00020000UL
55 /** Mask synthetic interrupt */
56 #define HV_SINT_MASKED 0x00010000UL
58 /** Synthetic interrupt vector */
59 #define HV_SINT_VECTOR(x) ( (x) << 0 )
61 /** Synthetic interrupt vector mask */
62 #define HV_SINT_VECTOR_MASK HV_SINT_VECTOR ( 0xff )
65 #define HV_POST_MESSAGE 0x005c
69 * This is the input parameter list for the HvPostMessage hypercall.
71 struct hv_post_message {
78 /** Length of message */
82 } __attribute__ (( packed ));
84 /** A received message
86 * This is the HV_MESSAGE structure from the Hypervisor Top-Level
87 * Functional Specification. The field order given in the
88 * documentation is incorrect.
93 /** Length of message */
103 } __attribute__ (( packed ));
106 #define HV_SIGNAL_EVENT 0x005d
108 /** A signalled event */
109 struct hv_signal_event {
116 } __attribute__ (( packed ));
118 /** A received event */
122 } __attribute__ (( packed ));
124 /** A monitor trigger group
126 * This is the HV_MONITOR_TRIGGER_GROUP structure from the Hypervisor
127 * Top-Level Functional Specification.
129 struct hv_monitor_trigger {
130 /** Pending events */
134 } __attribute__ (( packed ));
136 /** A monitor parameter set
138 * This is the HV_MONITOR_PARAMETER structure from the Hypervisor
139 * Top-Level Functional Specification.
141 struct hv_monitor_parameter {
148 } __attribute__ (( packed ));
152 * This is the HV_MONITOR_PAGE structure from the Hypervisor Top-Level
153 * Functional Specification.
159 uint8_t reserved_a[4];
160 /** Trigger groups */
161 struct hv_monitor_trigger trigger[4];
163 uint8_t reserved_b[536];
165 uint16 latency[4][32];
167 uint8_t reserved_c[256];
169 struct hv_monitor_parameter param[4][32];
171 uint8_t reserved_d[1984];
172 } __attribute__ (( packed ));
174 /** A synthetic interrupt controller */
177 struct hv_message *message;
178 /** Event flag page */
179 struct hv_event *event;
182 /** A message buffer */
183 union hv_message_buffer {
184 /** Posted message */
185 struct hv_post_message posted;
186 /** Received message */
187 struct hv_message received;
188 /** Signalled event */
189 struct hv_signal_event signalled;
192 /** A Hyper-V hypervisor */
193 struct hv_hypervisor {
194 /** Hypercall page */
196 /** Synthetic interrupt controller (SynIC) */
197 struct hv_synic synic;
198 /** Message buffer */
199 union hv_message_buffer *message;
200 /** Virtual machine bus */
204 #include <bits/hyperv.h>
207 * Calculate the number of pages covering an address range
209 * @v data Start of data
210 * @v len Length of data (must be non-zero)
211 * @ret pfn_count Number of pages covered
213 static inline unsigned int hv_pfn_count ( physaddr_t data, size_t len ) {
214 unsigned int first_pfn = ( data / PAGE_SIZE );
215 unsigned int last_pfn = ( ( data + len - 1 ) / PAGE_SIZE );
217 return ( last_pfn - first_pfn + 1 );
220 extern __attribute__ (( sentinel )) int
221 hv_alloc_pages ( struct hv_hypervisor *hv, ... );
222 extern __attribute__ (( sentinel )) void
223 hv_free_pages ( struct hv_hypervisor *hv, ... );
224 extern void hv_enable_sint ( struct hv_hypervisor *hv, unsigned int sintx );
225 extern void hv_disable_sint ( struct hv_hypervisor *hv, unsigned int sintx );
226 extern int hv_post_message ( struct hv_hypervisor *hv, unsigned int id,
227 unsigned int type, const void *data, size_t len );
228 extern int hv_wait_for_message ( struct hv_hypervisor *hv, unsigned int sintx );
229 extern int hv_signal_event ( struct hv_hypervisor *hv, unsigned int id,
232 #endif /* _IPXE_HYPERV_H */