VirtualBox

Ignore:
Timestamp:
Aug 28, 2020 7:17:55 AM (4 years ago)
Author:
vboxsync
Message:

AMD IOMMU: bugref:9654 Split IOMMU data into relevant headers to share it with other devices/VMM (ACPI, chipset, maybe Main and firmware in the future).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp

    r85895 r85912  
    2222#define LOG_GROUP LOG_GROUP_DEV_IOMMU
    2323#include <VBox/msi.h>
     24#include <VBox/iommu-amd.h>
    2425#include <VBox/vmm/pdmdev.h>
    2526#include <VBox/AssertGuest.h>
    2627
    27 #include "VBoxDD.h"
    2828#include <iprt/x86.h>
    2929#include <iprt/string.h>
     30
     31#include "VBoxDD.h"
     32#include "DevIommuAmd.h"
    3033
    3134
     
    3336*   Defined Constants And Macros                                                                                                 *
    3437*********************************************************************************************************************************/
    35 /**
    36  * @name PCI configuration register offsets.
    37  * In accordance with the AMD spec.
    38  * @{
    39  */
    40 #define IOMMU_PCI_OFF_CAP_HDR                       0x40
    41 #define IOMMU_PCI_OFF_BASE_ADDR_REG_LO              0x44
    42 #define IOMMU_PCI_OFF_BASE_ADDR_REG_HI              0x48
    43 #define IOMMU_PCI_OFF_RANGE_REG                     0x4c
    44 #define IOMMU_PCI_OFF_MISCINFO_REG_0                0x50
    45 #define IOMMU_PCI_OFF_MISCINFO_REG_1                0x54
    46 #define IOMMU_PCI_OFF_MSI_CAP_HDR                   0x64
    47 #define IOMMU_PCI_OFF_MSI_ADDR_LO                   0x68
    48 #define IOMMU_PCI_OFF_MSI_ADDR_HI                   0x6c
    49 #define IOMMU_PCI_OFF_MSI_DATA                      0x70
    50 #define IOMMU_PCI_OFF_MSI_MAP_CAP_HDR               0x74
    51 /** @} */
    52 
    53 /**
    54  * @name MMIO register offsets.
    55  * In accordance with the AMD spec.
    56  * @{
    57  */
    58 #define IOMMU_MMIO_OFF_DEV_TAB_BAR                  0x00
    59 #define IOMMU_MMIO_OFF_CMD_BUF_BAR                  0x08
    60 #define IOMMU_MMIO_OFF_EVT_LOG_BAR                  0x10
    61 #define IOMMU_MMIO_OFF_CTRL                         0x18
    62 #define IOMMU_MMIO_OFF_EXCL_BAR                     0x20
    63 #define IOMMU_MMIO_OFF_EXCL_RANGE_LIMIT             0x28
    64 #define IOMMU_MMIO_OFF_EXT_FEAT                     0x30
    65 
    66 #define IOMMU_MMIO_OFF_PPR_LOG_BAR                  0x38
    67 #define IOMMU_MMIO_OFF_HW_EVT_HI                    0x40
    68 #define IOMMU_MMIO_OFF_HW_EVT_LO                    0x48
    69 #define IOMMU_MMIO_OFF_HW_EVT_STATUS                0x50
    70 
    71 #define IOMMU_MMIO_OFF_SMI_FLT_FIRST                0x60
    72 #define IOMMU_MMIO_OFF_SMI_FLT_LAST                 0xd8
    73 
    74 #define IOMMU_MMIO_OFF_GALOG_BAR                    0xe0
    75 #define IOMMU_MMIO_OFF_GALOG_TAIL_ADDR              0xe8
    76 
    77 #define IOMMU_MMIO_OFF_PPR_LOG_B_BAR                0xf0
    78 #define IOMMU_MMIO_OFF_PPR_EVT_B_BAR                0xf8
    79 
    80 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_FIRST            0x100
    81 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_1                0x100
    82 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_2                0x108
    83 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_3                0x110
    84 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_4                0x118
    85 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_5                0x120
    86 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_6                0x128
    87 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_7                0x130
    88 #define IOMMU_MMIO_OFF_DEV_TAB_SEG_LAST             0x130
    89 
    90 #define IOMMU_MMIO_OFF_DEV_SPECIFIC_FEAT            0x138
    91 #define IOMMU_MMIO_OFF_DEV_SPECIFIC_CTRL            0x140
    92 #define IOMMU_MMIO_OFF_DEV_SPECIFIC_STATUS          0x148
    93 
    94 #define IOMMU_MMIO_OFF_MSI_VECTOR_0                 0x150
    95 #define IOMMU_MMIO_OFF_MSI_VECTOR_1                 0x154
    96 #define IOMMU_MMIO_OFF_MSI_CAP_HDR                  0x158
    97 #define IOMMU_MMIO_OFF_MSI_ADDR_LO                  0x15c
    98 #define IOMMU_MMIO_OFF_MSI_ADDR_HI                  0x160
    99 #define IOMMU_MMIO_OFF_MSI_DATA                     0x164
    100 #define IOMMU_MMIO_OFF_MSI_MAPPING_CAP_HDR          0x168
    101 
    102 #define IOMMU_MMIO_OFF_PERF_OPT_CTRL                0x16c
    103 
    104 #define IOMMU_MMIO_OFF_XT_GEN_INTR_CTRL             0x170
    105 #define IOMMU_MMIO_OFF_XT_PPR_INTR_CTRL             0x178
    106 #define IOMMU_MMIO_OFF_XT_GALOG_INT_CTRL            0x180
    107 
    108 #define IOMMU_MMIO_OFF_MARC_APER_BAR_0              0x200
    109 #define IOMMU_MMIO_OFF_MARC_APER_RELOC_0            0x208
    110 #define IOMMU_MMIO_OFF_MARC_APER_LEN_0              0x210
    111 #define IOMMU_MMIO_OFF_MARC_APER_BAR_1              0x218
    112 #define IOMMU_MMIO_OFF_MARC_APER_RELOC_1            0x220
    113 #define IOMMU_MMIO_OFF_MARC_APER_LEN_1              0x228
    114 #define IOMMU_MMIO_OFF_MARC_APER_BAR_2              0x230
    115 #define IOMMU_MMIO_OFF_MARC_APER_RELOC_2            0x238
    116 #define IOMMU_MMIO_OFF_MARC_APER_LEN_2              0x240
    117 #define IOMMU_MMIO_OFF_MARC_APER_BAR_3              0x248
    118 #define IOMMU_MMIO_OFF_MARC_APER_RELOC_3            0x250
    119 #define IOMMU_MMIO_OFF_MARC_APER_LEN_3              0x258
    120 
    121 #define IOMMU_MMIO_OFF_RSVD_REG                     0x1ff8
    122 
    123 #define IOMMU_MMIO_CMD_BUF_HEAD_PTR                 0x2000
    124 #define IOMMU_MMIO_CMD_BUF_TAIL_PTR                 0x2008
    125 #define IOMMU_MMIO_EVT_LOG_HEAD_PTR                 0x2010
    126 #define IOMMU_MMIO_EVT_LOG_TAIL_PTR                 0x2018
    127 
    128 #define IOMMU_MMIO_OFF_STATUS                       0x2020
    129 
    130 #define IOMMU_MMIO_OFF_PPR_LOG_HEAD_PTR             0x2030
    131 #define IOMMU_MMIO_OFF_PPR_LOG_TAIL_PTR             0x2038
    132 
    133 #define IOMMU_MMIO_OFF_GALOG_HEAD_PTR               0x2040
    134 #define IOMMU_MMIO_OFF_GALOG_TAIL_PTR               0x2048
    135 
    136 #define IOMMU_MMIO_OFF_PPR_LOG_B_HEAD_PTR           0x2050
    137 #define IOMMU_MMIO_OFF_PPR_LOG_B_TAIL_PTR           0x2058
    138 
    139 #define IOMMU_MMIO_OFF_EVT_LOG_B_HEAD_PTR           0x2070
    140 #define IOMMU_MMIO_OFF_EVT_LOG_B_TAIL_PTR           0x2078
    141 
    142 #define IOMMU_MMIO_OFF_PPR_LOG_AUTO_RESP            0x2080
    143 #define IOMMU_MMIO_OFF_PPR_LOG_OVERFLOW_EARLY       0x2088
    144 #define IOMMU_MMIO_OFF_PPR_LOG_B_OVERFLOW_EARLY     0x2090
    145 /** @} */
    146 
    147 /**
    148  * @name MMIO register-access table offsets.
    149  * Each table [first..last] (both inclusive) represents the range of registers
    150  * covered by a distinct register-access table. This is done due to arbitrary large
    151  * gaps in the MMIO register offsets themselves.
    152  * @{
    153  */
    154 #define IOMMU_MMIO_OFF_TABLE_0_FIRST               0x00
    155 #define IOMMU_MMIO_OFF_TABLE_0_LAST                0x258
    156 
    157 #define IOMMU_MMIO_OFF_TABLE_1_FIRST               0x1ff8
    158 #define IOMMU_MMIO_OFF_TABLE_1_LAST                0x2090
    159 /** @} */
    160 
    161 /**
    162  * @name Commands.
    163  * In accordance with the AMD spec.
    164  * @{
    165  */
    166 #define IOMMU_CMD_COMPLETION_WAIT                   0x01
    167 #define IOMMU_CMD_INV_DEV_TAB_ENTRY                 0x02
    168 #define IOMMU_CMD_INV_IOMMU_PAGES                   0x03
    169 #define IOMMU_CMD_INV_IOTLB_PAGES                   0x04
    170 #define IOMMU_CMD_INV_INTR_TABLE                    0x05
    171 #define IOMMU_CMD_PREFETCH_IOMMU_PAGES              0x06
    172 #define IOMMU_CMD_COMPLETE_PPR_REQ                  0x07
    173 #define IOMMU_CMD_INV_IOMMU_ALL                     0x08
    174 /** @} */
    175 
    176 /**
    177  * @name Event codes.
    178  * In accordance with the AMD spec.
    179  * @{
    180  */
    181 #define IOMMU_EVT_ILLEGAL_DEV_TAB_ENTRY             0x01
    182 #define IOMMU_EVT_IO_PAGE_FAULT                     0x02
    183 #define IOMMU_EVT_DEV_TAB_HW_ERROR                  0x03
    184 #define IOMMU_EVT_PAGE_TAB_HW_ERROR                 0x04
    185 #define IOMMU_EVT_ILLEGAL_CMD_ERROR                 0x05
    186 #define IOMMU_EVT_COMMAND_HW_ERROR                  0x06
    187 #define IOMMU_EVT_IOTLB_INV_TIMEOUT                 0x07
    188 #define IOMMU_EVT_INVALID_DEV_REQ                   0x08
    189 #define IOMMU_EVT_INVALID_PPR_REQ                   0x09
    190 #define IOMMU_EVT_EVENT_COUNTER_ZERO                0x10
    191 #define IOMMU_EVT_GUEST_EVENT_FAULT                 0x11
    192 /** @} */
    193 
    194 /**
    195  * @name IOMMU Capability Header.
    196  * In accordance with the AMD spec.
    197  * @{
    198  */
    199 /** CapId: Capability ID. */
    200 #define IOMMU_BF_CAPHDR_CAP_ID_SHIFT                0
    201 #define IOMMU_BF_CAPHDR_CAP_ID_MASK                 UINT32_C(0x000000ff)
    202 /** CapPtr: Capability Pointer. */
    203 #define IOMMU_BF_CAPHDR_CAP_PTR_SHIFT               8
    204 #define IOMMU_BF_CAPHDR_CAP_PTR_MASK                UINT32_C(0x0000ff00)
    205 /** CapType: Capability Type. */
    206 #define IOMMU_BF_CAPHDR_CAP_TYPE_SHIFT              16
    207 #define IOMMU_BF_CAPHDR_CAP_TYPE_MASK               UINT32_C(0x00070000)
    208 /** CapRev: Capability Revision. */
    209 #define IOMMU_BF_CAPHDR_CAP_REV_SHIFT               19
    210 #define IOMMU_BF_CAPHDR_CAP_REV_MASK                UINT32_C(0x00f80000)
    211 /** IoTlbSup: IO TLB Support. */
    212 #define IOMMU_BF_CAPHDR_IOTLB_SUP_SHIFT             24
    213 #define IOMMU_BF_CAPHDR_IOTLB_SUP_MASK              UINT32_C(0x01000000)
    214 /** HtTunnel: HyperTransport Tunnel translation support. */
    215 #define IOMMU_BF_CAPHDR_HT_TUNNEL_SHIFT             25
    216 #define IOMMU_BF_CAPHDR_HT_TUNNEL_MASK              UINT32_C(0x02000000)
    217 /** NpCache: Not Present table entries Cached. */
    218 #define IOMMU_BF_CAPHDR_NP_CACHE_SHIFT              26
    219 #define IOMMU_BF_CAPHDR_NP_CACHE_MASK               UINT32_C(0x04000000)
    220 /** EFRSup: Extended Feature Register (EFR) Supported. */
    221 #define IOMMU_BF_CAPHDR_EFR_SUP_SHIFT               27
    222 #define IOMMU_BF_CAPHDR_EFR_SUP_MASK                UINT32_C(0x08000000)
    223 /** CapExt: Miscellaneous Information Register Supported . */
    224 #define IOMMU_BF_CAPHDR_CAP_EXT_SHIFT               28
    225 #define IOMMU_BF_CAPHDR_CAP_EXT_MASK                UINT32_C(0x10000000)
    226 /** Bits 31:29 reserved. */
    227 #define IOMMU_BF_CAPHDR_RSVD_29_31_SHIFT            29
    228 #define IOMMU_BF_CAPHDR_RSVD_29_31_MASK             UINT32_C(0xe0000000)
    229 RT_BF_ASSERT_COMPILE_CHECKS(IOMMU_BF_CAPHDR_, UINT32_C(0), UINT32_MAX,
    230                             (CAP_ID, CAP_PTR, CAP_TYPE, CAP_REV, IOTLB_SUP, HT_TUNNEL, NP_CACHE, EFR_SUP, CAP_EXT, RSVD_29_31));
    231 /** @} */
    232 
    233 /**
    234  * @name IOMMU Base Address Low Register.
    235  * In accordance with the AMD spec.
    236  * @{
    237  */
    238 /** Enable: Enables access to the address specified in the Base Address Register. */
    239 #define IOMMU_BF_BASEADDR_LO_ENABLE_SHIFT           0
    240 #define IOMMU_BF_BASEADDR_LO_ENABLE_MASK            UINT32_C(0x00000001)
    241 /** Bits 13:1 reserved. */
    242 #define IOMMU_BF_BASEADDR_LO_RSVD_1_13_SHIFT        1
    243 #define IOMMU_BF_BASEADDR_LO_RSVD_1_13_MASK         UINT32_C(0x00003ffe)
    244 /** Base Address[31:14]: Low Base address of IOMMU MMIO control registers. */
    245 #define IOMMU_BF_BASEADDR_LO_ADDR_SHIFT             14
    246 #define IOMMU_BF_BASEADDR_LO_ADDR_MASK              UINT32_C(0xffffc000)
    247 RT_BF_ASSERT_COMPILE_CHECKS(IOMMU_BF_BASEADDR_LO_, UINT32_C(0), UINT32_MAX,
    248                             (ENABLE, RSVD_1_13, ADDR));
    249 /** @} */
    250 
    251 /**
    252  * @name IOMMU Range Register.
    253  * In accordance with the AMD spec.
    254  * @{
    255  */
    256 /** UnitID: HyperTransport Unit ID. */
    257 #define IOMMU_BF_RANGE_UNIT_ID_SHIFT                0
    258 #define IOMMU_BF_RANGE_UNIT_ID_MASK                 UINT32_C(0x0000001f)
    259 /** Bits 6:5 reserved. */
    260 #define IOMMU_BF_RANGE_RSVD_5_6_SHIFT               5
    261 #define IOMMU_BF_RANGE_RSVD_5_6_MASK                UINT32_C(0x00000060)
    262 /** RngValid: Range valid. */
    263 #define IOMMU_BF_RANGE_VALID_SHIFT                  7
    264 #define IOMMU_BF_RANGE_VALID_MASK                   UINT32_C(0x00000080)
    265 /** BusNumber: Device range bus number. */
    266 #define IOMMU_BF_RANGE_BUS_NUMBER_SHIFT             8
    267 #define IOMMU_BF_RANGE_BUS_NUMBER_MASK              UINT32_C(0x0000ff00)
    268 /** First Device. */
    269 #define IOMMU_BF_RANGE_FIRST_DEVICE_SHIFT           16
    270 #define IOMMU_BF_RANGE_FIRST_DEVICE_MASK            UINT32_C(0x00ff0000)
    271 /** Last Device. */
    272 #define IOMMU_BF_RANGE_LAST_DEVICE_SHIFT            24
    273 #define IOMMU_BF_RANGE_LAST_DEVICE_MASK             UINT32_C(0xff000000)
    274 RT_BF_ASSERT_COMPILE_CHECKS(IOMMU_BF_RANGE_, UINT32_C(0), UINT32_MAX,
    275                             (UNIT_ID, RSVD_5_6, VALID, BUS_NUMBER, FIRST_DEVICE, LAST_DEVICE));
    276 /** @} */
    277 
    278 /**
    279  * @name IOMMU Miscellaneous Information Register 0.
    280  * In accordance with the AMD spec.
    281  * @{
    282  */
    283 /** MsiNum: MSI message number. */
    284 #define IOMMU_BF_MISCINFO_0_MSI_NUM_SHIFT           0
    285 #define IOMMU_BF_MISCINFO_0_MSI_NUM_MASK            UINT32_C(0x0000001f)
    286 /** GvaSize: Guest Virtual Address Size. */
    287 #define IOMMU_BF_MISCINFO_0_GVA_SIZE_SHIFT          5
    288 #define IOMMU_BF_MISCINFO_0_GVA_SIZE_MASK           UINT32_C(0x000000e0)
    289 /** PaSize: Physical Address Size. */
    290 #define IOMMU_BF_MISCINFO_0_PA_SIZE_SHIFT           8
    291 #define IOMMU_BF_MISCINFO_0_PA_SIZE_MASK            UINT32_C(0x00007f00)
    292 /** VaSize: Virtual Address Size. */
    293 #define IOMMU_BF_MISCINFO_0_VA_SIZE_SHIFT           15
    294 #define IOMMU_BF_MISCINFO_0_VA_SIZE_MASK            UINT32_C(0x003f8000)
    295 /** HtAtsResv: HyperTransport ATS Response Address range Reserved. */
    296 #define IOMMU_BF_MISCINFO_0_HT_ATS_RESV_SHIFT       22
    297 #define IOMMU_BF_MISCINFO_0_HT_ATS_RESV_MASK        UINT32_C(0x00400000)
    298 /** Bits 26:23 reserved. */
    299 #define IOMMU_BF_MISCINFO_0_RSVD_23_26_SHIFT        23
    300 #define IOMMU_BF_MISCINFO_0_RSVD_23_26_MASK         UINT32_C(0x07800000)
    301 /** MsiNumPPR: Peripheral Page Request MSI message number. */
    302 #define IOMMU_BF_MISCINFO_0_MSI_NUM_PPR_SHIFT       27
    303 #define IOMMU_BF_MISCINFO_0_MSI_NUM_PPR_MASK        UINT32_C(0xf8000000)
    304 RT_BF_ASSERT_COMPILE_CHECKS(IOMMU_BF_MISCINFO_0_, UINT32_C(0), UINT32_MAX,
    305                             (MSI_NUM, GVA_SIZE, PA_SIZE, VA_SIZE, HT_ATS_RESV, RSVD_23_26, MSI_NUM_PPR));
    306 /** @} */
    307 
    308 /**
    309  * @name IOMMU Miscellaneous Information Register 1.
    310  * In accordance with the AMD spec.
    311  * @{
    312  */
    313 /** MsiNumGA: MSI message number for guest virtual-APIC log. */
    314 #define IOMMU_BF_MISCINFO_1_MSI_NUM_GA_SHIFT        0
    315 #define IOMMU_BF_MISCINFO_1_MSI_NUM_GA_MASK         UINT32_C(0x0000001f)
    316 /** Bits 31:5 reserved. */
    317 #define IOMMU_BF_MISCINFO_1_RSVD_5_31_SHIFT         5
    318 #define IOMMU_BF_MISCINFO_1_RSVD_5_31_MASK          UINT32_C(0xffffffe0)
    319 RT_BF_ASSERT_COMPILE_CHECKS(IOMMU_BF_MISCINFO_1_, UINT32_C(0), UINT32_MAX,
    320                             (MSI_NUM_GA, RSVD_5_31));
    321 /** @} */
    322 
    323 /**
    324  * @name MSI Capability Header Register.
    325  * In accordance with the AMD spec.
    326  * @{
    327  */
    328 /** MsiCapId: Capability ID. */
    329 #define IOMMU_BF_MSI_CAP_HDR_CAP_ID_SHIFT           0
    330 #define IOMMU_BF_MSI_CAP_HDR_CAP_ID_MASK            UINT32_C(0x000000ff)
    331 /** MsiCapPtr: Pointer (PCI config offset) to the next capability. */
    332 #define IOMMU_BF_MSI_CAP_HDR_CAP_PTR_SHIFT          8
    333 #define IOMMU_BF_MSI_CAP_HDR_CAP_PTR_MASK           UINT32_C(0x0000ff00)
    334 /** MsiEn: Message Signal Interrupt enable. */
    335 #define IOMMU_BF_MSI_CAP_HDR_EN_SHIFT               16
    336 #define IOMMU_BF_MSI_CAP_HDR_EN_MASK                UINT32_C(0x00010000)
    337 /** MsiMultMessCap: MSI Multi-Message Capability. */
    338 #define IOMMU_BF_MSI_CAP_HDR_MULTMESS_CAP_SHIFT     17
    339 #define IOMMU_BF_MSI_CAP_HDR_MULTMESS_CAP_MASK      UINT32_C(0x000e0000)
    340 /** MsiMultMessEn: MSI Mult-Message Enable. */
    341 #define IOMMU_BF_MSI_CAP_HDR_MULTMESS_EN_SHIFT      20
    342 #define IOMMU_BF_MSI_CAP_HDR_MULTMESS_EN_MASK       UINT32_C(0x00700000)
    343 /** Msi64BitEn: MSI 64-bit Enabled. */
    344 #define IOMMU_BF_MSI_CAP_HDR_64BIT_EN_SHIFT         23
    345 #define IOMMU_BF_MSI_CAP_HDR_64BIT_EN_MASK          UINT32_C(0x00800000)
    346 /** Bits 31:24 reserved. */
    347 #define IOMMU_BF_MSI_CAP_HDR_RSVD_24_31_SHIFT       24
    348 #define IOMMU_BF_MSI_CAP_HDR_RSVD_24_31_MASK        UINT32_C(0xff000000)
    349 RT_BF_ASSERT_COMPILE_CHECKS(IOMMU_BF_MSI_CAP_HDR_, UINT32_C(0), UINT32_MAX,
    350                             (CAP_ID, CAP_PTR, EN, MULTMESS_CAP, MULTMESS_EN, 64BIT_EN, RSVD_24_31));
    351 /** @} */
    352 
    353 /**
    354  * @name MSI Mapping Capability Header Register.
    355  * In accordance with the AMD spec.
    356  * @{
    357  */
    358 /** MsiMapCapId: Capability ID. */
    359 #define IOMMU_BF_MSI_MAP_CAPHDR_CAP_ID_SHIFT        0
    360 #define IOMMU_BF_MSI_MAP_CAPHDR_CAP_ID_MASK         UINT32_C(0x000000ff)
    361 /** MsiMapCapPtr: Pointer (PCI config offset) to the next capability. */
    362 #define IOMMU_BF_MSI_MAP_CAPHDR_CAP_PTR_SHIFT       8
    363 #define IOMMU_BF_MSI_MAP_CAPHDR_CAP_PTR_MASK        UINT32_C(0x0000ff00)
    364 /** MsiMapEn: MSI mapping capability enable. */
    365 #define IOMMU_BF_MSI_MAP_CAPHDR_EN_SHIFT            16
    366 #define IOMMU_BF_MSI_MAP_CAPHDR_EN_MASK             UINT32_C(0x00010000)
    367 /** MsiMapFixd: MSI interrupt mapping range is not programmable. */
    368 #define IOMMU_BF_MSI_MAP_CAPHDR_FIXED_SHIFT         17
    369 #define IOMMU_BF_MSI_MAP_CAPHDR_FIXED_MASK          UINT32_C(0x00020000)
    370 /** Bits 18:28 reserved. */
    371 #define IOMMU_BF_MSI_MAP_CAPHDR_RSVD_18_28_SHIFT    18
    372 #define IOMMU_BF_MSI_MAP_CAPHDR_RSVD_18_28_MASK     UINT32_C(0x07fc0000)
    373 /** MsiMapCapType: MSI mapping capability. */
    374 #define IOMMU_BF_MSI_MAP_CAPHDR_CAP_TYPE_SHIFT      27
    375 #define IOMMU_BF_MSI_MAP_CAPHDR_CAP_TYPE_MASK       UINT32_C(0xf8000000)
    376 RT_BF_ASSERT_COMPILE_CHECKS(IOMMU_BF_MSI_MAP_CAPHDR_, UINT32_C(0), UINT32_MAX,
    377                             (CAP_ID, CAP_PTR, EN, FIXED, RSVD_18_28, CAP_TYPE));
    378 /** @} */
    379 
    380 /**
    381  * @name IOMMU Status Register Bits.
    382  * In accordance with the AMD spec.
    383  * @{
    384  */
    385 /** EventOverflow: Event log overflow. */
    386 #define IOMMU_STATUS_EVT_LOG_OVERFLOW               RT_BIT_64(0)
    387 /** EventLogInt: Event log interrupt. */
    388 #define IOMMU_STATUS_EVT_LOG_INTR                   RT_BIT_64(1)
    389 /** ComWaitInt: Completion wait interrupt. */
    390 #define IOMMU_STATUS_COMPLETION_WAIT_INTR           RT_BIT_64(2)
    391 /** EventLogRun: Event log is running. */
    392 #define IOMMU_STATUS_EVT_LOG_RUNNING                RT_BIT_64(3)
    393 /** CmdBufRun: Command buffer is running. */
    394 #define IOMMU_STATUS_CMD_BUF_RUNNING                RT_BIT_64(4)
    395 /** PprOverflow: Peripheral page request log overflow. */
    396 #define IOMMU_STATUS_PPR_LOG_OVERFLOW               RT_BIT_64(5)
    397 /** PprInt: Peripheral page request log interrupt. */
    398 #define IOMMU_STATUS_PPR_LOG_INTR                   RT_BIT_64(6)
    399 /** PprLogRun: Peripheral page request log is running. */
    400 #define IOMMU_STATUS_PPR_LOG_RUN                    RT_BIT_64(7)
    401 /** GALogRun: Guest virtual-APIC log is running. */
    402 #define IOMMU_STATUS_GA_LOG_RUN                     RT_BIT_64(8)
    403 /** GALOverflow: Guest virtual-APIC log overflow. */
    404 #define IOMMU_STATUS_GA_LOG_OVERFLOW                RT_BIT_64(9)
    405 /** GAInt: Guest virtual-APIC log interrupt. */
    406 #define IOMMU_STATUS_GA_LOG_INTR                    RT_BIT_64(10)
    407 /** PprOvrflwB: PPR Log B overflow. */
    408 #define IOMMU_STATUS_PPR_LOG_B_OVERFLOW             RT_BIT_64(11)
    409 /** PprLogActive: PPR Log B is active. */
    410 #define IOMMU_STATUS_PPR_LOG_B_ACTIVE               RT_BIT_64(12)
    411 /** EvtOvrflwB: Event log B overflow. */
    412 #define IOMMU_STATUS_EVT_LOG_B_OVERFLOW             RT_BIT_64(15)
    413 /** EventLogActive: Event log B active. */
    414 #define IOMMU_STATUS_EVT_LOG_B_ACTIVE               RT_BIT_64(16)
    415 /** PprOvrflwEarlyB: PPR log B overflow early warning. */
    416 #define IOMMU_STATUS_PPR_LOG_B_OVERFLOW_EARLY       RT_BIT_64(17)
    417 /** PprOverflowEarly: PPR log overflow early warning. */
    418 #define IOMMU_STATUS_PPR_LOG_OVERFLOW_EARLY         RT_BIT_64(18)
    419 /** @} */
    420 
    421 /** @name IOMMU_IO_PERM_XXX: IOMMU I/O access permissions bits.
    422  * In accordance with the AMD spec.
    423  *
    424  * These values match the shifted values of the IR and IW field of the DTE and the
    425  * PTE, PDE of the I/O page tables.
    426  *
    427  * @{ */
    428 #define IOMMU_IO_PERM_NONE                          (0)
    429 #define IOMMU_IO_PERM_READ                          RT_BIT_64(0)
    430 #define IOMMU_IO_PERM_WRITE                         RT_BIT_64(1)
    431 #define IOMMU_IO_PERM_READ_WRITE                    (IOMMU_IO_PERM_READ | IOMMU_IO_PERM_WRITE)
    432 #define IOMMU_IO_PERM_SHIFT                         61
    433 #define IOMMU_IO_PERM_MASK                          0x3
    434 /** @} */
    435 
    436 /** @name SYSMGT_TYPE_XXX: System Management Message Enable Types.
    437  * In accordance with the AMD spec.
    438  * @{ */
    439 #define SYSMGTTYPE_DMA_DENY                         (0)
    440 #define SYSMGTTYPE_MSG_ALL_ALLOW                    (1)
    441 #define SYSMGTTYPE_MSG_INT_ALLOW                    (2)
    442 #define SYSMGTTYPE_DMA_ALLOW                        (3)
    443 /** @} */
    444 
    445 /** @name IOMMU_INTR_CTRL_XX: DTE::IntCtl field values.
    446  * These are control bits for handling fixed and arbitrated interrupts.
    447  * In accordance with the AMD spec.
    448  * @{ */
    449 #define IOMMU_INTR_CTRL_TARGET_ABORT                (0)
    450 #define IOMMU_INTR_CTRL_FWD_UNMAPPED                (1)
    451 #define IOMMU_INTR_CTRL_REMAP                       (2)
    452 #define IOMMU_INTR_CTRL_RSVD                        (3)
    453 /** @} */
    454 
    455 /** @name Miscellaneous IOMMU defines.
    456  * @{ */
    45738/** Log prefix string. */
    45839#define IOMMU_LOG_PFX                               "IOMMU-AMD"
    45940/** The current saved state version. */
    46041#define IOMMU_SAVED_STATE_VERSION                   1
    461 /** AMD's vendor ID. */
    462 #define IOMMU_PCI_VENDOR_ID                         0x1022
    463 /** VirtualBox IOMMU device ID. */
    464 #define IOMMU_PCI_DEVICE_ID                         0xc0de
    465 /** VirtualBox IOMMU device revision ID. */
    466 #define IOMMU_PCI_REVISION_ID                       0x01
    467 /** Size of the MMIO region in bytes. */
    468 #define IOMMU_MMIO_REGION_SIZE                      _16K
    469 /** Number of device table segments supported (power of 2). */
    470 #define IOMMU_MAX_DEV_TAB_SEGMENTS                  3
    471 /** Maximum host address translation level supported (inclusive). NOTE! If you
    472  *  change this make sure to change the value in ACPI tables (DevACPI.cpp) */
    473 #define IOMMU_MAX_HOST_PT_LEVEL                     6
    47442/** The IOTLB entry magic. */
    47543#define IOMMU_IOTLBE_MAGIC                          0x10acce55
    476 /** The device-specific feature major revision. */
    477 #define IOMMU_DEVSPEC_FEAT_MAJOR_VERSION            0x1
    478 /** The device-specific feature minor revision. */
    479 #define IOMMU_DEVSPEC_FEAT_MINOR_VERSION            0x0
    480 /** The device-specific control major revision. */
    481 #define IOMMU_DEVSPEC_CTRL_MAJOR_VERSION            0x1
    482 /** The device-specific control minor revision. */
    483 #define IOMMU_DEVSPEC_CTRL_MINOR_VERSION            0x0
    484 /** The device-specific status major revision. */
    485 #define IOMMU_DEVSPEC_STATUS_MAJOR_VERSION          0x1
    486 /** The device-specific status minor revision. */
    487 #define IOMMU_DEVSPEC_STATUS_MINOR_VERSION          0x0
    488 /** @} */
    489 
     44
     45
     46/*********************************************************************************************************************************
     47*   Structures and Typedefs                                                                                                      *
     48*********************************************************************************************************************************/
    49049/**
    49150 * Acquires the IOMMU PDM lock.
     
    53493        Assert(!PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->CTX_SUFF(pCritSectRo))); \
    53594    }  while (0)
    536 
    537 /**
    538  * Gets the device table size given the size field.
    539  */
    540 #define IOMMU_GET_DEV_TAB_SIZE(a_uSize)     (((a_uSize) + 1) << X86_PAGE_4K_SHIFT)
    541 
    542 
    543 /*********************************************************************************************************************************
    544 *   Structures and Typedefs                                                                                                      *
    545 *********************************************************************************************************************************/
    546 /**
    547  * The Device ID.
    548  * In accordance with VirtualBox's PCI configuration.
    549  */
    550 typedef union
    551 {
    552     struct
    553     {
    554         uint16_t    u3Function : 3;  /**< Bits 2:0   - Function. */
    555         uint16_t    u9Device : 9;    /**< Bits 11:3  - Device. */
    556         uint16_t    u4Bus : 4;       /**< Bits 15:12 - Bus. */
    557     } n;
    558     /** The unsigned integer view. */
    559     uint16_t        u;
    560 } DEVICE_ID_T;
    561 AssertCompileSize(DEVICE_ID_T, 2);
    562 
    563 /**
    564  * Device Table Entry (DTE).
    565  * In accordance with the AMD spec.
    566  */
    567 typedef union
    568 {
    569     struct
    570     {
    571         RT_GCC_EXTENSION uint64_t  u1Valid : 1;                   /**< Bit  0       - V: Valid. */
    572         RT_GCC_EXTENSION uint64_t  u1TranslationValid : 1;        /**< Bit  1       - TV: Translation information Valid. */
    573         RT_GCC_EXTENSION uint64_t  u5Rsvd0 : 5;                   /**< Bits 6:2     - Reserved. */
    574         RT_GCC_EXTENSION uint64_t  u2Had : 2;                     /**< Bits 8:7     - HAD: Host Access Dirty. */
    575         RT_GCC_EXTENSION uint64_t  u3Mode : 3;                    /**< Bits 11:9    - Mode: Paging mode. */
    576         RT_GCC_EXTENSION uint64_t  u40PageTableRootPtrLo : 40;    /**< Bits 51:12   - Page Table Root Pointer. */
    577         RT_GCC_EXTENSION uint64_t  u1Ppr : 1;                     /**< Bit  52      - PPR: Peripheral Page Request. */
    578         RT_GCC_EXTENSION uint64_t  u1GstPprRespPasid : 1;         /**< Bit  53      - GRPR: Guest PPR Response with PASID. */
    579         RT_GCC_EXTENSION uint64_t  u1GstIoValid : 1;              /**< Bit  54      - GIoV: Guest I/O Protection Valid. */
    580         RT_GCC_EXTENSION uint64_t  u1GstTranslateValid : 1;       /**< Bit  55      - GV: Guest translation Valid. */
    581         RT_GCC_EXTENSION uint64_t  u2GstMode : 2;                 /**< Bits 57:56   - GLX: Guest Paging mode levels. */
    582         RT_GCC_EXTENSION uint64_t  u3GstCr3TableRootPtrLo : 2;    /**< Bits 60:58   - GCR3 TRP: Guest CR3 Table Root Ptr (Lo). */
    583         RT_GCC_EXTENSION uint64_t  u1IoRead : 1;                  /**< Bit  61      - IR: I/O Read permission. */
    584         RT_GCC_EXTENSION uint64_t  u1IoWrite : 1;                 /**< Bit  62      - IW: I/O Write permission. */
    585         RT_GCC_EXTENSION uint64_t  u1Rsvd0 : 1;                   /**< Bit  63      - Reserved. */
    586         RT_GCC_EXTENSION uint64_t  u16DomainId : 1;               /**< Bits 79:64   - Domain ID. */
    587         RT_GCC_EXTENSION uint64_t  u16GstCr3TableRootPtrMed : 16; /**< Bits 95:80   - GCR3 TRP: Guest CR3 Table Root Ptr (Mid). */
    588         RT_GCC_EXTENSION uint64_t  u1IoTlbEnable : 1;             /**< Bit  96      - I: IOTLB Enable. */
    589         RT_GCC_EXTENSION uint64_t  u1SuppressPfEvents : 1;        /**< Bit  97      - SE: Supress Page-fault events. */
    590         RT_GCC_EXTENSION uint64_t  u1SuppressAllPfEvents : 1;     /**< Bit  98      - SA: Supress All Page-fault events. */
    591         RT_GCC_EXTENSION uint64_t  u2IoCtl : 1;                   /**< Bits 100:99  - IoCtl: Port I/O Control. */
    592         RT_GCC_EXTENSION uint64_t  u1Cache : 1;                   /**< Bit  101     - Cache: IOTLB Cache Hint. */
    593         RT_GCC_EXTENSION uint64_t  u1SnoopDisable : 1;            /**< Bit  102     - SD: Snoop Disable. */
    594         RT_GCC_EXTENSION uint64_t  u1AllowExclusion : 1;          /**< Bit  103     - EX: Allow Exclusion. */
    595         RT_GCC_EXTENSION uint64_t  u2SysMgt : 2;                  /**< Bits 105:104 - SysMgt: System Management message enable. */
    596         RT_GCC_EXTENSION uint64_t  u1Rsvd1 : 1;                   /**< Bit  106     - Reserved. */
    597         RT_GCC_EXTENSION uint64_t  u21GstCr3TableRootPtrHi : 21;  /**< Bits 127:107 - GCR3 TRP: Guest CR3 Table Root Ptr (Hi). */
    598         RT_GCC_EXTENSION uint64_t  u1IntrMapValid : 1;            /**< Bit  128     - IV: Interrupt map Valid. */
    599         RT_GCC_EXTENSION uint64_t  u4IntrTableLength : 4;         /**< Bits 132:129 - IntTabLen: Interrupt Table Length. */
    600         RT_GCC_EXTENSION uint64_t  u1IgnoreUnmappedIntrs : 1;     /**< Bits 133     - IG: Ignore unmapped interrupts. */
    601         RT_GCC_EXTENSION uint64_t  u26IntrTableRootPtr : 26;      /**< Bits 159:134 - Interrupt Root Table Pointer (Lo). */
    602         RT_GCC_EXTENSION uint64_t  u20IntrTableRootPtr : 20;      /**< Bits 179:160 - Interrupt Root Table Pointer (Hi). */
    603         RT_GCC_EXTENSION uint64_t  u4Rsvd0 : 4;                   /**< Bits 183:180 - Reserved. */
    604         RT_GCC_EXTENSION uint64_t  u1InitPassthru : 1;            /**< Bits 184     - INIT Pass-through. */
    605         RT_GCC_EXTENSION uint64_t  u1ExtIntPassthru : 1;          /**< Bits 185     - External Interrupt Pass-through. */
    606         RT_GCC_EXTENSION uint64_t  u1NmiPassthru : 1;             /**< Bits 186     - NMI Pass-through. */
    607         RT_GCC_EXTENSION uint64_t  u1Rsvd2 : 1;                   /**< Bits 187     - Reserved. */
    608         RT_GCC_EXTENSION uint64_t  u2IntrCtrl : 2;                /**< Bits 189:188 - IntCtl: Interrupt Control. */
    609         RT_GCC_EXTENSION uint64_t  u1Lint0Passthru : 1;           /**< Bit  190     - Lint0Pass: LINT0 Pass-through. */
    610         RT_GCC_EXTENSION uint64_t  u1Lint1Passthru : 1;           /**< Bit  191     - Lint1Pass: LINT1 Pass-through. */
    611         RT_GCC_EXTENSION uint64_t  u32Rsvd0 : 32;                 /**< Bits 223:192 - Reserved. */
    612         RT_GCC_EXTENSION uint64_t  u22Rsvd0 : 22;                 /**< Bits 245:224 - Reserved. */
    613         RT_GCC_EXTENSION uint64_t  u1AttrOverride : 1;            /**< Bit  246     - AttrV: Attribute Override. */
    614         RT_GCC_EXTENSION uint64_t  u1Mode0FC: 1;                  /**< Bit  247     - Mode0FC. */
    615         RT_GCC_EXTENSION uint64_t  u8SnoopAttr: 1;                /**< Bits 255:248 - Snoop Attribute. */
    616     } n;
    617     /** The 32-bit unsigned integer view. */
    618     uint32_t        au32[8];
    619     /** The 64-bit unsigned integer view. */
    620     uint64_t        au64[4];
    621 } DTE_T;
    622 AssertCompileSize(DTE_T, 32);
    623 /** Pointer to a device table entry. */
    624 typedef DTE_T *PDTE_T;
    625 /** Pointer to a const device table entry. */
    626 typedef DTE_T const *PCDTE_T;
    627 
    628 /** Mask of valid  bits for EPHSUP (Enhanced Peripheral Page Request Handling
    629  *  Support) feature (bits 52:53). */
    630 #define IOMMU_DTE_QWORD_0_FEAT_EPHSUP_MASK      UINT64_C(0x0030000000000000)
    631 
    632 /** Mask of valid bits for GTSup (Guest Translation Support) feature (bits 55:60,
    633  *  bits 80:95). */
    634 #define IOMMU_DTE_QWORD_0_FEAT_GTSUP_MASK       UINT64_C(0x1f80000000000000)
    635 #define IOMMU_DTE_QWORD_1_FEAT_GTSUP_MASK       UINT64_C(0x00000000ffff0000)
    636 
    637 /* Mask of valid bits for GIoSup (Guest I/O Protection Support) feature (bit 54). */
    638 #define IOMMU_DTE_QWORD_0_FEAT_GIOSUP_MASK      UINT64_C(0x0040000000000000)
    639 
    640 /* Mask of valid DTE feature bits. */
    641 #define IOMMU_DTE_QWORD_0_FEAT_MASK             (  IOMMU_DTE_QWORD_0_FEAT_EPHSUP_MASK \
    642                                                  | IOMMU_DTE_QWORD_0_FEAT_GTSUP_MASK  \
    643                                                  | IOMMU_DTE_QWORD_0_FEAT_GIOSUP_MASK)
    644 #define IOMMU_DTE_QWORD_1_FEAT_MASK             (IOMMU_DTE_QWORD_0_FEAT_GIOSUP_MASK)
    645 
    646 /* Mask of all valid DTE bits (including all feature bits). */
    647 #define IOMMU_DTE_QWORD_0_VALID_MASK            UINT64_C(0x7fffffffffffff83)
    648 #define IOMMU_DTE_QWORD_1_VALID_MASK            UINT64_C(0xfffffbffffffffff)
    649 #define IOMMU_DTE_QWORD_2_VALID_MASK            UINT64_C(0xf70fffffffffffff)
    650 #define IOMMU_DTE_QWORD_3_VALID_MASK            UINT64_C(0xffc0000000000000)
    651 
    652 /* Mask of the interrupt table root pointer. */
    653 #define IOMMU_DTE_IRTE_ROOT_PTR_MASK            UINT64_C(0x000fffffffffff80)
    654 
    655 /**
    656  * I/O Page Translation Entry.
    657  * In accordance with the AMD spec.
    658  */
    659 typedef union
    660 {
    661     struct
    662     {
    663         RT_GCC_EXTENSION uint64_t    u1Present : 1;             /**< Bit  0      - PR: Present. */
    664         RT_GCC_EXTENSION uint64_t    u4Ign0 : 4;                /**< Bits 4:1    - Ignored. */
    665         RT_GCC_EXTENSION uint64_t    u1Accessed : 1;            /**< Bit  5      - A: Accessed. */
    666         RT_GCC_EXTENSION uint64_t    u1Dirty : 1;               /**< Bit  6      - D: Dirty. */
    667         RT_GCC_EXTENSION uint64_t    u2Ign0 : 2;                /**< Bits 8:7    - Ignored. */
    668         RT_GCC_EXTENSION uint64_t    u3NextLevel : 3;           /**< Bits 11:9   - Next Level: Next page translation level. */
    669         RT_GCC_EXTENSION uint64_t    u40PageAddr : 40;          /**< Bits 51:12  - Page address. */
    670         RT_GCC_EXTENSION uint64_t    u7Rsvd0 : 7;               /**< Bits 58:52  - Reserved. */
    671         RT_GCC_EXTENSION uint64_t    u1UntranslatedAccess : 1;  /**< Bit 59      - U: Untranslated Access Only. */
    672         RT_GCC_EXTENSION uint64_t    u1ForceCoherent : 1;       /**< Bit 60      - FC: Force Coherent. */
    673         RT_GCC_EXTENSION uint64_t    u1IoRead : 1;              /**< Bit 61      - IR: I/O Read permission. */
    674         RT_GCC_EXTENSION uint64_t    u1IoWrite : 1;             /**< Bit 62      - IW: I/O Wead permission. */
    675         RT_GCC_EXTENSION uint64_t    u1Ign0 : 1;                /**< Bit 63      - Ignored. */
    676     } n;
    677     /** The 64-bit unsigned integer view. */
    678     uint64_t        u64;
    679 } IOPTE_T;
    680 AssertCompileSize(IOPTE_T, 8);
    681 
    682 /**
    683  * I/O Page Directory Entry.
    684  * In accordance with the AMD spec.
    685  */
    686 typedef union
    687 {
    688     struct
    689     {
    690         RT_GCC_EXTENSION uint64_t    u1Present : 1;         /**< Bit  0      - PR: Present. */
    691         RT_GCC_EXTENSION uint64_t    u4Ign0 : 4;            /**< Bits 4:1    - Ignored. */
    692         RT_GCC_EXTENSION uint64_t    u1Accessed : 1;        /**< Bit  5      - A: Accessed. */
    693         RT_GCC_EXTENSION uint64_t    u3Ign0 : 3;            /**< Bits 8:6    - Ignored. */
    694         RT_GCC_EXTENSION uint64_t    u3NextLevel : 3;       /**< Bits 11:9   - Next Level: Next page translation level. */
    695         RT_GCC_EXTENSION uint64_t    u40PageAddr : 40;      /**< Bits 51:12  - Page address (Next Table Address). */
    696         RT_GCC_EXTENSION uint64_t    u9Rsvd0 : 9;           /**< Bits 60:52  - Reserved. */
    697         RT_GCC_EXTENSION uint64_t    u1IoRead : 1;          /**< Bit 61      - IR: I/O Read permission. */
    698         RT_GCC_EXTENSION uint64_t    u1IoWrite : 1;         /**< Bit 62      - IW: I/O Wead permission. */
    699         RT_GCC_EXTENSION uint64_t    u1Ign0 : 1;            /**< Bit 63      - Ignored. */
    700     } n;
    701     /** The 64-bit unsigned integer view. */
    702     uint64_t        u64;
    703 } IOPDE_T;
    704 AssertCompileSize(IOPDE_T, 8);
    705 
    706 /**
    707  * I/O Page Table Entity.
    708  * In accordance with the AMD spec.
    709  *
    710  * This a common subset of an DTE.au64[0], PTE and PDE.
    711  * Named as an "entity" to avoid confusing it with PTE.
    712  */
    713 typedef union
    714 {
    715     struct
    716     {
    717         RT_GCC_EXTENSION uint64_t    u1Present : 1;         /**< Bit  0      - PR: Present. */
    718         RT_GCC_EXTENSION uint64_t    u8Ign0 : 8;            /**< Bits 8:1    - Ignored. */
    719         RT_GCC_EXTENSION uint64_t    u3NextLevel : 3;       /**< Bits 11:9   - Mode / Next Level: Next page translation level. */
    720         RT_GCC_EXTENSION uint64_t    u40Addr : 40;          /**< Bits 51:12  - Page address. */
    721         RT_GCC_EXTENSION uint64_t    u9Ign0 : 9;            /**< Bits 60:52  - Ignored. */
    722         RT_GCC_EXTENSION uint64_t    u1IoRead : 1;          /**< Bit 61      - IR: I/O Read permission. */
    723         RT_GCC_EXTENSION uint64_t    u1IoWrite : 1;         /**< Bit 62      - IW: I/O Wead permission. */
    724         RT_GCC_EXTENSION uint64_t    u1Ign0 : 1;            /**< Bit 63      - Ignored. */
    725     } n;
    726     /** The 64-bit unsigned integer view. */
    727     uint64_t        u64;
    728 } IOPTENTITY_T;
    729 AssertCompileSize(IOPTENTITY_T, 8);
    730 AssertCompile(sizeof(IOPTENTITY_T) == sizeof(IOPTE_T));
    731 AssertCompile(sizeof(IOPTENTITY_T) == sizeof(IOPDE_T));
    732 /** Pointer to an IOPT_ENTITY_T struct. */
    733 typedef IOPTENTITY_T *PIOPTENTITY_T;
    734 /** Pointer to a const IOPT_ENTITY_T struct. */
    735 typedef IOPTENTITY_T const *PCIOPTENTITY_T;
    736 /** Mask of the address field. */
    737 #define IOMMU_PTENTITY_ADDR_MASK     UINT64_C(0x000ffffffffff000)
    738 
    739 /**
    740  * Interrupt Remapping Table Entry (IRTE).
    741  * In accordance with the AMD spec.
    742  */
    743 typedef union
    744 {
    745     struct
    746     {
    747         uint32_t    u1RemapEnable : 1;      /**< Bit  0     - RemapEn: Remap Enable. */
    748         uint32_t    u1SuppressPf : 1;       /**< Bit  1     - SupIOPF: Supress I/O Page Fault. */
    749         uint32_t    u3IntrType : 1;         /**< Bits 4:2   - IntType: Interrupt Type. */
    750         uint32_t    u1ReqEoi : 1;           /**< Bit  5     - RqEoi: Request EOI. */
    751         uint32_t    u1DestMode : 1;         /**< Bit  6     - DM: Destination Mode. */
    752         uint32_t    u1GuestMode : 1;        /**< Bit  7     - GuestMode. */
    753         uint32_t    u8Dest : 8;             /**< Bits 15:8  - Destination. */
    754         uint32_t    u8Vector : 8;           /**< Bits 23:16 - Vector. */
    755         uint32_t    u8Rsvd0 : 8;            /**< Bits 31:24 - Reserved. */
    756     } n;
    757     /** The 32-bit unsigned integer view. */
    758     uint32_t        u32;
    759 } IRTE_T;
    760 AssertCompileSize(IRTE_T, 4);
    761 /** The number of bits to shift the IRTE offset to get the IRTE. */
    762 #define IOMMU_IRTE_SIZE_SHIFT   (2)
    763 /** Pointer to an IRTE_T struct. */
    764 typedef IRTE_T *PIRTE_T;
    765 /** Pointer to a const IRTE_T struct. */
    766 typedef IRTE_T const *PCIRTE_T;
    767 
    768 /** The IRTE offset corresponds directly to bits 10:0 of the originating MSI
    769  *  interrupt message. See AMD IOMMU spec. 2.2.5 "Interrupt Remapping Tables". */
    770 #define IOMMU_MSI_DATA_IRTE_OFFSET_MASK     UINT32_C(0x000007ff)
    771 
    772 /**
    773  * Command: Generic Command Buffer Entry.
    774  * In accordance with the AMD spec.
    775  */
    776 typedef union
    777 {
    778     struct
    779     {
    780         uint32_t    u32Operand1Lo;          /**< Bits 31:0   - Operand 1 (Lo). */
    781         uint32_t    u32Operand1Hi : 28;     /**< Bits 59:32  - Operand 1 (Hi). */
    782         uint32_t    u4Opcode : 4;           /**< Bits 63:60  - Op Code. */
    783         uint64_t    u64Operand2;            /**< Bits 127:64 - Operand 2. */
    784     } n;
    785     /** The 64-bit unsigned integer view. */
    786     uint64_t    au64[2];
    787 } CMD_GENERIC_T;
    788 AssertCompileSize(CMD_GENERIC_T, 16);
    789 /** Pointer to a generic command buffer entry. */
    790 typedef CMD_GENERIC_T *PCMD_GENERIC_T;
    791 /** Pointer to a const generic command buffer entry. */
    792 typedef CMD_GENERIC_T const *PCCMD_GENERIC_T;
    793 
    794 /** Number of bits to shift the byte offset of a command in the command buffer to
    795  *  get its index. */
    796 #define IOMMU_CMD_GENERIC_SHIFT   4
    797 
    798 /**
    799  * Command: COMPLETION_WAIT.
    800  * In accordance with the AMD spec.
    801  */
    802 typedef union
    803 {
    804     struct
    805     {
    806         uint32_t    u1Store : 1;           /**< Bit  0      - S: Completion Store. */
    807         uint32_t    u1Interrupt : 1;       /**< Bit  1      - I: Completion Interrupt. */
    808         uint32_t    u1Flush : 1;           /**< Bit  2      - F: Flush Queue. */
    809         uint32_t    u29StoreAddrLo : 29;   /**< Bits 31:3   - Store Address (Lo). */
    810         uint32_t    u20StoreAddrHi : 20;   /**< Bits 51:32  - Store Address (Hi). */
    811         uint32_t    u8Rsvd0 : 8;           /**< Bits 59:52  - Reserved. */
    812         uint32_t    u4OpCode : 4;          /**< Bits 63:60  - OpCode (Command). */
    813         uint64_t    u64StoreData;          /**< Bits 127:64 - Store Data. */
    814     } n;
    815     /** The 64-bit unsigned integer view. */
    816     uint64_t    au64[2];
    817 } CMD_COMWAIT_T;
    818 AssertCompileSize(CMD_COMWAIT_T, 16);
    819 /** Pointer to a completion wait command. */
    820 typedef CMD_COMWAIT_T *PCMD_COMWAIT_T;
    821 /** Pointer to a const completion wait command. */
    822 typedef CMD_COMWAIT_T const *PCCMD_COMWAIT_T;
    823 #define IOMMU_CMD_COM_WAIT_QWORD_0_VALID_MASK        UINT64_C(0xf00fffffffffffff)
    824 
    825 /**
    826  * Command: INVALIDATE_DEVTAB_ENTRY.
    827  * In accordance with the AMD spec.
    828  */
    829 typedef union
    830 {
    831     struct
    832     {
    833         uint16_t                     u16DevId;          /**< Bits 15:0   - Device ID. */
    834         uint16_t                     u16Rsvd0;          /**< Bits 31:16  - Reserved. */
    835         uint32_t                     u28Rsvd0 : 28;     /**< Bits 59:32  - Reserved. */
    836         uint32_t                     u4OpCode : 4;      /**< Bits 63:60  - Op Code (Command). */
    837         uint64_t                     u64Rsvd0;          /**< Bits 127:64 - Reserved. */
    838     } n;
    839     /** The 64-bit unsigned integer view. */
    840     uint64_t    au64[2];
    841 } CMD_INV_DTE_T;
    842 AssertCompileSize(CMD_INV_DTE_T, 16);
    843 
    844 /**
    845  * Command: INVALIDATE_IOMMU_PAGES.
    846  * In accordance with the AMD spec.
    847  */
    848 typedef union
    849 {
    850     struct
    851     {
    852         uint32_t    u20Pasid : 20;          /**< Bits 19:0   - PASID: Process Address-Space ID. */
    853         uint32_t    u12Rsvd0 : 12;          /**< Bits 31:20  - Reserved. */
    854         uint32_t    u16DomainId : 16;       /**< Bits 47:32  - Domain ID. */
    855         uint32_t    u12Rsvd1 : 12;          /**< Bits 59:48  - Reserved. */
    856         uint32_t    u4OpCode : 4;           /**< Bits 63:60  - Op Code (Command). */
    857         uint32_t    u1Size : 1;             /**< Bit  64     - S: Size. */
    858         uint32_t    u1PageDirEntries : 1;   /**< Bit  65     - PDE: Page Directory Entries. */
    859         uint32_t    u1GuestOrNested : 1;    /**< Bit  66     - GN: Guest (GPA) or Nested (GVA). */
    860         uint32_t    u9Rsvd0 : 9;            /**< Bits 75:67  - Reserved. */
    861         uint32_t    u20AddrLo : 20;         /**< Bits 95:76  - Address (Lo). */
    862         uint32_t    u32AddrHi;              /**< Bits 127:96 - Address (Hi). */
    863     } n;
    864     /** The 64-bit unsigned integer view. */
    865     uint64_t    au64[2];
    866 } CMD_INV_IOMMU_PAGES_T;
    867 AssertCompileSize(CMD_INV_IOMMU_PAGES_T, 16);
    868 
    869 /**
    870  * Command: INVALIDATE_IOTLB_PAGES.
    871  * In accordance with the AMD spec.
    872  */
    873 typedef union
    874 {
    875     struct
    876     {
    877         uint16_t    u16DevId;               /**< Bits 15:0   - Device ID. */
    878         uint8_t     u8PasidLo;              /**< Bits 23:16  - PASID: Process Address-Space ID (Lo). */
    879         uint8_t     u8MaxPend;              /**< Bits 31:24  - Maxpend: Maximum simultaneous in-flight transactions. */
    880         uint32_t    u16QueueId : 16;        /**< Bits 47:32  - Queue ID. */
    881         uint32_t    u12PasidHi : 12;        /**< Bits 59:48  - PASID: Process Address-Space ID (Hi). */
    882         uint32_t    u4OpCode : 4;           /**< Bits 63:60  - Op Code (Command). */
    883         uint32_t    u1Size : 1;             /**< Bit  64     - S: Size. */
    884         uint32_t    u1Rsvd0: 1;             /**< Bit  65     - Reserved. */
    885         uint32_t    u1GuestOrNested : 1;    /**< Bit  66     - GN: Guest (GPA) or Nested (GVA). */
    886         uint32_t    u1Rsvd1 : 1;            /**< Bit  67     - Reserved. */
    887         uint32_t    u2Type : 2;             /**< Bit  69:68  - Type. */
    888         uint32_t    u6Rsvd0 : 6;            /**< Bits 75:70  - Reserved. */
    889         uint32_t    u20AddrLo : 20;         /**< Bits 95:76  - Address (Lo). */
    890         uint32_t    u32AddrHi;              /**< Bits 127:96 - Address (Hi). */
    891     } n;
    892     /** The 64-bit unsigned integer view. */
    893     uint64_t    au64[2];
    894 } CMD_INV_IOTLB_PAGES_T;
    895 AssertCompileSize(CMD_INV_IOTLB_PAGES_T, 16);
    896 
    897 /**
    898  * Command: INVALIDATE_INTR_TABLE.
    899  * In accordance with the AMD spec.
    900  */
    901 typedef union
    902 {
    903     struct
    904     {
    905         uint16_t    u16DevId;           /**< Bits 15:0   - Device ID. */
    906         uint16_t    u16Rsvd0;           /**< Bits 31:16  - Reserved. */
    907         uint32_t    u32Rsvd0 : 28;      /**< Bits 59:32  - Reserved. */
    908         uint32_t    u4OpCode : 4;       /**< Bits 63:60  - Op Code (Command). */
    909         uint64_t    u64Rsvd0;           /**< Bits 127:64 - Reserved. */
    910     } u;
    911     /** The 64-bit unsigned integer view. */
    912     uint64_t    au64[2];
    913 } CMD_INV_INTR_TABLE_T;
    914 AssertCompileSize(CMD_INV_INTR_TABLE_T, 16);
    915 
    916 /**
    917  * Command: COMPLETE_PPR_REQ.
    918  * In accordance with the AMD spec.
    919  */
    920 typedef union
    921 {
    922     struct
    923     {
    924         uint16_t    u16DevId;               /**< Bits 15:0    - Device ID. */
    925         uint16_t    u16Rsvd0;               /**< Bits 31:16   - Reserved. */
    926         uint32_t    u20Pasid : 20;          /**< Bits 51:32   - PASID: Process Address-Space ID. */
    927         uint32_t    u8Rsvd0 : 8;            /**< Bits 59:52   - Reserved. */
    928         uint32_t    u4OpCode : 4;           /**< Bits 63:60   - Op Code (Command). */
    929         uint32_t    u2Rsvd0 : 2;            /**< Bits 65:64   - Reserved. */
    930         uint32_t    u1GuestOrNested : 1;    /**< Bit  66      - GN: Guest (GPA) or Nested (GVA). */
    931         uint32_t    u29Rsvd0 : 29;          /**< Bits 95:67   - Reserved. */
    932         uint32_t    u16CompletionTag : 16;  /**< Bits 111:96  - Completion Tag. */
    933         uint32_t    u16Rsvd1 : 16;          /**< Bits 127:112 - Reserved. */
    934     } n;
    935     /** The 64-bit unsigned integer view. */
    936     uint64_t    au64[2];
    937 } CMD_COMPLETE_PPR_REQ_T;
    938 AssertCompileSize(CMD_COMPLETE_PPR_REQ_T, 16);
    939 
    940 /**
    941  * Command: INV_IOMMU_ALL.
    942  * In accordance with the AMD spec.
    943  */
    944 typedef union
    945 {
    946     struct
    947     {
    948         uint32_t    u32Rsvd0;           /**< Bits 31:0   - Reserved. */
    949         uint32_t    u28Rsvd0 : 28;      /**< Bits 59:32  - Reserved. */
    950         uint32_t    u4OpCode : 4;       /**< Bits 63:60  - Op Code (Command). */
    951         uint64_t    u64Rsvd0;           /**< Bits 127:64 - Reserved. */
    952     } n;
    953     /** The 64-bit unsigned integer view. */
    954     uint64_t    au64[2];
    955 } CMD_IOMMU_ALL_T;
    956 AssertCompileSize(CMD_IOMMU_ALL_T, 16);
    957 
    958 /**
    959  * Event Log Entry: Generic.
    960  * In accordance with the AMD spec.
    961  */
    962 typedef union
    963 {
    964     struct
    965     {
    966         uint32_t    u32Operand1Lo;          /**< Bits 31:0   - Operand 1 (Lo). */
    967         uint32_t    u32Operand1Hi : 28;     /**< Bits 59:32  - Operand 1 (Hi). */
    968         uint32_t    u4EvtCode : 4;          /**< Bits 63:60  - Event code. */
    969         uint32_t    u32Operand2Lo;          /**< Bits 95:64  - Operand 2 (Lo). */
    970         uint32_t    u32Operand2Hi;          /**< Bits 127:96 - Operand 2 (Hi). */
    971     } n;
    972     /** The 32-bit unsigned integer view.  */
    973     uint32_t    au32[4];
    974 } EVT_GENERIC_T;
    975 AssertCompileSize(EVT_GENERIC_T, 16);
    976 /** Number of bits to shift the byte offset of an event entry in the event log
    977  *  buffer to get its index. */
    978 #define IOMMU_EVT_GENERIC_SHIFT   4
    979 /** Pointer to a generic event log entry. */
    980 typedef EVT_GENERIC_T *PEVT_GENERIC_T;
    981 /** Pointer to a const generic event log entry. */
    982 typedef const EVT_GENERIC_T *PCEVT_GENERIC_T;
    983 
    984 /**
    985  * Hardware event types.
    986  * In accordance with the AMD spec.
    987  */
    988 typedef enum HWEVTTYPE
    989 {
    990     HWEVTTYPE_RSVD = 0,
    991     HWEVTTYPE_MASTER_ABORT,
    992     HWEVTTYPE_TARGET_ABORT,
    993     HWEVTTYPE_DATA_ERROR
    994 } HWEVTTYPE;
    995 AssertCompileSize(HWEVTTYPE, 4);
    996 
    997 /**
    998  * Event Log Entry: ILLEGAL_DEV_TABLE_ENTRY.
    999  * In accordance with the AMD spec.
    1000  */
    1001 typedef union
    1002 {
    1003     struct
    1004     {
    1005         uint16_t    u16DevId;               /**< Bits 15:0   - Device ID. */
    1006         uint16_t    u4PasidHi : 4;          /**< Bits 19:16  - PASID: Process Address-Space ID (Hi). */
    1007         uint16_t    u12Rsvd0 : 12;          /**< Bits 31:20  - Reserved. */
    1008         uint16_t    u16PasidLo;             /**< Bits 47:32  - PASID: Process Address-Space ID (Lo). */
    1009         uint16_t    u1GuestOrNested : 1;    /**< Bit  48     - GN: Guest (GPA) or Nested (GVA). */
    1010         uint16_t    u2Rsvd0 : 2;            /**< Bits 50:49  - Reserved. */
    1011         uint16_t    u1Interrupt : 1;        /**< Bit  51     - I: Interrupt. */
    1012         uint16_t    u1Rsvd0 : 1;            /**< Bit  52     - Reserved. */
    1013         uint16_t    u1ReadWrite : 1;        /**< Bit  53     - RW: Read/Write. */
    1014         uint16_t    u1Rsvd1 : 1;            /**< Bit  54     - Reserved. */
    1015         uint16_t    u1RsvdNotZero : 1;      /**< Bit  55     - RZ: Reserved bit not Zero (0=invalid level encoding). */
    1016         uint16_t    u1Translation : 1;      /**< Bit  56     - TN: Translation. */
    1017         uint16_t    u3Rsvd0 : 3;            /**< Bits 59:57  - Reserved. */
    1018         uint16_t    u4EvtCode : 4;          /**< Bits 63:60  - Event code. */
    1019         uint64_t    u64Addr;                /**< Bits 127:64 - Address: I/O Virtual Address (IOVA). */
    1020     } n;
    1021     /** The 32-bit unsigned integer view.  */
    1022     uint32_t    au32[4];
    1023     /** The 64-bit unsigned integer view. */
    1024     uint64_t    au64[2];
    1025 } EVT_ILLEGAL_DTE_T;
    1026 AssertCompileSize(EVT_ILLEGAL_DTE_T, 16);
    1027 /** Pointer to an illegal device table entry event. */
    1028 typedef EVT_ILLEGAL_DTE_T *PEVT_ILLEGAL_DTE_T;
    1029 /** Pointer to a const illegal device table entry event. */
    1030 typedef EVT_ILLEGAL_DTE_T const *PCEVT_ILLEGAL_DTE_T;
    1031 
    1032 /**
    1033  * Event Log Entry: IO_PAGE_FAULT_EVENT.
    1034  * In accordance with the AMD spec.
    1035  */
    1036 typedef union
    1037 {
    1038     struct
    1039     {
    1040         uint16_t    u16DevId;               /**< Bits 15:0   - Device ID. */
    1041         uint16_t    u4PasidHi : 4;          /**< Bits 19:16  - PASID: Process Address-Space ID (Hi). */
    1042         uint16_t    u16DomainOrPasidLo;     /**< Bits 47:32  - D/P: Domain ID or Process Address-Space ID (Lo). */
    1043         uint16_t    u1GuestOrNested : 1;    /**< Bit  48     - GN: Guest (GPA) or Nested (GVA). */
    1044         uint16_t    u1NoExecute : 1;        /**< Bit  49     - NX: No Execute. */
    1045         uint16_t    u1User : 1;             /**< Bit  50     - US: User/Supervisor. */
    1046         uint16_t    u1Interrupt : 1;        /**< Bit  51     - I: Interrupt. */
    1047         uint16_t    u1Present : 1;          /**< Bit  52     - PR: Present. */
    1048         uint16_t    u1ReadWrite : 1;        /**< Bit  53     - RW: Read/Write. */
    1049         uint16_t    u1PermDenied : 1;       /**< Bit  54     - PE: Permission Indicator. */
    1050         uint16_t    u1RsvdNotZero : 1;      /**< Bit  55     - RZ: Reserved bit not Zero (0=invalid level encoding). */
    1051         uint16_t    u1Translation : 1;      /**< Bit  56     - TN: Translation. */
    1052         uint16_t    u3Rsvd0 : 3;            /**< Bit  59:57  - Reserved. */
    1053         uint16_t    u4EvtCode : 4;          /**< Bits 63:60  - Event code. */
    1054         uint64_t    u64Addr;                /**< Bits 127:64 - Address: I/O Virtual Address (IOVA). */
    1055     } n;
    1056     /** The 32-bit unsigned integer view.  */
    1057     uint32_t    au32[4];
    1058     /** The 64-bit unsigned integer view. */
    1059     uint64_t    au64[2];
    1060 } EVT_IO_PAGE_FAULT_T;
    1061 AssertCompileSize(EVT_IO_PAGE_FAULT_T, 16);
    1062 /** Pointer to an I/O page fault event. */
    1063 typedef EVT_IO_PAGE_FAULT_T *PEVT_IO_PAGE_FAULT_T;
    1064 /** Pointer to a const I/O page fault event. */
    1065 typedef EVT_IO_PAGE_FAULT_T const *PCEVT_IO_PAGE_FAULT_T;
    1066 
    1067 
    1068 /**
    1069  * Event Log Entry: DEV_TAB_HARDWARE_ERROR.
    1070  * In accordance with the AMD spec.
    1071  */
    1072 typedef union
    1073 {
    1074     struct
    1075     {
    1076         uint16_t    u16DevId;               /**< Bits 15:0   - Device ID. */
    1077         uint16_t    u16Rsvd0;               /**< Bits 31:16  - Reserved. */
    1078         uint32_t    u19Rsvd0 : 19;          /**< Bits 50:32  - Reserved. */
    1079         uint32_t    u1Intr : 1;             /**< Bit  51     - I: Interrupt (1=interrupt request, 0=memory request). */
    1080         uint32_t    u1Rsvd0 : 1;            /**< Bit  52     - Reserved. */
    1081         uint32_t    u1ReadWrite : 1;        /**< Bit  53     - RW: Read/Write transaction (only meaninful when I=0 and TR=0). */
    1082         uint32_t    u2Rsvd0 : 2;            /**< Bits 55:54  - Reserved. */
    1083         uint32_t    u1Translation : 1;      /**< Bit  56     - TR: Translation (1=translation, 0=transaction). */
    1084         uint32_t    u2Type : 2;             /**< Bits 58:57  - Type: The type of hardware error. */
    1085         uint32_t    u1Rsvd1 : 1;            /**< Bit  59     - Reserved. */
    1086         uint32_t    u4EvtCode : 4;          /**< Bits 63:60  - Event code. */
    1087         uint64_t    u64Addr;                /**< Bits 127:64 - Address. */
    1088     } n;
    1089     /** The 32-bit unsigned integer view.  */
    1090     uint32_t    au32[4];
    1091     /** The 64-bit unsigned integer view. */
    1092     uint64_t    au64[2];
    1093 } EVT_DEV_TAB_HW_ERROR_T;
    1094 AssertCompileSize(EVT_DEV_TAB_HW_ERROR_T, 16);
    1095 /** Pointer to a device table hardware error event. */
    1096 typedef EVT_DEV_TAB_HW_ERROR_T *PEVT_DEV_TAB_HW_ERROR_T;
    1097 /** Pointer to a const device table hardware error event. */
    1098 typedef EVT_DEV_TAB_HW_ERROR_T const *PCEVT_DEV_TAB_HW_ERROR_T;
    1099 
    1100 /**
    1101  * Event Log Entry: EVT_PAGE_TAB_HARDWARE_ERROR.
    1102  * In accordance with the AMD spec.
    1103  */
    1104 typedef union
    1105 {
    1106     struct
    1107     {
    1108         uint16_t    u16DevId;                   /**< Bits 15:0   - Device ID. */
    1109         uint16_t    u16Rsvd0;                   /**< Bits 31:16  - Reserved. */
    1110         uint32_t    u16DomainOrPasidLo : 16;    /**< Bits 47:32  - D/P: Domain ID or Process Address-Space ID (Lo). */
    1111         uint32_t    u1GuestOrNested : 1;        /**< Bit  48     - GN: Guest (GPA) or Nested (GVA). */
    1112         uint32_t    u2Rsvd0 : 2;                /**< Bits 50:49  - Reserved. */
    1113         uint32_t    u1Interrupt : 1;            /**< Bit  51     - I: Interrupt. */
    1114         uint32_t    u1Rsvd0 : 1;                /**< Bit  52     - Reserved. */
    1115         uint32_t    u1ReadWrite : 1;            /**< Bit  53     - RW: Read/Write. */
    1116         uint32_t    u2Rsvd1 : 2;                /**< Bit  55:54  - Reserved. */
    1117         uint32_t    u1Translation : 1;          /**< Bit  56     - TR: Translation. */
    1118         uint32_t    u2Type : 2;                 /**< Bits 58:57  - Type: The type of hardware error. */
    1119         uint32_t    u1Rsvd1 : 1;                /**< Bit  59     - Reserved. */
    1120         uint32_t    u4EvtCode : 4;              /**< Bit  63:60  - Event code. */
    1121         /** @todo r=ramshankar: Figure 55: PAGE_TAB_HARDWARE_ERROR says Addr[31:3] but
    1122          *        table 58 mentions Addr[31:4], we just use the full 64-bits. Looks like a
    1123          *        typo in the figure.See AMD AMD IOMMU spec (3.05-PUB, Jan 2020). */
    1124         uint64_t    u64Addr;                    /** Bits 127:64  - Address: SPA of the page table entry. */
    1125     } n;
    1126     /** The 32-bit unsigned integer view. */
    1127     uint32_t    au32[4];
    1128     /** The 64-bit unsigned integer view. */
    1129     uint64_t    au64[2];
    1130 } EVT_PAGE_TAB_HW_ERR_T;
    1131 AssertCompileSize(EVT_PAGE_TAB_HW_ERR_T, 16);
    1132 /** Pointer to a page table hardware error event. */
    1133 typedef EVT_PAGE_TAB_HW_ERR_T *PEVT_PAGE_TAB_HW_ERR_T;
    1134 /** Pointer to a const page table hardware error event. */
    1135 typedef EVT_PAGE_TAB_HW_ERR_T const *PCEVT_PAGE_TAB_HW_ERR_T;
    1136 
    1137 /**
    1138  * Event Log Entry: ILLEGAL_COMMAND_ERROR.
    1139  * In accordance with the AMD spec.
    1140  */
    1141 typedef union
    1142 {
    1143     struct
    1144     {
    1145         uint32_t    u32Rsvd0;           /**< Bits 31:0   - Reserved. */
    1146         uint32_t    u28Rsvd0 : 28;      /**< Bits 47:32  - Reserved. */
    1147         uint32_t    u4EvtCode : 4;      /**< Bits 63:60  - Event code. */
    1148         uint64_t    u64Addr;            /**< Bits 127:64 - Address: SPA of the invalid command. */
    1149     } n;
    1150     /** The 32-bit unsigned integer view. */
    1151     uint32_t    au32[4];
    1152     /** The 64-bit unsigned integer view. */
    1153     uint64_t    au64[2];
    1154 } EVT_ILLEGAL_CMD_ERR_T;
    1155 AssertCompileSize(EVT_ILLEGAL_CMD_ERR_T, 16);
    1156 /** Pointer to an illegal command error event. */
    1157 typedef EVT_ILLEGAL_CMD_ERR_T *PEVT_ILLEGAL_CMD_ERR_T;
    1158 /** Pointer to a const illegal command error event. */
    1159 typedef EVT_ILLEGAL_CMD_ERR_T const *PCEVT_ILLEGAL_CMD_ERR_T;
    1160 
    1161 /**
    1162  * Event Log Entry: COMMAND_HARDWARE_ERROR.
    1163  * In accordance with the AMD spec.
    1164  */
    1165 typedef union
    1166 {
    1167     struct
    1168     {
    1169         uint32_t    u32Rsvd0;           /**< Bits 31:0   - Reserved. */
    1170         uint32_t    u25Rsvd1 : 25;      /**< Bits 56:32  - Reserved. */
    1171         uint32_t    u2Type : 2;         /**< Bits 58:57  - Type: The type of hardware error. */
    1172         uint32_t    u1Rsvd1 : 1;        /**< Bit  59     - Reserved. */
    1173         uint32_t    u4EvtCode : 4;      /**< Bits 63:60  - Event code. */
    1174         uint64_t    u64Addr;            /**< Bits 128:64 - Address: SPA of the attempted access. */
    1175     } n;
    1176     /** The 32-bit unsigned integer view. */
    1177     uint32_t    au32[4];
    1178     /** The 64-bit unsigned integer view. */
    1179     uint64_t    au64[2];
    1180 } EVT_CMD_HW_ERR_T;
    1181 AssertCompileSize(EVT_CMD_HW_ERR_T, 16);
    1182 /** Pointer to a command hardware error event. */
    1183 typedef EVT_CMD_HW_ERR_T *PEVT_CMD_HW_ERR_T;
    1184 /** Pointer to a const command hardware error event. */
    1185 typedef EVT_CMD_HW_ERR_T const *PCEVT_CMD_HW_ERR_T;
    1186 
    1187 /**
    1188  * Event Log Entry: IOTLB_INV_TIMEOUT.
    1189  * In accordance with the AMD spec.
    1190  */
    1191 typedef union
    1192 {
    1193     struct
    1194     {
    1195         uint16_t    u16DevId;           /**< Bits 15:0   - Device ID. */
    1196         uint16_t    u16Rsvd0;           /**< Bits 31:16  - Reserved.*/
    1197         uint32_t    u28Rsvd0 : 28;      /**< Bits 59:32  - Reserved. */
    1198         uint32_t    u4EvtCode : 4;      /**< Bits 63:60  - Event code. */
    1199         uint32_t    u4Rsvd0 : 4;        /**< Bits 67:64  - Reserved. */
    1200         uint32_t    u28AddrLo : 28;     /**< Bits 95:68  - Address: SPA of the invalidation command that timedout (Lo). */
    1201         uint32_t    u32AddrHi;          /**< Bits 127:96 - Address: SPA of the invalidation command that timedout (Hi). */
    1202     } n;
    1203     /** The 32-bit unsigned integer view. */
    1204     uint32_t    au32[4];
    1205 } EVT_IOTLB_INV_TIMEOUT_T;
    1206 AssertCompileSize(EVT_IOTLB_INV_TIMEOUT_T, 16);
    1207 
    1208 /**
    1209  * Event Log Entry: INVALID_DEVICE_REQUEST.
    1210  * In accordance with the AMD spec.
    1211  */
    1212 typedef union
    1213 {
    1214     struct
    1215     {
    1216         uint32_t    u16DevId : 16;          /***< Bits 15:0   - Device ID. */
    1217         uint32_t    u4PasidHi : 4;          /***< Bits 19:16  - PASID: Process Address-Space ID (Hi). */
    1218         uint32_t    u12Rsvd0 : 12;          /***< Bits 31:20  - Reserved. */
    1219         uint32_t    u16PasidLo : 16;        /***< Bits 47:32  - PASID: Process Address-Space ID (Lo). */
    1220         uint32_t    u1GuestOrNested : 1;    /***< Bit  48     - GN: Guest (GPA) or Nested (GVA). */
    1221         uint32_t    u1User : 1;             /***< Bit  49     - US: User/Supervisor. */
    1222         uint32_t    u6Rsvd0 : 6;            /***< Bits 55:50  - Reserved. */
    1223         uint32_t    u1Translation: 1;       /***< Bit  56     - TR: Translation. */
    1224         uint32_t    u3Type: 3;              /***< Bits 59:57  - Type: The type of hardware error. */
    1225         uint32_t    u4EvtCode : 4;          /***< Bits 63:60  - Event code. */
    1226         uint64_t    u64Addr;                /***< Bits 127:64 - Address: Translation or access address. */
    1227     } n;
    1228     /** The 32-bit unsigned integer view. */
    1229     uint32_t    au32[4];
    1230 } EVT_INVALID_DEV_REQ_T;
    1231 AssertCompileSize(EVT_INVALID_DEV_REQ_T, 16);
    1232 
    1233 /**
    1234  * Event Log Entry: EVENT_COUNTER_ZERO.
    1235  * In accordance with the AMD spec.
    1236  */
    1237 typedef union
    1238 {
    1239     struct
    1240     {
    1241         uint32_t    u32Rsvd0;               /**< Bits 31:0   - Reserved. */
    1242         uint32_t    u28Rsvd0 : 28;          /**< Bits 59:32  - Reserved. */
    1243         uint32_t    u4EvtCode : 4;          /**< Bits 63:60  - Event code. */
    1244         uint32_t    u20CounterNoteHi : 20;  /**< Bits 83:64  - CounterNote: Counter value for the event counter register (Hi). */
    1245         uint32_t    u12Rsvd0 : 12;          /**< Bits 95:84  - Reserved. */
    1246         uint32_t    u32CounterNoteLo;       /**< Bits 127:96 - CounterNote: Counter value for the event cuonter register (Lo). */
    1247     } n;
    1248     /** The 32-bit unsigned integer view. */
    1249     uint32_t    au32[4];
    1250 } EVT_EVENT_COUNTER_ZERO_T;
    1251 AssertCompileSize(EVT_EVENT_COUNTER_ZERO_T, 16);
    1252 
    1253 /**
    1254  * IOMMU Capability Header (PCI).
    1255  * In accordance with the AMD spec.
    1256  */
    1257 typedef union
    1258 {
    1259     struct
    1260     {
    1261         uint32_t    u8CapId : 8;        /**< Bits 7:0   - CapId: Capability ID. */
    1262         uint32_t    u8CapPtr : 8;       /**< Bits 15:8  - CapPtr: Pointer (PCI config offset) to the next capability. */
    1263         uint32_t    u3CapType : 3;      /**< Bits 18:16 - CapType: Capability Type. */
    1264         uint32_t    u5CapRev : 5;       /**< Bits 23:19 - CapRev: Capability revision. */
    1265         uint32_t    u1IoTlbSup : 1;     /**< Bit  24    - IotlbSup: IOTLB Support. */
    1266         uint32_t    u1HtTunnel : 1;     /**< Bit  25    - HtTunnel: HyperTransport Tunnel translation support. */
    1267         uint32_t    u1NpCache : 1;      /**< Bit  26    - NpCache: Not Present table entries are cached. */
    1268         uint32_t    u1EfrSup : 1;       /**< Bit  27    - EFRSup: Extended Feature Register Support. */
    1269         uint32_t    u1CapExt : 1;       /**< Bit  28    - CapExt: Misc. Information Register 1 Support. */
    1270         uint32_t    u3Rsvd0 : 3;        /**< Bits 31:29 - Reserved. */
    1271     } n;
    1272     /** The 32-bit unsigned integer view. */
    1273     uint32_t    u32;
    1274 } IOMMU_CAP_HDR_T;
    1275 AssertCompileSize(IOMMU_CAP_HDR_T, 4);
    1276 
    1277 /**
    1278  * IOMMU Base Address (Lo and Hi) Register (PCI).
    1279  * In accordance with the AMD spec.
    1280  */
    1281 typedef union
    1282 {
    1283     struct
    1284     {
    1285         uint32_t   u1Enable : 1;       /**< Bit  1     - Enable: RW1S - Enable IOMMU MMIO region. */
    1286         uint32_t   u12Rsvd0 : 12;      /**< Bits 13:1  - Reserved. */
    1287         uint32_t   u18BaseAddrLo : 18; /**< Bits 31:14 - Base address (Lo) of the MMIO region. */
    1288         uint32_t   u32BaseAddrHi;      /**< Bits 63:32 - Base address (Hi) of the MMIO region. */
    1289     } n;
    1290     /** The 32-bit unsigned integer view. */
    1291     uint32_t    au32[2];
    1292     /** The 64-bit unsigned integer view. */
    1293     uint64_t    u64;
    1294 } IOMMU_BAR_T;
    1295 AssertCompileSize(IOMMU_BAR_T, 8);
    1296 #define IOMMU_BAR_VALID_MASK        UINT64_C(0xffffffffffffc001)
    1297 
    1298 /**
    1299  * IOMMU Range Register (PCI).
    1300  * In accordance with the AMD spec.
    1301  */
    1302 typedef union
    1303 {
    1304     struct
    1305     {
    1306         uint32_t    u5HtUnitId : 5;     /**< Bits 4:0   - UnitID: IOMMU HyperTransport Unit ID (not used). */
    1307         uint32_t    u2Rsvd0 : 2;        /**< Bits 6:5   - Reserved. */
    1308         uint32_t    u1RangeValid : 1;   /**< Bit  7     - RngValid: Range Valid. */
    1309         uint32_t    u8Bus : 8;          /**< Bits 15:8  - BusNumber: Bus number of the first and last device. */
    1310         uint32_t    u8FirstDevice : 8;  /**< Bits 23:16 - FirstDevice: Device and function number of the first device. */
    1311         uint32_t    u8LastDevice: 8;    /**< Bits 31:24 - LastDevice: Device and function number of the last device. */
    1312     } n;
    1313     /** The 32-bit unsigned integer view. */
    1314     uint32_t    u32;
    1315 } IOMMU_RANGE_T;
    1316 AssertCompileSize(IOMMU_RANGE_T, 4);
    1317 
    1318 /**
    1319  * Device Table Base Address Register (MMIO).
    1320  * In accordance with the AMD spec.
    1321  */
    1322 typedef union
    1323 {
    1324     struct
    1325     {
    1326         RT_GCC_EXTENSION uint64_t   u9Size : 9;     /**< Bits 8:0   - Size: Size of the device table. */
    1327         RT_GCC_EXTENSION uint64_t   u3Rsvd0 : 3;    /**< Bits 11:9  - Reserved. */
    1328         RT_GCC_EXTENSION uint64_t   u40Base : 40;   /**< Bits 51:12 - DevTabBase: Device table base address. */
    1329         RT_GCC_EXTENSION uint64_t   u12Rsvd0 : 12;  /**< Bits 63:52 - Reserved. */
    1330     } n;
    1331     /** The 64-bit unsigned integer view. */
    1332     uint64_t    u64;
    1333 } DEV_TAB_BAR_T;
    1334 AssertCompileSize(DEV_TAB_BAR_T, 8);
    1335 #define IOMMU_DEV_TAB_BAR_VALID_MASK          UINT64_C(0x000ffffffffff1ff)
    1336 #define IOMMU_DEV_TAB_SEG_BAR_VALID_MASK      UINT64_C(0x000ffffffffff0ff)
    1337 
    1338 /**
    1339  * Command Buffer Base Address Register (MMIO).
    1340  * In accordance with the AMD spec.
    1341  */
    1342 typedef union
    1343 {
    1344     struct
    1345     {
    1346         RT_GCC_EXTENSION uint64_t   u12Rsvd0 : 12;      /**< Bits 11:0  - Reserved. */
    1347         RT_GCC_EXTENSION uint64_t   u40Base : 40;       /**< Bits 51:12 - ComBase: Command buffer base address. */
    1348         RT_GCC_EXTENSION uint64_t   u4Rsvd0 : 4;        /**< Bits 55:52 - Reserved. */
    1349         RT_GCC_EXTENSION uint64_t   u4Len : 4;          /**< Bits 59:56 - ComLen: Command buffer length. */
    1350         RT_GCC_EXTENSION uint64_t   u4Rsvd1 : 4;        /**< Bits 63:60 - Reserved. */
    1351     } n;
    1352     /** The 64-bit unsigned integer view. */
    1353     uint64_t    u64;
    1354 } CMD_BUF_BAR_T;
    1355 AssertCompileSize(CMD_BUF_BAR_T, 8);
    1356 #define IOMMU_CMD_BUF_BAR_VALID_MASK      UINT64_C(0x0f0ffffffffff000)
    1357 
    1358 /**
    1359  * Event Log Base Address Register (MMIO).
    1360  * In accordance with the AMD spec.
    1361  */
    1362 typedef union
    1363 {
    1364     struct
    1365     {
    1366         RT_GCC_EXTENSION uint64_t   u12Rsvd0 : 12;      /**< Bits 11:0  - Reserved. */
    1367         RT_GCC_EXTENSION uint64_t   u40Base : 40;       /**< Bits 51:12 - EventBase: Event log base address. */
    1368         RT_GCC_EXTENSION uint64_t   u4Rsvd0 : 4;        /**< Bits 55:52 - Reserved. */
    1369         RT_GCC_EXTENSION uint64_t   u4Len : 4;          /**< Bits 59:56 - EventLen: Event log length. */
    1370         RT_GCC_EXTENSION uint64_t   u4Rsvd1 : 4;        /**< Bits 63:60 - Reserved. */
    1371     } n;
    1372     /** The 64-bit unsigned integer view. */
    1373     uint64_t    u64;
    1374 } EVT_LOG_BAR_T;
    1375 AssertCompileSize(EVT_LOG_BAR_T, 8);
    1376 #define IOMMU_EVT_LOG_BAR_VALID_MASK      UINT64_C(0x0f0ffffffffff000)
    1377 
    1378 /**
    1379  * IOMMU Control Register (MMIO).
    1380  * In accordance with the AMD spec.
    1381  */
    1382 typedef union
    1383 {
    1384     struct
    1385     {
    1386         uint32_t    u1IommuEn : 1;               /**< Bit  0     - IommuEn: IOMMU Enable. */
    1387         uint32_t    u1HtTunEn : 1;               /**< Bit  1     - HtTunEn: HyperTransport Tunnel Enable. */
    1388         uint32_t    u1EvtLogEn : 1;              /**< Bit  2     - EventLogEn: Event Log Enable. */
    1389         uint32_t    u1EvtIntrEn : 1;             /**< Bit  3     - EventIntEn: Event Log Interrupt Enable. */
    1390         uint32_t    u1CompWaitIntrEn : 1;        /**< Bit  4     - ComWaitIntEn: Completion Wait Interrupt Enable. */
    1391         uint32_t    u3InvTimeOut : 3;            /**< Bits 7:5   - InvTimeOut: Invalidation Timeout. */
    1392         uint32_t    u1PassPW : 1;                /**< Bit  8     - PassPW: Pass Posted Write. */
    1393         uint32_t    u1ResPassPW : 1;             /**< Bit  9     - ResPassPW: Response Pass Posted Write. */
    1394         uint32_t    u1Coherent : 1;              /**< Bit  10    - Coherent: HT read request packet Coherent bit. */
    1395         uint32_t    u1Isoc : 1;                  /**< Bit  11    - Isoc: HT read request packet Isochronous bit. */
    1396         uint32_t    u1CmdBufEn : 1;              /**< Bit  12    - CmdBufEn: Command Buffer Enable. */
    1397         uint32_t    u1PprLogEn : 1;              /**< Bit  13    - PprLogEn: Peripheral Page Request (PPR) Log Enable. */
    1398         uint32_t    u1PprIntrEn : 1;             /**< Bit  14    - PprIntrEn: Peripheral Page Request Interrupt Enable. */
    1399         uint32_t    u1PprEn : 1;                 /**< Bit  15    - PprEn: Peripheral Page Request processing Enable. */
    1400         uint32_t    u1GstTranslateEn : 1;        /**< Bit  16    - GTEn: Guest Translate Enable. */
    1401         uint32_t    u1GstVirtApicEn : 1;         /**< Bit  17    - GAEn: Guest Virtual-APIC Enable. */
    1402         uint32_t    u4Crw : 1;                   /**< Bits 21:18 - CRW: Intended for future use (not documented). */
    1403         uint32_t    u1SmiFilterEn : 1;           /**< Bit  22    - SmiFEn: SMI Filter Enable. */
    1404         uint32_t    u1SelfWriteBackDis : 1;      /**< Bit  23    - SlfWBDis: Self Write-Back Disable. */
    1405         uint32_t    u1SmiFilterLogEn : 1;        /**< Bit  24    - SmiFLogEn: SMI Filter Log Enable. */
    1406         uint32_t    u3GstVirtApicModeEn : 3;     /**< Bits 27:25 - GAMEn: Guest Virtual-APIC Mode Enable. */
    1407         uint32_t    u1GstLogEn : 1;              /**< Bit  28    - GALogEn: Guest Virtual-APIC GA Log Enable. */
    1408         uint32_t    u1GstIntrEn : 1;             /**< Bit  29    - GAIntEn: Guest Virtual-APIC Interrupt Enable. */
    1409         uint32_t    u2DualPprLogEn : 2;          /**< Bits 31:30 - DualPprLogEn: Dual Peripheral Page Request Log Enable. */
    1410         uint32_t    u2DualEvtLogEn : 2;          /**< Bits 33:32 - DualEventLogEn: Dual Event Log Enable. */
    1411         uint32_t    u3DevTabSegEn : 3;           /**< Bits 36:34 - DevTblSegEn: Device Table Segment Enable. */
    1412         uint32_t    u2PrivAbortEn : 2;           /**< Bits 38:37 - PrivAbrtEn: Privilege Abort Enable. */
    1413         uint32_t    u1PprAutoRespEn : 1;         /**< Bit  39    - PprAutoRspEn: Peripheral Page Request Auto Response Enable. */
    1414         uint32_t    u1MarcEn : 1;                /**< Bit  40    - MarcEn: Memory Address Routing and Control Enable. */
    1415         uint32_t    u1BlockStopMarkEn : 1;       /**< Bit  41    - BlkStopMarkEn: Block StopMark messages Enable. */
    1416         uint32_t    u1PprAutoRespAlwaysOnEn : 1; /**< Bit  42    - PprAutoRspAon:: PPR Auto Response - Always On Enable. */
    1417         uint32_t    u1DomainIDPNE : 1;           /**< Bit  43    - DomainIDPE: Reserved (not documented). */
    1418         uint32_t    u1Rsvd0 : 1;                 /**< Bit  44    - Reserved. */
    1419         uint32_t    u1EnhancedPpr : 1;           /**< Bit  45    - EPHEn: Enhanced Peripheral Page Request Handling Enable. */
    1420         uint32_t    u2HstAccDirtyBitUpdate : 2;  /**< Bits 47:46 - HADUpdate: Access and Dirty Bit updated in host page table. */
    1421         uint32_t    u1GstDirtyUpdateDis : 1;     /**< Bit  48    - GDUpdateDis: Disable hardare update of Dirty bit in GPT. */
    1422         uint32_t    u1Rsvd1 : 1;                 /**< Bit  49    - Reserved. */
    1423         uint32_t    u1X2ApicEn : 1;              /**< Bit  50    - XTEn: Enable X2APIC. */
    1424         uint32_t    u1X2ApicIntrGenEn : 1;       /**< Bit  51    - IntCapXTEn: Enable IOMMU X2APIC Interrupt generation. */
    1425         uint32_t    u2Rsvd0 : 2;                 /**< Bits 53:52 - Reserved. */
    1426         uint32_t    u1GstAccessUpdateDis : 1;    /**< Bit  54    - GAUpdateDis: Disable hardare update of Access bit in GPT. */
    1427         uint32_t    u8Rsvd0 : 8;                 /**< Bits 63:55 - Reserved. */
    1428     } n;
    1429     /** The 64-bit unsigned integer view. */
    1430     uint64_t    u64;
    1431 } IOMMU_CTRL_T;
    1432 AssertCompileSize(IOMMU_CTRL_T, 8);
    1433 #define IOMMU_CTRL_VALID_MASK           UINT64_C(0x004defffffffffff)
    1434 #define IOMMU_CTRL_CMD_BUF_EN_MASK      UINT64_C(0x0000000000001001)
    1435 
    1436 /**
    1437  * IOMMU Exclusion Base Register (MMIO).
    1438  * In accordance with the AMD spec.
    1439  */
    1440 typedef union
    1441 {
    1442     struct
    1443     {
    1444         RT_GCC_EXTENSION uint64_t   u1ExclEnable : 1;       /**< Bit 0      - ExEn: Exclusion Range Enable. */
    1445         RT_GCC_EXTENSION uint64_t   u1AllowAll : 1;         /**< Bit 1      - Allow: Allow All Devices. */
    1446         RT_GCC_EXTENSION uint64_t   u10Rsvd0 : 10;          /**< Bits 11:2  - Reserved. */
    1447         RT_GCC_EXTENSION uint64_t   u40ExclRangeBase : 40;  /**< Bits 51:12 - Exclusion Range Base Address. */
    1448         RT_GCC_EXTENSION uint64_t   u12Rsvd0 : 12;          /**< Bits 63:52 - Reserved. */
    1449     } n;
    1450     /** The 64-bit unsigned integer view. */
    1451     uint64_t    u64;
    1452 } IOMMU_EXCL_RANGE_BAR_T;
    1453 AssertCompileSize(IOMMU_EXCL_RANGE_BAR_T, 8);
    1454 #define IOMMU_EXCL_RANGE_BAR_VALID_MASK     UINT64_C(0x000ffffffffff003)
    1455 
    1456 /**
    1457  * IOMMU Exclusion Range Limit Register (MMIO).
    1458  * In accordance with the AMD spec.
    1459  */
    1460 typedef union
    1461 {
    1462     struct
    1463     {
    1464         RT_GCC_EXTENSION uint64_t   u52ExclLimit : 52;  /**< Bits 51:0 - Exclusion Range Limit (last 12 bits are treated as 1s). */
    1465         RT_GCC_EXTENSION uint64_t   u12Rsvd1 : 12;      /**< Bits 63:52 - Reserved. */
    1466     } n;
    1467     /** The 64-bit unsigned integer view. */
    1468     uint64_t    u64;
    1469 } IOMMU_EXCL_RANGE_LIMIT_T;
    1470 AssertCompileSize(IOMMU_EXCL_RANGE_LIMIT_T, 8);
    1471 #define IOMMU_EXCL_RANGE_LIMIT_VALID_MASK   UINT64_C(0x000fffffffffffff)
    1472 
    1473 /**
    1474  * IOMMU Extended Feature Register (MMIO).
    1475  * In accordance with the AMD spec.
    1476  */
    1477 typedef union
    1478 {
    1479     struct
    1480     {
    1481         uint32_t    u1PrefetchSup : 1;            /**< Bit  0     - PreFSup: Prefetch Support. */
    1482         uint32_t    u1PprSup : 1;                 /**< Bit  1     - PPRSup: Peripheral Page Request Support. */
    1483         uint32_t    u1X2ApicSup : 1;              /**< Bit  2     - XTSup: x2Apic Support. */
    1484         uint32_t    u1NoExecuteSup : 1;           /**< Bit  3     - NXSup: No-Execute and Privilege Level Support. */
    1485         uint32_t    u1GstTranslateSup : 1;        /**< Bit  4     - GTSup: Guest Translations (for GVAs) Support. */
    1486         uint32_t    u1Rsvd0 : 1;                  /**< Bit  5     - Reserved. */
    1487         uint32_t    u1InvAllSup : 1;              /**< Bit  6     - IASup: Invalidate-All Support. */
    1488         uint32_t    u1GstVirtApicSup : 1;         /**< Bit  7     - GASup: Guest Virtual-APIC Support. */
    1489         uint32_t    u1HwErrorSup : 1;             /**< Bit  8     - HESup: Hardware Error registers Support. */
    1490         uint32_t    u1PerfCounterSup : 1;         /**< Bit  8     - PCSup: Performance Counter Support. */
    1491         uint32_t    u2HostAddrTranslateSize : 2;  /**< Bits 11:10 - HATS: Host Address Translation Size. */
    1492         uint32_t    u2GstAddrTranslateSize : 2;   /**< Bits 13:12 - GATS: Guest Address Translation Size. */
    1493         uint32_t    u2GstCr3RootTblLevel : 2;     /**< Bits 15:14 - GLXSup: Guest CR3 Root Table Level (Max) Size Support. */
    1494         uint32_t    u2SmiFilterSup : 2;           /**< Bits 17:16 - SmiFSup: SMI Filter Register Support. */
    1495         uint32_t    u3SmiFilterCount : 3;         /**< Bits 20:18 - SmiFRC: SMI Filter Register Count. */
    1496         uint32_t    u3GstVirtApicModeSup : 3;     /**< Bits 23:21 - GAMSup: Guest Virtual-APIC Modes Supported. */
    1497         uint32_t    u2DualPprLogSup : 2;          /**< Bits 25:24 - DualPprLogSup: Dual Peripheral Page Request Log Support. */
    1498         uint32_t    u2Rsvd0 : 2;                  /**< Bits 27:26 - Reserved. */
    1499         uint32_t    u2DualEvtLogSup : 2;          /**< Bits 29:28 - DualEventLogSup: Dual Event Log Support. */
    1500         uint32_t    u2Rsvd1 : 2;                  /**< Bits 31:30 - Reserved. */
    1501         uint32_t    u5MaxPasidSup : 5;            /**< Bits 36:32 - PASMax: Maximum PASID Supported. */
    1502         uint32_t    u1UserSupervisorSup : 1;      /**< Bit  37    - USSup: User/Supervisor Page Protection Support. */
    1503         uint32_t    u2DevTabSegSup : 2;           /**< Bits 39:38 - DevTlbSegSup: Segmented Device Table Support. */
    1504         uint32_t    u1PprLogOverflowWarn : 1;     /**< Bit  40    - PprOvrflwEarlySup: PPR Log Overflow Early Warning Support. */
    1505         uint32_t    u1PprAutoRespSup : 1;         /**< Bit  41    - PprAutoRspSup: PPR Automatic Response Support. */
    1506         uint32_t    u2MarcSup : 2;                /**< Bit  43:42 - MarcSup: Memory Access Routing and Control Support. */
    1507         uint32_t    u1BlockStopMarkSup : 1;       /**< Bit  44    - BlkStopMarkSup: Block StopMark messages Support. */
    1508         uint32_t    u1PerfOptSup : 1;             /**< Bit  45    - PerfOptSup: IOMMU Performance Optimization Support. */
    1509         uint32_t    u1MsiCapMmioSup : 1;          /**< Bit  46    - MsiCapMmioSup: MSI Capability Register MMIO Access Support. */
    1510         uint32_t    u1Rsvd1 : 1;                  /**< Bit  47    - Reserved. */
    1511         uint32_t    u1GstIoSup : 1;               /**< Bit  48    - GIoSup: Guest I/O Protection Support. */
    1512         uint32_t    u1HostAccessSup : 1;          /**< Bit  49    - HASup: Host Access Support. */
    1513         uint32_t    u1EnhancedPprSup : 1;         /**< Bit  50    - EPHSup: Enhanced Peripheral Page Request Handling Support. */
    1514         uint32_t    u1AttrForwardSup : 1;         /**< Bit  51    - AttrFWSup: Attribute Forward Support. */
    1515         uint32_t    u1HostDirtySup : 1;           /**< Bit  52    - HDSup: Host Dirty Support. */
    1516         uint32_t    u1Rsvd2 : 1;                  /**< Bit  53    - Reserved. */
    1517         uint32_t    u1InvIoTlbTypeSup : 1;        /**< Bit  54    - InvIotlbTypeSup: Invalidate IOTLB Type Support. */
    1518         uint32_t    u6Rsvd0 : 6;                  /**< Bit  60:55 - Reserved. */
    1519         uint32_t    u1GstUpdateDisSup : 1;        /**< Bit  61    - GAUpdateDisSup: Disable hardware update on GPT Support. */
    1520         uint32_t    u1ForcePhysDstSup : 1;        /**< Bit  62    - ForcePhyDestSup: Force Phys. Dst. Mode for Remapped Intr. */
    1521         uint32_t    u1Rsvd3 : 1;                  /**< Bit  63    - Reserved. */
    1522     } n;
    1523     /** The 64-bit unsigned integer view. */
    1524     uint64_t    u64;
    1525 } IOMMU_EXT_FEAT_T;
    1526 AssertCompileSize(IOMMU_EXT_FEAT_T, 8);
    1527 
    1528 /**
    1529  * Peripheral Page Request Log Base Address Register (MMIO).
    1530  * In accordance with the AMD spec.
    1531  */
    1532 typedef union
    1533 {
    1534     struct
    1535     {
    1536         RT_GCC_EXTENSION uint64_t   u12Rsvd0 : 12;      /**< Bit 11:0   - Reserved. */
    1537         RT_GCC_EXTENSION uint64_t   u40Base : 40;       /**< Bits 51:12 - PPRLogBase: Peripheral Page Request Log Base Address. */
    1538         RT_GCC_EXTENSION uint64_t   u4Rsvd0 : 4;        /**< Bits 55:52 - Reserved. */
    1539         RT_GCC_EXTENSION uint64_t   u4Len : 4;          /**< Bits 59:56 - PPRLogLen: Peripheral Page Request Log Length. */
    1540         RT_GCC_EXTENSION uint64_t   u4Rsvd1 : 4;        /**< Bits 63:60 - Reserved. */
    1541     } n;
    1542     /** The 64-bit unsigned integer view. */
    1543     uint64_t    u64;
    1544 } PPR_LOG_BAR_T;
    1545 AssertCompileSize(PPR_LOG_BAR_T, 8);
    1546 #define IOMMU_PPR_LOG_BAR_VALID_MASK    UINT64_C(0x0f0ffffffffff000)
    1547 
    1548 /**
    1549  * IOMMU Hardware Event Upper Register (MMIO).
    1550  * In accordance with the AMD spec.
    1551  */
    1552 typedef union
    1553 {
    1554     struct
    1555     {
    1556         RT_GCC_EXTENSION uint64_t   u60FirstOperand : 60;   /**< Bits 59:0  - First event code dependent operand. */
    1557         RT_GCC_EXTENSION uint64_t   u4EvtCode : 4;          /**< Bits 63:60 - Event Code. */
    1558     } n;
    1559     /** The 64-bit unsigned integer view. */
    1560     uint64_t    u64;
    1561 } IOMMU_HW_EVT_HI_T;
    1562 AssertCompileSize(IOMMU_HW_EVT_HI_T, 8);
    1563 
    1564 /**
    1565  * IOMMU Hardware Event Lower Register (MMIO).
    1566  * In accordance with the AMD spec.
    1567  */
    1568 typedef uint64_t IOMMU_HW_EVT_LO_T;
    1569 
    1570 /**
    1571  * IOMMU Hardware Event Status (MMIO).
    1572  * In accordance with the AMD spec.
    1573  */
    1574 typedef union
    1575 {
    1576     struct
    1577     {
    1578         uint32_t   u1Valid : 1;     /**< Bit 0      - HEV: Hardware Event Valid. */
    1579         uint32_t   u1Overflow : 1;  /**< Bit 1      - HEO: Hardware Event Overflow. */
    1580         uint32_t   u30Rsvd0 : 30;   /**< Bits 31:2  - Reserved. */
    1581         uint32_t   u32Rsvd0;        /**< Bits 63:32 - Reserved. */
    1582     } n;
    1583     /** The 64-bit unsigned integer view. */
    1584     uint64_t    u64;
    1585 } IOMMU_HW_EVT_STATUS_T;
    1586 AssertCompileSize(IOMMU_HW_EVT_STATUS_T, 8);
    1587 #define IOMMU_HW_EVT_STATUS_VALID_MASK      UINT64_C(0x0000000000000003)
    1588 
    1589 /**
    1590  * Guest Virtual-APIC Log Base Address Register (MMIO).
    1591  * In accordance with the AMD spec.
    1592  */
    1593 typedef union
    1594 {
    1595     struct
    1596     {
    1597         RT_GCC_EXTENSION uint64_t   u12Rsvd0 : 12;  /**< Bit 11:0   - Reserved. */
    1598         RT_GCC_EXTENSION uint64_t   u40Base : 40;   /**< Bits 51:12 - GALogBase: Guest Virtual-APIC Log Base Address. */
    1599         RT_GCC_EXTENSION uint64_t   u4Rsvd0 : 4;    /**< Bits 55:52 - Reserved. */
    1600         RT_GCC_EXTENSION uint64_t   u4Len : 4;      /**< Bits 59:56 - GALogLen: Guest Virtual-APIC Log Length. */
    1601         RT_GCC_EXTENSION uint64_t   u4Rsvd1 : 4;    /**< Bits 63:60 - Reserved. */
    1602     } n;
    1603     /** The 64-bit unsigned integer view. */
    1604     uint64_t    u64;
    1605 } GALOG_BAR_T;
    1606 AssertCompileSize(GALOG_BAR_T, 8);
    1607 
    1608 /**
    1609  * Guest Virtual-APIC Log Tail Address Register (MMIO).
    1610  * In accordance with the AMD spec.
    1611  */
    1612 typedef union
    1613 {
    1614     struct
    1615     {
    1616         RT_GCC_EXTENSION uint64_t   u3Rsvd0 : 3;            /**< Bits 2:0   - Reserved. */
    1617         RT_GCC_EXTENSION uint64_t   u40GALogTailAddr : 48;  /**< Bits 51:3  - GATAddr: Guest Virtual-APIC Tail Log Address. */
    1618         RT_GCC_EXTENSION uint64_t   u11Rsvd1 : 11;          /**< Bits 63:52 - Reserved. */
    1619     } n;
    1620     /** The 64-bit unsigned integer view. */
    1621     uint64_t    u64;
    1622 } GALOG_TAIL_ADDR_T;
    1623 AssertCompileSize(GALOG_TAIL_ADDR_T, 8);
    1624 
    1625 /**
    1626  * PPR Log B Base Address Register (MMIO).
    1627  * In accordance with the AMD spec.
    1628  * Currently identical to PPR_LOG_BAR_T.
    1629  */
    1630 typedef PPR_LOG_BAR_T       PPR_LOG_B_BAR_T;
    1631 
    1632 /**
    1633  * Event Log B Base Address Register (MMIO).
    1634  * In accordance with the AMD spec.
    1635  * Currently identical to EVT_LOG_BAR_T.
    1636  */
    1637 typedef EVT_LOG_BAR_T       EVT_LOG_B_BAR_T;
    1638 
    1639 /**
    1640  * Device-specific Feature Extension (DSFX) Register (MMIO).
    1641  * In accordance with the AMD spec.
    1642  */
    1643 typedef union
    1644 {
    1645     struct
    1646     {
    1647         uint32_t    u24DevSpecFeat : 24;     /**< Bits 23:0  - DevSpecificFeatSupp: Implementation specific features. */
    1648         uint32_t    u4RevMinor : 4;          /**< Bits 27:24 - RevMinor: Minor revision identifier. */
    1649         uint32_t    u4RevMajor : 4;          /**< Bits 31:28 - RevMajor: Major revision identifier. */
    1650         uint32_t    u32Rsvd0;                /**< Bits 63:32 - Reserved.*/
    1651     } n;
    1652     /** The 64-bit unsigned integer view. */
    1653     uint64_t    u64;
    1654 } DEV_SPECIFIC_FEAT_T;
    1655 AssertCompileSize(DEV_SPECIFIC_FEAT_T, 8);
    1656 
    1657 /**
    1658  * Device-specific Control Extension (DSCX) Register (MMIO).
    1659  * In accordance with the AMD spec.
    1660  */
    1661 typedef union
    1662 {
    1663     struct
    1664     {
    1665         uint32_t    u24DevSpecCtrl : 24;     /**< Bits 23:0  - DevSpecificFeatCntrl: Implementation specific control. */
    1666         uint32_t    u4RevMinor : 4;          /**< Bits 27:24 - RevMinor: Minor revision identifier. */
    1667         uint32_t    u4RevMajor : 4;          /**< Bits 31:28 - RevMajor: Major revision identifier. */
    1668         uint32_t    u32Rsvd0;                /**< Bits 63:32 - Reserved.*/
    1669     } n;
    1670     /** The 64-bit unsigned integer view. */
    1671     uint64_t    u64;
    1672 } DEV_SPECIFIC_CTRL_T;
    1673 AssertCompileSize(DEV_SPECIFIC_CTRL_T, 8);
    1674 
    1675 /**
    1676  * Device-specific Status Extension (DSSX) Register (MMIO).
    1677  * In accordance with the AMD spec.
    1678  */
    1679 typedef union
    1680 {
    1681     struct
    1682     {
    1683         uint32_t    u24DevSpecStatus : 24;      /**< Bits 23:0  - DevSpecificFeatStatus: Implementation specific status. */
    1684         uint32_t    u4RevMinor : 4;             /**< Bits 27:24 - RevMinor: Minor revision identifier. */
    1685         uint32_t    u4RevMajor : 4;             /**< Bits 31:28 - RevMajor: Major revision identifier. */
    1686         uint32_t    u32Rsvd0;                   /**< Bits 63:32 - Reserved.*/
    1687     } n;
    1688     /** The 64-bit unsigned integer view. */
    1689     uint64_t    u64;
    1690 } DEV_SPECIFIC_STATUS_T;
    1691 AssertCompileSize(DEV_SPECIFIC_STATUS_T, 8);
    1692 
    1693 /**
    1694  * MSI Information Register 0 and 1 (PCI) / MSI Vector Register 0 and 1 (MMIO).
    1695  * In accordance with the AMD spec.
    1696  */
    1697 typedef union
    1698 {
    1699     struct
    1700     {
    1701         uint32_t    u5MsiNumEvtLog : 5;     /**< Bits 4:0   - MsiNum: Event Log MSI message number. */
    1702         uint32_t    u3GstVirtAddrSize: 3;   /**< Bits 7:5   - GVAsize: Guest Virtual Address Size. */
    1703         uint32_t    u7PhysAddrSize : 7;     /**< Bits 14:8  - PAsize: Physical Address Size. */
    1704         uint32_t    u7VirtAddrSize : 7;     /**< Bits 21:15 - VAsize: Virtual Address Size. */
    1705         uint32_t    u1HtAtsResv: 1;         /**< Bit  22    - HtAtsResv: HyperTransport ATS Response Address range Reserved. */
    1706         uint32_t    u4Rsvd0 : 4;            /**< Bits 26:23 - Reserved. */
    1707         uint32_t    u5MsiNumPpr : 5;        /**< Bits 31:27 - MsiNumPPR: Peripheral Page Request MSI message number. */
    1708         uint32_t    u5MsiNumGa : 5;         /**< Bits 36:32 - MsiNumGa: MSI message number for guest virtual-APIC log. */
    1709         uint32_t    u27Rsvd0: 27;           /**< Bits 63:37 - Reserved. */
    1710     } n;
    1711     /** The 32-bit unsigned integer view. */
    1712     uint32_t    au32[2];
    1713     /** The 64-bit unsigned integer view. */
    1714     uint64_t    u64;
    1715 } MSI_MISC_INFO_T;
    1716 AssertCompileSize(MSI_MISC_INFO_T, 8);
    1717 /** MSI Vector Register 0 and 1 (MMIO). */
    1718 typedef MSI_MISC_INFO_T       MSI_VECTOR_T;
    1719 
    1720 /**
    1721  * MSI Capability Header Register (PCI + MMIO).
    1722  * In accordance with the AMD spec.
    1723  */
    1724 typedef union
    1725 {
    1726     struct
    1727     {
    1728         uint32_t    u8MsiCapId : 8;         /**< Bits 7:0   - MsiCapId: Capability ID. */
    1729         uint32_t    u8MsiCapPtr : 8;        /**< Bits 15:8  - MsiCapPtr: Pointer (PCI config offset) to the next capability. */
    1730         uint32_t    u1MsiEnable : 1;        /**< Bit  16    - MsiEn: Message Signal Interrupt Enable. */
    1731         uint32_t    u3MsiMultiMessCap : 3;  /**< Bits 19:17 - MsiMultMessCap: MSI Multi-Message Capability. */
    1732         uint32_t    u3MsiMultiMessEn : 3;   /**< Bits 22:20 - MsiMultMessEn: MSI Multi-Message Enable. */
    1733         uint32_t    u1Msi64BitEn : 1;       /**< Bit  23    - Msi64BitEn: MSI 64-bit Enable. */
    1734         uint32_t    u8Rsvd0 : 8;            /**< Bits 31:24 - Reserved. */
    1735     } n;
    1736     /** The 32-bit unsigned integer view. */
    1737     uint32_t    u32;
    1738 } MSI_CAP_HDR_T;
    1739 AssertCompileSize(MSI_CAP_HDR_T, 4);
    1740 #define IOMMU_MSI_CAP_HDR_MSI_EN_MASK       RT_BIT(16)
    1741 
    1742 /**
    1743  * MSI Mapping Capability Header Register (PCI + MMIO).
    1744  * In accordance with the AMD spec.
    1745  */
    1746 typedef union
    1747 {
    1748     struct
    1749     {
    1750         uint32_t    u8MsiMapCapId : 8;  /**< Bits 7:0   - MsiMapCapId: MSI Map capability ID. */
    1751         uint32_t    u8Rsvd0 : 8;        /**< Bits 15:8  - Reserved. */
    1752         uint32_t    u1MsiMapEn : 1;     /**< Bit  16    - MsiMapEn: MSI Map enable. */
    1753         uint32_t    u1MsiMapFixed : 1;  /**< Bit  17    - MsiMapFixd: MSI Map fixed. */
    1754         uint32_t    u9Rsvd0 : 9;        /**< Bits 26:18 - Reserved. */
    1755         uint32_t    u5MapCapType : 5;   /**< Bits 31:27 - MsiMapCapType: MSI Mapping capability type. */
    1756     } n;
    1757     /** The 32-bit unsigned integer view. */
    1758     uint32_t    u32;
    1759 } MSI_MAP_CAP_HDR_T;
    1760 AssertCompileSize(MSI_MAP_CAP_HDR_T, 4);
    1761 
    1762 /**
    1763  * Performance Optimization Control Register (MMIO).
    1764  * In accordance with the AMD spec.
    1765  */
    1766 typedef union
    1767 {
    1768     struct
    1769     {
    1770         uint32_t    u13Rsvd0 : 13;      /**< Bits 12:0  - Reserved. */
    1771         uint32_t    u1PerfOptEn : 1;    /**< Bit  13    - PerfOptEn: Performance Optimization Enable. */
    1772         uint32_t    u17Rsvd0 : 18;      /**< Bits 31:14 - Reserved. */
    1773     } n;
    1774     /** The 32-bit unsigned integer view. */
    1775     uint32_t    u32;
    1776 } IOMMU_PERF_OPT_CTRL_T;
    1777 AssertCompileSize(IOMMU_PERF_OPT_CTRL_T, 4);
    1778 
    1779 /**
    1780  * XT (x2APIC) IOMMU General Interrupt Control Register (MMIO).
    1781  * In accordance with the AMD spec.
    1782  */
    1783 typedef union
    1784 {
    1785     struct
    1786     {
    1787         uint32_t    u2Rsvd0 : 2;                    /**< Bits 1:0   - Reserved.*/
    1788         uint32_t    u1X2ApicIntrDstMode : 1;        /**< Bit  2     - Destination Mode for general interrupt.*/
    1789         uint32_t    u4Rsvd0 : 4;                    /**< Bits 7:3   - Reserved.*/
    1790         uint32_t    u24X2ApicIntrDstLo : 24;        /**< Bits 31:8  - Destination for general interrupt (Lo).*/
    1791         uint32_t    u8X2ApicIntrVector : 8;         /**< Bits 39:32 - Vector for general interrupt.*/
    1792         uint32_t    u1X2ApicIntrDeliveryMode : 1;   /**< Bit  40    - Delivery Mode for general interrupt.*/
    1793         uint32_t    u15Rsvd0 : 15;                  /**< Bits 55:41 - Reserved.*/
    1794         uint32_t    u7X2ApicIntrDstHi : 7;          /**< Bits 63:56 - Destination for general interrupt (Hi) .*/
    1795     } n;
    1796     /** The 64-bit unsigned integer view. */
    1797     uint64_t    u64;
    1798 } IOMMU_XT_GEN_INTR_CTRL_T;
    1799 AssertCompileSize(IOMMU_XT_GEN_INTR_CTRL_T, 8);
    1800 
    1801 /**
    1802  * XT (x2APIC) IOMMU General Interrupt Control Register (MMIO).
    1803  * In accordance with the AMD spec.
    1804  */
    1805 typedef union
    1806 {
    1807     struct
    1808     {
    1809         uint32_t    u2Rsvd0 : 2;                    /**< Bits 1:0   - Reserved.*/
    1810         uint32_t    u1X2ApicIntrDstMode : 1;        /**< Bit  2     - Destination Mode for the interrupt.*/
    1811         uint32_t    u4Rsvd0 : 4;                    /**< Bits 7:3   - Reserved.*/
    1812         uint32_t    u24X2ApicIntrDstLo : 24;        /**< Bits 31:8  - Destination for the interrupt (Lo).*/
    1813         uint32_t    u8X2ApicIntrVector : 8;         /**< Bits 39:32 - Vector for the interrupt.*/
    1814         uint32_t    u1X2ApicIntrDeliveryMode : 1;   /**< Bit  40    - Delivery Mode for the interrupt.*/
    1815         uint32_t    u15Rsvd0 : 15;                  /**< Bits 55:41 - Reserved.*/
    1816         uint32_t    u7X2ApicIntrDstHi : 7;          /**< Bits 63:56 - Destination for the interrupt (Hi) .*/
    1817     } n;
    1818     /** The 64-bit unsigned integer view. */
    1819     uint64_t    u64;
    1820 } IOMMU_XT_INTR_CTRL_T;
    1821 AssertCompileSize(IOMMU_XT_INTR_CTRL_T, 8);
    1822 
    1823 /**
    1824  * XT (x2APIC) IOMMU PPR Interrupt Control Register (MMIO).
    1825  * In accordance with the AMD spec.
    1826  * Currently identical to IOMMU_XT_INTR_CTRL_T.
    1827  */
    1828 typedef IOMMU_XT_INTR_CTRL_T    IOMMU_XT_PPR_INTR_CTRL_T;
    1829 
    1830 /**
    1831  * XT (x2APIC) IOMMU GA (Guest Address) Log Control Register (MMIO).
    1832  * In accordance with the AMD spec.
    1833  * Currently identical to IOMMU_XT_INTR_CTRL_T.
    1834  */
    1835 typedef IOMMU_XT_INTR_CTRL_T    IOMMU_XT_GALOG_INTR_CTRL_T;
    1836 
    1837 /**
    1838  * Memory Access and Routing Control (MARC) Aperture Base Register (MMIO).
    1839  * In accordance with the AMD spec.
    1840  */
    1841 typedef union
    1842 {
    1843     struct
    1844     {
    1845         RT_GCC_EXTENSION uint64_t   u12Rsvd0 : 12;          /**< Bits 11:0  - Reserved. */
    1846         RT_GCC_EXTENSION uint64_t   u40MarcBaseAddr : 40;   /**< Bits 51:12 - MarcBaseAddr: MARC Aperture Base Address. */
    1847         RT_GCC_EXTENSION uint64_t   u12Rsvd1 : 12;          /**< Bits 63:52 - Reserved. */
    1848     } n;
    1849     /** The 64-bit unsigned integer view. */
    1850     uint64_t    u64;
    1851 } MARC_APER_BAR_T;
    1852 AssertCompileSize(MARC_APER_BAR_T, 8);
    1853 
    1854 /**
    1855  * Memory Access and Routing Control (MARC) Relocation Register (MMIO).
    1856  * In accordance with the AMD spec.
    1857  */
    1858 typedef union
    1859 {
    1860     struct
    1861     {
    1862         RT_GCC_EXTENSION uint64_t   u1RelocEn : 1;          /**< Bit  0     - RelocEn: Relocation Enabled. */
    1863         RT_GCC_EXTENSION uint64_t   u1ReadOnly : 1;         /**< Bit  1     - ReadOnly: Whether only read-only acceses allowed. */
    1864         RT_GCC_EXTENSION uint64_t   u10Rsvd0 : 10;          /**< Bits 11:2  - Reserved. */
    1865         RT_GCC_EXTENSION uint64_t   u40MarcRelocAddr : 40;  /**< Bits 51:12 - MarcRelocAddr: MARC Aperture Relocation Address. */
    1866         RT_GCC_EXTENSION uint64_t   u12Rsvd1 : 12;          /**< Bits 63:52 - Reserved. */
    1867     } n;
    1868     /** The 64-bit unsigned integer view. */
    1869     uint64_t    u64;
    1870 } MARC_APER_RELOC_T;
    1871 AssertCompileSize(MARC_APER_RELOC_T, 8);
    1872 
    1873 /**
    1874  * Memory Access and Routing Control (MARC) Length Register (MMIO).
    1875  * In accordance with the AMD spec.
    1876  */
    1877 typedef union
    1878 {
    1879     struct
    1880     {
    1881         RT_GCC_EXTENSION uint64_t   u12Rsvd0 : 12;          /**< Bits 11:0  - Reserved. */
    1882         RT_GCC_EXTENSION uint64_t   u40MarcLength : 40;     /**< Bits 51:12 - MarcLength: MARC Aperture Length. */
    1883         RT_GCC_EXTENSION uint64_t   u12Rsvd1 : 12;          /**< Bits 63:52 - Reserved. */
    1884     } n;
    1885     /** The 64-bit unsigned integer view. */
    1886     uint64_t    u64;
    1887 } MARC_APER_LEN_T;
    1888 
    1889 /**
    1890  * Memory Access and Routing Control (MARC) Aperture Register.
    1891  * This combines other registers to match the MMIO layout for convenient access.
    1892  */
    1893 typedef struct
    1894 {
    1895     MARC_APER_BAR_T     Base;
    1896     MARC_APER_RELOC_T   Reloc;
    1897     MARC_APER_LEN_T     Length;
    1898 } MARC_APER_T;
    1899 AssertCompileSize(MARC_APER_T, 24);
    1900 
    1901 /**
    1902  * IOMMU Reserved Register (MMIO).
    1903  * In accordance with the AMD spec.
    1904  * This register is reserved for hardware use (although RW?).
    1905  */
    1906 typedef uint64_t    IOMMU_RSVD_REG_T;
    1907 
    1908 /**
    1909  * Command Buffer Head Pointer Register (MMIO).
    1910  * In accordance with the AMD spec.
    1911  */
    1912 typedef union
    1913 {
    1914     struct
    1915     {
    1916         uint32_t    off;            /**< Bits 31:0  - Buffer pointer (offset; 16 byte aligned, 512 KB max). */
    1917         uint32_t    u32Rsvd0;       /**< Bits 63:32 - Reserved. */
    1918     } n;
    1919     /** The 32-bit unsigned integer view. */
    1920     uint32_t    au32[2];
    1921     /** The 64-bit unsigned integer view. */
    1922     uint64_t    u64;
    1923 } CMD_BUF_HEAD_PTR_T;
    1924 AssertCompileSize(CMD_BUF_HEAD_PTR_T, 8);
    1925 #define IOMMU_CMD_BUF_HEAD_PTR_VALID_MASK       UINT64_C(0x000000000007fff0)
    1926 
    1927 /**
    1928  * Command Buffer Tail Pointer Register (MMIO).
    1929  * In accordance with the AMD spec.
    1930  * Currently identical to CMD_BUF_HEAD_PTR_T.
    1931  */
    1932 typedef CMD_BUF_HEAD_PTR_T    CMD_BUF_TAIL_PTR_T;
    1933 #define IOMMU_CMD_BUF_TAIL_PTR_VALID_MASK       IOMMU_CMD_BUF_HEAD_PTR_VALID_MASK
    1934 
    1935 /**
    1936  * Event Log Head Pointer Register (MMIO).
    1937  * In accordance with the AMD spec.
    1938  * Currently identical to CMD_BUF_HEAD_PTR_T.
    1939  */
    1940 typedef CMD_BUF_HEAD_PTR_T    EVT_LOG_HEAD_PTR_T;
    1941 #define IOMMU_EVT_LOG_HEAD_PTR_VALID_MASK       IOMMU_CMD_BUF_HEAD_PTR_VALID_MASK
    1942 
    1943 /**
    1944  * Event Log Tail Pointer Register (MMIO).
    1945  * In accordance with the AMD spec.
    1946  * Currently identical to CMD_BUF_HEAD_PTR_T.
    1947  */
    1948 typedef CMD_BUF_HEAD_PTR_T    EVT_LOG_TAIL_PTR_T;
    1949 #define IOMMU_EVT_LOG_TAIL_PTR_VALID_MASK       IOMMU_CMD_BUF_HEAD_PTR_VALID_MASK
    1950 
    1951 
    1952 /**
    1953  * IOMMU Status Register (MMIO).
    1954  * In accordance with the AMD spec.
    1955  */
    1956 typedef union
    1957 {
    1958     struct
    1959     {
    1960         uint32_t    u1EvtOverflow : 1;          /**< Bit  0     - EventOverflow: Event log overflow. */
    1961         uint32_t    u1EvtLogIntr : 1;           /**< Bit  1     - EventLogInt: Event log interrupt. */
    1962         uint32_t    u1CompWaitIntr : 1;         /**< Bit  2     - ComWaitInt: Completion wait interrupt . */
    1963         uint32_t    u1EvtLogRunning : 1;        /**< Bit  3     - EventLogRun: Event logging is running. */
    1964         uint32_t    u1CmdBufRunning : 1;        /**< Bit  4     - CmdBufRun: Command buffer is running. */
    1965         uint32_t    u1PprOverflow : 1;          /**< Bit  5     - PprOverflow: Peripheral Page Request Log (PPR) overflow. */
    1966         uint32_t    u1PprIntr : 1;              /**< Bit  6     - PprInt: PPR interrupt. */
    1967         uint32_t    u1PprLogRunning : 1;        /**< Bit  7     - PprLogRun: PPR logging is running. */
    1968         uint32_t    u1GstLogRunning : 1;        /**< Bit  8     - GALogRun: Guest virtual-APIC logging is running. */
    1969         uint32_t    u1GstLogOverflow : 1;       /**< Bit  9     - GALOverflow: Guest virtual-APIC log overflow. */
    1970         uint32_t    u1GstLogIntr : 1;           /**< Bit  10    - GAInt: Guest virtual-APIC log interrupt. */
    1971         uint32_t    u1PprOverflowB : 1;         /**< Bit  11    - PprOverflowB: PPR log B overflow. */
    1972         uint32_t    u1PprLogActive : 1;         /**< Bit  12    - PprLogActive: PPR log A is active. */
    1973         uint32_t    u2Rsvd0 : 2;                /**< Bits 14:13 - Reserved. */
    1974         uint32_t    u1EvtOverflowB : 1;         /**< Bit  15    - EvtOverflowB: Event log B overflow. */
    1975         uint32_t    u1EvtLogActive : 1;         /**< Bit  16    - EvtLogActive: Event log A active. */
    1976         uint32_t    u1PprOverflowEarlyB : 1;    /**< Bit  17    - PprOverflowEarlyB: PPR log B overflow early warning. */
    1977         uint32_t    u1PprOverflowEarly : 1;     /**< Bit  18    - PprOverflowEarly: PPR log overflow early warning. */
    1978         uint32_t    u13Rsvd0 : 13;              /**< Bits 31:19 - Reserved. */
    1979         uint32_t    u32Rsvd0;                   /**< Bits 63:32 - Reserved . */
    1980     } n;
    1981     /** The 32-bit unsigned integer view. */
    1982     uint32_t    au32[2];
    1983     /** The 64-bit unsigned integer view. */
    1984     uint64_t    u64;
    1985 } IOMMU_STATUS_T;
    1986 AssertCompileSize(IOMMU_STATUS_T, 8);
    1987 #define IOMMU_STATUS_VALID_MASK     UINT64_C(0x0000000000079fff)
    1988 #define IOMMU_STATUS_RW1C_MASK      UINT64_C(0x0000000000068e67)
    1989 
    1990 /**
    1991  * PPR Log Head Pointer Register (MMIO).
    1992  * In accordance with the AMD spec.
    1993  * Currently identical to CMD_BUF_HEAD_PTR_T.
    1994  */
    1995 typedef CMD_BUF_HEAD_PTR_T      PPR_LOG_HEAD_PTR_T;
    1996 
    1997 /**
    1998  * PPR Log Tail Pointer Register (MMIO).
    1999  * In accordance with the AMD spec.
    2000  * Currently identical to CMD_BUF_HEAD_PTR_T.
    2001  */
    2002 typedef CMD_BUF_HEAD_PTR_T      PPR_LOG_TAIL_PTR_T;
    2003 
    2004 /**
    2005  * Guest Virtual-APIC Log Head Pointer Register (MMIO).
    2006  * In accordance with the AMD spec.
    2007  */
    2008 typedef union
    2009 {
    2010     struct
    2011     {
    2012         uint32_t    u2Rsvd0 : 2;            /**< Bits 2:0   - Reserved. */
    2013         uint32_t    u12GALogPtr : 12;       /**< Bits 15:3  - Guest Virtual-APIC Log Head or Tail Pointer. */
    2014         uint32_t    u16Rsvd0 : 16;          /**< Bits 31:16 - Reserved. */
    2015         uint32_t    u32Rsvd0;               /**< Bits 63:32 - Reserved. */
    2016     } n;
    2017     /** The 32-bit unsigned integer view. */
    2018     uint32_t    au32[2];
    2019     /** The 64-bit unsigned integer view. */
    2020     uint64_t    u64;
    2021 } GALOG_HEAD_PTR_T;
    2022 AssertCompileSize(GALOG_HEAD_PTR_T, 8);
    2023 
    2024 /**
    2025  * Guest Virtual-APIC Log Tail Pointer Register (MMIO).
    2026  * In accordance with the AMD spec.
    2027  * Currently identical to GALOG_HEAD_PTR_T.
    2028  */
    2029 typedef GALOG_HEAD_PTR_T        GALOG_TAIL_PTR_T;
    2030 
    2031 /**
    2032  * PPR Log B Head Pointer Register (MMIO).
    2033  * In accordance with the AMD spec.
    2034  * Currently identical to CMD_BUF_HEAD_PTR_T.
    2035  */
    2036 typedef CMD_BUF_HEAD_PTR_T      PPR_LOG_B_HEAD_PTR_T;
    2037 
    2038 /**
    2039  * PPR Log B Tail Pointer Register (MMIO).
    2040  * In accordance with the AMD spec.
    2041  * Currently identical to CMD_BUF_HEAD_PTR_T.
    2042  */
    2043 typedef CMD_BUF_HEAD_PTR_T      PPR_LOG_B_TAIL_PTR_T;
    2044 
    2045 /**
    2046  * Event Log B Head Pointer Register (MMIO).
    2047  * In accordance with the AMD spec.
    2048  * Currently identical to CMD_BUF_HEAD_PTR_T.
    2049  */
    2050 typedef CMD_BUF_HEAD_PTR_T      EVT_LOG_B_HEAD_PTR_T;
    2051 
    2052 /**
    2053  * Event Log B Tail Pointer Register (MMIO).
    2054  * In accordance with the AMD spec.
    2055  * Currently identical to CMD_BUF_HEAD_PTR_T.
    2056  */
    2057 typedef CMD_BUF_HEAD_PTR_T      EVT_LOG_B_TAIL_PTR_T;
    2058 
    2059 /**
    2060  * PPR Log Auto Response Register (MMIO).
    2061  * In accordance with the AMD spec.
    2062  */
    2063 typedef union
    2064 {
    2065     struct
    2066     {
    2067         uint32_t    u4AutoRespCode : 4;     /**< Bits 3:0   - PprAutoRespCode: PPR log Auto Response Code. */
    2068         uint32_t    u1AutoRespMaskGen : 1;  /**< Bit  4     - PprAutoRespMaskGn: PPR log Auto Response Mask Gen. */
    2069         uint32_t    u27Rsvd0 : 27;          /**< Bits 31:5  - Reserved. */
    2070         uint32_t    u32Rsvd0;               /**< Bits 63:32 - Reserved.*/
    2071     } n;
    2072     /** The 32-bit unsigned integer view. */
    2073     uint32_t    au32[2];
    2074     /** The 64-bit unsigned integer view. */
    2075     uint64_t    u64;
    2076 } PPR_LOG_AUTO_RESP_T;
    2077 AssertCompileSize(PPR_LOG_AUTO_RESP_T, 8);
    2078 
    2079 /**
    2080  * PPR Log Overflow Early Indicator Register (MMIO).
    2081  * In accordance with the AMD spec.
    2082  */
    2083 typedef union
    2084 {
    2085     struct
    2086     {
    2087         uint32_t    u15Threshold : 15;  /**< Bits 14:0  - PprOvrflwEarlyThreshold: Overflow early indicator threshold. */
    2088         uint32_t    u15Rsvd0 : 15;      /**< Bits 29:15 - Reserved. */
    2089         uint32_t    u1IntrEn : 1;       /**< Bit  30    - PprOvrflwEarlyIntEn: Overflow early indicator interrupt enable. */
    2090         uint32_t    u1Enable : 1;       /**< Bit  31    - PprOvrflwEarlyEn: Overflow early indicator enable. */
    2091         uint32_t    u32Rsvd0;           /**< Bits 63:32 - Reserved. */
    2092     } n;
    2093     /** The 32-bit unsigned integer view. */
    2094     uint32_t    au32[2];
    2095     /** The 64-bit unsigned integer view. */
    2096     uint64_t    u64;
    2097 } PPR_LOG_OVERFLOW_EARLY_T;
    2098 AssertCompileSize(PPR_LOG_OVERFLOW_EARLY_T, 8);
    2099 
    2100 /**
    2101  * PPR Log B Overflow Early Indicator Register (MMIO).
    2102  * In accordance with the AMD spec.
    2103  * Currently identical to PPR_LOG_OVERFLOW_EARLY_T.
    2104  */
    2105 typedef PPR_LOG_OVERFLOW_EARLY_T        PPR_LOG_B_OVERFLOW_EARLY_T;
    2106 
    2107 /**
    2108  * ILLEGAL_DEV_TABLE_ENTRY Event Types.
    2109  * In accordance with the AMD spec.
    2110  */
    2111 typedef enum EVT_ILLEGAL_DTE_TYPE_T
    2112 {
    2113     kIllegalDteType_RsvdNotZero = 0,
    2114     kIllegalDteType_RsvdIntTabLen,
    2115     kIllegalDteType_RsvdIoCtl,
    2116     kIllegalDteType_RsvdIntCtl
    2117 } EVT_ILLEGAL_DTE_TYPE_T;
    2118 
    2119 /**
    2120  * ILLEGAL_DEV_TABLE_ENTRY Event Types.
    2121  * In accordance with the AMD spec.
    2122  */
    2123 typedef enum EVT_IO_PAGE_FAULT_TYPE_T
    2124 {
    2125     /* Memory transaction. */
    2126     kIoPageFaultType_DteRsvdPagingMode = 0,
    2127     kIoPageFaultType_PteInvalidPageSize,
    2128     kIoPageFaultType_PteInvalidLvlEncoding,
    2129     kIoPageFaultType_SkippedLevelIovaNotZero,
    2130     kIoPageFaultType_PteRsvdNotZero,
    2131     kIoPageFaultType_PteValidNotSet,
    2132     kIoPageFaultType_DteTranslationDisabled,
    2133     kIoPageFaultType_PasidInvalidRange,
    2134     kIoPageFaultType_PermDenied,
    2135     kIoPageFaultType_UserSupervisor,
    2136     /* Interrupt remapping */
    2137     kIoPageFaultType_IrteAddrInvalid,
    2138     kIoPageFaultType_IrteRsvdNotZero,
    2139     kIoPageFaultType_IrteRemapEn,
    2140     kIoPageFaultType_IrteRsvdIntType,
    2141     kIoPageFaultType_IntrReqAborted,
    2142     kIoPageFaultType_IntrWithPasid,
    2143     kIoPageFaultType_SmiFilterMismatch,
    2144     /* Memory transaction or interrupt remapping. */
    2145     kIoPageFaultType_DevId_Invalid
    2146 } EVT_IO_PAGE_FAULT_TYPE_T;
    2147 
    2148 /**
    2149  * IOTLB_INV_TIMEOUT Event Types.
    2150  * In accordance with the AMD spec.
    2151  */
    2152 typedef enum EVT_IOTLB_INV_TIMEOUT_TYPE_T
    2153 {
    2154     InvTimeoutType_NoResponse = 0
    2155 } EVT_IOTLB_INV_TIMEOUT_TYPE_T;
    2156 
    2157 /**
    2158  * INVALID_DEVICE_REQUEST Event Types.
    2159  * In accordance with the AMD spec.
    2160  */
    2161 typedef enum EVT_INVALID_DEV_REQ_TYPE_T
    2162 {
    2163     /* Access. */
    2164     kInvalidDevReqType_ReadOrNonPostedWrite = 0,
    2165     kInvalidDevReqType_PretranslatedTransaction,
    2166     kInvalidDevReqType_PortIo,
    2167     kInvalidDevReqType_SysMgt,
    2168     kInvalidDevReqType_IntrRange,
    2169     kInvalidDevReqType_RsvdIntrRange,
    2170     kInvalidDevReqType_SysMgtAddr,
    2171     /* Translation Request. */
    2172     kInvalidDevReqType_TrAccessInvalid,
    2173     kInvalidDevReqType_TrDisabled,
    2174     kInvalidDevReqType_DevIdInvalid,
    2175 } EVT_INVALID_DEV_REQ_TYPE_T;
    2176 
    2177 /**
    2178  * INVALID_PPR_REQUEST Event Types.
    2179  * In accordance with the AMD spec.
    2180  */
    2181 typedef enum EVT_INVALID_PPR_REQ_TYPE_T
    2182 {
    2183     kInvalidPprReqType_PriNotSupported,
    2184     kInvalidPprReqType_GstTranslateDisabled
    2185 } EVT_INVALID_PPR_REQ_TYPE_T;
    218695
    218796/**
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette