Commit | Line | Data |
---|---|---|
0f2a6619 S |
1 | /* |
2 | * | |
3 | * Copyright (c) 2011, Microsoft Corporation. | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms and conditions of the GNU General Public License, | |
7 | * version 2, as published by the Free Software Foundation. | |
8 | * | |
9 | * This program is distributed in the hope it will be useful, but WITHOUT | |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
12 | * more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License along with | |
15 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | |
16 | * Place - Suite 330, Boston, MA 02111-1307 USA. | |
17 | * | |
18 | * Authors: | |
19 | * Haiyang Zhang <haiyangz@microsoft.com> | |
20 | * Hank Janssen <hjanssen@microsoft.com> | |
21 | * K. Y. Srinivasan <kys@microsoft.com> | |
22 | * | |
23 | */ | |
24 | ||
25 | #ifndef _HYPERV_VMBUS_H | |
26 | #define _HYPERV_VMBUS_H | |
27 | ||
afbdc4a9 S |
28 | /* |
29 | * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent | |
30 | * is set by CPUID(HVCPUID_VERSION_FEATURES). | |
31 | */ | |
32 | enum hv_cpuid_function { | |
33 | HVCPUID_VERSION_FEATURES = 0x00000001, | |
34 | HVCPUID_VENDOR_MAXFUNCTION = 0x40000000, | |
35 | HVCPUID_INTERFACE = 0x40000001, | |
36 | ||
37 | /* | |
38 | * The remaining functions depend on the value of | |
39 | * HVCPUID_INTERFACE | |
40 | */ | |
41 | HVCPUID_VERSION = 0x40000002, | |
42 | HVCPUID_FEATURES = 0x40000003, | |
43 | HVCPUID_ENLIGHTENMENT_INFO = 0x40000004, | |
44 | HVCPUID_IMPLEMENTATION_LIMITS = 0x40000005, | |
45 | }; | |
46 | ||
47 | /* Define version of the synthetic interrupt controller. */ | |
48 | #define HV_SYNIC_VERSION (1) | |
49 | ||
50 | /* Define the expected SynIC version. */ | |
51 | #define HV_SYNIC_VERSION_1 (0x1) | |
52 | ||
53 | /* Define synthetic interrupt controller message constants. */ | |
54 | #define HV_MESSAGE_SIZE (256) | |
55 | #define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240) | |
56 | #define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30) | |
57 | #define HV_ANY_VP (0xFFFFFFFF) | |
58 | ||
59 | /* Define synthetic interrupt controller flag constants. */ | |
60 | #define HV_EVENT_FLAGS_COUNT (256 * 8) | |
61 | #define HV_EVENT_FLAGS_BYTE_COUNT (256) | |
62 | #define HV_EVENT_FLAGS_DWORD_COUNT (256 / sizeof(u32)) | |
63 | ||
64 | /* Define hypervisor message types. */ | |
65 | enum hv_message_type { | |
66 | HVMSG_NONE = 0x00000000, | |
67 | ||
68 | /* Memory access messages. */ | |
69 | HVMSG_UNMAPPED_GPA = 0x80000000, | |
70 | HVMSG_GPA_INTERCEPT = 0x80000001, | |
71 | ||
72 | /* Timer notification messages. */ | |
73 | HVMSG_TIMER_EXPIRED = 0x80000010, | |
74 | ||
75 | /* Error messages. */ | |
76 | HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020, | |
77 | HVMSG_UNRECOVERABLE_EXCEPTION = 0x80000021, | |
78 | HVMSG_UNSUPPORTED_FEATURE = 0x80000022, | |
79 | ||
80 | /* Trace buffer complete messages. */ | |
81 | HVMSG_EVENTLOG_BUFFERCOMPLETE = 0x80000040, | |
82 | ||
83 | /* Platform-specific processor intercept messages. */ | |
84 | HVMSG_X64_IOPORT_INTERCEPT = 0x80010000, | |
85 | HVMSG_X64_MSR_INTERCEPT = 0x80010001, | |
86 | HVMSG_X64_CPUID_INTERCEPT = 0x80010002, | |
87 | HVMSG_X64_EXCEPTION_INTERCEPT = 0x80010003, | |
88 | HVMSG_X64_APIC_EOI = 0x80010004, | |
89 | HVMSG_X64_LEGACY_FP_ERROR = 0x80010005 | |
90 | }; | |
91 | ||
92 | /* Define the number of synthetic interrupt sources. */ | |
93 | #define HV_SYNIC_SINT_COUNT (16) | |
94 | #define HV_SYNIC_STIMER_COUNT (4) | |
95 | ||
96 | /* Define invalid partition identifier. */ | |
97 | #define HV_PARTITION_ID_INVALID ((u64)0x0) | |
98 | ||
99 | /* Define connection identifier type. */ | |
100 | union hv_connection_id { | |
101 | u32 asu32; | |
102 | struct { | |
103 | u32 id:24; | |
104 | u32 reserved:8; | |
105 | } u; | |
106 | }; | |
107 | ||
108 | /* Define port identifier type. */ | |
109 | union hv_port_id { | |
110 | u32 asu32; | |
111 | struct { | |
112 | u32 id:24; | |
113 | u32 reserved:8; | |
114 | } u ; | |
115 | }; | |
116 | ||
117 | /* Define port type. */ | |
118 | enum hv_port_type { | |
119 | HVPORT_MSG = 1, | |
120 | HVPORT_EVENT = 2, | |
121 | HVPORT_MONITOR = 3 | |
122 | }; | |
123 | ||
124 | /* Define port information structure. */ | |
125 | struct hv_port_info { | |
126 | enum hv_port_type port_type; | |
127 | u32 padding; | |
128 | union { | |
129 | struct { | |
130 | u32 target_sint; | |
131 | u32 target_vp; | |
132 | u64 rsvdz; | |
133 | } message_port_info; | |
134 | struct { | |
135 | u32 target_sint; | |
136 | u32 target_vp; | |
137 | u16 base_flag_bumber; | |
138 | u16 flag_count; | |
139 | u32 rsvdz; | |
140 | } event_port_info; | |
141 | struct { | |
142 | u64 monitor_address; | |
143 | u64 rsvdz; | |
144 | } monitor_port_info; | |
145 | }; | |
146 | }; | |
147 | ||
148 | struct hv_connection_info { | |
149 | enum hv_port_type port_type; | |
150 | u32 padding; | |
151 | union { | |
152 | struct { | |
153 | u64 rsvdz; | |
154 | } message_connection_info; | |
155 | struct { | |
156 | u64 rsvdz; | |
157 | } event_connection_info; | |
158 | struct { | |
159 | u64 monitor_address; | |
160 | } monitor_connection_info; | |
161 | }; | |
162 | }; | |
163 | ||
164 | /* Define synthetic interrupt controller message flags. */ | |
165 | union hv_message_flags { | |
166 | u8 asu8; | |
167 | struct { | |
168 | u8 msg_pending:1; | |
169 | u8 reserved:7; | |
170 | }; | |
171 | }; | |
172 | ||
173 | /* Define synthetic interrupt controller message header. */ | |
174 | struct hv_message_header { | |
175 | enum hv_message_type message_type; | |
176 | u8 payload_size; | |
177 | union hv_message_flags message_flags; | |
178 | u8 reserved[2]; | |
179 | union { | |
180 | u64 sender; | |
181 | union hv_port_id port; | |
182 | }; | |
183 | }; | |
184 | ||
185 | /* Define timer message payload structure. */ | |
186 | struct hv_timer_message_payload { | |
187 | u32 timer_index; | |
188 | u32 reserved; | |
189 | u64 expiration_time; /* When the timer expired */ | |
190 | u64 delivery_time; /* When the message was delivered */ | |
191 | }; | |
192 | ||
193 | /* Define synthetic interrupt controller message format. */ | |
194 | struct hv_message { | |
195 | struct hv_message_header header; | |
196 | union { | |
197 | u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT]; | |
198 | } u ; | |
199 | }; | |
200 | ||
201 | /* Define the number of message buffers associated with each port. */ | |
202 | #define HV_PORT_MESSAGE_BUFFER_COUNT (16) | |
203 | ||
204 | /* Define the synthetic interrupt message page layout. */ | |
205 | struct hv_message_page { | |
206 | struct hv_message sint_message[HV_SYNIC_SINT_COUNT]; | |
207 | }; | |
208 | ||
209 | /* Define the synthetic interrupt controller event flags format. */ | |
210 | union hv_synic_event_flags { | |
211 | u8 flags8[HV_EVENT_FLAGS_BYTE_COUNT]; | |
212 | u32 flags32[HV_EVENT_FLAGS_DWORD_COUNT]; | |
213 | }; | |
214 | ||
215 | /* Define the synthetic interrupt flags page layout. */ | |
216 | struct hv_synic_event_flags_page { | |
217 | union hv_synic_event_flags sintevent_flags[HV_SYNIC_SINT_COUNT]; | |
218 | }; | |
219 | ||
220 | /* Define SynIC control register. */ | |
221 | union hv_synic_scontrol { | |
222 | u64 as_uint64; | |
223 | struct { | |
224 | u64 enable:1; | |
225 | u64 reserved:63; | |
226 | }; | |
227 | }; | |
228 | ||
229 | /* Define synthetic interrupt source. */ | |
230 | union hv_synic_sint { | |
231 | u64 as_uint64; | |
232 | struct { | |
233 | u64 vector:8; | |
234 | u64 reserved1:8; | |
235 | u64 masked:1; | |
236 | u64 auto_eoi:1; | |
237 | u64 reserved2:46; | |
238 | }; | |
239 | }; | |
240 | ||
241 | /* Define the format of the SIMP register */ | |
242 | union hv_synic_simp { | |
243 | u64 as_uint64; | |
244 | struct { | |
245 | u64 simp_enabled:1; | |
246 | u64 preserved:11; | |
247 | u64 base_simp_gpa:52; | |
248 | }; | |
249 | }; | |
250 | ||
251 | /* Define the format of the SIEFP register */ | |
252 | union hv_synic_siefp { | |
253 | u64 as_uint64; | |
254 | struct { | |
255 | u64 siefp_enabled:1; | |
256 | u64 preserved:11; | |
257 | u64 base_siefp_gpa:52; | |
258 | }; | |
259 | }; | |
260 | ||
261 | /* Definitions for the monitored notification facility */ | |
262 | union hv_monitor_trigger_group { | |
263 | u64 as_uint64; | |
264 | struct { | |
265 | u32 pending; | |
266 | u32 armed; | |
267 | }; | |
268 | }; | |
269 | ||
270 | struct hv_monitor_parameter { | |
271 | union hv_connection_id connectionid; | |
272 | u16 flagnumber; | |
273 | u16 rsvdz; | |
274 | }; | |
275 | ||
276 | union hv_monitor_trigger_state { | |
277 | u32 asu32; | |
278 | ||
279 | struct { | |
280 | u32 group_enable:4; | |
281 | u32 rsvdz:28; | |
282 | }; | |
283 | }; | |
284 | ||
285 | /* struct hv_monitor_page Layout */ | |
286 | /* ------------------------------------------------------ */ | |
287 | /* | 0 | TriggerState (4 bytes) | Rsvd1 (4 bytes) | */ | |
288 | /* | 8 | TriggerGroup[0] | */ | |
289 | /* | 10 | TriggerGroup[1] | */ | |
290 | /* | 18 | TriggerGroup[2] | */ | |
291 | /* | 20 | TriggerGroup[3] | */ | |
292 | /* | 28 | Rsvd2[0] | */ | |
293 | /* | 30 | Rsvd2[1] | */ | |
294 | /* | 38 | Rsvd2[2] | */ | |
295 | /* | 40 | NextCheckTime[0][0] | NextCheckTime[0][1] | */ | |
296 | /* | ... | */ | |
297 | /* | 240 | Latency[0][0..3] | */ | |
298 | /* | 340 | Rsvz3[0] | */ | |
299 | /* | 440 | Parameter[0][0] | */ | |
300 | /* | 448 | Parameter[0][1] | */ | |
301 | /* | ... | */ | |
302 | /* | 840 | Rsvd4[0] | */ | |
303 | /* ------------------------------------------------------ */ | |
304 | struct hv_monitor_page { | |
305 | union hv_monitor_trigger_state trigger_state; | |
306 | u32 rsvdz1; | |
307 | ||
308 | union hv_monitor_trigger_group trigger_group[4]; | |
309 | u64 rsvdz2[3]; | |
310 | ||
311 | s32 next_checktime[4][32]; | |
312 | ||
313 | u16 latency[4][32]; | |
314 | u64 rsvdz3[32]; | |
315 | ||
316 | struct hv_monitor_parameter parameter[4][32]; | |
317 | ||
318 | u8 rsvdz4[1984]; | |
319 | }; | |
320 | ||
321 | /* Declare the various hypercall operations. */ | |
322 | enum hv_call_code { | |
323 | HVCALL_POST_MESSAGE = 0x005c, | |
324 | HVCALL_SIGNAL_EVENT = 0x005d, | |
325 | }; | |
326 | ||
327 | /* Definition of the hv_post_message hypercall input structure. */ | |
328 | struct hv_input_post_message { | |
329 | union hv_connection_id connectionid; | |
330 | u32 reserved; | |
331 | enum hv_message_type message_type; | |
332 | u32 payload_size; | |
333 | u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT]; | |
334 | }; | |
335 | ||
336 | /* Definition of the hv_signal_event hypercall input structure. */ | |
337 | struct hv_input_signal_event { | |
338 | union hv_connection_id connectionid; | |
339 | u16 flag_number; | |
340 | u16 rsvdz; | |
341 | }; | |
342 | ||
343 | /* | |
344 | * Versioning definitions used for guests reporting themselves to the | |
345 | * hypervisor, and visa versa. | |
346 | */ | |
347 | ||
348 | /* Version info reported by guest OS's */ | |
349 | enum hv_guest_os_vendor { | |
350 | HVGUESTOS_VENDOR_MICROSOFT = 0x0001 | |
351 | }; | |
352 | ||
353 | enum hv_guest_os_microsoft_ids { | |
354 | HVGUESTOS_MICROSOFT_UNDEFINED = 0x00, | |
355 | HVGUESTOS_MICROSOFT_MSDOS = 0x01, | |
356 | HVGUESTOS_MICROSOFT_WINDOWS3X = 0x02, | |
357 | HVGUESTOS_MICROSOFT_WINDOWS9X = 0x03, | |
358 | HVGUESTOS_MICROSOFT_WINDOWSNT = 0x04, | |
359 | HVGUESTOS_MICROSOFT_WINDOWSCE = 0x05 | |
360 | }; | |
361 | ||
362 | /* | |
363 | * Declare the MSR used to identify the guest OS. | |
364 | */ | |
365 | #define HV_X64_MSR_GUEST_OS_ID 0x40000000 | |
366 | ||
367 | union hv_x64_msr_guest_os_id_contents { | |
368 | u64 as_uint64; | |
369 | struct { | |
370 | u64 build_number:16; | |
371 | u64 service_version:8; /* Service Pack, etc. */ | |
372 | u64 minor_version:8; | |
373 | u64 major_version:8; | |
374 | u64 os_id:8; /* enum hv_guest_os_microsoft_ids (if Vendor=MS) */ | |
375 | u64 vendor_id:16; /* enum hv_guest_os_vendor */ | |
376 | }; | |
377 | }; | |
378 | ||
379 | /* | |
380 | * Declare the MSR used to setup pages used to communicate with the hypervisor. | |
381 | */ | |
382 | #define HV_X64_MSR_HYPERCALL 0x40000001 | |
383 | ||
384 | union hv_x64_msr_hypercall_contents { | |
385 | u64 as_uint64; | |
386 | struct { | |
387 | u64 enable:1; | |
388 | u64 reserved:11; | |
389 | u64 guest_physical_address:52; | |
390 | }; | |
391 | }; | |
392 | ||
0f2a6619 | 393 | #endif /* _HYPERV_VMBUS_H */ |