VirtualBox

Changeset 34231 in vbox


Ignore:
Timestamp:
Nov 22, 2010 10:23:59 AM (14 years ago)
Author:
vboxsync
Message:

PCI: allow arbitrary width BAR accesses

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/pci.h

    r33314 r34231  
    492492
    493493/** Fixed I/O region number for ROM. */
    494 #define PCI_ROM_SLOT 6
     494#define PCI_ROM_SLOT    6
     495#define VBOX_PCI_ROM_SLOT    6
    495496/** Max number of I/O regions. */
    496497#define PCI_NUM_REGIONS 7
     498#define VBOX_PCI_NUM_REGIONS 7
    497499
    498500/*
     
    649651{
    650652    return (PCIDevGetCommand(pPciDev) & VBOX_PCI_COMMAND_INTX_DISABLE) != 0;
     653}
     654
     655/**
     656 * Gets the status config register.
     657 *
     658 * @returns status config register.
     659 * @param   pPciDev         The PCI device.
     660 */
     661DECLINLINE(uint16_t) PCIDevGetStatus(PPCIDEVICE pPciDev)
     662{
     663    return PCIDevGetWord(pPciDev, VBOX_PCI_STATUS);
    651664}
    652665
  • trunk/src/VBox/Devices/Bus/DevPciIch9.cpp

    r34201 r34231  
    699699DECLINLINE(uint32_t) ich9pciGetRegionReg(int iRegion)
    700700{
    701     return (iRegion == PCI_ROM_SLOT) ?
     701    return (iRegion == VBOX_PCI_ROM_SLOT) ?
    702702            VBOX_PCI_ROM_ADDRESS : (VBOX_PCI_BASE_ADDRESS_0 + iRegion * 4);
    703703}
     
    17311731}
    17321732
    1733 
     1733DECLINLINE(void) ich9pciWriteBarByte(PCIDevice *aDev, int iRegion, int iOffset, uint8_t u8Val)
     1734{
     1735    PCIIORegion * pRegion = &aDev->Int.s.aIORegions[iRegion];
     1736
     1737    int iRegionSize = pRegion->size;
     1738
     1739    /* Region doesn't exist */
     1740    if (iRegionSize == 0)
     1741        return;
     1742
     1743    uint32_t uAddr = ich9pciGetRegionReg(iRegion) + iOffset;
     1744    /* Region size must be power of two */
     1745    Assert((iRegionSize & (iRegionSize - 1)) == 0);
     1746    uint8_t uMask = ((iRegionSize - 1) >> (iOffset*8)) & 0xff;
     1747
     1748    if (iOffset == 0)
     1749    {
     1750        uMask |= (pRegion->type & PCI_ADDRESS_SPACE_IO) ?
     1751                (1 << 2) - 1 /* 2 lowest bits for IO region */ :
     1752                (1 << 4) - 1 /* 4 lowest bits for memory region, also ROM enable bit for ROM region */;
     1753    }
     1754
     1755    u8Val = (PCIDevGetByte(aDev, uAddr) & uMask) | (u8Val & ~uMask);
     1756    PCIDevSetByte(aDev, uAddr, u8Val);
     1757}
    17341758/**
    17351759 * See paragraph 7.5 of PCI Express specification (p. 349) for definition of
     
    17701794    }
    17711795
    1772 
    1773     /* Fast case - update one of BARs or ROM address, 'while' only for 'break' */
    1774     while (   len == 4
    1775            && (   (   u32Address >= VBOX_PCI_BASE_ADDRESS_0
    1776                    && u32Address <  VBOX_PCI_BASE_ADDRESS_0 + 6 * 4)
    1777                || (   u32Address >= VBOX_PCI_ROM_ADDRESS
    1778                    && u32Address <  VBOX_PCI_ROM_ADDRESS+4)
    1779               )
    1780            )
    1781     {
    1782         PCIIORegion *pRegion;
    1783         int reg, regionSize;
    1784 
    1785         reg = (u32Address >= VBOX_PCI_ROM_ADDRESS) ? PCI_ROM_SLOT : (u32Address - VBOX_PCI_BASE_ADDRESS_0) >> 2;
    1786         pRegion = &aDev->Int.s.aIORegions[reg];
    1787         regionSize = pRegion->size;
    1788         if (regionSize == 0)
    1789             break;
    1790         /* compute the stored value */
    1791         if (reg == PCI_ROM_SLOT) {
    1792             /* keep ROM enable bit */
    1793             val &= (~(regionSize - 1)) | 1;
    1794         } else {
    1795             val &= ~(regionSize - 1);
    1796             val |= pRegion->type;
    1797         }
    1798         PCIDevSetDWord(aDev, u32Address, val);
    1799         ich9pciUpdateMappings(aDev);
    1800         return;
    1801     }
    1802 
    18031796    uint32_t addr = u32Address;
    18041797    bool fUpdateMappings = false;
     
    18061799    {
    18071800        bool fWritable = false;
     1801        bool fRom = false;
    18081802        switch (PCIDevGetHeaderType(aDev))
    18091803        {
     
    18201814                    case VBOX_PCI_CLASS_BASE:
    18211815                    case VBOX_PCI_HEADER_TYPE:
    1822                     case VBOX_PCI_BASE_ADDRESS_0: case VBOX_PCI_BASE_ADDRESS_0+1: case VBOX_PCI_BASE_ADDRESS_0+2: case VBOX_PCI_BASE_ADDRESS_0+3:
    1823                     case VBOX_PCI_BASE_ADDRESS_1: case VBOX_PCI_BASE_ADDRESS_1+1: case VBOX_PCI_BASE_ADDRESS_1+2: case VBOX_PCI_BASE_ADDRESS_1+3:
    1824                     case VBOX_PCI_BASE_ADDRESS_2: case VBOX_PCI_BASE_ADDRESS_2+1: case VBOX_PCI_BASE_ADDRESS_2+2: case VBOX_PCI_BASE_ADDRESS_2+3:
    1825                     case VBOX_PCI_BASE_ADDRESS_3: case VBOX_PCI_BASE_ADDRESS_3+1: case VBOX_PCI_BASE_ADDRESS_3+2: case VBOX_PCI_BASE_ADDRESS_3+3:
    1826                     case VBOX_PCI_BASE_ADDRESS_4: case VBOX_PCI_BASE_ADDRESS_4+1: case VBOX_PCI_BASE_ADDRESS_4+2: case VBOX_PCI_BASE_ADDRESS_4+3:
    1827                     case VBOX_PCI_BASE_ADDRESS_5: case VBOX_PCI_BASE_ADDRESS_5+1: case VBOX_PCI_BASE_ADDRESS_5+2: case VBOX_PCI_BASE_ADDRESS_5+3:
    18281816                    case VBOX_PCI_SUBSYSTEM_VENDOR_ID: case VBOX_PCI_SUBSYSTEM_VENDOR_ID+1:
    18291817                    case VBOX_PCI_SUBSYSTEM_ID: case VBOX_PCI_SUBSYSTEM_ID+1:
     
    18631851
    18641852        uint8_t u8Val = (uint8_t)val;
    1865 
    18661853        switch (addr)
    18671854        {
     
    18881875                aDev->config[addr] &= ~u8Val;
    18891876                break;
     1877            case VBOX_PCI_ROM_ADDRESS:    case VBOX_PCI_ROM_ADDRESS   +1: case VBOX_PCI_ROM_ADDRESS   +2: case VBOX_PCI_ROM_ADDRESS   +3:
     1878                fRom = true;
     1879            case VBOX_PCI_BASE_ADDRESS_0: case VBOX_PCI_BASE_ADDRESS_0+1: case VBOX_PCI_BASE_ADDRESS_0+2: case VBOX_PCI_BASE_ADDRESS_0+3:
     1880            case VBOX_PCI_BASE_ADDRESS_1: case VBOX_PCI_BASE_ADDRESS_1+1: case VBOX_PCI_BASE_ADDRESS_1+2: case VBOX_PCI_BASE_ADDRESS_1+3:
     1881            case VBOX_PCI_BASE_ADDRESS_2: case VBOX_PCI_BASE_ADDRESS_2+1: case VBOX_PCI_BASE_ADDRESS_2+2: case VBOX_PCI_BASE_ADDRESS_2+3:
     1882            case VBOX_PCI_BASE_ADDRESS_3: case VBOX_PCI_BASE_ADDRESS_3+1: case VBOX_PCI_BASE_ADDRESS_3+2: case VBOX_PCI_BASE_ADDRESS_3+3:
     1883            case VBOX_PCI_BASE_ADDRESS_4: case VBOX_PCI_BASE_ADDRESS_4+1: case VBOX_PCI_BASE_ADDRESS_4+2: case VBOX_PCI_BASE_ADDRESS_4+3:
     1884            case VBOX_PCI_BASE_ADDRESS_5: case VBOX_PCI_BASE_ADDRESS_5+1: case VBOX_PCI_BASE_ADDRESS_5+2: case VBOX_PCI_BASE_ADDRESS_5+3:
     1885            {
     1886                int iRegion = fRom ? VBOX_PCI_ROM_SLOT : (addr - VBOX_PCI_BASE_ADDRESS_0) >> 2;
     1887                int iOffset = addr & 0x3;
     1888                ich9pciWriteBarByte(aDev, iRegion, iOffset, u8Val);
     1889                fUpdateMappings = true;
     1890                break;
     1891            }
    18901892            default:
    18911893                if (fWritable)
     
    18971899
    18981900    if (fUpdateMappings)
    1899         /* if the command register is modified, we must modify the mappings */
     1901        /* if the command/base address register is modified, we must modify the mappings */
    19001902        ich9pciUpdateMappings(aDev);
    19011903}
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