VirtualBox

Ignore:
Timestamp:
Oct 28, 2016 3:19:42 PM (8 years ago)
Author:
vboxsync
Message:

DevPci: Cleaning up ich9pciUpdateMappings and friends.

File:
1 edited

Legend:

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

    r64466 r64467  
    7171#define VBOX_ICH9PCI_SAVED_STATE_VERSION_CURRENT VBOX_ICH9PCI_SAVED_STATE_VERSION_MSI
    7272
    73 #define INVALID_PCI_ADDRESS ~0U
     73/** Invalid PCI region mapping address. */
     74#define INVALID_PCI_ADDRESS     UINT32_MAX
    7475
    7576
     
    18071808}
    18081809
    1809 static int  ich9pciUnmapRegion(PPDMPCIDEV pDev, int iRegion)
    1810 {
    1811     PCIIORegion* pRegion = &pDev->Int.s.aIORegions[iRegion];
    1812     int rc = VINF_SUCCESS;
    1813     PDEVPCIBUS pBus = pDev->Int.s.CTX_SUFF(pBus);
    1814 
    1815     Assert (pRegion->size != 0);
    1816 
    1817     if (pRegion->addr != INVALID_PCI_ADDRESS)
     1810/**
     1811 * Worker for ich9pciResetDevice and devpciR3UpdateMappings that unmaps a region.
     1812 *
     1813 * @returns VBox status code.
     1814 * @param   pDev                The PCI device.
     1815 * @param   iRegion             The region to unmap.
     1816 */
     1817static int ich9pciUnmapRegion(PPDMPCIDEV pDev, int iRegion)
     1818{
     1819    PCIIORegion *pRegion = &pDev->Int.s.aIORegions[iRegion];
     1820    AssertReturn(pRegion->size != 0, VINF_SUCCESS);
     1821
     1822    int rc;
     1823    if (pRegion->addr == INVALID_PCI_ADDRESS)
     1824        rc = VINF_SUCCESS;
     1825    else
    18181826    {
    18191827        if (pRegion->type & PCI_ADDRESS_SPACE_IO)
     
    18251833        else
    18261834        {
    1827             RTGCPHYS GCPhysBase = pRegion->addr;
     1835            PDEVPCIBUS pBus       = pDev->Int.s.CTX_SUFF(pBus);
     1836            RTGCPHYS   GCPhysBase = pRegion->addr;
    18281837            if (pBus->pPciHlpR3->pfnIsMMIOExBase(pBus->pDevInsR3, pDev->Int.s.pDevInsR3, GCPhysBase))
    18291838            {
     
    18371846                rc = PDMDevHlpMMIODeregister(pDev->Int.s.pDevInsR3, GCPhysBase, pRegion->size);
    18381847        }
    1839 
    18401848        pRegion->addr = INVALID_PCI_ADDRESS;
    18411849    }
    1842 
    18431850    return rc;
    18441851}
    18451852
    1846 static void ich9pciUpdateMappings(PDMPCIDEV* pDev)
     1853static void devpciR3UpdateMappings(PDMPCIDEV* pDev)
    18471854{
    18481855    uint16_t const u16Cmd = ich9pciGetWord(pDev, VBOX_PCI_COMMAND);
     
    18541861        {
    18551862            uint32_t const offCfgReg = ich9pciGetRegionReg(iRegion);
    1856             int rc;
    1857 
    1858             bool f64Bit =    (pRegion->type & ((uint8_t)(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_IO)))
    1859                           == PCI_ADDRESS_SPACE_BAR64;
    1860 
    1861             uint64_t uNew = INVALID_PCI_ADDRESS;
     1863            bool const     f64Bit    =    (pRegion->type & ((uint8_t)(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_IO)))
     1864                                       == PCI_ADDRESS_SPACE_BAR64;
     1865            uint64_t       uNew      = INVALID_PCI_ADDRESS;
     1866
     1867            /*
     1868             * Port I/O region. Check if mapped and within 1..65535 range.
     1869             */
    18621870            if (pRegion->type & PCI_ADDRESS_SPACE_IO)
    18631871            {
    1864                 /*
    1865                  * Port I/O region. Check if mapped and within 0..65535 range.
    1866                  */
    18671872                if (u16Cmd & PCI_COMMAND_IOACCESS)
    18681873                {
    1869                     uint32_t uBase = ich9pciGetDWord(pDev, offCfgReg);
    1870                     uBase &= ~(uint32_t)(cbRegion - 1);
    1871                     uint64_t uLast = cbRegion - 1 + uBase;
     1874                    uint32_t uIoBase = ich9pciGetDWord(pDev, offCfgReg);
     1875                    uIoBase &= ~(uint32_t)(cbRegion - 1);
     1876
     1877                    uint64_t uLast = cbRegion - 1 + uIoBase;
    18721878                    if (   uLast < _64K
    1873                         && uBase <= uLast
    1874                         && uBase > 0)
    1875                         uNew = uBase;
     1879                        && uIoBase < uLast
     1880                        && uIoBase > 0)
     1881                        uNew = uIoBase;
    18761882                }
    18771883            }
    1878             else
     1884            /*
     1885             * MMIO or ROM.  Check ROM enable bit and range.
     1886             *
     1887             * Note! We exclude the I/O-APIC/HPET/ROM area at the end of the first 4GB to
     1888             *       prevent the (fake) PCI BIOS and others from making a mess.  Pure paranoia.
     1889             */
     1890            else if (u16Cmd & PCI_COMMAND_MEMACCESS)
    18791891            {
    1880                 /* MMIO region */
    1881                 if (u16Cmd & PCI_COMMAND_MEMACCESS)
     1892                uint64_t uMemBase = ich9pciGetDWord(pDev, offCfgReg);
     1893                if (f64Bit)
    18821894                {
    1883                     uNew = ich9pciGetDWord(pDev, offCfgReg);
    1884                     if (f64Bit)
    1885                         uNew |= (uint64_t)ich9pciGetDWord(pDev, offCfgReg + 4) << 32;
    1886 
    1887                     /* the ROM slot has a specific enable bit */
    1888                     if (iRegion == PCI_ROM_SLOT && !(uNew & 1))
    1889                         uNew = INVALID_PCI_ADDRESS;
    1890                     else
    1891                     {
    1892                         uNew &= ~(cbRegion - 1);
    1893                         uint64_t uLast = uNew + cbRegion - 1;
    1894                         /* NOTE: we do not support wrapping */
    1895                         /* XXX: as we cannot support really dynamic
    1896                            mappings, we handle specific values as invalid
    1897                            mappings. */
    1898                         /* Unconditionally exclude I/O-APIC/HPET/ROM. Pessimistic, but better than causing a mess. */
    1899                         if (uLast <= uNew || uNew == 0 || (uNew <= UINT32_C(0xffffffff) && uLast >= UINT32_C(0xfec00000)))
    1900                             uNew = INVALID_PCI_ADDRESS;
    1901                     }
    1902                 } else
    1903                     uNew = INVALID_PCI_ADDRESS;
     1895                    Assert(iRegion < VBOX_PCI_ROM_SLOT);
     1896                    uMemBase |= (uint64_t)ich9pciGetDWord(pDev, offCfgReg + 4) << 32;
     1897                }
     1898                if (   iRegion != PCI_ROM_SLOT
     1899                    || (uMemBase & RT_BIT_32(0))) /* ROM enable bit. */
     1900                {
     1901                    uMemBase &= ~(cbRegion - 1);
     1902
     1903                    uint64_t uLast = uNew + cbRegion - 1;
     1904                    if (   uMemBase < uLast
     1905                        && uMemBase > 0
     1906                        && !(   uNew  <= UINT32_C(0xffffffff)
     1907                             && uLast >= UINT32_C(0xfec00000)) )
     1908                        uNew = uMemBase;
     1909                }
    19041910            }
    1905             LogRel2(("PCI: config dev %u/%u BAR%i uOld=%#018llx uNew=%#018llx size=%llu\n", pDev->uDevFn >> 3, pDev->uDevFn & 7, iRegion, pRegion->addr, uNew, pRegion->size));
    1906             /* now do the real mapping */
     1911
     1912            /*
     1913             * Do real unmapping and/or mapping if the address change.
     1914             */
    19071915            if (uNew != pRegion->addr)
    19081916            {
    1909                 if (pRegion->addr != INVALID_PCI_ADDRESS)
    1910                     ich9pciUnmapRegion(pDev, iRegion);
    1911 
     1917                LogRel2(("PCI: config dev %u/%u (%s) BAR%i: %#RX64 -> %#RX64 (LB %RX64 (%RU64))\n",
     1918                         pDev->uDevFn >> VBOX_PCI_DEVFN_DEV_SHIFT, pDev->uDevFn & VBOX_PCI_DEVFN_FUN_MASK, pDev->pszNameR3,
     1919                         iRegion, pRegion->addr, uNew, cbRegion, cbRegion));
     1920
     1921                ich9pciUnmapRegion(pDev, iRegion);
    19121922                pRegion->addr = uNew;
    1913                 if (pRegion->addr != INVALID_PCI_ADDRESS)
     1923                if (uNew != INVALID_PCI_ADDRESS)
    19141924                {
    1915 
    1916                     /* finally, map the region */
    1917                     rc = pRegion->map_func(pDev->Int.s.pDevInsR3, pDev, iRegion,
    1918                                            pRegion->addr, pRegion->size,
    1919                                            (PCIADDRESSSPACE)(pRegion->type));
     1925                    int rc = pRegion->map_func(pDev->Int.s.pDevInsR3, pDev, iRegion,
     1926                                               pRegion->addr, pRegion->size,
     1927                                               (PCIADDRESSSPACE)(pRegion->type));
    19201928                    AssertRC(rc);
    19211929                }
     
    21562164             */
    21572165            if (fUpdateMappings)
    2158                 ich9pciUpdateMappings(pPciDev);
     2166                devpciR3UpdateMappings(pPciDev);
    21592167        }
    21602168    }
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