Changeset 71456 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Mar 22, 2018 2:08:12 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 121425
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevE1000.cpp
r71190 r71456 1783 1783 1784 1784 1785 #if defined(E1K_WITH_RXD_CACHE) && defined(IN_RING3) /* currently only used in ring-3 due to stack space requirements of the caller */ 1785 #ifdef E1K_WITH_RXD_CACHE 1786 /** 1787 * Return the number of RX descriptor that belong to the hardware. 1788 * 1789 * @returns the number of available descriptors in RX ring. 1790 * @param pThis The device state structure. 1791 * @thread ??? 1792 */ 1793 DECLINLINE(uint32_t) e1kGetRxLen(PE1KSTATE pThis) 1794 { 1795 /** 1796 * Make sure RDT won't change during computation. EMT may modify RDT at 1797 * any moment. 1798 */ 1799 uint32_t rdt = RDT; 1800 return (RDH > rdt ? RDLEN/sizeof(E1KRXDESC) : 0) + rdt - RDH; 1801 } 1802 1803 DECLINLINE(unsigned) e1kRxDInCache(PE1KSTATE pThis) 1804 { 1805 return pThis->nRxDFetched > pThis->iRxDCurrent ? 1806 pThis->nRxDFetched - pThis->iRxDCurrent : 0; 1807 } 1808 1809 DECLINLINE(unsigned) e1kRxDIsCacheEmpty(PE1KSTATE pThis) 1810 { 1811 return pThis->iRxDCurrent >= pThis->nRxDFetched; 1812 } 1813 1814 /** 1815 * Load receive descriptors from guest memory. The caller needs to be in Rx 1816 * critical section. 1817 * 1818 * We need two physical reads in case the tail wrapped around the end of RX 1819 * descriptor ring. 1820 * 1821 * @returns the actual number of descriptors fetched. 1822 * @param pThis The device state structure. 1823 * @param pDesc Pointer to descriptor union. 1824 * @param addr Physical address in guest context. 1825 * @thread EMT, RX 1826 */ 1827 DECLINLINE(unsigned) e1kRxDPrefetch(PE1KSTATE pThis) 1828 { 1829 /* We've already loaded pThis->nRxDFetched descriptors past RDH. */ 1830 unsigned nDescsAvailable = e1kGetRxLen(pThis) - e1kRxDInCache(pThis); 1831 unsigned nDescsToFetch = RT_MIN(nDescsAvailable, E1K_RXD_CACHE_SIZE - pThis->nRxDFetched); 1832 unsigned nDescsTotal = RDLEN / sizeof(E1KRXDESC); 1833 Assert(nDescsTotal != 0); 1834 if (nDescsTotal == 0) 1835 return 0; 1836 unsigned nFirstNotLoaded = (RDH + e1kRxDInCache(pThis)) % nDescsTotal; 1837 unsigned nDescsInSingleRead = RT_MIN(nDescsToFetch, nDescsTotal - nFirstNotLoaded); 1838 E1kLog3(("%s e1kRxDPrefetch: nDescsAvailable=%u nDescsToFetch=%u " 1839 "nDescsTotal=%u nFirstNotLoaded=0x%x nDescsInSingleRead=%u\n", 1840 pThis->szPrf, nDescsAvailable, nDescsToFetch, nDescsTotal, 1841 nFirstNotLoaded, nDescsInSingleRead)); 1842 if (nDescsToFetch == 0) 1843 return 0; 1844 E1KRXDESC* pFirstEmptyDesc = &pThis->aRxDescriptors[pThis->nRxDFetched]; 1845 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), 1846 ((uint64_t)RDBAH << 32) + RDBAL + nFirstNotLoaded * sizeof(E1KRXDESC), 1847 pFirstEmptyDesc, nDescsInSingleRead * sizeof(E1KRXDESC)); 1848 // uint64_t addrBase = ((uint64_t)RDBAH << 32) + RDBAL; 1849 // unsigned i, j; 1850 // for (i = pThis->nRxDFetched; i < pThis->nRxDFetched + nDescsInSingleRead; ++i) 1851 // { 1852 // pThis->aRxDescAddr[i] = addrBase + (nFirstNotLoaded + i - pThis->nRxDFetched) * sizeof(E1KRXDESC); 1853 // E1kLog3(("%s aRxDescAddr[%d] = %p\n", pThis->szPrf, i, pThis->aRxDescAddr[i])); 1854 // } 1855 E1kLog3(("%s Fetched %u RX descriptors at %08x%08x(0x%x), RDLEN=%08x, RDH=%08x, RDT=%08x\n", 1856 pThis->szPrf, nDescsInSingleRead, 1857 RDBAH, RDBAL + RDH * sizeof(E1KRXDESC), 1858 nFirstNotLoaded, RDLEN, RDH, RDT)); 1859 if (nDescsToFetch > nDescsInSingleRead) 1860 { 1861 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), 1862 ((uint64_t)RDBAH << 32) + RDBAL, 1863 pFirstEmptyDesc + nDescsInSingleRead, 1864 (nDescsToFetch - nDescsInSingleRead) * sizeof(E1KRXDESC)); 1865 // Assert(i == pThis->nRxDFetched + nDescsInSingleRead); 1866 // for (j = 0; i < pThis->nRxDFetched + nDescsToFetch; ++i, ++j) 1867 // { 1868 // pThis->aRxDescAddr[i] = addrBase + j * sizeof(E1KRXDESC); 1869 // E1kLog3(("%s aRxDescAddr[%d] = %p\n", pThis->szPrf, i, pThis->aRxDescAddr[i])); 1870 // } 1871 E1kLog3(("%s Fetched %u RX descriptors at %08x%08x\n", 1872 pThis->szPrf, nDescsToFetch - nDescsInSingleRead, 1873 RDBAH, RDBAL)); 1874 } 1875 pThis->nRxDFetched += nDescsToFetch; 1876 return nDescsToFetch; 1877 } 1878 1879 # ifdef IN_RING3 /* currently only used in ring-3 due to stack space requirements of the caller */ 1786 1880 /** 1787 1881 * Dump receive descriptor to debug log. … … 1813 1907 E1K_SPEC_PRI(pDesc->status.u16Special))); 1814 1908 } 1815 #endif /* E1K_WITH_RXD_CACHE && IN_RING3 */ 1909 # endif /* IN_RING3 */ 1910 #endif /* E1K_WITH_RXD_CACHE */ 1816 1911 1817 1912 /** … … 2005 2100 if (++RDH * sizeof(E1KRXDESC) >= RDLEN) 2006 2101 RDH = 0; 2102 #ifdef E1K_WITH_RXD_CACHE 2103 /* 2104 * We need to fetch descriptors now as the guest may advance RDT all the way 2105 * to RDH as soon as we generate RXDMT0 interrupt. This is mostly to provide 2106 * compatibility with Phar Lap ETS, see @bugref(7346). Note that we do not 2107 * check if the receiver is enabled. It must be, otherwise we won't get here 2108 * in the first place. 2109 * 2110 * Note that we should have moved both RDH and iRxDCurrent by now. 2111 */ 2112 if (e1kRxDIsCacheEmpty(pThis)) 2113 { 2114 /* Cache is empty, reset it and check if we can fetch more. */ 2115 pThis->iRxDCurrent = pThis->nRxDFetched = 0; 2116 E1kLog3(("%s e1kAdvanceRDH: Rx cache is empty, RDH=%x RDT=%x " 2117 "iRxDCurrent=%x nRxDFetched=%x\n", 2118 pThis->szPrf, RDH, RDT, pThis->iRxDCurrent, pThis->nRxDFetched)); 2119 e1kRxDPrefetch(pThis); 2120 } 2121 #endif /* E1K_WITH_RXD_CACHE */ 2007 2122 /* 2008 2123 * Compute current receive queue length and fire RXDMT0 interrupt … … 2034 2149 #ifdef E1K_WITH_RXD_CACHE 2035 2150 2036 /**2037 * Return the number of RX descriptor that belong to the hardware.2038 *2039 * @returns the number of available descriptors in RX ring.2040 * @param pThis The device state structure.2041 * @thread ???2042 */2043 DECLINLINE(uint32_t) e1kGetRxLen(PE1KSTATE pThis)2044 {2045 /**2046 * Make sure RDT won't change during computation. EMT may modify RDT at2047 * any moment.2048 */2049 uint32_t rdt = RDT;2050 return (RDH > rdt ? RDLEN/sizeof(E1KRXDESC) : 0) + rdt - RDH;2051 }2052 2053 DECLINLINE(unsigned) e1kRxDInCache(PE1KSTATE pThis)2054 {2055 return pThis->nRxDFetched > pThis->iRxDCurrent ?2056 pThis->nRxDFetched - pThis->iRxDCurrent : 0;2057 }2058 2059 DECLINLINE(unsigned) e1kRxDIsCacheEmpty(PE1KSTATE pThis)2060 {2061 return pThis->iRxDCurrent >= pThis->nRxDFetched;2062 }2063 2064 /**2065 * Load receive descriptors from guest memory. The caller needs to be in Rx2066 * critical section.2067 *2068 * We need two physical reads in case the tail wrapped around the end of RX2069 * descriptor ring.2070 *2071 * @returns the actual number of descriptors fetched.2072 * @param pThis The device state structure.2073 * @param pDesc Pointer to descriptor union.2074 * @param addr Physical address in guest context.2075 * @thread EMT, RX2076 */2077 DECLINLINE(unsigned) e1kRxDPrefetch(PE1KSTATE pThis)2078 {2079 /* We've already loaded pThis->nRxDFetched descriptors past RDH. */2080 unsigned nDescsAvailable = e1kGetRxLen(pThis) - e1kRxDInCache(pThis);2081 unsigned nDescsToFetch = RT_MIN(nDescsAvailable, E1K_RXD_CACHE_SIZE - pThis->nRxDFetched);2082 unsigned nDescsTotal = RDLEN / sizeof(E1KRXDESC);2083 Assert(nDescsTotal != 0);2084 if (nDescsTotal == 0)2085 return 0;2086 unsigned nFirstNotLoaded = (RDH + e1kRxDInCache(pThis)) % nDescsTotal;2087 unsigned nDescsInSingleRead = RT_MIN(nDescsToFetch, nDescsTotal - nFirstNotLoaded);2088 E1kLog3(("%s e1kRxDPrefetch: nDescsAvailable=%u nDescsToFetch=%u "2089 "nDescsTotal=%u nFirstNotLoaded=0x%x nDescsInSingleRead=%u\n",2090 pThis->szPrf, nDescsAvailable, nDescsToFetch, nDescsTotal,2091 nFirstNotLoaded, nDescsInSingleRead));2092 if (nDescsToFetch == 0)2093 return 0;2094 E1KRXDESC* pFirstEmptyDesc = &pThis->aRxDescriptors[pThis->nRxDFetched];2095 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns),2096 ((uint64_t)RDBAH << 32) + RDBAL + nFirstNotLoaded * sizeof(E1KRXDESC),2097 pFirstEmptyDesc, nDescsInSingleRead * sizeof(E1KRXDESC));2098 // uint64_t addrBase = ((uint64_t)RDBAH << 32) + RDBAL;2099 // unsigned i, j;2100 // for (i = pThis->nRxDFetched; i < pThis->nRxDFetched + nDescsInSingleRead; ++i)2101 // {2102 // pThis->aRxDescAddr[i] = addrBase + (nFirstNotLoaded + i - pThis->nRxDFetched) * sizeof(E1KRXDESC);2103 // E1kLog3(("%s aRxDescAddr[%d] = %p\n", pThis->szPrf, i, pThis->aRxDescAddr[i]));2104 // }2105 E1kLog3(("%s Fetched %u RX descriptors at %08x%08x(0x%x), RDLEN=%08x, RDH=%08x, RDT=%08x\n",2106 pThis->szPrf, nDescsInSingleRead,2107 RDBAH, RDBAL + RDH * sizeof(E1KRXDESC),2108 nFirstNotLoaded, RDLEN, RDH, RDT));2109 if (nDescsToFetch > nDescsInSingleRead)2110 {2111 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns),2112 ((uint64_t)RDBAH << 32) + RDBAL,2113 pFirstEmptyDesc + nDescsInSingleRead,2114 (nDescsToFetch - nDescsInSingleRead) * sizeof(E1KRXDESC));2115 // Assert(i == pThis->nRxDFetched + nDescsInSingleRead);2116 // for (j = 0; i < pThis->nRxDFetched + nDescsToFetch; ++i, ++j)2117 // {2118 // pThis->aRxDescAddr[i] = addrBase + j * sizeof(E1KRXDESC);2119 // E1kLog3(("%s aRxDescAddr[%d] = %p\n", pThis->szPrf, i, pThis->aRxDescAddr[i]));2120 // }2121 E1kLog3(("%s Fetched %u RX descriptors at %08x%08x\n",2122 pThis->szPrf, nDescsToFetch - nDescsInSingleRead,2123 RDBAH, RDBAL));2124 }2125 pThis->nRxDFetched += nDescsToFetch;2126 return nDescsToFetch;2127 }2128 2129 2151 # ifdef IN_RING3 /* currently only used in ring-3 due to stack space requirements of the caller */ 2130 2152 … … 2175 2197 e1kDescAddr(RDBAH, RDBAL, RDH), 2176 2198 pDesc, sizeof(E1KRXDESC)); 2199 /* 2200 * We need to print the descriptor before advancing RDH as it may fetch new 2201 * descriptors into the cache. 2202 */ 2203 e1kPrintRDesc(pThis, pDesc); 2177 2204 e1kAdvanceRDH(pThis); 2178 e1kPrintRDesc(pThis, pDesc);2179 2205 } 2180 2206 … … 2197 2223 } 2198 2224 2199 # endif 2225 # endif /* IN_RING3 */ 2200 2226 2201 2227 #else /* !E1K_WITH_RXD_CACHE */ … … 3184 3210 { 3185 3211 E1kLog(("%s e1kRegWriteRDT\n", pThis->szPrf)); 3212 #ifndef E1K_WITH_RXD_CACHE 3186 3213 /* 3187 3214 * Some drivers advance RDT too far, so that it equals RDH. This … … 3198 3225 value = RDH - 1; 3199 3226 } 3227 #endif /* !E1K_WITH_RXD_CACHE */ 3200 3228 rc = e1kRegWriteDefault(pThis, offset, index, value); 3201 3229 #ifdef E1K_WITH_RXD_CACHE
Note:
See TracChangeset
for help on using the changeset viewer.