VirtualBox

Changeset 20154 in vbox for trunk


Ignore:
Timestamp:
May 29, 2009 2:16:42 PM (16 years ago)
Author:
vboxsync
Message:

PCI: The risky half of the remapping fix. Fixes #1587 and #3903.

Location:
trunk
Files:
2 edited

Legend:

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

    r13189 r20154  
    280280
    281281/**
     282 * Gets the command config register.
     283 * @returns The command register value.
     284 * @param   pPciDev         The PCI device.
     285 */
     286DECLINLINE(uint16_t) PCIDevGetCommand(PPCIDEVICE pPciDev)
     287{
     288    return RT_LE2H_U16(RT_MAKE_U16(pPciDev->config[VBOX_PCI_COMMAND], pPciDev->config[VBOX_PCI_COMMAND + 1]));
     289}
     290
     291
     292/**
    282293 * Sets the status config register.
    283294 *
  • trunk/src/VBox/Devices/Bus/DevPCI.cpp

    r20153 r20154  
    12651265 * @param   pSSMHandle  The handle to save the state to.
    12661266 */
    1267 static DECLCALLBACK(int) pciSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
     1267static DECLCALLBACK(int) pciR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
    12681268{
    12691269    uint32_t    i;
     
    12911291
    12921292    /*
    1293      * Iterate all the devices.
     1293     * Iterate thru all the devices.
    12941294     */
    12951295    for (i = 0; i < RT_ELEMENTS(pBus->devices); i++)
     
    13121312
    13131313/**
     1314 * Disables all PCI devices prior to state loading.
     1315 *
     1316 * @returns VINF_SUCCESS.
     1317 * @param   pBus                The PCI bus instance.
     1318 */
     1319static int pciR3CommonLoadPrep(PPCIBUS pBus)
     1320{
     1321    /*
     1322     * Iterate thru all the devices and write 0 to the COMMAND register.
     1323     * The register value is restored afterwards so we can do proper
     1324     * LogRels in pciR3CommonRestoreConfig.
     1325     */
     1326    for (uint32_t i = 0; i < RT_ELEMENTS(pBus->devices); i++)
     1327    {
     1328        PPCIDEVICE pDev = pBus->devices[i];
     1329        if (pDev)
     1330        {
     1331            uint16_t u16 = PCIDevGetCommand(pDev);
     1332            pDev->Int.s.pfnConfigWrite(pDev, VBOX_PCI_COMMAND, 0, 2);
     1333            PCIDevSetCommand(pDev, u16);
     1334            Assert(PCIDevGetCommand(pDev) == u16);
     1335        }
     1336    }
     1337    return VINF_SUCCESS;
     1338}
     1339
     1340
     1341/**
     1342 * Prepares a state load.
     1343 *
     1344 * This will disable all the device so that the I/O regions gets unmapped.
     1345 *
     1346 * @returns VINF_SUCCESS
     1347 * @param   pDevIns             The device instance.
     1348 * @param   pSSMHandle          The saved state handle.
     1349 */
     1350static DECLCALLBACK(int) pciR3LoadPrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
     1351{
     1352    PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
     1353    return pciR3CommonLoadPrep(&pThis->PciBus);
     1354}
     1355
     1356
     1357/**
    13141358 * Common routine for restoring the config registers of a PCI device.
    13151359 *
     
    13211365{
    13221366    /* 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). */
     1367       the order in which they need to be restored. */
    13241368    static const struct PciField
    13251369    {
     
    13341378        { 0x00, 2, 0, 3, "VENDOR_ID" },
    13351379        { 0x02, 2, 0, 3, "DEVICE_ID" },
    1336         { 0x04, 2, 1, 3, "COMMAND" },
    13371380        { 0x06, 2, 1, 3, "STATUS" },
    13381381        { 0x08, 1, 0, 3, "REVISION_ID" },
     
    13761419        { 0x3e, 1, 1, 2, "BRIDGE_CONTROL" },    // fWritable = !? cb=!?
    13771420        { 0x3f, 1, 1, 3, "MAX_LAT" },           // fWritable = !? fBridge=!?
     1421        /* The COMMAND register must come last as it requires the *ADDRESS*
     1422           registers to be restored before we pretent to change it from 0 to
     1423           whatever value the guest assigned it. */
     1424        { 0x04, 2, 1, 3, "COMMAND" },
    13781425    };
    13791426
     
    14061453            }
    14071454
    1408             if (u32Src != u32Dst)
     1455            if (    u32Src != u32Dst
     1456                ||  off == VBOX_PCI_COMMAND)
    14091457            {
    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));
     1458                if (u32Src != u32Dst)
     1459                {
     1460                    if (!s_aFields[i].fWritable)
     1461                        LogRel(("PCI: %8s/%u: %2u-bit field %s: %x -> %x - !READ ONLY!\n",
     1462                                pDev->name, pDev->pDevIns->iInstance, cb*8, s_aFields[i].pszName, u32Dst, u32Src));
     1463                    else
     1464                        LogRel(("PCI: %8s/%u: %2u-bit field %s: %x -> %x\n",
     1465                                pDev->name, pDev->pDevIns->iInstance, cb*8, s_aFields[i].pszName, u32Dst, u32Src));
     1466                }
     1467                if (off == VBOX_PCI_COMMAND)
     1468                    PCIDevSetCommand(pDev, 0); /* For remapping, see pciR3CommonLoadPrep. */
    14161469                pDev->Int.s.pfnConfigWrite(pDev, off, u32Src, cb);
    14171470            }
     
    14281481 * @param   u32Version  The data unit version number.
    14291482 */
    1430 static DECLCALLBACK(int) pciLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version)
     1483static DECLCALLBACK(int) pciR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version)
    14311484{
    14321485    PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
     
    20122065
    20132066    rc = SSMR3RegisterDevice(PDMDevHlpGetVM(pDevIns), pDevIns, "pci", iInstance, VBOX_PCI_SAVED_STATE_VERSION, sizeof(*pBus) + 16*128, "pgm",
    2014                              NULL, pciSaveExec, NULL, NULL, pciLoadExec, NULL);
     2067                             NULL, pciR3SaveExec, NULL, pciR3LoadPrep, pciR3LoadExec, NULL);
    20152068    if (RT_FAILURE(rc))
    20162069        return rc;
     
    21802233 * @param   pSSMHandle  The handle to save the state to.
    21812234 */
    2182 static DECLCALLBACK(int) pcibridgeSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
    2183 {
     2235static DECLCALLBACK(int) pcibridgeR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
     2236{
     2237/** @todo make common with pciR3SaveExec! */
    21842238    uint32_t    i;
    21852239    PPCIBUS pThis = PDMINS_2_DATA(pDevIns, PPCIBUS);
     
    22042258    return SSMR3PutU32(pSSMHandle, ~0); /* terminator */
    22052259}
     2260
     2261
     2262/**
     2263 * Prepares a state load.
     2264 *
     2265 * This will disable all the device so that the I/O regions gets unmapped.
     2266 *
     2267 * @returns VINF_SUCCESS
     2268 * @param   pDevIns             The device instance.
     2269 * @param   pSSMHandle          The saved state handle.
     2270 */
     2271static DECLCALLBACK(int) pcibridgeR3LoadPrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
     2272{
     2273    PPCIBUS pThis = PDMINS_2_DATA(pDevIns, PPCIBUS);
     2274    return pciR3CommonLoadPrep(pThis);
     2275}
     2276
    22062277
    22072278/**
     
    22132284 * @param   u32Version  The data unit version number.
    22142285 */
    2215 static DECLCALLBACK(int) pcibridgeLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version)
     2286static DECLCALLBACK(int) pcibridgeR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version)
    22162287{
    22172288    PPCIBUS     pBus  = PDMINS_2_DATA(pDevIns, PPCIBUS);
     
    22202291    int         rc;
    22212292
    2222 /** @todo r=bird: this is a copy of pciLoadExec. combine the two!  */
     2293/** @todo r=bird: this is a copy of pciR3LoadExec. combine the two!  */
    22232294
    22242295    /*
     
    24792550     */
    24802551    rc = SSMR3RegisterDevice(PDMDevHlpGetVM(pDevIns), pDevIns, "pcibridge", iInstance, VBOX_PCI_SAVED_STATE_VERSION, sizeof(*pBus) + 16*128, "pgm",
    2481                              NULL, pcibridgeSaveExec, NULL, NULL, pcibridgeLoadExec, NULL);
     2552                             NULL, pcibridgeR3SaveExec, NULL, pcibridgeR3LoadPrep, pcibridgeR3LoadExec, NULL);
    24822553    if (RT_FAILURE(rc))
    24832554        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