Changeset 54549 in vbox
- Timestamp:
- Feb 27, 2015 12:18:28 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/TM.cpp
r54444 r54549 852 852 static bool tmR3HasFixedTSC(PVM pVM) 853 853 { 854 /* 855 * ASSUME that if the GIP is in invariant TSC mode, it's because the CPU 856 * actually has invariant TSC. 857 */ 854 858 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage; 855 859 if (pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC) 856 860 return true; 857 861 862 /* 863 * Go by features and model info from the CPUID instruction. 864 */ 858 865 if (ASMHasCpuId()) 859 866 { 860 867 uint32_t uEAX, uEBX, uECX, uEDX; 861 868 869 /* 870 * By feature. (Used to be AMD specific, intel seems to have picked it up.) 871 */ 872 ASMCpuId(0x80000000, &uEAX, &uEBX, &uECX, &uEDX); 873 if (uEAX >= 0x80000007 && ASMIsValidExtRange(uEAX)) 874 { 875 ASMCpuId(0x80000007, &uEAX, &uEBX, &uECX, &uEDX); 876 if ( (uEDX & X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR) /* TscInvariant */ 877 && pGip->u32Mode != SUPGIPMODE_ASYNC_TSC) /* No fixed tsc if the gip timer is in async mode. */ 878 return true; 879 } 880 881 /* 882 * By model. 883 */ 862 884 if (CPUMGetHostCpuVendor(pVM) == CPUMCPUVENDOR_AMD) 863 885 { 864 /** @todo This is redundant as it would get satisified in the invariant case865 * above. Remove later or keep around for sync mode override? */866 886 /* 867 887 * AuthenticAMD - Check for APM support and that TscInvariant is set. … … 871 891 * only used for making a decision on AMD-V models. 872 892 */ 893 #if 0 /* Promoted to generic */ 873 894 ASMCpuId(0x80000000, &uEAX, &uEBX, &uECX, &uEDX); 874 895 if (uEAX >= 0x80000007) … … 880 901 return true; 881 902 } 903 #endif 882 904 } 883 905 else if (CPUMGetHostCpuVendor(pVM) == CPUMCPUVENDOR_INTEL) … … 916 938 && uStepping >= 0x0c 917 939 && uStepping <= 0x0f) 918 {919 940 return true; 920 }921 941 } 922 942 } … … 932 952 static uint64_t tmR3CalibrateTSC(PVM pVM) 933 953 { 934 /* 935 * Use GIP when available. 936 */ 937 uint64_t u64Hz = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage); 938 if (g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_INVARIANT_TSC) 939 { 940 Assert(u64Hz != UINT64_MAX); 941 return u64Hz; 942 } 943 944 if (u64Hz != UINT64_MAX) 945 { 946 if (tmR3HasFixedTSC(pVM)) 947 /* Sleep a bit to get a more reliable CpuHz value. */ 948 RTThreadSleep(32); 949 else 950 { 951 /* Spin for 40ms to try push up the CPU frequency and get a more reliable CpuHz value. */ 952 const uint64_t u64 = RTTimeMilliTS(); 953 while ((RTTimeMilliTS() - u64) < 40 /* ms */) 954 /* nothing */; 955 } 956 957 u64Hz = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage); 958 if (u64Hz != UINT64_MAX) 954 uint64_t u64Hz; 955 956 /* 957 * Use GIP when available. Prefere the nominal one, no need to wait for it. 958 */ 959 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage; 960 if (pGip) 961 { 962 u64Hz = pGip->u64CpuHz; 963 if (u64Hz < _1T && u64Hz > _1M) 959 964 return u64Hz; 960 } 965 AssertFailed(); /* This shouldn't happen. */ 966 967 u64Hz = SUPGetCpuHzFromGip(pGip); 968 if (u64Hz < _1T && u64Hz > _1M) 969 return u64Hz; 970 971 AssertFailed(); /* This shouldn't happen. */ 972 } 973 /* else: This should only happen in fake SUPLib mode, which we don't really support any more... */ 961 974 962 975 /* Call this once first to make sure it's initialized. */
Note:
See TracChangeset
for help on using the changeset viewer.