- Timestamp:
- Jan 25, 2007 2:55:10 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 17851
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevPCNet.cpp
r252 r303 72 72 73 73 /* Enable this to catch writes to the ring descriptors instead of using excessive polling */ 74 / /#define PCNET_NO_POLLING74 /* #define PCNET_NO_POLLING */ 75 75 76 76 /* Enable to handle frequent io reads in the guest context */ … … 120 120 { 121 121 PCIDEVICE PciDev; 122 #ifndef PCNET_NO_POLLING 122 123 /** Poll timer (address for host context) */ 123 124 PTMTIMERHC pTimerPollHC; 124 125 /** Poll timer (address for guest context) */ 125 126 PTMTIMERGC pTimerPollGC; 126 127 #endif 127 128 /** Register Address Pointer */ 128 129 uint32_t u32RAP; … … 217 218 PDMCRITSECT CritSect; 218 219 220 #ifdef PCNET_NO_POLLING 221 RTGCPHYS TRDAPhysOld; 222 uint32_t cbTRDAOld; 223 224 RTGCPHYS RDRAPhysOld; 225 uint32_t cbRDRAOld; 226 227 DECLGCCALLBACKMEMBER(int, pfnEMInterpretInstructionGC, (PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize)); 228 DECLR0CALLBACKMEMBER(int, pfnEMInterpretInstructionR0, (PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize)); 229 #endif 230 219 231 bool fGCEnabled; 220 232 bool fR0Enabled; … … 247 259 STAMCOUNTER StatTXRingWrite; 248 260 STAMCOUNTER StatRingWriteHC; 261 STAMCOUNTER StatRingWriteR0; 249 262 STAMCOUNTER StatRingWriteGC; 263 264 STAMCOUNTER StatRingWriteFailedHC; 265 STAMCOUNTER StatRingWriteFailedR0; 266 STAMCOUNTER StatRingWriteFailedGC; 267 268 STAMCOUNTER StatRingWriteOutsideRangeHC; 269 STAMCOUNTER StatRingWriteOutsideRangeR0; 270 STAMCOUNTER StatRingWriteOutsideRangeGC; 250 271 # endif 251 272 #endif /* VBOX_WITH_STATISTICS */ … … 921 942 RTGCPHYS GCPhysAddr, void *pv, unsigned cb); 922 943 #ifndef IN_RING3 923 DECLEXPORT(int) pcnetHandleRingWrite GC(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame,924 944 DECLEXPORT(int) pcnetHandleRingWrite(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, 945 RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser); 925 946 #endif 926 947 __END_DECLS … … 933 954 static void pcnetPollRxTx(PCNetState *pData); 934 955 static void pcnetPollTimer(PCNetState *pData); 956 static void pcnetUpdateIrq(PCNetState *pData); 935 957 static uint32_t pcnetBCRReadU16(PCNetState *pData, uint32_t u32RAP); 936 958 static int pcnetBCRWriteU16(PCNetState *pData, uint32_t u32RAP, uint32_t val); … … 951 973 * @param pvUser User argument. 952 974 */ 953 DECLEXPORT(int) pcnetHandleRingWriteGC(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, 954 RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser) 955 { 956 PPDMDEVINS pDevIns = (PPDMDEVINS)pvUser; 957 PCNetState *pData = PDMINS2DATA(pDevIns, PCNetState *); 975 DECLEXPORT(int) pcnetHandleRingWrite(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, 976 RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser) 977 { 978 PCNetState *pData = (PCNetState *)pvUser; 958 979 959 980 Log(("#%d pcnetHandleRingWriteGC: write to %08x\n", PCNETSTATE_2_DEVINS(pData)->iInstance, GCPhysFault)); 960 STAM_COUNTER_INC(&CTXSUFF(pData->StatRingWrite)); NOREF(pData); 981 982 uint32_t cb; 983 int rc = CTXALLSUFF(pData->pfnEMInterpretInstruction)(pVM, pRegFrame, pvFault, &cb); 984 if (VBOX_SUCCESS(rc) && cb) 985 { 986 if (GCPhysFault >= pData->GCTDRA && GCPhysFault + cb < pcnetTdraAddr(pData, 0)) 987 { 988 int rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY); 989 if (VBOX_SUCCESS(rc)) 990 { 991 STAM_COUNTER_INC(&CTXALLSUFF(pData->StatRingWrite)); ; 992 993 /* Check if we can do something now */ 994 pcnetPollRxTx(pData); 995 996 PDMCritSectLeave(&pData->CritSect); 997 return VINF_SUCCESS; 998 } 999 } 1000 else 1001 { 1002 STAM_COUNTER_INC(&CTXALLSUFF(pData->StatRingWriteOutsideRange)); ; 1003 return VINF_SUCCESS; /* outside of the ring range */ 1004 } 1005 } 1006 STAM_COUNTER_INC(&CTXALLSUFF(pData->StatRingWriteFailed)); ; 961 1007 return VINF_IOM_HC_MMIO_WRITE; /* handle in ring3 */ 962 1008 } … … 1003 1049 AssertReleaseRC(rc); 1004 1050 /* Check if we can do something now */ 1005 pcnetPollTimer(pData); 1051 pcnetPollRxTx(pData); 1052 pcnetUpdateIrq(pData); 1006 1053 PDMCritSectLeave(&pData->CritSect); 1007 1054 } … … 1143 1190 #ifdef IN_RING3 1144 1191 #ifdef PCNET_NO_POLLING 1145 static void pcnetUpdateRingHandlers(PCNetState *pData, 1146 RTGCPHYS oldrdra, uint16_t oldrcvrl, 1147 RTGCPHYS oldtdra, uint16_t oldxmtrl) 1192 static void pcnetUpdateRingHandlers(PCNetState *pData) 1148 1193 { 1149 1194 PPDMDEVINS pDevIns = PCNETSTATE_2_DEVINS(pData); 1195 1196 Log(("pcnetUpdateRingHandlers TD %VGp size %x -> %VGp size %x\n", pData->TRDAPhysOld, pData->cbTRDAOld, pData->GCTDRA, pcnetTdraAddr(pData, 0))); 1197 Log(("pcnetUpdateRingHandlers RX %VGp size %x -> %VGp size %x\n", pData->RDRAPhysOld, pData->cbRDRAOld, pData->GCRDRA, pcnetRdraAddr(pData, 0))); 1198 1150 1199 #if 0 1151 if ( oldrdra != 0 && pData->GCRDRA != oldrdra)1200 if (pData->RDRAPhysOld != 0 && pData->GCRDRA != pData->RDRAPhysOld) 1152 1201 PGMHandlerPhysicalDeregister(pDevIns->pDevHlp->pfnGetVM(pDevIns), 1153 oldrdra& ~PAGE_OFFSET_MASK);1154 if ( oldtdra != 0 && pData->GCTDRA != oldtdra1202 pData->RDRAPhysOld & ~PAGE_OFFSET_MASK); 1203 if ( pData->TRDAPhysOld != 0 && pData->GCTDRA != pData->TRDAPhysOld 1155 1204 && (pData->GCRDRA & ~PAGE_OFFSET_MASK) != (pData->GCTDRA & ~PAGE_OFFSET_MASK)) 1156 1205 #endif … … 1164 1213 RT_ALIGN(pcnetRdraAddr(pData, 0), PAGE_SIZE) - 1, 1165 1214 pcnetHandleRingWrite, pDevIns, 1166 g_DevicePCNet.szR0Mod, "pcnetHandleRingWrite GC",1215 g_DevicePCNet.szR0Mod, "pcnetHandleRingWrite", 1167 1216 pData->pDevInsHC->pvInstanceDataHC, 1168 g_DevicePCNet.szGCMod, "pcnetHandleRingWrite GC",1217 g_DevicePCNet.szGCMod, "pcnetHandleRingWrite", 1169 1218 pData->pDevInsHC->pvInstanceDataGC, 1170 1219 "PCNet receive ring write access handler"); 1171 1220 AssertRC(rc); 1172 } 1173 #endif 1174 if (pData->GCTDRA != oldtdra || CSR_XMTRL(pData) != oldxmtrl) 1175 { 1176 if (oldtdra != 0) 1221 1222 pData->RDRAPhysOld = pData->GCRDRA; 1223 pData->cbRDRAOld = pcnetRdraAddr(pData, 0); 1224 } 1225 #endif 1226 if (pData->GCTDRA != pData->TRDAPhysOld || CSR_XMTRL(pData) != pData->cbTRDAOld) 1227 { 1228 if (pData->TRDAPhysOld != 0) 1177 1229 PGMHandlerPhysicalDeregister(pDevIns->pDevHlp->pfnGetVM(pDevIns), 1178 oldtdra & ~PAGE_OFFSET_MASK); 1230 pData->TRDAPhysOld & ~PAGE_OFFSET_MASK); 1231 1179 1232 int rc; 1233 1180 1234 rc = PGMR3HandlerPhysicalRegister(pDevIns->pDevHlp->pfnGetVM(pDevIns), 1181 1235 PGMPHYSHANDLERTYPE_PHYSICAL_WRITE, … … 1183 1237 RT_ALIGN(pcnetTdraAddr(pData, 0), PAGE_SIZE) - 1, 1184 1238 pcnetHandleRingWrite, pDevIns, 1185 g_DevicePCNet.szR0Mod, "pcnetHandleRingWrite GC",1239 g_DevicePCNet.szR0Mod, "pcnetHandleRingWrite", 1186 1240 pData->pDevInsHC->pvInstanceDataHC, 1187 g_DevicePCNet.szGCMod, "pcnetHandleRingWrite GC",1241 g_DevicePCNet.szGCMod, "pcnetHandleRingWrite", 1188 1242 pData->pDevInsHC->pvInstanceDataGC, 1189 1243 "PCNet transmit ring write access handler"); 1190 1244 AssertRC(rc); 1245 1246 pData->TRDAPhysOld = pData->GCTDRA; 1247 pData->cbTRDAOld = pcnetTdraAddr(pData, 0); 1191 1248 } 1192 1249 } … … 1196 1253 { 1197 1254 PPDMDEVINS pDevIns = PCNETSTATE_2_DEVINS(pData); 1198 #ifdef PCNET_NO_POLLING1199 RTGCPHYS oldrdra = pData->GCRDRA, oldtdra = pData->GCTDRA;1200 uint16_t oldrcvrl = CSR_RCVRL(pData), oldxmtrl = CSR_XMTRL(pData);1201 #endif1202 1255 Log(("#%d pcnetInit: init_addr=0x%08x\n", PCNETSTATE_2_DEVINS(pData)->iInstance, 1203 1256 PHYSADDR(pData, CSR_IADR(pData)))); … … 1249 1302 1250 1303 #ifdef PCNET_NO_POLLING 1251 pcnetUpdateRingHandlers(pData , oldrdra, oldrcvrl, oldtdra, oldxmtrl);1304 pcnetUpdateRingHandlers(pData); 1252 1305 #endif 1253 1306 … … 2085 2138 * but so far I have not seen any guest depending on these values. The 2ms 2086 2139 * interval is the default polling interval of the PCNet card (65536/33MHz). */ 2140 #ifdef PCNET_NO_POLLING 2141 pcnetPollRxTx(pData); 2142 #else 2087 2143 uint64_t u64Now = TMTimerGet(pData->CTXSUFF(pTimerPoll)); 2088 2144 if (RT_UNLIKELY(u64Now - pData->u64LastPoll > 200000)) … … 2095 2151 TMTimerSet(pData->CTXSUFF(pTimerPoll), 2096 2152 TMTimerGet(pData->CTXSUFF(pTimerPoll)) + 2000000); 2153 #endif 2097 2154 } 2098 2155 STAM_PROFILE_ADV_STOP(&pData->StatPollTimer, a); … … 3432 3489 SSMR3PutMem(pSSMHandle, &pData->MacConfigured, sizeof(pData->MacConfigured)); 3433 3490 SSMR3PutBool(pSSMHandle, pData->fAm79C973); 3491 #ifdef PCNET_NO_POLLING 3492 return VINF_SUCCESS; 3493 #else 3434 3494 return TMR3TimerSave(pData->CTXSUFF(pTimerPoll), pSSMHandle); 3495 #endif 3435 3496 } 3436 3497 … … 3466 3527 Assert(!memcmp(&Mac, &pData->MacConfigured, sizeof(Mac))); 3467 3528 SSMR3GetBool(pSSMHandle, &pData->fAm79C973); 3529 #ifndef PCNET_NO_POLLING 3468 3530 TMR3TimerLoad(pData->CTXSUFF(pTimerPoll), pSSMHandle); 3531 #endif 3469 3532 3470 3533 pData->iLog2DescSize = BCR_SWSTYLE(pData) … … 3708 3771 PCNetState *pData = PDMINS2DATA(pDevIns, PCNetState *); 3709 3772 pData->pDevInsGC = PDMDEVINS_2_GCPTR(pDevIns); 3710 pData->pTimerPollGC = TMTimerGCPtr(pData->pTimerPollHC);3711 3773 pData->pXmitQueueGC = PDMQueueGCPtr(pData->pXmitQueueHC); 3712 3774 pData->pCanRxQueueGC = PDMQueueGCPtr(pData->pCanRxQueueHC); 3775 #ifdef PCNET_NO_POLLING 3776 *(RTHCUINTPTR *)&pData->pfnEMInterpretInstructionGC += offDelta; 3777 #else 3778 pData->pTimerPollGC = TMTimerGCPtr(pData->pTimerPollHC); 3779 #endif 3713 3780 } 3714 3781 … … 3873 3940 return rc; 3874 3941 3942 #ifdef PCNET_NO_POLLING 3943 rc = PDMR3GetSymbolR0Lazy(pDevIns->pDevHlp->pfnGetVM(pDevIns), NULL, "EMInterpretInstruction", (void **)&pData->pfnEMInterpretInstructionR0); 3944 if (VBOX_SUCCESS(rc)) 3945 { 3946 /* 3947 * Resolve the GC handler. 3948 */ 3949 RTGCPTR pfnHandlerGC; 3950 rc = PDMR3GetSymbolGCLazy(pDevIns->pDevHlp->pfnGetVM(pDevIns), NULL, "EMInterpretInstruction", (RTGCPTR *)&pData->pfnEMInterpretInstructionGC); 3951 } 3952 if (VBOX_FAILURE(rc)) 3953 { 3954 AssertMsgFailed(("PDMR3GetSymbolGCLazy -> %Vrc\n", rc)); 3955 return rc; 3956 } 3957 #else 3875 3958 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimer, 3876 3959 "PCNet Poll Timer", &pData->pTimerPollHC); … … 3880 3963 return rc; 3881 3964 } 3965 #endif 3882 3966 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimerRestore, 3883 3967 "PCNet Restore Timer", &pData->pTimerRestore); … … 3996 4080 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRCVRingWrite, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of receive ring writes", "/Devices/PCNet%d/Ring/RCVWrites", iInstance); 3997 4081 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatTXRingWrite, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of transmit ring writes", "/Devices/PCNet%d/Ring/TXWrites", iInstance); 3998 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteHC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of monitored ring page writes", "/Devices/PCNet%d/Ring/HCWrites", iInstance); 3999 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteGC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of monitored ring page writes", "/Devices/PCNet%d/Ring/GCWrites", iInstance); 4082 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteHC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of monitored ring page writes", "/Devices/PCNet%d/Ring/HC/Writes", iInstance); 4083 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteR0, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of monitored ring page writes", "/Devices/PCNet%d/Ring/R0/Writes", iInstance); 4084 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteGC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of monitored ring page writes", "/Devices/PCNet%d/Ring/GC/Writes", iInstance); 4085 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteFailedHC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of failed ring page writes", "/Devices/PCNet%d/Ring/HC/Failed", iInstance); 4086 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteFailedR0, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of failed ring page writes", "/Devices/PCNet%d/Ring/R0/Failed", iInstance); 4087 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteFailedGC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of failed ring page writes", "/Devices/PCNet%d/Ring/GC/Failed", iInstance); 4088 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteOutsideRangeHC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of monitored writes outside ring range", "/Devices/PCNet%d/Ring/HC/Outside", iInstance); 4089 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteOutsideRangeR0, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of monitored writes outside ring range", "/Devices/PCNet%d/Ring/R0/Outside", iInstance); 4090 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteOutsideRangeGC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of monitored writes outside ring range", "/Devices/PCNet%d/Ring/GC/Outside", iInstance); 4000 4091 # endif /* PCNET_NO_POLLING */ 4001 4092 #endif
Note:
See TracChangeset
for help on using the changeset viewer.