VirtualBox

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


Ignore:
Timestamp:
Mar 3, 2011 4:14:59 PM (14 years ago)
Author:
vboxsync
Message:

PCI: more raw and 64-bit BARs coding

File:
1 edited

Legend:

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

    r36138 r36153  
    248248PDMBOTHCBDECL(int)  ich9pciIOPortAddressWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
    249249{
    250     Log(("ich9pciIOPortAddressWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
     250    LogFlow(("ich9pciIOPortAddressWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
    251251    NOREF(pvUser);
    252252    if (cb == 4)
     
    282282        *pu32 = pThis->uConfigReg;
    283283        PCI_UNLOCK(pDevIns);
    284         Log(("pciIOPortAddressRead: Port=%#x cb=%d -> %#x\n", Port, cb, *pu32));
     284        LogFlow(("pciIOPortAddressRead: Port=%#x cb=%d -> %#x\n", Port, cb, *pu32));
    285285        return VINF_SUCCESS;
    286286    }
     
    329329#ifdef IN_RING3
    330330            R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pAddr->iDeviceFunc];
    331             Log(("ich9pciConfigWrite: %s: addr=%02x val=%08x len=%d\n", aDev->name, pAddr->iRegister, val, cb));
    332331            aDev->Int.s.pfnConfigWrite(aDev, pAddr->iRegister, val, cb);
    333332#else
     
    383382PDMBOTHCBDECL(int)  ich9pciIOPortDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
    384383{
    385     Log(("pciIOPortDataWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
     384    LogFlow(("pciIOPortDataWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
    386385    NOREF(pvUser);
    387386    int rc = VINF_SUCCESS;
     
    437436            R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pPciAddr->iDeviceFunc];
    438437            *pu32 = aDev->Int.s.pfnConfigRead(aDev, pPciAddr->iRegister, cb);
    439             Log(("ich9pciDataReadAddr: %s: addr=%02x val=%08x len=%d\n", aDev->name, pPciAddr->iRegister, *pu32, cb));
    440438#else
    441439            rc = rcReschedule;
     
    448446
    449447  out:
    450     Log2(("ich9pciDataReadAddr: %02x:%02x:%02x reg %x(%d) gave %x %Rrc\n",
     448    Log3(("ich9pciDataReadAddr: %02x:%02x:%02x reg %x(%d) gave %x %Rrc\n",
    451449          pPciAddr->iBus, pPciAddr->iDeviceFunc >> 3, pPciAddr->iDeviceFunc & 0x7, pPciAddr->iRegister,
    452450          cb, *pu32, rc));
     
    494492        int rc = ich9pciDataRead(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), Port, cb, pu32);
    495493        PCI_UNLOCK(pDevIns);
    496         Log(("pciIOPortDataRead: Port=%#x cb=%#x -> %#x (%Rrc)\n", Port, cb, *pu32, rc));
     494        LogFlow(("pciIOPortDataRead: Port=%#x cb=%#x -> %#x (%Rrc)\n", Port, cb, *pu32, rc));
    497495        return rc;
    498496    }
     
    701699        uint32_t uSecondary   = PCIDevGetByte(pBridge, VBOX_PCI_SECONDARY_BUS);
    702700        uint32_t uSubordinate = PCIDevGetByte(pBridge, VBOX_PCI_SUBORDINATE_BUS);
    703         Log2(("ich9pciFindBridge on bus %p, bridge %d: %d in %d..%d\n", pBus, iBridge, iBus, uSecondary, uSubordinate));
     701        Log3(("ich9pciFindBridge on bus %p, bridge %d: %d in %d..%d\n", pBus, iBridge, iBus, uSecondary, uSubordinate));
    704702        if (iBus >= uSecondary && iBus <= uSubordinate)
    705703            return pBridge;
     
    708706    /* Nothing found. */
    709707    return NULL;
     708}
     709
     710static uint32_t ich9pciGetCfg(PCIDevice* aDev, int32_t iRegister, int cb)
     711{
     712    return aDev->Int.s.pfnConfigRead(aDev, iRegister, cb);
     713}
     714
     715static uint8_t ich9pciGetByte(PCIDevice* aDev, int32_t iRegister)
     716{
     717    return (uint8_t)ich9pciGetCfg(aDev, iRegister, 1);
     718}
     719
     720static uint16_t ich9pciGetWord(PCIDevice* aDev, int32_t iRegister)
     721{
     722    return (uint16_t)ich9pciGetCfg(aDev, iRegister, 2);
     723}
     724
     725static uint32_t ich9pciGetDWord(PCIDevice* aDev, int32_t iRegister)
     726{
     727    return (uint32_t)ich9pciGetCfg(aDev, iRegister, 4);
    710728}
    711729
     
    757775{
    758776    PPCIBUS pBus = pDev->Int.s.CTX_SUFF(pBus);
    759     uint32_t uLast, uNew;
    760 
    761     int iCmd = PCIDevGetCommand(pDev);
     777    uint64_t uLast, uNew;
     778
     779    int iCmd = ich9pciGetWord(pDev, VBOX_PCI_COMMAND);
    762780    for (int iRegion = 0; iRegion < PCI_NUM_REGIONS; iRegion++)
    763781    {
    764782        PCIIORegion* pRegion = &pDev->Int.s.aIORegions[iRegion];
    765         uint32_t uConfigReg = ich9pciGetRegionReg(iRegion);
    766         int32_t  iRegionSize =  pRegion->size;
     783        uint32_t uConfigReg  = ich9pciGetRegionReg(iRegion);
     784        int64_t  iRegionSize =  pRegion->size;
    767785        int rc;
    768786
     
    770788            continue;
    771789
    772         AssertMsg((pRegion->type & PCI_ADDRESS_SPACE_BAR64) == 0, ("64-bit BARs not yet implemented\n"));
     790        bool f64Bit = (pRegion->type & PCI_ADDRESS_SPACE_BAR64) != 0;
    773791
    774792        if (pRegion->type & PCI_ADDRESS_SPACE_IO)
     
    778796            {
    779797                /* IO access allowed */
    780                 uNew = ich9pciConfigReadDev(pDev, uConfigReg, 4);
     798                uNew = ich9pciGetDWord(pDev, uConfigReg);
    781799                uNew &= ~(iRegionSize - 1);
    782800                uLast = uNew + iRegionSize - 1;
     
    792810            if (iCmd & PCI_COMMAND_MEMACCESS)
    793811            {
    794                 uNew = ich9pciConfigReadDev(pDev, uConfigReg, 4);
     812                uNew = ich9pciGetDWord(pDev, uConfigReg);
     813
     814                if (f64Bit)
     815                {
     816                    uNew |= ((uint64_t)ich9pciGetDWord(pDev, uConfigReg+4)) << 32;
     817                    if (uNew > UINT64_C(0x0000010000000000))
     818                    {
     819                        /* Workaround for REM being unhapping with mapping very lange 64-bit addresses */
     820                        Log(("Ignoring too 64-bit BAR: %llx\n", uNew));
     821                        uNew = INVALID_PCI_ADDRESS;
     822                    }
     823                }
     824
    795825                /* the ROM slot has a specific enable bit */
    796826                if (iRegion == PCI_ROM_SLOT && !(uNew & 1))
     
    819849            if (pRegion->addr != INVALID_PCI_ADDRESS)
    820850            {
     851
    821852                /* finally, map the region */
    822853                rc = pRegion->map_func(pDev, iRegion,
     
    15121543}
    15131544
    1514 static void ich9pciSetRegionAddress(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, int iRegion, uint32_t addr)
     1545static void ich9pciSetRegionAddress(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, int iRegion, uint64_t addr)
    15151546{
    15161547    uint32_t uReg = ich9pciGetRegionReg(iRegion);
     
    15201551    /* Read command register. */
    15211552    uint16_t uCmd = ich9pciConfigRead(pGlobals, uBus, uDevFn, VBOX_PCI_COMMAND, 2);
     1553
     1554    Log(("Set region address: %02x:%02x.%d region %d address=%lld\n",
     1555         uBus, uDevFn>>3, uDevFn&7, addr));
    15221556
    15231557    if ( iRegion == PCI_ROM_SLOT )
     
    15281562        uCmd |= PCI_COMMAND_MEMACCESS; /* Enable MMIO access. */
    15291563
     1564    bool f64Bit = (uResourceType & PCI_ADDRESS_SPACE_BAR64) != 0;
     1565
    15301566    /* Write address of the device. */
    1531     ich9pciConfigWrite(pGlobals, uBus, uDevFn, uReg, addr, 4);
     1567    ich9pciConfigWrite(pGlobals, uBus, uDevFn, uReg, (uint32_t)addr, 4);
     1568    if (f64Bit)
     1569        ich9pciConfigWrite(pGlobals, uBus, uDevFn, uReg + 4, (uint32_t)(addr >> 32), 4);
    15321570
    15331571    /* enable memory mappings */
     
    16041642static void ich9pciBiosInitDevice(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn)
    16051643{
    1606     uint32_t *paddr;
    16071644    uint16_t uDevClass, uVendor, uDevice;
    16081645    uint8_t uCmd;
    1609    
     1646
    16101647    uDevClass  = ich9pciConfigRead(pGlobals, uBus, uDevFn, VBOX_PCI_CLASS_DEVICE, 2);
    16111648    uVendor    = ich9pciConfigRead(pGlobals, uBus, uDevFn, VBOX_PCI_VENDOR_ID, 2);
     
    16621699                   are cleared. . */
    16631700                uint8_t u8ResourceType = ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address, 1);
    1664                 ich9pciConfigWrite(pGlobals, uBus, uDevFn, u32Address, UINT32_C(0xffffffff), 4);
    1665                 uint32_t u32Size = ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address, 4);
    1666                 /* Clear resource information depending on resource type. */
    1667                 if ((u8ResourceType & PCI_COMMAND_IOACCESS) == PCI_COMMAND_IOACCESS) /* I/O */
    1668                     u32Size &= ~(0x01);
    1669                 else                        /* MMIO */
    1670                     u32Size &= ~(0x0f);
    1671 
     1701
     1702                bool f64bit = (u8ResourceType & PCI_ADDRESS_SPACE_BAR64) != 0;
    16721703                bool fIsPio = ((u8ResourceType & PCI_COMMAND_IOACCESS) == PCI_COMMAND_IOACCESS);
    1673                 /*
    1674                  * Invert all bits and add 1 to get size of the region.
    1675                  * (From PCI implementation note)
    1676                  */
    1677                 if (fIsPio && (u32Size & UINT32_C(0xffff0000)) == 0)
    1678                     u32Size = (~(u32Size | UINT32_C(0xffff0000))) + 1;
     1704                uint64_t cbRegSize64 = 0;
     1705
     1706                if (f64bit)
     1707                {
     1708                    ich9pciConfigWrite(pGlobals, uBus, uDevFn, u32Address,   UINT32_C(0xffffffff), 4);
     1709                    ich9pciConfigWrite(pGlobals, uBus, uDevFn, u32Address+4, UINT32_C(0xffffffff), 4);
     1710                    cbRegSize64  =            ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address,   4);
     1711                    cbRegSize64 |= ((uint64_t)ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address+4, 4) << 32);
     1712                    cbRegSize64 &= ~UINT64_C(0x0f);
     1713                    cbRegSize64 = (~cbRegSize64) + 1;
     1714
     1715                    /* No 64-bit PIO regions possible. */
     1716                    Assert((u8ResourceType & PCI_COMMAND_IOACCESS) == 0);
     1717                }
    16791718                else
    1680                     u32Size = (~u32Size) + 1;
    1681 
    1682                 Log(("%s: Size of region %u for device %d on bus %d is %u\n", __FUNCTION__, iRegion, uDevFn, uBus, u32Size));
    1683 
    1684                 if (u32Size)
    16851719                {
    1686                     paddr = fIsPio ? &pGlobals->uPciBiosIo : &pGlobals->uPciBiosMmio;
    1687                     *paddr = (*paddr + u32Size - 1) & ~(u32Size - 1);
     1720                    uint32_t cbRegSize32;
     1721                    ich9pciConfigWrite(pGlobals, uBus, uDevFn, u32Address, UINT32_C(0xffffffff), 4);
     1722                    cbRegSize32 = ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address, 4);
     1723
     1724                    /* Clear resource information depending on resource type. */
     1725                    if (fIsPio) /* PIO */
     1726                        cbRegSize32 &= ~UINT32_C(0x01);
     1727                    else        /* MMIO */
     1728                        cbRegSize32 &= ~UINT32_C(0x0f);
     1729
     1730                    /*
     1731                     * Invert all bits and add 1 to get size of the region.
     1732                     * (From PCI implementation note)
     1733                     */
     1734                    if (fIsPio && (cbRegSize32 & UINT32_C(0xffff0000)) == 0)
     1735                        cbRegSize32 = (~(cbRegSize32 | UINT32_C(0xffff0000))) + 1;
     1736                    else
     1737                        cbRegSize32 = (~cbRegSize32) + 1;
     1738
     1739                    cbRegSize64 = cbRegSize32;
     1740                }
     1741                Assert(cbRegSize64 == (uint32_t)cbRegSize64);
     1742                Log2(("%s: Size of region %u for device %d on bus %d is %lld\n", __FUNCTION__, iRegion, uDevFn, uBus, cbRegSize64));
     1743
     1744                if (cbRegSize64)
     1745                {
     1746                    uint32_t  cbRegSize32 = (uint32_t)cbRegSize64;
     1747                    uint32_t* paddr = fIsPio ? &pGlobals->uPciBiosIo : &pGlobals->uPciBiosMmio;
     1748                    *paddr = (*paddr + cbRegSize32 - 1) & ~(cbRegSize32 - 1);
    16881749                    Log(("%s: Start address of %s region %u is %#x\n", __FUNCTION__, (fIsPio ? "I/O" : "MMIO"), iRegion, *paddr));
    16891750                    ich9pciSetRegionAddress(pGlobals, uBus, uDevFn, iRegion, *paddr);
    1690                     *paddr += u32Size;
    1691                     Log(("%s: New address is %#x\n", __FUNCTION__, *paddr));
     1751                    *paddr += cbRegSize32;
     1752                    Log2(("%s: New address is %#x\n", __FUNCTION__, *paddr));
     1753
     1754                    if (f64bit)
     1755                        iRegion++; /* skip next region */
    16921756                }
    16931757            }
     
    19161980
    19171981    uint32_t addr = u32Address;
    1918     bool fUpdateMappings = false;
    1919     bool fP2PBridge = false;
     1982    bool     fUpdateMappings = false;
     1983    bool     fP2PBridge = false;
     1984    bool     fPassthrough = pciDevIsPassthrough(aDev);
     1985    uint8_t  u8HeaderType = ich9pciGetByte(aDev, VBOX_PCI_HEADER_TYPE);
     1986
    19201987    for (uint32_t i = 0; i < len; i++)
    19211988    {
    19221989        bool fWritable = false;
    19231990        bool fRom = false;
    1924         switch (PCIDevGetHeaderType(aDev))
     1991        switch (u8HeaderType)
    19251992        {
    19261993            case 0x00: /* normal device */
     
    19812048            case VBOX_PCI_COMMAND: /* Command register, bits 0-7. */
    19822049                fUpdateMappings = true;
    1983                 PCIDevSetByte(aDev, addr, u8Val);
    1984                 break;
     2050                goto default_case;
    19852051            case VBOX_PCI_COMMAND+1: /* Command register, bits 8-15. */
    19862052                /* don't change reserved bits (11-15) */
    19872053                u8Val &= UINT32_C(~0xf8);
    19882054                fUpdateMappings = true;
    1989                 PCIDevSetByte(aDev, addr, u8Val);
    1990                 break;
     2055                goto default_case;
    19912056            case VBOX_PCI_STATUS:  /* Status register, bits 0-7. */
    19922057                /* don't change read-only bits => actually all lower bits are read-only */
    19932058                u8Val &= UINT32_C(~0xff);
    19942059                /* status register, low part: clear bits by writing a '1' to the corresponding bit */
    1995                 aDev->config[addr] &= ~u8Val;
     2060                if (!fPassthrough)
     2061                    aDev->config[addr] &= ~u8Val;
    19962062                break;
    19972063            case VBOX_PCI_STATUS+1:  /* Status register, bits 8-15. */
     
    19992065                u8Val &= UINT32_C(~0x06);
    20002066                /* status register, high part: clear bits by writing a '1' to the corresponding bit */
    2001                 aDev->config[addr] &= ~u8Val;
     2067                if (!fPassthrough)
     2068                    aDev->config[addr] &= ~u8Val;
    20022069                break;
    20032070            case VBOX_PCI_ROM_ADDRESS:    case VBOX_PCI_ROM_ADDRESS   +1: case VBOX_PCI_ROM_ADDRESS   +2: case VBOX_PCI_ROM_ADDRESS   +3:
     
    20172084                    int iRegion = fRom ? VBOX_PCI_ROM_SLOT : (addr - VBOX_PCI_BASE_ADDRESS_0) >> 2;
    20182085                    int iOffset = addr & 0x3;
    2019                     ich9pciWriteBarByte(aDev, iRegion, iOffset, u8Val);
     2086                    if (!fPassthrough)
     2087                        ich9pciWriteBarByte(aDev, iRegion, iOffset, u8Val);
    20202088                    fUpdateMappings = true;
    20212089                }
     
    20242092            default:
    20252093            default_case:
    2026                 if (fWritable)
     2094                if (fWritable && !fPassthrough)
    20272095                    PCIDevSetByte(aDev, addr, u8Val);
    20282096        }
     
    21992267        pHlp->pfnPrintf(pHlp, "    ");
    22002268    }
    2201 }
    2202 static uint32_t ich9pciGetCfg(PCIDevice* aDev, int32_t iRegister, int cb)
    2203 {
    2204     return aDev->Int.s.pfnConfigRead(aDev, iRegister, cb);
    2205 }
    2206 
    2207 static uint8_t ich9pciGetByte(PCIDevice* aDev, int32_t iRegister)
    2208 {
    2209     return (uint8_t)ich9pciGetCfg(aDev, iRegister, 1);
    2210 }
    2211 
    2212 static uint16_t ich9pciGetWord(PCIDevice* aDev, int32_t iRegister)
    2213 {
    2214     return (uint16_t)ich9pciGetCfg(aDev, iRegister, 2);
    2215 }
    2216 
    2217 static uint32_t ich9pciGetDWord(PCIDevice* aDev, int32_t iRegister)
    2218 {
    2219     return (uint32_t)ich9pciGetCfg(aDev, iRegister, 4);
    22202269}
    22212270
     
    22582307
    22592308                    uint32_t u32Addr = ich9pciGetDWord(pPciDev, ich9pciGetRegionReg(iRegion));
    2260                     const char * szDesc;
    2261 
     2309                    const char * pszDesc;
     2310                    char szDescBuf[128];
     2311
     2312                    bool f64Bit = (pRegion->type & PCI_ADDRESS_SPACE_BAR64);
    22622313                    if (pRegion->type & PCI_ADDRESS_SPACE_IO)
    22632314                    {
    2264                         szDesc = "IO";
     2315                        pszDesc = "IO";
    22652316                        u32Addr &= ~0x3;
    22662317                    }
    22672318                    else
    22682319                    {
    2269                         szDesc = "MMIO";
     2320                        RTStrPrintf(szDescBuf, sizeof(szDescBuf), "MMIO%s%s",
     2321                                    f64Bit ? "64" : "32",
     2322                                    (pRegion->type & PCI_ADDRESS_SPACE_MEM_PREFETCH) ? " PREFETCH" : "");
     2323                        pszDesc = szDescBuf;
    22702324                        u32Addr &= ~0xf;
    22712325                    }
     
    22732327                    printIndent(pHlp, iIndent + 2);
    22742328                    pHlp->pfnPrintf(pHlp, "  %s region #%d: %x..%x\n",
    2275                                     szDesc, iRegion, u32Addr, u32Addr+iRegionSize);
     2329                                    pszDesc, iRegion, u32Addr, u32Addr+iRegionSize);
     2330                    if (f64Bit)
     2331                        iRegion++;
    22762332                }
    22772333            }
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