Changeset 64464 in vbox for trunk/src/VBox
- Timestamp:
- Oct 28, 2016 2:25:38 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
r64463 r64464 71 71 #define VBOX_ICH9PCI_SAVED_STATE_VERSION_CURRENT VBOX_ICH9PCI_SAVED_STATE_VERSION_MSI 72 72 73 #define INVALID_PCI_ADDRESS ~0U 74 73 75 74 76 /********************************************************************************************************************************* … … 80 82 #ifdef IN_RING3 81 83 static void ich9pcibridgeReset(PPDMDEVINS pDevIns); 82 static void ich9pciUpdateMappings(PDMPCIDEV *pDev);83 84 DECLINLINE(PPDMPCIDEV) ich9pciFindBridge(PDEVPCIBUS pBus, uint8_t iBus); 84 85 static void ich9pciBiosInitDevice(PDEVPCIROOT pGlobals, uint8_t uBus, uint8_t uDevFn); … … 733 734 return iRegion == VBOX_PCI_ROM_SLOT 734 735 ? VBOX_PCI_ROM_ADDRESS : (VBOX_PCI_BASE_ADDRESS_0 + iRegion * 4); 735 }736 737 #define INVALID_PCI_ADDRESS ~0U738 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 else756 {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 else767 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 } else807 uNew = INVALID_PCI_ADDRESS;808 }809 else810 {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 else822 {823 uNew &= ~(iRegionSize - 1);824 uLast = uNew + iRegionSize - 1;825 /* NOTE: we do not support wrapping */826 /* XXX: as we cannot support really dynamic827 mappings, we handle specific values as invalid828 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 } else834 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 }858 736 } 859 737 … … 1927 1805 } 1928 1806 return uValue; 1807 } 1808 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) 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 1846 static 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 } 1929 1928 } 1930 1929
Note:
See TracChangeset
for help on using the changeset viewer.