diff options
Diffstat (limited to 'src/common/x64')
| -rw-r--r-- | src/common/x64/cpu_detect.cpp | 16 | ||||
| -rw-r--r-- | src/common/x64/cpu_detect.h | 5 | 
2 files changed, 21 insertions, 0 deletions
| diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp index 322aa1f08..1a27532d4 100644 --- a/src/common/x64/cpu_detect.cpp +++ b/src/common/x64/cpu_detect.cpp @@ -161,6 +161,22 @@ static CPUCaps Detect() {          caps.invariant_tsc = Common::Bit<8>(cpu_id[3]);      } +    if (max_std_fn >= 0x15) { +        __cpuid(cpu_id, 0x15); +        caps.tsc_crystal_ratio_denominator = cpu_id[0]; +        caps.tsc_crystal_ratio_numerator = cpu_id[1]; +        caps.crystal_frequency = cpu_id[2]; +        // Some CPU models might not return a crystal frequency. +        // The CPU model can be detected to use the values from turbostat +        // https://github.com/torvalds/linux/blob/master/tools/power/x86/turbostat/turbostat.c#L5569 +        // but it's easier to just estimate the TSC tick rate for these cases. +        if (caps.tsc_crystal_ratio_denominator) { +            caps.tsc_frequency = static_cast<u64>(caps.crystal_frequency) * +                                 caps.tsc_crystal_ratio_numerator / +                                 caps.tsc_crystal_ratio_denominator; +        } +    } +      if (max_std_fn >= 0x16) {          __cpuid(cpu_id, 0x16);          caps.base_frequency = cpu_id[0]; diff --git a/src/common/x64/cpu_detect.h b/src/common/x64/cpu_detect.h index 9bdc9dbfa..6830f3795 100644 --- a/src/common/x64/cpu_detect.h +++ b/src/common/x64/cpu_detect.h @@ -30,6 +30,11 @@ struct CPUCaps {      u32 max_frequency;      u32 bus_frequency; +    u32 tsc_crystal_ratio_denominator; +    u32 tsc_crystal_ratio_numerator; +    u32 crystal_frequency; +    u64 tsc_frequency; // Derived from the above three values +      bool sse : 1;      bool sse2 : 1;      bool sse3 : 1; | 
