VirtualBox

Changeset 65292 in vbox for trunk


Ignore:
Timestamp:
Jan 13, 2017 6:03:48 PM (8 years ago)
Author:
vboxsync
Message:

DevPciIch9.cpp: Since the code can't deal with prefetchable memory BARs if they're behind some bridge, make sure that such BARs aren't set up. The guest OS can hopefully fix this. Additionally fix BAR dumping of PCI devices (the command register doesn't make them invisible).

File:
1 edited

Legend:

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

    r65286 r65292  
    15381538        cRegions = 2;
    15391539
     1540    bool fSuppressMem = false;
    15401541    bool fActiveMemRegion = false;
    15411542    bool fActiveIORegion = false;
     
    15481549        uint8_t u8ResourceType = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address, 1);
    15491550
     1551        bool fPrefetch =    (u8ResourceType & ((uint8_t)(PCI_ADDRESS_SPACE_MEM_PREFETCH | PCI_ADDRESS_SPACE_IO)))
     1552                      == PCI_ADDRESS_SPACE_MEM_PREFETCH;
    15501553        bool f64Bit =    (u8ResourceType & ((uint8_t)(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_IO)))
    15511554                      == PCI_ADDRESS_SPACE_BAR64;
    15521555        bool fIsPio = ((u8ResourceType & PCI_ADDRESS_SPACE_IO) == PCI_ADDRESS_SPACE_IO);
    15531556        uint64_t cbRegSize64 = 0;
     1557
     1558        /* Hack: since this PCI init code cannot handle prefetchable BARs on
     1559         * anything besides the primary bus, it's for now the best solution
     1560         * to leave such BARs uninitialized and keep memory transactions
     1561         * disabled. The OS will hopefully be clever enough to fix this.
     1562         * Prefetchable BARs are the only ones which can be truly big (and
     1563         * are almost always 64-bit BARs). The non-prefetchable ones will not
     1564         * cause running out of space in the PCI memory hole. */
     1565        if (fPrefetch && uBus != 0)
     1566        {
     1567            fSuppressMem = true;
     1568            if (f64Bit)
     1569                iRegion++; /* skip next region */
     1570            continue;
     1571        }
    15541572
    15551573        if (f64Bit)
     
    16481666    /* Update the command word appropriately. */
    16491667    uint8_t uCmd = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, 2);
    1650     if (fActiveMemRegion)
     1668    if (fActiveMemRegion && !fSuppressMem)
    16511669        uCmd |= VBOX_PCI_COMMAND_MEMORY; /* Enable MMIO access. */
    16521670    if (fActiveIORegion)
     
    18561874    pPciRoot->uPciBiosMmio64 = cbAbove4GB + _4G;
    18571875
    1858     /* NB: Assume that if PCI controller MMIO range is enabled, it is at the bottom of the memory hole. */
     1876    /* NB: Assume that if PCI controller MMIO range is enabled, it is below the beginning of the memory hole. */
    18591877    if (pPciRoot->u64PciConfigMMioAddress)
    18601878    {
     
    24022420            }
    24032421
     2422            for (unsigned iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS; iRegion++)
     2423            {
     2424                PCIIORegion const *pRegion  = &pPciDev->Int.s.aIORegions[iRegion];
     2425                uint64_t const     cbRegion = pRegion->size;
     2426
     2427                if (cbRegion == 0)
     2428                    continue;
     2429
     2430                uint32_t uAddr = ich9pciGetDWord(pPciDev, ich9pciGetRegionReg(iRegion));
     2431                const char * pszDesc;
     2432                char szDescBuf[128];
     2433
     2434                bool f64Bit =    (pRegion->type & ((uint8_t)(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_IO)))
     2435                              == PCI_ADDRESS_SPACE_BAR64;
     2436                if (pRegion->type & PCI_ADDRESS_SPACE_IO)
     2437                {
     2438                    pszDesc = "IO";
     2439                    uAddr &= ~0x3;
     2440                }
     2441                else
     2442                {
     2443                    RTStrPrintf(szDescBuf, sizeof(szDescBuf), "MMIO%s%s",
     2444                                f64Bit ? "64" : "32",
     2445                                pRegion->type & PCI_ADDRESS_SPACE_MEM_PREFETCH ? " PREFETCH" : "");
     2446                    pszDesc = szDescBuf;
     2447                    uAddr &= ~0xf;
     2448                }
     2449
     2450                devpciR3InfoIndent(pHlp, iIndentLvl + 2);
     2451                pHlp->pfnPrintf(pHlp, "%s region #%u: ", pszDesc, iRegion);
     2452                if (f64Bit)
     2453                {
     2454                    uint32_t u32High = ich9pciGetDWord(pPciDev, ich9pciGetRegionReg(iRegion+1));
     2455                    uint64_t u64Addr = RT_MAKE_U64(uAddr, u32High);
     2456                    pHlp->pfnPrintf(pHlp, "%RX64..%RX64\n", u64Addr, u64Addr + cbRegion - 1);
     2457                    iRegion++;
     2458                }
     2459                else
     2460                    pHlp->pfnPrintf(pHlp, "%x..%x\n", uAddr, uAddr + (uint32_t)cbRegion - 1);
     2461            }
     2462
     2463            devpciR3InfoIndent(pHlp, iIndentLvl + 2);
    24042464            uint16_t iCmd = ich9pciGetWord(pPciDev, VBOX_PCI_COMMAND);
    2405             if ((iCmd & (VBOX_PCI_COMMAND_IO | VBOX_PCI_COMMAND_MEMORY)) != 0)
    2406             {
    2407                 for (unsigned iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS; iRegion++)
    2408                 {
    2409                     PCIIORegion const *pRegion  = &pPciDev->Int.s.aIORegions[iRegion];
    2410                     uint64_t const     cbRegion = pRegion->size;
    2411 
    2412                     if (cbRegion == 0)
    2413                         continue;
    2414 
    2415                     uint32_t uAddr = ich9pciGetDWord(pPciDev, ich9pciGetRegionReg(iRegion));
    2416                     const char * pszDesc;
    2417                     char szDescBuf[128];
    2418 
    2419                     bool f64Bit =    (pRegion->type & ((uint8_t)(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_IO)))
    2420                                   == PCI_ADDRESS_SPACE_BAR64;
    2421                     if (pRegion->type & PCI_ADDRESS_SPACE_IO)
    2422                     {
    2423                         pszDesc = "IO";
    2424                         uAddr &= ~0x3;
    2425                     }
    2426                     else
    2427                     {
    2428                         RTStrPrintf(szDescBuf, sizeof(szDescBuf), "MMIO%s%s",
    2429                                     f64Bit ? "64" : "32",
    2430                                     pRegion->type & PCI_ADDRESS_SPACE_MEM_PREFETCH ? " PREFETCH" : "");
    2431                         pszDesc = szDescBuf;
    2432                         uAddr &= ~0xf;
    2433                     }
    2434 
    2435                     devpciR3InfoIndent(pHlp, iIndentLvl + 2);
    2436                     pHlp->pfnPrintf(pHlp, "%s region #%u: ", pszDesc, iRegion);
    2437                     if (f64Bit)
    2438                     {
    2439                         uint32_t u32High = ich9pciGetDWord(pPciDev, ich9pciGetRegionReg(iRegion+1));
    2440                         uint64_t u64Addr = RT_MAKE_U64(uAddr, u32High);
    2441                         pHlp->pfnPrintf(pHlp, "%RX64..%RX64\n", u64Addr, u64Addr + cbRegion - 1);
    2442                         iRegion++;
    2443                     }
    2444                     else
    2445                         pHlp->pfnPrintf(pHlp, "%x..%x\n", uAddr, uAddr + (uint32_t)cbRegion - 1);
    2446                 }
    2447             }
    2448 
    2449             devpciR3InfoIndent(pHlp, iIndentLvl + 2);
    24502465            uint16_t iStatus = ich9pciGetWord(pPciDev, VBOX_PCI_STATUS);
    24512466            pHlp->pfnPrintf(pHlp, "Command: %04X, Status: %04x\n", iCmd, iStatus);
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