VirtualBox

Changeset 65845 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 22, 2017 8:42:48 PM (8 years ago)
Author:
vboxsync
Message:

DevPciIch9.cpp: optionally turn the PCI-to-PCI bridge into a PCIe one (mostly, no support for the config space beyond the first 256 bytes yet), closely resembling what a real PCIe bridge would report. Add lots of general todos to the entire file, as it has functionality gaps.

File:
1 edited

Legend:

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

    r65844 r65845  
    474474}
    475475
    476 /* irqs corresponding to PCI irqs A-D, must match pci_irq_list in rombios.c */
     476/* irqs corresponding to PCI irqs A-D, must match pci_irq_list in pcibios.inc */
     477/** @todo r=klaus inconsistent! ich9 doesn't implement PIRQ yet, so both needs to be addressed and tested thoroughly. */
    477478static const uint8_t aPciIrqs[4] = { 11, 10, 9, 5 };
    478479
     
    568569    {
    569570        pPciDev->Int.s.uIrqPinState = (iLevel & PDM_IRQ_LEVEL_HIGH);
     571
     572        /** @todo r=klaus: implement PIRQ handling (if APIC isn't active). Needed for legacy OSes which don't use the APIC stuff. */
    570573
    571574        /* Send interrupt to I/O APIC only now. */
     
    22042207    uint64_t const  cbAbove4GB = MMR3PhysGetRamSizeAbove4GB(pVM);
    22052208
     2209    /** @todo r=klaus this needs to do the same elcr magic as DevPCI.cpp, as the BIOS can't be trusted to do the right thing. Of course it's more difficult than with the old code, as there are bridges to be handled. The interrupt routing needs to be taken into account. Also I highly suspect that the chipset has 8 interrupt lines which we might be able to use for handling things on the root bus better (by treating them as devices on the mainboard). */
     2210
    22062211    /*
    22072212     * Set the start addresses.
     
    23392344
    23402345/**
    2341  * Worker for devpciR3IsConfigByteWritable that update BAR and ROM mappings.
     2346 * Worker for devpciR3CommonDefaultConfigWrite that updates BAR and ROM mappings.
    23422347 *
    23432348 * @param   pPciDev             The PCI device to update the mappings for.
     
    23462351static void devpciR3UpdateMappings(PPDMPCIDEV pPciDev, bool fP2PBridge)
    23472352{
     2353    /** @todo r=klaus analyze if it's safe to rely on cached config space data, as that's cheaper to read in the raw pci device and pass-through cases. */
    23482354    uint16_t const u16Cmd = ich9pciGetWord(pPciDev, VBOX_PCI_COMMAND);
    23492355    for (unsigned iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS; iRegion++)
     
    30593065    /** @todo Disabled for now because this causes error messages with Linux guests.
    30603066     *         The guest loads the x38_edac device which tries to map a memory region
    3061      *         using an address given at place 0x48 - 0x4f in the PCi config space.
     3067     *         using an address given at place 0x48 - 0x4f in the PCI config space.
    30623068     *         This fails. because we don't register such a region.
    30633069     */
     
    33023308     * Validate and read configuration.
    33033309     */
    3304     if (!CFGMR3AreValuesValid(pCfg, "GCEnabled\0" "R0Enabled\0"))
     3310    if (!CFGMR3AreValuesValid(pCfg, "GCEnabled\0" "R0Enabled\0" "ExpressEnabled\0"))
    33053311        return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
    33063312
     
    33193325                                N_("Configuration error: Failed to query boolean value \"R0Enabled\""));
    33203326    Log(("PCI: fGCEnabled=%RTbool fR0Enabled=%RTbool\n", fGCEnabled, fR0Enabled));
     3327
     3328    /* check if we're supposed to implement a PCIe bridge. */
     3329    bool fExpress;
     3330    rc = CFGMR3QueryBoolDef(pCfg, "ExpressEnabled", &fExpress, false);
     3331    if (RT_FAILURE(rc))
     3332        return PDMDEV_SET_ERROR(pDevIns, rc,
     3333                                N_("Configuration error: Failed to query boolean value \"ExpressEnabled\""));
    33213334
    33223335    pDevIns->IBase.pfnQueryInterface = ich9pcibridgeQueryInterface;
     
    33323345    pBus->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
    33333346    pBus->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
     3347    /** @todo r=klaus figure out how to extend this to allow PCIe config space
     3348     * extension, which increases the config space frorm 256 bytes to 4K. */
    33343349    pBus->papBridgesR3 = (PPDMPCIDEV *)PDMDevHlpMMHeapAllocZ(pDevIns, sizeof(PPDMPCIDEV) * RT_ELEMENTS(pBus->apDevices));
    33353350    AssertLogRelReturn(pBus->papBridgesR3, VERR_NO_MEMORY);
     
    33733388     */
    33743389    PDMPciDevSetVendorId(  &pBus->PciDev, 0x8086); /* Intel */
    3375     PDMPciDevSetDeviceId(  &pBus->PciDev, 0x2448); /* 82801 Mobile PCI bridge. */
    3376     PDMPciDevSetRevisionId(&pBus->PciDev,   0xf2);
     3390    if (fExpress)
     3391    {
     3392        PDMPciDevSetDeviceId(&pBus->PciDev, 0x29e1); /* 82X38/X48 Express Host-Primary PCI Express Bridge. */
     3393        PDMPciDevSetRevisionId(&pBus->PciDev, 0x01);
     3394    }
     3395    else
     3396    {
     3397        PDMPciDevSetDeviceId(&pBus->PciDev, 0x2448); /* 82801 Mobile PCI bridge. */
     3398        PDMPciDevSetRevisionId(&pBus->PciDev, 0xf2);
     3399    }
    33773400    PDMPciDevSetClassSub(  &pBus->PciDev,   0x04); /* pci2pci */
    33783401    PDMPciDevSetClassBase( &pBus->PciDev,   0x06); /* PCI_bridge */
    3379     PDMPciDevSetClassProg( &pBus->PciDev,   0x01); /* Supports subtractive decoding. */
     3402    if (fExpress)
     3403        PDMPciDevSetClassProg(&pBus->PciDev, 0x00); /* Normal decoding. */
     3404    else
     3405        PDMPciDevSetClassProg(&pBus->PciDev, 0x01); /* Supports subtractive decoding. */
    33803406    PDMPciDevSetHeaderType(&pBus->PciDev,   0x01); /* Single function device which adheres to the PCI-to-PCI bridge spec. */
    3381     PDMPciDevSetCommand(   &pBus->PciDev,   0x00);
    3382     PDMPciDevSetStatus(    &pBus->PciDev,   0x20); /* 66MHz Capable. */
     3407    if (fExpress)
     3408    {
     3409        PDMPciDevSetCommand(&pBus->PciDev, VBOX_PCI_COMMAND_SERR);
     3410        PDMPciDevSetStatus(&pBus->PciDev, VBOX_PCI_STATUS_CAP_LIST); /* Has capabilities. */
     3411        PDMPciDevSetByte(&pBus->PciDev, VBOX_PCI_CACHE_LINE_SIZE, 8); /* 32 bytes */
     3412        /* PCI Express */
     3413        PDMPciDevSetByte(&pBus->PciDev, 0xa0 + 0, VBOX_PCI_CAP_ID_EXP); /* PCI_Express */
     3414        PDMPciDevSetByte(&pBus->PciDev, 0xa0 + 1, 0); /* next */
     3415        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 2,
     3416                        /* version */ 0x2
     3417                      | /* Root Complex Integrated Endpoint */ (VBOX_PCI_EXP_TYPE_ROOT_INT_EP << 4));
     3418        PDMPciDevSetDWord(&pBus->PciDev, 0xa0 + 4, VBOX_PCI_EXP_DEVCAP_RBE); /* Device capabilities. */
     3419        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 8, 0x0000); /* Device control. */
     3420        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 10, 0x0000); /* Device status. */
     3421        PDMPciDevSetDWord(&pBus->PciDev, 0xa0 + 12,
     3422                         /* Max Link Speed */ 2
     3423                       | /* Maximum Link Width */ (16 << 4)
     3424                       | /* Active State Power Management (ASPM) Sopport */ (0 << 10)
     3425                       | VBOX_PCI_EXP_LNKCAP_LBNC
     3426                       | /* Port Number */ ((2 + iInstance) << 24)); /* Link capabilities. */
     3427        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 16, VBOX_PCI_EXP_LNKCTL_CLOCK); /* Link control. */
     3428        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 18,
     3429                        /* Current Link Speed */ 2
     3430                      | /* Negotiated Link Width */ (16 << 4)
     3431                      | VBOX_PCI_EXP_LNKSTA_SL_CLK); /* Link status. */
     3432        PDMPciDevSetDWord(&pBus->PciDev, 0xa0 + 20,
     3433                         /* Slot Power Limit Value */ (75 << 7)
     3434                       | /* Physical Slot Number */ (0 << 19)); /* Slot capabilities. */
     3435        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 24, 0x0000); /* Slot control. */
     3436        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 26, 0x0000); /* Slot status. */
     3437        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 28, 0x0000); /* Root control. */
     3438        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 30, 0x0000); /* Root capabilities. */
     3439        PDMPciDevSetDWord(&pBus->PciDev, 0xa0 + 32, 0x00000000); /* Root status. */
     3440        PDMPciDevSetDWord(&pBus->PciDev, 0xa0 + 36, 0x00000000); /* Device capabilities 2. */
     3441        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 40, 0x0000); /* Device control 2. */
     3442        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 42, 0x0000); /* Device status 2. */
     3443        PDMPciDevSetDWord(&pBus->PciDev, 0xa0 + 44,
     3444                         /* Supported Link Speeds Vector */ (2 << 1)); /* Link capabilities 2. */
     3445        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 48,
     3446                        /* Target Link Speed */ 2); /* Link control 2. */
     3447        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 50, 0x0000); /* Link status 2. */
     3448        PDMPciDevSetDWord(&pBus->PciDev, 0xa0 + 52, 0x00000000); /* Slot capabilities 2. */
     3449        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 56, 0x0000); /* Slot control 2. */
     3450        PDMPciDevSetWord(&pBus->PciDev, 0xa0 + 58, 0x0000); /* Slot status 2. */
     3451        PDMPciDevSetCapabilityList(&pBus->PciDev, 0xa0);
     3452    }
     3453    else
     3454    {
     3455        PDMPciDevSetCommand(&pBus->PciDev, 0x00);
     3456        PDMPciDevSetStatus(&pBus->PciDev, 0x20); /* 66MHz Capable. */
     3457    }
    33833458    PDMPciDevSetInterruptLine(&pBus->PciDev, 0x00); /* This device does not assert interrupts. */
    33843459
     
    33883463     */
    33893464    PDMPciDevSetInterruptPin (&pBus->PciDev, 0x00);
     3465
     3466    if (fExpress)
     3467    {
     3468        /** @todo r=klaus set up the PCIe config space beyond the old 256 byte
     3469         * limit, containing additional capability descriptors. */
     3470    }
    33903471
    33913472    /*
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