VirtualBox

Changeset 89003 in vbox for trunk/src/VBox/Devices/PC


Ignore:
Timestamp:
May 12, 2021 8:45:47 AM (4 years ago)
Author:
vboxsync
Message:

Intel IOMMU: bugref:9967 DevIoApic: Add support guests to program RTE's in Intel IOMMU format as well as generate MSIs in the IOMMU compatible remappable format when forwarding interrupts to the IOMMU.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevIoApic.cpp

    r88826 r89003  
    9393/** Redirection table entry - Trigger Mode. */
    9494#define IOAPIC_RTE_TRIGGER_MODE                 RT_BIT_64(15)
    95 /** Redirection table entry - the mask bit number. */
     95/** Redirection table entry - Number of bits to shift to get the Mask. */
    9696#define IOAPIC_RTE_MASK_BIT                     16
    97 /** Redirection table entry - the mask. */
     97/** Redirection table entry - The Mask. */
    9898#define IOAPIC_RTE_MASK                         RT_BIT_64(IOAPIC_RTE_MASK_BIT)
    9999/** Redirection table entry - Extended Destination ID. */
     
    123123#define IOAPIC_RTE_GET_VECTOR(a_Reg)            ((a_Reg) & IOAPIC_RTE_VECTOR)
    124124
     125/** @name DMAR variant interpretation of RTE fields.
     126 * @{ */
     127/** Redirection table entry - Number of bits to shift to get Interrupt
     128 *  Index[14:0]. */
     129#define IOAPIC_RTE_INTR_INDEX_LO_BIT            49
     130/** Redirection table entry - Interrupt Index[14:0]. */
     131#define IOAPIC_RTE_INTR_INDEX_LO                UINT64_C(0xfffe000000000000)
     132/** Redirection table entry - Number of bits to shift to get interrupt format. */
     133#define IOAPIC_RTE_INTR_FORMAT_BIT              48
     134/** Redirection table entry - Interrupt format. */
     135#define IOAPIC_RTE_INTR_FORMAT                  RT_BIT_64(IOAPIC_RTE_INTR_FORMAT_BIT)
     136/** Redirection table entry - Number of bits to shift to get Interrupt Index[15]. */
     137#define IOAPIC_RTE_INTR_INDEX_HI_BIT            11
     138/** Redirection table entry - Interrupt Index[15]. */
     139#define IOAPIC_RTE_INTR_INDEX_HI                RT_BIT_64(11)
     140
     141/** Redirection table entry - Gets the Interrupt Index[14:0]. */
     142#define IOAPIC_RTE_GET_INTR_INDEX_LO(a_Reg)     ((a_Reg) >> IOAPIC_RTE_INTR_INDEX_LO_BIT)
     143/** Redirection table entry - Gets the Interrupt format. */
     144#define IOAPIC_RTE_GET_INTR_FORMAT(a_Reg)       (((a_Reg) >> IOAPIC_RTE_INTR_FORMAT_BIT) & 0x1)
     145/** Redirection table entry - Gets the Interrupt Index[15]. */
     146#define IOAPIC_RTE_GET_INTR_INDEX_HI(a_Reg)     (((a_Reg) >> IOAPIC_RTE_INTR_INDEX_HI_BIT) & 0x1)
     147/** @} */
     148
    125149/** Redirection table entry - Valid write mask for 82093AA. */
    126150#define IOAPIC_RTE_VALID_WRITE_MASK_82093AA     (  IOAPIC_RTE_DEST     | IOAPIC_RTE_MASK      | IOAPIC_RTE_TRIGGER_MODE \
     
    135159/** @note The remote IRR bit has been reverted to read-only as it turns out the
    136160 *        ICH9 spec. is wrong, see @bugref{8386#c46}. */
    137 #define IOAPIC_RTE_VALID_WRITE_MASK_ICH9        (  IOAPIC_RTE_DEST       | IOAPIC_RTE_MASK      | IOAPIC_RTE_TRIGGER_MODE \
     161#define IOAPIC_RTE_VALID_WRITE_MASK_ICH9        (  IOAPIC_RTE_DEST           | IOAPIC_RTE_MASK      | IOAPIC_RTE_TRIGGER_MODE \
    138162                                                 /*| IOAPIC_RTE_REMOTE_IRR */| IOAPIC_RTE_POLARITY  | IOAPIC_RTE_DEST_MODE \
    139                                                  | IOAPIC_RTE_DELIVERY_MODE | IOAPIC_RTE_VECTOR)
     163                                                 | IOAPIC_RTE_DELIVERY_MODE  | IOAPIC_RTE_VECTOR)
    140164/** Redirection table entry - Valid read mask (incl. ExtDestID) for ICH9. */
    141165#define IOAPIC_RTE_VALID_READ_MASK_ICH9         (  IOAPIC_RTE_DEST            | IOAPIC_RTE_EXT_DEST_ID | IOAPIC_RTE_MASK \
    142166                                                 | IOAPIC_RTE_TRIGGER_MODE    | IOAPIC_RTE_REMOTE_IRR  | IOAPIC_RTE_POLARITY \
    143167                                                 | IOAPIC_RTE_DELIVERY_STATUS | IOAPIC_RTE_DEST_MODE   | IOAPIC_RTE_DELIVERY_MODE \
     168                                                 | IOAPIC_RTE_VECTOR)
     169
     170/** Redirection table entry - Valid write mask for DMAR variant. */
     171#define IOAPIC_RTE_VALID_WRITE_MASK_DMAR        (  IOAPIC_RTE_INTR_INDEX_LO  | IOAPIC_RTE_INTR_FORMAT |  IOAPIC_RTE_MASK \
     172                                                 | IOAPIC_RTE_TRIGGER_MODE   | IOAPIC_RTE_POLARITY    | IOAPIC_RTE_INTR_INDEX_HI \
     173                                                 | IOAPIC_RTE_DELIVERY_MODE  | IOAPIC_RTE_VECTOR)
     174/** Redirection table entry - Valid read mask for DMAR variant. */
     175#define IOAPIC_RTE_VALID_READ_MASK_DMAR         (  IOAPIC_RTE_INTR_INDEX_LO   | IOAPIC_RTE_INTR_FORMAT   | IOAPIC_RTE_MASK \
     176                                                 | IOAPIC_RTE_TRIGGER_MODE    | IOAPIC_RTE_REMOTE_IRR    | IOAPIC_RTE_POLARITY \
     177                                                 | IOAPIC_RTE_DELIVERY_STATUS | IOAPIC_RTE_INTR_INDEX_HI | IOAPIC_RTE_DELIVERY_MODE \
    144178                                                 | IOAPIC_RTE_VECTOR)
    145179
     
    181215*   Structures and Typedefs                                                                                                      *
    182216*********************************************************************************************************************************/
     217/**
     218 * I/O APIC chipset (and variants) we support.
     219 */
     220typedef enum IOAPICTYPE
     221{
     222    IOAPICTYPE_ICH9 = 1,
     223    IOAPICTYPE_DMAR,
     224    IOAPICTYPE_82093AA,
     225    IOAPICTYPE_82379AB,
     226    IOAPICTYPE_32BIT_HACK = 0x7fffffff
     227} IOAPICTYPE;
     228AssertCompileSize(IOAPICTYPE, 4);
     229
    183230/**
    184231 * The shared I/O APIC device state.
     
    214261    /** The internal IRR reflecting state of the interrupt lines. */
    215262    uint32_t                uIrr;
    216     /** Alignment padding. */
    217     uint32_t                u32Padding2;
     263    /** The I/O APIC chipset type. */
     264    IOAPICTYPE              enmType;
    218265
    219266#ifndef IOAPIC_WITH_PDM_CRITSECT
     
    453500
    454501
    455 #ifdef VBOX_WITH_IOMMU_AMD
    456 /**
    457  * Convert an APIC interrupt to an MSI message.
     502#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
     503/**
     504 * Convert an RTE into an MSI message.
    458505 *
    459  * @param   pIntr   The APIC interrupt to convert.
    460  * @param   pMsi    Where to store the MSI message.
    461  */
    462 DECLINLINE(void) ioapicGetMsiFromApicIntr(PCXAPICINTR pIntr, PMSIMSG pMsi)
    463 {
    464     pMsi->Addr.n.u12Addr        = VBOX_MSI_ADDR_BASE >> VBOX_MSI_ADDR_SHIFT;
    465     pMsi->Addr.n.u8DestId       = pIntr->u8Dest;
    466     pMsi->Addr.n.u1RedirHint    = pIntr->u8RedirHint;
    467     pMsi->Addr.n.u1DestMode     = pIntr->u8DestMode;
    468 
    469     pMsi->Data.n.u8Vector       = pIntr->u8Vector;
    470     pMsi->Data.n.u3DeliveryMode = pIntr->u8DeliveryMode;
    471     pMsi->Data.n.u1TriggerMode  = pIntr->u8TriggerMode;
    472 
    473     /* pMsi->Data.n.u1Level     = ??? */
    474     /** @todo r=ramshankar: Level triggered MSIs don't make much sense though
    475      *        possible in theory? Maybe document this more explicitly... */
     506 * @param   u64Rte      The RTE to convert.
     507 * @param   enmType     The I/O APIC chipset type.
     508 * @param   pMsi        Where to store the MSI message.
     509 */
     510DECLINLINE(void) ioapicGetMsiFromRte(uint64_t u64Rte, IOAPICTYPE enmType, PMSIMSG pMsi)
     511{
     512    bool const fRemappable = IOAPIC_RTE_GET_INTR_FORMAT(u64Rte);
     513    if (!fRemappable)
     514    {
     515        pMsi->Addr.n.u12Addr        = VBOX_MSI_ADDR_BASE >> VBOX_MSI_ADDR_SHIFT;
     516        pMsi->Addr.n.u8DestId       = IOAPIC_RTE_GET_DEST(u64Rte);
     517        pMsi->Addr.n.u1RedirHint    = 0;
     518        pMsi->Addr.n.u1DestMode     = IOAPIC_RTE_GET_DEST_MODE(u64Rte);
     519
     520        pMsi->Data.n.u8Vector       = IOAPIC_RTE_GET_VECTOR(u64Rte);
     521        pMsi->Data.n.u3DeliveryMode = IOAPIC_RTE_GET_DELIVERY_MODE(u64Rte);
     522        pMsi->Data.n.u1TriggerMode  = IOAPIC_RTE_GET_TRIGGER_MODE(u64Rte);
     523        /* pMsi->Data.n.u1Level     = ??? */
     524        /** @todo r=ramshankar: Level triggered MSIs don't make much sense though
     525         *        possible in theory? Maybe document this more explicitly... */
     526    }
     527    else
     528    {
     529        Assert(enmType == IOAPICTYPE_DMAR);
     530        NOREF(enmType);
     531
     532        /*
     533         * The spec. mentions that SHV will be 0 when delivery mode is 0 (fixed), but
     534         * not what SHV will be if delivery mode is not 0. I ASSUME copying delivery
     535         * mode into SHV here is what hardware actually does.
     536         *
     537         * See Intel VT-d spec. 5.1.5.1 "I/OxAPIC Programming".
     538         */
     539        pMsi->Addr.dmar_remap.u12Addr        = VBOX_MSI_ADDR_BASE >> VBOX_MSI_ADDR_SHIFT;
     540        pMsi->Addr.dmar_remap.u14IntrIndexLo = IOAPIC_RTE_GET_INTR_INDEX_LO(u64Rte);
     541        pMsi->Addr.dmar_remap.fIntrFormat    = 1;
     542        pMsi->Addr.dmar_remap.fShv           = IOAPIC_RTE_GET_DELIVERY_MODE(u64Rte);
     543        pMsi->Addr.dmar_remap.u1IntrIndexHi  = IOAPIC_RTE_GET_INTR_INDEX_HI(u64Rte);
     544
     545        pMsi->Data.dmar_remap.u16SubHandle   = 0;
     546    }
    476547}
    477548#endif
     
    524595    XAPICINTR ApicIntr;
    525596    RT_ZERO(ApicIntr);
    526     ApicIntr.u8Vector       = IOAPIC_RTE_GET_VECTOR(u64Rte);
    527     ApicIntr.u8Dest         = IOAPIC_RTE_GET_DEST(u64Rte);
    528     ApicIntr.u8DestMode     = IOAPIC_RTE_GET_DEST_MODE(u64Rte);
    529     ApicIntr.u8DeliveryMode = IOAPIC_RTE_GET_DELIVERY_MODE(u64Rte);
    530     ApicIntr.u8Polarity     = IOAPIC_RTE_GET_POLARITY(u64Rte);
    531     ApicIntr.u8TriggerMode  = u8TriggerMode;
    532     //ApicIntr.u8RedirHint    = 0;
    533597
    534598#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
     
    542606    RT_ZERO(MsiOut);
    543607    RT_ZERO(MsiIn);
    544     ioapicGetMsiFromApicIntr(&ApicIntr, &MsiIn);
     608    ioapicGetMsiFromRte(u64Rte, pThis->enmType, &MsiIn);
    545609    int const rcRemap = pThisCC->pIoApicHlp->pfnIommuMsiRemap(pDevIns, VBOX_PCI_BDF_SB_IOAPIC, &MsiIn, &MsiOut);
    546610    if (   rcRemap == VERR_IOMMU_NOT_PRESENT
     
    556620
    557621    ioapicGetApicIntrFromMsi(&MsiOut, &ApicIntr);
    558 
    559622# ifdef RT_STRICT
    560623    if (RT_SUCCESS(rcRemap))
     
    564627    }
    565628# endif
     629#else
     630    ApicIntr.u8Vector       = IOAPIC_RTE_GET_VECTOR(u64Rte);
     631    ApicIntr.u8Dest         = IOAPIC_RTE_GET_DEST(u64Rte);
     632    ApicIntr.u8DestMode     = IOAPIC_RTE_GET_DEST_MODE(u64Rte);
     633    ApicIntr.u8DeliveryMode = IOAPIC_RTE_GET_DELIVERY_MODE(u64Rte);
     634    ApicIntr.u8Polarity     = IOAPIC_RTE_GET_POLARITY(u64Rte);
     635    ApicIntr.u8TriggerMode  = u8TriggerMode;
     636    //ApicIntr.u8RedirHint    = 0;
    566637#endif
    567638
     
    9311002     *
    9321003     * If the Bus:Dev:Fn isn't valid, it is ASSUMED the device generating the
    933      * MSI may be the IOMMU itself and hence is not subject to remapping.
     1004     * MSI is the IOMMU itself and hence isn't subjected to remapping. This
     1005     * is the case with Intel IOMMUs.
    9341006     *
    935      * For AMD IOMMUs, since it's a full fledged PCI device, the BDF will be
    936      * valid but will be handled by VERR_IOMMU_CANNOT_CALL_SELF case.
     1007     * AMD IOMMUs are full fledged PCI devices, hence the BDF will be a
     1008     * valid PCI slot, but interrupts generated by the IOMMU will be handled
     1009     * by VERR_IOMMU_CANNOT_CALL_SELF case.
    9371010     */
    9381011    if (PCIBDF_IS_VALID(uBusDevFn))
     
    11991272    LogFlow(("IOAPIC: ioapicR3DbgInfo: pThis=%p pszArgs=%s\n", pThis, pszArgs));
    12001273
     1274    bool const fLegacy = RTStrCmp(pszArgs, "legacy") == 0;
     1275
     1276    static const char * const s_apszDeliveryModes[] =
     1277    {
     1278        " fixed",
     1279        "lowpri",
     1280        "   smi",
     1281        "  rsvd",
     1282        "   nmi",
     1283        "  init",
     1284        "  rsvd",
     1285        "extint"
     1286    };
     1287    static const char * const s_apszDestMode[]       = { "phys", "log " };
     1288    static const char * const s_apszTrigMode[]       = { " edge", "level" };
     1289    static const char * const s_apszPolarity[]       = { "acthi", "actlo" };
     1290    static const char * const s_apszDeliveryStatus[] = { "idle", "pend" };
     1291
    12011292    pHlp->pfnPrintf(pHlp, "I/O APIC at %#010x:\n", IOAPIC_MMIO_BASE_PHYSADDR);
    12021293
     
    12211312
    12221313    pHlp->pfnPrintf(pHlp, "  I/O Redirection Table and IRR:\n");
    1223     pHlp->pfnPrintf(pHlp, "  idx dst_mode dst_addr mask irr trigger rirr polar dlvr_st dlvr_mode vector\n");
    1224 
    1225     uint8_t const idxMaxRte = RT_MIN(pThis->u8MaxRte, RT_ELEMENTS(pThis->au64RedirTable) - 1);
    1226     for (uint8_t idxRte = 0; idxRte <= idxMaxRte; idxRte++)
    1227     {
    1228         static const char * const s_apszDeliveryModes[] =
     1314    if (   pThis->enmType != IOAPICTYPE_DMAR
     1315        || fLegacy)
     1316    {
     1317        pHlp->pfnPrintf(pHlp, "  idx dst_mode dst_addr mask irr trigger rirr polar dlvr_st dlvr_mode vector rte\n");
     1318        pHlp->pfnPrintf(pHlp, "  ---------------------------------------------------------------------------------------------\n");
     1319
     1320        uint8_t const idxMaxRte = RT_MIN(pThis->u8MaxRte, RT_ELEMENTS(pThis->au64RedirTable) - 1);
     1321        for (uint8_t idxRte = 0; idxRte <= idxMaxRte; idxRte++)
    12291322        {
    1230             "Fixed ",
    1231             "LowPri",
    1232             "SMI   ",
    1233             "Rsvd  ",
    1234             "NMI   ",
    1235             "INIT  ",
    1236             "Rsvd  ",
    1237             "ExtINT"
    1238         };
    1239 
    1240         const uint64_t u64Rte = pThis->au64RedirTable[idxRte];
    1241         const char    *pszDestMode       = IOAPIC_RTE_GET_DEST_MODE(u64Rte) == 0 ? "phys" : "log ";
    1242         const uint8_t  uDest             = IOAPIC_RTE_GET_DEST(u64Rte);
    1243         const uint8_t  uMask             = IOAPIC_RTE_GET_MASK(u64Rte);
    1244         const char    *pszTriggerMode    = IOAPIC_RTE_GET_TRIGGER_MODE(u64Rte) == 0 ? "edge " : "level";
    1245         const uint8_t  uRemoteIrr        = IOAPIC_RTE_GET_REMOTE_IRR(u64Rte);
    1246         const char    *pszPolarity       = IOAPIC_RTE_GET_POLARITY(u64Rte) == 0 ? "acthi" : "actlo";
    1247         const char    *pszDeliveryStatus = IOAPIC_RTE_GET_DELIVERY_STATUS(u64Rte) == 0 ? "idle" : "pend";
    1248         const uint8_t  uDeliveryMode     = IOAPIC_RTE_GET_DELIVERY_MODE(u64Rte);
    1249         Assert(uDeliveryMode < RT_ELEMENTS(s_apszDeliveryModes));
    1250         const char    *pszDeliveryMode   = s_apszDeliveryModes[uDeliveryMode];
    1251         const uint8_t  uVector           = IOAPIC_RTE_GET_VECTOR(u64Rte);
    1252 
    1253         pHlp->pfnPrintf(pHlp, "   %02d   %s      %02x     %u    %u   %s   %u   %s  %s     %s   %3u (%016llx)\n",
    1254                         idxRte,
    1255                         pszDestMode,
    1256                         uDest,
    1257                         uMask,
    1258                         (pThis->uIrr >> idxRte) & 1,
    1259                         pszTriggerMode,
    1260                         uRemoteIrr,
    1261                         pszPolarity,
    1262                         pszDeliveryStatus,
    1263                         pszDeliveryMode,
    1264                         uVector,
    1265                         u64Rte);
     1323            const uint64_t u64Rte = pThis->au64RedirTable[idxRte];
     1324            const char    *pszDestMode       = s_apszDestMode[IOAPIC_RTE_GET_DEST_MODE(u64Rte)];
     1325            const uint8_t  uDest             = IOAPIC_RTE_GET_DEST(u64Rte);
     1326            const uint8_t  uMask             = IOAPIC_RTE_GET_MASK(u64Rte);
     1327            const char    *pszTriggerMode    = s_apszTrigMode[IOAPIC_RTE_GET_TRIGGER_MODE(u64Rte)];
     1328            const uint8_t  uRemoteIrr        = IOAPIC_RTE_GET_REMOTE_IRR(u64Rte);
     1329            const char    *pszPolarity       = s_apszPolarity[IOAPIC_RTE_GET_POLARITY(u64Rte)];
     1330            const char    *pszDeliveryStatus = s_apszDeliveryStatus[IOAPIC_RTE_GET_DELIVERY_STATUS(u64Rte)];
     1331            const uint8_t  uDeliveryMode     = IOAPIC_RTE_GET_DELIVERY_MODE(u64Rte);
     1332            Assert(uDeliveryMode < RT_ELEMENTS(s_apszDeliveryModes));
     1333            const char    *pszDeliveryMode   = s_apszDeliveryModes[uDeliveryMode];
     1334            const uint8_t  uVector           = IOAPIC_RTE_GET_VECTOR(u64Rte);
     1335
     1336            pHlp->pfnPrintf(pHlp, "   %02d     %s       %02x    %u   %u   %s    %u %s    %s    %s    %3u (%016llx)\n",
     1337                            idxRte,
     1338                            pszDestMode,
     1339                            uDest,
     1340                            uMask,
     1341                            (pThis->uIrr >> idxRte) & 1,
     1342                            pszTriggerMode,
     1343                            uRemoteIrr,
     1344                            pszPolarity,
     1345                            pszDeliveryStatus,
     1346                            pszDeliveryMode,
     1347                            uVector,
     1348                            u64Rte);
     1349        }
     1350    }
     1351    else
     1352    {
     1353        pHlp->pfnPrintf(pHlp, "  idx intr_idx fmt mask irr trigger rirr polar dlvr_st dlvr_mode vector rte\n");
     1354        pHlp->pfnPrintf(pHlp, "  ----------------------------------------------------------------------------------------\n");
     1355
     1356        uint8_t const idxMaxRte = RT_MIN(pThis->u8MaxRte, RT_ELEMENTS(pThis->au64RedirTable) - 1);
     1357        for (uint8_t idxRte = 0; idxRte <= idxMaxRte; idxRte++)
     1358        {
     1359            const uint64_t u64Rte = pThis->au64RedirTable[idxRte];
     1360            const uint16_t idxIntrLo         = IOAPIC_RTE_GET_INTR_INDEX_LO(u64Rte);
     1361            const uint8_t  fIntrFormat       = IOAPIC_RTE_GET_INTR_FORMAT(u64Rte);
     1362            const uint8_t  uMask             = IOAPIC_RTE_GET_MASK(u64Rte);
     1363            const char    *pszTriggerMode    = s_apszTrigMode[IOAPIC_RTE_GET_TRIGGER_MODE(u64Rte)];
     1364            const uint8_t  uRemoteIrr        = IOAPIC_RTE_GET_REMOTE_IRR(u64Rte);
     1365            const char    *pszPolarity       = s_apszPolarity[IOAPIC_RTE_GET_POLARITY(u64Rte)];
     1366            const char    *pszDeliveryStatus = s_apszDeliveryStatus[IOAPIC_RTE_GET_DELIVERY_STATUS(u64Rte)];
     1367            const uint8_t  uDeliveryMode     = IOAPIC_RTE_GET_DELIVERY_MODE(u64Rte);
     1368            Assert(uDeliveryMode < RT_ELEMENTS(s_apszDeliveryModes));
     1369            const char    *pszDeliveryMode   = s_apszDeliveryModes[uDeliveryMode];
     1370            const uint16_t idxIntrHi         = IOAPIC_RTE_GET_INTR_INDEX_HI(u64Rte);
     1371            const uint8_t  uVector           = IOAPIC_RTE_GET_VECTOR(u64Rte);
     1372            const uint16_t idxIntr           = idxIntrLo | (idxIntrHi << 15);
     1373            pHlp->pfnPrintf(pHlp, "   %02d     %4u   %u    %u   %u   %s    %u %s    %s    %s    %3u (%016llx)\n",
     1374                            idxRte,
     1375                            idxIntr,
     1376                            fIntrFormat,
     1377                            uMask,
     1378                            (pThis->uIrr >> idxRte) & 1,
     1379                            pszTriggerMode,
     1380                            uRemoteIrr,
     1381                            pszPolarity,
     1382                            pszDeliveryStatus,
     1383                            pszDeliveryMode,
     1384                            uVector,
     1385                            u64Rte);
     1386        }
    12661387    }
    12671388}
     
    14131534    {
    14141535        /* Newer 2007-ish I/O APIC integrated into ICH southbridges. */
     1536        pThis->enmType         = IOAPICTYPE_ICH9;
    14151537        pThis->u8ApicVer       = IOAPIC_VERSION_ICH9;
    14161538        pThis->u8IdMask        = 0xff;
     
    14201542        pThis->u64RteReadMask  = IOAPIC_RTE_VALID_READ_MASK_ICH9;
    14211543    }
     1544    else if (!strcmp(szChipType, "DMAR"))
     1545    {
     1546        /* Intel DMAR compatible I/O APIC integrated into ICH southbridges. */
     1547        /* Identical to ICH9, but interprets RTEs and MSI address and data fields differently. */
     1548        pThis->enmType         = IOAPICTYPE_DMAR;
     1549        pThis->u8ApicVer       = IOAPIC_VERSION_ICH9;
     1550        pThis->u8IdMask        = 0xff;
     1551        pThis->u8MaxRte        = IOAPIC_MAX_RTE_INDEX;
     1552        pThis->u8LastRteRegIdx = IOAPIC_INDIRECT_INDEX_RTE_END;
     1553        pThis->u64RteWriteMask = IOAPIC_RTE_VALID_WRITE_MASK_DMAR;
     1554        pThis->u64RteReadMask  = IOAPIC_RTE_VALID_READ_MASK_DMAR;
     1555    }
    14221556    else if (!strcmp(szChipType, "82093AA"))
    14231557    {
    14241558        /* Older 1995-ish discrete I/O APIC, used in P6 class systems. */
     1559        pThis->enmType         = IOAPICTYPE_82093AA;
    14251560        pThis->u8ApicVer       = IOAPIC_VERSION_82093AA;
    14261561        pThis->u8IdMask        = 0x0f;
     
    14341569        /* Even older 1993-ish I/O APIC built into SIO.A, used in EISA and early PCI systems. */
    14351570        /* Exact same version and behavior as 82093AA, only the number of RTEs is different. */
     1571        pThis->enmType         = IOAPICTYPE_82379AB;
    14361572        pThis->u8ApicVer       = IOAPIC_VERSION_82093AA;
    14371573        pThis->u8IdMask        = 0x0f;
     
    15331669     * Init. the device state.
    15341670     */
    1535     LogRel(("IOAPIC: Using implementation 2.0! I/O APIC version is %d.%d\n", pThis->u8ApicVer >> 4, pThis->u8ApicVer & 0x0F));
     1671    LogRel(("IOAPIC: Version=%d.%d ChipType=%s\n", pThis->u8ApicVer >> 4, pThis->u8ApicVer & 0x0f, szChipType));
    15361672    ioapicR3Reset(pDevIns);
    15371673
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