summaryrefslogtreecommitdiffstats
path: root/include/iprt/nt/hyperv.h
blob: 956b9d6c0dcf06a286ddf9fa85c4c3714aa0dd35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
/** @file
 * Hyper-V related types and definitions.
 */

/*
 * Copyright (C) 2018-2023 Oracle and/or its affiliates.
 *
 * This file is part of VirtualBox base platform packages, as
 * available from https://www.virtualbox.org.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, in version 3 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses>.
 *
 * The contents of this file may alternatively be used under the terms
 * of the Common Development and Distribution License Version 1.0
 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
 * in the VirtualBox distribution, in which case the provisions of the
 * CDDL are applicable instead of those of the GPL.
 *
 * You may elect to license modified versions of this file under the
 * terms and conditions of either the GPL or the CDDL or both.
 *
 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
 */

#ifndef IPRT_INCLUDED_nt_hyperv_h
#define IPRT_INCLUDED_nt_hyperv_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif


#ifndef IN_IDA_PRO
# include <iprt/types.h>
# include <iprt/assertcompile.h>
#else
# define RT_FLEXIBLE_ARRAY
# define RT_FLEXIBLE_ARRAY_EXTENSION
# define AssertCompile(expr)
# define AssertCompileSize(type, size)
# define AssertCompileMemberOffset(type, member, off)
typedef unsigned char uint8_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#endif


/** Hyper-V partition ID. */
typedef uint64_t HV_PARTITION_ID;
/** Invalid Hyper-V partition ID. */
#define HV_PARTITION_ID_INVALID UINT64_C(0)
/** Hyper-V virtual processor index (== VMCPUID). */
typedef uint32_t HV_VP_INDEX;
/** Guest physical address (== RTGCPHYS). */
typedef uint64_t HV_GPA;
/** Guest physical page number. */
typedef uint64_t HV_GPA_PAGE_NUMBER;
/** System(/parent) physical page number. */
typedef uint64_t HV_SPA_PAGE_NUMBER;
/** Hyper-V unsigned 128-bit integer type.   */
typedef struct { uint64_t Low64, High64; } HV_UINT128;
/** Hyper-V port ID. */
typedef union
{
    uint32_t        AsUINT32;
    struct
    {
        uint32_t    Id       : 24;
        uint32_t    Reserved : 8;
    };
} HV_PORT_ID;
/** Pointer to a Hyper-V port ID. */
typedef HV_PORT_ID *PHV_PORT_ID;


/**
 * Hypercall IDs.
 */
typedef enum
{
    HvCallReserved0000 = 0,

    HvCallSwitchVirtualAddressSpace,
    HvCallFlushVirtualAddressSpace,
    HvCallFlushVirtualAddressList,
    HvCallGetLogicalProcessorRunTime,
    /* 5, 6 & 7 are deprecated / reserved. */
    HvCallNotifyLongSpinWait = 8,
    HvCallParkLogicalProcessors,        /**< @since v2 */
    HvCallInvokeHypervisorDebugger,     /**< @since v2 - not mentioned in TLFS v5.0b  */
    HvCallSendSyntheticClusterIpi,      /**< @since v? */
    HvCallModifyVtlProtectionMask,      /**< @since v? */
    HvCallEnablePartitionVtl,           /**< @since v? */
    HvCallDisablePartitionVtl,          /**< @since v? */
    HvCallEnableVpVtl,                  /**< @since v? */
    HvCallDisableVpVtl,                 /**< @since v? */
    HvCallVtlCall,                      /**< @since v? */
    HvCallVtlReturn,                    /**< @since v? */
    HvCallFlushVirtualAddressSpaceEx,   /**< @since v? */
    HvCallFlushVirtualAddressListEx,    /**< @since v? */
    HvCallSendSyntheticClusterIpiEx,    /**< @since v? */
    /* Reserved: 0x16..0x3f */

    HvCallCreatePartition = 0x40,
    HvCallInitializePartition,
    HvCallFinalizePartition,
    HvCallDeletePartition,
    HvCallGetPartitionProperty,
    HvCallSetPartitionProperty,
    HvCallGetPartitionId,
    HvCallGetNextChildPartition,
    HvCallDepositMemory,                /**< 0x48 - Repeat call. */
    HvCallWithdrawMemory,               /**< 0x49 - Repeat call. */
    HvCallGetMemoryBalance,
    HvCallMapGpaPages,                  /**< 0X4b - Repeat call. */
    HvCallUnmapGpaPages,                /**< 0X4c - Repeat call. */
    HvCallInstallIntercept,
    HvCallCreateVp,
    HvCallDeleteVp,                     /**< 0x4f - Fast call.  */
    HvCallGetVpRegisters,               /**< 0x50 - Repeat call. */
    HvCallSetVpRegisters,               /**< 0x51 - Repeat call. */
    HvCallTranslateVirtualAddress,
    HvCallReadGpa,
    HvCallWriteGpa,
    HvCallAssertVirtualInterruptV1,
    HvCallClearVirtualInterrupt,        /**< 0x56 - Fast call. */
    HvCallCreatePortV1,
    HvCallDeletePort,                   /**< 0x58 - Fast call. */
    HvCallConnectPortV1,
    HvCallGetPortProperty,
    HvCallDisconnectPort,
    HvCallPostMessage,
    HvCallSignalEvent,
    HvCallSavePartitionState,
    HvCallRestorePartitionState,
    HvCallInitializeEventLogBufferGroup,
    HvCallFinalizeEventLogBufferGroup,
    HvCallCreateEventLogBuffer,
    HvCallDeleteEventLogBuffer,
    HvCallMapEventLogBuffer,
    HvCallUnmapEventLogBuffer,
    HvCallSetEventLogGroupSources,
    HvCallReleaseEventLogBuffer,
    HvCallFlushEventLogBuffer,
    HvCallPostDebugData,
    HvCallRetrieveDebugData,
    HvCallResetDebugSession,
    HvCallMapStatsPage,
    HvCallUnmapStatsPage,
    HvCallMapSparseGpaPages,            /**< @since v2 */
    HvCallSetSystemProperty,            /**< @since v2 */
    HvCallSetPortProperty,              /**< @since v2 */
    /* 0x71..0x75 reserved/deprecated (was v2 test IDs). */
    HvCallAddLogicalProcessor = 0x76,
    HvCallRemoveLogicalProcessor,
    HvCallQueryNumaDistance,
    HvCallSetLogicalProcessorProperty,
    HvCallGetLogicalProcessorProperty,
    HvCallGetSystemProperty,
    HvCallMapDeviceInterrupt,
    HvCallUnmapDeviceInterrupt,
    HvCallRetargetDeviceInterrupt,
    /* 0x7f is reserved. */
    HvCallMapDevicePages = 0x80,
    HvCallUnmapDevicePages,
    HvCallAttachDevice,
    HvCallDetachDevice,
    HvCallNotifyStandbyTransition,
    HvCallPrepareForSleep,
    HvCallPrepareForHibernate,
    HvCallNotifyPartitionEvent,
    HvCallGetLogicalProcessorRegisters,
    HvCallSetLogicalProcessorRegisters,
    HvCallQueryAssociatedLpsforMca,
    HvCallNotifyRingEmpty,
    HvCallInjectSyntheticMachineCheck,
    HvCallScrubPartition,
    HvCallCollectLivedump,
    HvCallDisableHypervisor,
    HvCallModifySparseGpaPages,
    HvCallRegisterInterceptResult,
    HvCallUnregisterInterceptResult,
    /* 0x93 is reserved/undocumented. */
    HvCallAssertVirtualInterrupt = 0x94,
    HvCallCreatePort,
    HvCallConnectPort,
    HvCallGetSpaPageList,
    /* 0x98 is reserved. */
    HvCallStartVirtualProcessor = 0x99,
    HvCallGetVpIndexFromApicId,
    /* 0x9b..0xae are reserved/undocumented.
       0xad: New version of HvCallGetVpRegisters? Perhaps on logical CPU or smth. */
    HvCallFlushGuestPhysicalAddressSpace = 0xaf,
    HvCallFlushGuestPhysicalAddressList,
    /* 0xb1..0xb4 are unknown */
    HvCallCreateCpuGroup = 0xb5,
    HvCallDeleteCpuGroup,
    HvCallGetCpuGroupProperty,
    HvCallSetCpuGroupProperty,
    HvCallGetCpuGroupAffinit,
    HvCallGetNextCpuGroup = 0xba,
    HvCallGetNextCpuGroupPartition,
    HvCallPrecommitGpaPages = 0xbe,
    HvCallUncommitGpaPages,             /**< Happens when VidDestroyGpaRangeCheckSecure/WHvUnmapGpaRange is called. */
    /* 0xc0 is unknown */
    HvCallVpRunloopRelated = 0xc2,      /**< Fast */
    /* 0xc3..0xcb are unknown */
    HvCallQueryVtlProtectionMaskRange = 0xcc,
    HvCallModifyVtlProtectionMaskRange,
    /* 0xce..0xd1 are unknown */
    HvCallAcquireSparseGpaPageHostAccess = 0xd2,
    HvCallReleaseSparseGpaPageHostAccess,
    HvCallCheckSparseGpaPageVtlAccess,
    HvCallAcquireSparseSpaPageHostAccess = 0xd7,
    HvCallReleaseSparseSpaPageHostAccess,
    HvCallAcceptGpaPages,                       /**< 0x18 byte input, zero rep, no output. */
    /* 0xda..0xe0 are unknown (not dug out yet) */
    HvCallMapVpRegisterPage = 0xe1,             /**< Takes partition id + VP index (16 bytes). Returns a physical address (8 bytes). */
    HvCallUnmapVpRegisterPage,                  /**< Takes partition id + VP index. */
    HvCallUnknownE3,
    HvCallUnknownE4,
    HvCallUnknownE5,
    HvCallUnknownE6,
    /** Number of defined hypercalls (varies with version). */
    HvCallCount
} HV_CALL_CODE;
AssertCompile(HvCallSendSyntheticClusterIpiEx == 0x15);
AssertCompile(HvCallMapGpaPages == 0x4b);
AssertCompile(HvCallSetPortProperty == 0x70);
AssertCompile(HvCallRetargetDeviceInterrupt == 0x7e);
AssertCompile(HvCallUnregisterInterceptResult == 0x92);
AssertCompile(HvCallGetSpaPageList == 0x97);
AssertCompile(HvCallFlushGuestPhysicalAddressList == 0xb0);
AssertCompile(HvCallUncommitGpaPages == 0xbf);
AssertCompile(HvCallCount == 0xe7);

/** Makes the first parameter to a hypercall (rcx).  */
#define HV_MAKE_CALL_INFO(a_enmCallCode, a_cReps) ( (uint64_t)(a_enmCallCode) | ((uint64_t)(a_cReps) << 32) )
/** Makes the return value (success) for a rep hypercall. */
#define HV_MAKE_CALL_REP_RET(a_cReps)    ((uint64_t)(a_cReps) << 32)

/** Hypercall status code. */
typedef uint16_t HV_STATUS;

/** @name Hyper-V Hypercall status codes
 * @{ */
