- Timestamp:
- Mar 6, 2009 3:22:21 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r17432 r17434 1133 1133 * @param cbRange Physical range 1134 1134 * @param pR3Ptr Where to store the R3 pointer on success. 1135 * 1136 * @deprecated Avoid when possible! 1135 1137 */ 1136 1138 VMMDECL(int) PGMPhysGCPhys2R3Ptr(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange, PRTR3PTR pR3Ptr) 1137 1139 { 1138 1140 #ifdef VBOX_WITH_NEW_PHYS_CODE 1141 /** @todo this is kind of hacky and needs some more work. */ 1139 1142 VM_ASSERT_EMT(pVM); /* no longer safe for use outside the EMT thread! */ 1140 1143 … … 1202 1205 1203 1206 1207 #ifdef VBOX_STRICT 1204 1208 /** 1205 1209 * PGMPhysGCPhys2R3Ptr convenience for use with assertions. … … 1209 1213 * @param GCPhys The GC Physical addresss. 1210 1214 * @param cbRange Physical range. 1215 * 1216 * @deprecated Avoid when possible. 1211 1217 */ 1212 1218 VMMDECL(RTR3PTR) PGMPhysGCPhys2R3PtrAssert(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange) … … 1218 1224 return NIL_RTR3PTR; 1219 1225 } 1226 #endif /* VBOX_STRICT */ 1220 1227 1221 1228 … … 1269 1276 * @param pR3Ptr Where to store the R3 virtual address. 1270 1277 * 1271 * @deprecated 1278 * @deprecated Don't use this. 1272 1279 */ 1273 1280 VMMDECL(int) PGMPhysGCPtr2R3Ptr(PVM pVM, RTGCPTR GCPtr, PRTR3PTR pR3Ptr) … … 1755 1762 { 1756 1763 void *pvDst = NULL; 1764 int rc; 1757 1765 1758 1766 /* … … 1763 1771 * the heavy usage of full page handlers in the page pool. 1764 1772 */ 1765 if (!PGM_PAGE_HAS_ACTIVE_VIRTUAL_HANDLERS(pPage)) 1773 if ( !PGM_PAGE_HAS_ACTIVE_VIRTUAL_HANDLERS(pPage) 1774 || PGM_PAGE_IS_MMIO(pPage) /* screw virtual handlers on MMIO pages */) 1766 1775 { 1767 1776 PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys); … … 1776 1785 1777 1786 #ifdef IN_RING3 1778 int rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDst); 1787 if (!PGM_PAGE_IS_MMIO(pPage)) 1788 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDst); 1789 else 1790 rc = VINF_SUCCESS; 1779 1791 if (RT_SUCCESS(rc)) 1780 1792 { … … 1785 1797 memcpy(pvDst, pvBuf, cbRange); 1786 1798 else 1787 AssertLogRelMsg(rc == VINF_SUCCESS, ("rc=%Rrc GCPhys=%RGp %s\n", rc, GCPhys, pCur->pszDesc));1799 AssertLogRelMsg(rc == VINF_SUCCESS, ("rc=%Rrc GCPhys=%RGp pPage=%R[pgmpage] %s\n", rc, GCPhys, pPage, pCur->pszDesc)); 1788 1800 } 1789 1801 else 1790 AssertLogRelMsgFailed (("pgmPhysGCPhys2CCPtrInternal failed on %RGp / %R[pgmpage] -> %Rrc\n",1791 GCPhys, pPage, rc));1802 AssertLogRelMsgFailedReturnVoid(("pgmPhysGCPhys2CCPtrInternal failed on %RGp / %R[pgmpage] -> %Rrc\n", 1803 GCPhys, pPage, rc)); 1792 1804 #else 1793 1805 AssertReleaseMsgFailed(("Wrong API! GCPhys=%RGp cbRange=%#x\n", GCPhys, cbRange)); … … 1797 1809 1798 1810 /* more fun to be had below */ 1811 cbWrite -= cbRange; 1799 1812 GCPhys += cbRange; 1800 cbWrite -= cbRange;1801 1813 pvBuf = (uint8_t *)pvBuf + cbRange; 1814 pvDst = (uint8_t *)pvDst + cbRange; 1802 1815 } 1803 1816 /* else: the handler is somewhere else in the page, deal with it below. */ 1817 Assert(!PGM_PAGE_IS_MMIO(pPage)); /* MMIO handlers are all PAGE_SIZEed! */ 1804 1818 } 1805 1819 /* … … 1811 1825 unsigned iPage; 1812 1826 PPGMVIRTHANDLER pCur; 1813 intrc = pgmHandlerVirtualFindByPhysAddr(pVM, GCPhys, &pCur, &iPage);1827 rc = pgmHandlerVirtualFindByPhysAddr(pVM, GCPhys, &pCur, &iPage); 1814 1828 if (RT_SUCCESS(rc)) 1815 1829 { … … 1819 1833 1820 1834 #ifdef IN_RING3 1821 intrc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDst);1835 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDst); 1822 1836 if (RT_SUCCESS(rc)) 1823 1837 { … … 1836 1850 memcpy(pvDst, pvBuf, cbRange); 1837 1851 else 1838 AssertLogRelMsg(rc == VINF_SUCCESS, ("rc=%Rrc GCPhys=%RGp %s\n", rc, GCPhys, pCur->pszDesc));1852 AssertLogRelMsg(rc == VINF_SUCCESS, ("rc=%Rrc GCPhys=%RGp pPage=%R[pgmpage] %s\n", rc, GCPhys, pPage, pCur->pszDesc)); 1839 1853 } 1840 1854 else 1841 AssertLogRelMsgFailed (("pgmPhysGCPhys2CCPtrInternal failed on %RGp / %R[pgmpage] -> %Rrc\n",1842 GCPhys, pPage, rc));1855 AssertLogRelMsgFailedReturnVoid(("pgmPhysGCPhys2CCPtrInternal failed on %RGp / %R[pgmpage] -> %Rrc\n", 1856 GCPhys, pPage, rc)); 1843 1857 #else 1844 1858 AssertReleaseMsgFailed(("Wrong API! GCPhys=%RGp cb=%#x\n", GCPhys, cbRange)); … … 1848 1862 1849 1863 /* more fun to be had below */ 1864 cbWrite -= cbRange; 1850 1865 GCPhys += cbRange; 1851 cbWrite -= cbRange;1852 1866 pvBuf = (uint8_t *)pvBuf + cbRange; 1867 pvDst = (uint8_t *)pvDst + cbRange; 1853 1868 } 1854 1869 /* else: the handler is somewhere else in the page, deal with it below. */ … … 1858 1873 * Deal with all the odd ends. 1859 1874 */ 1860 while (cbWrite > 0) 1861 { 1862 AssertReleaseMsgFailed(("%RGp %#x %R[pgmpage]\n", GCPhys, cbWrite, pPage)); 1875 1876 /* We need a writable destination page. */ 1877 if (!pvDst) 1878 { 1879 rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDst); 1880 AssertLogRelMsgReturnVoid(RT_SUCCESS(rc), 1881 ("pgmPhysGCPhys2CCPtrInternal failed on %RGp / %R[pgmpage] -> %Rrc\n", 1882 GCPhys, pPage, rc)); 1883 } 1884 1885 /* The loop state (big + ugly). */ 1886 unsigned iVirtPage = 0; 1887 PPGMVIRTHANDLER pVirt = NULL; 1888 uint32_t offVirt = PAGE_SIZE; 1889 uint32_t offVirtLast = PAGE_SIZE; 1890 bool fMoreVirt = PGM_PAGE_HAS_ACTIVE_VIRTUAL_HANDLERS(pPage); 1891 1892 PPGMPHYSHANDLER pPhys = NULL; 1893 uint32_t offPhys = PAGE_SIZE; 1894 uint32_t offPhysLast = PAGE_SIZE; 1895 bool fMorePhys = PGM_PAGE_HAS_ACTIVE_PHYSICAL_HANDLERS(pPage); 1896 1897 /* The loop. */ 1898 for (;;) 1899 { 1900 /* 1901 * Find the closest handler above GCPhys. 1902 */ 1903 if (fMoreVirt && !pVirt) 1904 { 1905 int rc = pgmHandlerVirtualFindByPhysAddr(pVM, GCPhys, &pVirt, &iVirtPage); 1906 if (RT_SUCCESS(rc)) 1907 { 1908 offVirt = 0; 1909 offVirtLast = (pVirt->aPhysToVirt[iVirtPage].Core.KeyLast & PAGE_OFFSET_MASK) - (GCPhys & PAGE_OFFSET_MASK); 1910 } 1911 else 1912 { 1913 PPGMPHYS2VIRTHANDLER pVirtPhys; 1914 pVirtPhys = (PPGMPHYS2VIRTHANDLER)RTAvlroGCPhysGetBestFit(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysToVirtHandlers, 1915 GCPhys, true /* fAbove */); 1916 if (pVirtPhys) 1917 { 1918 /* ASSUME that pVirtPhys only covers one page. */ 1919 Assert((pVirtPhys->Core.Key >> PAGE_SHIFT) == (pVirtPhys->Core.KeyLast >> PAGE_SHIFT)); 1920 pVirt = (PPGMVIRTHANDLER)((uintptr_t)pVirtPhys + pVirtPhys->offVirtHandler); 1921 iVirtPage = pVirtPhys - &pVirt->aPhysToVirt[0]; Assert(iVirtPage == 0); 1922 offVirtLast = pVirtPhys->Core.KeyLast & PAGE_OFFSET_MASK - (GCPhys & PAGE_OFFSET_MASK); 1923 } 1924 else 1925 { 1926 pVirt = NULL; 1927 fMoreVirt = false; 1928 offVirt = offVirtLast = PAGE_SIZE; 1929 } 1930 } 1931 } 1932 1933 if (fMorePhys && !pPhys) 1934 { 1935 pPhys = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys); 1936 if (pPhys) 1937 { 1938 offPhys = 0; 1939 offPhysLast = pPhys->Core.KeyLast - GCPhys; /* ASSUMES < 4GB handlers... */ 1940 } 1941 else 1942 { 1943 pPhys = (PPGMPHYSHANDLER)RTAvlroGCPhysGetBestFit(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, 1944 GCPhys, true /* fAbove */); 1945 if ( pPhys 1946 && pPhys->Core.Key <= GCPhys + (cbWrite - 1)) 1947 { 1948 offPhys = pPhys->Core.Key - GCPhys; 1949 offPhysLast = pPhys->Core.KeyLast - GCPhys; /* ASSUMES < 4GB handlers... */ 1950 } 1951 else 1952 { 1953 pPhys = NULL; 1954 fMorePhys = false; 1955 offPhys = offPhysLast = PAGE_SIZE; 1956 } 1957 } 1958 } 1959 1960 /* 1961 * Handle access to space without handlers (that's easy). 1962 */ 1963 rc = VINF_PGM_HANDLER_DO_DEFAULT; 1964 size_t cbRange = cbWrite; 1965 if (offPhys && offVirt) 1966 { 1967 if (cbRange > offPhys) 1968 cbRange = offPhys; 1969 if (cbRange > offVirt) 1970 cbRange = offVirt; 1971 } 1972 /* 1973 * Physical handler. 1974 */ 1975 else if (!offPhys && offVirt) 1976 { 1977 if (cbRange > offPhysLast + 1) 1978 cbRange = offPhysLast + 1; 1979 if (cbRange > offVirt) 1980 cbRange = offVirt; 1981 #ifdef IN_RING3 1982 STAM_PROFILE_START(&pPhys->Stat, h); 1983 rc = pPhys->CTX_SUFF(pfnHandler)(pVM, GCPhys, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE, pPhys->CTX_SUFF(pvUser)); 1984 STAM_PROFILE_STOP(&pPhys->Stat, h); 1985 AssertLogRelMsg(rc != VINF_SUCCESS && rc != VINF_PGM_HANDLER_DO_DEFAULT, ("rc=%Rrc GCPhys=%RGp pPage=%R[pgmpage] %s\n", rc, GCPhys, pPage, pPhys->pszDesc)); 1986 #else 1987 AssertReleaseMsgFailed(("Wrong API! GCPhys=%RGp cbRange=%#x\n", GCPhys, cbRange)); 1988 #endif 1989 pPhys = NULL; 1990 } 1991 /* 1992 * Virtual handler. 1993 */ 1994 else if (offPhys && !offVirt) 1995 { 1996 if (cbRange > offVirtLast + 1) 1997 cbRange = offVirtLast + 1; 1998 if (cbRange > offPhys) 1999 cbRange = offPhys; 2000 #ifdef IN_RING3 2001 if (pVirt->pfnHandlerR3) 2002 { 2003 RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pVirt->Core.Key & PAGE_BASE_GC_MASK) 2004 + (iVirtPage << PAGE_SHIFT) 2005 + (GCPhys & PAGE_OFFSET_MASK); 2006 STAM_PROFILE_START(&pVirt->Stat, h); 2007 rc = pVirt->CTX_SUFF(pfnHandler)(pVM, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE, /*pCur->CTX_SUFF(pvUser)*/ NULL); 2008 STAM_PROFILE_STOP(&pVirt->Stat, h); 2009 AssertLogRelMsg(rc != VINF_SUCCESS && rc != VINF_PGM_HANDLER_DO_DEFAULT, ("rc=%Rrc GCPhys=%RGp pPage=%R[pgmpage] %s\n", rc, GCPhys, pPage, pVirt->pszDesc)); 2010 } 2011 #else 2012 AssertReleaseMsgFailed(("Wrong API! GCPhys=%RGp cb=%#x\n", GCPhys, cbRange)); 2013 #endif 2014 pVirt = NULL; 2015 } 2016 /* 2017 * Both... give the physical one priority. 2018 */ 2019 else 2020 { 2021 Assert(!offPhys && !offVirt); 2022 if (cbRange > offVirtLast + 1) 2023 cbRange = offVirtLast + 1; 2024 if (cbRange > offPhysLast + 1) 2025 cbRange = offPhysLast + 1; 2026 2027 #ifdef IN_RING3 2028 if (pVirt->pfnHandlerR3) 2029 Log(("pgmPhysWriteHandler: overlapping phys and virt handlers at %RGp %R[pgmpage]; cbRange=%#x\n", GCPhys, pPage, cbRange)); 2030 2031 STAM_PROFILE_START(&pPhys->Stat, h); 2032 rc = pPhys->CTX_SUFF(pfnHandler)(pVM, GCPhys, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE, pPhys->CTX_SUFF(pvUser)); 2033 STAM_PROFILE_STOP(&pPhys->Stat, h); 2034 AssertLogRelMsg(rc != VINF_SUCCESS && rc != VINF_PGM_HANDLER_DO_DEFAULT, ("rc=%Rrc GCPhys=%RGp pPage=%R[pgmpage] %s\n", rc, GCPhys, pPage, pPhys->pszDesc)); 2035 if (pVirt->pfnHandlerR3) 2036 { 2037 2038 RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pVirt->Core.Key & PAGE_BASE_GC_MASK) 2039 + (iVirtPage << PAGE_SHIFT) 2040 + (GCPhys & PAGE_OFFSET_MASK); 2041 STAM_PROFILE_START(&pVirt->Stat, h); 2042 int rc2 = pVirt->CTX_SUFF(pfnHandler)(pVM, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE, /*pCur->CTX_SUFF(pvUser)*/ NULL); 2043 STAM_PROFILE_STOP(&pVirt->Stat, h); 2044 AssertLogRelMsg(rc2 != VINF_SUCCESS && rc2 != VINF_PGM_HANDLER_DO_DEFAULT, ("rc=%Rrc GCPhys=%RGp pPage=%R[pgmpage] %s\n", rc, GCPhys, pPage, pVirt->pszDesc)); 2045 if (rc2 == VINF_SUCCESS && rc == VINF_PGM_HANDLER_DO_DEFAULT) 2046 rc = VINF_SUCCESS; 2047 } 2048 #else 2049 AssertReleaseMsgFailed(("Wrong API! GCPhys=%RGp cbRange=%#x\n", GCPhys, cbRange)); 2050 #endif 2051 pPhys = NULL; 2052 pVirt = NULL; 2053 } 2054 if (rc == VINF_PGM_HANDLER_DO_DEFAULT) 2055 memcpy(pvDst, pvBuf, cbRange); 2056 2057 /* 2058 * Advance if we've got more stuff to do. 2059 */ 2060 if (cbRange >= cbWrite) 2061 return; 2062 2063 cbWrite -= cbRange; 2064 GCPhys += cbRange; 2065 pvBuf = (uint8_t *)pvBuf + cbRange; 2066 pvDst = (uint8_t *)pvDst + cbRange; 2067 2068 offPhys -= cbRange; 2069 offPhysLast -= cbRange; 2070 offVirt -= cbRange; 2071 offVirtLast -= cbRange; 1863 2072 } 1864 2073 }
Note:
See TracChangeset
for help on using the changeset viewer.