Changeset 87868 in vbox
- Timestamp:
- Feb 25, 2021 8:44:26 AM (4 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r87867 r87868 5157 5157 5158 5158 /** 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 */ 5167 static 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; 5213 5200 } 5214 5201 … … 5251 5238 { 5252 5239 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 } 5254 5247 else 5255 5248 { … … 5263 5256 { 5264 5257 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 } 5266 5262 else 5267 5263 LogFunc(("Writing Base Address (Hi) when it's already enabled -> Ignored\n")); … … 6575 6571 IOMMU_LOCK(pDevIns, pThisR3); 6576 6572 6577 /* Write the IOMMU base registers and map MMIO regions as needed. */6578 i ommuAmdR3IommuBarHiWrite(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); 6580 6576 6581 6577 /* Wake up the command thread if commands need processing. */
Note:
See TracChangeset
for help on using the changeset viewer.

