Changeset 88682 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Apr 23, 2021 3:18:37 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp
r88669 r88682 815 815 * register. 816 816 */ 817 static void dmarRegChange 32(PDMAR pThis, uint16_t offReg, uint32_t fAndMask, uint32_t fOrMask)818 { 819 uint32_t uReg = dmarRegRead 32(pThis, offReg);817 static void dmarRegChangeRaw32(PDMAR pThis, uint16_t offReg, uint32_t fAndMask, uint32_t fOrMask) 818 { 819 uint32_t uReg = dmarRegReadRaw32(pThis, offReg); 820 820 uReg = (uReg & fAndMask) | fOrMask; 821 821 dmarRegWriteRaw32(pThis, offReg, uReg); … … 833 833 * register. 834 834 */ 835 static void dmarRegChange 64(PDMAR pThis, uint16_t offReg, uint64_t fAndMask, uint64_t fOrMask)836 { 837 uint64_t uReg = dmarRegRead 64(pThis, offReg);835 static void dmarRegChangeRaw64(PDMAR pThis, uint16_t offReg, uint64_t fAndMask, uint64_t fOrMask) 836 { 837 uint64_t uReg = dmarRegReadRaw64(pThis, offReg); 838 838 uReg = (uReg & fAndMask) | fOrMask; 839 839 dmarRegWriteRaw64(pThis, offReg, uReg); … … 875 875 * Checks whether the invalidation-queue is capable of processing requests. 876 876 * 877 * @returns @c true if the invalidation-queue can be processed, @c false otherwise. 877 * @returns @c true if the invalidation-queue can process requests, @c false 878 * otherwise. 878 879 * @param pThis The shared DMAR device state. 879 880 */ … … 884 885 if (uGstsReg & VTD_BF_GSTS_REG_QIES_MASK) 885 886 { 886 /* Check if there are no IQ errors and that the queue isn't empty. */887 /* Check if there are no invalidation-queue or timeout errors. */ 887 888 uint32_t const uFstsReg = dmarRegRead32(pThis, VTD_MMIO_OFF_FSTS_REG); 888 if ( !(uFstsReg & VTD_BF_FSTS_REG_IQE_MASK) 889 && !dmarInvQueueIsEmpty(pThis)) 889 if (!(uFstsReg & (VTD_BF_FSTS_REG_IQE_MASK | VTD_BF_FSTS_REG_ITE_MASK))) 890 890 return true; 891 891 } … … 908 908 909 909 if ( dmarInvQueueCanProcessRequests(pThis) 910 && !dmarInvQueueIsEmpty(pThis) 910 911 && !ASMAtomicXchgBool(&pThis->fInvQueueThreadSignaled, true)) 911 912 { … … 939 940 if (!(uFectlReg & VTD_BF_FECTL_REG_IM_MASK)) 940 941 { 942 /* Software has unmasked the interrupt, raise it. */ 941 943 MSIMSG Msi; 942 944 Msi.Addr.u64 = RT_MAKE_U64(dmarRegRead32(pThis, VTD_MMIO_OFF_FEADDR_REG), … … 947 949 * FEADD_REG write it can't be anything else. */ 948 950 949 /* Software has unmasked the interrupt, raise it. */950 951 pThisCC->CTX_SUFF(pIommuHlp)->pfnSendMsi(pDevIns, &Msi, 0 /* uTagSrc */); 951 952 … … 1017 1018 /* Set the error bit. */ 1018 1019 uint32_t const fIqe = RT_BF_MAKE(VTD_BF_FSTS_REG_IQE, 1); 1019 dmarRegChange 32(pThis, VTD_MMIO_OFF_FSTS_REG, UINT32_MAX, fIqe);1020 dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_FSTS_REG, UINT32_MAX, fIqe); 1020 1021 1021 1022 /* Set the error information. */ 1022 1023 uint64_t const fIqei = RT_BF_MAKE(VTD_BF_IQERCD_REG_IQEI, enmIqei); 1023 dmarRegChange 64(pThis, VTD_MMIO_OFF_IQERCD_REG, UINT64_MAX, fIqei);1024 dmarRegChangeRaw64(pThis, VTD_MMIO_OFF_IQERCD_REG, UINT64_MAX, fIqei); 1024 1025 1025 1026 dmarFaultRaiseInterrupt(pDevIns); 1027 } 1028 1029 1030 /** 1031 * Handles writes to GCMD_REG. 1032 * 1033 * @returns Strict VBox status code. 1034 * @param pDevIns The IOMMU device instance. 1035 * @param uGcmdReg The value written to GCMD_REG. 1036 */ 1037 static VBOXSTRICTRC dmarGcmdRegWrite(PPDMDEVINS pDevIns, uint32_t uGcmdReg) 1038 { 1039 PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); 1040 uint32_t const uGstsReg = dmarRegRead32(pThis, VTD_MMIO_OFF_GSTS_REG); 1041 uint32_t const fChanged = uGstsReg ^ uGcmdReg; 1042 if (pThis->fExtCap & VTD_BF_ECAP_REG_QI_MASK) 1043 { 1044 if (fChanged & VTD_BF_GCMD_REG_QIE_MASK) 1045 { 1046 if (uGcmdReg & VTD_BF_GCMD_REG_QIE_MASK) 1047 { 1048 /* Enable the invalidation-queue. */ 1049 dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, UINT32_MAX /* fAndMask */, 1050 VTD_BF_GSTS_REG_QIES_MASK /* fOrMask */); 1051 dmarInvQueueThreadWakeUpIfNeeded(pDevIns); 1052 } 1053 else 1054 { 1055 /* Disable the invalidation-queue and reset the queue head offset. */ 1056 dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, ~VTD_BF_GSTS_REG_QIES_MASK /* fAndMask */, 0 /* fOrMask */); 1057 dmarRegWriteRaw32(pThis, VTD_MMIO_OFF_IQH_REG, 0); 1058 } 1059 } 1060 } 1061 1062 /** @todo Rest of the bits? */ 1063 1064 return VINF_SUCCESS; 1026 1065 } 1027 1066 … … 1092 1131 else 1093 1132 { 1094 /* Hardware treats bit 4 as RsvdZ here, so clear it. */1095 dmarRegChange 32(pThis, offReg, ~RT_BIT(4) /* fAndMask*/ , 0 /* fOrMask */);1133 /* Hardware treats bit 4 as RsvdZ in this situation, so clear it. */ 1134 dmarRegChangeRaw32(pThis, offReg, ~RT_BIT(4) /* fAndMask*/ , 0 /* fOrMask */); 1096 1135 dmarIqeFaultRecord(pDevIns, kDmarDiag_IqtReg_Qt_NotAligned, kQueueTailNotAligned); 1097 1136 } … … 1217 1256 switch (off) 1218 1257 { 1258 case VTD_MMIO_OFF_GCMD_REG: 1259 { 1260 rcStrict = dmarGcmdRegWrite(pDevIns, uRegWritten); 1261 break; 1262 } 1263 1219 1264 case VTD_MMIO_OFF_CCMD_REG: 1220 1265 case VTD_MMIO_OFF_CCMD_REG + 4: … … 1301 1346 return VINF_SUCCESS; 1302 1347 1303 PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR);1304 PCDMARR3 pThisR3 = PDMDEVINS_2_DATA_CC(pDevIns, PCDMARR3);1305 1306 1348 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 1307 1349 { 1350 PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); 1351 PCDMARR3 pThisR3 = PDMDEVINS_2_DATA_CC(pDevIns, PCDMARR3); 1352 1308 1353 /* 1309 1354 * Sleep until we are woken up. … … 1319 1364 } 1320 1365 1321 /* 1322 * Fetch and process invalidation requests. 1323 */ 1324 DMAR_LOCK_RET(pDevIns, pThisR3, VERR_IGNORED); 1325 /** @todo use dmarInvQueueCanProcessRequests instead? */ 1326 uint32_t const uGstsReg = dmarRegRead32(pThis, VTD_MMIO_OFF_GSTS_REG); 1366 DMAR_LOCK(pDevIns, pThisR3); 1367 if (dmarInvQueueCanProcessRequests(pThis)) 1368 { 1369 /** @todo Read IQH and IQT, descriptors from memory and perform invalidation. */ 1370 } 1327 1371 DMAR_UNLOCK(pDevIns, pThisR3); 1328 1329 if (uGstsReg & VTD_BF_GSTS_REG_QIES_MASK)1330 {1331 /** @todo Read invalidation descriptors and perform invalidation. */1332 }1333 1372 } 1334 1373 … … 1385 1424 { 1386 1425 PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); 1426 1427 /* 1428 * Wipe all registers (required on reset). 1429 */ 1387 1430 RT_ZERO(pThis->abRegs0); 1388 1431 RT_ZERO(pThis->abRegs1); … … 1460 1503 1461 1504 pThis->fExtCap = RT_BF_MAKE(VTD_BF_ECAP_REG_C, 0) /* Accesses don't snoop CPU cache. */ 1462 | RT_BF_MAKE(VTD_BF_ECAP_REG_QI, 1)1505 | RT_BF_MAKE(VTD_BF_ECAP_REG_QI, fQi) 1463 1506 | RT_BF_MAKE(VTD_BF_ECAP_REG_DT, 0) /* Device-TLBs not supported. */ 1464 1507 | RT_BF_MAKE(VTD_BF_ECAP_REG_IR, fQi & fIr) … … 1539 1582 LogFlowFunc(("\n")); 1540 1583 1541 DMAR_LOCK _RET(pDevIns, pThisR3, VERR_IGNORED);1584 DMAR_LOCK(pDevIns, pThisR3); 1542 1585 1543 1586 if (pThis->hEvtInvQueue != NIL_SUPSEMEVENT)
Note:
See TracChangeset
for help on using the changeset viewer.