Changeset 64465 in vbox
- Timestamp:
- Oct 28, 2016 2:30:59 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 111599
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
r64464 r64465 1848 1848 uint64_t uLast, uNew; 1849 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) 1850 uint16_t const u16Cmd = ich9pciGetWord(pDev, VBOX_PCI_COMMAND); 1851 for (unsigned iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS; iRegion++) 1852 { 1853 PCIIORegion *pRegion = &pDev->Int.s.aIORegions[iRegion]; 1854 uint64_t const cbRegion = pRegion->size; 1855 if (cbRegion != 0) 1856 { 1857 uint32_t const offCfgReg = ich9pciGetRegionReg(iRegion); 1858 int rc; 1859 1860 bool f64Bit = (pRegion->type & ((uint8_t)(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_IO))) 1861 == PCI_ADDRESS_SPACE_BAR64; 1862 1863 if (pRegion->type & PCI_ADDRESS_SPACE_IO) 1868 1864 { 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) 1865 /* port IO region */ 1866 if (u16Cmd & PCI_COMMAND_IOACCESS) 1867 { 1868 /* IO access allowed */ 1869 uNew = ich9pciGetDWord(pDev, offCfgReg); 1870 uNew &= ~(cbRegion - 1); 1871 uLast = uNew + cbRegion - 1; 1872 /* only 64K ioports on PC */ 1873 if (uLast <= uNew || uNew == 0 || uLast >= 0x10000) 1874 uNew = INVALID_PCI_ADDRESS; 1875 } else 1875 1876 uNew = INVALID_PCI_ADDRESS; 1876 } else 1877 uNew = INVALID_PCI_ADDRESS; 1878 } 1879 else 1880 { 1881 /* MMIO region */ 1882 if (iCmd & PCI_COMMAND_MEMACCESS) 1877 } 1878 else 1883 1879 { 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)) 1880 /* MMIO region */ 1881 if (u16Cmd & PCI_COMMAND_MEMACCESS) 1882 { 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 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 1890 1903 uNew = INVALID_PCI_ADDRESS; 1891 else 1904 } 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 */ 1907 if (uNew != pRegion->addr) 1908 { 1909 if (pRegion->addr != INVALID_PCI_ADDRESS) 1910 ich9pciUnmapRegion(pDev, iRegion); 1911 1912 pRegion->addr = uNew; 1913 if (pRegion->addr != INVALID_PCI_ADDRESS) 1892 1914 { 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; 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)); 1920 AssertRC(rc); 1902 1921 } 1903 } else1904 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 1922 } 1923 } 1924 1925 if (f64Bit) 1926 iRegion++; 1923 1924 if (f64Bit) 1925 iRegion++; 1926 } 1927 /* else: size == 0: unused region */ 1927 1928 } 1928 1929 }
Note:
See TracChangeset
for help on using the changeset viewer.