VirtualBox

Changeset 20153 in vbox for trunk/src/VBox/Devices/Bus


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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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;
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