#define HV_STATUS_SUCCESS                                               (0x0000)
#define HV_STATUS_RESERVED_1                                            (0x0001)
#define HV_STATUS_INVALID_HYPERCALL_CODE                                (0x0002)
#define HV_STATUS_INVALID_HYPERCALL_INPUT                               (0x0003)
#define HV_STATUS_INVALID_ALIGNMENT                                     (0x0004)
#define HV_STATUS_INVALID_PARAMETER                                     (0x0005)
#define HV_STATUS_ACCESS_DENIED                                         (0x0006)
#define HV_STATUS_INVALID_PARTITION_STATE                               (0x0007)
#define HV_STATUS_OPERATION_DENIED                                      (0x0008)
#define HV_STATUS_UNKNOWN_PROPERTY                                      (0x0009)
#define HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE                           (0x000a)
#define HV_STATUS_INSUFFICIENT_MEMORY                                   (0x000b)
#define HV_STATUS_PARTITION_TOO_DEEP                                    (0x000c)
#define HV_STATUS_INVALID_PARTITION_ID                                  (0x000d)
#define HV_STATUS_INVALID_VP_INDEX                                      (0x000e)
#define HV_STATUS_RESERVED_F                                            (0x000f)
#define HV_STATUS_NOT_FOUND                                             (0x0010)
#define HV_STATUS_INVALID_PORT_ID                                       (0x0011)
#define HV_STATUS_INVALID_CONNECTION_ID                                 (0x0012)
#define HV_STATUS_INSUFFICIENT_BUFFERS                                  (0x0013)
#define HV_STATUS_NOT_ACKNOWLEDGED                                      (0x0014)
#define HV_STATUS_INVALID_VP_STATE                                      (0x0015)
#define HV_STATUS_ACKNOWLEDGED                                          (0x0016)
#define HV_STATUS_INVALID_SAVE_RESTORE_STATE                            (0x0017)
#define HV_STATUS_INVALID_SYNIC_STATE                                   (0x0018)
#define HV_STATUS_OBJECT_IN_USE                                         (0x0019)
#define HV_STATUS_INVALID_PROXIMITY_DOMAIN_INFO                         (0x001a)
#define HV_STATUS_NO_DATA                                               (0x001b)
#define HV_STATUS_INACTIVE                                              (0x001c)
#define HV_STATUS_NO_RESOURCES                                          (0x001d)
#define HV_STATUS_FEATURE_UNAVAILABLE                                   (0x001e)
#define HV_STATUS_PARTIAL_PACKET                                        (0x001f)
#define HV_STATUS_PROCESSOR_FEATURE_SSE3_NOT_SUPPORTED                  (0x0020)
#define HV_STATUS_PROCESSOR_FEATURE_LAHFSAHF_NOT_SUPPORTED              (0x0021)
#define HV_STATUS_PROCESSOR_FEATURE_SSSE3_NOT_SUPPORTED                 (0x0022)
#define HV_STATUS_PROCESSOR_FEATURE_SSE4_1_NOT_SUPPORTED                (0x0023)
#define HV_STATUS_PROCESSOR_FEATURE_SSE4_2_NOT_SUPPORTED                (0x0024)
#define HV_STATUS_PROCESSOR_FEATURE_SSE4A_NOT_SUPPORTED                 (0x0025)
#define HV_STATUS_PROCESSOR_FEATURE_XOP_NOT_SUPPORTED                   (0x0026)
#define HV_STATUS_PROCESSOR_FEATURE_POPCNT_NOT_SUPPORTED                (0x0027)
#define HV_STATUS_PROCESSOR_FEATURE_CMPXCHG16B_NOT_SUPPORTED            (0x0028)
#define HV_STATUS_PROCESSOR_FEATURE_ALTMOVCR8_NOT_SUPPORTED             (0x0029)
#define HV_STATUS_PROCESSOR_FEATURE_LZCNT_NOT_SUPPORTED                 (0x002a)
#define HV_STATUS_PROCESSOR_FEATURE_MISALIGNED_SSE_NOT_SUPPORTED        (0x002b)
#define HV_STATUS_PROCESSOR_FEATURE_MMX_EXT_NOT_SUPPORTED               (0x002c)
#define HV_STATUS_PROCESSOR_FEATURE_3DNOW_NOT_SUPPORTED                 (0x002d)
#define HV_STATUS_PROCESSOR_FEATURE_EXTENDED_3DNOW_NOT_SUPPORTED        (0x002e)
#define HV_STATUS_PROCESSOR_FEATURE_PAGE_1GB_NOT_SUPPORTED              (0x002f)
#define HV_STATUS_PROCESSOR_CACHE_LINE_FLUSH_SIZE_INCOMPATIBLE          (0x0030)
#define HV_STATUS_PROCESSOR_FEATURE_XSAVE_NOT_SUPPORTED                 (0x0031)
#define HV_STATUS_PROCESSOR_FEATURE_XSAVEOPT_NOT_SUPPORTED              (0x0032)
#define HV_STATUS_INSUFFICIENT_BUFFER                                   (0x0033)
#define HV_STATUS_PROCESSOR_FEATURE_XSAVE_AVX_NOT_SUPPORTED             (0x0034)
#define HV_STATUS_PROCESSOR_FEATURE_XSAVE_ FEATURE_NOT_SUPPORTED        (0x0035)
#define HV_STATUS_PROCESSOR_XSAVE_SAVE_AREA_INCOMPATIBLE                (0x0036)
#define HV_STATUS_INCOMPATIBLE_PROCESSOR                                (0x0037)
#define HV_STATUS_INSUFFICIENT_DEVICE_DOMAINS                           (0x0038)
#define HV_STATUS_PROCESSOR_FEATURE_AES_NOT_SUPPORTED                   (0x0039)
#define HV_STATUS_PROCESSOR_FEATURE_PCLMULQDQ_NOT_SUPPORTED             (0x003a)
#define HV_STATUS_PROCESSOR_FEATURE_INCOMPATIBLE_XSAVE_FEATURES         (0x003b)
#define HV_STATUS_CPUID_FEATURE_VALIDATION_ERROR                        (0x003c)
#define HV_STATUS_CPUID_XSAVE_FEATURE_VALIDATION_ERROR                  (0x003d)
#define HV_STATUS_PROCESSOR_STARTUP_TIMEOUT                             (0x003e)
#define HV_STATUS_SMX_ENABLED                                           (0x003f)
#define HV_STATUS_PROCESSOR_FEATURE_PCID_NOT_SUPPORTED                  (0x0040)
#define HV_STATUS_INVALID_LP_INDEX                                      (0x0041)
#define HV_STATUS_FEATURE_FMA4_NOT_SUPPORTED                            (0x0042)
#define HV_STATUS_FEATURE_F16C_NOT_SUPPORTED                            (0x0043)
#define HV_STATUS_PROCESSOR_FEATURE_RDRAND_NOT_SUPPORTED                (0x0044)
#define HV_STATUS_PROCESSOR_FEATURE_RDWRFSGS_NOT_SUPPORTED              (0x0045)
#define HV_STATUS_PROCESSOR_FEATURE_SMEP_NOT_SUPPORTED                  (0x0046)
#define HV_STATUS_PROCESSOR_FEATURE_ENHANCED_FAST_STRING_NOT_SUPPORTED  (0x0047)
#define HV_STATUS_PROCESSOR_FEATURE_MOVBE_NOT_SUPPORTED                 (0x0048)
#define HV_STATUS_PROCESSOR_FEATURE_BMI1_NOT_SUPPORTED                  (0x0049)
#define HV_STATUS_PROCESSOR_FEATURE_BMI2_NOT_SUPPORTED                  (0x004a)
#define HV_STATUS_PROCESSOR_FEATURE_HLE_NOT_SUPPORTED                   (0x004b)
#define HV_STATUS_PROCESSOR_FEATURE_RTM_NOT_SUPPORTED                   (0x004c)
#define HV_STATUS_PROCESSOR_FEATURE_XSAVE_FMA_NOT_SUPPORTED             (0x004d)
#define HV_STATUS_PROCESSOR_FEATURE_XSAVE_AVX2_NOT_SUPPORTED            (0x004e)
#define HV_STATUS_PROCESSOR_FEATURE_NPIEP1_NOT_SUPPORTED                (0x004f)
#define HV_STATUS_INVALID_REGISTER_VALUE                                (0x0050)
#define HV_STATUS_PROCESSOR_FEATURE_RDSEED_NOT_SUPPORTED                (0x0052)
#define HV_STATUS_PROCESSOR_FEATURE_ADX_NOT_SUPPORTED                   (0x0053)
#define HV_STATUS_PROCESSOR_FEATURE_SMAP_NOT_SUPPORTED                  (0x0054)
#define HV_STATUS_NX_NOT_DETECTED                                       (0x0055)
#define HV_STATUS_PROCESSOR_FEATURE_INTEL_PREFETCH_NOT_SUPPORTED        (0x0056)
#define HV_STATUS_INVALID_DEVICE_ID                                     (0x0057)
#define HV_STATUS_INVALID_DEVICE_STATE                                  (0x0058)
#define HV_STATUS_PENDING_PAGE_REQUESTS                                 (0x0059)
#define HV_STATUS_PAGE_REQUEST_INVALID                                  (0x0060)
#define HV_STATUS_OPERATION_FAILED                                      (0x0071)
#define HV_STATUS_NOT_ALLOWED_WITH_NESTED_VIRT_ACTIVE                   (0x0072)
/** @} */


/** Hyper-V partition property value. */
typedef uint64_t HV_PARTITION_PROPERTY;
/** Pointer to a partition property value. */
typedef HV_PARTITION_PROPERTY *PHV_PARTITION_PROPERTY;
/**
 * Hyper-V partition property code.
 * This is documented in TLFS, except version 5.x.
 */
