Commit | Line | Data |
---|---|---|
565e7dc8 HJ |
1 | /* |
2 | * | |
3 | * Copyright (c) 2009, 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 | * | |
22 | */ | |
23 | ||
24 | #pragma once | |
25 | ||
26 | // | |
27 | // Define the virtual APIC registers | |
28 | // | |
29 | #define HV_X64_MSR_EOI (0x40000070) | |
30 | #define HV_X64_MSR_ICR (0x40000071) | |
31 | #define HV_X64_MSR_TPR (0x40000072) | |
32 | #define HV_X64_MSR_APIC_ASSIST_PAGE (0x40000073) | |
33 | ||
34 | // | |
35 | // Define version of the synthetic interrupt controller. | |
36 | // | |
37 | ||
38 | #define HV_SYNIC_VERSION (1) | |
39 | ||
40 | ||
41 | // | |
42 | // Define synthetic interrupt controller model specific registers. | |
43 | // | |
44 | ||
45 | #define HV_X64_MSR_SCONTROL (0x40000080) | |
46 | #define HV_X64_MSR_SVERSION (0x40000081) | |
47 | #define HV_X64_MSR_SIEFP (0x40000082) | |
48 | #define HV_X64_MSR_SIMP (0x40000083) | |
49 | #define HV_X64_MSR_EOM (0x40000084) | |
50 | #define HV_X64_MSR_SINT0 (0x40000090) | |
51 | #define HV_X64_MSR_SINT1 (0x40000091) | |
52 | #define HV_X64_MSR_SINT2 (0x40000092) | |
53 | #define HV_X64_MSR_SINT3 (0x40000093) | |
54 | #define HV_X64_MSR_SINT4 (0x40000094) | |
55 | #define HV_X64_MSR_SINT5 (0x40000095) | |
56 | #define HV_X64_MSR_SINT6 (0x40000096) | |
57 | #define HV_X64_MSR_SINT7 (0x40000097) | |
58 | #define HV_X64_MSR_SINT8 (0x40000098) | |
59 | #define HV_X64_MSR_SINT9 (0x40000099) | |
60 | #define HV_X64_MSR_SINT10 (0x4000009A) | |
61 | #define HV_X64_MSR_SINT11 (0x4000009B) | |
62 | #define HV_X64_MSR_SINT12 (0x4000009C) | |
63 | #define HV_X64_MSR_SINT13 (0x4000009D) | |
64 | #define HV_X64_MSR_SINT14 (0x4000009E) | |
65 | #define HV_X64_MSR_SINT15 (0x4000009F) | |
66 | ||
67 | // | |
68 | // Define the expected SynIC version. | |
69 | // | |
70 | #define HV_SYNIC_VERSION_1 (0x1) | |
71 | ||
72 | // | |
73 | // Define synthetic interrupt controller message constants. | |
74 | // | |
75 | ||
76 | #define HV_MESSAGE_SIZE (256) | |
77 | #define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240) | |
78 | #define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30) | |
79 | #define HV_ANY_VP (0xFFFFFFFF) | |
80 | ||
81 | // | |
82 | // Define synthetic interrupt controller flag constants. | |
83 | // | |
84 | ||
85 | #define HV_EVENT_FLAGS_COUNT (256 * 8) | |
86 | #define HV_EVENT_FLAGS_BYTE_COUNT (256) | |
87 | #define HV_EVENT_FLAGS_DWORD_COUNT (256 / sizeof(UINT32)) | |
88 | ||
89 | // | |
90 | // Define hypervisor message types. | |
91 | // | |
92 | typedef enum _HV_MESSAGE_TYPE | |
93 | { | |
94 | HvMessageTypeNone = 0x00000000, | |
95 | ||
96 | // | |
97 | // Memory access messages. | |
98 | // | |
99 | HvMessageTypeUnmappedGpa = 0x80000000, | |
100 | HvMessageTypeGpaIntercept = 0x80000001, | |
101 | ||
102 | // | |
103 | // Timer notification messages. | |
104 | // | |
105 | HvMessageTimerExpired = 0x80000010, | |
106 | ||
107 | // | |
108 | // Error messages. | |
109 | // | |
110 | HvMessageTypeInvalidVpRegisterValue = 0x80000020, | |
111 | HvMessageTypeUnrecoverableException = 0x80000021, | |
112 | HvMessageTypeUnsupportedFeature = 0x80000022, | |
113 | ||
114 | // | |
115 | // Trace buffer complete messages. | |
116 | // | |
117 | HvMessageTypeEventLogBufferComplete = 0x80000040, | |
118 | ||
119 | // | |
120 | // Platform-specific processor intercept messages. | |
121 | // | |
122 | HvMessageTypeX64IoPortIntercept = 0x80010000, | |
123 | HvMessageTypeX64MsrIntercept = 0x80010001, | |
124 | HvMessageTypeX64CpuidIntercept = 0x80010002, | |
125 | HvMessageTypeX64ExceptionIntercept = 0x80010003, | |
126 | HvMessageTypeX64ApicEoi = 0x80010004, | |
127 | HvMessageTypeX64LegacyFpError = 0x80010005 | |
128 | ||
129 | } HV_MESSAGE_TYPE, *PHV_MESSAGE_TYPE; | |
130 | ||
131 | // | |
132 | // Define the number of synthetic interrupt sources. | |
133 | // | |
134 | ||
135 | #define HV_SYNIC_SINT_COUNT (16) | |
136 | #define HV_SYNIC_STIMER_COUNT (4) | |
137 | ||
138 | // | |
139 | // Define the synthetic interrupt source index type. | |
140 | // | |
141 | ||
142 | typedef UINT32 HV_SYNIC_SINT_INDEX, *PHV_SYNIC_SINT_INDEX; | |
143 | ||
144 | // | |
145 | // Define partition identifier type. | |
146 | // | |
147 | ||
148 | typedef UINT64 HV_PARTITION_ID, *PHV_PARTITION_ID; | |
149 | ||
150 | // | |
151 | // Define invalid partition identifier. | |
152 | // | |
153 | #define HV_PARTITION_ID_INVALID ((HV_PARTITION_ID) 0x0) | |
154 | ||
155 | // | |
156 | // Define connection identifier type. | |
157 | // | |
158 | ||
159 | typedef union _HV_CONNECTION_ID | |
160 | { | |
161 | UINT32 AsUINT32; | |
162 | ||
163 | struct | |
164 | { | |
165 | UINT32 Id:24; | |
166 | UINT32 Reserved:8; | |
167 | } u; | |
168 | ||
169 | } HV_CONNECTION_ID, *PHV_CONNECTION_ID; | |
170 | ||
171 | // | |
172 | // Define port identifier type. | |
173 | // | |
174 | ||
175 | typedef union _HV_PORT_ID | |
176 | { | |
177 | UINT32 AsUINT32; | |
178 | ||
179 | struct | |
180 | { | |
181 | UINT32 Id:24; | |
182 | UINT32 Reserved:8; | |
183 | } u ; | |
184 | ||
185 | } HV_PORT_ID, *PHV_PORT_ID; | |
186 | ||
187 | // | |
188 | // Define port type. | |
189 | // | |
190 | ||
191 | typedef enum _HV_PORT_TYPE | |
192 | { | |
193 | HvPortTypeMessage = 1, | |
194 | HvPortTypeEvent = 2, | |
195 | HvPortTypeMonitor = 3 | |
196 | } HV_PORT_TYPE, *PHV_PORT_TYPE; | |
197 | ||
198 | // | |
199 | // Define port information structure. | |
200 | // | |
201 | ||
202 | typedef struct _HV_PORT_INFO | |
203 | { | |
204 | HV_PORT_TYPE PortType; | |
205 | UINT32 Padding; | |
206 | ||
207 | union | |
208 | { | |
209 | struct | |
210 | { | |
211 | HV_SYNIC_SINT_INDEX TargetSint; | |
212 | HV_VP_INDEX TargetVp; | |
213 | UINT64 RsvdZ; | |
214 | } MessagePortInfo; | |
215 | ||
216 | struct | |
217 | { | |
218 | HV_SYNIC_SINT_INDEX TargetSint; | |
219 | HV_VP_INDEX TargetVp; | |
220 | UINT16 BaseFlagNumber; | |
221 | UINT16 FlagCount; | |
222 | UINT32 RsvdZ; | |
223 | } EventPortInfo; | |
224 | ||
225 | struct | |
226 | { | |
227 | HV_GPA MonitorAddress; | |
228 | UINT64 RsvdZ; | |
229 | } MonitorPortInfo; | |
230 | }; | |
231 | } HV_PORT_INFO, *PHV_PORT_INFO; | |
232 | ||
233 | typedef const HV_PORT_INFO *PCHV_PORT_INFO; | |
234 | ||
235 | typedef struct _HV_CONNECTION_INFO | |
236 | { | |
237 | HV_PORT_TYPE PortType; | |
238 | UINT32 Padding; | |
239 | ||
240 | union | |
241 | { | |
242 | struct | |
243 | { | |
244 | UINT64 RsvdZ; | |
245 | } MessageConnectionInfo; | |
246 | ||
247 | struct | |
248 | { | |
249 | UINT64 RsvdZ; | |
250 | } EventConnectionInfo; | |
251 | ||
252 | struct | |
253 | { | |
254 | HV_GPA MonitorAddress; | |
255 | } MonitorConnectionInfo; | |
256 | }; | |
257 | } HV_CONNECTION_INFO, *PHV_CONNECTION_INFO; | |
258 | ||
259 | typedef const HV_CONNECTION_INFO *PCHV_CONNECTION_INFO; | |
260 | ||
261 | // | |
262 | // Define synthetic interrupt controller message flags. | |
263 | // | |
264 | ||
265 | typedef union _HV_MESSAGE_FLAGS | |
266 | { | |
5654e932 | 267 | u8 Asu8; |
565e7dc8 HJ |
268 | struct |
269 | { | |
5654e932 GKH |
270 | u8 MessagePending:1; |
271 | u8 Reserved:7; | |
565e7dc8 HJ |
272 | }; |
273 | } HV_MESSAGE_FLAGS, *PHV_MESSAGE_FLAGS; | |
274 | ||
275 | ||
276 | // | |
277 | // Define synthetic interrupt controller message header. | |
278 | // | |
279 | ||
280 | typedef struct _HV_MESSAGE_HEADER | |
281 | { | |
282 | HV_MESSAGE_TYPE MessageType; | |
5654e932 | 283 | u8 PayloadSize; |
565e7dc8 | 284 | HV_MESSAGE_FLAGS MessageFlags; |
5654e932 | 285 | u8 Reserved[2]; |
565e7dc8 HJ |
286 | union |
287 | { | |
288 | HV_PARTITION_ID Sender; | |
289 | HV_PORT_ID Port; | |
290 | }; | |
291 | ||
292 | } HV_MESSAGE_HEADER, *PHV_MESSAGE_HEADER; | |
293 | ||
294 | // | |
295 | // Define timer message payload structure. | |
296 | // | |
297 | typedef struct _HV_TIMER_MESSAGE_PAYLOAD | |
298 | { | |
299 | UINT32 TimerIndex; | |
300 | UINT32 Reserved; | |
301 | HV_NANO100_TIME ExpirationTime; // When the timer expired | |
302 | HV_NANO100_TIME DeliveryTime; // When the message was delivered | |
303 | } HV_TIMER_MESSAGE_PAYLOAD, *PHV_TIMER_MESSAGE_PAYLOAD; | |
304 | ||
305 | // | |
306 | // Define synthetic interrupt controller message format. | |
307 | // | |
308 | ||
309 | typedef struct _HV_MESSAGE | |
310 | { | |
311 | HV_MESSAGE_HEADER Header; | |
312 | union | |
313 | { | |
314 | UINT64 Payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT]; | |
315 | } u ; | |
316 | } HV_MESSAGE, *PHV_MESSAGE; | |
317 | ||
318 | // | |
319 | // Define the number of message buffers associated with each port. | |
320 | // | |
321 | ||
322 | #define HV_PORT_MESSAGE_BUFFER_COUNT (16) | |
323 | ||
324 | // | |
325 | // Define the synthetic interrupt message page layout. | |
326 | // | |
327 | ||
328 | typedef struct _HV_MESSAGE_PAGE | |
329 | { | |
330 | volatile HV_MESSAGE SintMessage[HV_SYNIC_SINT_COUNT]; | |
331 | } HV_MESSAGE_PAGE, *PHV_MESSAGE_PAGE; | |
332 | ||
333 | ||
334 | // | |
335 | // Define the synthetic interrupt controller event flags format. | |
336 | // | |
337 | ||
338 | typedef union _HV_SYNIC_EVENT_FLAGS | |
339 | { | |
5654e932 | 340 | u8 Flags8[HV_EVENT_FLAGS_BYTE_COUNT]; |
565e7dc8 HJ |
341 | UINT32 Flags32[HV_EVENT_FLAGS_DWORD_COUNT]; |
342 | } HV_SYNIC_EVENT_FLAGS, *PHV_SYNIC_EVENT_FLAGS; | |
343 | ||
344 | ||
345 | // | |
346 | // Define the synthetic interrupt flags page layout. | |
347 | // | |
348 | ||
349 | typedef struct _HV_SYNIC_EVENT_FLAGS_PAGE | |
350 | { | |
351 | volatile HV_SYNIC_EVENT_FLAGS SintEventFlags[HV_SYNIC_SINT_COUNT]; | |
352 | } HV_SYNIC_EVENT_FLAGS_PAGE, *PHV_SYNIC_EVENT_FLAGS_PAGE; | |
353 | ||
354 | ||
355 | // | |
356 | // Define SynIC control register. | |
357 | // | |
358 | typedef union _HV_SYNIC_SCONTROL | |
359 | { | |
360 | UINT64 AsUINT64; | |
361 | struct | |
362 | { | |
363 | UINT64 Enable:1; | |
364 | UINT64 Reserved:63; | |
365 | }; | |
366 | } HV_SYNIC_SCONTROL, *PHV_SYNIC_SCONTROL; | |
367 | ||
368 | // | |
369 | // Define synthetic interrupt source. | |
370 | // | |
371 | ||
372 | typedef union _HV_SYNIC_SINT | |
373 | { | |
374 | UINT64 AsUINT64; | |
375 | struct | |
376 | { | |
377 | UINT64 Vector :8; | |
378 | UINT64 Reserved1 :8; | |
379 | UINT64 Masked :1; | |
380 | UINT64 AutoEoi :1; | |
381 | UINT64 Reserved2 :46; | |
382 | }; | |
383 | } HV_SYNIC_SINT, *PHV_SYNIC_SINT; | |
384 | ||
385 | // | |
386 | // Define the format of the SIMP register | |
387 | // | |
388 | ||
389 | typedef union _HV_SYNIC_SIMP | |
390 | { | |
391 | UINT64 AsUINT64; | |
392 | struct | |
393 | { | |
394 | UINT64 SimpEnabled : 1; | |
395 | UINT64 Preserved : 11; | |
396 | UINT64 BaseSimpGpa : 52; | |
397 | }; | |
398 | } HV_SYNIC_SIMP, *PHV_SYNIC_SIMP; | |
399 | ||
400 | // | |
401 | // Define the format of the SIEFP register | |
402 | // | |
403 | ||
404 | typedef union _HV_SYNIC_SIEFP | |
405 | { | |
406 | UINT64 AsUINT64; | |
407 | struct | |
408 | { | |
409 | UINT64 SiefpEnabled : 1; | |
410 | UINT64 Preserved : 11; | |
411 | UINT64 BaseSiefpGpa : 52; | |
412 | }; | |
413 | } HV_SYNIC_SIEFP, *PHV_SYNIC_SIEFP; | |
414 | ||
415 | // | |
416 | // Definitions for the monitored notification facility | |
417 | // | |
418 | ||
419 | typedef union _HV_MONITOR_TRIGGER_GROUP | |
420 | { | |
421 | UINT64 AsUINT64; | |
422 | ||
423 | struct | |
424 | { | |
425 | UINT32 Pending; | |
426 | UINT32 Armed; | |
427 | }; | |
428 | ||
429 | } HV_MONITOR_TRIGGER_GROUP, *PHV_MONITOR_TRIGGER_GROUP; | |
430 | ||
431 | typedef struct _HV_MONITOR_PARAMETER | |
432 | { | |
433 | HV_CONNECTION_ID ConnectionId; | |
434 | UINT16 FlagNumber; | |
435 | UINT16 RsvdZ; | |
436 | } HV_MONITOR_PARAMETER, *PHV_MONITOR_PARAMETER; | |
437 | ||
438 | typedef union _HV_MONITOR_TRIGGER_STATE | |
439 | { | |
440 | UINT32 AsUINT32; | |
441 | ||
442 | struct | |
443 | { | |
444 | UINT32 GroupEnable : 4; | |
445 | UINT32 RsvdZ : 28; | |
446 | }; | |
447 | ||
448 | } HV_MONITOR_TRIGGER_STATE, *PHV_MONITOR_TRIGGER_STATE; | |
449 | ||
450 | // | |
451 | // HV_MONITOR_PAGE Layout | |
452 | // ------------------------------------------------------ | |
453 | // | 0 | TriggerState (4 bytes) | Rsvd1 (4 bytes) | | |
454 | // | 8 | TriggerGroup[0] | | |
455 | // | 10 | TriggerGroup[1] | | |
456 | // | 18 | TriggerGroup[2] | | |
457 | // | 20 | TriggerGroup[3] | | |
458 | // | 28 | Rsvd2[0] | | |
459 | // | 30 | Rsvd2[1] | | |
460 | // | 38 | Rsvd2[2] | | |
461 | // | 40 | NextCheckTime[0][0] | NextCheckTime[0][1] | | |
462 | // | ... | | |
463 | // | 240 | Latency[0][0..3] | | |
464 | // | 340 | Rsvz3[0] | | |
465 | // | 440 | Parameter[0][0] | | |
466 | // | 448 | Parameter[0][1] | | |
467 | // | ... | | |
468 | // | 840 | Rsvd4[0] | | |
469 | // ------------------------------------------------------ | |
470 | ||
471 | typedef struct _HV_MONITOR_PAGE | |
472 | { | |
473 | HV_MONITOR_TRIGGER_STATE TriggerState; | |
474 | UINT32 RsvdZ1; | |
475 | ||
476 | HV_MONITOR_TRIGGER_GROUP TriggerGroup[4]; | |
477 | UINT64 RsvdZ2[3]; | |
478 | ||
479 | INT32 NextCheckTime[4][32]; | |
480 | ||
481 | UINT16 Latency[4][32]; | |
482 | UINT64 RsvdZ3[32]; | |
483 | ||
484 | HV_MONITOR_PARAMETER Parameter[4][32]; | |
485 | ||
5654e932 | 486 | u8 RsvdZ4[1984]; |
565e7dc8 HJ |
487 | |
488 | } HV_MONITOR_PAGE, *PHV_MONITOR_PAGE; | |
489 | ||
490 | typedef volatile HV_MONITOR_PAGE* PVHV_MONITOR_PAGE; |