Changeset 64467 in vbox for trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
- Timestamp:
- Oct 28, 2016 3:19:42 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
r64466 r64467 71 71 #define VBOX_ICH9PCI_SAVED_STATE_VERSION_CURRENT VBOX_ICH9PCI_SAVED_STATE_VERSION_MSI 72 72 73 #define INVALID_PCI_ADDRESS ~0U 73 /** Invalid PCI region mapping address. */ 74 #define INVALID_PCI_ADDRESS UINT32_MAX 74 75 75 76 … … 1807 1808 } 1808 1809 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 */ 1817 static 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 1818 1826 { 1819 1827 if (pRegion->type & PCI_ADDRESS_SPACE_IO) … … 1825 1833 else 1826 1834 { 1827 RTGCPHYS GCPhysBase = pRegion->addr; 1835 PDEVPCIBUS pBus = pDev->Int.s.CTX_SUFF(pBus); 1836 RTGCPHYS GCPhysBase = pRegion->addr; 1828 1837 if (pBus->pPciHlpR3->pfnIsMMIOExBase(pBus->pDevInsR3, pDev->Int.s.pDevInsR3, GCPhysBase)) 1829 1838 { … … 1837 1846 rc = PDMDevHlpMMIODeregister(pDev->Int.s.pDevInsR3, GCPhysBase, pRegion->size); 1838 1847 } 1839 1840 1848 pRegion->addr = INVALID_PCI_ADDRESS; 1841 1849 } 1842 1843 1850 return rc; 1844 1851 } 1845 1852 1846 static void ich9pciUpdateMappings(PDMPCIDEV* pDev)1853 static void devpciR3UpdateMappings(PDMPCIDEV* pDev) 1847 1854 { 1848 1855 uint16_t const u16Cmd = ich9pciGetWord(pDev, VBOX_PCI_COMMAND); … … 1854 1861 { 1855 1862 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 */ 1862 1870 if (pRegion->type & PCI_ADDRESS_SPACE_IO) 1863 1871 { 1864 /*1865 * Port I/O region. Check if mapped and within 0..65535 range.1866 */1867 1872 if (u16Cmd & PCI_COMMAND_IOACCESS) 1868 1873 { 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; 1872 1878 if ( uLast < _64K 1873 && u Base <=uLast1874 && u Base > 0)1875 uNew = u Base;1879 && uIoBase < uLast 1880 && uIoBase > 0) 1881 uNew = uIoBase; 1876 1882 } 1877 1883 } 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) 1879 1891 { 1880 /* MMIO region */1881 if ( u16Cmd & PCI_COMMAND_MEMACCESS)1892 uint64_t uMemBase = ich9pciGetDWord(pDev, offCfgReg); 1893 if (f64Bit) 1882 1894 { 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 } 1904 1910 } 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 */ 1907 1915 if (uNew != pRegion->addr) 1908 1916 { 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); 1912 1922 pRegion->addr = uNew; 1913 if ( pRegion->addr!= INVALID_PCI_ADDRESS)1923 if (uNew != INVALID_PCI_ADDRESS) 1914 1924 { 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)); 1920 1928 AssertRC(rc); 1921 1929 } … … 2156 2164 */ 2157 2165 if (fUpdateMappings) 2158 ich9pciUpdateMappings(pPciDev);2166 devpciR3UpdateMappings(pPciDev); 2159 2167 } 2160 2168 }
Note:
See TracChangeset
for help on using the changeset viewer.