VirtualBox

Changeset 65283 in vbox


Ignore:
Timestamp:
Jan 13, 2017 2:25:05 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
112848
Message:

DevPciIch9.cpp (and minor other corresponding adaptions): eliminate config space access overoptimization. For devices which have non-trivial config space callbacks (e.g. passthrough) it is vital that the accesses don't just go to the config space array used by the base PCI device emulation (which in this case serves as a approximate cache, so that we can do certain config space accesses even in R0/GC). Addressed all todos related to devpciR3CommonRestoreConfig. Fix PCI topology setup, in particular the subordinate bus, otherwise there is trouble with passthrough. In the same place enable IO/MEM/BM for all bridges, again avoiding trouble with the passthrough case. Use the same values as Linux for the bridge base/limit registers when no transaction should be going through. Fixed devpciR3UpdateMappings to deal with 64-bit BARs better, especially when the guest OS is probing them without disabling the corresponding transactions. Finally many function, register name and bit mask naming cleanups, avoiding legacy or confusing ones.

Location:
trunk/src/VBox/Devices/Bus
Files:
3 edited

Legend:

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

    r65101 r65283  
    10371037
    10381038        /* commit the loaded device config. */
    1039         devpciR3CommonRestoreConfig(pDev, &DevTmp.abConfig[0], false ); /** @todo fix bridge fun! */
     1039        devpciR3CommonRestoreConfig(pDev, &DevTmp.abConfig[0]);
    10401040
    10411041        pDev->Int.s.uIrqPinState = DevTmp.Int.s.uIrqPinState;
  • trunk/src/VBox/Devices/Bus/DevPciIch9.cpp

    r65101 r65283  
    99 *          For the time being the DevPciMerge1.cpp.h file will remain separate,
    1010 *          due to 5.1.  We can merge it into this one later in the dev cycle.
     11 *
     12 *          DO NOT use the PDMPciDev* or PCIDev* family of functions in this
     13 *          file except in the two callbacks for config space access (and the
     14 *          functions which are used exclusively by that code) and the two
     15 *          device constructors when setting up the config space for the
     16 *          bridges.  Everything else need extremely careful review.  Using
     17 *          them elsewhere (especially in the init code) causes weird failures
     18 *          with PCI passthrough, as it would only update the array of
     19 *          (emulated) config space, but not talk to the actual device (needs
     20 *          invoking the respective callback).
    1121 */
    1222
    1323/*
    14  * Copyright (C) 2010-2016 Oracle Corporation
     24 * Copyright (C) 2010-2017 Oracle Corporation
    1525 *
    1626 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    229239        if (pPciRoot->PciBus.cBridges)
    230240        {
    231 #ifdef IN_RING3 /** @todo do lookup in R0/RC too! */
     241#ifdef IN_RING3 /** @todo do lookup in R0/RC too! r=klaus don't think that it can work, since the config space access callback only works in R3 */
    232242            PPDMPCIDEV pBridgeDevice = ich9pciFindBridge(&pPciRoot->PciBus, pAddr->iBus);
    233243            if (pBridgeDevice)
     
    342352        if (pPciRoot->PciBus.cBridges)
    343353        {
    344 #ifdef IN_RING3 /** @todo do lookup in R0/RC too! */
     354#ifdef IN_RING3 /** @todo do lookup in R0/RC too! r=klaus don't think that it can work, since the config space access callback only works in R3 */
    345355            PPDMPCIDEV pBridgeDevice = ich9pciFindBridge(&pPciRoot->PciBus, pPciAddr->iBus);
    346356            if (pBridgeDevice)
     
    544554    }
    545555
    546     PDEVPCIBUS     pBus      =     &pPciRoot->PciBus;
    547     const bool  fIsAcpiDevice = PCIDevGetDeviceId(pPciDev) == 0x7113;
     556    PDEVPCIBUS pBus = &pPciRoot->PciBus;
     557    /* safe, only needs to go to the config space array */
     558    const bool fIsAcpiDevice = PDMPciDevGetDeviceId(pPciDev) == 0x7113;
    548559
    549560    LogFlowFunc(("PCI Dev %p : IRQ\n", pPciDev));
     
    562573             * PCI device configuration space).
    563574             */
    564             ich9pciApicSetIrq(pBus, uDevFn, pPciDev, -1, iLevel, uTagSrc, PCIDevGetInterruptLine(pPciDev));
     575            /* safe, only needs to go to the config space array */
     576            ich9pciApicSetIrq(pBus, uDevFn, pPciDev, -1, iLevel, uTagSrc, PDMPciDevGetInterruptLine(pPciDev));
    565577        else
    566578            ich9pciApicSetIrq(pBus, uDevFn, pPciDev, iIrq, iLevel, uTagSrc, -1);
     
    699711        AssertMsg(pBridge && pciDevIsPci2PciBridge(pBridge),
    700712                  ("Device is not a PCI bridge but on the list of PCI bridges\n"));
     713        /* safe, only needs to go to the config space array */
    701714        uint32_t uSecondary   = PDMPciDevGetByte(pBridge, VBOX_PCI_SECONDARY_BUS);
     715        /* safe, only needs to go to the config space array */
    702716        uint32_t uSubordinate = PDMPciDevGetByte(pBridge, VBOX_PCI_SUBORDINATE_BUS);
    703717        Log3(("ich9pciFindBridge on bus %p, bridge %d: %d in %d..%d\n", pBus, iBridge, uBus, uSecondary, uSubordinate));
     
    715729}
    716730
    717 static uint8_t ich9pciGetByte(PPDMPCIDEV pPciDev, int32_t iRegister)
     731DECLINLINE(uint8_t) ich9pciGetByte(PPDMPCIDEV pPciDev, int32_t iRegister)
    718732{
    719733    return (uint8_t)ich9pciGetCfg(pPciDev, iRegister, 1);
    720734}
    721735
    722 static uint16_t ich9pciGetWord(PPDMPCIDEV pPciDev, int32_t iRegister)
     736DECLINLINE(uint16_t) ich9pciGetWord(PPDMPCIDEV pPciDev, int32_t iRegister)
    723737{
    724738    return (uint16_t)ich9pciGetCfg(pPciDev, iRegister, 2);
    725739}
    726740
    727 static uint32_t ich9pciGetDWord(PPDMPCIDEV pPciDev, int32_t iRegister)
     741DECLINLINE(uint32_t) ich9pciGetDWord(PPDMPCIDEV pPciDev, int32_t iRegister)
    728742{
    729743    return (uint32_t)ich9pciGetCfg(pPciDev, iRegister, 4);
     
    734748    return iRegion == VBOX_PCI_ROM_SLOT
    735749         ?  VBOX_PCI_ROM_ADDRESS : (VBOX_PCI_BASE_ADDRESS_0 + iRegion * 4);
     750}
     751
     752static void ich9pciSetCfg(PPDMPCIDEV pPciDev, int32_t iRegister, uint32_t u32, int cb)
     753{
     754    pPciDev->Int.s.pfnConfigWrite(pPciDev->Int.s.CTX_SUFF(pDevIns), pPciDev, iRegister, u32, cb);
     755}
     756
     757DECLINLINE(void) ich9pciSetByte(PPDMPCIDEV pPciDev, int32_t iRegister, uint8_t u8)
     758{
     759    ich9pciSetCfg(pPciDev, iRegister, u8, 1);
     760}
     761
     762DECLINLINE(void) ich9pciSetWord(PPDMPCIDEV pPciDev, int32_t iRegister, uint16_t u16)
     763{
     764    ich9pciSetCfg(pPciDev, iRegister, u16, 2);
     765}
     766
     767DECLINLINE(void) ich9pciSetDWord(PPDMPCIDEV pPciDev, int32_t iRegister, uint32_t u32)
     768{
     769    ich9pciSetCfg(pPciDev, iRegister, u32, 4);
    736770}
    737771
     
    816850    AssertCompile(PCI_ADDRESS_SPACE_MEM_PREFETCH == RT_BIT_32(3));
    817851    uint32_t u32Value   = (uint32_t)enmType & (PCI_ADDRESS_SPACE_IO | PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_MEM_PREFETCH);
    818     PCIDevSetDWord(pPciDev, ich9pciGetRegionReg(iRegion), u32Value);
     852    /* safe, only needs to go to the config space array */
     853    PDMPciDevSetDWord(pPciDev, ich9pciGetRegionReg(iRegion), u32Value);
    819854
    820855    return VINF_SUCCESS;
     
    929964
    930965    /* If the current bus is not the target bus search for the bus which contains the device. */
     966    /* safe, only needs to go to the config space array */
    931967    if (uBus != PDMPciDevGetByte(&pBus->PciDev, VBOX_PCI_SECONDARY_BUS))
    932968    {
     
    959995
    960996    /* If the current bus is not the target bus search for the bus which contains the device. */
     997    /* safe, only needs to go to the config space array */
    961998    if (uBus != PDMPciDevGetByte(&pBus->PciDev, VBOX_PCI_SECONDARY_BUS))
    962999    {
     
    9971034 * @param   pDev                The PCI device.
    9981035 * @param   pbSrcConfig         The configuration register values to be loaded.
    999  * @param   fIsBridge           Whether this is a bridge device or not.
    1000  */
    1001 void devpciR3CommonRestoreConfig(PPDMPCIDEV pDev, uint8_t const *pbSrcConfig, bool fIsBridge)
     1036 */
     1037void devpciR3CommonRestoreConfig(PPDMPCIDEV pDev, uint8_t const *pbSrcConfig)
    10021038{
    10031039    /*
     
    10291065        { 0x14, 4, 1, 3, "BASE_ADDRESS_1" },
    10301066        { 0x18, 4, 1, 1, "BASE_ADDRESS_2" },
    1031         { 0x18, 1, 1, 2, "PRIMARY_BUS" },       // fWritable = ??
    1032         { 0x19, 1, 1, 2, "SECONDARY_BUS" },     // fWritable = ??
    1033         { 0x1a, 1, 1, 2, "SUBORDINATE_BUS" },   // fWritable = ??
    1034         { 0x1b, 1, 1, 2, "SEC_LATENCY_TIMER" }, // fWritable = ??
     1067        { 0x18, 1, 1, 2, "PRIMARY_BUS" },
     1068        { 0x19, 1, 1, 2, "SECONDARY_BUS" },
     1069        { 0x1a, 1, 1, 2, "SUBORDINATE_BUS" },
     1070        { 0x1b, 1, 1, 2, "SEC_LATENCY_TIMER" },
    10351071        { 0x1c, 4, 1, 1, "BASE_ADDRESS_3" },
    1036         { 0x1c, 1, 1, 2, "IO_BASE" },           // fWritable = ??
    1037         { 0x1d, 1, 1, 2, "IO_LIMIT" },          // fWritable = ??
    1038         { 0x1e, 2, 1, 2, "SEC_STATUS" },        // fWritable = ??
     1072        { 0x1c, 1, 1, 2, "IO_BASE" },
     1073        { 0x1d, 1, 1, 2, "IO_LIMIT" },
     1074        { 0x1e, 2, 1, 2, "SEC_STATUS" },
    10391075        { 0x20, 4, 1, 1, "BASE_ADDRESS_4" },
    1040         { 0x20, 2, 1, 2, "MEMORY_BASE" },       // fWritable = ??
    1041         { 0x22, 2, 1, 2, "MEMORY_LIMIT" },      // fWritable = ??
     1076        { 0x20, 2, 1, 2, "MEMORY_BASE" },
     1077        { 0x22, 2, 1, 2, "MEMORY_LIMIT" },
    10421078        { 0x24, 4, 1, 1, "BASE_ADDRESS_5" },
    1043         { 0x24, 2, 1, 2, "PREF_MEMORY_BASE" },  // fWritable = ??
    1044         { 0x26, 2, 1, 2, "PREF_MEMORY_LIMIT" }, // fWritable = ??
    1045         { 0x28, 4, 1, 1, "CARDBUS_CIS" },       // fWritable = ??
    1046         { 0x28, 4, 1, 2, "PREF_BASE_UPPER32" }, // fWritable = ??
    1047         { 0x2c, 2, 0, 1, "SUBSYSTEM_VENDOR_ID" },// fWritable = !?
    1048         { 0x2c, 4, 1, 2, "PREF_LIMIT_UPPER32" },// fWritable = ??
    1049         { 0x2e, 2, 0, 1, "SUBSYSTEM_ID" },      // fWritable = !?
    1050         { 0x30, 4, 1, 1, "ROM_ADDRESS" },       // fWritable = ?!
    1051         { 0x30, 2, 1, 2, "IO_BASE_UPPER16" },   // fWritable = ?!
    1052         { 0x32, 2, 1, 2, "IO_LIMIT_UPPER16" },  // fWritable = ?!
    1053         { 0x34, 4, 0, 3, "CAPABILITY_LIST" },   // fWritable = !? cb=!?
    1054         { 0x38, 4, 1, 1, "RESERVED_38" },       // ???
    1055         { 0x38, 4, 1, 2, "ROM_ADDRESS_BR" },    // fWritable = !? cb=!? fBridge=!?
    1056         { 0x3c, 1, 1, 3, "INTERRUPT_LINE" },    // fBridge=??
    1057         { 0x3d, 1, 0, 3, "INTERRUPT_PIN" },     // fBridge=??
     1079        { 0x24, 2, 1, 2, "PREF_MEMORY_BASE" },
     1080        { 0x26, 2, 1, 2, "PREF_MEMORY_LIMIT" },
     1081        { 0x28, 4, 0, 1, "CARDBUS_CIS" },
     1082        { 0x28, 4, 1, 2, "PREF_BASE_UPPER32" },
     1083        { 0x2c, 2, 0, 1, "SUBSYSTEM_VENDOR_ID" },
     1084        { 0x2c, 4, 1, 2, "PREF_LIMIT_UPPER32" },
     1085        { 0x2e, 2, 0, 1, "SUBSYSTEM_ID" },
     1086        { 0x30, 4, 1, 1, "ROM_ADDRESS" },
     1087        { 0x30, 2, 1, 2, "IO_BASE_UPPER16" },
     1088        { 0x32, 2, 1, 2, "IO_LIMIT_UPPER16" },
     1089        { 0x34, 4, 0, 3, "CAPABILITY_LIST" },
     1090        { 0x38, 4, 1, 1, "RESERVED_38" },
     1091        { 0x38, 4, 1, 2, "ROM_ADDRESS_BR" },
     1092        { 0x3c, 1, 1, 3, "INTERRUPT_LINE" },
     1093        { 0x3d, 1, 0, 3, "INTERRUPT_PIN" },
    10581094        { 0x3e, 1, 0, 1, "MIN_GNT" },
    1059         { 0x3e, 2, 1, 2, "BRIDGE_CONTROL" },    // fWritable = !?
     1095        { 0x3e, 2, 1, 2, "BRIDGE_CONTROL" },
    10601096        { 0x3f, 1, 0, 1, "MAX_LAT" },
    10611097        /* The COMMAND register must come last as it requires the *ADDRESS*
     
    10951131     * Loop thru the fields covering the 64 bytes of standard registers.
    10961132     */
    1097     uint8_t const fBridge = fIsBridge ? 2 : 1;
     1133    uint8_t const fBridge = pciDevIsPci2PciBridge(pDev) ? 2 : 1;
    10981134    Assert(!pciDevIsPassthrough(pDev));
    10991135    uint8_t *pbDstConfig = &pDev->abConfig[0];
     
    11381174                }
    11391175                if (off == VBOX_PCI_COMMAND)
    1140                     PCIDevSetCommand(pDev, 0); /* For remapping, see ich9pciR3CommonLoadExec. */
     1176                    /* safe, only needs to go to the config space array */
     1177                    PDMPciDevSetCommand(pDev, 0); /* For remapping, see ich9pciR3CommonLoadExec. */
    11411178                pDev->Int.s.pfnConfigWrite(pDev->Int.s.CTX_SUFF(pDevIns), pDev, off, u32Src, cb);
    11421179            }
     
    11911228        if (pDev)
    11921229        {
    1193             uint16_t u16 = PCIDevGetCommand(pDev);
     1230            /* safe, only needs to go to the config space array */
     1231            uint16_t u16 = PDMPciDevGetCommand(pDev);
    11941232            pDev->Int.s.pfnConfigWrite(pDev->Int.s.CTX_SUFF(pDevIns), pDev, VBOX_PCI_COMMAND, 0, 2);
    1195             PCIDevSetCommand(pDev, u16);
    1196             Assert(PCIDevGetCommand(pDev) == u16);
     1233            /* safe, only needs to go to the config space array */
     1234            PDMPciDevSetCommand(pDev, u16);
     1235            /* safe, only needs to go to the config space array */
     1236            Assert(PDMPciDevGetCommand(pDev) == u16);
    11971237        }
    11981238    }
     
    12231263            if (pDev)
    12241264            {
     1265                /* safe, only needs to go to the config space array */
    12251266                LogRel(("PCI: New device in slot %#x, %s (vendor=%#06x device=%#06x)\n", i, pDev->pszNameR3,
    1226                         PCIDevGetVendorId(pDev), PCIDevGetDeviceId(pDev)));
     1267                        PDMPciDevGetVendorId(pDev), PDMPciDevGetDeviceId(pDev)));
    12271268                if (SSMR3HandleGetAfter(pSSM) != SSMAFTER_DEBUG_IT)
    12281269                {
     1270                    /* safe, only needs to go to the config space array */
    12291271                    rc = SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("New device in slot %#x, %s (vendor=%#06x device=%#06x)"),
    1230                                           i, pDev->pszNameR3, PCIDevGetVendorId(pDev), PCIDevGetDeviceId(pDev));
     1272                                          i, pDev->pszNameR3, PDMPciDevGetVendorId(pDev), PDMPciDevGetDeviceId(pDev));
    12311273                    break;
    12321274                }
     
    12671309        if (!pDev)
    12681310        {
     1311            /* safe, only needs to go to the config space array */
    12691312            LogRel(("PCI: Device in slot %#x has been removed! vendor=%#06x device=%#06x\n", i,
    1270                     PCIDevGetVendorId(&DevTmp), PCIDevGetDeviceId(&DevTmp)));
     1313                    PDMPciDevGetVendorId(&DevTmp), PDMPciDevGetDeviceId(&DevTmp)));
    12711314            if (SSMR3HandleGetAfter(pSSM) != SSMAFTER_DEBUG_IT)
    12721315            {
     1316                /* safe, only needs to go to the config space array */
    12731317                rc = SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Device in slot %#x has been removed! vendor=%#06x device=%#06x"),
    1274                                       i, PCIDevGetVendorId(&DevTmp), PCIDevGetDeviceId(&DevTmp));
     1318                                      i, PDMPciDevGetVendorId(&DevTmp), PDMPciDevGetDeviceId(&DevTmp));
    12751319                break;
    12761320            }
     
    12791323
    12801324        /* match the vendor id assuming that this will never be changed. */
    1281         if (PCIDevGetVendorId(&DevTmp) != PCIDevGetVendorId(pDev))
    1282         {
     1325        /* safe, only needs to go to the config space array */
     1326        if (PDMPciDevGetVendorId(&DevTmp) != PDMPciDevGetVendorId(pDev))
     1327        {
     1328            /* safe, only needs to go to the config space array */
    12831329            rc = SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Device in slot %#x (%s) vendor id mismatch! saved=%.4Rhxs current=%.4Rhxs"),
    1284                                   i, pDev->pszNameR3, PCIDevGetVendorId(&DevTmp), PCIDevGetVendorId(pDev));
     1330                                  i, pDev->pszNameR3, PDMPciDevGetVendorId(&DevTmp), PDMPciDevGetVendorId(pDev));
    12851331            break;
    12861332        }
     
    12881334        /* commit the loaded device config. */
    12891335        Assert(!pciDevIsPassthrough(pDev));
    1290         devpciR3CommonRestoreConfig(pDev, &DevTmp.abConfig[0], false ); /** @todo fix bridge fun! */
     1336        devpciR3CommonRestoreConfig(pDev, &DevTmp.abConfig[0]);
    12911337
    12921338        pDev->Int.s.uIrqPinState = DevTmp.Int.s.uIrqPinState;
     
    13551401
    13561402/*
    1357  * Perform imeediate read of configuration space register.
     1403 * Perform immediate read of configuration space register.
    13581404 * Cannot be rescheduled, as already in R3.
    13591405 */
     
    14411487
    14421488    /*
    1443      * Set I/O limit register. If there is no device with I/O space behind the bridge
    1444      * we set a lower value than in the base register.
    1445      * The result with a real bridge is that no I/O transactions are passed to the secondary
    1446      * interface. Again this doesn't really matter here but we want to be compliant to the spec.
     1489     * Set I/O limit register. If there is no device with I/O space behind the
     1490     * bridge we set a lower value than in the base register.
    14471491     */
    1448     if ((u32IoAddressBase != pPciRoot->uPciBiosIo) && ((pPciRoot->uPciBiosIo % 4096) != 0))
    1449     {
    1450         /* The upper boundary must be one byte less than a 4KB boundary. */
     1492    if (u32IoAddressBase != pPciRoot->uPciBiosIo)
     1493    {
     1494        /* Need again alignment to a 4KB boundary. */
    14511495        pPciRoot->uPciBiosIo = RT_ALIGN_32(pPciRoot->uPciBiosIo, 4*1024);
    1452     }
    1453 
    1454     ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_IO_LIMIT, ((pPciRoot->uPciBiosIo >> 8) & 0xf0) - 1, 1);
     1496        ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_IO_LIMIT, ((pPciRoot->uPciBiosIo >> 8) & 0xf0) - 1, 1);
     1497    }
     1498    else
     1499    {
     1500        ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_IO_BASE, 0xf0, 1);
     1501        ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_IO_LIMIT, 0x00, 1);
     1502    }
    14551503
    14561504    /* Same with the MMIO limit register but with 1MB boundary here. */
    1457     if ((u32MMIOAddressBase != pPciRoot->uPciBiosMmio) && ((pPciRoot->uPciBiosMmio % (1024 * 1024)) != 0))
    1458     {
    1459         /* The upper boundary must be one byte less than a 1MB boundary. */
     1505    if (u32MMIOAddressBase != pPciRoot->uPciBiosMmio)
     1506    {
    14601507        pPciRoot->uPciBiosMmio = RT_ALIGN_32(pPciRoot->uPciBiosMmio, 1024*1024);
    1461     }
    1462     ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_MEMORY_LIMIT, ((pPciRoot->uPciBiosMmio >> 16) & UINT32_C(0xfff0)) - 1, 2);
     1508        ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_MEMORY_LIMIT, ((pPciRoot->uPciBiosMmio >> 16) & UINT32_C(0xfff0)) - 1, 2);
     1509    }
     1510    else
     1511    {
     1512        ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_MEMORY_BASE, 0xfff0, 2);
     1513        ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_MEMORY_LIMIT, 0x0000, 2);
     1514    }
    14631515
    14641516    /*
     
    14961548        bool f64Bit =    (u8ResourceType & ((uint8_t)(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_IO)))
    14971549                      == PCI_ADDRESS_SPACE_BAR64;
    1498         bool fIsPio = ((u8ResourceType & PCI_COMMAND_IOACCESS) == PCI_COMMAND_IOACCESS);
     1550        bool fIsPio = ((u8ResourceType & PCI_ADDRESS_SPACE_IO) == PCI_ADDRESS_SPACE_IO);
    14991551        uint64_t cbRegSize64 = 0;
    15001552
     
    15101562            /* No 64-bit PIO regions possible. */
    15111563#ifndef DEBUG_bird /* EFI triggers this for DevAHCI. */
    1512             AssertMsg((u8ResourceType & PCI_COMMAND_IOACCESS) == 0, ("type=%#x rgn=%d\n", u8ResourceType, iRegion));
     1564            AssertMsg((u8ResourceType & PCI_ADDRESS_SPACE_IO) == 0, ("type=%#x rgn=%d\n", u8ResourceType, iRegion));
    15131565#endif
    15141566        }
     
    15951647    uint8_t uCmd = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, 2);
    15961648    if (fActiveMemRegion)
    1597         uCmd |= PCI_COMMAND_MEMACCESS; /* Enable MMIO access. */
     1649        uCmd |= VBOX_PCI_COMMAND_MEMORY; /* Enable MMIO access. */
    15981650    if (fActiveIORegion)
    1599         uCmd |= PCI_COMMAND_IOACCESS; /* Enable I/O space access. */
     1651        uCmd |= VBOX_PCI_COMMAND_IO; /* Enable I/O space access. */
    16001652    ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, uCmd, 2);
    16011653}
     
    16381690                uint8_t uCmd = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, 1);
    16391691                ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND,
    1640                                            uCmd | PCI_COMMAND_IOACCESS,
     1692                                           uCmd | VBOX_PCI_COMMAND_IO,
    16411693                                           1);
    16421694                break;
     
    16641716                        break;
    16651717                    }
     1718                    /* safe, only needs to go to the config space array */
    16661719                    if (uBus == PDMPciDevGetByte(pBridge, VBOX_PCI_SECONDARY_BUS))
    16671720                    {
     
    17351788    if (pBus->iBus != 0)
    17361789    {
    1737         PCIDevSetByte(pBridgeDev, VBOX_PCI_PRIMARY_BUS, uBusPrimary);
    1738         PCIDevSetByte(pBridgeDev, VBOX_PCI_SECONDARY_BUS, pBus->iBus);
     1790        ich9pciSetByte(pBridgeDev, VBOX_PCI_PRIMARY_BUS, uBusPrimary);
     1791        ich9pciSetByte(pBridgeDev, VBOX_PCI_SECONDARY_BUS, pBus->iBus);
     1792        /* Since the subordinate bus value can only be finalized once we
     1793         * finished recursing through everything behind the bridge, the only
     1794         * solution is temporarily configuring the subordinate to the maximum
     1795         * possible value. This makes sure that the config space accesses work
     1796         * (for our own sloppy emulation it apparently doesn't matter, but
     1797         * this is vital for real PCI bridges/devices in passthrough mode). */
     1798        ich9pciSetByte(pBridgeDev, VBOX_PCI_SUBORDINATE_BUS, 0xff);
    17391799    }
    17401800
     
    17501810    }
    17511811
    1752     PCIDevSetByte(pBridgeDev, VBOX_PCI_SUBORDINATE_BUS, uMaxSubNum);
     1812    if (pBus->iBus != 0)
     1813        ich9pciSetByte(pBridgeDev, VBOX_PCI_SUBORDINATE_BUS, uMaxSubNum);
    17531814    for (uint32_t i = pBus->iBus; i <= uMaxSubNum; i++)
    17541815        *pbmUsed |= RT_BIT_32(i);
    17551816
     1817    /* Make sure that transactions are able to get through the bridge. Not
     1818     * strictly speaking necessary this early (before any device is set up),
     1819     * but on the other hand it can't hurt either. */
     1820    if (pBus->iBus != 0)
     1821        ich9pciSetWord(pBridgeDev, VBOX_PCI_COMMAND,
     1822                         VBOX_PCI_COMMAND_IO
     1823                       | VBOX_PCI_COMMAND_MEMORY
     1824                       | VBOX_PCI_COMMAND_MASTER);
     1825
     1826    /* safe, only needs to go to the config space array */
    17561827    Log2(("ich9pciBiosInitBridgeTopology: for bus %p: primary=%d secondary=%d subordinate=%d\n",
    17571828          pBus,
     
    18251896        {
    18261897            case 1:
     1898                /* safe, only needs to go to the config space array */
    18271899                uValue = PDMPciDevGetByte(pPciDev,  uAddress);
    18281900                break;
    18291901            case 2:
     1902                /* safe, only needs to go to the config space array */
    18301903                uValue = PDMPciDevGetWord(pPciDev,  uAddress);
    18311904                break;
    18321905            case 4:
     1906                /* safe, only needs to go to the config space array */
    18331907                uValue = PDMPciDevGetDWord(pPciDev, uAddress);
    18341908                break;
     
    19342008            if (pRegion->type & PCI_ADDRESS_SPACE_IO)
    19352009            {
    1936                 if (u16Cmd & PCI_COMMAND_IOACCESS)
     2010                if (u16Cmd & VBOX_PCI_COMMAND_IO)
    19372011                {
    19382012                    uint32_t uIoBase = ich9pciGetDWord(pPciDev, offCfgReg);
     
    19512025             * Note! We exclude the I/O-APIC/HPET/ROM area at the end of the first 4GB to
    19522026             *       prevent the (fake) PCI BIOS and others from making a mess.  Pure paranoia.
     2027             *       Additionally addresses with the top 32 bits all set are excluded, to
     2028             *       catch silly OSes which probe 64-bit BARs without disabling the
     2029             *       corresponding transactions.
    19532030             */
    1954             else if (u16Cmd & PCI_COMMAND_MEMACCESS)
     2031            else if (u16Cmd & VBOX_PCI_COMMAND_MEMORY)
    19552032            {
    19562033                uint64_t uMemBase = ich9pciGetDWord(pPciDev, offCfgReg);
     
    19692046                        && uMemBase > 0
    19702047                        && !(   uMemBase <= UINT32_C(0xffffffff)
    1971                              && uLast    >= UINT32_C(0xfec00000)) )
     2048                             && uLast    >= UINT32_C(0xfec00000))
     2049                        && uMemBase <= UINT64_C(0xffffffff00000000) )
    19722050                        uNew = uMemBase;
    19732051                }
     
    20362114                     (1 << 4) - 1 /* 4 lowest bits for memory region, also ROM enable bit for ROM region */;
    20372115
     2116        /* safe, only needs to go to the config space array */
    20382117        uint8_t bOld = PDMPciDevGetByte(pPciDev, uAddr) & bMask;
    20392118        bVal = (bOld & bMask) | (bVal & ~bMask);
     
    20412120        Log3(("devpciR3WriteBarByte: %x changed to  %x\n", bOld, bVal));
    20422121
    2043         PCIDevSetByte(pPciDev, uAddr, bVal);
     2122        /* safe, only needs to go to the config space array */
     2123        PDMPciDevSetByte(pPciDev, uAddr, bVal);
    20442124    }
    20452125}
     
    21682248                        if (fWritable)
    21692249                        {
    2170                             PCIDevSetByte(pPciDev, uAddress, bVal);
     2250                            /* safe, only needs to go to the config space array */
     2251                            PDMPciDevSetByte(pPciDev, uAddress, bVal);
    21712252                            fUpdateMappings = true;
    21722253                        }
     
    21782259                            /* don't change reserved bits (11-15) */
    21792260                            bVal &= ~UINT8_C(0xf8);
    2180                             PCIDevSetByte(pPciDev, uAddress, bVal);
     2261                            /* safe, only needs to go to the config space array */
     2262                            PDMPciDevSetByte(pPciDev, uAddress, bVal);
    21812263                            fUpdateMappings = true;
    21822264                        }
     
    22242306                    default:
    22252307                        if (fWritable)
    2226                             PCIDevSetByte(pPciDev, uAddress, bVal);
     2308                            /* safe, only needs to go to the config space array */
     2309                            PDMPciDevSetByte(pPciDev, uAddress, bVal);
    22272310                        break;
    22282311                }
     
    22702353static void devpciR3InfoPciBus(PDEVPCIBUS pBus, PCDBGFINFOHLP pHlp, unsigned iIndentLvl, bool fRegisters)
    22712354{
    2272 /** @todo r=bird: Not sure if we should actually do PCI config space
    2273  *                callbacks from this code!! */
     2355    /* This has to use the callbacks for accuracy reasons. Otherwise it can get
     2356     * confusing in the passthrough case or when the callbacks for some device
     2357     * are doing something non-trivial (like implementing an indirect
     2358     * passthrough approach), because then the abConfig array is an imprecise
     2359     * cache needed for efficiency (so that certain reads can be done from
     2360     * R0/GC), but far from authoritative or what the guest would see. */
    22742361
    22752362    for (uint32_t iDev = 0; iDev < RT_ELEMENTS(pBus->apDevices); iDev++)
     
    23912478            devpciR3InfoIndent(pHlp, iIndentLvl);
    23922479            pHlp->pfnPrintf(pHlp, "bridge topology: primary=%d secondary=%d subordinate=%d\n",
    2393                             PDMPciDevGetByte(&pBusSub->PciDev, VBOX_PCI_PRIMARY_BUS),
    2394                             PDMPciDevGetByte(&pBusSub->PciDev, VBOX_PCI_SECONDARY_BUS),
    2395                             PDMPciDevGetByte(&pBusSub->PciDev, VBOX_PCI_SUBORDINATE_BUS));
     2480                            ich9pciGetByte(&pBusSub->PciDev, VBOX_PCI_PRIMARY_BUS),
     2481                            ich9pciGetByte(&pBusSub->PciDev, VBOX_PCI_SECONDARY_BUS),
     2482                            ich9pciGetByte(&pBusSub->PciDev, VBOX_PCI_SUBORDINATE_BUS));
    23962483            devpciR3InfoIndent(pHlp, iIndentLvl);
    23972484            pHlp->pfnPrintf(pHlp, "behind bridge: I/O %#06x..%#06x\n",
    2398                             (PDMPciDevGetByte(&pBusSub->PciDev, VBOX_PCI_IO_BASE) & 0xf0) << 8,
    2399                             (PDMPciDevGetByte(&pBusSub->PciDev, VBOX_PCI_IO_LIMIT) & 0xf0) << 8 | 0xfff);
     2485                            (ich9pciGetByte(&pBusSub->PciDev, VBOX_PCI_IO_BASE) & 0xf0) << 8,
     2486                            (ich9pciGetByte(&pBusSub->PciDev, VBOX_PCI_IO_LIMIT) & 0xf0) << 8 | 0xfff);
    24002487            devpciR3InfoIndent(pHlp, iIndentLvl);
    24012488            pHlp->pfnPrintf(pHlp, "behind bridge: memory %#010x..%#010x\n",
    2402                             PDMPciDevGetWord(&pBusSub->PciDev, VBOX_PCI_MEMORY_BASE) << 16,
    2403                             PDMPciDevGetWord(&pBusSub->PciDev, VBOX_PCI_MEMORY_LIMIT) << 16 | 0xffff);
     2489                            (ich9pciGetWord(&pBusSub->PciDev, VBOX_PCI_MEMORY_BASE) & 0xfff0) << 16,
     2490                            (ich9pciGetWord(&pBusSub->PciDev, VBOX_PCI_MEMORY_LIMIT) & 0xfff0) << 16 | 0xfffff);
     2491            devpciR3InfoIndent(pHlp, iIndentLvl);
     2492            pHlp->pfnPrintf(pHlp, "behind bridge: prefetch memory %#018x..%#018x\n",
     2493                            (  (uint64_t)ich9pciGetDWord(&pBusSub->PciDev, VBOX_PCI_PREF_BASE_UPPER32) << 32
     2494                             | ich9pciGetWord(&pBusSub->PciDev, VBOX_PCI_PREF_MEMORY_BASE) & 0xfff0) << 16,
     2495                            (  (uint64_t)ich9pciGetDWord(&pBusSub->PciDev, VBOX_PCI_PREF_LIMIT_UPPER32) << 32
     2496                             | ich9pciGetWord(&pBusSub->PciDev, VBOX_PCI_PREF_MEMORY_LIMIT) & 0xfff0) << 16
     2497                             | 0xfffff);
    24042498            devpciR3InfoPciBus(pBusSub, pHlp, iIndentLvl + 1, fRegisters);
    24052499        }
     
    25542648#if 0
    25552649    /* Host bridge device */
    2556     PCIDevSetVendorId(  &pBus->PciDev, 0x8086); /* Intel */
    2557     PCIDevSetDeviceId(  &pBus->PciDev, 0x29e0); /* Desktop */
    2558     PCIDevSetRevisionId(&pBus->PciDev,   0x01); /* rev. 01 */
    2559     PCIDevSetClassBase( &pBus->PciDev,   0x06); /* bridge */
    2560     PCIDevSetClassSub(  &pBus->PciDev,   0x00); /* Host/PCI bridge */
    2561     PCIDevSetClassProg( &pBus->PciDev,   0x00); /* Host/PCI bridge */
    2562     PCIDevSetHeaderType(&pBus->PciDev,   0x00); /* bridge */
    2563     PCIDevSetWord(&pBus->PciDev,  VBOX_PCI_SEC_STATUS, 0x0280);  /* secondary status */
     2650    PDMPciDevSetVendorId(  &pBus->PciDev, 0x8086); /* Intel */
     2651    PDMPciDevSetDeviceId(  &pBus->PciDev, 0x29e0); /* Desktop */
     2652    PDMPciDevSetRevisionId(&pBus->PciDev,   0x01); /* rev. 01 */
     2653    PDMPciDevSetClassBase( &pBus->PciDev,   0x06); /* bridge */
     2654    PDMPciDevSetClassSub(  &pBus->PciDev,   0x00); /* Host/PCI bridge */
     2655    PDMPciDevSetClassProg( &pBus->PciDev,   0x00); /* Host/PCI bridge */
     2656    PDMPciDevSetHeaderType(&pBus->PciDev,   0x00); /* bridge */
     2657    PDMPciDevSetWord(&pBus->PciDev,  VBOX_PCI_SEC_STATUS, 0x0280);  /* secondary status */
    25642658
    25652659    pBus->PciDev.pDevIns               = pDevIns;
     
    26572751    else
    26582752    {
    2659         PCIDevSetCommand(pDev,
    2660                          PCIDevGetCommand(pDev)
    2661                          &
    2662                          ~(VBOX_PCI_COMMAND_IO | VBOX_PCI_COMMAND_MEMORY |
     2753        ich9pciSetWord(pDev, VBOX_PCI_COMMAND,
     2754                         ich9pciGetWord(pDev, VBOX_PCI_COMMAND)
     2755                       & ~(VBOX_PCI_COMMAND_IO | VBOX_PCI_COMMAND_MEMORY |
    26632756                           VBOX_PCI_COMMAND_MASTER | VBOX_PCI_COMMAND_SPECIAL |
    26642757                           VBOX_PCI_COMMAND_PARITY | VBOX_PCI_COMMAND_SERR |
     
    26682761        if (!pciDevIsPci2PciBridge(pDev))
    26692762        {
    2670             PCIDevSetByte(pDev, VBOX_PCI_CACHE_LINE_SIZE, 0x0);
    2671             PCIDevSetInterruptLine(pDev, 0x0);
     2763            ich9pciSetByte(pDev, VBOX_PCI_CACHE_LINE_SIZE, 0x0);
     2764            ich9pciSetByte(pDev, VBOX_PCI_INTERRUPT_LINE, 0x0);
    26722765        }
    26732766
     
    28312924     * Fill in PCI configs and add them to the bus.
    28322925     */
    2833     PCIDevSetVendorId(  &pBus->PciDev, 0x8086); /* Intel */
    2834     PCIDevSetDeviceId(  &pBus->PciDev, 0x2448); /* 82801 Mobile PCI bridge. */
    2835     PCIDevSetRevisionId(&pBus->PciDev,   0xf2);
    2836     PCIDevSetClassSub(  &pBus->PciDev,   0x04); /* pci2pci */
    2837     PCIDevSetClassBase( &pBus->PciDev,   0x06); /* PCI_bridge */
    2838     PCIDevSetClassProg( &pBus->PciDev,   0x01); /* Supports subtractive decoding. */
    2839     PCIDevSetHeaderType(&pBus->PciDev,   0x01); /* Single function device which adheres to the PCI-to-PCI bridge spec. */
    2840     PCIDevSetCommand(   &pBus->PciDev,   0x00);
    2841     PCIDevSetStatus(    &pBus->PciDev,   0x20); /* 66MHz Capable. */
    2842     PCIDevSetInterruptLine(&pBus->PciDev, 0x00); /* This device does not assert interrupts. */
     2926    PDMPciDevSetVendorId(  &pBus->PciDev, 0x8086); /* Intel */
     2927    PDMPciDevSetDeviceId(  &pBus->PciDev, 0x2448); /* 82801 Mobile PCI bridge. */
     2928    PDMPciDevSetRevisionId(&pBus->PciDev,   0xf2);
     2929    PDMPciDevSetClassSub(  &pBus->PciDev,   0x04); /* pci2pci */
     2930    PDMPciDevSetClassBase( &pBus->PciDev,   0x06); /* PCI_bridge */
     2931    PDMPciDevSetClassProg( &pBus->PciDev,   0x01); /* Supports subtractive decoding. */
     2932    PDMPciDevSetHeaderType(&pBus->PciDev,   0x01); /* Single function device which adheres to the PCI-to-PCI bridge spec. */
     2933    PDMPciDevSetCommand(   &pBus->PciDev,   0x00);
     2934    PDMPciDevSetStatus(    &pBus->PciDev,   0x20); /* 66MHz Capable. */
     2935    PDMPciDevSetInterruptLine(&pBus->PciDev, 0x00); /* This device does not assert interrupts. */
    28432936
    28442937    /*
     
    28462939     * devices attached to the bus is unaffected.
    28472940     */
    2848     PCIDevSetInterruptPin (&pBus->PciDev, 0x00);
     2941    PDMPciDevSetInterruptPin (&pBus->PciDev, 0x00);
    28492942
    28502943    /*
     
    28832976
    28842977    /* Reset config space to default values. */
    2885     PCIDevSetByte(&pBus->PciDev, VBOX_PCI_PRIMARY_BUS, 0);
    2886     PCIDevSetByte(&pBus->PciDev, VBOX_PCI_SECONDARY_BUS, 0);
    2887     PCIDevSetByte(&pBus->PciDev, VBOX_PCI_SUBORDINATE_BUS, 0);
     2978    ich9pciSetByte(&pBus->PciDev, VBOX_PCI_PRIMARY_BUS, 0);
     2979    ich9pciSetByte(&pBus->PciDev, VBOX_PCI_SECONDARY_BUS, 0);
     2980    ich9pciSetByte(&pBus->PciDev, VBOX_PCI_SUBORDINATE_BUS, 0);
    28882981
    28892982    /* PCI-specific reset for each device. */
  • trunk/src/VBox/Devices/Bus/DevPciInternal.h

    r64697 r65283  
    193193DECLCALLBACK(void)     devpciR3CommonDefaultConfigWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
    194194                                                        uint32_t uAddress, uint32_t u32Value, unsigned cb);
    195 void devpciR3CommonRestoreConfig(PPDMPCIDEV pDev, uint8_t const *pbSrcConfig, bool fIsBridge);
     195void devpciR3CommonRestoreConfig(PPDMPCIDEV pDev, uint8_t const *pbSrcConfig);
    196196
    197197#endif
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