- Timestamp:
- Feb 23, 2007 8:38:37 PM (18 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/tm.h
r443 r1057 34 34 /** Enable a timer hack which improves the timer response/resolution a bit. */ 35 35 #define VBOX_HIGH_RES_TIMERS_HACK 36 37 /** Use the real CPU TSC. */38 #define TM_REAL_CPU_TICK39 36 40 37 -
trunk/src/VBox/VMM/EM.cpp
r1055 r1057 3217 3217 rc = TMVirtualResume(pVM); 3218 3218 Assert(rc == VINF_SUCCESS); 3219 rc = TMCpuTickResume(pVM); 3220 Assert(rc == VINF_SUCCESS); 3219 3221 3220 3222 /* … … 3336 3338 Log2(("EMR3ExecuteVM: returns VINF_EM_OFF (%d -> %d)\n", pVM->em.s.enmState, EMSTATE_TERMINATING)); 3337 3339 TMVirtualPause(pVM); 3340 TMCpuTickPause(pVM); 3338 3341 VMMR3Unlock(pVM); 3339 3342 STAM_PROFILE_ADV_STOP(&pVM->em.s.StatTotal, x); … … 3347 3350 Log(("EMR3ExecuteVM returns VINF_EM_TERMINATE (%d -> %d)\n", pVM->em.s.enmState, EMSTATE_TERMINATING)); 3348 3351 TMVirtualPause(pVM); 3352 TMCpuTickPause(pVM); 3349 3353 STAM_PROFILE_ADV_STOP(&pVM->em.s.StatTotal, x); 3350 3354 return rc; … … 3455 3459 case EMSTATE_SUSPENDED: 3456 3460 TMVirtualPause(pVM); 3461 TMCpuTickPause(pVM); 3457 3462 VMMR3Unlock(pVM); 3458 3463 STAM_PROFILE_ADV_STOP(&pVM->em.s.StatTotal, x); … … 3465 3470 case EMSTATE_DEBUG_GUEST_RAW: 3466 3471 TMVirtualPause(pVM); 3472 TMCpuTickPause(pVM); 3467 3473 rc = emR3Debug(pVM, rc); 3468 3474 TMVirtualResume(pVM); 3475 TMCpuTickResume(pVM); 3469 3476 Log2(("EMR3ExecuteVM: enmr3Debug -> %Vrc (state %d)\n", rc, pVM->em.s.enmState)); 3470 3477 break; … … 3476 3483 { 3477 3484 TMVirtualPause(pVM); 3485 TMCpuTickPause(pVM); 3478 3486 STAM_PROFILE_ADV_STOP(&pVM->em.s.StatTotal, x); 3479 3487 … … 3490 3498 STAM_PROFILE_ADV_START(&pVM->em.s.StatTotal, x); 3491 3499 TMVirtualResume(pVM); 3500 TMCpuTickResume(pVM); 3492 3501 break; 3493 3502 } … … 3500 3509 /** @todo this ain't entirely safe. make a better return code check and specify this in DBGF/emR3Debug. */ 3501 3510 TMVirtualPause(pVM); 3511 TMCpuTickPause(pVM); 3502 3512 VMMR3FatalDump(pVM, rc); 3503 3513 int rc2 = emR3Debug(pVM, rc); … … 3510 3520 } 3511 3521 TMVirtualResume(pVM); 3522 TMCpuTickResume(pVM); 3512 3523 rc = rc2; 3513 3524 /** @todo we're not doing the right thing in emR3Debug and will cause code to be executed on disconnect and stuff.. */ … … 3525 3536 pVM->em.s.enmState = EMSTATE_GURU_MEDITATION; 3526 3537 TMVirtualPause(pVM); 3538 TMCpuTickPause(pVM); 3527 3539 VMMR3Unlock(pVM); 3528 3540 STAM_PROFILE_ADV_STOP(&pVM->em.s.StatTotal, x); … … 3538 3550 LogFlow(("EMR3ExecuteVM: returns %Vrc (longjmp / fatal error)\n", rc)); 3539 3551 TMVirtualPause(pVM); 3552 TMCpuTickPause(pVM); 3540 3553 VMMR3FatalDump(pVM, rc); 3541 3554 emR3Debug(pVM, rc); -
trunk/src/VBox/VMM/TM.cpp
r1027 r1057 97 97 static DECLCALLBACK(void) tmR3TimerInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs); 98 98 static DECLCALLBACK(void) tmR3TimerInfoActive(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs); 99 static DECLCALLBACK(void) tmR3InfoClocks(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs); 99 100 100 101 … … 178 179 179 180 /* 180 * Calibrate the cpu timestamp counter. 181 */ 182 pVM->tm.s.cTSCTicksPerSecond = tmR3Calibrate(); 183 Log(("TM: cTSCTicksPerSecond=%#RX64 (%RU64)\n", pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.cTSCTicksPerSecond)); 181 * Determin the TSC configuration and frequency. 182 */ 183 /* mode */ 184 rc = CFGMR3QueryBool(CFGMR3GetRoot(pVM), "TSCVirtualized", &pVM->tm.s.fTSCVirtualized); 185 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 186 #if 0 /* seems to kind of work... */ 187 pVM->tm.s.fTSCVirtualized = true; 188 #else 189 pVM->tm.s.fTSCVirtualized = false; 190 #endif 191 else if (VBOX_FAILURE(rc)) 192 return VMSetError(pVM, rc, RT_SRC_POS, 193 N_("Configuration error: Failed to querying bool value \"UseRealTSC\". (%Vrc)"), rc); 194 195 /* source */ 196 rc = CFGMR3QueryBool(CFGMR3GetRoot(pVM), "UseRealTSC", &pVM->tm.s.fTSCTicking); 197 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 198 #if 1 /* doesn't seem to work reliably yet... xp takes several ~2 min to shutdown now. darn. */ 199 pVM->tm.s.fTSCUseRealTSC = false; /* virtualize it */ 200 #else 201 pVM->tm.s.fTSCUseRealTSC = true; /* don't virtualize it */ 202 #endif 203 else if (VBOX_FAILURE(rc)) 204 return VMSetError(pVM, rc, RT_SRC_POS, 205 N_("Configuration error: Failed to querying bool value \"UseRealTSC\". (%Vrc)"), rc); 206 if (!pVM->tm.s.fTSCUseRealTSC) 207 pVM->tm.s.fTSCVirtualized = true; 208 209 /* frequency */ 210 rc = CFGMR3QueryU64(CFGMR3GetRoot(pVM), "TSCTicksPerSecond", &pVM->tm.s.cTSCTicksPerSecond); 211 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 212 { 213 #if 0 /* when tmCpuTickGetRawVirtual is done */ 214 pVM->tm.s.cTSCTicksPerSecond = tmR3Calibrate(); 215 #else 216 if (pVM->tm.s.fTSCUseRealTSC) 217 pVM->tm.s.cTSCTicksPerSecond = tmR3Calibrate(); 218 else 219 pVM->tm.s.cTSCTicksPerSecond = TMCLOCK_FREQ_VIRTUAL;/* same as the virtual clock. */ 220 #endif 221 } 222 else if (VBOX_FAILURE(rc)) 223 return VMSetError(pVM, rc, RT_SRC_POS, 224 N_("Configuration error: Failed to querying uint64_t value \"TSCTicksPerSecond\". (%Vrc)"), rc); 225 #if 0 /* when tmCpuTickGetRawVirtual is done */ 226 else if ( pVM->tm.s.cTSCTicksPerSecond < _1M 227 || pVM->tm.s.cTSCTicksPerSecond > _1E) 228 return VMSetError(pVM, VERR_INVALID_PARAMETER, RT_SRC_POS, 229 N_("Configuration error: \"TSCTicksPerSecond\" = %RI64 is not in the range 1MHz..1EHz!"), 230 pVM->tm.s.cTSCTicksPerSecond); 231 #else 232 else if (pVM->tm.s.cTSCTicksPerSecond != TMCLOCK_FREQ_VIRTUAL) 233 return VMSetError(pVM, VERR_INVALID_PARAMETER, RT_SRC_POS, 234 N_("Configuration error: \"TSCTicksPerSecond\" = %RI64 is not 1GHz! (temporary restriction)"), 235 pVM->tm.s.cTSCTicksPerSecond); 236 #endif 237 else 238 { 239 pVM->tm.s.fTSCUseRealTSC = false; 240 pVM->tm.s.fTSCVirtualized = true; 241 } 242 243 /* setup and report */ 244 if (pVM->tm.s.fTSCUseRealTSC) 245 CPUMR3SetCR4Feature(pVM, 0, ~X86_CR4_TSD); 246 else 247 CPUMR3SetCR4Feature(pVM, X86_CR4_TSD, ~X86_CR4_TSD); 248 LogRel(("TM: cTSCTicksPerSecond=%#RX64 (%RU64) fTSCVirtualized=%RTbool fTSCUseRealTSC=%RTbool\n", 249 pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.fTSCVirtualized, pVM->tm.s.fTSCUseRealTSC)); 184 250 185 251 /* … … 272 338 DBGFR3InfoRegisterInternal(pVM, "timers", "Dumps all timers. No arguments.", tmR3TimerInfo); 273 339 DBGFR3InfoRegisterInternal(pVM, "activetimers", "Dumps active all timers. No arguments.", tmR3TimerInfoActive); 340 DBGFR3InfoRegisterInternal(pVM, "clocks", "Display the time of the various clocks.", tmR3InfoClocks); 274 341 275 342 return VINF_SUCCESS; … … 1192 1259 } 1193 1260 1261 1262 /** 1263 * Display all clocks. 1264 * 1265 * @param pVM VM Handle. 1266 * @param pHlp The info helpers. 1267 * @param pszArgs Arguments, ignored. 1268 */ 1269 static DECLCALLBACK(void) tmR3InfoClocks(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs) 1270 { 1271 NOREF(pszArgs); 1272 1273 /* TSC */ 1274 uint64_t u64 = TMCpuTickGet(pVM); 1275 pHlp->pfnPrintf(pHlp, 1276 "Cpu Tick: %#RX64 (%RU64) %RU64Hz %s%s", 1277 u64, u64, TMCpuTicksPerSecond(pVM), 1278 pVM->tm.s.fTSCTicking ? "ticking" : "paused", 1279 pVM->tm.s.fTSCVirtualized ? " - virtualized" : ""); 1280 if (pVM->tm.s.fTSCUseRealTSC) 1281 { 1282 pHlp->pfnPrintf(pHlp, "- real tsc"); 1283 if (pVM->tm.s.u64TSCOffset) 1284 pHlp->pfnPrintf(pHlp, "\n offset %#RX64", pVM->tm.s.u64TSCOffset); 1285 } 1286 else 1287 pHlp->pfnPrintf(pHlp, "- virtual clock"); 1288 pHlp->pfnPrintf(pHlp, "\n"); 1289 1290 /* virtual */ 1291 u64 = TMVirtualGet(pVM); 1292 pHlp->pfnPrintf(pHlp, 1293 " Virtual: %#RX64 (%RU64) %RU64Hz %s", 1294 u64, u64, TMVirtualGetFreq(pVM), 1295 pVM->tm.s.fVirtualTicking ? "ticking" : "paused"); 1296 if (pVM->tm.s.fVirtualWarpDrive) 1297 pHlp->pfnPrintf(pHlp, " WarpDrive %RU32 %%", pVM->tm.s.u32VirtualWarpDrivePercentage); 1298 pHlp->pfnPrintf(pHlp, "\n"); 1299 1300 /* virtual sync */ 1301 u64 = TMVirtualGetSync(pVM); 1302 pHlp->pfnPrintf(pHlp, 1303 "VirtSync: %#RX64 (%RU64) %s%s", 1304 u64, u64, 1305 pVM->tm.s.fVirtualSyncTicking ? "ticking" : "paused", 1306 pVM->tm.s.fVirtualSyncCatchUp ? " - catchup" : ""); 1307 if (pVM->tm.s.u64VirtualSyncOffset) 1308 pHlp->pfnPrintf(pHlp, "\n offset %#RX64", pVM->tm.s.u64VirtualSyncOffset); 1309 pHlp->pfnPrintf(pHlp, "\n"); 1310 1311 /* real */ 1312 u64 = TMRealGet(pVM); 1313 pHlp->pfnPrintf(pHlp, 1314 " Real: %#RX64 (%RU64) %RU64Hz\n", 1315 u64, u64, TMRealGetFreq(pVM)); 1316 } -
trunk/src/VBox/VMM/TMInternal.h
r443 r1057 288 288 /** CPU timestamp ticking enabled indicator (bool). (RDTSC) */ 289 289 bool fTSCTicking; 290 /** Set if we fully virtualize the TSC, i.e. intercept all rdtsc instructions. 291 * Config variable: TSCVirtualized (bool) */ 292 bool fTSCVirtualized; 293 /** Set if we use the real TSC as time source or if we use the virtual clock. 294 * If fTSCVirtualized is set we maintain a offset to the TSC and pausing/resuming the 295 * ticking. fTSCVirtualized = false implies fTSCUseRealTSC = true. 296 * Config variable: TSCUseRealTSC (bool) */ 297 bool fTSCUseRealTSC; 290 298 /** The offset between the host TSC and the Guest TSC. 291 * Only valid if fTicking is set . */299 * Only valid if fTicking is set and and fTSCUseRealTSC is clear. */ 292 300 uint64_t u64TSCOffset; 293 301 /** The guest TSC when fTicking is cleared. */ 294 302 uint64_t u64TSC; 295 /** The number of CPU clock ticks per second (TMCLOCK_TSC). 296 * If GIP is available, g_pSUPGlobalInfoPage->u64CpuHz will be used instead. */ 303 /** The number of CPU clock ticks per second (TMCLOCK_TSC). 304 * Config variable: TSCTicksPerSecond (64-bit unsigned int) 305 * The config variable implies fTSCVirtualized = true and fTSCUseRealTSC = false. */ 297 306 uint64_t cTSCTicksPerSecond; 298 307 -
trunk/src/VBox/VMM/VMEmt.cpp
r866 r1057 305 305 * and the yielder is suspended. 306 306 */ 307 TMCpuTickResume(pVM);307 // TMCpuTickResume(pVM); 308 308 VMMR3YieldSuspend(pVM); 309 309 … … 416 416 * and resume the yielder. 417 417 */ 418 TMCpuTickPause(pVM);418 // TMCpuTickPause(pVM); 419 419 VMMR3YieldResume(pVM); 420 420 -
trunk/src/VBox/VMM/VMMAll/TMAll.cpp
r1027 r1057 609 609 610 610 case TMCLOCK_TSC: 611 { 612 PCSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage; 613 if (pGip) 614 return SUPGetCpuHzFromGIP(pGip) ; 615 return pTimer->CTXALLSUFF(pVM)->tm.s.cTSCTicksPerSecond; 616 } 611 return TMCpuTicksPerSecond(pTimer->CTXALLSUFF(pVM)); 617 612 618 613 default: -
trunk/src/VBox/VMM/VMMAll/TMAllCpu.cpp
r23 r1057 28 28 #include "TMInternal.h" 29 29 #include <VBox/vm.h> 30 #include <VBox/sup.h> 30 31 31 32 #include <VBox/param.h> … … 33 34 #include <iprt/assert.h> 34 35 #include <iprt/asm.h> 36 37 38 /** 39 * Gets the raw cpu tick from current virtual time. 40 */ 41 DECLINLINE(uint64_t) tmCpuTickGetRawVirtual(PVM pVM) 42 { 43 uint64_t u64 = TMVirtualGet(pVM); 44 /** @todo calc tsc from virtual time. */ 45 return u64; 46 } 35 47 36 48 … … 46 58 { 47 59 pVM->tm.s.fTSCTicking = true; 48 #ifndef TM_REAL_CPU_TICK 49 pVM->tm.s.u64TSCOffset = ASMReadTSC() - pVM->tm.s.u64TSC; 50 #endif 60 if (pVM->tm.s.fTSCVirtualized) 61 { 62 if (pVM->tm.s.fTSCUseRealTSC) 63 pVM->tm.s.u64TSCOffset = ASMReadTSC() - pVM->tm.s.u64TSC; 64 else 65 pVM->tm.s.u64TSCOffset = tmCpuTickGetRawVirtual(pVM) - pVM->tm.s.u64TSC; 66 } 51 67 return VINF_SUCCESS; 52 68 } … … 66 82 if (pVM->tm.s.fTSCTicking) 67 83 { 68 #ifndef TM_REAL_CPU_TICK 69 pVM->tm.s.u64TSC = ASMReadTSC() - pVM->tm.s.u64TSCOffset; 70 #endif 84 if (!pVM->tm.s.fTSCVirtualized) 85 { 86 if (pVM->tm.s.fTSCUseRealTSC) 87 pVM->tm.s.u64TSC = ASMReadTSC() - pVM->tm.s.u64TSCOffset; 88 else 89 pVM->tm.s.u64TSC = tmCpuTickGetRawVirtual(pVM) - pVM->tm.s.u64TSCOffset; 90 } 71 91 pVM->tm.s.fTSCTicking = false; 72 92 return VINF_SUCCESS; … … 86 106 TMDECL(uint64_t) TMCpuTickGet(PVM pVM) 87 107 { 88 #ifdef TM_REAL_CPU_TICK 89 return ASMReadTSC(); 90 #else 91 if (pVM->tm.s.fTSCTicking) 92 return ASMReadTSC() - pVM->tm.s.u64TSCOffset; 93 return pVM->tm.s.u64TSC; 94 #endif 108 uint64_t u64; 109 if (pVM->tm.s.fTSCUseRealTSC) 110 u64 = ASMReadTSC(); 111 else 112 { 113 if (pVM->tm.s.fTSCTicking) 114 { 115 if (pVM->tm.s.fTSCUseRealTSC) 116 u64 = ASMReadTSC() - pVM->tm.s.u64TSCOffset; 117 else 118 u64 = tmCpuTickGetRawVirtual(pVM) - pVM->tm.s.u64TSCOffset; 119 } 120 else 121 u64 = pVM->tm.s.u64TSC; 122 } 123 return u64; 95 124 } 96 125 … … 119 148 TMDECL(uint64_t) TMCpuTicksPerSecond(PVM pVM) 120 149 { 150 if (pVM->tm.s.fTSCUseRealTSC) 151 { 152 uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGIP(g_pSUPGlobalInfoPage); 153 if (RT_LIKELY(cTSCTicksPerSecond != ~(uint64_t)0)) 154 return cTSCTicksPerSecond; 155 } 121 156 return pVM->tm.s.cTSCTicksPerSecond; 122 157 } -
trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
r443 r1057 372 372 int rc = TMVirtualPause(pVM); 373 373 AssertRCReturn(rc, rc); 374 rc = TMCpuTickPause(pVM); 375 AssertRCReturn(rc, rc); 374 376 } 375 377 … … 383 385 int rc = TMVirtualResume(pVM); 384 386 AssertRCReturn(rc, rc); 387 rc = TMCpuTickResume(pVM); 388 AssertRCReturn(rc, rc); 385 389 } 386 390 -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r1006 r1057 429 429 STAM_COUNTER_INC(&pVM->vmm.s.StatRunGC); 430 430 register int rc; 431 TMCpuTickResume(pVM);432 431 pVM->vmm.s.iLastGCRc = rc = pVM->vmm.s.pfnR0HostToGuest(pVM); 433 TMCpuTickPause(pVM);434 432 435 433 #ifdef VBOX_WITH_STATISTICS … … 511 509 512 510 STAM_COUNTER_INC(&pVM->vmm.s.StatRunGC); 513 TMCpuTickResume(pVM);514 511 rc = HWACCMR0Enable(pVM); 515 512 if (VBOX_SUCCESS(rc)) … … 525 522 AssertRC(rc2); 526 523 } 527 TMCpuTickPause(pVM);528 524 pVM->vmm.s.iLastGCRc = rc; 529 525 -
trunk/src/recompiler/VBoxRecompiler.c
r858 r1057 719 719 */ 720 720 pVM->rem.s.Env.interrupt_request = CPU_INTERRUPT_SINGLE_INSTR; 721 TMCpuTickResume(pVM);722 721 rc = cpu_exec(&pVM->rem.s.Env); 723 TMCpuTickPause(pVM);724 722 switch (rc) 725 723 { … … 826 824 do 827 825 { 828 TMCpuTickResume(pVM);829 826 rc = cpu_exec(&pVM->rem.s.Env); 830 TMCpuTickPause(pVM);831 832 827 } while ( eip == pVM->rem.s.Env.eip 833 828 && (rc == EXCP_DEBUG || rc == EXCP_EXECUTE_RAW) … … 949 944 950 945 951 TMCpuTickResume(pVM);952 946 int rc = cpu_exec(&pVM->rem.s.Env); 953 TMCpuTickPause(pVM);954 947 switch (rc) 955 948 { -
trunk/src/recompiler/new/VBoxRecompiler.c
r1001 r1057 735 735 */ 736 736 pVM->rem.s.Env.interrupt_request = CPU_INTERRUPT_SINGLE_INSTR; 737 TMCpuTickResume(pVM);738 737 rc = cpu_exec(&pVM->rem.s.Env); 739 TMCpuTickPause(pVM);740 738 switch (rc) 741 739 { … … 850 848 do 851 849 { 852 TMCpuTickResume(pVM);853 850 rc = cpu_exec(&pVM->rem.s.Env); 854 TMCpuTickPause(pVM);855 851 856 852 } while ( eip == pVM->rem.s.Env.eip … … 981 977 982 978 983 TMCpuTickResume(pVM);984 979 int rc = cpu_exec(&pVM->rem.s.Env); 985 TMCpuTickPause(pVM);986 980 switch (rc) 987 981 {
Note:
See TracChangeset
for help on using the changeset viewer.