VirtualBox

Changeset 87868 in vbox


Ignore:
Timestamp:
Feb 25, 2021 8:44:26 AM (4 years ago)
Author:
vboxsync
Message:

AMD IOMMU: bugref:9654 SSM bits.

File:
1 edited

Legend:

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

    r87867 r87868  
    51575157
    51585158/**
    5159  * Writes the upper 32-bits of the IOMMU base address register.
    5160  *
    5161  * @param   pThis           The shared IOMMU device state.
    5162  * @param   uIommuBarHi     The upper 32-bits of the IOMMU BAR.
    5163  */
    5164 static void iommuAmdR3IommuBarHiWrite(PIOMMU pThis, uint32_t uIommuBarHi)
    5165 {
    5166     AssertCompile((IOMMU_BAR_VALID_MASK >> 32) == 0xffffffff);
    5167     pThis->IommuBar.au32[1] = uIommuBarHi;
    5168 }
    5169 
    5170 
    5171 /**
    5172  * Writes the lower 32-bits of the IOMMU base address register.
    5173  *
    5174  * @param   pDevIns         The IOMMU instance data.
    5175  * @param   pThis           The shared IOMMU device state.
    5176  * @param   uIommuBarLo     The lower 32-bits of the IOMMU BAR.
    5177  */
    5178 static VBOXSTRICTRC iommuAmdR3IommuBarLoWrite(PPDMDEVINS pDevIns, PIOMMU pThis, uint32_t uIommuBarLo)
    5179 {
    5180     pThis->IommuBar.au32[0] = uIommuBarLo & IOMMU_BAR_VALID_MASK;
    5181     if (pThis->IommuBar.n.u1Enable)
    5182     {
    5183         Assert(pThis->hMmio != NIL_IOMMMIOHANDLE);  /* Paranoia. Ensure we have a valid IOM MMIO handle. */
    5184         Assert(!pThis->ExtFeat.n.u1PerfCounterSup); /* Base is 16K aligned when performance counters aren't supported. */
    5185         RTGCPHYS const GCPhysMmioBase     = RT_MAKE_U64(pThis->IommuBar.au32[0] & 0xffffc000, pThis->IommuBar.au32[1]);
    5186         RTGCPHYS const GCPhysMmioBasePrev = PDMDevHlpMmioGetMappingAddress(pDevIns, pThis->hMmio);
    5187 
    5188         /* If the MMIO region is already mapped at the specified address, we're done. */
    5189         Assert(GCPhysMmioBase != NIL_RTGCPHYS);
    5190         if (GCPhysMmioBasePrev == GCPhysMmioBase)
    5191             return VINF_SUCCESS;
    5192 
    5193         /* Unmap the previous MMIO region (which is at a different address). */
    5194         if (GCPhysMmioBasePrev != NIL_RTGCPHYS)
    5195         {
    5196             LogFlowFunc(("Unmapping previous MMIO region at %#RGp\n", GCPhysMmioBasePrev));
    5197             VBOXSTRICTRC rcStrict = PDMDevHlpMmioUnmap(pDevIns, pThis->hMmio);
    5198             if (RT_FAILURE(rcStrict))
    5199             {
    5200                 LogFunc(("Failed to unmap MMIO region at %#RGp. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    5201                 return rcStrict;
    5202             }
    5203         }
    5204 
    5205         /* Map the newly specified MMIO region. */
    5206         LogFlowFunc(("Mapping MMIO region at %#RGp\n", GCPhysMmioBase));
    5207         VBOXSTRICTRC rcStrict = PDMDevHlpMmioMap(pDevIns, pThis->hMmio, GCPhysMmioBase);
    5208         if (RT_FAILURE(rcStrict))
    5209         {
    5210             LogFunc(("Failed to unmap MMIO region at %#RGp. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    5211             return rcStrict;
    5212         }
     5159 * Sets up the IOMMU MMIO region (usually in response to an IOMMU base address
     5160 * register write).
     5161 *
     5162 * @returns VBox status code.
     5163 * @param   pDevIns     The IOMMU instance data.
     5164 *
     5165 * @remarks Call this function only when the IOMMU BAR is enabled.
     5166 */
     5167static int iommuAmdR3MmioSetup(PPDMDEVINS pDevIns)
     5168{
     5169    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     5170    Assert(pThis->IommuBar.n.u1Enable);
     5171    Assert(pThis->hMmio != NIL_IOMMMIOHANDLE);     /* Paranoia. Ensure we have a valid IOM MMIO handle. */
     5172    Assert(!pThis->ExtFeat.n.u1PerfCounterSup);    /* Base is 16K aligned when performance counters aren't supported. */
     5173    RTGCPHYS const GCPhysMmioBase     = RT_MAKE_U64(pThis->IommuBar.au32[0] & 0xffffc000, pThis->IommuBar.au32[1]);
     5174    RTGCPHYS const GCPhysMmioBasePrev = PDMDevHlpMmioGetMappingAddress(pDevIns, pThis->hMmio);
     5175
     5176    /* If the MMIO region is already mapped at the specified address, we're done. */
     5177    Assert(GCPhysMmioBase != NIL_RTGCPHYS);
     5178    if (GCPhysMmioBasePrev == GCPhysMmioBase)
     5179        return VINF_SUCCESS;
     5180
     5181    /* Unmap the previous MMIO region (which is at a different address). */
     5182    if (GCPhysMmioBasePrev != NIL_RTGCPHYS)
     5183    {
     5184        LogFlowFunc(("Unmapping previous MMIO region at %#RGp\n", GCPhysMmioBasePrev));
     5185        int rc = PDMDevHlpMmioUnmap(pDevIns, pThis->hMmio);
     5186        if (RT_FAILURE(rc))
     5187        {
     5188            LogFunc(("Failed to unmap MMIO region at %#RGp. rc=%Rrc\n", rc));
     5189            return rc;
     5190        }
     5191    }
     5192
     5193    /* Map the newly specified MMIO region. */
     5194    LogFlowFunc(("Mapping MMIO region at %#RGp\n", GCPhysMmioBase));
     5195    int rc = PDMDevHlpMmioMap(pDevIns, pThis->hMmio, GCPhysMmioBase);
     5196    if (RT_FAILURE(rc))
     5197    {
     5198        LogFunc(("Failed to unmap MMIO region at %#RGp. rc=%Rrc\n", rc));
     5199        return rc;
    52135200    }
    52145201
     
    52515238        {
    52525239            if (!pThis->IommuBar.n.u1Enable)
    5253                 rcStrict = iommuAmdR3IommuBarLoWrite(pDevIns, pThis, u32Value);
     5240            {
     5241                pThis->IommuBar.au32[0] = u32Value & IOMMU_BAR_VALID_MASK;
     5242                if (pThis->IommuBar.n.u1Enable)
     5243                    rcStrict = iommuAmdR3MmioSetup(pDevIns);
     5244                else
     5245                    rcStrict = VINF_SUCCESS;
     5246            }
    52545247            else
    52555248            {
     
    52635256        {
    52645257            if (!pThis->IommuBar.n.u1Enable)
    5265                 iommuAmdR3IommuBarHiWrite(pThis, u32Value);
     5258            {
     5259                AssertCompile((IOMMU_BAR_VALID_MASK >> 32) == 0xffffffff);
     5260                pThis->IommuBar.au32[1] = u32Value;
     5261            }
    52665262            else
    52675263                LogFunc(("Writing Base Address (Hi) when it's already enabled -> Ignored\n"));
     
    65756571    IOMMU_LOCK(pDevIns, pThisR3);
    65766572
    6577     /* Write the IOMMU base registers and map MMIO regions as needed. */
    6578     iommuAmdR3IommuBarHiWrite(pThis, pThis->IommuBar.au32[1]);
    6579     iommuAmdR3IommuBarLoWrite(pDevIns, pThis, pThis->IommuBar.au32[0]);
     6573    /* Map MMIO regions if the IOMMU BAR is enabled. */
     6574    if (pThis->IommuBar.n.u1Enable)
     6575        iommuAmdR3MmioSetup(pDevIns);
    65806576
    65816577    /* Wake up the command thread if commands need processing. */
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