- Timestamp:
- Jan 15, 2017 6:07:07 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
-
include/VBox/vmm/pdmpcidev.h (modified) (3 diffs)
-
src/VBox/Devices/Bus/DevPCI.cpp (modified) (8 diffs)
-
src/VBox/Devices/Bus/DevPciIch9.cpp (modified) (14 diffs)
-
src/VBox/Devices/Bus/DevPciInternal.h (modified) (1 diff)
-
src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmpcidev.h
r64455 r65301 81 81 * @param pDevIns Pointer to the device instance the PCI device 82 82 * belongs to. 83 * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.83 * @param pPciDev Pointer to the PCI device. 84 84 * @param iRegion The region number. 85 85 * @param GCPhysAddress Physical address of the region. If enmType is PCI_ADDRESS_SPACE_IO, this … … 100 100 /** Pointer to a FNPCIIOREGIONMAP() function. */ 101 101 typedef FNPCIIOREGIONMAP *PFNPCIIOREGIONMAP; 102 103 104 /** 105 * Sets the size and type for old saved states from within a 106 * PDMPCIDEV::pfnRegionLoadChangeHookR3 callback. 107 * 108 * @returns VBox status code. 109 * @param pPciDev Pointer to the PCI device. 110 * @param iRegion The region number. 111 * @param cbRegion The region size. 112 * @param enmType Combination of the PCI_ADDRESS_SPACE_* values. 113 */ 114 typedef DECLCALLBACK(int) FNPCIIOREGIONOLDSETTER(PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cbRegion, PCIADDRESSSPACE enmType); 115 /** Pointer to a FNPCIIOREGIONOLDSETTER() function. */ 116 typedef FNPCIIOREGIONOLDSETTER *PFNPCIIOREGIONOLDSETTER; 117 102 118 103 119 … … 142 158 /** Device name. */ 143 159 R3PTRTYPE(const char *) pszNameR3; 144 /** Reserved. */145 RTR3PTR pvReserved;146 160 /** @} */ 161 162 /** 163 * Callback for dealing with size changes. 164 * 165 * This is set by the PCI device when needed. It is only needed if any changes 166 * in the PCI resources have been made that may be incompatible with saved state 167 * (i.e. does not reflect configuration, but configuration defaults changed). 168 * 169 * The implementation can use PDMDevHlpMMIOExReduce to adjust the resource 170 * allocation down in size. There is currently no way of growing resources. 171 * Dropping a resource is automatic. 172 * 173 * @returns VBox status code. 174 * @param pDevIns Pointer to the device instance the PCI device 175 * belongs to. 176 * @param pPciDev Pointer to the PCI device. 177 * @param iRegion The region number or UINT32_MAX if old saved state call. 178 * @param cbRegion The size being loaded, RTGCPHYS_MAX if old saved state 179 * call, or 0 for dummy 64-bit top half region. 180 * @param enmType The type being loaded, -1 if old saved state call, or 181 * 0xff if dummy 64-bit top half region. 182 * @param pfnOldSetter Callback for setting size and type for call 183 * regarding old saved states. NULL otherwise. 184 */ 185 DECLR3CALLBACKMEMBER(int, pfnRegionLoadChangeHookR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, 186 uint64_t cbRegion, PCIADDRESSSPACE enmType, 187 PFNPCIIOREGIONOLDSETTER pfnOldSetter)); 147 188 } PDMPCIDEV; 148 189 #ifdef PDMPCIDEVINT_DECLARED -
trunk/src/VBox/Devices/Bus/DevPCI.cpp
r65283 r65301 68 68 * Defined Constants And Macros * 69 69 *********************************************************************************************************************************/ 70 /** @def VBOX_PCI_SAVED_STATE_VERSION 71 * Saved state version of the PCI bus device. 72 */ 73 #define VBOX_PCI_SAVED_STATE_VERSION 3 70 /** Saved state version of the PCI bus device. */ 71 #define VBOX_PCI_SAVED_STATE_VERSION VBOX_PCI_SAVED_STATE_VERSION_REGION_SIZES 72 /** Adds I/O region types and sizes for dealing changes in resource regions. */ 73 #define VBOX_PCI_SAVED_STATE_VERSION_REGION_SIZES 4 74 /** Before region sizes, the first named one. 75 * Looking at the code though, we support even older version. */ 76 #define VBOX_PCI_SAVED_STATE_VERSION_IRQ_STATES 3 77 /** Notes whether we use the I/O APIC. */ 78 #define VBOX_PCI_SAVED_STATE_VERSION_USE_IO_APIC 2 74 79 75 80 … … 886 891 SSMR3PutMem(pSSM, pDev->abConfig, sizeof(pDev->abConfig)); 887 892 888 int rc = SSMR3PutS32(pSSM, pDev->Int.s.uIrqPinState); 889 if (RT_FAILURE(rc)) 890 return rc; 893 SSMR3PutS32(pSSM, pDev->Int.s.uIrqPinState); 894 895 /* Save the type an size of all the regions. */ 896 for (uint32_t iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS; iRegion++) 897 { 898 SSMR3PutU8(pSSM, pDev->Int.s.aIORegions[iRegion].type); 899 SSMR3PutU64(pSSM, pDev->Int.s.aIORegions[iRegion].size); 900 } 891 901 } 892 902 } … … 971 981 for (i = 0;; i++) 972 982 { 973 PDMPCIDEV DevTmp;974 PPDMPCIDEV pDev;975 976 983 /* index / terminator */ 977 984 rc = SSMR3GetU32(pSSM, &u32); 978 985 if (RT_FAILURE(rc)) 979 986 return rc; 980 if (u32 == (uint32_t)~0)987 if (u32 == UINT32_MAX) 981 988 break; 982 989 if ( u32 >= RT_ELEMENTS(pBus->apDevices) … … 1001 1008 1002 1009 /* get the data */ 1010 PDMPCIDEV DevTmp; 1011 RT_ZERO(DevTmp); 1003 1012 DevTmp.Int.s.uIrqPinState = ~0; /* Invalid value in case we have an older saved state to force a state change in pciSetIrq. */ 1004 1013 SSMR3GetMem(pSSM, DevTmp.abConfig, sizeof(DevTmp.abConfig)); 1005 if (uVersion < 3)1014 if (uVersion < VBOX_PCI_SAVED_STATE_VERSION_IRQ_STATES) 1006 1015 { 1007 1016 int32_t i32Temp; … … 1018 1027 } 1019 1028 1029 /* Load the region types and sizes. */ 1030 if (uVersion >= VBOX_PCI_SAVED_STATE_VERSION_REGION_SIZES) 1031 { 1032 for (uint32_t iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS; iRegion++) 1033 { 1034 SSMR3GetU8(pSSM, &DevTmp.Int.s.aIORegions[iRegion].type); 1035 rc = SSMR3GetU64(pSSM, &DevTmp.Int.s.aIORegions[iRegion].size); 1036 AssertLogRelRCReturn(rc, rc); 1037 } 1038 } 1039 1020 1040 /* check that it's still around. */ 1021 pDev = pBus->apDevices[i];1041 PPDMPCIDEV pDev = pBus->apDevices[i]; 1022 1042 if (!pDev) 1023 1043 { … … 1033 1053 if ( DevTmp.abConfig[0] != pDev->abConfig[0] 1034 1054 || DevTmp.abConfig[1] != pDev->abConfig[1]) 1035 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Device in slot %#x (%s) vendor id mismatch! saved=%.4Rhxs current=%.4Rhxs"), 1055 return SSMR3SetCfgError(pSSM, RT_SRC_POS, 1056 N_("Device in slot %#x (%s) vendor id mismatch! saved=%.4Rhxs current=%.4Rhxs"), 1036 1057 i, pDev->pszNameR3, DevTmp.abConfig, pDev->abConfig); 1037 1058 1038 1059 /* commit the loaded device config. */ 1060 rc = devpciR3CommonRestoreRegions(pSSM, pDev, DevTmp.Int.s.aIORegions, 1061 uVersion >= VBOX_PCI_SAVED_STATE_VERSION_REGION_SIZES); 1062 if (RT_FAILURE(rc)) 1063 break; 1039 1064 devpciR3CommonRestoreConfig(pDev, &DevTmp.abConfig[0]); 1040 1065 … … 1067 1092 */ 1068 1093 SSMR3GetU32(pSSM, &pThis->uConfigReg); 1069 if (uVersion > 1)1094 if (uVersion >= VBOX_PCI_SAVED_STATE_VERSION_USE_IO_APIC) 1070 1095 SSMR3GetBool(pSSM, &pThis->fUseIoApic); 1071 1096 1072 1097 /* Load IRQ states. */ 1073 if (uVersion > 2)1098 if (uVersion >= VBOX_PCI_SAVED_STATE_VERSION_IRQ_STATES) 1074 1099 { 1075 1100 for (uint8_t i = 0; i < RT_ELEMENTS(pThis->Piix3.auPciLegacyIrqLevels); i++) … … 1086 1111 if (RT_FAILURE(rc)) 1087 1112 return rc; 1088 if (u32 != (uint32_t)~0)1113 if (u32 != UINT32_MAX) 1089 1114 AssertMsgFailedReturn(("u32=%#x\n", u32), rc); 1090 1115 -
trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
r65292 r65301 74 74 * Defined Constants And Macros * 75 75 *********************************************************************************************************************************/ 76 /** @def VBOX_ICH9PCI_SAVED_STATE_VERSION_CURRENT 77 * Saved state version of the ICH9 PCI bus device. 78 */ 79 #define VBOX_ICH9PCI_SAVED_STATE_VERSION_NOMSI 1 80 #define VBOX_ICH9PCI_SAVED_STATE_VERSION_MSI 2 81 #define VBOX_ICH9PCI_SAVED_STATE_VERSION_CURRENT VBOX_ICH9PCI_SAVED_STATE_VERSION_MSI 76 /** Saved state version of the ICH9 PCI bus device. */ 77 #define VBOX_ICH9PCI_SAVED_STATE_VERSION VBOX_ICH9PCI_SAVED_STATE_VERSION_REGION_SIZES 78 /** Adds I/O region types and sizes for dealing changes in resource regions. */ 79 #define VBOX_ICH9PCI_SAVED_STATE_VERSION_REGION_SIZES 3 80 /** This appears to be the first state we need to care about. */ 81 #define VBOX_ICH9PCI_SAVED_STATE_VERSION_MSI 2 82 /** This is apparently not supported or has a grossly incomplete state, juding 83 * from hints in the code. */ 84 #define VBOX_ICH9PCI_SAVED_STATE_VERSION_NOMSI 1 82 85 83 86 /** Invalid PCI region mapping address. */ … … 918 921 if (RT_FAILURE(rc)) 919 922 return rc; 923 920 924 /* Save MSI-X page state */ 921 925 if (pDev->Int.s.u8MsixCapOffset != 0) … … 925 929 if (RT_FAILURE(rc)) 926 930 return rc; 931 } 932 933 /* Save the type an size of all the regions. */ 934 for (uint32_t iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS; iRegion++) 935 { 936 SSMR3PutU8(pSSM, pDev->Int.s.aIORegions[iRegion].type); 937 rc = SSMR3PutU64(pSSM, pDev->Int.s.aIORegions[iRegion].size); 938 AssertRCReturn(rc, rc); 927 939 } 928 940 } … … 1198 1210 } 1199 1211 1212 1213 /** 1214 * @callback_method_impl{FNPCIIOREGIONOLDSETTER} 1215 */ 1216 static DECLCALLBACK(int) devpciR3CommonRestoreOldSetRegion(PPDMPCIDEV pPciDev, uint32_t iRegion, 1217 RTGCPHYS cbRegion, PCIADDRESSSPACE enmType) 1218 { 1219 AssertLogRelReturn(iRegion < RT_ELEMENTS(pPciDev->Int.s.aIORegions), VERR_INVALID_PARAMETER); 1220 pPciDev->Int.s.aIORegions[iRegion].type = enmType; 1221 pPciDev->Int.s.aIORegions[iRegion].size = cbRegion; 1222 return VINF_SUCCESS; 1223 } 1224 1225 1226 /** 1227 * Checks for and deals with changes in resource sizes and types. 1228 * 1229 * @returns VBox status code. 1230 * @param pSSM The Saved state handle. 1231 * @param pPciDev The PCI device in question. 1232 * @param paIoRegions I/O regions with the size and type fields from 1233 * the saved state. 1234 * @param fNewState Set if this is a new state with I/O region sizes 1235 * and types, clear if old one. 1236 */ 1237 int devpciR3CommonRestoreRegions(PSSMHANDLE pSSM, PPDMPCIDEV pPciDev, PPCIIOREGION paIoRegions, bool fNewState) 1238 { 1239 int rc; 1240 if (fNewState) 1241 { 1242 for (uint32_t iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS; iRegion++) 1243 { 1244 if ( pPciDev->Int.s.aIORegions[iRegion].type != paIoRegions[iRegion].type 1245 || pPciDev->Int.s.aIORegions[iRegion].size != paIoRegions[iRegion].size) 1246 { 1247 AssertLogRelMsgFailed(("PCI: %8s/%u: region #%u size/type load change: %#RGp/%#x -> %#RGp/%#x\n", 1248 pPciDev->pszNameR3, pPciDev->Int.s.CTX_SUFF(pDevIns)->iInstance, 1249 pPciDev->Int.s.aIORegions[iRegion].size, pPciDev->Int.s.aIORegions[iRegion].type, 1250 paIoRegions[iRegion].size, paIoRegions[iRegion].type)); 1251 if (pPciDev->pfnRegionLoadChangeHookR3) 1252 { 1253 rc = pPciDev->pfnRegionLoadChangeHookR3(pPciDev->Int.s.pDevInsR3, pPciDev, iRegion, paIoRegions[iRegion].size, 1254 (PCIADDRESSSPACE)paIoRegions[iRegion].type, NULL /*pfnOldSetter*/); 1255 if (RT_FAILURE(rc)) 1256 return SSMR3SetLoadError(pSSM, rc, RT_SRC_POS, 1257 N_("Device %s/%u failed to respond to region #%u size/type changing from %#RGp/%#x to %#RGp/%#x: %Rrc"), 1258 pPciDev->pszNameR3, pPciDev->Int.s.CTX_SUFF(pDevIns)->iInstance, iRegion, 1259 pPciDev->Int.s.aIORegions[iRegion].size, pPciDev->Int.s.aIORegions[iRegion].type, 1260 paIoRegions[iRegion].size, paIoRegions[iRegion].type, rc); 1261 } 1262 pPciDev->Int.s.aIORegions[iRegion].type = paIoRegions[iRegion].type; 1263 pPciDev->Int.s.aIORegions[iRegion].size = paIoRegions[iRegion].size; 1264 } 1265 } 1266 } 1267 /* Old saved state without sizes and types. Do a special hook call to give 1268 devices with changes a chance to adjust resources back to old values. */ 1269 else if (pPciDev->pfnRegionLoadChangeHookR3) 1270 { 1271 rc = pPciDev->pfnRegionLoadChangeHookR3(pPciDev->Int.s.pDevInsR3, pPciDev, UINT32_MAX, RTGCPHYS_MAX, (PCIADDRESSSPACE)-1, 1272 devpciR3CommonRestoreOldSetRegion); 1273 if (RT_FAILURE(rc)) 1274 return SSMR3SetLoadError(pSSM, rc, RT_SRC_POS, N_("Device %s/%u failed to resize its resources: %Rrc"), 1275 pPciDev->pszNameR3, pPciDev->Int.s.CTX_SUFF(pDevIns)->iInstance, rc); 1276 } 1277 return VINF_SUCCESS; 1278 } 1279 1280 1200 1281 /** 1201 1282 * Common worker for ich9pciR3LoadExec and ich9pcibridgeR3LoadExec. … … 1214 1295 1215 1296 Assert(uPass == SSM_PASS_FINAL); NOREF(uPass); 1216 if (uVersion != VBOX_ICH9PCI_SAVED_STATE_VERSION_CURRENT) 1297 if ( uVersion < VBOX_ICH9PCI_SAVED_STATE_VERSION_MSI 1298 || uVersion > VBOX_ICH9PCI_SAVED_STATE_VERSION) 1217 1299 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 1218 1300 … … 1248 1330 for (i = 0;; i++) 1249 1331 { 1250 PPDMPCIDEV pDev;1251 PDMPCIDEV DevTmp;1252 1253 1332 /* index / terminator */ 1254 1333 rc = SSMR3GetU32(pSSM, &u32); … … 1260 1339 1261 1340 /* skip forward to the device checking that no new devices are present. */ 1341 PPDMPCIDEV pDev; 1262 1342 for (; i < u32; i++) 1263 1343 { … … 1281 1361 1282 1362 /* get the data */ 1363 PDMPCIDEV DevTmp; 1364 RT_ZERO(DevTmp); 1283 1365 DevTmp.Int.s.fFlags = 0; 1284 1366 DevTmp.Int.s.u8MsiCapOffset = 0; … … 1307 1389 } 1308 1390 1309 /* check that it's still around. */ 1391 /* Load the region types and sizes. */ 1392 if (uVersion >= VBOX_ICH9PCI_SAVED_STATE_VERSION_REGION_SIZES) 1393 { 1394 for (uint32_t iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS; iRegion++) 1395 { 1396 SSMR3GetU8(pSSM, &DevTmp.Int.s.aIORegions[iRegion].type); 1397 rc = SSMR3GetU64(pSSM, &DevTmp.Int.s.aIORegions[iRegion].size); 1398 AssertLogRelRCReturn(rc, rc); 1399 } 1400 } 1401 1402 /* 1403 * Check that it's still around. 1404 */ 1310 1405 pDev = pBus->apDevices[i]; 1311 1406 if (!pDev) … … 1335 1430 1336 1431 /* commit the loaded device config. */ 1432 rc = devpciR3CommonRestoreRegions(pSSM, pDev, DevTmp.Int.s.aIORegions, 1433 uVersion >= VBOX_ICH9PCI_SAVED_STATE_VERSION_REGION_SIZES); 1434 if (RT_FAILURE(rc)) 1435 break; 1337 1436 Assert(!pciDevIsPassthrough(pDev)); 1338 1437 devpciR3CommonRestoreConfig(pDev, &DevTmp.abConfig[0]); … … 1363 1462 1364 1463 /* We ignore this version as there's no saved state with it anyway */ 1365 if (uVersion == VBOX_ICH9PCI_SAVED_STATE_VERSION_NOMSI)1464 if (uVersion <= VBOX_ICH9PCI_SAVED_STATE_VERSION_NOMSI) 1366 1465 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 1367 if (uVersion > VBOX_ICH9PCI_SAVED_STATE_VERSION _MSI)1466 if (uVersion > VBOX_ICH9PCI_SAVED_STATE_VERSION) 1368 1467 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 1369 1468 … … 1392 1491 { 1393 1492 PDEVPCIBUS pThis = PDMINS_2_DATA(pDevIns, PDEVPCIBUS); 1394 if (uVersion > VBOX_ICH9PCI_SAVED_STATE_VERSION_MSI)1395 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;1396 1493 return ich9pciR3CommonLoadExec(pThis, pSSM, uVersion, uPass); 1397 1494 } … … 2730 2827 } 2731 2828 2732 rc = PDMDevHlpSSMRegisterEx(pDevIns, VBOX_ICH9PCI_SAVED_STATE_VERSION _CURRENT,2829 rc = PDMDevHlpSSMRegisterEx(pDevIns, VBOX_ICH9PCI_SAVED_STATE_VERSION, 2733 2830 sizeof(*pBus) + 16*128, "pgm", 2734 2831 NULL, NULL, NULL, … … 2972 3069 * to make changes easier. 2973 3070 */ 2974 rc = PDMDevHlpSSMRegisterEx(pDevIns, VBOX_ICH9PCI_SAVED_STATE_VERSION _CURRENT,3071 rc = PDMDevHlpSSMRegisterEx(pDevIns, VBOX_ICH9PCI_SAVED_STATE_VERSION, 2975 3072 sizeof(*pBus) + 16*128, 2976 3073 "pgm" /* before */, -
trunk/src/VBox/Devices/Bus/DevPciInternal.h
r65283 r65301 194 194 uint32_t uAddress, uint32_t u32Value, unsigned cb); 195 195 void devpciR3CommonRestoreConfig(PPDMPCIDEV pDev, uint8_t const *pbSrcConfig); 196 int devpciR3CommonRestoreRegions(PSSMHANDLE pSSM, PPDMPCIDEV pPciDev, PPCIIOREGION paIoRegions, bool fNewState); 196 197 197 198 #endif -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
r65294 r65301 148 148 GEN_CHECK_OFF(PDMPCIDEV, uDevFn); 149 149 GEN_CHECK_OFF(PDMPCIDEV, pszNameR3); 150 GEN_CHECK_OFF(PDMPCIDEV, p vReserved);150 GEN_CHECK_OFF(PDMPCIDEV, pfnRegionLoadChangeHookR3); 151 151 GEN_CHECK_OFF(PDMPCIDEV, Int); 152 152 GEN_CHECK_OFF(PDMPCIDEV, Int.s.aIORegions);
Note:
See TracChangeset
for help on using the changeset viewer.