typedef enum
{
    HvPartitionPropertyPrivilegeFlags = 0x00010000,
    HvPartitionPropertySyntheticProcessorFeaturesBanks, /**< Read by WHvApi::Capabilities::GetSyntheticProcessorFeaturesBanks (build 22000) */

    HvPartitionPropertyCpuReserve = 0x00020001,
    HvPartitionPropertyCpuCap,
    HvPartitionPropertyCpuWeight,
    HvPartitionPropertyUnknown20004,                /**< On exo partition (build 17134), initial value zero. */

    HvPartitionPropertyEmulatedTimerPeriod = 0x00030000, /**< @note Fails on exo partition (build 17134). */
    HvPartitionPropertyEmulatedTimerControl,        /**< @note Fails on exo partition (build 17134). */
    HvPartitionPropertyPmTimerAssist,               /**< @note Fails on exo partition (build 17134). */
    HvPartitionPropertyUnknown30003,                /**< @note WHvSetupPartition writes this (build 22000). */
    HvPartitionPropertyUnknown30004,                /**< ? */
    HvPartitionPropertyUnknown30005,                /**< WHvPartitionPropertyCodeReferenceTime maps to this (build 22000) */

    HvPartitionPropertyDebugChannelId = 0x00040000, /**< @note Hangs system on exo partition hangs (build 17134). */

    HvPartitionPropertyVirtualTlbPageCount = 0x00050000,
    HvPartitionPropertyUnknown50001,                /**< On exo partition (build 17134), initial value zero. */
    HvPartitionPropertyUnknown50002,                /**< On exo partition (build 17134), initial value zero. */
    HvPartitionPropertyUnknown50003,                /**< On exo partition (build 17134), initial value zero. */
    HvPartitionPropertyUnknown50004,                /**< On exo partition (build 17134), initial value zero. */
    HvPartitionPropertyUnknown50005,                /**< On exo partition (build 17134), initial value one. */
    HvPartitionPropertyUnknown50006,                /**< On exo partition (build 17134), initial value zero.
                                                     * @note build 22000/w11-ga fends this off in VID.SYS. */
    HvPartitionPropertyUnknown50007,
    HvPartitionPropertyUnknown50008,
    HvPartitionPropertyUnknown50009,
    HvPartitionPropertyUnknown5000a,
    HvPartitionPropertyUnknown5000b,
    HvPartitionPropertyUnknown5000c,
    HvPartitionPropertyUnknown5000d,
    HvPartitionPropertyUnknown5000e,
    HvPartitionPropertyUnknown5000f,
    HvPartitionPropertyUnknown50010,
    HvPartitionPropertyUnknown50012,
    HvPartitionPropertyUnknown50013,                /**< Set by WHvSetupPartition (build 22000) */
    HvPartitionPropertyUnknown50014,
    HvPartitionPropertyUnknown50015,
    HvPartitionPropertyUnknown50016,
    HvPartitionPropertyUnknown50017,                /**< Set by WHvSetupPartition (build 22000) */

    HvPartitionPropertyProcessorVendor = 0x00060000,
    HvPartitionPropertyProcessorFeatures,           /**< On exo/17134/threadripper: 0x6cb26f39fbf */
    HvPartitionPropertyProcessorXsaveFeatures,
    HvPartitionPropertyProcessorCLFlushSize,        /**< On exo/17134/threadripper: 8 */
    HvPartitionPropertyUnknown60004,                /**< On exo partition (build 17134), initial value zero. */
    HvPartitionPropertyUnknown60005,                /**< On exo partition (build 17134), initial value 0x603. */
    HvPartitionPropertyUnknown60006,                /**< On exo partition (build 17134), initial value 0x2c. */
    HvPartitionPropertyUnknown60007,                /**< WHvSetupPartition reads this (build 22000). */
    HvPartitionPropertyUnknown60008,                /**< WHvSetupPartition reads this (build 22000). */
    HvPartitionPropertyProcessorClockFrequency,     /**< Read by WHvApi::Capabilities::GetProcessorClockFrequency (build 22000). */
    HvPartitionPropertyProcessorFeaturesBank0,      /**< Read by WHvApi::Capabilities::GetProcessorFeaturesBanks (build 22000). */
    HvPartitionPropertyProcessorFeaturesBank1,      /**< Read by WHvApi::Capabilities::GetProcessorFeaturesBanks (build 22000). */

    HvPartitionPropertyGuestOsId = 0x00070000,      /**< @since v4 */

    HvPartitionPropertyUnknown800000 = 0x00080000   /**< On exo partition (build 17134), initial value zero. */
} HV_PARTITION_PROPERTY_CODE;
AssertCompileSize(HV_PARTITION_PROPERTY_CODE, 4);
/** Pointer to a partition property code. */
typedef HV_PARTITION_PROPERTY_CODE *PHV_PARTITION_PROPERTY_CODE;


/** Input for HvCallGetPartitionProperty. */
typedef struct
{
    HV_PARTITION_ID             PartitionId;
    HV_PARTITION_PROPERTY_CODE  PropertyCode;
    uint32_t                    uPadding;
} HV_INPUT_GET_PARTITION_PROPERTY;
AssertCompileSize(HV_INPUT_GET_PARTITION_PROPERTY, 16);
/** Pointer to input for HvCallGetPartitionProperty. */
typedef HV_INPUT_GET_PARTITION_PROPERTY *PHV_INPUT_GET_PARTITION_PROPERTY;

/** Output for HvCallGetPartitionProperty. */
typedef struct
{
    HV_PARTITION_PROPERTY       PropertyValue;
} HV_OUTPUT_GET_PARTITION_PROPERTY;
/** Pointer to output for HvCallGetPartitionProperty. */
typedef HV_OUTPUT_GET_PARTITION_PROPERTY *PHV_OUTPUT_GET_PARTITION_PROPERTY;


/** Input for HvCallSetPartitionProperty. */
typedef struct
{
    HV_PARTITION_ID             PartitionId;
    HV_PARTITION_PROPERTY_CODE  PropertyCode;
    uint32_t                    uPadding;
    HV_PARTITION_PROPERTY       PropertyValue;
} HV_INPUT_SET_PARTITION_PROPERTY;
AssertCompileSize(HV_INPUT_SET_PARTITION_PROPERTY, 24);
/** Pointer to input for HvCallSetPartitionProperty. */
typedef HV_INPUT_SET_PARTITION_PROPERTY *PHV_INPUT_SET_PARTITION_PROPERTY;


/** Hyper-V NUMA node ID.
 * On systems without NUMA, i.e. a single node, it uses 0 as identifier.  */
typedef uint32_t HV_PROXIMITY_DOMAIN_ID;
/** Pointer to NUMA node ID. */
typedef HV_PROXIMITY_DOMAIN_ID *PHV_PROXIMITY_DOMAIN_ID;

/** Hyper-V NUMA flags. */
typedef struct
{
    uint32_t    ProximityPreferred      : 1;    /**< When set, allocations may come from other NUMA nodes.  */
    uint32_t    Reserved                : 30;   /**< Reserved for future (as of circa v2). */
    uint32_t    ProxyimityInfoValid     : 1;    /**< Set if the NUMA information is valid. */
} HV_PROXIMITY_DOMAIN_FLAGS;
/** Pointer to Hyper-V NUMA flags. */
typedef HV_PROXIMITY_DOMAIN_FLAGS *PHV_PROXIMITY_DOMAIN_FLAGS;

/** Hyper-V NUMA information. */
typedef struct
{
    HV_PROXIMITY_DOMAIN_ID      Id;             /**< NUMA node identifier.  */
    HV_PROXIMITY_DOMAIN_FLAGS   Flags;          /**< NUMA flags. */
} HV_PROXIMITY_DOMAIN_INFO;
/** Pointer to Hyper-V NUMA information. */
typedef HV_PROXIMITY_DOMAIN_INFO *PHV_PROXIMITY_DOMAIN_INFO;

/** Input for HvCallGetMemoryBalance. */
typedef struct
{
    HV_PARTITION_ID             TargetPartitionId;
    HV_PROXIMITY_DOMAIN_INFO    ProximityDomainInfo;
} HV_INPUT_GET_MEMORY_BALANCE;
AssertCompileSize(HV_INPUT_GET_MEMORY_BALANCE, 16);
/** Pointer to the input for HvCallGetMemoryBalance. */
typedef HV_INPUT_GET_MEMORY_BALANCE *PHV_INPUT_GET_MEMORY_BALANCE;

/** Output for HvCallGetMemoryBalance. */
typedef struct
{
    uint64_t                    PagesAvailable;
    uint64_t                    PagesInUse;
} HV_OUTPUT_GET_MEMORY_BALANCE;
/** Pointer to the output for HvCallGetMemoryBalance. */
typedef HV_OUTPUT_GET_MEMORY_BALANCE *PHV_OUTPUT_GET_MEMORY_BALANCE;


/** @name Flags used with HvCallMapGpaPages and HvCallMapSparseGpaPages.
 * @note There seems to be a more flags defined after v2.
 * @{ */
typedef uint32_t HV_MAP_GPA_FLAGS;
#define HV_MAP_GPA_READABLE             UINT32_C(0x0001)
#define HV_MAP_GPA_WRITABLE             UINT32_C(0x0002)
#define HV_MAP_GPA_EXECUTABLE           UINT32_C(0x0004)
/** Seems this have to be set when HV_MAP_GPA_EXECUTABLE is (17101). */
#define HV_MAP_GPA_EXECUTABLE_AGAIN     UINT32_C(0x0008)
/** Dunno what this is yet, but it requires HV_MAP_GPA_DUNNO_1000.
 * The readable bit gets put here when both HV_MAP_GPA_DUNNO_1000 and
 * HV_MAP_GPA_DUNNO_MASK_0700 are clear. */
#define HV_MAP_GPA_DUNNO_ACCESS         UINT32_C(0x0010)
/** Guess work. */
#define HV_MAP_GPA_MAYBE_ACCESS_MASK    UINT32_C(0x001f)
/** Some kind of mask. */
#define HV_MAP_GPA_DUNNO_MASK_0700      UINT32_C(0x0700)
/** Dunno what this is, but required for HV_MAP_GPA_DUNNO_ACCESS. */
#define HV_MAP_GPA_DUNNO_1000           UINT32_C(0x1000)
/** Working with large 2MB pages. */
#define HV_MAP_GPA_LARGE                UINT32_C(0x2000)
/** Valid mask as per build 17101. */
#define HV_MAP_GPA_VALID_MASK           UINT32_C(0x7f1f)
/** @}  */

/** Input for HvCallMapGpaPages. */
typedef struct
{
    HV_PARTITION_ID     TargetPartitionId;
    HV_GPA_PAGE_NUMBER  TargetGpaBase;
    HV_MAP_GPA_FLAGS    MapFlags;
    uint32_t            u32ExplicitPadding;
    /* The repeating part: */
    RT_FLEXIBLE_ARRAY_EXTENSION
    HV_SPA_PAGE_NUMBER  PageList[RT_FLEXIBLE_ARRAY];
} HV_INPUT_MAP_GPA_PAGES;
AssertCompileMemberOffset(HV_INPUT_MAP_GPA_PAGES, PageList, 24);
/** Pointer to the input for HvCallMapGpaPages. */
typedef HV_INPUT_MAP_GPA_PAGES *PHV_INPUT_MAP_GPA_PAGES;


/** A parent to guest mapping pair for HvCallMapSparseGpaPages. */
typedef struct
{
    HV_GPA_PAGE_NUMBER TargetGpaPageNumber;
    HV_SPA_PAGE_NUMBER SourceSpaPageNumber;
} HV_GPA_MAPPING;
/** Pointer to a parent->guest mapping pair for HvCallMapSparseGpaPages. */
typedef HV_GPA_MAPPING *PHV_GPA_MAPPING;

/** Input for HvCallMapSparseGpaPages. */
typedef struct
{
    HV_PARTITION_ID     TargetPartitionId;
    HV_MAP_GPA_FLAGS    MapFlags;
    uint32_t            u32ExplicitPadding;
    /* The repeating part: */
    RT_FLEXIBLE_ARRAY_EXTENSION
    HV_GPA_MAPPING      PageList[RT_FLEXIBLE_ARRAY];
} HV_INPUT_MAP_SPARSE_GPA_PAGES;
AssertCompileMemberOffset(HV_INPUT_MAP_SPARSE_GPA_PAGES, PageList, 16);
/** Pointer to the input for HvCallMapSparseGpaPages. */
typedef HV_INPUT_MAP_SPARSE_GPA_PAGES *PHV_INPUT_MAP_SPARSE_GPA_PAGES;


/** Input for HvCallUnmapGpaPages. */
typedef struct
{
    HV_PARTITION_ID     TargetPartitionId;
    HV_GPA_PAGE_NUMBER  TargetGpaBase;
    /** This field is either an omission in the 7600 WDK or a later additions.
     *  Anyway, not quite sure what it does.  Bit 2 seems to indicate 2MB pages. */
    uint64_t            fFlags;
} HV_INPUT_UNMAP_GPA_PAGES;
AssertCompileSize(HV_INPUT_UNMAP_GPA_PAGES, 24);
/** Pointer to the input for HvCallUnmapGpaPages. */
typedef HV_INPUT_UNMAP_GPA_PAGES *PHV_INPUT_UNMAP_GPA_PAGES;



