Currently we have to manually provide the reference TSC frequency when testing the calibration. However, newer x86 CPUs provide this number through CPUID. Feed it EAX=0x15, and the cpu frequency is given by
tsc_freq = ecx * (edx / eax)
where ECX is the crystal frequency and the ratio of the other two is the multiplier to TSC frequency.
For slightly older specs (Skylake, Kaby Lake, a few Atoms) the crystal frequency reads zero, but is known from design (see kernel source below):
https://elixir.bootlin.com/linux/v4.12.4/source/arch/x86/kernel/tsc.c#L675
For older specs, this doesn't work and gives nonsense, but you can check the largest valid value for EAX and ignore the output if it's less than 0x15. (In that case, you just have to use the calibrated result.)
Currently we have to manually provide the reference TSC frequency when testing the calibration. However, newer x86 CPUs provide this number through CPUID. Feed it EAX=0x15, and the cpu frequency is given by
where ECX is the crystal frequency and the ratio of the other two is the multiplier to TSC frequency.
For slightly older specs (Skylake, Kaby Lake, a few Atoms) the crystal frequency reads zero, but is known from design (see kernel source below):
https://elixir.bootlin.com/linux/v4.12.4/source/arch/x86/kernel/tsc.c#L675
For older specs, this doesn't work and gives nonsense, but you can check the largest valid value for EAX and ignore the output if it's less than 0x15. (In that case, you just have to use the calibrated result.)