VirtualBox

Changeset 20153 in vbox


Ignore:
Timestamp:
May 29, 2009 1:28:12 PM (16 years ago)
Author:
vboxsync
Message:

SSM,PCI: We must restore the PCI configuration registers before PGM so that the MMIO mappings are in sync. Should fix #3903 and #1587.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/ssm.h

    r20114 r20153  
    418418
    419419
    420 VMMR3DECL(int) SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess,
     420VMMR3DECL(int) SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess, const char *pszBefore,
    421421    PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
    422422    PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone);
  • trunk/src/VBox/Devices/Bus/DevPCI.cpp

    r19314 r20153  
    12761276    SSMR3PutU32(pSSMHandle, pThis->uConfigReg);
    12771277    SSMR3PutBool(pSSMHandle, pThis->fUseIoApic);
     1278
    12781279    /*
    12791280     * Save IRQ states.
     
    13091310}
    13101311
     1312
     1313/**
     1314 * Common routine for restoring the config registers of a PCI device.
     1315 *
     1316 * @param   pDev                The PCI device.
     1317 * @param   pbSrcConfig         The configuration register values to be loaded.
     1318 * @param   fIsBridge           Whether this is a bridge device or not.
     1319 */
     1320static void pciR3CommonRestoreConfig(PPCIDEVICE pDev, uint8_t const *pbSrcConfig, bool fIsBridge)
     1321{
     1322    /* This table defines the fields for normal devices and bridge devices, and
     1323       the order in which they need to be restored (nothing special there atm). */
     1324    static const struct PciField
     1325    {
     1326        uint8_t     off;
     1327        uint8_t     cb;
     1328        uint8_t     fWritable;
     1329        uint8_t     fBridge;
     1330        const char *pszName;
     1331    } s_aFields[] =
     1332    {
     1333        /* off,cb,fW,fB, pszName */
     1334        { 0x00, 2, 0, 3, "VENDOR_ID" },
     1335        { 0x02, 2, 0, 3, "DEVICE_ID" },
     1336        { 0x04, 2, 1, 3, "COMMAND" },
     1337        { 0x06, 2, 1, 3, "STATUS" },
     1338        { 0x08, 1, 0, 3, "REVISION_ID" },
     1339        { 0x09, 1, 0, 3, "CLASS_PROG" },
     1340        { 0x0a, 1, 0, 3, "CLASS_SUB" },
     1341        { 0x0b, 1, 0, 3, "CLASS_BASE" },
     1342        { 0x0c, 1, 0, 3, "CACHE_LINE_SIZE" },   // fWritable = ??
     1343        { 0x0d, 1, 0, 3, "LATENCY_TIMER" },     // fWritable = ??
     1344        { 0x0e, 1, 0, 3, "HEADER_TYPE" },       // fWritable = ??
     1345        { 0x0f, 1, 0, 3, "BIST" },              // fWritable = ??
     1346        { 0x10, 4, 1, 3, "BASE_ADDRESS_0" },
     1347        { 0x14, 4, 1, 3, "BASE_ADDRESS_1" },
     1348        { 0x18, 4, 1, 3, "BASE_ADDRESS_2" },
     1349        { 0x18, 1, 1, 2, "PRIMARY_BUS" },       // fWritable = ??
     1350        { 0x19, 1, 1, 2, "SECONDARY_BUS" },     // fWritable = ??
     1351        { 0x1a, 1, 1, 2, "SUBORDINATE_BUS" },   // fWritable = ??
     1352        { 0x1b, 1, 1, 2, "SEC_LATENCY_TIMER" }, // fWritable = ??
     1353        { 0x1c, 4, 1, 1, "BASE_ADDRESS_3" },
     1354        { 0x1c, 1, 1, 2, "IO_BASE" },           // fWritable = ??
     1355        { 0x1d, 1, 1, 2, "IO_LIMIT" },          // fWritable = ??
     1356        { 0x1e, 2, 1, 2, "SEC_STATUS" },        // fWritable = ??
     1357        { 0x20, 4, 1, 1, "BASE_ADDRESS_4" },
     1358        { 0x20, 2, 1, 2, "MEMORY_BASE" },       // fWritable = ??
     1359        { 0x22, 2, 1, 2, "MEMORY_LIMIT" },      // fWritable = ??
     1360        { 0x24, 4, 1, 1, "BASE_ADDRESS_4" },
     1361        { 0x24, 2, 1, 2, "PREF_MEMORY_BASE" },  // fWritable = ??
     1362        { 0x26, 2, 1, 2, "PREF_MEMORY_LIMIT" }, // fWritable = ??
     1363        { 0x28, 4, 1, 1, "CARDBUS_CIS" },       // fWritable = ??
     1364        { 0x28, 4, 1, 2, "PREF_BASE_UPPER32" }, // fWritable = ??
     1365        { 0x2c, 2, 0, 1, "SUBSYSTEM_VENDOR_ID" },// fWritable = !?
     1366        { 0x2c, 4, 1, 2, "PREF_LIMIT_UPPER32" },// fWritable = ??
     1367        { 0x2e, 2, 0, 1, "SUBSYSTEM_ID" },      // fWritable = !?
     1368        { 0x30, 4, 1, 1, "ROM_ADDRESS" },       // fWritable = ?!
     1369        { 0x30, 2, 1, 2, "IO_BASE_UPPER16" },   // fWritable = ?!
     1370        { 0x32, 2, 1, 2, "IO_LIMIT_UPPER16" },  // fWritable = ?!
     1371        { 0x34, 4, 0, 3, "CAPABILITY_LIST" },   // fWritable = !? cb=!?
     1372        { 0x38, 4, 1, 2, "ROM_ADDRESS_BR" },    // fWritable = !? cb=!? fBridge=!?
     1373        { 0x3c, 1, 1, 3, "INTERRUPT_LINE" },    // fBridge=??
     1374        { 0x3d, 1, 0, 3, "INTERRUPT_PIN" },     // fBridge=??
     1375        { 0x3e, 1, 0, 1, "MIN_GNT" },           // fWritable = !?
     1376        { 0x3e, 1, 1, 2, "BRIDGE_CONTROL" },    // fWritable = !? cb=!?
     1377        { 0x3f, 1, 1, 3, "MAX_LAT" },           // fWritable = !? fBridge=!?
     1378    };
     1379
     1380    uint8_t const fBridge = fIsBridge ? 2 : 1;
     1381    uint8_t *pbDstConfig = &pDev->config[0];
     1382    for (uint32_t i = 0; i < RT_ELEMENTS(s_aFields); i++)
     1383        if (s_aFields[i].fBridge & fBridge)
     1384        {
     1385            uint8_t const   off = s_aFields[i].off;
     1386            uint8_t const   cb  = s_aFields[i].cb;
     1387            uint32_t        u32Src;
     1388            uint32_t        u32Dst;
     1389            switch (cb)
     1390            {
     1391                case 1:
     1392                    u32Src = pbSrcConfig[off];
     1393                    u32Dst = pbDstConfig[off];
     1394                    break;
     1395                case 2:
     1396                    u32Src = *(uint16_t const *)&pbSrcConfig[off];
     1397                    u32Dst = *(uint16_t const *)&pbDstConfig[off];
     1398                    break;
     1399                case 4:
     1400                    u32Src = *(uint32_t const *)&pbSrcConfig[off];
     1401                    u32Dst = *(uint32_t const *)&pbDstConfig[off];
     1402                    break;
     1403                default:
     1404                    AssertFailed();
     1405                    continue;
     1406            }
     1407
     1408            if (u32Src != u32Dst)
     1409            {
     1410                if (!s_aFields[i].fWritable)
     1411                    LogRel(("PCI: %8s/%u: %2u-bit field %s: %x -> %x - !READ ONLY!\n",
     1412                            pDev->name, pDev->pDevIns->iInstance, cb*8, s_aFields[i].pszName, u32Dst, u32Src));
     1413                else
     1414                    LogRel(("PCI: %8s/%u: %2u-bit field %s: %x -> %x\n",
     1415                            pDev->name, pDev->pDevIns->iInstance, cb*8, s_aFields[i].pszName, u32Dst, u32Src));
     1416                pDev->Int.s.pfnConfigWrite(pDev, off, u32Src, cb);
     1417            }
     1418        }
     1419}
     1420
     1421
    13111422/**
    13121423 * Loads a saved PCI device state.
     
    13191430static DECLCALLBACK(int) pciLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version)
    13201431{
    1321     PPCIGLOBALS  pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
    1322     PPCIBUS      pBus  = &pThis->PciBus;
     1432    PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
     1433    PPCIBUS     pBus  = &pThis->PciBus;
    13231434    uint32_t    u32;
    13241435    uint32_t    i;
     
    14321543
    14331544        /* commit the loaded device config. */
    1434         memcpy(pDev->config, DevTmp.config, sizeof(pDev->config));
     1545        pciR3CommonRestoreConfig(pDev, &DevTmp.config[0], false ); /** @todo fix bridge fun! */
    14351546
    14361547        pDev->Int.s.uIrqPinState = DevTmp.Int.s.uIrqPinState;
     
    19002011    }
    19012012
    1902     rc = PDMDevHlpSSMRegister(pDevIns, "pci", iInstance, VBOX_PCI_SAVED_STATE_VERSION, sizeof(*pBus),
    1903                               NULL, pciSaveExec, NULL, NULL, pciLoadExec, NULL);
     2013    rc = SSMR3RegisterDevice(PDMDevHlpGetVM(pDevIns), pDevIns, "pci", iInstance, VBOX_PCI_SAVED_STATE_VERSION, sizeof(*pBus) + 16*128, "pgm",
     2014                             NULL, pciSaveExec, NULL, NULL, pciLoadExec, NULL);
    19042015    if (RT_FAILURE(rc))
    19052016        return rc;
     
    21092220    int         rc;
    21102221
     2222/** @todo r=bird: this is a copy of pciLoadExec. combine the two!  */
     2223
    21112224    /*
    21122225     * Check the version.
     
    21792292
    21802293        /* commit the loaded device config. */
    2181         memcpy(pDev->config, DevTmp.config, sizeof(pDev->config));
     2294        pciR3CommonRestoreConfig(pDev, &DevTmp.config[0], false ); /** @todo fix bridge fun! */
    21822295
    21832296        pDev->Int.s.uIrqPinState = DevTmp.Int.s.uIrqPinState;
     
    23652478     * to make changes easier.
    23662479     */
    2367     rc = PDMDevHlpSSMRegister(pDevIns, "pcibridge", iInstance, VBOX_PCI_SAVED_STATE_VERSION, sizeof(*pBus),
    2368                               NULL, pcibridgeSaveExec, NULL, NULL, pcibridgeLoadExec, NULL);
     2480    rc = SSMR3RegisterDevice(PDMDevHlpGetVM(pDevIns), pDevIns, "pcibridge", iInstance, VBOX_PCI_SAVED_STATE_VERSION, sizeof(*pBus) + 16*128, "pgm",
     2481                             NULL, pcibridgeSaveExec, NULL, NULL, pcibridgeLoadExec, NULL);
    23692482    if (RT_FAILURE(rc))
    23702483        return rc;
  • trunk/src/VBox/VMM/PDMDevHlp.cpp

    r20094 r20153  
    371371             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pszName, pszName, u32Instance, u32Version, cbGuess, pfnSavePrep, pfnSaveExec, pfnSaveDone, pfnLoadPrep, pfnLoadExec, pfnLoadDone));
    372372
    373     int rc = SSMR3RegisterDevice(pDevIns->Internal.s.pVMR3, pDevIns, pszName, u32Instance, u32Version, cbGuess,
     373    int rc = SSMR3RegisterDevice(pDevIns->Internal.s.pVMR3, pDevIns, pszName, u32Instance, u32Version, cbGuess, NULL,
    374374                                 pfnSavePrep, pfnSaveExec, pfnSaveDone,
    375375                                 pfnLoadPrep, pfnLoadExec, pfnLoadDone);
  • trunk/src/VBox/VMM/SSM.cpp

    r20114 r20153  
    4545 * There are plans to extend SSM to make it easier to be both backwards and
    4646 * (somewhat) forwards compatible.  One of the new features will be being able
    47  * to classify units and data items as unimportant, one example where this would
    48  * be nice can be seen in with the SSM data unit.  Another potentail feature is
    49  * naming data items, perhaps by extending the SSMR3PutStruct API.
     47 * to classify units and data items as unimportant.  Another potentail feature
     48 * is naming data items, perhaps by extending the SSMR3PutStruct API.
    5049 *
    5150 */
     
    297296static DECLCALLBACK(int)    ssmR3SelfSaveExec(PVM pVM, PSSMHANDLE pSSM);
    298297static DECLCALLBACK(int)    ssmR3SelfLoadExec(PVM pVM, PSSMHANDLE pSSM, uint32_t u32Version);
    299 static int                  ssmR3Register(PVM pVM, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess, PSSMUNIT *ppUnit);
     298static int                  ssmR3Register(PVM pVM, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess, const char *pszBefore, PSSMUNIT *ppUnit);
    300299static int                  ssmR3CalcChecksum(RTFILE File, uint64_t cbFile, uint32_t *pu32CRC);
    301300static void                 ssmR3Progress(PSSMHANDLE pSSM, uint64_t cbAdvance);
     
    399398 * @param   u32Version      The data unit version.
    400399 * @param   cbGuess         The guessed data unit size.
     400 * @param   pszBefore       Name of data unit to be placed in front of.
     401 *                          Optional.
    401402 * @param   ppUnit          Where to store the insterted unit node.
    402403 *                          Caller must fill in the missing details.
    403404 */
    404 static int ssmR3Register(PVM pVM, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess, PSSMUNIT *ppUnit)
    405 {
     405static int ssmR3Register(PVM pVM, const char *pszName, uint32_t u32Instance,
     406                         uint32_t u32Version, size_t cbGuess, const char *pszBefore, PSSMUNIT *ppUnit)
     407{
     408    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
     409    AssertReturn(*pszName, VERR_INVALID_PARAMETER);
     410    AssertReturn(!pszBefore || *pszBefore, VERR_INVALID_PARAMETER);
     411
    406412    /*
    407413     * Lazy init.
     
    416422     * Walk to the end of the list checking for duplicates as we go.
    417423     */
    418     size_t      cchName = strlen(pszName);
    419     PSSMUNIT    pUnitPrev = NULL;
    420     PSSMUNIT    pUnit = pVM->ssm.s.pHead;
     424    size_t      cchBefore       = pszBefore ? strlen(pszBefore) : 0;
     425    PSSMUNIT    pUnitBeforePrev = NULL;
     426    PSSMUNIT    pUnitBefore     = NULL;
     427    size_t      cchName         = strlen(pszName);
     428    PSSMUNIT    pUnitPrev       = NULL;
     429    PSSMUNIT    pUnit           = pVM->ssm.s.pHead;
    421430    while (pUnit)
    422431    {
     
    428437            return VERR_SSM_UNIT_EXISTS;
    429438        }
     439        if (    pUnit->cchName == cchBefore
     440            &&  !pUnitBefore
     441            &&  !memcmp(pUnit->szName, pszBefore, cchBefore))
     442        {
     443            pUnitBeforePrev = pUnitPrev;
     444            pUnitBefore     = pUnit;
     445        }
     446
    430447        /* next */
    431448        pUnitPrev = pUnit;
     
    443460     * Fill in (some) data. (Stuff is zero'ed.)
    444461     */
    445     pUnit->u32Version = u32Version;
    446     pUnit->u32Instance = u32Instance;
    447     pUnit->cbGuess = cbGuess;
    448     pUnit->cchName = cchName;
     462    pUnit->u32Version   = u32Version;
     463    pUnit->u32Instance  = u32Instance;
     464    pUnit->cbGuess      = cbGuess;
     465    pUnit->cchName      = cchName;
    449466    memcpy(pUnit->szName, pszName, cchName);
    450467
     
    452469     * Insert
    453470     */
    454     if (pUnitPrev)
     471    if (pUnitBefore)
     472    {
     473        pUnit->pNext = pUnitBefore;
     474        if (pUnitBeforePrev)
     475            pUnitBeforePrev->pNext = pUnit;
     476        else
     477            pVM->ssm.s.pHead       = pUnit;
     478    }
     479    else if (pUnitPrev)
    455480        pUnitPrev->pNext = pUnit;
    456481    else
     
    475500 * @param   cbGuess         The approximate amount of data in the unit.
    476501 *                          Only for progress indicators.
     502 * @param   pszBefore       Name of data unit which we should be put in front
     503 *                          of. Optional (NULL).
    477504 * @param   pfnSavePrep     Prepare save callback, optional.
    478505 * @param   pfnSaveExec     Execute save callback, optional.
     
    482509 * @param   pfnLoadDone     Done load callback, optional.
    483510 */
    484 VMMR3DECL(int) SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess,
     511VMMR3DECL(int) SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess, const char *pszBefore,
    485512    PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
    486513    PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)
    487514{
    488515    PSSMUNIT pUnit;
    489     int rc = ssmR3Register(pVM, pszName, u32Instance, u32Version, cbGuess, &pUnit);
     516    int rc = ssmR3Register(pVM, pszName, u32Instance, u32Version, cbGuess, pszBefore, &pUnit);
    490517    if (RT_SUCCESS(rc))
    491518    {
     
    528555{
    529556    PSSMUNIT pUnit;
    530     int rc = ssmR3Register(pVM, pszName, u32Instance, u32Version, cbGuess, &pUnit);
     557    int rc = ssmR3Register(pVM, pszName, u32Instance, u32Version, cbGuess, NULL, &pUnit);
    531558    if (RT_SUCCESS(rc))
    532559    {
     
    568595{
    569596    PSSMUNIT pUnit;
    570     int rc = ssmR3Register(pVM, pszName, u32Instance, u32Version, cbGuess, &pUnit);
     597    int rc = ssmR3Register(pVM, pszName, u32Instance, u32Version, cbGuess, NULL, &pUnit);
    571598    if (RT_SUCCESS(rc))
    572599    {
     
    608635{
    609636    PSSMUNIT pUnit;
    610     int rc = ssmR3Register(pVM, pszName, u32Instance, u32Version, cbGuess, &pUnit);
     637    int rc = ssmR3Register(pVM, pszName, u32Instance, u32Version, cbGuess, NULL, &pUnit);
    611638    if (RT_SUCCESS(rc))
    612639    {
  • trunk/src/VBox/VMM/testcase/tstSSM.cpp

    r18456 r20153  
    651651     * Register a few callbacks.
    652652     */
    653     rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.1 (all types)", 1, 0, 256,
     653    rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.1 (all types)", 1, 0, 256, NULL,
    654654        NULL, Item01Save, NULL,
    655655        NULL, Item01Load, NULL);
     
    660660    }
    661661
    662     rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.2 (rand mem)", 2, 0, _1M * 8,
     662    rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.2 (rand mem)", 2, 0, _1M * 8, NULL,
    663663        NULL, Item02Save, NULL,
    664664        NULL, Item02Load, NULL);
     
    669669    }
    670670
    671     rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.3 (big mem)", 0, 123, 512*_1M,
     671    rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.3 (big mem)", 0, 123, 512*_1M, NULL,
    672672        NULL, Item03Save, NULL,
    673673        NULL, Item03Load, NULL);
     
    678678    }
    679679
    680     rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.4 (big zero mem)", 0, 42, 512*_1M,
     680    rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.4 (big zero mem)", 0, 42, 512*_1M, NULL,
    681681        NULL, Item04Save, NULL,
    682682        NULL, Item04Load, NULL);
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