VirtualBox

Changeset 88858 in vbox


Ignore:
Timestamp:
May 4, 2021 2:29:52 PM (4 years ago)
Author:
vboxsync
Message:

Intel IOMMU: bugref:9967 Interrupt remapping, work-in-progress.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/iommu-intel.h

    r88841 r88858  
    671671                            (SID, SQ, SVT, RSVD_63_20));
    672672
     673/** IRTE: Qword 0 valid mask. */
     674#define VTD_IRTE_0_VALID_MASK                                   (  VTD_BF_0_IRTE_P_MASK  | VTD_BF_0_IRTE_FPD_MASK \
     675                                                                 | VTD_BF_0_IRTE_DM_MASK | VTD_BF_0_IRTE_RH_MASK \
     676                                                                 | VTD_BF_0_IRTE_TM_MASK | VTD_BF_0_IRTE_DLM_MASK \
     677                                                                 | VTD_BF_0_IRTE_AVAIL_MASK | VTD_BF_0_IRTE_IM_MASK \
     678                                                                 | VTD_BF_0_IRTE_V_MASK | VTD_BF_0_IRTE_DST_MASK)
     679/** IRTE: Qword 1 valid mask. */
     680#define VTD_IRTE_1_VALID_MASK                                   (  VTD_BF_1_IRTE_SID_MASK | VTD_BF_1_IRTE_SQ_MASK \
     681                                                                 | VTD_BF_1_IRTE_SVT_MASK)
     682
    673683/** Interrupt Remapping Table Entry (IRTE) for remapped interrupts. */
    674684typedef struct VTD_IRTE_T
     
    681691/** Pointer to a const IRTE. */
    682692typedef VTD_IRTE_T const *PCVTD_IRTE_T;
     693
     694/** IRTE SVT: No validation required. */
     695#define VTD_IRTE_SVT_NONE                                       0
     696/** IRTE SVT: Validate using a mask derived from SID and SQT. */
     697#define VTD_IRTE_SVT_VALIDATE_MASK                              1
     698/** IRTE SVT: Validate using Bus range in the SID. */
     699#define VTD_IRTE_SVT_VALIDATE_BUS_RANGE                         2
     700/** IRTE SVT: Reserved. */
     701#define VTD_IRTE_SVT_VALIDATE_RSVD                              3
    683702/** @} */
    684703
     
    15481567#define VTD_IRTA_REG_RW_MASK                                    (  VTD_BF_IRTA_REG_S_MASK | VTD_BF_IRTA_REG_EIME_MASK \
    15491568                                                                 | VTD_BF_IRTA_REG_IRTA_MASK)
     1569/** IRTA_REG: Get number of interrupt entries. */
     1570#define VTD_IRTA_REG_GET_ENTRIES(a)                             (UINT32_C(1) << (1 + ((a) & VTD_BF_IRTA_REG_S_MASK)))
    15501571/** @} */
    15511572
     
    22052226
    22062227
     2228/** @name Remappable Format Interrupt Request.
     2229 * In accordance with the Intel spec.
     2230 * @{ */
     2231/** IGN: Ignored (bits 1:0). */
     2232#define VTD_BF_REMAPPABLE_MSI_ADDR_IGN_1_0_SHIFT                0
     2233#define VTD_BF_REMAPPABLE_MSI_ADDR_IGN_1_0_MASK                 UINT32_C(0x00000003)
     2234/** Handle (Hi). */
     2235#define VTD_BF_REMAPPABLE_MSI_ADDR_HANDLE_HI_SHIFT              2
     2236#define VTD_BF_REMAPPABLE_MSI_ADDR_HANDLE_HI_MASK               UINT32_C(0x00000004)
     2237/** SHV: Subhandle Valid. */
     2238#define VTD_BF_REMAPPABLE_MSI_ADDR_SHV_SHIFT                    3
     2239#define VTD_BF_REMAPPABLE_MSI_ADDR_SHV_MASK                     UINT32_C(0x00000008)
     2240/** Interrupt format. */
     2241#define VTD_BF_REMAPPABLE_MSI_ADDR_INTR_FMT_SHIFT               4
     2242#define VTD_BF_REMAPPABLE_MSI_ADDR_INTR_FMT_MASK                UINT32_C(0x00000010)
     2243/** Handle (Lo). */
     2244#define VTD_BF_REMAPPABLE_MSI_ADDR_HANDLE_LO_SHIFT              5
     2245#define VTD_BF_REMAPPABLE_MSI_ADDR_HANDLE_LO_MASK               UINT32_C(0x000fffe0)
     2246/** Address. */
     2247#define VTD_BF_REMAPPABLE_MSI_ADDR_ADDR_SHIFT                   20
     2248#define VTD_BF_REMAPPABLE_MSI_ADDR_ADDR_MASK                    UINT32_C(0xfff00000)
     2249RT_BF_ASSERT_COMPILE_CHECKS(VTD_BF_REMAPPABLE_MSI_ADDR_, UINT32_C(0), UINT32_MAX,
     2250                            (IGN_1_0, HANDLE_HI, SHV, INTR_FMT, HANDLE_LO, ADDR));
     2251
     2252/** Subhandle. */
     2253#define VTD_BF_REMAPPABLE_MSI_DATA_SUBHANDLE_SHIFT              0
     2254#define VTD_BF_REMAPPABLE_MSI_DATA_SUBHANDLE_MASK               UINT32_C(0x0000ffff)
     2255/** R: Reserved (bits 31:16). */
     2256#define VTD_BF_REMAPPABLE_MSI_DATA_RSVD_31_16_SHIFT             16
     2257#define VTD_BF_REMAPPABLE_MSI_DATA_RSVD_31_16_MASK              UINT32_C(0xffff0000)
     2258RT_BF_ASSERT_COMPILE_CHECKS(VTD_BF_REMAPPABLE_MSI_DATA_, UINT32_C(0), UINT32_MAX,
     2259                            (SUBHANDLE, RSVD_31_16));
     2260
     2261/** Remappable MSI Address: Valid mask. */
     2262#define VTD_REMAPPABLE_MSI_ADDR_VALID_MASK                      UINT32_MAX
     2263/** Remappable MSI Data: Valid mask. */
     2264#define VTD_REMAPPABLE_MSI_DATA_VALID_MASK                      VTD_BF_REMAPPABLE_MSI_DATA_SUBHANDLE_MASK
     2265
    22072266/** Gets the interrupt format from an MSI address. */
    22082267#define VTD_MSI_ADDR_GET_INTR_FORMAT(a_uMsiAddr)                ((a_uMsiAddr) & RT_BIT_64(4))
     
    22112270/** Interrupt format: Remappable. */
    22122271#define VTD_INTR_FORMAT_REMAPPABLE                              1
    2213 
    2214 
    2215 /** @name Remappable Format Interrupt Request.
    2216  * In accordance with the Intel spec.
    2217  * @{ */
    2218 /** IGN: Ignored (bits 1:0). */
    2219 #define VTD_BF_REMAPPABLE_IR_ADDR_IGN_1_0_SHIFT                 0
    2220 #define VTD_BF_REMAPPABLE_IR_ADDR_IGN_1_0_MASK                  UINT32_C(0x00000003)
    2221 /** Handle (Hi). */
    2222 #define VTD_BF_REMAPPABLE_IR_ADDR_HANDLE_HI_SHIFT               2
    2223 #define VTD_BF_REMAPPABLE_IR_ADDR_HANDLE_HI_MASK                UINT32_C(0x00000004)
    2224 /** SHV: Subhandle Valid. */
    2225 #define VTD_BF_REMAPPABLE_IR_ADDR_SHV_SHIFT                     3
    2226 #define VTD_BF_REMAPPABLE_IR_ADDR_SHV_MASK                      UINT32_C(0x00000008)
    2227 /** Interrupt format. */
    2228 #define VTD_BF_REMAPPABLE_IR_ADDR_INTR_FMT_SHIFT                4
    2229 #define VTD_BF_REMAPPABLE_IR_ADDR_INTR_FMT_MASK                 UINT32_C(0x00000010)
    2230 /** Handle (Lo). */
    2231 #define VTD_BF_REMAPPABLE_IR_ADDR_HANDLE_LO_SHIFT               5
    2232 #define VTD_BF_REMAPPABLE_IR_ADDR_HANDLE_LO_MASK                UINT32_C(0x000fffe0)
    2233 /** Address. */
    2234 #define VTD_BF_REMAPPABLE_IR_ADDR_ADDR_SHIFT                    20
    2235 #define VTD_BF_REMAPPABLE_IR_ADDR_ADDR_MASK                     UINT32_C(0xfff00000)
    2236 RT_BF_ASSERT_COMPILE_CHECKS(VTD_BF_REMAPPABLE_IR_ADDR_, UINT32_C(0), UINT32_MAX,
    2237                             (IGN_1_0, HANDLE_HI, SHV, INTR_FMT, HANDLE_LO, ADDR));
    2238 
    2239 /** Subhandle. */
    2240 #define VTD_BF_REMAPPABLE_IR_DATA_SUBHANDLE_SHIFT               0
    2241 #define VTD_BF_REMAPPABLE_IR_DATA_SUBHANDLE_MASK                UINT32_C(0x0000ffff)
    2242 /** R: Reserved (bits 31:16). */
    2243 #define VTD_BF_REMAPPABLE_IR_DATA_RSVD_31_16_SHIFT              16
    2244 #define VTD_BF_REMAPPABLE_IR_DATA_RSVD_31_16_MASK               UINT32_C(0xffff0000)
    2245 RT_BF_ASSERT_COMPILE_CHECKS(VTD_BF_REMAPPABLE_IR_DATA_, UINT32_C(0), UINT32_MAX,
    2246                             (SUBHANDLE, RSVD_31_16));
     2272/** @} */
     2273
     2274
     2275/** @name Interrupt Remapping Fault Conditions.
     2276 * In accordance with the Intel spec.
     2277 * @{ */
     2278typedef enum VTD_IR_FAULT_T
     2279{
     2280    /** Reserved bits invalid in remappable interrupt. */
     2281    kIrf_Remappable_Intr_Rsvd = 0x20,
     2282    /** Interrupt index for remappable interrupt exceeds table size or referenced
     2283     *  address above host address width (HAW) */
     2284    kIrf_Intr_Index_Invalid = 0x21,
     2285    /** The IRTE is not present.  */
     2286    kIrf_Irte_Not_Present = 0x22,
     2287    /** Reading IRTE from memory failed. */
     2288    kIrf_Irte_Read_Failed = 0x23,
     2289    /** IRTE reserved bits invalid for an IRTE with Present bit set. */
     2290    kIrf_Irte_Present_Rsvd = 0x24,
     2291    /** Compatibility format interrupt (CFI) blocked due to EIME is enabled or CFIs
     2292     *  disabled. */
     2293    kIrf_Cfi_Blocked = 0x25,
     2294    /** IRTE SID, SVT, SQ bits invalid for an IRTE with Present bit set. */
     2295    kIrf_Irte_Present_Invalid = 0x26,
     2296    /** Reading posted interrupt descriptor (PID) failed. */
     2297    kIrf_Pid_Read_Failed = 0x27,
     2298    /** PID reserved bits invalid. */
     2299    kIrf_Pid_Rsvd = 0x28,
     2300    /** Untranslated interrupt requested (without PASID) is invalid. */
     2301    kIrf_Ir_Without_Pasid_Invalid = 0x29
     2302} VTD_IR_FAULT_T;
    22472303/** @} */
    22482304
  • trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp

    r88842 r88858  
    5555                                                     || (a_off) - DMAR_MMIO_GROUP_1_OFF_FIRST < DMAR_MMIO_GROUP_1_SIZE)
    5656
    57 /** Acquires the DMAR lock but returns with the given error code on failure. */
     57/** Acquires the DMAR lock but returns with the given busy error code on failure. */
    5858#define DMAR_LOCK_RET(a_pDevIns, a_pThisCC, a_rcBusy) \
    5959    do { \
     
    6464    } while (0)
    6565
    66 /** Acquires the DMAR lock and is not expected to fail. */
    67 #define DMAR_LOCK(a_pDevIns, a_pThisCC) \
     66/** Acquires the DMAR lock (not expected to fail). */
     67#ifdef IN_RING3
     68# define DMAR_LOCK(a_pDevIns, a_pThisCC)            (a_pThisCC)->CTX_SUFF(pIommuHlp)->pfnLock((a_pDevIns), VERR_IGNORED)
     69#else
     70# define DMAR_LOCK(a_pDevIns, a_pThisCC) \
    6871    do { \
    69         int const rcLock = (a_pThisCC)->CTX_SUFF(pIommuHlp)->pfnLock((a_pDevIns), VERR_IGNORED); \
    70         Assert(rcLock == VINF_SUCCESS); \
     72        int const rcLock = (a_pThisCC)->CTX_SUFF(pIommuHlp)->pfnLock((a_pDevIns), VINF_SUCCESS); \
     73        AssertRC(rcLock); \
    7174    } while (0)
     75#endif
    7276
    7377/** Release the DMAR lock. */
     
    164168    kDmarDiag_IqtReg_Qt_Invalid,
    165169    kDmarDiag_IqtReg_Qt_NotAligned,
     170    kDmarDiag_Ir_Cfi_Blocked,
     171    kDmarDiag_Ir_Rfi_Intr_Index_Invalid,
     172    kDmarDiag_Ir_Rfi_Irte_Read_Failed,
     173    kDmarDiag_Ir_Rfi_Irte_Not_Present,
     174    kDmarDiag_Ir_Rfi_Irte_Rsvd,
     175    kDmarDiag_Ir_Rfi_Rsvd,
    166176    /* Member for determining array index limit. */
    167177    kDmarDiag_End,
     
    192202    DMARDIAG_DESC(Iqei_Ttm_Rsvd             ),
    193203    DMARDIAG_DESC(IqtReg_Qt_Invalid         ),
    194     DMARDIAG_DESC(IqtReg_Qt_NotAligned      )
     204    DMARDIAG_DESC(IqtReg_Qt_NotAligned      ),
     205    DMARDIAG_DESC(Ir_Cfi_Blocked            ),
     206    DMARDIAG_DESC(Ir_Rfi_Intr_Index_Invalid ),
     207    DMARDIAG_DESC(Ir_Rfi_Irte_Read_Failed   ),
     208    DMARDIAG_DESC(Ir_Rfi_Irte_Not_Present   ),
     209    DMARDIAG_DESC(Ir_Rfi_Irte_Rsvd          ),
     210    DMARDIAG_DESC(Ir_Rfi_Rsvd               ),
    195211    /* kDmarDiag_End */
    196212};
     
    623639
    624640/**
     641 * Returns whether the interrupt remapping fault is qualified or not.
     642 *
     643 * @returns @c true if qualified, @c false otherwise.
     644 * @param   enmIrFault  The interrupt remapping fault condition.
     645 */
     646static bool vtdIrFaultIsQualified(VTD_IR_FAULT_T enmIrFault)
     647{
     648    switch (enmIrFault)
     649    {
     650        case kIrf_Irte_Not_Present:
     651        case kIrf_Irte_Present_Rsvd:
     652        case kIrf_Irte_Present_Invalid:
     653        case kIrf_Pid_Read_Failed:
     654        case kIrf_Pid_Rsvd:
     655            return true;
     656        default:
     657            return false;
     658    }
     659}
     660
     661
     662/**
    625663 * Returns table translation mode's descriptive name.
    626664 *
     
    10081046 *
    10091047 * @param   pDevIns     The IOMMU device instance.
     1048 *
     1049 * @remarks This assumes the caller has already set the required status bits in the
     1050 *          FSTS_REG (namely one or more of PPF, PFO, IQE, ICE or ITE bits).
    10101051 */
    10111052static void dmarFaultEventRaiseInterrupt(PPDMDEVINS pDevIns)
     
    10911132
    10921133
    1093 #if 0
    10941134/**
    10951135 * Checks if a primary fault can be recorded.
     
    10981138 * @param   pDevIns     The IOMMU device instance.
    10991139 * @param   pThis       The shared DMAR device state.
     1140 *
     1141 * @remarks Warning: This function has side-effects wrt the DMAR register state. Do
     1142 *          NOT call it unless there is a fault condition!
    11001143 */
    11011144static bool dmarPrimaryFaultCanRecord(PPDMDEVINS pDevIns, PDMAR pThis)
     
    11241167    }
    11251168
    1126     uFstsReg |= VTD_BF_FSTS_REG_PPF_MASK;
    1127     dmarRegWrite32(pThis, VTD_MMIO_OFF_FSTS_REG, uFstsReg);
    11281169    return true;
    11291170}
    1130 #endif
     1171
     1172
     1173/**
     1174 * Records an interrupt request fault.
     1175 *
     1176 * @param   pDevIns     The IOMMU device instance.
     1177 * @param   enmDiag     The diagnostic reason.
     1178 * @param   enmIrFault  The interrupt fault reason.
     1179 * @param   idDevice    The device ID (bus, device, function).
     1180 * @param   idxIntr     The interrupt index.
     1181 */
     1182static void dmarIrFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTD_IR_FAULT_T enmIrFault, uint16_t idDevice,
     1183                              uint16_t idxIntr)
     1184{
     1185    PDMAR    pThis   = PDMDEVINS_2_DATA(pDevIns, PDMAR);
     1186    PCDMARCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PCDMARCC);
     1187    DMAR_ASSERT_LOCK_IS_OWNER(pDevIns, pThisCC);
     1188
     1189    /* Update the diagnostic reason. */
     1190    pThis->enmDiag = enmDiag;
     1191
     1192    /* We don't support advance fault logging. */
     1193    Assert(!(dmarRegRead32(pThis, VTD_MMIO_OFF_GSTS_REG) & VTD_BF_GSTS_REG_AFLS_MASK));
     1194
     1195    if (dmarPrimaryFaultCanRecord(pDevIns, pThis))
     1196    {
     1197        /* Update the fault recording registers with the fault information. */
     1198        uint64_t const uFrcdHi = RT_BF_MAKE(VTD_BF_1_FRCD_REG_SID, idDevice)
     1199                               | RT_BF_MAKE(VTD_BF_1_FRCD_REG_FR,  enmIrFault)
     1200                               | RT_BF_MAKE(VTD_BF_1_FRCD_REG_F,   1);
     1201        uint64_t const uFrcdLo = (uint64_t)idxIntr << 48;
     1202        dmarRegWriteRaw64(pThis, DMAR_MMIO_OFF_FRCD_HI_REG, uFrcdHi);
     1203        dmarRegWriteRaw64(pThis, DMAR_MMIO_OFF_FRCD_LO_REG, uFrcdLo);
     1204
     1205        /* Set the Pending Primary Fault (PPF) field in the status register. */
     1206        dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_FSTS_REG, UINT32_MAX, VTD_BF_FSTS_REG_PPF_MASK);
     1207
     1208        /* Raise interrupt if necessary. */
     1209        dmarFaultEventRaiseInterrupt(pDevIns);
     1210    }
     1211}
     1212
     1213
     1214/**
     1215 * Records a qualified interrupt request fault.
     1216 *
     1217 * Qualified faults are those that can be suppressed by software using the FPD bit
     1218 * in the IRTE.
     1219 *
     1220 * @param   pDevIns     The IOMMU device instance.
     1221 * @param   enmDiag     The diagnostic reason.
     1222 * @param   enmIrFault  The interrupt fault reason.
     1223 * @param   idDevice    The device ID (bus, device, function).
     1224 * @param   idxIntr     The interrupt index.
     1225 * @param   pIrte       The IRTE that caused this fault.
     1226 */
     1227static void dmarIrFaultRecordQualified(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTD_IR_FAULT_T enmIrFault, uint16_t idDevice,
     1228                                       uint16_t idxIntr, PCVTD_IRTE_T pIrte)
     1229{
     1230    Assert(vtdIrFaultIsQualified(enmIrFault));
     1231    Assert(pIrte);
     1232    if (!(pIrte->au64[0] & VTD_BF_0_IRTE_FPD_MASK))
     1233        return dmarIrFaultRecord(pDevIns, enmDiag, enmIrFault, idDevice, idxIntr);
     1234}
    11311235
    11321236
     
    11821286        {
    11831287            /* Enable the invalidation-queue. */
    1184             dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, UINT32_MAX /* fAndMask */, VTD_BF_GSTS_REG_QIES_MASK /* fOrMask */);
     1288            dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, UINT32_MAX, VTD_BF_GSTS_REG_QIES_MASK);
    11851289            dmarInvQueueThreadWakeUpIfNeeded(pDevIns);
    11861290        }
     
    11881292        {
    11891293            /* Disable the invalidation-queue. */
    1190             dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, ~VTD_BF_GSTS_REG_QIES_MASK /* fAndMask */, 0 /* fOrMask */);
     1294            dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, ~VTD_BF_GSTS_REG_QIES_MASK, 0 /* fOrMask */);
    11911295            dmarRegWriteRaw32(pThis, VTD_MMIO_OFF_IQH_REG, 0);
    11921296        }
     
    12031307             *        supported. */
    12041308            pThis->uIrtaReg = dmarRegReadRaw64(pThis, VTD_MMIO_OFF_IRTA_REG);
    1205             dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, UINT32_MAX /* fAndMask */, VTD_BF_GSTS_REG_IRTPS_MASK /* fOrMask */);
     1309            dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, UINT32_MAX, VTD_BF_GSTS_REG_IRTPS_MASK);
    12061310        }
    12071311
     
    12121316        {
    12131317            if (uGcmdReg & VTD_BF_GCMD_REG_IRE_MASK)
    1214                 dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, UINT32_MAX /* fAndMask */,
    1215                                    VTD_BF_GSTS_REG_IRES_MASK /* fOrMask */);
     1318                dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, UINT32_MAX, VTD_BF_GSTS_REG_IRES_MASK);
    12161319            else
    1217                 dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, ~VTD_BF_GSTS_REG_IRES_MASK /* fAndMask */, 0 /* fOrMask */);
     1320                dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, ~VTD_BF_GSTS_REG_IRES_MASK, 0 /* fOrMask */);
    12181321        }
    12191322    }
     
    12751378            else
    12761379                pThis->enmDiag = kDmarDiag_CcmdReg_NotSupported;
    1277             dmarRegChangeRaw64(pThis, VTD_MMIO_OFF_GSTS_REG, ~VTD_BF_CCMD_REG_CAIG_MASK /* fAndMask */, 0 /* fOrMask */);
     1380            dmarRegChangeRaw64(pThis, VTD_MMIO_OFF_GSTS_REG, ~VTD_BF_CCMD_REG_CAIG_MASK, 0 /* fOrMask */);
    12781381        }
    12791382    }
     
    13101413    {
    13111414        /* Hardware treats bit 4 as RsvdZ in this situation, so clear it. */
    1312         dmarRegChangeRaw32(pThis, offReg, ~RT_BIT(4) /* fAndMask*/ , 0 /* fOrMask */);
     1415        dmarRegChangeRaw32(pThis, offReg, ~RT_BIT(4), 0 /* fOrMask */);
    13131416        dmarIqeFaultRecord(pDevIns, kDmarDiag_IqtReg_Qt_NotAligned, kIqei_QueueTailNotAligned);
    13141417    }
     
    13951498
    13961499/**
     1500 * Reads an IRTE from guest memory.
     1501 *
     1502 * @returns VBox status code.
     1503 * @param   pDevIns     The IOMMU device instance.
     1504 * @param   uIrtaReg    The IRTA_REG.
     1505 * @param   idxIntr     The interrupt index.
     1506 * @param   pIrte       Where to store the read IRTE.
     1507 */
     1508static int dmarIrReadIrte(PPDMDEVINS pDevIns, uint64_t uIrtaReg, uint16_t idxIntr, PVTD_IRTE_T pIrte)
     1509{
     1510    Assert(idxIntr < VTD_IRTA_REG_GET_ENTRIES(uIrtaReg));
     1511
     1512    size_t const   cbIrte     = sizeof(*pIrte);
     1513    RTGCPHYS const GCPhysIrte = (uIrtaReg & VTD_BF_IRTA_REG_IRTA_MASK) + (idxIntr * cbIrte);
     1514    int rc = PDMDevHlpPhysReadMeta(pDevIns, GCPhysIrte, pIrte, cbIrte);
     1515    if (RT_SUCCESS(rc))
     1516        return VINF_SUCCESS;
     1517    return rc;
     1518}
     1519
     1520
     1521/**
     1522 * Handles remapping of interrupts in remappable interrupt format.
     1523 *
     1524 * @returns VBox status code.
     1525 * @param   pDevIns     The IOMMU device instance.
     1526 * @param   uIrtaReg    The IRTA_REG.
     1527 * @param   uGstsReg    The GSTS_REG.
     1528 * @param   idDevice    The device ID (bus, device, function).
     1529 * @param   pMsiIn      The source MSI.
     1530 * @param   pMsiOut     Where to store the remapped MSI.
     1531 */
     1532static int dmarIrRemapIntr(PPDMDEVINS pDevIns, uint64_t uIrtaReg, uint16_t idDevice, PCMSIMSG pMsiIn, PMSIMSG pMsiOut)
     1533{
     1534    Assert(VTD_MSI_ADDR_GET_INTR_FORMAT(pMsiIn->Addr.u64) == VTD_INTR_FORMAT_REMAPPABLE);
     1535
     1536    /* Validate reserved bits in the interrupt request. */
     1537    AssertCompile(VTD_REMAPPABLE_MSI_ADDR_VALID_MASK == UINT32_MAX);
     1538    if (!(pMsiIn->Data.u32 & ~VTD_REMAPPABLE_MSI_DATA_VALID_MASK))
     1539    { /* likely */ }
     1540    else
     1541    {
     1542        dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Rsvd, kIrf_Remappable_Intr_Rsvd, idDevice, 0 /* idxIntr */);
     1543        return VERR_IOMMU_INTR_REMAP_DENIED;
     1544    }
     1545
     1546    /* Compute the index into the interrupt remap table. */
     1547    uint16_t const uHandleHi       = RT_BF_GET(pMsiIn->Addr.au32[0], VTD_BF_REMAPPABLE_MSI_ADDR_HANDLE_HI);
     1548    uint16_t const uHandleLo       = RT_BF_GET(pMsiIn->Addr.au32[0], VTD_BF_REMAPPABLE_MSI_ADDR_HANDLE_LO);
     1549    uint16_t const uHandle         = uHandleLo | (uHandleHi << 15);
     1550    bool const     fSubHandleValid = RT_BF_GET(pMsiIn->Addr.au32[0], VTD_BF_REMAPPABLE_MSI_ADDR_SHV);
     1551    uint32_t const idxIntr         = fSubHandleValid
     1552                                   ? uHandle + RT_BF_GET(pMsiIn->Data.u32, VTD_BF_REMAPPABLE_MSI_DATA_SUBHANDLE)
     1553                                   : uHandle;
     1554
     1555    /* Validate the index. */
     1556    uint32_t const cEntries = VTD_IRTA_REG_GET_ENTRIES(uIrtaReg);
     1557    if (idxIntr < cEntries)
     1558    { /* likely */ }
     1559    else
     1560    {
     1561        dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Intr_Index_Invalid, kIrf_Intr_Index_Invalid, idDevice, idxIntr);
     1562        return VERR_IOMMU_INTR_REMAP_DENIED;
     1563    }
     1564
     1565    /** @todo Implement and read IRTE from interrupt-entry cache here. */
     1566
     1567    /* Read the interrupt remap table entry (IRTE). */
     1568    VTD_IRTE_T Irte;
     1569    int rc = dmarIrReadIrte(pDevIns, uIrtaReg, idxIntr, &Irte);
     1570    if (RT_SUCCESS(rc))
     1571    { /* likely */ }
     1572    else
     1573    {
     1574        dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Irte_Read_Failed, kIrf_Irte_Read_Failed, idDevice, idxIntr);
     1575        return VERR_IOMMU_INTR_REMAP_DENIED;
     1576    }
     1577
     1578    /* Validate IRTE. */
     1579    uint64_t const uIrteQword0 = Irte.au64[0];
     1580    uint64_t const uIrteQword1 = Irte.au64[1];
     1581    bool const fPresent = RT_BF_GET(uIrteQword0, VTD_BF_0_IRTE_P);
     1582    if (fPresent)
     1583    { /* likely */ }
     1584    else
     1585    {
     1586        dmarIrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Not_Present, kIrf_Irte_Not_Present, idDevice, idxIntr, &Irte);
     1587        return VERR_IOMMU_INTR_REMAP_DENIED;
     1588    }
     1589    if (   !(uIrteQword0 & ~VTD_IRTE_0_VALID_MASK)
     1590        && !(uIrteQword1 & ~VTD_IRTE_1_VALID_MASK))
     1591    { /* likely */ }
     1592    else
     1593    {
     1594        dmarIrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Rsvd, kIrf_Irte_Present_Rsvd, idDevice, idxIntr, &Irte);
     1595        return VERR_IOMMU_INTR_REMAP_DENIED;
     1596    }
     1597
     1598    /** @todo rest of validation using SVT and SQ. */
     1599    *pMsiOut = *pMsiIn;      // This is just temporary to shut up the compiler!
     1600    return VERR_NOT_IMPLEMENTED;
     1601}
     1602
     1603
     1604/**
    13971605 * Interrupt remap request from a device.
    13981606 *
     
    14201628    DMAR_UNLOCK(pDevIns, pThisCC);
    14211629
     1630    /* Check if interrupt remapping is enabled. */
    14221631    if (uGstsReg & VTD_BF_GSTS_REG_IRES_MASK)
    14231632    {
    14241633        STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMsiRemap));
    14251634
    1426         /*
    1427          * Handle interrupts in compatibility format.
    1428          */
     1635        /* Handle compatibility format interrupts. */
    14291636        uint8_t const fIntrFormat = VTD_MSI_ADDR_GET_INTR_FORMAT(pMsiIn->Addr.u64);
    14301637        if (fIntrFormat == VTD_INTR_FORMAT_COMPAT)
    14311638        {
    1432             /* If Extended Interrupt Mode (EIM) is enabled or compatibility format interrupts (CFI) are  disabled,
    1433                block the interrupt. */
     1639            /* If in Extended Interrupt Mode (EIM) or compatibility format interrupts are  disabled, block the interrupt. */
    14341640            if (    (uIrtaReg & VTD_BF_IRTA_REG_EIME_MASK)
    14351641                || !(uGstsReg & VTD_BF_GSTS_REG_CFIS_MASK))
     1642            {
     1643                dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Cfi_Blocked, kIrf_Cfi_Blocked, idDevice, 0 /* idxIntr */);
    14361644                return VERR_IOMMU_INTR_REMAP_DENIED;
     1645            }
    14371646
    14381647            /* Interrupt isn't subject to remapping, pass-through the interrupt. */
     
    14411650        }
    14421651
    1443         /*
    1444          * Handle interrupts in remappable format.
    1445          */
    1446         /** @todo index IRTA. */
    1447     }
    1448     else
    1449     {
    1450         /* If interrupt-remapping isn't enabled, all interrupts are pass-through.  */
    1451         *pMsiOut = *pMsiIn;
    1452     }
    1453 
     1652        /* Handle remappable format interrupts. */
     1653        return dmarIrRemapIntr(pDevIns, uIrtaReg, idDevice, pMsiIn, pMsiOut);
     1654    }
     1655
     1656    /* If interrupt-remapping isn't enabled, all interrupts are pass-through.  */
     1657    *pMsiOut = *pMsiIn;
    14541658    return VINF_SUCCESS;
    14551659}
     
    19292133    uint64_t const uMtrrcapReg  = dmarRegReadRaw64(pThis, VTD_MMIO_OFF_MTRRCAP_REG);
    19302134    uint64_t const uMtrrdefReg  = dmarRegReadRaw64(pThis, VTD_MMIO_OFF_MTRRDEF_REG);
    1931     /** @todo Do other registers as required, we don't implement them for now. */
    19322135
    19332136    DMAR_UNLOCK(pDevIns, pThisR3);
     
    19362139    pHlp->pfnPrintf(pHlp, "Intel-IOMMU:\n");
    19372140    pHlp->pfnPrintf(pHlp, " Diag         = %s\n", pszDiag);
     2141
     2142    /*
     2143     * Non-verbose output.
     2144     */
    19382145    if (!fVerbose)
    19392146    {
     
    19772184        pHlp->pfnPrintf(pHlp, " MTRRDEF_REG  = %#RX64\n", uMtrrdefReg);
    19782185        pHlp->pfnPrintf(pHlp, "\n");
    1979     }
    1980     else
    1981     {
    1982         pHlp->pfnPrintf(pHlp, " VER_REG      = %#RX32\n", uVerReg);
    1983         {
    1984             pHlp->pfnPrintf(pHlp, "   MAJ          = %#x\n", RT_BF_GET(uVerReg, VTD_BF_VER_REG_MAX));
    1985             pHlp->pfnPrintf(pHlp, "   MIN          = %#x\n", RT_BF_GET(uVerReg, VTD_BF_VER_REG_MIN));
    1986         }
    1987         pHlp->pfnPrintf(pHlp, " CAP_REG      = %#RX64\n", uCapReg);
    1988         {
    1989             uint8_t const uSagaw = RT_BF_GET(uCapReg, VTD_BF_CAP_REG_SAGAW);
    1990             uint8_t const uMgaw  = RT_BF_GET(uCapReg, VTD_BF_CAP_REG_MGAW);
    1991             uint8_t const uNfr   = RT_BF_GET(uCapReg, VTD_BF_CAP_REG_NFR);
    1992             pHlp->pfnPrintf(pHlp, "   ND           = %u\n",         RT_BF_GET(uCapReg, VTD_BF_CAP_REG_ND));
    1993             pHlp->pfnPrintf(pHlp, "   AFL          = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_AFL));
    1994             pHlp->pfnPrintf(pHlp, "   RWBF         = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_RWBF));
    1995             pHlp->pfnPrintf(pHlp, "   PLMR         = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_PLMR));
    1996             pHlp->pfnPrintf(pHlp, "   PHMR         = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_PHMR));
    1997             pHlp->pfnPrintf(pHlp, "   CM           = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_CM));
    1998             pHlp->pfnPrintf(pHlp, "   SAGAW        = %#x (%u bits)\n", uSagaw, vtdCapRegGetSagawBits(uSagaw));
    1999             pHlp->pfnPrintf(pHlp, "   MGAW         = %#x (%u bits)\n", uMgaw, uMgaw + 1);
    2000             pHlp->pfnPrintf(pHlp, "   ZLR          = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_ZLR));
    2001             pHlp->pfnPrintf(pHlp, "   FRO          = %#x bytes\n",  RT_BF_GET(uCapReg, VTD_BF_CAP_REG_FRO));
    2002             pHlp->pfnPrintf(pHlp, "   SLLPS        = %#x\n",        RT_BF_GET(uCapReg, VTD_BF_CAP_REG_SLLPS));
    2003             pHlp->pfnPrintf(pHlp, "   PSI          = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_PSI));
    2004             pHlp->pfnPrintf(pHlp, "   NFR          = %u (%u FRCD register%s)\n", uNfr, uNfr + 1, uNfr > 0 ? "s" : "");
    2005             pHlp->pfnPrintf(pHlp, "   MAMV         = %#x\n",        RT_BF_GET(uCapReg, VTD_BF_CAP_REG_MAMV));
    2006             pHlp->pfnPrintf(pHlp, "   DWD          = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_DWD));
    2007             pHlp->pfnPrintf(pHlp, "   DRD          = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_DRD));
    2008             pHlp->pfnPrintf(pHlp, "   FL1GP        = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_FL1GP));
    2009             pHlp->pfnPrintf(pHlp, "   PI           = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_PI));
    2010             pHlp->pfnPrintf(pHlp, "   FL5LP        = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_FL5LP));
    2011             pHlp->pfnPrintf(pHlp, "   ESIRTPS      = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_ESIRTPS));
    2012             pHlp->pfnPrintf(pHlp, "   ESRTPS       = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_ESRTPS));
    2013         }
    2014         pHlp->pfnPrintf(pHlp, " ECAP_REG     = %#RX64\n", uEcapReg);
    2015         {
    2016             uint8_t const uPss = RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_PSS);
    2017             pHlp->pfnPrintf(pHlp, "   C            = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_C));
    2018             pHlp->pfnPrintf(pHlp, "   QI           = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_QI));
    2019             pHlp->pfnPrintf(pHlp, "   DT           = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_DT));
    2020             pHlp->pfnPrintf(pHlp, "   IR           = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_IR));
    2021             pHlp->pfnPrintf(pHlp, "   EIM          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_EIM));
    2022             pHlp->pfnPrintf(pHlp, "   PT           = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_PT));
    2023             pHlp->pfnPrintf(pHlp, "   SC           = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_SC));
    2024             pHlp->pfnPrintf(pHlp, "   IRO          = %#x bytes\n",  RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_IRO));
    2025             pHlp->pfnPrintf(pHlp, "   MHMV         = %#x\n",        RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_MHMV));
    2026             pHlp->pfnPrintf(pHlp, "   MTS          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_MTS));
    2027             pHlp->pfnPrintf(pHlp, "   NEST         = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_NEST));
    2028             pHlp->pfnPrintf(pHlp, "   PRS          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_PRS));
    2029             pHlp->pfnPrintf(pHlp, "   ERS          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_ERS));
    2030             pHlp->pfnPrintf(pHlp, "   SRS          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_SRS));
    2031             pHlp->pfnPrintf(pHlp, "   NWFS         = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_NWFS));
    2032             pHlp->pfnPrintf(pHlp, "   EAFS         = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_EAFS));
    2033             pHlp->pfnPrintf(pHlp, "   PSS          = %u (%u bits)\n", uPss, uPss > 0 ? uPss + 1 : 0);
    2034             pHlp->pfnPrintf(pHlp, "   PASID        = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_PASID));
    2035             pHlp->pfnPrintf(pHlp, "   DIT          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_DIT));
    2036             pHlp->pfnPrintf(pHlp, "   PDS          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_PDS));
    2037             pHlp->pfnPrintf(pHlp, "   SMTS         = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_SMTS));
    2038             pHlp->pfnPrintf(pHlp, "   VCS          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_VCS));
    2039             pHlp->pfnPrintf(pHlp, "   SLADS        = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_SLADS));
    2040             pHlp->pfnPrintf(pHlp, "   SLTS         = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_SLTS));
    2041             pHlp->pfnPrintf(pHlp, "   FLTS         = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_FLTS));
    2042             pHlp->pfnPrintf(pHlp, "   SMPWCS       = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_SMPWCS));
    2043             pHlp->pfnPrintf(pHlp, "   RPS          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_RPS));
    2044             pHlp->pfnPrintf(pHlp, "   ADMS         = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_ADMS));
    2045             pHlp->pfnPrintf(pHlp, "   RPRIVS       = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_RPRIVS));
    2046         }
    2047         pHlp->pfnPrintf(pHlp, " GCMD_REG     = %#RX32\n", uGcmdReg);
    2048         {
    2049             uint8_t const fCfi = RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_CFI);
    2050             pHlp->pfnPrintf(pHlp, "   CFI          = %u (%s)\n", fCfi, fCfi ? "Bypass interrupt remapping"
    2051                                                                             : "Block compatible format interrupts");
    2052             pHlp->pfnPrintf(pHlp, "   SIRTP        = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_SIRTP));
    2053             pHlp->pfnPrintf(pHlp, "   IRE          = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_IRE));
    2054             pHlp->pfnPrintf(pHlp, "   QIE          = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_QIE));
    2055             pHlp->pfnPrintf(pHlp, "   WBF          = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_WBF));
    2056             pHlp->pfnPrintf(pHlp, "   EAFL         = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_SFL));
    2057             pHlp->pfnPrintf(pHlp, "   SFL          = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_SFL));
    2058             pHlp->pfnPrintf(pHlp, "   SRTP         = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_SRTP));
    2059             pHlp->pfnPrintf(pHlp, "   TE           = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_TE));
    2060         }
    2061         pHlp->pfnPrintf(pHlp, " GSTS_REG     = %#RX32\n", uGstsReg);
    2062         {
    2063             uint8_t const fCfis = RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_CFIS);
    2064             pHlp->pfnPrintf(pHlp, "   CFIS         = %u (%s)\n", fCfis, fCfis ? "Bypass interrupt remapping"
    2065                                                                               : "Block compatible format interrupts");
    2066             pHlp->pfnPrintf(pHlp, "   IRTPS        = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_IRTPS));
    2067             pHlp->pfnPrintf(pHlp, "   IRES         = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_IRES));
    2068             pHlp->pfnPrintf(pHlp, "   QIES         = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_QIES));
    2069             pHlp->pfnPrintf(pHlp, "   WBFS         = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_WBFS));
    2070             pHlp->pfnPrintf(pHlp, "   AFLS         = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_AFLS));
    2071             pHlp->pfnPrintf(pHlp, "   FLS          = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_FLS));
    2072             pHlp->pfnPrintf(pHlp, "   RTPS         = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_RTPS));
    2073             pHlp->pfnPrintf(pHlp, "   TES          = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_TES));
    2074         }
    2075         pHlp->pfnPrintf(pHlp, " RTADDR_REG   = %#RX64\n", uRtaddrReg);
    2076         {
    2077             uint8_t const uTtm = RT_BF_GET(uRtaddrReg, VTD_BF_RTADDR_REG_TTM);
    2078             pHlp->pfnPrintf(pHlp, "   TTM          = %u (%s)\n",  uTtm, vtdRtaddrRegGetTtmDesc(uTtm));
    2079             pHlp->pfnPrintf(pHlp, "   RTA          = %#RX64\n",   RT_BF_GET(uRtaddrReg, VTD_BF_RTADDR_REG_RTA));
    2080         }
    2081         pHlp->pfnPrintf(pHlp, " CCMD_REG     = %#RX64\n", uCcmdReg);
    2082         pHlp->pfnPrintf(pHlp, " FSTS_REG     = %#RX32\n", uFstsReg);
    2083         {
    2084             pHlp->pfnPrintf(pHlp, "   PFO          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_PFO));
    2085             pHlp->pfnPrintf(pHlp, "   PPF          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_PPF));
    2086             pHlp->pfnPrintf(pHlp, "   AFO          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_AFO));
    2087             pHlp->pfnPrintf(pHlp, "   APF          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_APF));
    2088             pHlp->pfnPrintf(pHlp, "   IQE          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_IQE));
    2089             pHlp->pfnPrintf(pHlp, "   ICS          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_ICE));
    2090             pHlp->pfnPrintf(pHlp, "   ITE          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_ITE));
    2091             pHlp->pfnPrintf(pHlp, "   FRI          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_FRI));
    2092         }
    2093         pHlp->pfnPrintf(pHlp, " FECTL_REG    = %#RX32\n", uFectlReg);
    2094         {
    2095             pHlp->pfnPrintf(pHlp, "   IM           = %RTbool\n",  RT_BF_GET(uFectlReg, VTD_BF_FECTL_REG_IM));
    2096             pHlp->pfnPrintf(pHlp, "   IP           = %RTbool\n",  RT_BF_GET(uFectlReg, VTD_BF_FECTL_REG_IP));
    2097         }
    2098         pHlp->pfnPrintf(pHlp, " FEDATA_REG   = %#RX32\n", uFedataReg);
    2099         pHlp->pfnPrintf(pHlp, " FEADDR_REG   = %#RX32\n", uFeaddrReg);
    2100         pHlp->pfnPrintf(pHlp, " FEUADDR_REG  = %#RX32\n", uFeuaddrReg);
    2101         pHlp->pfnPrintf(pHlp, " AFLOG_REG    = %#RX64\n", uAflogReg);
    2102         pHlp->pfnPrintf(pHlp, " PMEN_REG     = %#RX32\n", uPmenReg);
    2103         pHlp->pfnPrintf(pHlp, " PLMBASE_REG  = %#RX32\n", uPlmbaseReg);
    2104         pHlp->pfnPrintf(pHlp, " PLMLIMIT_REG = %#RX32\n", uPlmlimitReg);
    2105         pHlp->pfnPrintf(pHlp, " PHMBASE_REG  = %#RX64\n", uPhmbaseReg);
    2106         pHlp->pfnPrintf(pHlp, " PHMLIMIT_REG = %#RX64\n", uPhmlimitReg);
    2107         pHlp->pfnPrintf(pHlp, " IQH_REG      = %#RX64\n", uIqhReg);
    2108         pHlp->pfnPrintf(pHlp, " IQT_REG      = %#RX64\n", uIqtReg);
    2109         pHlp->pfnPrintf(pHlp, " IQA_REG      = %#RX64\n", uIqaReg);
    2110         {
    2111             uint8_t const  fDw = RT_BF_GET(uIqaReg, VTD_BF_IQA_REG_DW);
    2112             uint8_t const  fQs = RT_BF_GET(uIqaReg, VTD_BF_IQA_REG_QS);
    2113             uint8_t const  cQueuePages = 1 << fQs;
    2114             pHlp->pfnPrintf(pHlp, "   DW           = %u (%s)\n",  fDw, fDw == VTD_IQA_REG_DW_128_BIT ? "128-bit" : "256-bit");
    2115             pHlp->pfnPrintf(pHlp, "   QS           = %u (%u page%s)\n", fQs, cQueuePages, cQueuePages > 1 ? "s" : "");
    2116         }
    2117         pHlp->pfnPrintf(pHlp, " ICS_REG      = %#RX32\n", uIcsReg);
    2118         {
    2119             pHlp->pfnPrintf(pHlp, "   IWC          = %u\n",       RT_BF_GET(uIcsReg, VTD_BF_ICS_REG_IWC));
    2120         }
    2121         pHlp->pfnPrintf(pHlp, " IECTL_REG    = %#RX32\n", uIectlReg);
    2122         {
    2123             pHlp->pfnPrintf(pHlp, "   IM           = %RTbool\n",  RT_BF_GET(uIectlReg, VTD_BF_IECTL_REG_IM));
    2124             pHlp->pfnPrintf(pHlp, "   IP           = %RTbool\n",  RT_BF_GET(uIectlReg, VTD_BF_IECTL_REG_IP));
    2125         }
    2126         pHlp->pfnPrintf(pHlp, " IEDATA_REG   = %#RX32\n", uIedataReg);
    2127         pHlp->pfnPrintf(pHlp, " IEADDR_REG   = %#RX32\n", uIeaddrReg);
    2128         pHlp->pfnPrintf(pHlp, " IEUADDR_REG  = %#RX32\n", uIeuaddrReg);
    2129         pHlp->pfnPrintf(pHlp, " IQERCD_REG   = %#RX64\n", uIqercdReg);
    2130         {
    2131             pHlp->pfnPrintf(pHlp, "   ICESID       = %#RX32\n",   RT_BF_GET(uIqercdReg, VTD_BF_IQERCD_REG_ICESID));
    2132             pHlp->pfnPrintf(pHlp, "   ITESID       = %#RX32\n",   RT_BF_GET(uIqercdReg, VTD_BF_IQERCD_REG_ITESID));
    2133             pHlp->pfnPrintf(pHlp, "   IQEI         = %#RX32\n",   RT_BF_GET(uIqercdReg, VTD_BF_IQERCD_REG_IQEI));
    2134         }
    2135         pHlp->pfnPrintf(pHlp, " IRTA_REG     = %#RX64\n", uIrtaReg);
    2136         pHlp->pfnPrintf(pHlp, " PQH_REG      = %#RX64\n", uPqhReg);
    2137         pHlp->pfnPrintf(pHlp, " PQT_REG      = %#RX64\n", uPqtReg);
    2138         pHlp->pfnPrintf(pHlp, " PQA_REG      = %#RX64\n", uPqaReg);
    2139         pHlp->pfnPrintf(pHlp, " PRS_REG      = %#RX32\n", uPrsReg);
    2140         pHlp->pfnPrintf(pHlp, " PECTL_REG    = %#RX32\n", uPectlReg);
    2141         pHlp->pfnPrintf(pHlp, " PEDATA_REG   = %#RX32\n", uPedataReg);
    2142         pHlp->pfnPrintf(pHlp, " PEADDR_REG   = %#RX32\n", uPeaddrReg);
    2143         pHlp->pfnPrintf(pHlp, " PEUADDR_REG  = %#RX32\n", uPeuaddrReg);
    2144         pHlp->pfnPrintf(pHlp, " MTRRCAP_REG  = %#RX64\n", uMtrrcapReg);
    2145         pHlp->pfnPrintf(pHlp, " MTRRDEF_REG  = %#RX64\n", uMtrrdefReg);
    2146         pHlp->pfnPrintf(pHlp, "\n");
    2147     }
     2186        return;
     2187    }
     2188
     2189    /*
     2190     * Verbose output.
     2191     */
     2192    pHlp->pfnPrintf(pHlp, " VER_REG      = %#RX32\n", uVerReg);
     2193    {
     2194        pHlp->pfnPrintf(pHlp, "   MAJ          = %#x\n", RT_BF_GET(uVerReg, VTD_BF_VER_REG_MAX));
     2195        pHlp->pfnPrintf(pHlp, "   MIN          = %#x\n", RT_BF_GET(uVerReg, VTD_BF_VER_REG_MIN));
     2196    }
     2197    pHlp->pfnPrintf(pHlp, " CAP_REG      = %#RX64\n", uCapReg);
     2198    {
     2199        uint8_t const uSagaw = RT_BF_GET(uCapReg, VTD_BF_CAP_REG_SAGAW);
     2200        uint8_t const uMgaw  = RT_BF_GET(uCapReg, VTD_BF_CAP_REG_MGAW);
     2201        uint8_t const uNfr   = RT_BF_GET(uCapReg, VTD_BF_CAP_REG_NFR);
     2202        pHlp->pfnPrintf(pHlp, "   ND           = %u\n",         RT_BF_GET(uCapReg, VTD_BF_CAP_REG_ND));
     2203        pHlp->pfnPrintf(pHlp, "   AFL          = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_AFL));
     2204        pHlp->pfnPrintf(pHlp, "   RWBF         = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_RWBF));
     2205        pHlp->pfnPrintf(pHlp, "   PLMR         = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_PLMR));
     2206        pHlp->pfnPrintf(pHlp, "   PHMR         = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_PHMR));
     2207        pHlp->pfnPrintf(pHlp, "   CM           = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_CM));
     2208        pHlp->pfnPrintf(pHlp, "   SAGAW        = %#x (%u bits)\n", uSagaw, vtdCapRegGetSagawBits(uSagaw));
     2209        pHlp->pfnPrintf(pHlp, "   MGAW         = %#x (%u bits)\n", uMgaw, uMgaw + 1);
     2210        pHlp->pfnPrintf(pHlp, "   ZLR          = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_ZLR));
     2211        pHlp->pfnPrintf(pHlp, "   FRO          = %#x bytes\n",  RT_BF_GET(uCapReg, VTD_BF_CAP_REG_FRO));
     2212        pHlp->pfnPrintf(pHlp, "   SLLPS        = %#x\n",        RT_BF_GET(uCapReg, VTD_BF_CAP_REG_SLLPS));
     2213        pHlp->pfnPrintf(pHlp, "   PSI          = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_PSI));
     2214        pHlp->pfnPrintf(pHlp, "   NFR          = %u (%u FRCD register%s)\n", uNfr, uNfr + 1, uNfr > 0 ? "s" : "");
     2215        pHlp->pfnPrintf(pHlp, "   MAMV         = %#x\n",        RT_BF_GET(uCapReg, VTD_BF_CAP_REG_MAMV));
     2216        pHlp->pfnPrintf(pHlp, "   DWD          = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_DWD));
     2217        pHlp->pfnPrintf(pHlp, "   DRD          = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_DRD));
     2218        pHlp->pfnPrintf(pHlp, "   FL1GP        = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_FL1GP));
     2219        pHlp->pfnPrintf(pHlp, "   PI           = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_PI));
     2220        pHlp->pfnPrintf(pHlp, "   FL5LP        = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_FL5LP));
     2221        pHlp->pfnPrintf(pHlp, "   ESIRTPS      = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_ESIRTPS));
     2222        pHlp->pfnPrintf(pHlp, "   ESRTPS       = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_ESRTPS));
     2223    }
     2224    pHlp->pfnPrintf(pHlp, " ECAP_REG     = %#RX64\n", uEcapReg);
     2225    {
     2226        uint8_t const uPss = RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_PSS);
     2227        pHlp->pfnPrintf(pHlp, "   C            = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_C));
     2228        pHlp->pfnPrintf(pHlp, "   QI           = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_QI));
     2229        pHlp->pfnPrintf(pHlp, "   DT           = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_DT));
     2230        pHlp->pfnPrintf(pHlp, "   IR           = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_IR));
     2231        pHlp->pfnPrintf(pHlp, "   EIM          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_EIM));
     2232        pHlp->pfnPrintf(pHlp, "   PT           = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_PT));
     2233        pHlp->pfnPrintf(pHlp, "   SC           = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_SC));
     2234        pHlp->pfnPrintf(pHlp, "   IRO          = %#x bytes\n",  RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_IRO));
     2235        pHlp->pfnPrintf(pHlp, "   MHMV         = %#x\n",        RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_MHMV));
     2236        pHlp->pfnPrintf(pHlp, "   MTS          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_MTS));
     2237        pHlp->pfnPrintf(pHlp, "   NEST         = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_NEST));
     2238        pHlp->pfnPrintf(pHlp, "   PRS          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_PRS));
     2239        pHlp->pfnPrintf(pHlp, "   ERS          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_ERS));
     2240        pHlp->pfnPrintf(pHlp, "   SRS          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_SRS));
     2241        pHlp->pfnPrintf(pHlp, "   NWFS         = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_NWFS));
     2242        pHlp->pfnPrintf(pHlp, "   EAFS         = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_EAFS));
     2243        pHlp->pfnPrintf(pHlp, "   PSS          = %u (%u bits)\n", uPss, uPss > 0 ? uPss + 1 : 0);
     2244        pHlp->pfnPrintf(pHlp, "   PASID        = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_PASID));
     2245        pHlp->pfnPrintf(pHlp, "   DIT          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_DIT));
     2246        pHlp->pfnPrintf(pHlp, "   PDS          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_PDS));
     2247        pHlp->pfnPrintf(pHlp, "   SMTS         = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_SMTS));
     2248        pHlp->pfnPrintf(pHlp, "   VCS          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_VCS));
     2249        pHlp->pfnPrintf(pHlp, "   SLADS        = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_SLADS));
     2250        pHlp->pfnPrintf(pHlp, "   SLTS         = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_SLTS));
     2251        pHlp->pfnPrintf(pHlp, "   FLTS         = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_FLTS));
     2252        pHlp->pfnPrintf(pHlp, "   SMPWCS       = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_SMPWCS));
     2253        pHlp->pfnPrintf(pHlp, "   RPS          = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_RPS));
     2254        pHlp->pfnPrintf(pHlp, "   ADMS         = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_ADMS));
     2255        pHlp->pfnPrintf(pHlp, "   RPRIVS       = %RTbool\n",    RT_BF_GET(uEcapReg, VTD_BF_ECAP_REG_RPRIVS));
     2256    }
     2257    pHlp->pfnPrintf(pHlp, " GCMD_REG     = %#RX32\n", uGcmdReg);
     2258    {
     2259        uint8_t const fCfi = RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_CFI);
     2260        pHlp->pfnPrintf(pHlp, "   CFI          = %u (%s)\n", fCfi, fCfi ? "Bypass interrupt remapping"
     2261                                                                        : "Block compatible format interrupts");
     2262        pHlp->pfnPrintf(pHlp, "   SIRTP        = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_SIRTP));
     2263        pHlp->pfnPrintf(pHlp, "   IRE          = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_IRE));
     2264        pHlp->pfnPrintf(pHlp, "   QIE          = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_QIE));
     2265        pHlp->pfnPrintf(pHlp, "   WBF          = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_WBF));
     2266        pHlp->pfnPrintf(pHlp, "   EAFL         = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_SFL));
     2267        pHlp->pfnPrintf(pHlp, "   SFL          = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_SFL));
     2268        pHlp->pfnPrintf(pHlp, "   SRTP         = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_SRTP));
     2269        pHlp->pfnPrintf(pHlp, "   TE           = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_TE));
     2270    }
     2271    pHlp->pfnPrintf(pHlp, " GSTS_REG     = %#RX32\n", uGstsReg);
     2272    {
     2273        uint8_t const fCfis = RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_CFIS);
     2274        pHlp->pfnPrintf(pHlp, "   CFIS         = %u (%s)\n", fCfis, fCfis ? "Bypass interrupt remapping"
     2275                                                                          : "Block compatible format interrupts");
     2276        pHlp->pfnPrintf(pHlp, "   IRTPS        = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_IRTPS));
     2277        pHlp->pfnPrintf(pHlp, "   IRES         = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_IRES));
     2278        pHlp->pfnPrintf(pHlp, "   QIES         = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_QIES));
     2279        pHlp->pfnPrintf(pHlp, "   WBFS         = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_WBFS));
     2280        pHlp->pfnPrintf(pHlp, "   AFLS         = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_AFLS));
     2281        pHlp->pfnPrintf(pHlp, "   FLS          = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_FLS));
     2282        pHlp->pfnPrintf(pHlp, "   RTPS         = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_RTPS));
     2283        pHlp->pfnPrintf(pHlp, "   TES          = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_TES));
     2284    }
     2285    pHlp->pfnPrintf(pHlp, " RTADDR_REG   = %#RX64\n", uRtaddrReg);
     2286    {
     2287        uint8_t const uTtm = RT_BF_GET(uRtaddrReg, VTD_BF_RTADDR_REG_TTM);
     2288        pHlp->pfnPrintf(pHlp, "   TTM          = %u (%s)\n",  uTtm, vtdRtaddrRegGetTtmDesc(uTtm));
     2289        pHlp->pfnPrintf(pHlp, "   RTA          = %#RX64\n",   RT_BF_GET(uRtaddrReg, VTD_BF_RTADDR_REG_RTA));
     2290    }
     2291    pHlp->pfnPrintf(pHlp, " CCMD_REG     = %#RX64\n", uCcmdReg);
     2292    pHlp->pfnPrintf(pHlp, " FSTS_REG     = %#RX32\n", uFstsReg);
     2293    {
     2294        pHlp->pfnPrintf(pHlp, "   PFO          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_PFO));
     2295        pHlp->pfnPrintf(pHlp, "   PPF          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_PPF));
     2296        pHlp->pfnPrintf(pHlp, "   AFO          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_AFO));
     2297        pHlp->pfnPrintf(pHlp, "   APF          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_APF));
     2298        pHlp->pfnPrintf(pHlp, "   IQE          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_IQE));
     2299        pHlp->pfnPrintf(pHlp, "   ICS          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_ICE));
     2300        pHlp->pfnPrintf(pHlp, "   ITE          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_ITE));
     2301        pHlp->pfnPrintf(pHlp, "   FRI          = %u\n",  RT_BF_GET(uFstsReg, VTD_BF_FSTS_REG_FRI));
     2302    }
     2303    pHlp->pfnPrintf(pHlp, " FECTL_REG    = %#RX32\n", uFectlReg);
     2304    {
     2305        pHlp->pfnPrintf(pHlp, "   IM           = %RTbool\n",  RT_BF_GET(uFectlReg, VTD_BF_FECTL_REG_IM));
     2306        pHlp->pfnPrintf(pHlp, "   IP           = %RTbool\n",  RT_BF_GET(uFectlReg, VTD_BF_FECTL_REG_IP));
     2307    }
     2308    pHlp->pfnPrintf(pHlp, " FEDATA_REG   = %#RX32\n", uFedataReg);
     2309    pHlp->pfnPrintf(pHlp, " FEADDR_REG   = %#RX32\n", uFeaddrReg);
     2310    pHlp->pfnPrintf(pHlp, " FEUADDR_REG  = %#RX32\n", uFeuaddrReg);
     2311    pHlp->pfnPrintf(pHlp, " AFLOG_REG    = %#RX64\n", uAflogReg);
     2312    pHlp->pfnPrintf(pHlp, " PMEN_REG     = %#RX32\n", uPmenReg);
     2313    pHlp->pfnPrintf(pHlp, " PLMBASE_REG  = %#RX32\n", uPlmbaseReg);
     2314    pHlp->pfnPrintf(pHlp, " PLMLIMIT_REG = %#RX32\n", uPlmlimitReg);
     2315    pHlp->pfnPrintf(pHlp, " PHMBASE_REG  = %#RX64\n", uPhmbaseReg);
     2316    pHlp->pfnPrintf(pHlp, " PHMLIMIT_REG = %#RX64\n", uPhmlimitReg);
     2317    pHlp->pfnPrintf(pHlp, " IQH_REG      = %#RX64\n", uIqhReg);
     2318    pHlp->pfnPrintf(pHlp, " IQT_REG      = %#RX64\n", uIqtReg);
     2319    pHlp->pfnPrintf(pHlp, " IQA_REG      = %#RX64\n", uIqaReg);
     2320    {
     2321        uint8_t const  fDw = RT_BF_GET(uIqaReg, VTD_BF_IQA_REG_DW);
     2322        uint8_t const  fQs = RT_BF_GET(uIqaReg, VTD_BF_IQA_REG_QS);
     2323        uint8_t const  cQueuePages = 1 << fQs;
     2324        pHlp->pfnPrintf(pHlp, "   DW           = %u (%s)\n",  fDw, fDw == VTD_IQA_REG_DW_128_BIT ? "128-bit" : "256-bit");
     2325        pHlp->pfnPrintf(pHlp, "   QS           = %u (%u page%s)\n", fQs, cQueuePages, cQueuePages > 1 ? "s" : "");
     2326    }
     2327    pHlp->pfnPrintf(pHlp, " ICS_REG      = %#RX32\n", uIcsReg);
     2328    {
     2329        pHlp->pfnPrintf(pHlp, "   IWC          = %u\n",       RT_BF_GET(uIcsReg, VTD_BF_ICS_REG_IWC));
     2330    }
     2331    pHlp->pfnPrintf(pHlp, " IECTL_REG    = %#RX32\n", uIectlReg);
     2332    {
     2333        pHlp->pfnPrintf(pHlp, "   IM           = %RTbool\n",  RT_BF_GET(uIectlReg, VTD_BF_IECTL_REG_IM));
     2334        pHlp->pfnPrintf(pHlp, "   IP           = %RTbool\n",  RT_BF_GET(uIectlReg, VTD_BF_IECTL_REG_IP));
     2335    }
     2336    pHlp->pfnPrintf(pHlp, " IEDATA_REG   = %#RX32\n", uIedataReg);
     2337    pHlp->pfnPrintf(pHlp, " IEADDR_REG   = %#RX32\n", uIeaddrReg);
     2338    pHlp->pfnPrintf(pHlp, " IEUADDR_REG  = %#RX32\n", uIeuaddrReg);
     2339    pHlp->pfnPrintf(pHlp, " IQERCD_REG   = %#RX64\n", uIqercdReg);
     2340    {
     2341        pHlp->pfnPrintf(pHlp, "   ICESID       = %#RX32\n",   RT_BF_GET(uIqercdReg, VTD_BF_IQERCD_REG_ICESID));
     2342        pHlp->pfnPrintf(pHlp, "   ITESID       = %#RX32\n",   RT_BF_GET(uIqercdReg, VTD_BF_IQERCD_REG_ITESID));
     2343        pHlp->pfnPrintf(pHlp, "   IQEI         = %#RX32\n",   RT_BF_GET(uIqercdReg, VTD_BF_IQERCD_REG_IQEI));
     2344    }
     2345    pHlp->pfnPrintf(pHlp, " IRTA_REG     = %#RX64\n", uIrtaReg);
     2346    pHlp->pfnPrintf(pHlp, " PQH_REG      = %#RX64\n", uPqhReg);
     2347    pHlp->pfnPrintf(pHlp, " PQT_REG      = %#RX64\n", uPqtReg);
     2348    pHlp->pfnPrintf(pHlp, " PQA_REG      = %#RX64\n", uPqaReg);
     2349    pHlp->pfnPrintf(pHlp, " PRS_REG      = %#RX32\n", uPrsReg);
     2350    pHlp->pfnPrintf(pHlp, " PECTL_REG    = %#RX32\n", uPectlReg);
     2351    pHlp->pfnPrintf(pHlp, " PEDATA_REG   = %#RX32\n", uPedataReg);
     2352    pHlp->pfnPrintf(pHlp, " PEADDR_REG   = %#RX32\n", uPeaddrReg);
     2353    pHlp->pfnPrintf(pHlp, " PEUADDR_REG  = %#RX32\n", uPeuaddrReg);
     2354    pHlp->pfnPrintf(pHlp, " MTRRCAP_REG  = %#RX64\n", uMtrrcapReg);
     2355    pHlp->pfnPrintf(pHlp, " MTRRDEF_REG  = %#RX64\n", uMtrrdefReg);
     2356    pHlp->pfnPrintf(pHlp, "\n");
    21482357}
    21492358
     
    22972506static DECLCALLBACK(void) iommuIntelR3Reset(PPDMDEVINS pDevIns)
    22982507{
    2299     RT_NOREF1(pDevIns);
     2508    PCDMARR3 pThisR3 = PDMDEVINS_2_DATA_CC(pDevIns, PCDMARR3);
    23002509    LogFlowFunc(("\n"));
    23012510
    2302     PCDMARR3 pThisR3 = PDMDEVINS_2_DATA_CC(pDevIns, PCDMARR3);
    23032511    DMAR_LOCK(pDevIns, pThisR3);
    2304 
    23052512    dmarR3RegsInit(pDevIns);
    2306 
    23072513    DMAR_UNLOCK(pDevIns, pThisR3);
    23082514}
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