VirtualBox

Changeset 64464 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Oct 28, 2016 2:25:38 PM (8 years ago)
Author:
vboxsync
Message:

DevPci: Cleaning up ich9pciUpdateMappings and friends (only moved, no change).

File:
1 edited

Legend:

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

    r64463 r64464  
    7171#define VBOX_ICH9PCI_SAVED_STATE_VERSION_CURRENT VBOX_ICH9PCI_SAVED_STATE_VERSION_MSI
    7272
     73#define INVALID_PCI_ADDRESS ~0U
     74
    7375
    7476/*********************************************************************************************************************************
     
    8082#ifdef IN_RING3
    8183static void ich9pcibridgeReset(PPDMDEVINS pDevIns);
    82 static void ich9pciUpdateMappings(PDMPCIDEV *pDev);
    8384DECLINLINE(PPDMPCIDEV) ich9pciFindBridge(PDEVPCIBUS pBus, uint8_t iBus);
    8485static void ich9pciBiosInitDevice(PDEVPCIROOT pGlobals, uint8_t uBus, uint8_t uDevFn);
     
    733734    return iRegion == VBOX_PCI_ROM_SLOT
    734735         ?  VBOX_PCI_ROM_ADDRESS : (VBOX_PCI_BASE_ADDRESS_0 + iRegion * 4);
    735 }
    736 
    737 #define INVALID_PCI_ADDRESS ~0U
    738 
    739 static int  ich9pciUnmapRegion(PPDMPCIDEV pDev, int iRegion)
    740 {
    741     PCIIORegion* pRegion = &pDev->Int.s.aIORegions[iRegion];
    742     int rc = VINF_SUCCESS;
    743     PDEVPCIBUS pBus = pDev->Int.s.CTX_SUFF(pBus);
    744 
    745     Assert (pRegion->size != 0);
    746 
    747     if (pRegion->addr != INVALID_PCI_ADDRESS)
    748     {
    749         if (pRegion->type & PCI_ADDRESS_SPACE_IO)
    750         {
    751             /* Port IO */
    752             rc = PDMDevHlpIOPortDeregister(pDev->Int.s.pDevInsR3, pRegion->addr, pRegion->size);
    753             AssertRC(rc);
    754         }
    755         else
    756         {
    757             RTGCPHYS GCPhysBase = pRegion->addr;
    758             if (pBus->pPciHlpR3->pfnIsMMIOExBase(pBus->pDevInsR3, pDev->Int.s.pDevInsR3, GCPhysBase))
    759             {
    760                 /* unmap it. */
    761                 rc = pRegion->map_func(pDev->Int.s.pDevInsR3, pDev, iRegion,
    762                                        NIL_RTGCPHYS, pRegion->size, (PCIADDRESSSPACE)(pRegion->type));
    763                 AssertRC(rc);
    764                 rc = PDMDevHlpMMIOExUnmap(pDev->Int.s.pDevInsR3, pDev, iRegion, GCPhysBase);
    765             }
    766             else
    767                 rc = PDMDevHlpMMIODeregister(pDev->Int.s.pDevInsR3, GCPhysBase, pRegion->size);
    768         }
    769 
    770         pRegion->addr = INVALID_PCI_ADDRESS;
    771     }
    772 
    773     return rc;
    774 }
    775 
    776 static void ich9pciUpdateMappings(PDMPCIDEV* pDev)
    777 {
    778     uint64_t uLast, uNew;
    779 
    780     int iCmd = ich9pciGetWord(pDev, VBOX_PCI_COMMAND);
    781     for (int iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS; iRegion++)
    782     {
    783         PCIIORegion* pRegion = &pDev->Int.s.aIORegions[iRegion];
    784         uint32_t uConfigReg  = ich9pciGetRegionReg(iRegion);
    785         int64_t  iRegionSize =  pRegion->size;
    786         int rc;
    787 
    788         if (iRegionSize == 0)
    789             continue;
    790 
    791         bool f64Bit =    (pRegion->type & ((uint8_t)(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_IO)))
    792                       == PCI_ADDRESS_SPACE_BAR64;
    793 
    794         if (pRegion->type & PCI_ADDRESS_SPACE_IO)
    795         {
    796             /* port IO region */
    797             if (iCmd & PCI_COMMAND_IOACCESS)
    798             {
    799                 /* IO access allowed */
    800                 uNew = ich9pciGetDWord(pDev, uConfigReg);
    801                 uNew &= ~(iRegionSize - 1);
    802                 uLast = uNew + iRegionSize - 1;
    803                 /* only 64K ioports on PC */
    804                 if (uLast <= uNew || uNew == 0 || uLast >= 0x10000)
    805                     uNew = INVALID_PCI_ADDRESS;
    806             } else
    807                 uNew = INVALID_PCI_ADDRESS;
    808         }
    809         else
    810         {
    811             /* MMIO region */
    812             if (iCmd & PCI_COMMAND_MEMACCESS)
    813             {
    814                 uNew = ich9pciGetDWord(pDev, uConfigReg);
    815                 if (f64Bit)
    816                     uNew |= (uint64_t)ich9pciGetDWord(pDev, uConfigReg + 4) << 32;
    817 
    818                 /* the ROM slot has a specific enable bit */
    819                 if (iRegion == PCI_ROM_SLOT && !(uNew & 1))
    820                     uNew = INVALID_PCI_ADDRESS;
    821                 else
    822                 {
    823                     uNew &= ~(iRegionSize - 1);
    824                     uLast = uNew + iRegionSize - 1;
    825                     /* NOTE: we do not support wrapping */
    826                     /* XXX: as we cannot support really dynamic
    827                        mappings, we handle specific values as invalid
    828                        mappings. */
    829                     /* Unconditionally exclude I/O-APIC/HPET/ROM. Pessimistic, but better than causing a mess. */
    830                     if (uLast <= uNew || uNew == 0 || (uNew <= UINT32_C(0xffffffff) && uLast >= UINT32_C(0xfec00000)))
    831                         uNew = INVALID_PCI_ADDRESS;
    832                 }
    833             } else
    834                 uNew = INVALID_PCI_ADDRESS;
    835         }
    836         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));
    837         /* now do the real mapping */
    838         if (uNew != pRegion->addr)
    839         {
    840             if (pRegion->addr != INVALID_PCI_ADDRESS)
    841                 ich9pciUnmapRegion(pDev, iRegion);
    842 
    843             pRegion->addr = uNew;
    844             if (pRegion->addr != INVALID_PCI_ADDRESS)
    845             {
    846 
    847                 /* finally, map the region */
    848                 rc = pRegion->map_func(pDev->Int.s.pDevInsR3, pDev, iRegion,
    849                                        pRegion->addr, pRegion->size,
    850                                        (PCIADDRESSSPACE)(pRegion->type));
    851                 AssertRC(rc);
    852             }
    853         }
    854 
    855         if (f64Bit)
    856             iRegion++;
    857     }
    858736}
    859737
     
    19271805    }
    19281806    return uValue;
     1807}
     1808
     1809static 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)
     1818    {
     1819        if (pRegion->type & PCI_ADDRESS_SPACE_IO)
     1820        {
     1821            /* Port IO */
     1822            rc = PDMDevHlpIOPortDeregister(pDev->Int.s.pDevInsR3, pRegion->addr, pRegion->size);
     1823            AssertRC(rc);
     1824        }
     1825        else
     1826        {
     1827            RTGCPHYS GCPhysBase = pRegion->addr;
     1828            if (pBus->pPciHlpR3->pfnIsMMIOExBase(pBus->pDevInsR3, pDev->Int.s.pDevInsR3, GCPhysBase))
     1829            {
     1830                /* unmap it. */
     1831                rc = pRegion->map_func(pDev->Int.s.pDevInsR3, pDev, iRegion,
     1832                                       NIL_RTGCPHYS, pRegion->size, (PCIADDRESSSPACE)(pRegion->type));
     1833                AssertRC(rc);
     1834                rc = PDMDevHlpMMIOExUnmap(pDev->Int.s.pDevInsR3, pDev, iRegion, GCPhysBase);
     1835            }
     1836            else
     1837                rc = PDMDevHlpMMIODeregister(pDev->Int.s.pDevInsR3, GCPhysBase, pRegion->size);
     1838        }
     1839
     1840        pRegion->addr = INVALID_PCI_ADDRESS;
     1841    }
     1842
     1843    return rc;
     1844}
     1845
     1846static void ich9pciUpdateMappings(PDMPCIDEV* pDev)
     1847{
     1848    uint64_t uLast, uNew;
     1849
     1850    int iCmd = ich9pciGetWord(pDev, VBOX_PCI_COMMAND);
     1851    for (int iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS; iRegion++)
     1852    {
     1853        PCIIORegion* pRegion = &pDev->Int.s.aIORegions[iRegion];
     1854        uint32_t uConfigReg  = ich9pciGetRegionReg(iRegion);
     1855        int64_t  iRegionSize =  pRegion->size;
     1856        int rc;
     1857
     1858        if (iRegionSize == 0)
     1859            continue;
     1860
     1861        bool f64Bit =    (pRegion->type & ((uint8_t)(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_IO)))
     1862                      == PCI_ADDRESS_SPACE_BAR64;
     1863
     1864        if (pRegion->type & PCI_ADDRESS_SPACE_IO)
     1865        {
     1866            /* port IO region */
     1867            if (iCmd & PCI_COMMAND_IOACCESS)
     1868            {
     1869                /* IO access allowed */
     1870                uNew = ich9pciGetDWord(pDev, uConfigReg);
     1871                uNew &= ~(iRegionSize - 1);
     1872                uLast = uNew + iRegionSize - 1;
     1873                /* only 64K ioports on PC */
     1874                if (uLast <= uNew || uNew == 0 || uLast >= 0x10000)
     1875                    uNew = INVALID_PCI_ADDRESS;
     1876            } else
     1877                uNew = INVALID_PCI_ADDRESS;
     1878        }
     1879        else
     1880        {
     1881            /* MMIO region */
     1882            if (iCmd & PCI_COMMAND_MEMACCESS)
     1883            {
     1884                uNew = ich9pciGetDWord(pDev, uConfigReg);
     1885                if (f64Bit)
     1886                    uNew |= (uint64_t)ich9pciGetDWord(pDev, uConfigReg + 4) << 32;
     1887
     1888                /* the ROM slot has a specific enable bit */
     1889                if (iRegion == PCI_ROM_SLOT && !(uNew & 1))
     1890                    uNew = INVALID_PCI_ADDRESS;
     1891                else
     1892                {
     1893                    uNew &= ~(iRegionSize - 1);
     1894                    uLast = uNew + iRegionSize - 1;
     1895                    /* NOTE: we do not support wrapping */
     1896                    /* XXX: as we cannot support really dynamic
     1897                       mappings, we handle specific values as invalid
     1898                       mappings. */
     1899                    /* Unconditionally exclude I/O-APIC/HPET/ROM. Pessimistic, but better than causing a mess. */
     1900                    if (uLast <= uNew || uNew == 0 || (uNew <= UINT32_C(0xffffffff) && uLast >= UINT32_C(0xfec00000)))
     1901                        uNew = INVALID_PCI_ADDRESS;
     1902                }
     1903            } else
     1904                uNew = INVALID_PCI_ADDRESS;
     1905        }
     1906        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));
     1907        /* now do the real mapping */
     1908        if (uNew != pRegion->addr)
     1909        {
     1910            if (pRegion->addr != INVALID_PCI_ADDRESS)
     1911                ich9pciUnmapRegion(pDev, iRegion);
     1912
     1913            pRegion->addr = uNew;
     1914            if (pRegion->addr != INVALID_PCI_ADDRESS)
     1915            {
     1916
     1917                /* finally, map the region */
     1918                rc = pRegion->map_func(pDev->Int.s.pDevInsR3, pDev, iRegion,
     1919                                       pRegion->addr, pRegion->size,
     1920                                       (PCIADDRESSSPACE)(pRegion->type));
     1921                AssertRC(rc);
     1922            }
     1923        }
     1924
     1925        if (f64Bit)
     1926            iRegion++;
     1927    }
    19291928}
    19301929
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