Changeset 87867 in vbox
- Timestamp:
- Feb 25, 2021 7:55:17 AM (4 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp (modified) (23 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r87866 r87867 4193 4193 * Gets the I/O permission and IOMMU operation type for the given access flags. 4194 4194 * 4195 * @param pThis The shared IOMMU device state. 4195 4196 * @param fFlags The PDM IOMMU flags, PDMIOMMU_MEM_F_XXX. 4196 4197 * @param penmOp Where to store the IOMMU operation. … … 4198 4199 * @param fBulk Whether this is a bulk read or write. 4199 4200 */ 4200 DECLINLINE(void) iommuAmdMemAccessGetPermAndOp( uint32_t fFlags, PIOMMUOP penmOp, uint8_t *pfPerm, bool fBulk)4201 DECLINLINE(void) iommuAmdMemAccessGetPermAndOp(PIOMMU pThis, uint32_t fFlags, PIOMMUOP penmOp, uint8_t *pfPerm, bool fBulk) 4201 4202 { 4202 4203 if (fFlags & PDMIOMMU_MEM_F_WRITE) … … 4206 4207 #ifdef VBOX_WITH_STATISTICS 4207 4208 if (!fBulk) 4208 STAM_COUNTER_INC( pThis->CTX_SUFF_Z(StatMemRead));4209 STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemRead)); 4209 4210 else 4210 STAM_COUNTER_INC( pThis->CTX_SUFF_Z(StatMemBulkRead));4211 STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemBulkRead)); 4211 4212 #else 4212 RT_NOREF (fBulk);4213 RT_NOREF2(pThis, fBulk); 4213 4214 #endif 4214 4215 } … … 4220 4221 #ifdef VBOX_WITH_STATISTICS 4221 4222 if (!fBulk) 4222 STAM_COUNTER_INC( pThis->CTX_SUFF_Z(StatMemWrite));4223 STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemWrite)); 4223 4224 else 4224 STAM_COUNTER_INC( pThis->CTX_SUFF_Z(StatMemBulkWrite));4225 STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemBulkWrite)); 4225 4226 #else 4226 RT_NOREF (fBulk);4227 RT_NOREF2(pThis, fBulk); 4227 4228 #endif 4228 4229 } … … 4260 4261 IOMMUOP enmOp; 4261 4262 uint8_t fPerm; 4262 iommuAmdMemAccessGetPermAndOp( fFlags, &enmOp, &fPerm, false /* fBulk */);4263 iommuAmdMemAccessGetPermAndOp(pThis, fFlags, &enmOp, &fPerm, false /* fBulk */); 4263 4264 LogFlowFunc(("%s: uDevId=%#x uIova=%#RX64 cb=%zu\n", iommuAmdMemAccessGetPermName(fPerm), uDevId, uIova, cbAccess)); 4264 NOREF(pThis);4265 4265 4266 4266 int rc; … … 4348 4348 IOMMUOP enmOp; 4349 4349 uint8_t fPerm; 4350 iommuAmdMemAccessGetPermAndOp( fFlags, &enmOp, &fPerm, true /* fBulk */);4350 iommuAmdMemAccessGetPermAndOp(pThis, fFlags, &enmOp, &fPerm, true /* fBulk */); 4351 4351 LogFlowFunc(("%s: uDevId=%#x cIovas=%zu\n", iommuAmdMemAccessGetPermName(fPerm), uDevId, cIovas)); 4352 4352 … … 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 } 5213 } 5214 5215 return VINF_SUCCESS; 5216 } 5217 5218 5219 /** 5159 5220 * @callback_method_impl{FNPCICONFIGWRITE} 5160 5221 */ … … 5184 5245 IOMMU_LOCK(pDevIns, pThisR3); 5185 5246 5186 VBOXSTRICTRC rcStrict = VERR_IOMMU_IPE_3;5247 VBOXSTRICTRC rcStrict; 5187 5248 switch (uAddress) 5188 5249 { 5189 5250 case IOMMU_PCI_OFF_BASE_ADDR_REG_LO: 5190 5251 { 5191 if (pThis->IommuBar.n.u1Enable)5192 {5193 rcStrict = VINF_SUCCESS;5194 LogFunc(("Writing Base Address (Lo) when it's already enabled -> Ignored\n"));5195 break;5196 }5197 5198 pThis->IommuBar.au32[0] = u32Value & IOMMU_BAR_VALID_MASK;5199 if (pThis->IommuBar.n.u1Enable)5200 {5201 Assert(pThis->hMmio != NIL_IOMMMIOHANDLE); /* Paranoia. Ensure we have a valid IOM MMIO handle. */5202 Assert(!pThis->ExtFeat.n.u1PerfCounterSup); /* Base is 16K aligned when performance counters aren't supported. */5203 RTGCPHYS const GCPhysMmioBase = RT_MAKE_U64(pThis->IommuBar.au32[0] & 0xffffc000, pThis->IommuBar.au32[1]);5204 RTGCPHYS const GCPhysMmioBasePrev = PDMDevHlpMmioGetMappingAddress(pDevIns, pThis->hMmio);5205 5206 /* If the MMIO region is already mapped at the specified address, we're done. */5207 Assert(GCPhysMmioBase != NIL_RTGCPHYS);5208 if (GCPhysMmioBasePrev == GCPhysMmioBase)5209 {5210 rcStrict = VINF_SUCCESS;5211 break;5212 }5213 5214 /* Unmap the previous MMIO region (which is at a different address). */5215 if (GCPhysMmioBasePrev != NIL_RTGCPHYS)5216 {5217 LogFlowFunc(("Unmapping previous MMIO region at %#RGp\n", GCPhysMmioBasePrev));5218 rcStrict = PDMDevHlpMmioUnmap(pDevIns, pThis->hMmio);5219 if (RT_FAILURE(rcStrict))5220 {5221 LogFunc(("Failed to unmap MMIO region at %#RGp. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));5222 break;5223 }5224 }5225 5226 /* Map the newly specified MMIO region. */5227 LogFlowFunc(("Mapping MMIO region at %#RGp\n", GCPhysMmioBase));5228 rcStrict = PDMDevHlpMmioMap(pDevIns, pThis->hMmio, GCPhysMmioBase);5229 if (RT_FAILURE(rcStrict))5230 {5231 LogFunc(("Failed to unmap MMIO region at %#RGp. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));5232 break;5233 }5234 }5235 else5236 rcStrict = VINF_SUCCESS;5237 break;5238 }5239 5240 case IOMMU_PCI_OFF_BASE_ADDR_REG_HI:5241 {5242 5252 if (!pThis->IommuBar.n.u1Enable) 5243 pThis->IommuBar.au32[1] = u32Value;5253 rcStrict = iommuAmdR3IommuBarLoWrite(pDevIns, pThis, u32Value); 5244 5254 else 5245 5255 { 5256 LogFunc(("Writing Base Address (Lo) when it's already enabled -> Ignored\n")); 5246 5257 rcStrict = VINF_SUCCESS; 5258 } 5259 break; 5260 } 5261 5262 case IOMMU_PCI_OFF_BASE_ADDR_REG_HI: 5263 { 5264 if (!pThis->IommuBar.n.u1Enable) 5265 iommuAmdR3IommuBarHiWrite(pThis, u32Value); 5266 else 5247 5267 LogFunc(("Writing Base Address (Hi) when it's already enabled -> Ignored\n")); 5248 }5268 rcStrict = VINF_SUCCESS; 5249 5269 break; 5250 5270 } … … 6141 6161 6142 6162 /** 6143 * @callback_method_impl{FNSSMDEV LIVEEXEC}6144 */ 6145 static DECLCALLBACK(int) iommuAmdR3 LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)6163 * @callback_method_impl{FNSSMDEVSAVEEXEC} 6164 */ 6165 static DECLCALLBACK(int) iommuAmdR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 6146 6166 { 6147 6167 PCIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 6148 6168 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 6149 RT_NOREF(uPass);6150 6169 LogFlowFunc(("\n")); 6151 6170 6152 /* Saveregisters that cannot be modified by the guest. */6171 /* First, save ExtFeat and other registers that cannot be modified by the guest. */ 6153 6172 pHlp->pfnSSMPutU64(pSSM, pThis->ExtFeat.u64); 6154 6173 pHlp->pfnSSMPutU64(pSSM, pThis->DevSpecificFeat.u64); … … 6158 6177 pHlp->pfnSSMPutU64(pSSM, pThis->RsvdReg); 6159 6178 6160 return VINF_SSM_DONT_CALL_AGAIN; 6161 } 6162 6163 6164 /** 6165 * @callback_method_impl{FNSSMDEVSAVEEXEC} 6166 */ 6167 static DECLCALLBACK(int) iommuAmdR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 6168 { 6169 PCIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 6170 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 6171 LogFlowFunc(("\n")); 6172 6179 /* Next, save all registers that can be modified by the guest. */ 6173 6180 pHlp->pfnSSMPutU64(pSSM, pThis->IommuBar.u64); 6174 6181 … … 6177 6184 for (uint8_t i = 0; i < cDevTabBaseAddrs; i++) 6178 6185 pHlp->pfnSSMPutU64(pSSM, pThis->aDevTabBaseAddrs[i].u64); 6186 6187 AssertReturn(pThis->CmdBufBaseAddr.n.u4Len >= 8, VERR_IOMMU_IPE_4); 6179 6188 pHlp->pfnSSMPutU64(pSSM, pThis->CmdBufBaseAddr.u64); 6180 6189 pHlp->pfnSSMPutU64(pSSM, pThis->EvtLogBaseAddr.u64); … … 6183 6192 pHlp->pfnSSMPutU64(pSSM, pThis->ExclRangeLimit.u64); 6184 6193 #if 0 6185 pHlp->pfnSSMPutU64(pSSM, pThis->ExtFeat.u64); /* read-only, done in liveExec*/6194 pHlp->pfnSSMPutU64(pSSM, pThis->ExtFeat.u64); /* read-only, done already (above). */ 6186 6195 #endif 6187 6196 … … 6198 6207 6199 6208 #if 0 6200 pHlp->pfnSSMPutU64(pSSM, pThis->DevSpecificFeat.u64); /* read-only, done in liveExec*/6201 pHlp->pfnSSMPutU64(pSSM, pThis->DevSpecificCtrl.u64); /* read-only, done in liveExec*/6202 pHlp->pfnSSMPutU64(pSSM, pThis->DevSpecificStatus.u64); /* read-only, done in liveExec*/6203 6204 pHlp->pfnSSMPutU64(pSSM, pThis->MiscInfo.u64); /* read-only, done in liveExec*/6209 pHlp->pfnSSMPutU64(pSSM, pThis->DevSpecificFeat.u64); /* read-only, done already (above). */ 6210 pHlp->pfnSSMPutU64(pSSM, pThis->DevSpecificCtrl.u64); /* read-only, done already (above). */ 6211 pHlp->pfnSSMPutU64(pSSM, pThis->DevSpecificStatus.u64); /* read-only, done already (above). */ 6212 6213 pHlp->pfnSSMPutU64(pSSM, pThis->MiscInfo.u64); /* read-only, done already (above). */ 6205 6214 #endif 6206 6215 pHlp->pfnSSMPutU32(pSSM, pThis->PerfOptCtrl.u32); … … 6220 6229 6221 6230 #if 0 6222 pHlp->pfnSSMPutU64(pSSM, pThis->RsvdReg); /* read-only, done in liveExec*/6231 pHlp->pfnSSMPutU64(pSSM, pThis->RsvdReg); /* read-only, done already (above). */ 6223 6232 #endif 6224 6233 … … 6257 6266 PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 6258 6267 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 6268 int const rcErr = VERR_SSM_UNEXPECTED_DATA; 6259 6269 LogFlowFunc(("\n")); 6260 6270 6261 6271 /* Validate. */ 6262 if (uPass != SSM_PASS_FINAL) 6263 return VINF_SUCCESS; 6272 AssertReturn(uPass == SSM_PASS_FINAL, VERR_WRONG_ORDER); 6264 6273 if (uVersion != IOMMU_SAVED_STATE_VERSION) 6274 { 6275 LogRel(("%s: Invalid saved-state version %#x\n", IOMMU_LOG_PFX, uVersion)); 6265 6276 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 6266 int const rcDataError = VERR_SSM_UNEXPECTED_DATA; 6267 6277 } 6278 6279 /* Load ExtFeat and other read-only registers first. */ 6268 6280 int rc = pHlp->pfnSSMGetU64(pSSM, &pThis->ExtFeat.u64); 6269 6281 AssertRCReturn(rc, rc); 6270 6282 AssertLogRelMsgReturn(pThis->ExtFeat.n.u2HostAddrTranslateSize < 0x3, 6271 ("ExtFeat invalid %#RX64\n", pThis->ExtFeat.u64), rcDataError); 6272 6283 ("ExtFeat.HATS register invalid %#RX64\n", pThis->ExtFeat.u64), rcErr); 6273 6284 pHlp->pfnSSMGetU64(pSSM, &pThis->DevSpecificFeat.u64); 6274 6285 pHlp->pfnSSMGetU64(pSSM, &pThis->DevSpecificCtrl.u64); … … 6277 6288 pHlp->pfnSSMGetU64(pSSM, &pThis->RsvdReg); 6278 6289 6290 /* IOMMU base address register. */ 6291 rc = pHlp->pfnSSMGetU64(pSSM, &pThis->IommuBar.u64); 6292 AssertRCReturn(rc, rc); 6293 pThis->IommuBar.u64 &= IOMMU_BAR_VALID_MASK; 6294 6279 6295 /* Device table base address registers. */ 6280 6296 uint8_t cDevTabBaseAddrs; 6281 6297 rc = pHlp->pfnSSMGetU8(pSSM, &cDevTabBaseAddrs); 6282 6298 AssertRCReturn(rc, rc); 6283 AssertLogRelMsgReturn(cDevTabBaseAddrs <= RT_ELEMENTS(pThis->aDevTabBaseAddrs),6284 ("Device table segment count invalid %#x\n", cDevTabBaseAddrs), rc DataError);6299 AssertLogRelMsgReturn(cDevTabBaseAddrs > 0 && cDevTabBaseAddrs <= RT_ELEMENTS(pThis->aDevTabBaseAddrs), 6300 ("Device table segment count invalid %#x\n", cDevTabBaseAddrs), rcErr); 6285 6301 for (uint8_t i = 0; i < cDevTabBaseAddrs; i++) 6286 6302 { … … 6289 6305 pThis->aDevTabBaseAddrs[i].u64 &= IOMMU_DEV_TAB_BAR_VALID_MASK; 6290 6306 AssertLogRelMsgReturn(pThis->aDevTabBaseAddrs[i].n.u9Size <= g_auDevTabSegMaxSizes[0], 6291 ("Device table segment size invalid %#x\n", pThis->aDevTabBaseAddrs[i].n.u9Size), rc DataError);6307 ("Device table segment size invalid %#x\n", pThis->aDevTabBaseAddrs[i].n.u9Size), rcErr); 6292 6308 } 6293 6309 … … 6297 6313 pThis->CmdBufBaseAddr.u64 &= IOMMU_CMD_BUF_BAR_VALID_MASK; 6298 6314 AssertLogRelMsgReturn(pThis->CmdBufBaseAddr.n.u4Len >= 8, 6299 ("Command buffer base address invalid %#RX64\n", pThis->CmdBufBaseAddr.u64), rc DataError);6315 ("Command buffer base address invalid %#RX64\n", pThis->CmdBufBaseAddr.u64), rcErr); 6300 6316 6301 6317 /* Event log base address register. */ 6302 pHlp->pfnSSMPutU64(pSSM, pThis->EvtLogBaseAddr.u64);6303 6318 rc = pHlp->pfnSSMGetU64(pSSM, &pThis->EvtLogBaseAddr.u64); 6304 6319 AssertRCReturn(rc, rc); 6305 6320 pThis->EvtLogBaseAddr.u64 &= IOMMU_EVT_LOG_BAR_VALID_MASK; 6306 6321 AssertLogRelMsgReturn(pThis->EvtLogBaseAddr.n.u4Len >= 8, 6307 ("Event log base address invalid %#RX64\n", pThis->EvtLogBaseAddr.u64), rc DataError);6322 ("Event log base address invalid %#RX64\n", pThis->EvtLogBaseAddr.u64), rcErr); 6308 6323 6309 6324 /* Control register. */ 6310 rc = pHlp->pfnSSM PutU64(pSSM,pThis->Ctrl.u64);6325 rc = pHlp->pfnSSMGetU64(pSSM, &pThis->Ctrl.u64); 6311 6326 AssertRCReturn(rc, rc); 6312 6327 pThis->Ctrl.u64 &= IOMMU_CTRL_VALID_MASK; 6313 6328 AssertLogRelMsgReturn(pThis->Ctrl.n.u3DevTabSegEn <= pThis->ExtFeat.n.u2DevTabSegSup, 6314 ("Control register invalid %#RX64\n", pThis->Ctrl.u64), rc DataError);6329 ("Control register invalid %#RX64\n", pThis->Ctrl.u64), rcErr); 6315 6330 6316 6331 /* Exclusion range base address register. */ … … 6402 6417 rc = pHlp->pfnSSMGetU8(pSSM, &cMarcApers); 6403 6418 AssertRCReturn(rc, rc); 6404 AssertLogRelMsgReturn(cMarcApers <= RT_ELEMENTS(pThis->aMarcApers),6405 ("MARC register count invalid %#x\n", cMarcApers), rc DataError);6419 AssertLogRelMsgReturn(cMarcApers > 0 && cMarcApers <= RT_ELEMENTS(pThis->aMarcApers), 6420 ("MARC register count invalid %#x\n", cMarcApers), rcErr); 6406 6421 for (uint8_t i = 0; i < cMarcApers; i++) 6407 6422 { … … 6423 6438 6424 6439 /* Command buffer head pointer register. */ 6425 { 6426 rc = pHlp->pfnSSMGetU64(pSSM, &pThis->CmdBufHeadPtr.u64); 6427 AssertRCReturn(rc, rc); 6428 6440 rc = pHlp->pfnSSMGetU64(pSSM, &pThis->CmdBufHeadPtr.u64); 6441 AssertRCReturn(rc, rc); 6442 { 6429 6443 /* 6430 6444 * IOMMU behavior is undefined when software writes a value outside the buffer length. … … 6436 6450 Assert(cbBuf <= _512K); 6437 6451 AssertLogRelMsgReturn(offBuf < cbBuf, 6438 ("Command buffer head pointer invalid %#x\n", pThis->CmdBufHeadPtr.u64), rc DataError);6452 ("Command buffer head pointer invalid %#x\n", pThis->CmdBufHeadPtr.u64), rcErr); 6439 6453 } 6440 6454 6441 6455 /* Command buffer tail pointer register. */ 6442 { 6443 rc = pHlp->pfnSSMGetU64(pSSM, &pThis->CmdBufTailPtr.u64); 6444 AssertRCReturn(rc, rc); 6445 6456 rc = pHlp->pfnSSMGetU64(pSSM, &pThis->CmdBufTailPtr.u64); 6457 AssertRCReturn(rc, rc); 6458 { 6446 6459 uint32_t const offBuf = pThis->CmdBufTailPtr.u64 & IOMMU_CMD_BUF_TAIL_PTR_VALID_MASK; 6447 6460 uint32_t const cbBuf = iommuAmdGetTotalBufLength(pThis->CmdBufBaseAddr.n.u4Len); 6448 6461 Assert(cbBuf <= _512K); 6449 6462 AssertLogRelMsgReturn(offBuf < cbBuf, 6450 ("Command buffer tail pointer invalid %#x\n", pThis->CmdBufTailPtr.u64), rc DataError);6463 ("Command buffer tail pointer invalid %#x\n", pThis->CmdBufTailPtr.u64), rcErr); 6451 6464 } 6452 6465 6453 6466 /* Event log head pointer register. */ 6454 { 6455 rc = pHlp->pfnSSMGetU64(pSSM, &pThis->EvtLogHeadPtr.u64); 6456 AssertRCReturn(rc, rc); 6457 6467 rc = pHlp->pfnSSMGetU64(pSSM, &pThis->EvtLogHeadPtr.u64); 6468 AssertRCReturn(rc, rc); 6469 { 6458 6470 uint32_t const offBuf = pThis->EvtLogHeadPtr.u64 & IOMMU_EVT_LOG_HEAD_PTR_VALID_MASK; 6459 6471 uint32_t const cbBuf = iommuAmdGetTotalBufLength(pThis->EvtLogBaseAddr.n.u4Len); 6460 6472 Assert(cbBuf <= _512K); 6461 6473 AssertLogRelMsgReturn(offBuf < cbBuf, 6462 ("Event log head pointer invalid %#x\n", pThis->EvtLogHeadPtr.u64), rc DataError);6474 ("Event log head pointer invalid %#x\n", pThis->EvtLogHeadPtr.u64), rcErr); 6463 6475 } 6464 6476 6465 6477 /* Event log tail pointer register. */ 6466 { 6467 rc = pHlp->pfnSSMGetU64(pSSM, &pThis->EvtLogTailPtr.u64); 6468 AssertRCReturn(rc, rc); 6469 6478 rc = pHlp->pfnSSMGetU64(pSSM, &pThis->EvtLogTailPtr.u64); 6479 AssertRCReturn(rc, rc); 6480 { 6470 6481 uint32_t const offBuf = pThis->EvtLogTailPtr.u64 & IOMMU_EVT_LOG_TAIL_PTR_VALID_MASK; 6471 6482 uint32_t const cbBuf = iommuAmdGetTotalBufLength(pThis->EvtLogBaseAddr.n.u4Len); 6472 6483 Assert(cbBuf <= _512K); 6473 6484 AssertLogRelMsgReturn(offBuf < cbBuf, 6474 ("Event log tail pointer invalid %#x\n", pThis->EvtLogTailPtr.u64), rc DataError);6485 ("Event log tail pointer invalid %#x\n", pThis->EvtLogTailPtr.u64), rcErr); 6475 6486 } 6476 6487 … … 6541 6552 AssertLogRelMsgRCReturn(rc, ("Failed to read end marker. rc=%Rrc\n", rc), VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 6542 6553 AssertLogRelMsgReturn(uEndMarker == UINT32_MAX, ("End marker invalid (%#x expected %#x)\n", uEndMarker, UINT32_MAX), 6543 rcDataError); 6544 } 6545 6554 rcErr); 6555 } 6556 6557 return rc; 6558 } 6559 6560 6561 /** 6562 * @callback_method_impl{FNSSMDEVLOADDONE} 6563 */ 6564 static DECLCALLBACK(int) iommuAmdR3LoadDone(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 6565 { 6566 PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU); 6567 PIOMMUR3 pThisR3 = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUR3); 6568 RT_NOREF(pSSM); 6569 LogFlowFunc(("\n")); 6570 6571 /* Sanity. */ 6572 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 6573 AssertPtrReturn(pThisR3, VERR_INVALID_POINTER); 6574 6575 IOMMU_LOCK(pDevIns, pThisR3); 6576 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]); 6580 6581 /* Wake up the command thread if commands need processing. */ 6546 6582 iommuAmdCmdThreadWakeUpIfNeeded(pDevIns); 6583 6584 IOMMU_UNLOCK(pDevIns, pThisR3); 6547 6585 return VINF_SUCCESS; 6548 6586 } … … 6848 6886 * Register saved state. 6849 6887 */ 6850 rc = PDMDevHlpSSMRegister3(pDevIns, IOMMU_SAVED_STATE_VERSION, sizeof(IOMMU), iommuAmdR3LiveExec, iommuAmdR3SaveExec, 6851 iommuAmdR3LoadExec); 6888 rc = PDMDevHlpSSMRegisterEx(pDevIns, IOMMU_SAVED_STATE_VERSION, sizeof(IOMMU), NULL /* pszBefore */, 6889 NULL /* pfnLivePrep */, NULL /* pfnLiveExec */, NULL /* pfnLiveVote */, 6890 NULL /* pfnSavePrep */, iommuAmdR3SaveExec, NULL /* pfnSaveDone */, 6891 NULL /* pfnLoadPrep */, iommuAmdR3LoadExec, iommuAmdR3LoadDone); 6852 6892 AssertLogRelRCReturn(rc, rc); 6853 6893
Note:
See TracChangeset
for help on using the changeset viewer.