/** Cache types used by HvCallReadGpa and HvCallWriteGpa. */
typedef enum
{
    HvCacheTypeX64Uncached = 0,
    HvCacheTypeX64WriteCombining,
    /* 2 & 3 are undefined. */
    HvCacheTypeX64WriteThrough = 4,
    HvCacheTypeX64WriteProtected,
    HvCacheTypeX64WriteBack
} HV_CACHE_TYPE;

/** Control flags for HvCallReadGpa and HvCallWriteGpa. */
typedef union
{
    uint64_t            AsUINT64;
    struct
    {
        uint64_t        CacheType : 8;      /**< HV_CACHE_TYPE */
#ifndef IN_IDA_PRO
        uint64_t        Reserved  : 56;
#endif
    };
} HV_ACCESS_GPA_CONTROL_FLAGS;

/** Results codes for HvCallReadGpa and HvCallWriteGpa. */
typedef enum
{
    HvAccessGpaSuccess = 0,
    HvAccessGpaUnmapped,
    HvAccessGpaReadIntercept,
    HvAccessGpaWriteIntercept,
    HvAccessGpaIllegalOverlayAccess
} HV_ACCESS_GPA_RESULT_CODE;

/** The result of HvCallReadGpa and HvCallWriteGpa. */
typedef union
{
    uint64_t                        AsUINT64;
    struct
    {
        HV_ACCESS_GPA_RESULT_CODE   ResultCode;
        uint32_t                    Reserved;
    };
} HV_ACCESS_GPA_RESULT;


/** Input for HvCallReadGpa. */
typedef struct
{
    HV_PARTITION_ID             PartitionId;
    HV_VP_INDEX                 VpIndex;
    uint32_t                    ByteCount;
    HV_GPA                      BaseGpa;
    HV_ACCESS_GPA_CONTROL_FLAGS ControlFlags;
} HV_INPUT_READ_GPA;
AssertCompileSize(HV_INPUT_READ_GPA, 32);
/** Pointer to the input for HvCallReadGpa. */
typedef HV_INPUT_READ_GPA *PHV_INPUT_READ_GPA;

/** Output for HvCallReadGpa. */
typedef struct
{
    HV_ACCESS_GPA_RESULT        AccessResult;
    uint8_t                     Data[16];
} HV_OUTPUT_READ_GPA;
AssertCompileSize(HV_OUTPUT_READ_GPA, 24);
/** Pointer to the output for HvCallReadGpa. */
typedef HV_OUTPUT_READ_GPA *PHV_OUTPUT_READ_GPA;


/** Input for HvCallWriteGpa. */
typedef struct
{
    HV_PARTITION_ID             PartitionId;
    HV_VP_INDEX                 VpIndex;
    uint32_t                    ByteCount;
    HV_GPA                      BaseGpa;
    HV_ACCESS_GPA_CONTROL_FLAGS ControlFlags;
    uint8_t                     Data[16];
} HV_INPUT_WRITE_GPA;
AssertCompileSize(HV_INPUT_READ_GPA, 32);
/** Pointer to the input for HvCallWriteGpa. */
typedef HV_INPUT_READ_GPA *PHV_INPUT_READ_GPA;

/** Output for HvCallWriteGpa. */
typedef struct
{
    HV_ACCESS_GPA_RESULT        AccessResult;
} HV_OUTPUT_WRITE_GPA;
AssertCompileSize(HV_OUTPUT_WRITE_GPA, 8);
/** Pointer to the output for HvCallWriteGpa. */
typedef HV_OUTPUT_WRITE_GPA *PHV_OUTPUT_WRITE_GPA;


/**
 * Register names used by HvCallGetVpRegisters and HvCallSetVpRegisters.
 */
