summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2009-02-16 15:44:26 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2009-02-16 15:44:26 +0000
commit12b0ca277e8cf3655bddd75b694086d6a8159dc2 (patch)
tree4772cfc4c7f1d2b576c7f30ba2cf48ad4ccdd32e /sys/arch/i386
parent7b6b94111a9292f433eef65e1ea39265309976a8 (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.c27
-rw-r--r--sys/arch/i386/include/cpu.h4
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 */