diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2009-02-16 15:44:26 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2009-02-16 15:44:26 +0000 |
commit | 12b0ca277e8cf3655bddd75b694086d6a8159dc2 (patch) | |
tree | 4772cfc4c7f1d2b576c7f30ba2cf48ad4ccdd32e /sys/arch/i386 | |
parent | 7b6b94111a9292f433eef65e1ea39265309976a8 (diff) |
Store conditionally extended cpuid family/model values
in seperate variables in struct cpu_info instead
of duplicating the process of extracting it from the signature.
Use this value when determining the bus clock on P6/family 0x6
chips, which fixes speedstep on bernd@'s ThinkPad x200s.
Discussed with several, 'just do it' weingart@, ok mikeb@
Diffstat (limited to 'sys/arch/i386')
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 27 | ||||
-rw-r--r-- | sys/arch/i386/include/cpu.h | 4 |
2 files changed, 23 insertions, 8 deletions
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 1de573184ad..ce933eac9f3 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.445 2009/02/14 11:22:25 kettenis Exp $ */ +/* $OpenBSD: machdep.c,v 1.446 2009/02/16 15:44:25 jsg Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -1628,7 +1628,9 @@ identifycpu(struct cpu_info *ci) max = sizeof (i386_cpuid_cpus) / sizeof (i386_cpuid_cpus[0]); modif = (ci->ci_signature >> 12) & 3; family = (ci->ci_signature >> 8) & 15; + ci->ci_family = family; model = (ci->ci_signature >> 4) & 15; + ci->ci_model = model; step = ci->ci_signature & 15; #ifdef CPUDEBUG printf("%s: family %x model %x step %x\n", cpu_device, family, @@ -1685,6 +1687,16 @@ identifycpu(struct cpu_info *ci) model = CPU_DEFMODEL; i = family - CPU_MINFAMILY; + /* store extended family/model values for later use */ + if ((vendor == CPUVENDOR_INTEL && + (family == 0x6 || family == 0xf)) || + (vendor == CPUVENDOR_AMD && family == 0xf)) { + ci->ci_family += (ci->ci_signature >> 20) & + 0xff; + ci->ci_model += ((ci->ci_signature >> 16) & + 0x0f) << 4; + } + /* Special hack for the PentiumII/III series. */ if (vendor == CPUVENDOR_INTEL && family == 6 && (model == 5 || model == 7)) { @@ -1964,10 +1976,9 @@ void p3_get_bus_clock(struct cpu_info *ci) { u_int64_t msr; - int model, bus; + int bus; - model = (ci->ci_signature >> 4) & 15; - switch (model) { + switch (ci->ci_model) { case 0x9: /* Pentium M (130 nm, Banias) */ bus_clock = BUS100; break; @@ -1989,6 +2000,8 @@ p3_get_bus_clock(struct cpu_info *ci) break; case 0xe: /* Core Duo/Solo */ case 0xf: /* Core Xeon */ + case 0x16: /* 65nm Celeron */ + case 0x17: /* Core 2 Extreme/45nm Xeon */ msr = rdmsr(MSR_FSB_FREQ); bus = (msr >> 0) & 0x7; switch (bus) { @@ -2016,7 +2029,7 @@ p3_get_bus_clock(struct cpu_info *ci) goto print_msr; } break; - case 0xc: /* Atom */ + case 0x1c: /* Atom */ msr = rdmsr(MSR_FSB_FREQ); bus = (msr >> 0) & 0x7; switch (bus) { @@ -2062,8 +2075,8 @@ p3_get_bus_clock(struct cpu_info *ci) } break; default: - printf("%s: unknown i686 model %d, can't get bus clock", - ci->ci_dev.dv_xname, model); + printf("%s: unknown i686 model 0x%x, can't get bus clock", + ci->ci_dev.dv_xname, ci->ci_model); print_msr: /* * Show the EBL_CR_POWERON MSR, so we'll at least have diff --git a/sys/arch/i386/include/cpu.h b/sys/arch/i386/include/cpu.h index 56e1263eb20..c9115640e46 100644 --- a/sys/arch/i386/include/cpu.h +++ b/sys/arch/i386/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.106 2008/11/22 18:12:32 art Exp $ */ +/* $OpenBSD: cpu.h,v 1.107 2009/02/16 15:44:25 jsg Exp $ */ /* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */ /*- @@ -115,6 +115,8 @@ struct cpu_info { u_int32_t ci_level; u_int32_t ci_vendor[4]; u_int32_t ci_signature; /* X86 cpuid type */ + u_int32_t ci_family; /* extended cpuid family */ + u_int32_t ci_model; /* extended cpuid model */ u_int32_t ci_feature_flags; /* X86 CPUID feature bits */ u_int32_t cpu_class; /* CPU class */ |