typedef enum _HV_REGISTER_NAME
{
    HvRegisterExplicitSuspend = 0x00000000,
    HvRegisterInterceptSuspend,
    HvRegisterUnknown02,                                /**< Reads as 0 initially on exo part. */
    HvRegisterUnknown03,                                /**< Reads as 0 initially on exo part. */
    HvRegisterInternalActivityState,                    /**< @since about build 17758 */

    HvRegisterHypervisorVersion = 0x00000100,           /**< @since v5 @note Not readable on exo part. */

    HvRegisterPrivilegesAndFeaturesInfo = 0x00000200,   /**< @since v5 @note Not readable on exo part. */
    HvRegisterFeaturesInfo,                             /**< @since v5 @note Not readable on exo part. */
    HvRegisterImplementationLimitsInfo,                 /**< @since v5 @note Not readable on exo part. */
    HvRegisterHardwareFeaturesInfo,                     /**< @since v5 @note Not readable on exo part. */

    HvRegisterGuestCrashP0 = 0x00000210,                /**< @since v5 @note Not readable on exo part. */
    HvRegisterGuestCrashP1,                             /**< @since v5 @note Not readable on exo part. */
    HvRegisterGuestCrashP2,                             /**< @since v5 @note Not readable on exo part. */
    HvRegisterGuestCrashP3,                             /**< @since v5 @note Not readable on exo part. */
    HvRegisterGuestCrashP4,                             /**< @since v5 @note Not readable on exo part. */
    HvRegisterGuestCrashCtl,                            /**< @since v5 @note Not readable on exo part. */

    HvRegisterPowerStateConfigC1 = 0x00000220,          /**< @since v5 @note Not readable on exo part. */
    HvRegisterPowerStateTriggerC1,                      /**< @since v5 @note Not readable on exo part. */
    HvRegisterPowerStateConfigC2,                       /**< @since v5 @note Not readable on exo part. */
    HvRegisterPowerStateTriggerC2,                      /**< @since v5 @note Not readable on exo part. */
    HvRegisterPowerStateConfigC3,                       /**< @since v5 @note Not readable on exo part. */
    HvRegisterPowerStateTriggerC3,                      /**< @since v5 @note Not readable on exo part. */

    HvRegisterSystemReset = 0x00000230,                 /**< @since v5 @note Not readable on exo part. */

    HvRegisterProcessorClockFrequency = 0x00000240,     /**< @since v5 @note Not readable on exo part. */
    HvRegisterInterruptClockFrequency,                  /**< @since v5 @note Not readable on exo part. */

    HvRegisterGuestIdle = 0x00000250,                   /**< @since v5 @note Not readable on exo part. */

    HvRegisterDebugDeviceOptions = 0x00000260,          /**< @since v5 @note Not readable on exo part. */

    HvRegisterPendingInterruption = 0x00010002,
    HvRegisterInterruptState,
    HvRegisterPendingEvent0,                            /**< @since v5 */
    HvRegisterPendingEvent1,                            /**< @since v5 */
    HvX64RegisterDeliverabilityNotifications,           /**< @since v5c? Late 2017? */

    HvX64RegisterRax = 0x00020000,
    HvX64RegisterRcx,
    HvX64RegisterRdx,
    HvX64RegisterRbx,
    HvX64RegisterRsp,
    HvX64RegisterRbp,
    HvX64RegisterRsi,
    HvX64RegisterRdi,
    HvX64RegisterR8,
    HvX64RegisterR9,
    HvX64RegisterR10,
    HvX64RegisterR11,
    HvX64RegisterR12,
    HvX64RegisterR13,
    HvX64RegisterR14,
    HvX64RegisterR15,
    HvX64RegisterRip,
    HvX64RegisterRflags,

    HvX64RegisterXmm0 = 0x00030000,
    HvX64RegisterXmm1,
    HvX64RegisterXmm2,
    HvX64RegisterXmm3,
    HvX64RegisterXmm4,
    HvX64RegisterXmm5,
    HvX64RegisterXmm6,
    HvX64RegisterXmm7,
    HvX64RegisterXmm8,
    HvX64RegisterXmm9,
    HvX64RegisterXmm10,
    HvX64RegisterXmm11,
    HvX64RegisterXmm12,
    HvX64RegisterXmm13,
    HvX64RegisterXmm14,
    HvX64RegisterXmm15,
    HvX64RegisterFpMmx0,
    HvX64RegisterFpMmx1,
    HvX64RegisterFpMmx2,
    HvX64RegisterFpMmx3,
    HvX64RegisterFpMmx4,
    HvX64RegisterFpMmx5,
    HvX64RegisterFpMmx6,
    HvX64RegisterFpMmx7,
    HvX64RegisterFpControlStatus,
    HvX64RegisterXmmControlStatus,

    HvX64RegisterCr0 = 0x00040000,
    HvX64RegisterCr2,
    HvX64RegisterCr3,
    HvX64RegisterCr4,
    HvX64RegisterCr8,
    HvX64RegisterXfem,

    HvX64RegisterIntermediateCr0 = 0x00041000,          /**< @since v5 */
    HvX64RegisterIntermediateCr4 = 0x00041003,          /**< @since v5 */
    HvX64RegisterIntermediateCr8,                       /**< @since v5 */

    HvX64RegisterDr0 = 0x00050000,
    HvX64RegisterDr1,
    HvX64RegisterDr2,
    HvX64RegisterDr3,
    HvX64RegisterDr6,
    HvX64RegisterDr7,

    HvX64RegisterEs = 0x00060000,
    HvX64RegisterCs,
    HvX64RegisterSs,
    HvX64RegisterDs,
    HvX64RegisterFs,
    HvX64RegisterGs,
    HvX64RegisterLdtr,
    HvX64RegisterTr,

    HvX64RegisterIdtr = 0x00070000,
    HvX64RegisterGdtr,

    HvX64RegisterTsc = 0x00080000,
    HvX64RegisterEfer,
    HvX64RegisterKernelGsBase,
    HvX64RegisterApicBase,
    HvX64RegisterPat,
    HvX64RegisterSysenterCs,
    HvX64RegisterSysenterEip,
    HvX64RegisterSysenterEsp,
    HvX64RegisterStar,
    HvX64RegisterLstar,
    HvX64RegisterCstar,
    HvX64RegisterSfmask,
    HvX64RegisterInitialApicId,

    HvX64RegisterMtrrCap,                           /**< Not readable in exo partitions? */
    HvX64RegisterMtrrDefType,

    HvX64RegisterMtrrPhysBase0 = 0x00080010,
    HvX64RegisterMtrrPhysBase1,
    HvX64RegisterMtrrPhysBase2,
    HvX64RegisterMtrrPhysBase3,
    HvX64RegisterMtrrPhysBase4,
    HvX64RegisterMtrrPhysBase5,
    HvX64RegisterMtrrPhysBase6,
    HvX64RegisterMtrrPhysBase7,
    HvX64RegisterMtrrPhysBase8,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterMtrrPhysBase9,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterMtrrPhysBaseA,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterMtrrPhysBaseB,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterMtrrPhysBaseC,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterMtrrPhysBaseD,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterMtrrPhysBaseE,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterMtrrPhysBaseF,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */

    HvX64RegisterMtrrPhysMask0 = 0x00080040,
    HvX64RegisterMtrrPhysMask1,
    HvX64RegisterMtrrPhysMask2,
    HvX64RegisterMtrrPhysMask3,
    HvX64RegisterMtrrPhysMask4,
    HvX64RegisterMtrrPhysMask5,
    HvX64RegisterMtrrPhysMask6,
    HvX64RegisterMtrrPhysMask7,
    HvX64RegisterMtrrPhysMask8,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterMtrrPhysMask9,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterMtrrPhysMaskA,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterMtrrPhysMaskB,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterMtrrPhysMaskC,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterMtrrPhysMaskD,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterMtrrPhysMaskE,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterMtrrPhysMaskF,                     /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */

    HvX64RegisterMtrrFix64k00000 = 0x00080070,
    HvX64RegisterMtrrFix16k80000,
    HvX64RegisterMtrrFix16kA0000,
    HvX64RegisterMtrrFix4kC0000,
    HvX64RegisterMtrrFix4kC8000,
    HvX64RegisterMtrrFix4kD0000,
    HvX64RegisterMtrrFix4kD8000,
    HvX64RegisterMtrrFix4kE0000,
    HvX64RegisterMtrrFix4kE8000,
    HvX64RegisterMtrrFix4kF0000,
    HvX64RegisterMtrrFix4kF8000,
    HvX64RegisterTscAux,                            /**< @since v5c? late 2017? */

    HvX64RegisterUnknown8007d = 0x0008007d,         /**< Readable on exo partition (17134), initial value is zero. */

    HvX64RegisterSpecCtrl = 0x00080084,             /**< @since build about 17758 */
    HvX64RegisterPredCmd,                           /**< @since build about 17758 */

    HvX64RegisterIa32MiscEnable = 0x000800a0,       /**< @since v5 @note Appears not to be readable on exo partition (Threadripper). */
    HvX64RegisterIa32FeatureControl,                /**< @since v5 @note Appears not to be readable on exo partition (Threadripper). */

    HvX64RegisterApicId = 0x00084802,               /**< @since build 17758 */
    HvX64RegisterApicVersion,                       /**< @since build 17758 */

    /** Uptime counter or some such thing.  Unit is different than HvRegisterTimeRefCount or the accounting is different. */
    HvX64RegisterVpRuntime = 0x00090000,
    HvX64RegisterHypercall,
    HvRegisterGuestOsId,
    HvRegisterVpIndex,
    HvRegisterTimeRefCount,                         /**< Time counter since partition creation, 100ns units. */

    HvRegisterCpuManagementVersion = 0x00090007,    /**< @since v5 @note Appears not to be readable on exo partition. */

    HvX64RegisterEoi = 0x00090010,                  /**< @note Appears not to be readable on exo partition. */
    HvX64RegisterIcr,                               /**< @note Appears not to be readable on exo partition. */
    HvX64RegisterTpr,                               /**< @note Appears not to be readable on exo partition. */
    HvRegisterVpAssistPage,
    /** Readable on exo partition (17134). Some kind of counter. */
    HvRegisterUnknown90014,

    HvRegisterStatsPartitionRetail = 0x00090020,
    HvRegisterStatsPartitionInternal,
    HvRegisterStatsVpRetail,
    HvRegisterStatsVpInternal,

    HvRegisterSint0 = 0x000a0000,
    HvRegisterSint1,
    HvRegisterSint2,
    HvRegisterSint3,
    HvRegisterSint4,
    HvRegisterSint5,
    HvRegisterSint6,
    HvRegisterSint7,
    HvRegisterSint8,
    HvRegisterSint9,
    HvRegisterSint10,
    HvRegisterSint11,
    HvRegisterSint12,
    HvRegisterSint13,
    HvRegisterSint14,
    HvRegisterSint15,
    HvRegisterScontrol,
    HvRegisterSversion,
    HvRegisterSifp,
    HvRegisterSipp,
    HvRegisterEom,
    HvRegisterSirbp,                                /**< @since v4 */

    HvRegisterStimer0Config = 0x000b0000,
    HvRegisterStimer0Count,
    HvRegisterStimer1Config,
    HvRegisterStimer1Count,
    HvRegisterStimer2Config,
    HvRegisterStimer2Count,
    HvRegisterStimer3Config,
    HvRegisterStimer3Count,

    HvRegisterUnknown0b0100 = 0x000b0100,           /**< Readable on exo partition (17134), initial value is zero. */
    HvRegisterUnknown0b0101,                        /**< Readable on exo partition (17134), initial value is zero. */

    HvX64RegisterYmm0Low = 0x000c0000,              /**< @note Not readable on exo partition.  Need something enabled? */
    HvX64RegisterYmm1Low,
    HvX64RegisterYmm2Low,
    HvX64RegisterYmm3Low,
    HvX64RegisterYmm4Low,
    HvX64RegisterYmm5Low,
    HvX64RegisterYmm6Low,
    HvX64RegisterYmm7Low,
    HvX64RegisterYmm8Low,
    HvX64RegisterYmm9Low,
    HvX64RegisterYmm10Low,
    HvX64RegisterYmm11Low,
    HvX64RegisterYmm12Low,
    HvX64RegisterYmm13Low,
    HvX64RegisterYmm14Low,
    HvX64RegisterYmm15Low,
    HvX64RegisterYmm0High,
    HvX64RegisterYmm1High,
    HvX64RegisterYmm2High,
    HvX64RegisterYmm3High,
    HvX64RegisterYmm4High,
    HvX64RegisterYmm5High,
    HvX64RegisterYmm6High,
    HvX64RegisterYmm7High,
    HvX64RegisterYmm8High,
    HvX64RegisterYmm9High,
    HvX64RegisterYmm10High,
    HvX64RegisterYmm11High,
    HvX64RegisterYmm12High,
    HvX64RegisterYmm13High,
    HvX64RegisterYmm14High,
    HvX64RegisterYmm15High,

    HvRegisterVsmVpVtlControl = 0x000d0000,         /**< @note Not readable on exo partition. */

    HvRegisterVsmCodePageOffsets = 0x000d0002,
    HvRegisterVsmVpStatus,
    HvRegisterVsmPartitionStatus,
    HvRegisterVsmVina,                              /**< @note Not readable on exo partition. */
    HvRegisterVsmCapabilities,
    HvRegisterVsmPartitionConfig,                   /**< @note Not readable on exo partition. */

    HvRegisterVsmVpSecureConfigVtl0 = 0x000d0010,   /**< @since v5 */
    HvRegisterVsmVpSecureConfigVtl1,                /**< @since v5 */
    HvRegisterVsmVpSecureConfigVtl2,                /**< @since v5 */
    HvRegisterVsmVpSecureConfigVtl3,                /**< @since v5 */
    HvRegisterVsmVpSecureConfigVtl4,                /**< @since v5 */
    HvRegisterVsmVpSecureConfigVtl5,                /**< @since v5 */
    HvRegisterVsmVpSecureConfigVtl6,                /**< @since v5 */
    HvRegisterVsmVpSecureConfigVtl7,                /**< @since v5 */
    HvRegisterVsmVpSecureConfigVtl8,                /**< @since v5 */
    HvRegisterVsmVpSecureConfigVtl9,                /**< @since v5 */
    HvRegisterVsmVpSecureConfigVtl10,               /**< @since v5 */
    HvRegisterVsmVpSecureConfigVtl11,               /**< @since v5 */
    HvRegisterVsmVpSecureConfigVtl12,               /**< @since v5 */
    HvRegisterVsmVpSecureConfigVtl13,               /**< @since v5 */
    HvRegisterVsmVpSecureConfigVtl14,               /**< @since v5 */

    HvRegisterUnknown0e0000 = 0x000e0000,           /**< Readable on exo partition (17134), initial value zero. */
    HvRegisterUnknown0e0001,                        /**< Readable on exo partition (17134), initial value zero. */
    HvRegisterUnknown0e0002,                        /**< Readable on exo partition (17134), initial value zero. */
    HvRegisterUnknown0e0003                         /**< Readable on exo partition (17134), initial value zero. */
} HV_REGISTER_NAME;
AssertCompile(HvRegisterInterceptSuspend == 0x00000001);
AssertCompile(HvRegisterPendingEvent1 == 0x00010005);
AssertCompile(HvX64RegisterDeliverabilityNotifications == 0x00010006);
AssertCompile(HvX64RegisterRflags == 0x00020011);
AssertCompile(HvX64RegisterXmmControlStatus == 0x00030019);
AssertCompile(HvX64RegisterXfem == 0x00040005);
AssertCompile(HvX64RegisterIntermediateCr0 == 0x00041000);
AssertCompile(HvX64RegisterIntermediateCr4 == 0x00041003);
AssertCompile(HvX64RegisterDr7 == 0x00050005);
AssertCompile(HvX64RegisterTr == 0x00060007);
AssertCompile(HvX64RegisterGdtr == 0x00070001);
AssertCompile(HvX64RegisterInitialApicId == 0x0008000c);
AssertCompile(HvX64RegisterMtrrCap == 0x0008000d);
AssertCompile(HvX64RegisterMtrrDefType == 0x0008000e);
AssertCompile(HvX64RegisterMtrrPhysBaseF == 0x0008001f);
AssertCompile(HvX64RegisterMtrrPhysMaskF == 0x0008004f);
AssertCompile(HvX64RegisterMtrrFix4kF8000 == 0x0008007a);
AssertCompile(HvRegisterTimeRefCount == 0x00090004);
AssertCompile(HvRegisterCpuManagementVersion == 0x00090007);
AssertCompile(HvRegisterVpAssistPage == 0x00090013);
AssertCompile(HvRegisterStatsVpInternal == 0x00090023);
AssertCompile(HvRegisterSirbp == 0x000a0015);
AssertCompile(HvRegisterStimer3Count == 0x000b0007);
AssertCompile(HvX64RegisterYmm15High == 0x000c001f);
AssertCompile(HvRegisterVsmVpSecureConfigVtl14 == 0x000d001e);
AssertCompileSize(HV_REGISTER_NAME, 4);


/** Value format for HvRegisterExplicitSuspend. */
typedef union
{
    uint64_t            AsUINT64;
    struct
    {
        uint64_t        Suspended : 1;
#ifndef IN_IDA_PRO
        uint64_t        Reserved  : 63;
#endif
    };
} HV_EXPLICIT_SUSPEND_REGISTER;
/** Pointer to a value of HvRegisterExplicitSuspend. */
typedef HV_EXPLICIT_SUSPEND_REGISTER *PHV_EXPLICIT_SUSPEND_REGISTER;

/** Value format for HvRegisterInterceptSuspend. */
typedef union
{
    uint64_t            AsUINT64;
    struct
    {
        uint64_t        Suspended : 1;
        uint64_t        TlbLocked : 1;
#ifndef IN_IDA_PRO
        uint64_t        Reserved  : 62;
#endif
    };
} HV_INTERCEPT_SUSPEND_REGISTER;
/** Pointer to a value of HvRegisterInterceptSuspend. */
typedef HV_INTERCEPT_SUSPEND_REGISTER *PHV_INTERCEPT_SUSPEND_REGISTER;

/** Value format for HvRegisterInterruptState.
 * @sa WHV_X64_INTERRUPT_STATE_REGISTER */
typedef union
{
    uint64_t            AsUINT64;
    struct
    {
        uint64_t        InterruptShadow : 1;
        uint64_t        NmiMasked       : 1;
#ifndef IN_IDA_PRO
        uint64_t        Reserved        : 62;
#endif
    };
} HV_X64_INTERRUPT_STATE_REGISTER;
/** Pointer to a value of HvRegisterInterruptState. */
typedef HV_X64_INTERRUPT_STATE_REGISTER *PHV_X64_INTERRUPT_STATE_REGISTER;

/** Pending exception type for HvRegisterPendingInterruption.
 * @sa WHV_X64_PENDING_INTERRUPTION_TYPE */
typedef enum
{
    HvX64PendingInterrupt = 0,
    /* what is/was 1? */
    HvX64PendingNmi = 2,
    HvX64PendingException
    /* any more? */
} HV_X64_PENDING_INTERRUPTION_TYPE;

