summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2007-06-01 22:28:22 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2007-06-01 22:28:22 +0000
commit8e6616c399a7ffa90d49afd4e3bf01016b49dac8 (patch)
tree844d1977c24a04685fa6d62131acf820c7696d30
parent88154fd1fd69bfb65f6e9bd703776f1fc823dac7 (diff)
some pentium 4 machines are 64-bit and have EST, but a different msr to
get bus clock. copy in some more code from i386 to deal with both families, and be more watchful for unknown models. fixes a panic reported by johan lindman. ok gwk
-rw-r--r--sys/arch/amd64/amd64/est.c121
-rw-r--r--sys/arch/amd64/include/specialreg.h3
2 files changed, 100 insertions, 24 deletions
diff --git a/sys/arch/amd64/amd64/est.c b/sys/arch/amd64/amd64/est.c
index 60d1ff0be65..14ad1eb1ad4 100644
--- a/sys/arch/amd64/amd64/est.c
+++ b/sys/arch/amd64/amd64/est.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: est.c,v 1.1 2007/05/29 06:31:44 tedu Exp $ */
+/* $OpenBSD: est.c,v 1.2 2007/06/01 22:28:21 tedu Exp $ */
/*
* Copyright (c) 2003 Michael Eriksson.
* All rights reserved.
@@ -97,40 +97,115 @@ extern int perflevel;
int bus_clock;
+void p4_get_bus_clock(struct cpu_info *);
+void p3_get_bus_clock(struct cpu_info *);
+
+void
+p4_get_bus_clock(struct cpu_info *ci)
+{
+ u_int64_t msr;
+ int model, bus;
+
+ model = (ci->ci_signature >> 4) & 15;
+ msr = rdmsr(MSR_EBC_FREQUENCY_ID);
+ if (model < 2) {
+ bus = (msr >> 21) & 0x7;
+ switch (bus) {
+ case 0:
+ bus_clock = 10000;
+ break;
+ case 1:
+ bus_clock = 13333;
+ break;
+ default:
+ printf("%s: unknown Pentium 4 (model %d) "
+ "EBC_FREQUENCY_ID value %d\n",
+ ci->ci_dev->dv_xname, model, bus);
+ break;
+ }
+ } else {
+ bus = (msr >> 16) & 0x7;
+ switch (bus) {
+ case 0:
+ bus_clock = (model == 2) ? 10000 : 26666;
+ break;
+ case 1:
+ bus_clock = 13333;
+ break;
+ case 2:
+ bus_clock = 20000;
+ break;
+ case 3:
+ bus_clock = 16666;
+ break;
+ default:
+ printf("%s: unknown Pentium 4 (model %d) "
+ "EBC_FREQUENCY_ID value %d\n",
+ ci->ci_dev->dv_xname, model, bus);
+ break;
+ }
+ }
+}
+
+void
+p3_get_bus_clock(struct cpu_info *ci)
+{
+ u_int64_t msr;
+ int model, bus;
+
+ model = (ci->ci_signature >> 4) & 15;
+ switch (model) {
+ case 0xe: /* Core Duo/Solo */
+ case 0xf: /* Core Xeon */
+ msr = rdmsr(MSR_FSB_FREQ);
+ bus = (msr >> 0) & 0x7;
+ switch (bus) {
+ case 5:
+ bus_clock = 10000;
+ break;
+ case 1:
+ bus_clock = 13333;
+ break;
+ case 3:
+ bus_clock = 16666;
+ break;
+ case 0:
+ bus_clock = 26666;
+ break;
+ case 4:
+ bus_clock = 33333;
+ break;
+ default:
+ printf("%s: unknown Core FSB_FREQ value %d",
+ ci->ci_dev->dv_xname, bus);
+ break;
+ }
+ break;
+ default:
+ printf("%s: unknown i686 model %d, can't get bus clock",
+ ci->ci_dev->dv_xname, model);
+ }
+}
+
void
est_init(struct cpu_info *ci)
{
const char *cpu_device = ci->ci_dev->dv_xname;
int vendor = -1;
- int i, mhz, mv, low, high, bus;
+ int i, mhz, mv, low, high, family;
u_int64_t msr;
u_int16_t idhi, idlo, cur;
u_int8_t crhi, crlo, crcur;
if (setperf_prio > 3)
return;
- msr = rdmsr(MSR_FSB_FREQ);
- bus = msr & 0x07;
- switch (bus) {
- case 5:
- bus_clock = 10000;
- break;
- case 1:
- bus_clock = 13333;
- break;
- case 3:
- bus_clock = 16666;
- break;
- case 0:
- bus_clock = 26666;
- break;
- case 4:
- bus_clock = 33333;
- break;
- default:
- printf("unknown bus %d\n", bus);
- }
+ family = (ci->ci_signature >> 8) & 15;
+ if (family == 0xf) {
+ p4_get_bus_clock(ci);
+ } else if (family == 6) {
+ p3_get_bus_clock(ci);
+ }
if (bus_clock == 0) {
printf("%s: EST: unknown system bus clock\n", cpu_device);
return;
diff --git a/sys/arch/amd64/include/specialreg.h b/sys/arch/amd64/include/specialreg.h
index fbc856244a4..568d3470051 100644
--- a/sys/arch/amd64/include/specialreg.h
+++ b/sys/arch/amd64/include/specialreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: specialreg.h,v 1.10 2007/05/29 06:40:15 tedu Exp $ */
+/* $OpenBSD: specialreg.h,v 1.11 2007/06/01 22:28:21 tedu Exp $ */
/* $NetBSD: specialreg.h,v 1.1 2003/04/26 18:39:48 fvdl Exp $ */
/* $NetBSD: x86/specialreg.h,v 1.2 2003/04/25 21:54:30 fvdl Exp $ */
@@ -165,6 +165,7 @@
#define MSR_CTR1 0x013 /* P5 only (trap on P6) */
#define MSR_APICBASE 0x01b
#define MSR_EBL_CR_POWERON 0x02a
+#define MSR_EBC_FREQUENCY_ID 0x02c /* Pentium 4 only */
#define MSR_TEST_CTL 0x033
#define MSR_BIOS_UPDT_TRIG 0x079
#define MSR_BBL_CR_D0 0x088 /* PII+ only */