VirtualBox

Changeset 83742 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Apr 17, 2020 10:47:28 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
137262
Message:

AMD IOMMU: bugref:9654 Bits.

File:
1 edited

Legend:

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

    r83733 r83742  
    19481948     * @{ */
    19491949    MSI_MISC_INFO_T             MsiMiscInfo;        /**< MSI Misc. info registers / MSI Vector registers. */
    1950     MSI_CAP_HDR_T               MsiCapHdr;          /**< MSI Capability header register. */
    1951     MSI_ADDR_T                  MsiAddr;            /**< MSI Address register.*/
    1952     MSI_DATA_T                  MsiData;            /**< MSI Data register. */
    1953     MSI_MAP_CAP_HDR_T           MsiMapCapHdr;       /**< MSI Mapping capability header register. */
    19541950    /** @} */
    19551951
     
    23262322static VBOXSTRICTRC iommuAmdMsiAddrLo_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t iReg, uint64_t u64Value)
    23272323{
    2328     RT_NOREF(pDevIns, iReg);
     2324    RT_NOREF(pThis, iReg);
    23292325    Assert(!RT_HI_U32(u64Value));
    2330     pThis->MsiAddr.au32[0] = u64Value & IOMMU_MSI_ADDR_VALID_MASK;
     2326    PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
     2327    PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev);
     2328    PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_LO, u64Value & IOMMU_MSI_ADDR_VALID_MASK);
    23312329    return VINF_SUCCESS;
    23322330}
     
    23382336static VBOXSTRICTRC iommuAmdMsiAddrHi_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t iReg, uint64_t u64Value)
    23392337{
    2340     RT_NOREF(pDevIns, iReg);
     2338    RT_NOREF(pThis, iReg);
    23412339    Assert(!RT_HI_U32(u64Value));
    2342     pThis->MsiAddr.au32[1] = u64Value;
     2340    PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
     2341    PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev);
     2342    PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_HI, u64Value);
    23432343    return VINF_SUCCESS;
    23442344}
     
    23502350static VBOXSTRICTRC iommuAmdMsiData_w(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t iReg, uint64_t u64Value)
    23512351{
    2352     RT_NOREF(pDevIns, iReg);
    2353     pThis->MsiData.u32 = u64Value & IOMMU_MSI_DATA_VALID_MASK;
     2352    RT_NOREF(pThis, iReg);
     2353    PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
     2354    PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev);
     2355    PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_DATA, u64Value & IOMMU_MSI_DATA_VALID_MASK);
    23542356    return VINF_SUCCESS;
    23552357}
     
    26412643    Assert(!(off & 7) || !(off & 3));
    26422644
     2645    PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
     2646    PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev);
     2647
    26432648    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    26442649    Assert(pThis);
     
    26822687        case IOMMU_MMIO_OFF_MSI_VECTOR_0:             uReg = pThis->MsiMiscInfo.u64;            break;
    26832688        case IOMMU_MMIO_OFF_MSI_VECTOR_1:             uReg = pThis->MsiMiscInfo.au32[1];        break;
    2684         case IOMMU_MMIO_OFF_MSI_CAP_HDR:              uReg = RT_MAKE_U64(pThis->MsiCapHdr.u32, pThis->MsiAddr.au32[0]);     break;
    2685         case IOMMU_MMIO_OFF_MSI_ADDR_LO:              uReg = pThis->MsiAddr.au32[0];            break;
    2686         case IOMMU_MMIO_OFF_MSI_ADDR_HI:              uReg = RT_MAKE_U64(pThis->MsiAddr.au32[1], pThis->MsiData.u32);       break;
    2687         case IOMMU_MMIO_OFF_MSI_DATA:                 uReg = pThis->MsiData.u32;                break;
    2688         case IOMMU_MMIO_OFF_MSI_MAPPING_CAP_HDR:      uReg = RT_MAKE_U64(pThis->MsiMapCapHdr.u32, pThis->PerfOptCtrl.u32);  break;
     2689        case IOMMU_MMIO_OFF_MSI_CAP_HDR:
     2690        {
     2691            uint32_t const uMsiCapHdr = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_CAP_HDR);
     2692            uint32_t const uMsiAddrLo = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_LO);
     2693            uReg = RT_MAKE_U64(uMsiCapHdr, uMsiAddrLo);
     2694            break;
     2695        }
     2696        case IOMMU_MMIO_OFF_MSI_ADDR_LO:
     2697        {
     2698            uReg = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_LO);
     2699            break;
     2700        }
     2701        case IOMMU_MMIO_OFF_MSI_ADDR_HI:
     2702        {
     2703            uint32_t const uMsiAddrHi = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_HI);
     2704            uint32_t const uMsiData   = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_DATA);
     2705            uReg = RT_MAKE_U64(uMsiAddrHi, uMsiData);
     2706            break;
     2707        }
     2708        case IOMMU_MMIO_OFF_MSI_DATA:
     2709        {
     2710            uReg = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_DATA);
     2711            break;
     2712        }
     2713        case IOMMU_MMIO_OFF_MSI_MAPPING_CAP_HDR:
     2714        {
     2715            /*
     2716             * The PCI spec. lists MSI Mapping Capability 08H as related to HyperTransport capability.
     2717             * The AMD IOMMU spec. fails to mention it explicitly and lists values for this register as
     2718             * though HyperTransport is supported. We don't support HyperTransport, we thus just return
     2719             * 0 for this register.
     2720             */
     2721            uReg = RT_MAKE_U64(0, pThis->PerfOptCtrl.u32);
     2722            break;
     2723        }
    26892724
    26902725        case IOMMU_MMIO_OFF_PERF_OPT_CTRL:            uReg = pThis->PerfOptCtrl.u32;            break;
     
    28672902        }
    28682903
     2904        case IOMMU_PCI_OFF_MSI_CAP_HDR:
     2905        {
     2906            u32Value |= RT_BIT(23);     /* 64-bit MSI addressess must always be enabled for IOMMU. */
     2907            RT_FALL_THRU();
     2908        }
     2909
    28692910        default:
     2911        {
    28702912            rcStrict = PDMDevHlpPCIConfigWrite(pDevIns, pPciDev, uAddress, cb, u32Value);
    28712913            break;
     2914        }
    28722915    }
    28732916
     
    28842927static DECLCALLBACK(void) iommuAmdR3DbgInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
    28852928{
     2929    PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
     2930    PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev);
     2931
    28862932    PCIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    28872933    Assert(pThis);
     
    31893235    /* MSI Capability Header. */
    31903236    {
    3191         MSI_CAP_HDR_T const MsiCapHdr = pThis->MsiCapHdr;
     3237        MSI_CAP_HDR_T MsiCapHdr;
     3238        MsiCapHdr.u32 = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_CAP_HDR);
    31923239        pHlp->pfnPrintf(pHlp, "  MSI Capability Header                   = %#RX32\n",    MsiCapHdr.u32);
    31933240        if (fVerbose)
     
    32023249    /* MSI Address Register (Lo and Hi). */
    32033250    {
    3204         MSI_ADDR_T const MsiAddr = pThis->MsiAddr;
     3251        uint32_t const uMsiAddrLo = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_LO);
     3252        uint32_t const uMsiAddrHi = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_ADDR_HI);
     3253        MSI_ADDR_T MsiAddr;
     3254        MsiAddr.u64 = RT_MAKE_U64(uMsiAddrLo, uMsiAddrHi);
    32053255        pHlp->pfnPrintf(pHlp, "  MSI Address                             = %#RX64\n",   MsiAddr.u64);
    32063256        if (fVerbose)
     
    32093259    /* MSI Data. */
    32103260    {
    3211         MSI_DATA_T const MsiData = pThis->MsiData;
     3261        MSI_DATA_T MsiData;
     3262        MsiData.u32 = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_DATA);
    32123263        pHlp->pfnPrintf(pHlp, "  MSI Data                                = %#RX32\n", MsiData.u32);
    32133264        if (fVerbose)
    32143265            pHlp->pfnPrintf(pHlp, "    Data                                    = %#x\n",  MsiData.n.u16MsiData);
    32153266    }
    3216     /* MSI Mapping Capability Header. */
    3217     {
    3218         MSI_MAP_CAP_HDR_T const MsiMapCapHdr = pThis->MsiMapCapHdr;
     3267    /* MSI Mapping Capability Header (HyperTransport, reporting all 0s currently). */
     3268    {
     3269        MSI_MAP_CAP_HDR_T MsiMapCapHdr;
     3270        MsiMapCapHdr.u32 = 0;
    32193271        pHlp->pfnPrintf(pHlp, "  MSI Mapping Capability Header           = %#RX32\n",    MsiMapCapHdr.u32);
    32203272        if (fVerbose)
     
    35233575    pThis->DevSpecificStatus.u64             = 0;
    35243576    pThis->MsiMiscInfo.u64                   = 0;
    3525     pThis->MsiCapHdr.u32                     = PDMPciDevGetDWord(pPciDev, IOMMU_PCI_OFF_MSI_CAP_HDR);
    3526     pThis->MsiAddr.u64                       = 0;
    3527     pThis->MsiData.u32                       = 0;
    3528     pThis->MsiMapCapHdr.u32                  = 0;
    35293577    pThis->PerfOptCtrl.u32                   = 0;
    35303578    pThis->XtGenIntrCtrl.u64                 = 0;
     
    35523600    PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_BASE_ADDR_REG_LO, 0);
    35533601    PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_BASE_ADDR_REG_HI, 0);
    3554     PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_RANGE_REG,        0);
    35553602}
    35563603
     
    36433690    PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_BASE_ADDR_REG_HI, 0x0);  /* RW - Base address (Hi) */
    36443691    /* IOMMU Range Register. */
    3645     PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_RANGE_REG, 0x0);         /* RW - Range register. */
     3692    PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_RANGE_REG, 0x0);         /* RW - Range register (implemented as RO by us). */
    36463693    /* Misc. Information Register 0. */
    36473694    PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MISCINFO_REG_0,
     
    36553702    PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MISCINFO_REG_0, 0);
    36563703    /* MSI Capability Header register. */
    3657 #if 0
    3658     PDMPciDevSetDWord(pPciDev, IOMMU_PCI_OFF_MSI_CAP_HDR,
    3659                         RT_BF_MAKE(IOMMU_BF_MSI_CAPHDR_CAP_ID,       0x5)             /* RO - Capability ID. */
    3660                       | RT_BF_MAKE(IOMMU_BF_MSI_CAPHDR_CAP_PTR,      offMsiMapCapHdr) /* RO - Offset to next capability block */
    3661                       | RT_BF_MAKE(IOMMU_BF_MSI_CAPHDR_EN,           0x0)             /* RW - MSI capability enable */
    3662                       | RT_BF_MAKE(IOMMU_BF_MSI_CAPHDR_MULTMESS_CAP, 0x0)             /* RO - MSI multi-message capability */
    3663                       | RT_BF_MAKE(IOMMU_BF_MSI_CAPHDR_MULTMESS_EN,  0x0)             /* RW - MSI multi-message enable */
    3664                       | RT_BF_MAKE(IOMMU_BF_MSI_CAPHDR_64BIT_EN,     0x1));           /* RO - MSI 64-bit enable */
    3665 #else
    36663704    PDMMSIREG MsiReg;
    36673705    RT_ZERO(MsiReg);
     
    36723710    rc = PDMDevHlpPCIRegisterMsi(pDevIns, &MsiReg);
    36733711    AssertRCReturn(rc, rc);
    3674     /* This is later copied to its MMIO shadow register (MsiCapHdr), see iommuAmdR3Init. */
    3675 #endif
    3676 
    3677     /* These read-write PCI config registers are initialized in iommuAmdR3Init. */
     3712
     3713    /* MSI Address (Lo, Hi) and MSI data are read-write PCI config registers handled by our generic PCI config space code. */
    36783714#if 0
    36793715    /* MSI Address Lo. */
Note: See TracChangeset for help on using the changeset viewer.

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