/** Value format for HvRegisterPendingInterruption.
 * @sa WHV_X64_PENDING_INTERRUPTION_REGISTER  */
typedef union
{
    uint64_t            AsUINT64;
    struct
    {
        uint32_t        InterruptionPending : 1;
        uint32_t        InterruptionType    : 3;    /**< HV_X64_PENDING_INTERRUPTION_TYPE */
        uint32_t        DeliverErrorCode    : 1;
        uint32_t        InstructionLength   : 4;    /**< @since v5? Wasn't in 7600 WDK */
        uint32_t        NestedEvent         : 1;    /**< @since v5? Wasn't in 7600 WDK */
        uint32_t        Reserved            : 6;
        uint32_t        InterruptionVector  : 16;
        uint32_t        ErrorCode;
    };
} HV_X64_PENDING_INTERRUPTION_REGISTER;
/** Pointer to a value of HvRegisterPendingInterruption. */
typedef HV_X64_PENDING_INTERRUPTION_REGISTER *PHV_X64_PENDING_INTERRUPTION_REGISTER;

/** Value format for HvX64RegisterDeliverabilityNotifications.
 *  Value format for HvRegisterPendingEvent0/1.
 * @sa WHV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER  */
typedef union
{
    uint64_t            AsUINT64;
    struct
    {
        uint64_t        NmiNotification         : 1;
        uint64_t        InterruptNotification   : 1;
        uint64_t        InterruptPriority       : 4;
#ifndef IN_IDA_PRO
        uint64_t        Reserved                : 58;
#endif
    };
} HV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER;
/** Pointer to a value of HvRegisterPendingEvent0/1. */
typedef HV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER *PHV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER;


/** Value format for HvX64RegisterEs..Tr.
 * @sa WHV_X64_SEGMENT_REGISTER  */
typedef struct _HV_X64_SEGMENT_REGISTER
{
    uint64_t            Base;
    uint32_t            Limit;
    uint16_t            Selector;
    union
    {
        struct
        {
            uint16_t    SegmentType              : 4;
            uint16_t    NonSystemSegment         : 1;
            uint16_t    DescriptorPrivilegeLevel : 2;
            uint16_t    Present                  : 1;
            uint16_t    Reserved                 : 4;
            uint16_t    Available                : 1;
            uint16_t    Long                     : 1;
            uint16_t    Default                  : 1;
            uint16_t    Granularity              : 1;
        };
        uint16_t        Attributes;
    };
} HV_X64_SEGMENT_REGISTER;
AssertCompileSize(HV_X64_SEGMENT_REGISTER, 16);
/** Pointer to a value of HvX64RegisterEs..Tr. */
typedef HV_X64_SEGMENT_REGISTER *PHV_X64_SEGMENT_REGISTER;

/** Value format for HvX64RegisterIdtr/Gdtr.
 * @sa WHV_X64_TABLE_REGISTER */
typedef struct
{
    uint16_t            Pad[3];
    uint16_t            Limit;
    uint64_t            Base;
} HV_X64_TABLE_REGISTER;
AssertCompileSize(HV_X64_TABLE_REGISTER, 16);
/** Pointer to a value of HvX64RegisterIdtr/Gdtrr. */
typedef HV_X64_TABLE_REGISTER *PHV_X64_TABLE_REGISTER;

/** Value format for HvX64RegisterFpMmx0..7 in floating pointer mode.
 * @sa WHV_X64_FP_REGISTER, RTFLOAT80U2 */
typedef union
{
    HV_UINT128          AsUINT128;
    struct
    {
        uint64_t        Mantissa;
        uint64_t        BiasedExponent  : 15;
        uint64_t        Sign            : 1;
#ifndef IN_IDA_PRO
        uint64_t        Reserved        : 48;
#endif
    };
} HV_X64_FP_REGISTER;
/** Pointer to a value of HvX64RegisterFpMmx0..7 in floating point mode. */
typedef HV_X64_FP_REGISTER *PHV_X64_FP_REGISTER;

/** Value union for HvX64RegisterFpMmx0..7. */
typedef union
{
    HV_UINT128          AsUINT128;
    HV_X64_FP_REGISTER  Fp;
    uint64_t            Mmx;
} HV_X64_FP_MMX_REGISTER;
/** Pointer to a value of HvX64RegisterFpMmx0..7. */
typedef HV_X64_FP_MMX_REGISTER *PHV_X64_FP_MMX_REGISTER;

/** Value format for HvX64RegisterFpControlStatus.
 * @sa WHV_X64_FP_CONTROL_STATUS_REGISTER  */
typedef union
{
    HV_UINT128              AsUINT128;
    struct
    {
        uint16_t            FpControl;
        uint16_t            FpStatus;
        uint8_t             FpTag;
        uint8_t             IgnNe    : 1;
        uint8_t             Reserved : 7;
        uint16_t            LastFpOp;
        union
        {
            uint64_t        LastFpRip;
            struct
            {
                uint32_t    LastFpEip;
                uint16_t    LastFpCs;
            };
        };
    };
} HV_X64_FP_CONTROL_STATUS_REGISTER;
/** Pointer to a value of HvX64RegisterFpControlStatus. */
typedef HV_X64_FP_CONTROL_STATUS_REGISTER *PHV_X64_FP_CONTROL_STATUS_REGISTER;

/** Value format for HvX64RegisterXmmControlStatus.
 * @sa WHV_X64_XMM_CONTROL_STATUS_REGISTER  */
typedef union
{
    HV_UINT128 AsUINT128;
    struct
    {
        union
        {
            uint64_t        LastFpRdp;
            struct
            {
                uint32_t    LastFpDp;
                uint16_t    LastFpDs;
            };
        };
        uint32_t            XmmStatusControl;
        uint32_t            XmmStatusControlMask;
    };
} HV_X64_XMM_CONTROL_STATUS_REGISTER;
/** Pointer to a value of HvX64RegisterXmmControlStatus. */
typedef HV_X64_XMM_CONTROL_STATUS_REGISTER *PHV_X64_XMM_CONTROL_STATUS_REGISTER;

/** Register value union.
 * @sa WHV_REGISTER_VALUE  */
typedef union
{
    HV_UINT128                                      Reg128;
    uint64_t                                        Reg64;
    uint32_t                                        Reg32;
    uint16_t                                        Reg16;
    uint8_t                                         Reg8;
    HV_EXPLICIT_SUSPEND_REGISTER                    ExplicitSuspend;
    HV_INTERCEPT_SUSPEND_REGISTER                   InterceptSuspend;
    HV_X64_INTERRUPT_STATE_REGISTER                 InterruptState;
    HV_X64_PENDING_INTERRUPTION_REGISTER            PendingInterruption;
    HV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER    DeliverabilityNotifications;
    HV_X64_TABLE_REGISTER                           Table;
    HV_X64_SEGMENT_REGISTER                         Segment;
    HV_X64_FP_REGISTER                              Fp;
    HV_X64_FP_CONTROL_STATUS_REGISTER               FpControlStatus;
    HV_X64_XMM_CONTROL_STATUS_REGISTER              XmmControlStatus;
} HV_REGISTER_VALUE;
AssertCompileSize(HV_REGISTER_VALUE, 16);
/** Pointer to a Hyper-V register value union. */
typedef HV_REGISTER_VALUE *PHV_REGISTER_VALUE;
/** Pointer to a const Hyper-V register value union. */
typedef HV_REGISTER_VALUE const *PCHV_REGISTER_VALUE;


/** Input for HvCallGetVpRegisters. */
typedef struct
{
    HV_PARTITION_ID     PartitionId;
    HV_VP_INDEX         VpIndex;
    /** Was this introduced after v2? Dunno what it it really is. */
    uint32_t            fFlags;
    /* The repeating part: */
    RT_FLEXIBLE_ARRAY_EXTENSION
    HV_REGISTER_NAME    Names[RT_FLEXIBLE_ARRAY];
} HV_INPUT_GET_VP_REGISTERS;
AssertCompileMemberOffset(HV_INPUT_GET_VP_REGISTERS, Names, 16);
/** Pointer to input for HvCallGetVpRegisters. */
typedef HV_INPUT_GET_VP_REGISTERS *PHV_INPUT_GET_VP_REGISTERS;
/* Output for HvCallGetVpRegisters is an array of HV_REGISTER_VALUE parallel to HV_INPUT_GET_VP_REGISTERS::Names. */


/** Register and value pair for HvCallSetVpRegisters. */
typedef struct
{
    HV_REGISTER_NAME    Name;
    uint32_t            Pad0;
    uint64_t            Pad1;
    HV_REGISTER_VALUE   Value;
} HV_REGISTER_ASSOC;
AssertCompileSize(HV_REGISTER_ASSOC, 32);
AssertCompileMemberOffset(HV_REGISTER_ASSOC, Value, 16);
/** Pointer to a register and value pair for HvCallSetVpRegisters. */
typedef HV_REGISTER_ASSOC *PHV_REGISTER_ASSOC;
/** Helper for clearing the alignment padding members. */
#define HV_REGISTER_ASSOC_ZERO_PADDING(a_pRegAssoc) do { (a_pRegAssoc)->Pad0 = 0; (a_pRegAssoc)->Pad1 = 0; } while (0)
/** Helper for clearing the alignment padding members and the high 64-bit
 * part of the value. */
#define HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(a_pRegAssoc) \
    do { (a_pRegAssoc)->Pad0 = 0; (a_pRegAssoc)->Pad1 = 0; (a_pRegAssoc)->Value.Reg128.High64 = 0; } while (0)

/** Input for HvCallSetVpRegisters. */
typedef struct
{
    HV_PARTITION_ID     PartitionId;
    HV_VP_INDEX         VpIndex;
    uint32_t            RsvdZ;
    /* The repeating part: */
    RT_FLEXIBLE_ARRAY_EXTENSION
    HV_REGISTER_ASSOC   Elements[RT_FLEXIBLE_ARRAY];
} HV_INPUT_SET_VP_REGISTERS;
AssertCompileMemberOffset(HV_INPUT_SET_VP_REGISTERS, Elements, 16);
/** Pointer to input for HvCallSetVpRegisters. */
typedef HV_INPUT_SET_VP_REGISTERS *PHV_INPUT_SET_VP_REGISTERS;



/**
 * Hyper-V SyncIC message types.
 */
