Changeset View
Changeset View
Standalone View
Standalone View
sys/x86/x86/tsc.c
Show First 20 Lines • Show All 244 Lines • ▼ Show 20 Lines | probe_tsc_freq(void) | ||||
if (vm_guest == VM_GUEST_VMWARE) { | if (vm_guest == VM_GUEST_VMWARE) { | ||||
tsc_freq_vmware(); | tsc_freq_vmware(); | ||||
return; | return; | ||||
} | } | ||||
switch (cpu_vendor_id) { | switch (cpu_vendor_id) { | ||||
case CPU_VENDOR_AMD: | case CPU_VENDOR_AMD: | ||||
case CPU_VENDOR_HYGON: | |||||
if ((amd_pminfo & AMDPM_TSC_INVARIANT) != 0 || | if ((amd_pminfo & AMDPM_TSC_INVARIANT) != 0 || | ||||
(vm_guest == VM_GUEST_NO && | (vm_guest == VM_GUEST_NO && | ||||
CPUID_TO_FAMILY(cpu_id) >= 0x10)) | CPUID_TO_FAMILY(cpu_id) >= 0x10)) | ||||
tsc_is_invariant = 1; | tsc_is_invariant = 1; | ||||
if (cpu_feature & CPUID_SSE2) { | if (cpu_feature & CPUID_SSE2) { | ||||
tsc_timecounter.tc_get_timecount = | tsc_timecounter.tc_get_timecount = | ||||
tsc_get_timecount_mfence; | tsc_get_timecount_mfence; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 247 Lines • ▼ Show 20 Lines | retry: | ||||
free(data, M_TEMP); | free(data, M_TEMP); | ||||
if (bootverbose) | if (bootverbose) | ||||
printf("SMP: %sed TSC synchronization test%s\n", | printf("SMP: %sed TSC synchronization test%s\n", | ||||
smp_tsc ? "pass" : "fail", | smp_tsc ? "pass" : "fail", | ||||
adj > 0 ? " after adjustment" : ""); | adj > 0 ? " after adjustment" : ""); | ||||
if (smp_tsc && tsc_is_invariant) { | if (smp_tsc && tsc_is_invariant) { | ||||
switch (cpu_vendor_id) { | switch (cpu_vendor_id) { | ||||
case CPU_VENDOR_AMD: | case CPU_VENDOR_AMD: | ||||
case CPU_VENDOR_HYGON: | |||||
/* | /* | ||||
* Starting with Family 15h processors, TSC clock | * Starting with Family 15h processors, TSC clock | ||||
* source is in the north bridge. Check whether | * source is in the north bridge. Check whether | ||||
* we have a single-socket/multi-core platform. | * we have a single-socket/multi-core platform. | ||||
* XXX Need more work for complex cases. | * XXX Need more work for complex cases. | ||||
*/ | */ | ||||
if (CPUID_TO_FAMILY(cpu_id) < 0x15 || | if (CPUID_TO_FAMILY(cpu_id) < 0x15 || | ||||
(amd_feature2 & AMDID2_CMP) == 0 || | (amd_feature2 & AMDID2_CMP) == 0 || | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | #endif /* SMP */ | ||||
if (tsc_is_invariant) | if (tsc_is_invariant) | ||||
tsc_timecounter.tc_quality = 1000; | tsc_timecounter.tc_quality = 1000; | ||||
max_freq >>= tsc_shift; | max_freq >>= tsc_shift; | ||||
init: | init: | ||||
for (shift = 0; shift <= 31 && (tsc_freq >> shift) > max_freq; shift++) | for (shift = 0; shift <= 31 && (tsc_freq >> shift) > max_freq; shift++) | ||||
; | ; | ||||
if ((cpu_feature & CPUID_SSE2) != 0 && mp_ncpus > 1) { | if ((cpu_feature & CPUID_SSE2) != 0 && mp_ncpus > 1) { | ||||
if (cpu_vendor_id == CPU_VENDOR_AMD) { | if (cpu_vendor_id == CPU_VENDOR_AMD || | ||||
cpu_vendor_id == CPU_VENDOR_HYGON) { | |||||
tsc_timecounter.tc_get_timecount = shift > 0 ? | tsc_timecounter.tc_get_timecount = shift > 0 ? | ||||
tsc_get_timecount_low_mfence : | tsc_get_timecount_low_mfence : | ||||
tsc_get_timecount_mfence; | tsc_get_timecount_mfence; | ||||
} else { | } else { | ||||
tsc_timecounter.tc_get_timecount = shift > 0 ? | tsc_timecounter.tc_get_timecount = shift > 0 ? | ||||
tsc_get_timecount_low_lfence : | tsc_get_timecount_low_lfence : | ||||
tsc_get_timecount_lfence; | tsc_get_timecount_lfence; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 208 Lines • Show Last 20 Lines |