diff options
author | Dimitry Andric <dim@cvs.openbsd.org> | 2006-11-27 16:27:53 +0000 |
---|---|---|
committer | Dimitry Andric <dim@cvs.openbsd.org> | 2006-11-27 16:27:53 +0000 |
commit | e724935dfd29bb7478f23400f43ab64b89a0da33 (patch) | |
tree | 1593ed432d8f1ecf3b06f26bd1795c29970ebd52 | |
parent | d51deece22912c3ae87e4d39ca8c28bd4435bde7 (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.c | 34 |
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); |