typedef enum
{
    HvMessageTypeNone = 0x00000000,

    HvMessageTypeUnmappedGpa = 0x80000000,
    HvMessageTypeGpaIntercept,

    HvMessageTimerExpired = 0x80000010,

    HvMessageTypeInvalidVpRegisterValue = 0x80000020,
    HvMessageTypeUnrecoverableException,
    HvMessageTypeUnsupportedFeature,
    HvMessageTypeTlbPageSizeMismatch,                   /**< @since v5 */

    /** @note Same as HvMessageTypeX64ApicEoi? Gone in 5.0.  Missing from 7600 WDK
     *        headers even if it's in the 2.0 docs.  */
    HvMessageTypeApicEoi = 0x80000030,
    /** @note Same as HvMessageTypeX64LegacyFpError? Gone in 5.0, whereas 4.0b
     *        calls it HvMessageTypeX64LegacyFpError.  Missing from 7600 WDK
     *        headers even if it's in the 2.0 docs. */
    HvMessageTypeFerrAsserted,

    HvMessageTypeEventLogBufferComplete = 0x80000040,

    HvMessageTypeX64IoPortIntercept = 0x80010000,
    HvMessageTypeX64MsrIntercept,
    HvMessageTypeX64CpuidIntercept,
    HvMessageTypeX64ExceptionIntercept,
    /** @note Appeared in 5.0 docs, but were here in 7600 WDK headers already. */
    HvMessageTypeX64ApicEoi,
    /** @note Appeared in 5.0 docs, but were here in 7600 WDK headers already. */
    HvMessageTypeX64LegacyFpError,
    /** @since v5   */
    HvMessageTypeX64RegisterIntercept,
    /** @since WinHvPlatform? */
    HvMessageTypeX64Halt,
    /** @since WinHvPlatform? */
    HvMessageTypeX64InterruptWindow

} HV_MESSAGE_TYPE;
AssertCompileSize(HV_MESSAGE_TYPE, 4);
AssertCompile(HvMessageTypeX64RegisterIntercept == 0x80010006);
AssertCompile(HvMessageTypeX64Halt == 0x80010007);
AssertCompile(HvMessageTypeX64InterruptWindow == 0x80010008);
/** Pointer to a Hyper-V SyncIC message type. */
typedef HV_MESSAGE_TYPE *PHV_MESSAGE_TYPE;

/** Flag set for hypervisor messages, guest cannot send messages with this
 *  flag set. */
#define HV_MESSAGE_TYPE_HYPERVISOR_MASK     UINT32_C(0x80000000)

/** Hyper-V SynIC message size (they are fixed sized). */
#define HV_MESSAGE_SIZE                     256
/** Maximum Hyper-V SynIC message payload size in bytes. */
#define HV_MESSAGE_MAX_PAYLOAD_BYTE_COUNT   (HV_MESSAGE_SIZE - 16)
/** Maximum Hyper-V SynIC message payload size in QWORDs (uint64_t). */
#define HV_MESSAGE_MAX_PAYLOAD_QWORD_COUNT  (HV_MESSAGE_MAX_PAYLOAD_BYTE_COUNT / 8)

/** SynIC message flags.   */
typedef union
{
    uint8_t             AsUINT8;
    struct
    {
        /** Messages are pending in the queue. */
        uint8_t         MessagePending : 1;
        uint8_t         Reserved : 7;
    };
} HV_MESSAGE_FLAGS;
AssertCompileSize(HV_MESSAGE_FLAGS, 1);

/** SynIC message header. */
typedef struct
{
    HV_MESSAGE_TYPE     MessageType;
    /** The 2.0-5.0b docs all have this incorrectly switched with 'Reserved', WDK 7600 got it right. */
    uint8_t             PayloadSize;
    HV_MESSAGE_FLAGS    MessageFlags;
    uint16_t            Reserved;
    union
    {
        uint64_t        OriginationId;
        HV_PARTITION_ID Sender;
        HV_PORT_ID      Port;
    };
} HV_MESSAGE_HEADER;
AssertCompileSize(HV_MESSAGE_HEADER, 16);
/** Pointer to a Hyper-V message header. */
typedef HV_MESSAGE_HEADER *PHV_MESSAGE_HEADER;
/** Pointer to a const Hyper-V message header. */
typedef HV_MESSAGE_HEADER const *PCHV_MESSAGE_HEADER;



/** @name Intercept access type.
 * @{ */
typedef uint8_t HV_INTERCEPT_ACCESS_TYPE;
#define HV_INTERCEPT_ACCESS_READ            0
#define HV_INTERCEPT_ACCESS_WRITE           1
#define HV_INTERCEPT_ACCESS_EXECUTE         2
/** @} */

/** @name Intercept access type mask.
 * @{ */
typedef uint32_t HV_INTERCEPT_ACCESS_TYPE_MASK;
#define HV_INTERCEPT_ACCESS_MASK_NONE       0
#define HV_INTERCEPT_ACCESS_MASK_READ       1
#define HV_INTERCEPT_ACCESS_MASK_WRITE      2
#define HV_INTERCEPT_ACCESS_MASK_EXECUTE    4
/** @} */

/** X64 intercept execution state.
 * @sa WHV_X64_VP_EXECUTION_STATE */
typedef union
{
    uint16_t            AsUINT16;
    struct
    {
        uint16_t        Cpl                 : 2;
        uint16_t        Cr0Pe               : 1;
        uint16_t        Cr0Am               : 1;
        uint16_t        EferLma             : 1;
        uint16_t        DebugActive         : 1;
        uint16_t        InterruptionPending : 1;
        uint16_t        Reserved0           : 5;
        uint16_t        InterruptShadow     : 1;
        uint16_t        Reserved1           : 3;
    };
} HV_X64_VP_EXECUTION_STATE;
AssertCompileSize(HV_X64_VP_EXECUTION_STATE, 2);
/** Pointer to X86 intercept execution state. */
typedef HV_X64_VP_EXECUTION_STATE *PHV_X64_VP_EXECUTION_STATE;
/** Pointer to const X86 intercept execution state. */
typedef HV_X64_VP_EXECUTION_STATE const *PCHV_X64_VP_EXECUTION_STATE;

/** X64 intercept message header. */
typedef struct
{
    HV_VP_INDEX                     VpIndex;                /**< 0x00 */
    uint8_t                         InstructionLength : 4;  /**< 0x04[3:0]: Zero if not available, instruction fetch exit, ... */
    uint8_t                         Cr8 : 4;                /**< 0x04[7:4]: Not sure since when, but after v2. */
    HV_INTERCEPT_ACCESS_TYPE        InterceptAccessType;    /**< 0x05 */
    HV_X64_VP_EXECUTION_STATE       ExecutionState;         /**< 0x06 */
    HV_X64_SEGMENT_REGISTER         CsSegment;              /**< 0x08 */
    uint64_t                        Rip;                    /**< 0x18 */
    uint64_t                        Rflags;                 /**< 0x20 */
} HV_X64_INTERCEPT_MESSAGE_HEADER;
AssertCompileSize(HV_X64_INTERCEPT_MESSAGE_HEADER, 40);
/** Pointer to a x86 intercept message header. */
typedef HV_X64_INTERCEPT_MESSAGE_HEADER *PHV_X64_INTERCEPT_MESSAGE_HEADER;


/** X64 memory access flags (HvMessageTypeGpaIntercept, HvMessageTypeUnmappedGpa).
 * @sa WHV_MEMORY_ACCESS_INFO */
typedef union
{
    uint8_t             AsUINT8;
    struct
    {
        uint8_t         GvaValid : 1;
        uint8_t         Reserved : 7;
    };
} HV_X64_MEMORY_ACCESS_INFO;
AssertCompileSize(HV_X64_MEMORY_ACCESS_INFO, 1);

/** The payload format for HvMessageTypeGpaIntercept and HvMessageTypeUnmappedGpa.
 * @sa   WHV_MEMORY_ACCESS_CONTEXT
 * @note max message size. */
typedef struct
{
    HV_X64_INTERCEPT_MESSAGE_HEADER Header;                 /**< 0x00 */
    HV_CACHE_TYPE                   CacheType;              /**< 0x28 */
    uint8_t                         InstructionByteCount;   /**< 0x2c */
    HV_X64_MEMORY_ACCESS_INFO       MemoryAccessInfo;       /**< 0x2d */
    uint16_t                        Reserved1;              /**< 0x2e */
    uint64_t                        GuestVirtualAddress;    /**< 0x30 */
    uint64_t                        GuestPhysicalAddress;   /**< 0x38 */
    uint8_t                         InstructionBytes[16];   /**< 0x40 */
    /* We don't the following (v5 / WinHvPlatform): */
    HV_X64_SEGMENT_REGISTER         DsSegment;              /**< 0x50 */
    HV_X64_SEGMENT_REGISTER         SsSegment;              /**< 0x60 */
    uint64_t                        Rax;                    /**< 0x70 */
    uint64_t                        Rcx;                    /**< 0x78 */
    uint64_t                        Rdx;                    /**< 0x80 */
    uint64_t                        Rbx;                    /**< 0x88 */
    uint64_t                        Rsp;                    /**< 0x90 */
    uint64_t                        Rbp;                    /**< 0x98 */
    uint64_t                        Rsi;                    /**< 0xa0 */
    uint64_t                        Rdi;                    /**< 0xa8 */
    uint64_t                        R8;                     /**< 0xb0 */
    uint64_t                        R9;                     /**< 0xb8 */
    uint64_t                        R10;                    /**< 0xc0 */
    uint64_t                        R11;                    /**< 0xc8 */
    uint64_t                        R12;                    /**< 0xd0 */
    uint64_t                        R13;                    /**< 0xd8 */
    uint64_t                        R14;                    /**< 0xe0 */
    uint64_t                        R15;                    /**< 0xe8 */
} HV_X64_MEMORY_INTERCEPT_MESSAGE;
AssertCompileSize(HV_X64_MEMORY_INTERCEPT_MESSAGE, 0xf0);
AssertCompileMemberOffset(HV_X64_MEMORY_INTERCEPT_MESSAGE, DsSegment, 0x50);
/** Pointer to a HvMessageTypeGpaIntercept or HvMessageTypeUnmappedGpa payload. */
typedef HV_X64_MEMORY_INTERCEPT_MESSAGE *PHV_X64_MEMORY_INTERCEPT_MESSAGE;
/** Pointer to a const HvMessageTypeGpaIntercept or HvMessageTypeUnmappedGpa payload. */
typedef HV_X64_MEMORY_INTERCEPT_MESSAGE const *PCHV_X64_MEMORY_INTERCEPT_MESSAGE;


/** The payload format for HvMessageTypeX64MsrIntercept. */
typedef struct _HV_X64_MSR_INTERCEPT_MESSAGE
{
    HV_X64_INTERCEPT_MESSAGE_HEADER     Header;                 /**< 0x00 */
    uint32_t                            MsrNumber;              /**< 0x28 (ecx) */
    uint32_t                            Reserved;               /**< 0x2c */
    uint64_t                            Rdx;                    /**< 0x30 */
    uint64_t                            Rax;                    /**< 0x38 */
} HV_X64_MSR_INTERCEPT_MESSAGE;
AssertCompileSize(HV_X64_MSR_INTERCEPT_MESSAGE, 0x40);
/** Pointer to a HvMessageTypeX64MsrIntercept payload. */
typedef HV_X64_MSR_INTERCEPT_MESSAGE *PHV_X64_MSR_INTERCEPT_MESSAGE;
/** Pointer to a const HvMessageTypeX64MsrIntercept payload. */
typedef HV_X64_MSR_INTERCEPT_MESSAGE const *PCHV_X64_MSR_INTERCEPT_MESSAGE;

/** Full MSR message. */
typedef struct
{
    HV_MESSAGE_HEADER                   MsgHdr;
    HV_X64_MSR_INTERCEPT_MESSAGE        Payload;
} HV_X64_MSR_INTERCEPT_MESSAGE_FULL;


/** X64 I/O port access information (HvMessageTypeX64IoPortIntercept). */
typedef union HV_X64_IO_PORT_ACCESS_INFO
{
    uint8_t             AsUINT8;
    struct
    {
        uint8_t         AccessSize  : 3;
        uint8_t         StringOp    : 1;
        uint8_t         RepPrefix   : 1;
        uint8_t         Reserved    : 3;
    };
} HV_X64_IO_PORT_ACCESS_INFO;
AssertCompileSize(HV_X64_IO_PORT_ACCESS_INFO, 1);

