summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@cvs.openbsd.org>2006-11-27 16:27:53 +0000
committerDimitry Andric <dim@cvs.openbsd.org>2006-11-27 16:27:53 +0000
commite724935dfd29bb7478f23400f43ab64b89a0da33 (patch)
tree1593ed432d8f1ecf3b06f26bd1795c29970ebd52
parentd51deece22912c3ae87e4d39ca8c28bd4435bde7 (diff)
Only use the ichpcib speedstep feature if we're running on a (Mobile) Pentium 4,
since Celerons don't support it. prodded by gwk@
-rw-r--r--sys/arch/i386/pci/ichpcib.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/sys/arch/i386/pci/ichpcib.c b/sys/arch/i386/pci/ichpcib.c
index df2410ecf87..bd6f67950ee 100644
--- a/sys/arch/i386/pci/ichpcib.c
+++ b/sys/arch/i386/pci/ichpcib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ichpcib.c,v 1.11 2006/09/19 00:20:17 brad Exp $ */
+/* $OpenBSD: ichpcib.c,v 1.12 2006/11/27 16:27:52 dim Exp $ */
/*
* Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org>
*
@@ -38,6 +38,9 @@
#include <dev/pci/ichreg.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+
struct ichpcib_softc {
struct device sc_dev;
@@ -78,6 +81,8 @@ struct cfdriver ichpcib_cd = {
};
#ifndef SMALL_KERNEL
+extern char *cpu_model;
+static const char p4hint[] = "Mobile Intel(R) Pentium(R) 4";
static void *ichss_cookie; /* XXX */
extern int setperf_prio;
#endif /* !SMALL_KERNEL */
@@ -154,14 +159,14 @@ ichpcib_attach(struct device *parent, struct device *self, void *aux)
/* Enable SpeedStep */
pci_conf_write(pa->pa_pc, pa->pa_tag, ICH_GEN_PMCON1,
pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_GEN_PMCON1) |
- ICH_GEN_PMCON1_SS_EN);
+ ICH_GEN_PMCON1_SS_EN);
/* Hook into hw.setperf sysctl */
ichss_cookie = sc;
cpu_setperf = ichss_setperf;
setperf_prio = 2;
}
-#endif /* !SMALL_KERNEL */
+#endif /* !SMALL_KERNEL */
corepcib:
/* Provide core pcib(4) functionality */
@@ -174,10 +179,33 @@ ichss_present(struct pci_attach_args *pa)
{
pcitag_t br_tag;
pcireg_t br_id, br_class;
+ struct cpu_info *ci;
+ int family, model, stepping, brandid;
if (setperf_prio > 2)
return (0);
+ ci = curcpu();
+ family = (ci->ci_signature >> 8) & 15;
+ model = (ci->ci_signature >> 4) & 15;
+ stepping = ci->ci_signature & 15;
+ brandid = cpu_miscinfo & 0xff; /* XXX should put this in ci */
+
+ /*
+ * This form of SpeedStep works only on Intel Mobile Pentium 4.
+ * Intel Celeron processors don't support it. However, they
+ * can be coupled with ICH southbridges that do, causing false
+ * positives. So we ensure that we are running on Intel Mobile
+ * Pentium 4.
+ * This heuristic comes from the Linux speedstep-ich driver.
+ */
+ if (!(family == 15 && model == 2 &&
+ ((stepping == 4 && (brandid == 14 || brandid == 15)) ||
+ (stepping == 7 && brandid == 14) ||
+ (stepping == 9 && (brandid == 14 || strncasecmp(cpu_model, p4hint,
+ sizeof(p4hint) - 1) == 0)))))
+ return (0);
+
if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801DBM_LPC ||
PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801CAM_LPC)
return (1);