diff options
author | jhb <jhb@FreeBSD.org> | 2014-09-04 02:25:59 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2014-09-04 02:25:59 +0000 |
commit | f937116d2005d1bb59e30baff9ff73b2afd26270 (patch) | |
tree | 54e0b90111bbe41280e4bda9df0bb9bd054396fb | |
parent | 2d9d64ca44af1c88ddc687d0beab2e2d81fd765b (diff) | |
download | FreeBSD-src-f937116d2005d1bb59e30baff9ff73b2afd26270.zip FreeBSD-src-f937116d2005d1bb59e30baff9ff73b2afd26270.tar.gz |
- Move blacklists of broken TSCs out of the printcpuinfo() function
and into the TSC probe routine.
- Initialize cpu_exthigh once in finishidentcpu() which is called
before printcpuinfo() (and matches the behavior on amd64).
-rw-r--r-- | sys/i386/i386/identcpu.c | 47 | ||||
-rw-r--r-- | sys/x86/x86/tsc.c | 33 |
2 files changed, 44 insertions, 36 deletions
diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c index cb34bb0..9cb7fe7 100644 --- a/sys/i386/i386/identcpu.c +++ b/sys/i386/i386/identcpu.c @@ -65,7 +65,6 @@ __FBSDID("$FreeBSD$"); #define IDENTBLUE_CYRIXM2 2 static void identifycyrix(void); -static void init_exthigh(void); static u_int find_cpu_vendor_id(void); static void print_AMD_info(void); static void print_INTEL_info(void); @@ -147,28 +146,6 @@ static struct { #endif }; -static void -init_exthigh(void) -{ - static int done = 0; - u_int regs[4]; - - if (done == 0) { - if (cpu_high > 0 && - (cpu_vendor_id == CPU_VENDOR_INTEL || - cpu_vendor_id == CPU_VENDOR_AMD || - cpu_vendor_id == CPU_VENDOR_TRANSMETA || - cpu_vendor_id == CPU_VENDOR_CENTAUR || - cpu_vendor_id == CPU_VENDOR_NSC)) { - do_cpuid(0x80000000, regs); - if (regs[0] >= 0x80000000) - cpu_exthigh = regs[0]; - } - - done = 1; - } -} - void printcpuinfo(void) { @@ -180,7 +157,6 @@ printcpuinfo(void) strncpy(cpu_model, i386_cpus[cpu].cpu_name, sizeof (cpu_model)); /* Check for extended CPUID information and a processor name. */ - init_exthigh(); if (cpu_exthigh >= 0x80000004) { brand = cpu_brand; for (i = 0x80000002; i < 0x80000005; i++) { @@ -354,7 +330,6 @@ printcpuinfo(void) break; case 0x500: strcat(cpu_model, "K5 model 0"); - tsc_freq = 0; break; case 0x510: strcat(cpu_model, "K5 model 1"); @@ -553,13 +528,6 @@ printcpuinfo(void) switch (cpu_id & 0xff0) { case 0x540: strcpy(cpu_model, "IDT WinChip C6"); - /* - * http://www.centtech.com/c6_data_sheet.pdf - * - * I-12 RDTSC may return incoherent values in EDX:EAX - * I-13 RDTSC hangs when certain event counters are used - */ - tsc_freq = 0; break; case 0x580: strcpy(cpu_model, "IDT WinChip 2"); @@ -599,8 +567,6 @@ printcpuinfo(void) case 0x540: strcpy(cpu_model, "Geode SC1100"); cpu = CPU_GEODE1100; - if ((cpu_id & CPUID_STEPPING) == 0) - tsc_freq = 0; break; default: strcpy(cpu_model, "Geode/NSC unknown"); @@ -1110,10 +1076,20 @@ finishidentcpu(void) cpu_mon_max_size = regs[1] & CPUID5_MON_MAX_SIZE; } + if (cpu_high > 0 && + (cpu_vendor_id == CPU_VENDOR_INTEL || + cpu_vendor_id == CPU_VENDOR_AMD || + cpu_vendor_id == CPU_VENDOR_TRANSMETA || + cpu_vendor_id == CPU_VENDOR_CENTAUR || + cpu_vendor_id == CPU_VENDOR_NSC)) { + do_cpuid(0x80000000, regs); + if (regs[0] >= 0x80000000) + cpu_exthigh = regs[0]; + } + /* Detect AMD features (PTE no-execute bit, 3dnow, 64 bit mode etc) */ if (cpu_vendor_id == CPU_VENDOR_INTEL || cpu_vendor_id == CPU_VENDOR_AMD) { - init_exthigh(); if (cpu_exthigh >= 0x80000001) { do_cpuid(0x80000001, regs); amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff); @@ -1128,7 +1104,6 @@ finishidentcpu(void) cpu_procinfo2 = regs[2]; } } else if (cpu_vendor_id == CPU_VENDOR_CENTAUR) { - init_exthigh(); if (cpu_exthigh >= 0x80000001) { do_cpuid(0x80000001, regs); amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff); diff --git a/sys/x86/x86/tsc.c b/sys/x86/x86/tsc.c index 54c4d02..31d6715 100644 --- a/sys/x86/x86/tsc.c +++ b/sys/x86/x86/tsc.c @@ -324,6 +324,39 @@ init_TSC(void) if ((cpu_feature & CPUID_TSC) == 0 || tsc_disabled) return; +#ifdef __i386__ + /* The TSC is known to be broken on certain CPUs. */ + switch (cpu_vendor_id) { + case CPU_VENDOR_AMD: + switch (cpu_id & 0xFF0) { + case 0x500: + /* K5 Model 0 */ + return; + } + break; + case CPU_VENDOR_CENTAUR: + switch (cpu_id & 0xff0) { + case 0x540: + /* + * http://www.centtech.com/c6_data_sheet.pdf + * + * I-12 RDTSC may return incoherent values in EDX:EAX + * I-13 RDTSC hangs when certain event counters are used + */ + return; + } + break; + case CPU_VENDOR_NSC: + switch (cpu_id & 0xff0) { + case 0x540: + if ((cpu_id & CPUID_STEPPING) == 0) + return; + break; + } + break; + } +#endif + probe_tsc_freq(); /* |