VirtualBox

Changeset 67562 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Jun 22, 2017 2:10:15 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
116314
Message:

DevPciIch9.cpp: improve reset handling to be less broken (making less assumptions about the config space cache being authoritative), and additionally actually recursively reset all devices/bridges connected to a bridge, making the topology updates only once the bridge doesn't need to work any more.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevPciIch9.cpp

    r65867 r67562  
    9696                                  int iIrq, int iLevel, uint32_t uTagSrc);
    9797#ifdef IN_RING3
    98 static void ich9pcibridgeReset(PPDMDEVINS pDevIns);
    9998DECLINLINE(PPDMPCIDEV) ich9pciFindBridge(PDEVPCIBUS pBus, uint8_t uBus);
    10099static void ich9pciBiosInitAllDevicesOnBus(PDEVPCIROOT pPciRoot, uint8_t uBus);
     
    135134     * of our parent passing the device which asserted the interrupt instead of the device of the bridge.
    136135     */
    137     PDEVPCIBUS    pBus          = PDMINS_2_DATA(pDevIns, PDEVPCIBUS);
     136    PDEVPCIBUS     pBus          = PDMINS_2_DATA(pDevIns, PDEVPCIBUS);
    138137    PPDMPCIDEV     pPciDevBus    = pPciDev;
    139138    int            iIrqPinBridge = iIrq;
     
    14621461{
    14631462    PDEVPCIROOT pThis = PDMINS_2_DATA(pDevIns, PDEVPCIROOT);
    1464     PDEVPCIBUS     pBus  = &pThis->PciBus;
    1465     uint32_t        u32;
    1466     int             rc;
     1463    PDEVPCIBUS  pBus  = &pThis->PciBus;
     1464    uint32_t    u32;
     1465    int         rc;
    14671466
    14681467    /* We ignore this version as there's no saved state with it anyway */
     
    30023001     */
    30033002    PDEVPCIROOT pPciRoot = PDMINS_2_DATA(pDevIns, PDEVPCIROOT);
    3004     PDEVPCIBUS     pBus     = &pPciRoot->PciBus;
     3003    PDEVPCIBUS  pBus     = &pPciRoot->PciBus;
    30053004    /* Zero out everything */
    30063005    memset(pPciRoot, 0, sizeof(*pPciRoot));
     
    31813180        if (pRegion->size == 0)
    31823181            continue;
     3182        bool const f64Bit =    (pRegion->type & ((uint8_t)(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_IO)))
     3183                            == PCI_ADDRESS_SPACE_BAR64;
    31833184
    31843185        ich9pciUnmapRegion(pDev, iRegion);
     3186
     3187        if (f64Bit)
     3188            iRegion++;
    31853189    }
    31863190
     
    32093213        if (pciDevIsMsiCapable(pDev))
    32103214        {
    3211             /* Extracted from MsiPciConfigWrite(). */
    3212             pDev->abConfig[pDev->Int.s.u8MsiCapOffset + VBOX_MSI_CAP_MESSAGE_CONTROL] &= 0x8e;
     3215            ich9pciSetWord(pDev, pDev->Int.s.u8MsiCapOffset + VBOX_MSI_CAP_MESSAGE_CONTROL,
     3216                           ich9pciGetWord(pDev, pDev->Int.s.u8MsiCapOffset + VBOX_MSI_CAP_MESSAGE_CONTROL) & 0xff8e);
    32133217        }
    32143218
     
    32163220        if (pciDevIsMsixCapable(pDev))
    32173221        {
    3218             /* Extracted from MsixPciConfigWrite(); no side effects. */
    3219             pDev->abConfig[pDev->Int.s.u8MsixCapOffset + VBOX_MSIX_CAP_MESSAGE_CONTROL + 1] &= 0x3f;
     3222            ich9pciSetWord(pDev, pDev->Int.s.u8MsixCapOffset + VBOX_MSIX_CAP_MESSAGE_CONTROL,
     3223                           ich9pciGetWord(pDev, pDev->Int.s.u8MsixCapOffset + VBOX_MSIX_CAP_MESSAGE_CONTROL) & 0x3fff);
    32203224        }
    32213225    }
     
    32243228
    32253229/**
    3226  * @copydoc FNPDMDEVRESET
    3227  */
    3228 static DECLCALLBACK(void) ich9pciReset(PPDMDEVINS pDevIns)
    3229 {
    3230     PDEVPCIROOT pPciRoot = PDMINS_2_DATA(pDevIns, PDEVPCIROOT);
    3231     PDEVPCIBUS     pBus     = &pPciRoot->PciBus;
     3230 * Recursive worker for ich9pciReset.
     3231 *
     3232 * @param   pDevIns     ICH9 bridge (root or PCI-to-PCI) instance.
     3233 */
     3234static void ich9pciResetBridge(PPDMDEVINS pDevIns)
     3235{
     3236    PDEVPCIBUS pBus = PDMINS_2_DATA(pDevIns, PDEVPCIBUS);
    32323237
    32333238    /* PCI-specific reset for each device. */
     
    32413246    {
    32423247        if (pBus->papBridgesR3[iBridge])
    3243             ich9pcibridgeReset(pBus->papBridgesR3[iBridge]->Int.s.CTX_SUFF(pDevIns));
    3244     }
    3245 
     3248            ich9pciResetBridge(pBus->papBridgesR3[iBridge]->Int.s.CTX_SUFF(pDevIns));
     3249    }
     3250
     3251    /* Reset topology config for non-root bridge. Last thing to do, otherwise
     3252     * the secondary and subordinate are instantly unreachable. */
     3253    if (pBus->iBus != 0)
     3254    {
     3255        ich9pciSetByte(&pBus->PciDev, VBOX_PCI_PRIMARY_BUS, 0);
     3256        ich9pciSetByte(&pBus->PciDev, VBOX_PCI_SECONDARY_BUS, 0);
     3257        ich9pciSetByte(&pBus->PciDev, VBOX_PCI_SUBORDINATE_BUS, 0);
     3258        /* Not resetting the address decoders of the bridge to 0, since the
     3259         * PCI-to-PCI Bridge spec says that there is no default value. */
     3260    }
     3261}
     3262
     3263
     3264/**
     3265 * @interface_method_impl{PDMDEVREG,pfnReset}
     3266 */
     3267static DECLCALLBACK(void) ich9pciReset(PPDMDEVINS pDevIns)
     3268{
     3269    /* Reset everything under the root bridge. */
     3270    ich9pciResetBridge(pDevIns);
     3271
     3272    /* Do a fresh Fake PCI BIOS setup. */
    32463273    ich9pciFakePCIBIOS(pDevIns);
    32473274}
     
    35123539    }
    35133540    return VINF_SUCCESS;
    3514 }
    3515 
    3516 /**
    3517  * @copydoc FNPDMDEVRESET
    3518  */
    3519 static void ich9pcibridgeReset(PPDMDEVINS pDevIns)
    3520 {
    3521     PDEVPCIBUS pBus = PDMINS_2_DATA(pDevIns, PDEVPCIBUS);
    3522 
    3523     /* Reset config space to default values. */
    3524     ich9pciSetByte(&pBus->PciDev, VBOX_PCI_PRIMARY_BUS, 0);
    3525     ich9pciSetByte(&pBus->PciDev, VBOX_PCI_SECONDARY_BUS, 0);
    3526     ich9pciSetByte(&pBus->PciDev, VBOX_PCI_SUBORDINATE_BUS, 0);
    3527 
    3528     /* PCI-specific reset for each device. */
    3529     for (uint32_t i = 0; i < RT_ELEMENTS(pBus->apDevices); i++)
    3530     {
    3531         if (pBus->apDevices[i])
    3532             ich9pciResetDevice(pBus->apDevices[i]);
    3533     }
    35343541}
    35353542
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette