These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / include / ipxe / hyperv.h
1 #ifndef _IPXE_HYPERV_H
2 #define _IPXE_HYPERV_H
3
4 /** @file
5  *
6  * Hyper-V interface
7  *
8  */
9
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
12 #include <stdint.h>
13 #include <ipxe/io.h>
14
15 /** Hyper-V interface identification */
16 #define HV_INTERFACE_ID 0x31237648 /* "Hv#1" */
17
18 /** Guest OS identity for iPXE
19  *
20  * This field comprises:
21  *
22  * Bit  63    : set to 1 to indicate an open source OS
23  * Bits 62:56 : OS Type
24  * Bits 55:48 : OS ID
25  * Bits 47:16 : Version
26  * Bits 15:0  : Build number
27  *
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.
32  *
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
36  * number is included.
37  */
38 #define HV_GUEST_OS_ID_IPXE ( ( 1ULL << 63 ) | ( 0x18aeULL << 48 ) )
39
40 /** Enable hypercall page */
41 #define HV_HYPERCALL_ENABLE 0x00000001UL
42
43 /** Enable SynIC */
44 #define HV_SCONTROL_ENABLE 0x00000001UL
45
46 /** Enable SynIC event flags */
47 #define HV_SIEFP_ENABLE 0x00000001UL
48
49 /** Enable SynIC messages */
50 #define HV_SIMP_ENABLE 0x00000001UL
51
52 /** Perform implicit EOI upon synthetic interrupt delivery */
53 #define HV_SINT_AUTO_EOI 0x00020000UL
54
55 /** Mask synthetic interrupt */
56 #define HV_SINT_MASKED 0x00010000UL
57
58 /** Synthetic interrupt vector */
59 #define HV_SINT_VECTOR(x) ( (x) << 0 )
60
61 /** Synthetic interrupt vector mask */
62 #define HV_SINT_VECTOR_MASK HV_SINT_VECTOR ( 0xff )
63
64 /** Post message */
65 #define HV_POST_MESSAGE 0x005c
66
67 /** A posted message
68  *
69  * This is the input parameter list for the HvPostMessage hypercall.
70  */
71 struct hv_post_message {
72         /** Connection ID */
73         uint32_t id;
74         /** Padding */
75         uint32_t reserved;
76         /** Type */
77         uint32_t type;
78         /** Length of message */
79         uint32_t len;
80         /** Message */
81         uint8_t data[240];
82 } __attribute__ (( packed ));
83
84 /** A received message
85  *
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.
89  */
90 struct hv_message {
91         /** Type */
92         uint32_t type;
93         /** Length of message */
94         uint8_t len;
95         /** Flags */
96         uint8_t flags;
97         /** Padding */
98         uint16_t reserved;
99         /** Origin */
100         uint64_t origin;
101         /** Message */
102         uint8_t data[240];
103 } __attribute__ (( packed ));
104
105 /** Signal event */
106 #define HV_SIGNAL_EVENT 0x005d
107
108 /** A signalled event */
109 struct hv_signal_event {
110         /** Connection ID */
111         uint32_t id;
112         /** Flag number */
113         uint16_t flag;
114         /** Reserved */
115         uint16_t reserved;
116 } __attribute__ (( packed ));
117
118 /** A received event */
119 struct hv_event {
120         /** Event flags */
121         uint8_t flags[256];
122 } __attribute__ (( packed ));
123
124 /** A monitor trigger group
125  *
126  * This is the HV_MONITOR_TRIGGER_GROUP structure from the Hypervisor
127  * Top-Level Functional Specification.
128  */
129 struct hv_monitor_trigger {
130         /** Pending events */
131         uint32_t pending;
132         /** Armed events */
133         uint32_t armed;
134 } __attribute__ (( packed ));
135
136 /** A monitor parameter set
137  *
138  * This is the HV_MONITOR_PARAMETER structure from the Hypervisor
139  * Top-Level Functional Specification.
140  */
141 struct hv_monitor_parameter {
142         /** Connection ID */
143         uint32_t id;
144         /** Flag number */
145         uint16_t flag;
146         /** Reserved */
147         uint16_t reserved;
148 } __attribute__ (( packed ));
149
150 /** A monitor page
151  *
152  * This is the HV_MONITOR_PAGE structure from the Hypervisor Top-Level
153  * Functional Specification.
154  */
155 struct hv_monitor {
156         /** Flags */
157         uint32_t flags;
158         /** Reserved */
159         uint8_t reserved_a[4];
160         /** Trigger groups */
161         struct hv_monitor_trigger trigger[4];
162         /** Reserved */
163         uint8_t reserved_b[536];
164         /** Latencies */
165         uint16 latency[4][32];
166         /** Reserved */
167         uint8_t reserved_c[256];
168         /** Parameters */
169         struct hv_monitor_parameter param[4][32];
170         /** Reserved */
171         uint8_t reserved_d[1984];
172 } __attribute__ (( packed ));
173
174 /** A synthetic interrupt controller */
175 struct hv_synic {
176         /** Message page */
177         struct hv_message *message;
178         /** Event flag page */
179         struct hv_event *event;
180 };
181
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;
190 };
191
192 /** A Hyper-V hypervisor */
193 struct hv_hypervisor {
194         /** Hypercall page */
195         void *hypercall;
196         /** Synthetic interrupt controller (SynIC) */
197         struct hv_synic synic;
198         /** Message buffer */
199         union hv_message_buffer *message;
200         /** Virtual machine bus */
201         struct vmbus *vmbus;
202 };
203
204 #include <bits/hyperv.h>
205
206 /**
207  * Calculate the number of pages covering an address range
208  *
209  * @v data              Start of data
210  * @v len               Length of data (must be non-zero)
211  * @ret pfn_count       Number of pages covered
212  */
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 );
216
217         return ( last_pfn - first_pfn + 1 );
218 }
219
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,
230                              unsigned int flag );
231
232 #endif /* _IPXE_HYPERV_H */