Lines 134-144
Link Here
|
134 |
|
134 |
|
135 |
/* |
135 |
/* |
136 |
* Calculate TSC frequency using information from the CPUID leaf 0x15 |
136 |
* Calculate TSC frequency using information from the CPUID leaf 0x15 |
137 |
* 'Time Stamp Counter and Nominal Core Crystal Clock'. If leaf 0x15 |
137 |
* 'Time Stamp Counter and Nominal Core Crystal Clock'. It should be |
138 |
* is not functional, as it is on Skylake/Kabylake, try 0x16 'Processor |
|
|
139 |
* Frequency Information'. Leaf 0x16 is described in the SDM as |
140 |
* informational only, but if 0x15 did not work, and TSC calibration |
141 |
* is disabled, it is the best we can get at all. It should still be |
142 |
* an improvement over the parsing of the CPU model name in |
138 |
* an improvement over the parsing of the CPU model name in |
143 |
* tsc_freq_intel(), when available. |
139 |
* tsc_freq_intel(), when available. |
144 |
*/ |
140 |
*/ |
Lines 150-169
Link Here
|
150 |
if (cpu_high < 0x15) |
146 |
if (cpu_high < 0x15) |
151 |
return (false); |
147 |
return (false); |
152 |
do_cpuid(0x15, regs); |
148 |
do_cpuid(0x15, regs); |
153 |
if (regs[0] != 0 && regs[1] != 0 && regs[2] != 0) { |
149 |
if (regs[0] == 0 || regs[1] == 0 || regs[2] == 0) |
154 |
tsc_freq = (uint64_t)regs[2] * regs[1] / regs[0]; |
|
|
155 |
return (true); |
156 |
} |
157 |
|
158 |
if (cpu_high < 0x16) |
159 |
return (false); |
150 |
return (false); |
160 |
do_cpuid(0x16, regs); |
151 |
tsc_freq = (uint64_t)regs[2] * regs[1] / regs[0]; |
161 |
if (regs[0] != 0) { |
152 |
return (true); |
162 |
tsc_freq = (uint64_t)regs[0] * 1000000; |
|
|
163 |
return (true); |
164 |
} |
165 |
|
166 |
return (false); |
167 |
} |
153 |
} |
168 |
|
154 |
|
169 |
static void |
155 |
static void |