/** The payload format for HvMessageTypeX64IoPortIntercept.  */
typedef struct _HV_X64_IO_PORT_INTERCEPT_MESSAGE
{
    HV_X64_INTERCEPT_MESSAGE_HEADER     Header;                 /**< 0x00 */
    uint16_t                            PortNumber;             /**< 0x28 */
    HV_X64_IO_PORT_ACCESS_INFO          AccessInfo;             /**< 0x2a */
    uint8_t                             InstructionByteCount;   /**< 0x2b */
    uint32_t                            Reserved;               /**< 0x2c */
    uint64_t                            Rax;                    /**< 0x30 */
    uint8_t                             InstructionBytes[16];   /**< 0x38 */
    HV_X64_SEGMENT_REGISTER             DsSegment;              /**< 0x48 */
    HV_X64_SEGMENT_REGISTER             EsSegment;              /**< 0x58 */
    uint64_t                            Rcx;                    /**< 0x68 */
    uint64_t                            Rsi;                    /**< 0x70 */
    uint64_t                            Rdi;                    /**< 0x78 */
} HV_X64_IO_PORT_INTERCEPT_MESSAGE;
AssertCompileSize(HV_X64_IO_PORT_INTERCEPT_MESSAGE, 128);
/** Pointer to a HvMessageTypeX64IoPortIntercept payload. */
typedef HV_X64_IO_PORT_INTERCEPT_MESSAGE *PHV_X64_IO_PORT_INTERCEPT_MESSAGE;
/** Pointer to a const HvMessageTypeX64IoPortIntercept payload. */
typedef HV_X64_IO_PORT_INTERCEPT_MESSAGE const *PCHV_X64_IO_PORT_INTERCEPT_MESSAGE;

/** Full I/O port message. */
typedef struct
{
    HV_MESSAGE_HEADER                   MsgHdr;
    HV_X64_IO_PORT_INTERCEPT_MESSAGE    Payload;
} HV_X64_IO_PORT_INTERCEPT_MESSAGE_FULL;


/**
 * The payload format for HvMessageTypeX64CpuidIntercept,
 *
 * @note This message does not include HV_X64_INTERCEPT_MESSAGE_HEADER!
 */
typedef struct
{
    HV_X64_INTERCEPT_MESSAGE_HEADER     Header;                 /**< 0x00: The usual intercept header. */
    uint64_t                            Rax;                    /**< 0x28: Input RAX. */
    uint64_t                            Rcx;                    /**< 0x30: Input RCX. */
    uint64_t                            Rdx;                    /**< 0x38: Input RDX. */
    uint64_t                            Rbx;                    /**< 0x40: Input RBX. */
    uint64_t                            DefaultResultRax;       /**< 0x48: Default result RAX. */
    uint64_t                            DefaultResultRcx;       /**< 0x50: Default result RCX. */
    uint64_t                            DefaultResultRdx;       /**< 0x58: Default result RDX. */
    uint64_t                            DefaultResultRbx;       /**< 0x60: Default result RBX. */
} HV_X64_CPUID_INTERCEPT_MESSAGE;
AssertCompileSize(HV_X64_CPUID_INTERCEPT_MESSAGE, 0x68);
/** Pointer to a HvMessageTypeX64CpuidIntercept payload. */
typedef HV_X64_CPUID_INTERCEPT_MESSAGE *PHV_X64_CPUID_INTERCEPT_MESSAGE;
/** Pointer to a const HvMessageTypeX64CpuidIntercept payload. */
typedef HV_X64_CPUID_INTERCEPT_MESSAGE const *PCHV_X64_CPUID_INTERCEPT_MESSAGE;

/** Full HvMessageTypeX64CpuidIntercept message. */
typedef struct
{
    HV_MESSAGE_HEADER                   MsgHdr;
    HV_X64_CPUID_INTERCEPT_MESSAGE      Payload;
} HV_X64_CPUID_INTERCEPT_MESSAGE_FULL;


/** X64 exception information (HvMessageTypeX64ExceptionIntercept).
 * @sa WHV_VP_EXCEPTION_INFO */
typedef union
{
    uint8_t             AsUINT8;
    struct
    {
        uint8_t         ErrorCodeValid : 1;
        /** @todo WHV_VP_EXCEPTION_INFO::SoftwareException   */
        uint8_t         Reserved       : 7;
    };
} HV_X64_EXCEPTION_INFO;
AssertCompileSize(HV_X64_EXCEPTION_INFO, 1);

/** The payload format for HvMessageTypeX64ExceptionIntercept.
 * @sa   WHV_VP_EXCEPTION_CONTEXT
 * @note max message size. */
typedef struct
{
    HV_X64_INTERCEPT_MESSAGE_HEADER     Header;                 /**< 0x00 */
    uint16_t                            ExceptionVector;        /**< 0x28 */
    HV_X64_EXCEPTION_INFO               ExceptionInfo;          /**< 0x2a */
    uint8_t                             InstructionByteCount;   /**< 0x2b */
    uint32_t                            ErrorCode;              /**< 0x2c */
    uint64_t                            ExceptionParameter;     /**< 0x30 */
    uint64_t                            Reserved;               /**< 0x38 */
    uint8_t                             InstructionBytes[16];   /**< 0x40 */
    HV_X64_SEGMENT_REGISTER             DsSegment;              /**< 0x50 */
    HV_X64_SEGMENT_REGISTER             SsSegment;              /**< 0x60 */
    uint64_t                            Rax;                    /**< 0x70 */
    uint64_t                            Rcx;                    /**< 0x78 */
    uint64_t                            Rdx;                    /**< 0x80 */
    uint64_t                            Rbx;                    /**< 0x88 */
    uint64_t                            Rsp;                    /**< 0x90 */
    uint64_t                            Rbp;                    /**< 0x98 */
    uint64_t                            Rsi;                    /**< 0xa0 */
    uint64_t                            Rdi;                    /**< 0xa8 */
    uint64_t                            R8;                     /**< 0xb0 */
    uint64_t                            R9;                     /**< 0xb8 */
    uint64_t                            R10;                    /**< 0xc0 */
    uint64_t                            R11;                    /**< 0xc8 */
    uint64_t                            R12;                    /**< 0xd0 */
    uint64_t                            R13;                    /**< 0xd8 */
    uint64_t                            R14;                    /**< 0xe0 */
    uint64_t                            R15;                    /**< 0xe8 */
} HV_X64_EXCEPTION_INTERCEPT_MESSAGE;
AssertCompileSize(HV_X64_EXCEPTION_INTERCEPT_MESSAGE, 0xf0);
/** Pointer to a HvMessageTypeX64ExceptionIntercept payload. */
typedef HV_X64_EXCEPTION_INTERCEPT_MESSAGE *PHV_X64_EXCEPTION_INTERCEPT_MESSAGE;
/** Pointer to a ocnst HvMessageTypeX64ExceptionIntercept payload. */
typedef HV_X64_EXCEPTION_INTERCEPT_MESSAGE const *PCHV_X64_EXCEPTION_INTERCEPT_MESSAGE;


/**
 * The payload format for HvMessageTypeX64Halt,
 *
 * @note This message does not include HV_X64_INTERCEPT_MESSAGE_HEADER!
 */
typedef struct
{
    /** Seems to be a zero 64-bit field here.  */
    uint64_t    u64Reserved;
} HV_X64_HALT_MESSAGE;
/** Pointer to a HvMessageTypeX64Halt payload. */
typedef HV_X64_HALT_MESSAGE *PHV_X64_HALT_MESSAGE;
/** Pointer to a const HvMessageTypeX64Halt payload. */
typedef HV_X64_HALT_MESSAGE const *PCHV_X64_HALT_MESSAGE;

/** Full HvMessageTypeX64Halt message. */
typedef struct
{
    HV_MESSAGE_HEADER                   MsgHdr;
    HV_X64_HALT_MESSAGE                 Payload;
} HV_X64_HALT_MESSAGE_FULL;


/**
 * The payload format for HvMessageTypeX64InterruptWindow,
 *
 * @note This message does not include HV_X64_INTERCEPT_MESSAGE_HEADER!
 */
typedef struct
{
    /** 0x00: The usual intercept header. */
    HV_X64_INTERCEPT_MESSAGE_HEADER     Header;
    /** 0x28: What's pending. */
    HV_X64_PENDING_INTERRUPTION_TYPE    Type;
    /** 0x2c: Explicit structure alignment padding. */
    uint32_t                            u32ExplicitPadding;
} HV_X64_INTERRUPT_WINDOW_MESSAGE;
AssertCompileSize(HV_X64_INTERRUPT_WINDOW_MESSAGE, 0x30);
/** Pointer to a HvMessageTypeX64InterruptWindow payload. */
typedef HV_X64_INTERRUPT_WINDOW_MESSAGE *PHV_X64_INTERRUPT_WINDOW_MESSAGE;
/** Pointer to a const HvMessageTypeX64InterruptWindow payload. */
typedef HV_X64_INTERRUPT_WINDOW_MESSAGE const *PCHV_X64_INTERRUPT_WINDOW_MESSAGE;

/** Full HvMessageTypeX64InterruptWindow message. */
typedef struct
{
    /** Payload size is 0x30.   */
    HV_MESSAGE_HEADER                   MsgHdr;
    HV_X64_INTERRUPT_WINDOW_MESSAGE     Payload;
} HV_X64_INTERRUPT_WINDOW_MESSAGE_FULL;



/** Hyper-V SynIC message. */
typedef struct
{
    HV_MESSAGE_HEADER   Header;
    /** 0x10 */
    union
    {
        uint64_t                            Payload[HV_MESSAGE_MAX_PAYLOAD_QWORD_COUNT];

        /** Common header for X64 intercept messages.
         * The HvMessageTypeUnrecoverableException message only has this.  */
        HV_X64_INTERCEPT_MESSAGE_HEADER     X64InterceptHeader;
        /** HvMessageTypeGpaIntercept, HvMessageTypeUnmappedGpa. */
        HV_X64_MEMORY_INTERCEPT_MESSAGE     X64MemoryIntercept;
        /** HvMessageTypeX64IoPortIntercept */
        HV_X64_IO_PORT_INTERCEPT_MESSAGE    X64IoPortIntercept;
        /** HvMessageTypeX64MsrIntercept */
        HV_X64_MSR_INTERCEPT_MESSAGE        X64MsrIntercept;
        /** HvMessageTypeX64CpuidIntercept */
        HV_X64_CPUID_INTERCEPT_MESSAGE      X64CpuIdIntercept;
        /** HvMessageTypeX64ExceptionIntercept */
        HV_X64_EXCEPTION_INTERCEPT_MESSAGE  X64ExceptionIntercept;
        /** HvMessageTypeX64Halt.
         * @note No intercept header?  */
        HV_X64_HALT_MESSAGE                 X64Halt;
        /** HvMessageTypeX64InterruptWindow. */
        HV_X64_INTERRUPT_WINDOW_MESSAGE     X64InterruptWindow;
    };
} HV_MESSAGE;
AssertCompileSize(HV_MESSAGE, HV_MESSAGE_SIZE);
/** Pointer to a Hyper-V SynIC message. */
typedef HV_MESSAGE *PHV_MESSAGE;
/** Pointer to const a Hyper-V SynIC message. */
typedef HV_MESSAGE const *PCHV_MESSAGE;

#endif /* !IPRT_INCLUDED_nt_hyperv_h */