diff options
author | Gordon Willem Klok <gwk@cvs.openbsd.org> | 2009-06-06 23:21:44 +0000 |
---|---|---|
committer | Gordon Willem Klok <gwk@cvs.openbsd.org> | 2009-06-06 23:21:44 +0000 |
commit | d0ca62a445230166bc924e68e43e6e53ceebac82 (patch) | |
tree | 98dcc0ab0af09ba05a467252c3e4b9047abe38da /sys/arch | |
parent | 9cb1e5ced8a3c4590f197ee60a7b0464a8533d07 (diff) |
Update est.c, make it capable of using ACPI if the PSS is available but
still support all different methods of getting states without e.g.
(highest/lowest state), and on i386 use the tables. The only change
should be the deletion of the mV from the printf at boot.
ok jsg@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/amd64/amd64/est.c | 227 | ||||
-rw-r--r-- | sys/arch/i386/i386/est.c | 423 |
2 files changed, 447 insertions, 203 deletions
diff --git a/sys/arch/amd64/amd64/est.c b/sys/arch/amd64/amd64/est.c index 7f54997c322..082f89bd05c 100644 --- a/sys/arch/amd64/amd64/est.c +++ b/sys/arch/amd64/amd64/est.c @@ -1,4 +1,4 @@ -/* $OpenBSD: est.c,v 1.11 2009/04/23 07:30:03 jsg Exp $ */ +/* $OpenBSD: est.c,v 1.12 2009/06/06 23:21:43 gwk Exp $ */ /* * Copyright (c) 2003 Michael Eriksson. * All rights reserved. @@ -56,14 +56,22 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/sysctl.h> +#include <sys/malloc.h> #include <machine/cpu.h> #include <machine/cpufunc.h> #include <machine/specialreg.h> +#include <machine/bus.h> #define CPUVENDOR_INTEL 0 #define CPUVENDOR_VIA 8 +#include "acpicpu.h" + +#if NACPICPU > 0 +#include <dev/acpi/acpidev.h> +#include <dev/acpi/acpivar.h> +#endif /* Convert MHz and mV into IDs for passing to the MSR. */ #define ID16(MHz, mV, bus_clk) \ @@ -78,21 +86,22 @@ #define BUS333 33333 #define MSR2MHZ(msr, bus) \ - (((((int) (msr) >> 8) & 0xff) * (bus) + 50) / 100) -#define MSR2MV(msr) \ - (((int) (msr) & 0xff) * 16 + 700) + (((((int)(msr) >> 8) & 0xff) * (bus) + 50) / 100) + +struct est_op { + uint16_t ctrl; + uint16_t mhz; +}; struct fqlist { int vendor: 5; unsigned bus_clk : 1; unsigned n : 5; - const u_int16_t *table; + struct est_op *table; }; -static const struct fqlist *est_fqlist; -static u_int16_t fake_table[3]; -static struct fqlist fake_fqlist; +static struct fqlist *est_fqlist; extern int setperf_prio; extern int perflevel; @@ -206,21 +215,106 @@ p3_get_bus_clock(struct cpu_info *ci) break; } break; - default: + default: printf("%s: unknown i686 model 0x%x, can't get bus clock\n", ci->ci_dev->dv_xname, ci->ci_model); } } +#if NACPICPU > 0 +struct fqlist * est_acpi_init(void); +void est_acpi_pss_changed(struct acpicpu_pss *, int); + +struct fqlist * +est_acpi_init() +{ + struct acpicpu_pss *pss; + struct fqlist *acpilist; + int nstates, i; + + if ((nstates = acpicpu_fetch_pss(&pss)) == 0) + goto nolist; + + if ((acpilist = malloc(sizeof(struct fqlist), M_DEVBUF, M_NOWAIT)) + == NULL) + goto nolist; + + if ((acpilist->table = malloc(sizeof(struct est_op) * nstates, + M_DEVBUF, M_NOWAIT)) == NULL) + goto notable; + + acpilist->n = nstates; + + for (i = 0; i < nstates; i++) { + acpilist->table[i].mhz = pss[i].pss_core_freq; + acpilist->table[i].ctrl = pss[i].pss_ctrl; + } + + acpicpu_set_notify(est_acpi_pss_changed); + + return acpilist; + +notable: + free(acpilist, M_DEVBUF); + acpilist = NULL; +nolist: + return NULL; +} + +void +est_acpi_pss_changed(struct acpicpu_pss *pss, int npss) +{ + struct fqlist *acpilist; + int needtran = 1, nstates, i; + u_int64_t msr; + u_int16_t cur; + + msr = rdmsr(MSR_PERF_STATUS); + cur = msr & 0xffff; + + if ((acpilist = malloc(sizeof(struct fqlist), M_DEVBUF, M_NOWAIT)) + == NULL) { + printf("est_acpi_pss_changed: cannot allocate memory for new" + " est state"); + return; + } + + if ((acpilist->table = malloc(sizeof(struct est_op) * nstates, + M_DEVBUF, M_NOWAIT)) == NULL) { + printf("est_acpi_pss_changed: cannot allocate memory for new" + " operating points"); + free(acpilist, M_DEVBUF); + return; + } + + for (i = 0; i < nstates; i++) { + acpilist->table[i].mhz = pss[i].pss_core_freq; + acpilist->table[i].ctrl = pss[i].pss_ctrl; + if (pss[i].pss_ctrl == cur) + needtran = 0; + } + + free(est_fqlist->table, M_DEVBUF); + free(est_fqlist, M_DEVBUF); + est_fqlist = acpilist; + + if (needtran) { + est_setperf(perflevel); + } +} +#endif + 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, family; + int i, low, high, family; u_int64_t msr; u_int16_t idhi, idlo, cur; u_int8_t crhi, crlo, crcur; + struct fqlist *fake_fqlist; + struct est_op *fake_table; if (setperf_prio > 3) return; @@ -243,68 +337,98 @@ est_init(struct cpu_info *ci) crhi = (idhi >> 8) & 0xff; crlo = (idlo >> 8) & 0xff; crcur = (cur >> 8) & 0xff; - if (crlo == 0 || crhi == crlo) { - /* - * Don't complain about these cases, and silently disable EST: - * - A lowest clock ratio of 0, which seems to happen on all - * Pentium 4's that report EST. - * - An equal highest and lowest clock ratio, which happens on - * at least the Core 2 Duo X6800, maybe on newer models too. - */ - return; - } - if (crhi == 0 || crcur == 0 || crlo > crhi || - crcur < crlo || crcur > crhi) { - /* - * Do complain about other weirdness, because we first want to - * know about it, before we decide what to do with it. - */ - printf("%s: EST: strange msr value 0x%016llx\n", - cpu_device, msr); - return; - } + +#if NACPICPU > 0 + est_fqlist = est_acpi_init(); +#endif + if (est_fqlist == NULL) { + if (crhi == 0 || crcur == 0 || crlo > crhi || + crcur < crlo || crcur > crhi) { + /* + * Do complain about other weirdness, because we first + * want to know about it, before we decide what to do + * with it. + */ + printf("%s: EST: strange msr value 0x%016llx\n", + cpu_device, msr); + return; + } + if (crlo == 0 || crhi == crlo) { + /* + * Don't complain about these cases, and silently + * disable EST: - A lowest clock ratio of 0, which + * seems to happen on all Pentium 4's that report EST. + * - An equal highest and lowest clock ratio, which + * happens on at least the Core 2 Duo X6800, maybe on + * newer models too. + */ + return; + } + printf("%s: unknown Enhanced SpeedStep CPU, msr 0x%016llx\n", cpu_device, msr); - /* * Generate a fake table with the power states we know. */ - fake_table[0] = idhi; + + if ((fake_fqlist = malloc(sizeof(struct fqlist), M_DEVBUF, + M_NOWAIT)) == NULL) { + printf("%s: cannot allocate memory for fake list", + cpu_device); + return; + } + + + if ((fake_table = malloc(sizeof(struct est_op) * 3, M_DEVBUF, + M_NOWAIT)) == NULL) { + free(fake_fqlist, M_DEVBUF); + printf("%s: cannot allocate memory for fake table", + cpu_device); + return; + } + fake_table[0].ctrl = idhi; + fake_table[0].mhz = MSR2MHZ(idhi, bus_clock); if (cur == idhi || cur == idlo) { printf("%s: using only highest and lowest power " - "states\n", cpu_device); + "states\n", cpu_device); - fake_table[1] = idlo; - fake_fqlist.n = 2; + fake_table[1].ctrl = idlo; + fake_table[1].mhz = MSR2MHZ(idlo, bus_clock); + fake_fqlist->n = 2; } else { printf("%s: using only highest, current and lowest " "power states\n", cpu_device); - fake_table[1] = cur; - fake_table[2] = idlo; - fake_fqlist.n = 3; + fake_table[1].ctrl = cur; + fake_table[1].mhz = MSR2MHZ(cur, bus_clock); + + fake_table[2].ctrl = idlo; + fake_table[2].mhz = MSR2MHZ(idlo, bus_clock); + fake_fqlist->n = 3; } - fake_fqlist.vendor = vendor; - fake_fqlist.table = fake_table; - est_fqlist = &fake_fqlist; + + fake_fqlist->vendor = vendor; + fake_fqlist->table = fake_table; + est_fqlist = fake_fqlist; } - mhz = MSR2MHZ(cur, bus_clock); - mv = MSR2MV(cur); - printf("%s: Enhanced SpeedStep %d MHz (%d mV)", cpu_device, mhz, mv); + if (est_fqlist == NULL) + return; + + printf("%s: Enhanced SpeedStep %d MHz", cpu_device, cpuspeed); - low = MSR2MHZ(est_fqlist->table[est_fqlist->n - 1], bus_clock); - high = MSR2MHZ(est_fqlist->table[0], bus_clock); - perflevel = (mhz - low) * 100 / (high - low); + low = est_fqlist->table[est_fqlist->n - 1].mhz; + high = est_fqlist->table[0].mhz; + perflevel = (cpuspeed - low) * 100 / (high - low); /* * OK, tell the user the available frequencies. */ printf(": speeds: "); for (i = 0; i < est_fqlist->n; i++) - printf("%d%s", MSR2MHZ(est_fqlist->table[i], bus_clock), - i < est_fqlist->n - 1 ? ", " : " MHz\n"); + printf("%d%s", est_fqlist->table[i].mhz, i < est_fqlist->n - 1 + ? ", " : " MHz\n"); cpu_setperf = est_setperf; setperf_prio = 3; @@ -326,7 +450,8 @@ est_setperf(int level) msr = rdmsr(MSR_PERF_CTL); msr &= ~0xffffULL; - msr |= est_fqlist->table[i]; + msr |= est_fqlist->table[i].ctrl; + wrmsr(MSR_PERF_CTL, msr); - cpuspeed = MSR2MHZ(est_fqlist->table[i], bus_clock); + cpuspeed = est_fqlist->table[i].mhz; } diff --git a/sys/arch/i386/i386/est.c b/sys/arch/i386/i386/est.c index dfc27c6fd43..cadb224ecbf 100644 --- a/sys/arch/i386/i386/est.c +++ b/sys/arch/i386/i386/est.c @@ -1,4 +1,4 @@ -/* $OpenBSD: est.c,v 1.30 2007/06/07 11:20:58 dim Exp $ */ +/* $OpenBSD: est.c,v 1.31 2009/06/06 23:21:43 gwk Exp $ */ /* * Copyright (c) 2003 Michael Eriksson. * All rights reserved. @@ -56,26 +56,39 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/sysctl.h> +#include <sys/malloc.h> #include <machine/cpu.h> #include <machine/cpufunc.h> #include <machine/specialreg.h> +#include <machine/bus.h> +#include "acpicpu.h" + +#if NACPICPU > 0 +#include <dev/acpi/acpidev.h> +#include <dev/acpi/acpivar.h> +#endif /* Convert MHz and mV into IDs for passing to the MSR. */ #define ID16(MHz, mV, bus_clk) \ - ((((MHz * 100 + 50) / bus_clk) << 8) | ((mV ? mV - 700 : 0) >> 4)) + { ((((MHz * 100 + 50) / bus_clk) << 8) | ((mV ? mV - 700 : 0) >> 4)), \ + MHz } +struct est_op { + uint16_t ctrl; + uint16_t mhz; +}; /* Ultra Low Voltage Intel Pentium M processor 900 MHz */ -static const u_int16_t pm130_900_ulv[] = { +static struct est_op pm130_900_ulv[] = { ID16( 900, 1004, BUS100), ID16( 800, 988, BUS100), ID16( 600, 844, BUS100), }; /* Ultra Low Voltage Intel Pentium M processor 1.00 GHz */ -static const u_int16_t pm130_1000_ulv[] = { +static struct est_op pm130_1000_ulv[] = { ID16(1000, 1004, BUS100), ID16( 900, 988, BUS100), ID16( 800, 972, BUS100), @@ -83,7 +96,7 @@ static const u_int16_t pm130_1000_ulv[] = { }; /* Ultra Low Voltage Intel Pentium M processor 1.10 GHz */ -static const u_int16_t pm130_1100_ulv[] = { +static struct est_op pm130_1100_ulv[] = { ID16(1100, 1004, BUS100), ID16(1000, 988, BUS100), ID16( 900, 972, BUS100), @@ -92,7 +105,7 @@ static const u_int16_t pm130_1100_ulv[] = { }; /* Low Voltage Intel Pentium M processor 1.10 GHz */ -static const u_int16_t pm130_1100_lv[] = { +static struct est_op pm130_1100_lv[] = { ID16(1100, 1180, BUS100), ID16(1000, 1164, BUS100), ID16( 900, 1100, BUS100), @@ -101,7 +114,7 @@ static const u_int16_t pm130_1100_lv[] = { }; /* Low Voltage Intel Pentium M processor 1.20 GHz */ -static const u_int16_t pm130_1200_lv[] = { +static struct est_op pm130_1200_lv[] = { ID16(1200, 1180, BUS100), ID16(1100, 1164, BUS100), ID16(1000, 1100, BUS100), @@ -111,7 +124,7 @@ static const u_int16_t pm130_1200_lv[] = { }; /* Low Voltage Intel Pentium M processor 1.30 GHz */ -static const u_int16_t pm130_1300_lv[] = { +static struct est_op pm130_1300_lv[] = { ID16(1300, 1180, BUS100), ID16(1200, 1164, BUS100), ID16(1100, 1100, BUS100), @@ -122,7 +135,7 @@ static const u_int16_t pm130_1300_lv[] = { }; /* Intel Pentium M processor 1.30 GHz */ -static const u_int16_t pm130_1300[] = { +static struct est_op pm130_1300[] = { ID16(1300, 1388, BUS100), ID16(1200, 1356, BUS100), ID16(1000, 1292, BUS100), @@ -131,7 +144,7 @@ static const u_int16_t pm130_1300[] = { }; /* Intel Pentium M processor 1.40 GHz */ -static const u_int16_t pm130_1400[] = { +static struct est_op pm130_1400[] = { ID16(1400, 1484, BUS100), ID16(1200, 1436, BUS100), ID16(1000, 1308, BUS100), @@ -140,7 +153,7 @@ static const u_int16_t pm130_1400[] = { }; /* Intel Pentium M processor 1.50 GHz */ -static const u_int16_t pm130_1500[] = { +static struct est_op pm130_1500[] = { ID16(1500, 1484, BUS100), ID16(1400, 1452, BUS100), ID16(1200, 1356, BUS100), @@ -150,7 +163,7 @@ static const u_int16_t pm130_1500[] = { }; /* Intel Pentium M processor 1.60 GHz */ -static const u_int16_t pm130_1600[] = { +static struct est_op pm130_1600[] = { ID16(1600, 1484, BUS100), ID16(1400, 1420, BUS100), ID16(1200, 1276, BUS100), @@ -160,7 +173,7 @@ static const u_int16_t pm130_1600[] = { }; /* Intel Pentium M processor 1.70 GHz */ -static const u_int16_t pm130_1700[] = { +static struct est_op pm130_1700[] = { ID16(1700, 1484, BUS100), ID16(1400, 1308, BUS100), ID16(1200, 1228, BUS100), @@ -170,7 +183,7 @@ static const u_int16_t pm130_1700[] = { }; /* Intel Pentium M processor 723 1.0 GHz */ -static const u_int16_t pm90_n723[] = { +static struct est_op pm90_n723[] = { ID16(1000, 940, BUS100), ID16( 900, 908, BUS100), ID16( 800, 876, BUS100), @@ -178,7 +191,7 @@ static const u_int16_t pm90_n723[] = { }; /* Intel Pentium M processor 733 1.1 GHz, VID #G */ -static const u_int16_t pm90_n733g[] = { +static struct est_op pm90_n733g[] = { ID16(1100, 956, BUS100), ID16(1000, 940, BUS100), ID16( 900, 908, BUS100), @@ -187,7 +200,7 @@ static const u_int16_t pm90_n733g[] = { }; /* Intel Pentium M processor 733 1.1 GHz, VID #H */ -static const u_int16_t pm90_n733h[] = { +static struct est_op pm90_n733h[] = { ID16(1100, 940, BUS100), ID16(1000, 924, BUS100), ID16( 900, 892, BUS100), @@ -196,7 +209,7 @@ static const u_int16_t pm90_n733h[] = { }; /* Intel Pentium M processor 733 1.1 GHz, VID #I */ -static const u_int16_t pm90_n733i[] = { +static struct est_op pm90_n733i[] = { ID16(1100, 924, BUS100), ID16(1000, 908, BUS100), ID16( 900, 892, BUS100), @@ -205,7 +218,7 @@ static const u_int16_t pm90_n733i[] = { }; /* Intel Pentium M processor 733 1.1 GHz, VID #J */ -static const u_int16_t pm90_n733j[] = { +static struct est_op pm90_n733j[] = { ID16(1100, 908, BUS100), ID16(1000, 892, BUS100), ID16( 900, 876, BUS100), @@ -214,7 +227,7 @@ static const u_int16_t pm90_n733j[] = { }; /* Intel Pentium M processor 733 1.1 GHz, VID #K */ -static const u_int16_t pm90_n733k[] = { +static struct est_op pm90_n733k[] = { ID16(1100, 892, BUS100), ID16(1000, 876, BUS100), ID16( 900, 860, BUS100), @@ -223,7 +236,7 @@ static const u_int16_t pm90_n733k[] = { }; /* Intel Pentium M processor 733 1.1 GHz, VID #L */ -static const u_int16_t pm90_n733l[] = { +static struct est_op pm90_n733l[] = { ID16(1100, 876, BUS100), ID16(1000, 876, BUS100), ID16( 900, 860, BUS100), @@ -232,7 +245,7 @@ static const u_int16_t pm90_n733l[] = { }; /* Intel Pentium M processor 753 1.2 GHz, VID #G */ -static const u_int16_t pm90_n753g[] = { +static struct est_op pm90_n753g[] = { ID16(1200, 956, BUS100), ID16(1100, 940, BUS100), ID16(1000, 908, BUS100), @@ -242,7 +255,7 @@ static const u_int16_t pm90_n753g[] = { }; /* Intel Pentium M processor 753 1.2 GHz, VID #H */ -static const u_int16_t pm90_n753h[] = { +static struct est_op pm90_n753h[] = { ID16(1200, 940, BUS100), ID16(1100, 924, BUS100), ID16(1000, 908, BUS100), @@ -252,7 +265,7 @@ static const u_int16_t pm90_n753h[] = { }; /* Intel Pentium M processor 753 1.2 GHz, VID #I */ -static const u_int16_t pm90_n753i[] = { +static struct est_op pm90_n753i[] = { ID16(1200, 924, BUS100), ID16(1100, 908, BUS100), ID16(1000, 892, BUS100), @@ -262,7 +275,7 @@ static const u_int16_t pm90_n753i[] = { }; /* Intel Pentium M processor 753 1.2 GHz, VID #J */ -static const u_int16_t pm90_n753j[] = { +static struct est_op pm90_n753j[] = { ID16(1200, 908, BUS100), ID16(1100, 892, BUS100), ID16(1000, 876, BUS100), @@ -272,7 +285,7 @@ static const u_int16_t pm90_n753j[] = { }; /* Intel Pentium M processor 753 1.2 GHz, VID #K */ -static const u_int16_t pm90_n753k[] = { +static struct est_op pm90_n753k[] = { ID16(1200, 892, BUS100), ID16(1100, 892, BUS100), ID16(1000, 876, BUS100), @@ -282,7 +295,7 @@ static const u_int16_t pm90_n753k[] = { }; /* Intel Pentium M processor 753 1.2 GHz, VID #L */ -static const u_int16_t pm90_n753l[] = { +static struct est_op pm90_n753l[] = { ID16(1200, 876, BUS100), ID16(1100, 876, BUS100), ID16(1000, 860, BUS100), @@ -292,7 +305,7 @@ static const u_int16_t pm90_n753l[] = { }; /* Intel Pentium M processor 773 1.3 GHz, VID #G */ -static const u_int16_t pm90_n773g[] = { +static struct est_op pm90_n773g[] = { ID16(1300, 956, BUS100), ID16(1200, 940, BUS100), ID16(1100, 924, BUS100), @@ -303,7 +316,7 @@ static const u_int16_t pm90_n773g[] = { }; /* Intel Pentium M processor 773 1.3 GHz, VID #H */ -static const u_int16_t pm90_n773h[] = { +static struct est_op pm90_n773h[] = { ID16(1300, 940, BUS100), ID16(1200, 924, BUS100), ID16(1100, 908, BUS100), @@ -314,7 +327,7 @@ static const u_int16_t pm90_n773h[] = { }; /* Intel Pentium M processor 773 1.3 GHz, VID #I */ -static const u_int16_t pm90_n773i[] = { +static struct est_op pm90_n773i[] = { ID16(1300, 924, BUS100), ID16(1200, 908, BUS100), ID16(1100, 892, BUS100), @@ -325,7 +338,7 @@ static const u_int16_t pm90_n773i[] = { }; /* Intel Pentium M processor 773 1.3 GHz, VID #J */ -static const u_int16_t pm90_n773j[] = { +static struct est_op pm90_n773j[] = { ID16(1300, 908, BUS100), ID16(1200, 908, BUS100), ID16(1100, 892, BUS100), @@ -336,7 +349,7 @@ static const u_int16_t pm90_n773j[] = { }; /* Intel Pentium M processor 773 1.3 GHz, VID #K */ -static const u_int16_t pm90_n773k[] = { +static struct est_op pm90_n773k[] = { ID16(1300, 892, BUS100), ID16(1200, 892, BUS100), ID16(1100, 876, BUS100), @@ -347,7 +360,7 @@ static const u_int16_t pm90_n773k[] = { }; /* Intel Pentium M processor 773 1.3 GHz, VID #L */ -static const u_int16_t pm90_n773l[] = { +static struct est_op pm90_n773l[] = { ID16(1300, 876, BUS100), ID16(1200, 876, BUS100), ID16(1100, 860, BUS100), @@ -358,7 +371,7 @@ static const u_int16_t pm90_n773l[] = { }; /* Intel Pentium M processor 738 1.4 GHz */ -static const u_int16_t pm90_n738[] = { +static struct est_op pm90_n738[] = { ID16(1400, 1116, BUS100), ID16(1300, 1116, BUS100), ID16(1200, 1100, BUS100), @@ -370,7 +383,7 @@ static const u_int16_t pm90_n738[] = { }; /* Intel Pentium M processor 758 1.5 GHz */ -static const u_int16_t pm90_n758[] = { +static struct est_op pm90_n758[] = { ID16(1500, 1116, BUS100), ID16(1400, 1116, BUS100), ID16(1300, 1100, BUS100), @@ -383,7 +396,7 @@ static const u_int16_t pm90_n758[] = { }; /* Intel Pentium M processor 778 1.6 GHz */ -static const u_int16_t pm90_n778[] = { +static struct est_op pm90_n778[] = { ID16(1600, 1116, BUS100), ID16(1500, 1116, BUS100), ID16(1400, 1100, BUS100), @@ -397,7 +410,7 @@ static const u_int16_t pm90_n778[] = { }; /* Intel Pentium M processor 710 1.4 GHz, 533 MHz FSB */ -static const u_int16_t pm90_n710[] = { +static struct est_op pm90_n710[] = { ID16(1400, 1340, BUS133), ID16(1200, 1228, BUS133), ID16(1000, 1148, BUS133), @@ -406,7 +419,7 @@ static const u_int16_t pm90_n710[] = { }; /* Intel Pentium M processor 715 1.5 GHz, VID #A */ -static const u_int16_t pm90_n715a[] = { +static struct est_op pm90_n715a[] = { ID16(1500, 1340, BUS100), ID16(1200, 1228, BUS100), ID16(1000, 1148, BUS100), @@ -415,7 +428,7 @@ static const u_int16_t pm90_n715a[] = { }; /* Intel Pentium M processor 715 1.5 GHz, VID #B */ -static const u_int16_t pm90_n715b[] = { +static struct est_op pm90_n715b[] = { ID16(1500, 1324, BUS100), ID16(1200, 1212, BUS100), ID16(1000, 1148, BUS100), @@ -424,7 +437,7 @@ static const u_int16_t pm90_n715b[] = { }; /* Intel Pentium M processor 715 1.5 GHz, VID #C */ -static const u_int16_t pm90_n715c[] = { +static struct est_op pm90_n715c[] = { ID16(1500, 1308, BUS100), ID16(1200, 1212, BUS100), ID16(1000, 1132, BUS100), @@ -433,7 +446,7 @@ static const u_int16_t pm90_n715c[] = { }; /* Intel Pentium M processor 715 1.5 GHz, VID #D */ -static const u_int16_t pm90_n715d[] = { +static struct est_op pm90_n715d[] = { ID16(1500, 1276, BUS100), ID16(1200, 1180, BUS100), ID16(1000, 1116, BUS100), @@ -442,7 +455,7 @@ static const u_int16_t pm90_n715d[] = { }; /* Intel Pentium M processor 725 1.6 GHz, VID #A */ -static const u_int16_t pm90_n725a[] = { +static struct est_op pm90_n725a[] = { ID16(1600, 1340, BUS100), ID16(1400, 1276, BUS100), ID16(1200, 1212, BUS100), @@ -452,7 +465,7 @@ static const u_int16_t pm90_n725a[] = { }; /* Intel Pentium M processor 725 1.6 GHz, VID #B */ -static const u_int16_t pm90_n725b[] = { +static struct est_op pm90_n725b[] = { ID16(1600, 1324, BUS100), ID16(1400, 1260, BUS100), ID16(1200, 1196, BUS100), @@ -462,7 +475,7 @@ static const u_int16_t pm90_n725b[] = { }; /* Intel Pentium M processor 725 1.6 GHz, VID #C */ -static const u_int16_t pm90_n725c[] = { +static struct est_op pm90_n725c[] = { ID16(1600, 1308, BUS100), ID16(1400, 1244, BUS100), ID16(1200, 1180, BUS100), @@ -472,7 +485,7 @@ static const u_int16_t pm90_n725c[] = { }; /* Intel Pentium M processor 725 1.6 GHz, VID #D */ -static const u_int16_t pm90_n725d[] = { +static struct est_op pm90_n725d[] = { ID16(1600, 1276, BUS100), ID16(1400, 1228, BUS100), ID16(1200, 1164, BUS100), @@ -482,7 +495,7 @@ static const u_int16_t pm90_n725d[] = { }; /* Intel Pentium M processor 730 1.6 GHz, 533 MHz FSB */ -static const u_int16_t pm90_n730[] = { +static struct est_op pm90_n730[] = { ID16(1600, 1308, BUS133), ID16(1333, 1260, BUS133), ID16(1200, 1212, BUS133), @@ -491,7 +504,7 @@ static const u_int16_t pm90_n730[] = { }; /* Intel Pentium M processor 735 1.7 GHz, VID #A */ -static const u_int16_t pm90_n735a[] = { +static struct est_op pm90_n735a[] = { ID16(1700, 1340, BUS100), ID16(1400, 1244, BUS100), ID16(1200, 1180, BUS100), @@ -501,7 +514,7 @@ static const u_int16_t pm90_n735a[] = { }; /* Intel Pentium M processor 735 1.7 GHz, VID #B */ -static const u_int16_t pm90_n735b[] = { +static struct est_op pm90_n735b[] = { ID16(1700, 1324, BUS100), ID16(1400, 1244, BUS100), ID16(1200, 1180, BUS100), @@ -511,7 +524,7 @@ static const u_int16_t pm90_n735b[] = { }; /* Intel Pentium M processor 735 1.7 GHz, VID #C */ -static const u_int16_t pm90_n735c[] = { +static struct est_op pm90_n735c[] = { ID16(1700, 1308, BUS100), ID16(1400, 1228, BUS100), ID16(1200, 1164, BUS100), @@ -521,7 +534,7 @@ static const u_int16_t pm90_n735c[] = { }; /* Intel Pentium M processor 735 1.7 GHz, VID #D */ -static const u_int16_t pm90_n735d[] = { +static struct est_op pm90_n735d[] = { ID16(1700, 1276, BUS100), ID16(1400, 1212, BUS100), ID16(1200, 1148, BUS100), @@ -531,7 +544,7 @@ static const u_int16_t pm90_n735d[] = { }; /* Intel Pentium M processor 740 1.73 GHz, 533 MHz FSB */ -static const u_int16_t pm90_n740[] = { +static struct est_op pm90_n740[] = { ID16(1733, 1356, BUS133), ID16(1333, 1212, BUS133), ID16(1067, 1100, BUS133), @@ -539,7 +552,7 @@ static const u_int16_t pm90_n740[] = { }; /* Intel Pentium M processor 745 1.8 GHz, VID #A */ -static const u_int16_t pm90_n745a[] = { +static struct est_op pm90_n745a[] = { ID16(1800, 1340, BUS100), ID16(1600, 1292, BUS100), ID16(1400, 1228, BUS100), @@ -550,7 +563,7 @@ static const u_int16_t pm90_n745a[] = { }; /* Intel Pentium M processor 745 1.8 GHz, VID #B */ -static const u_int16_t pm90_n745b[] = { +static struct est_op pm90_n745b[] = { ID16(1800, 1324, BUS100), ID16(1600, 1276, BUS100), ID16(1400, 1212, BUS100), @@ -561,7 +574,7 @@ static const u_int16_t pm90_n745b[] = { }; /* Intel Pentium M processor 745 1.8 GHz, VID #C */ -static const u_int16_t pm90_n745c[] = { +static struct est_op pm90_n745c[] = { ID16(1800, 1308, BUS100), ID16(1600, 1260, BUS100), ID16(1400, 1212, BUS100), @@ -572,7 +585,7 @@ static const u_int16_t pm90_n745c[] = { }; /* Intel Pentium M processor 745 1.8 GHz, VID #D */ -static const u_int16_t pm90_n745d[] = { +static struct est_op pm90_n745d[] = { ID16(1800, 1276, BUS100), ID16(1600, 1228, BUS100), ID16(1400, 1180, BUS100), @@ -584,7 +597,7 @@ static const u_int16_t pm90_n745d[] = { /* Intel Pentium M processor 750 1.86 GHz, 533 MHz FSB */ /* values extracted from \_PR\NPSS (via _PSS) SDST ACPI table */ -static const u_int16_t pm90_n750[] = { +static struct est_op pm90_n750[] = { ID16(1867, 1308, BUS133), ID16(1600, 1228, BUS133), ID16(1333, 1148, BUS133), @@ -593,7 +606,7 @@ static const u_int16_t pm90_n750[] = { }; /* Intel Pentium M processor 755 2.0 GHz, VID #A */ -static const u_int16_t pm90_n755a[] = { +static struct est_op pm90_n755a[] = { ID16(2000, 1340, BUS100), ID16(1800, 1292, BUS100), ID16(1600, 1244, BUS100), @@ -605,7 +618,7 @@ static const u_int16_t pm90_n755a[] = { }; /* Intel Pentium M processor 755 2.0 GHz, VID #B */ -static const u_int16_t pm90_n755b[] = { +static struct est_op pm90_n755b[] = { ID16(2000, 1324, BUS100), ID16(1800, 1276, BUS100), ID16(1600, 1228, BUS100), @@ -617,7 +630,7 @@ static const u_int16_t pm90_n755b[] = { }; /* Intel Pentium M processor 755 2.0 GHz, VID #C */ -static const u_int16_t pm90_n755c[] = { +static struct est_op pm90_n755c[] = { ID16(2000, 1308, BUS100), ID16(1800, 1276, BUS100), ID16(1600, 1228, BUS100), @@ -629,7 +642,7 @@ static const u_int16_t pm90_n755c[] = { }; /* Intel Pentium M processor 755 2.0 GHz, VID #D */ -static const u_int16_t pm90_n755d[] = { +static struct est_op pm90_n755d[] = { ID16(2000, 1276, BUS100), ID16(1800, 1244, BUS100), ID16(1600, 1196, BUS100), @@ -641,7 +654,7 @@ static const u_int16_t pm90_n755d[] = { }; /* Intel Pentium M processor 760 2.0 GHz, 533 MHz FSB */ -static const u_int16_t pm90_n760[] = { +static struct est_op pm90_n760[] = { ID16(2000, 1356, BUS133), ID16(1600, 1244, BUS133), ID16(1333, 1164, BUS133), @@ -650,7 +663,7 @@ static const u_int16_t pm90_n760[] = { }; /* Intel Pentium M processor 765 2.1 GHz, VID #A */ -static const u_int16_t pm90_n765a[] = { +static struct est_op pm90_n765a[] = { ID16(2100, 1340, BUS100), ID16(1800, 1276, BUS100), ID16(1600, 1228, BUS100), @@ -662,7 +675,7 @@ static const u_int16_t pm90_n765a[] = { }; /* Intel Pentium M processor 765 2.1 GHz, VID #B */ -static const u_int16_t pm90_n765b[] = { +static struct est_op pm90_n765b[] = { ID16(2100, 1324, BUS100), ID16(1800, 1260, BUS100), ID16(1600, 1212, BUS100), @@ -674,7 +687,7 @@ static const u_int16_t pm90_n765b[] = { }; /* Intel Pentium M processor 765 2.1 GHz, VID #C */ -static const u_int16_t pm90_n765c[] = { +static struct est_op pm90_n765c[] = { ID16(2100, 1308, BUS100), ID16(1800, 1244, BUS100), ID16(1600, 1212, BUS100), @@ -686,7 +699,7 @@ static const u_int16_t pm90_n765c[] = { }; /* Intel Pentium M processor 765 2.1 GHz, VID #E */ -static const u_int16_t pm90_n765e[] = { +static struct est_op pm90_n765e[] = { ID16(2100, 1356, BUS100), ID16(1800, 1292, BUS100), ID16(1600, 1244, BUS100), @@ -698,7 +711,7 @@ static const u_int16_t pm90_n765e[] = { }; /* Intel Pentium M processor 770 2.13 GHz */ -static const u_int16_t pm90_n770[] = { +static struct est_op pm90_n770[] = { ID16(2133, 1356, BUS133), ID16(1867, 1292, BUS133), ID16(1600, 1212, BUS133), @@ -713,7 +726,7 @@ static const u_int16_t pm90_n770[] = { */ /* 1.00GHz Centaur C7-M ULV */ -static const u_int16_t C7M_770_ULV[] = { +static struct est_op C7M_770_ULV[] = { ID16(1000, 844, BUS100), ID16( 800, 796, BUS100), ID16( 600, 796, BUS100), @@ -721,7 +734,7 @@ static const u_int16_t C7M_770_ULV[] = { }; /* 1.00GHz Centaur C7-M ULV */ -static const u_int16_t C7M_779_ULV[] = { +static struct est_op C7M_779_ULV[] = { ID16(1000, 796, BUS100), ID16( 800, 796, BUS100), ID16( 600, 796, BUS100), @@ -729,7 +742,7 @@ static const u_int16_t C7M_779_ULV[] = { }; /* 1.20GHz Centaur C7-M ULV */ -static const u_int16_t C7M_772_ULV[] = { +static struct est_op C7M_772_ULV[] = { ID16(1200, 844, BUS100), ID16(1000, 844, BUS100), ID16( 800, 828, BUS100), @@ -738,7 +751,7 @@ static const u_int16_t C7M_772_ULV[] = { }; /* 1.50GHz Centaur C7-M ULV */ -static const u_int16_t C7M_775_ULV[] = { +static struct est_op C7M_775_ULV[] = { ID16(1500, 956, BUS100), ID16(1400, 940, BUS100), ID16(1000, 860, BUS100), @@ -748,7 +761,7 @@ static const u_int16_t C7M_775_ULV[] = { }; /* 1.20GHz Centaur C7-M 400 MHz FSB */ -static const u_int16_t C7M_771[] = { +static struct est_op C7M_771[] = { ID16(1200, 860, BUS100), ID16(1000, 860, BUS100), ID16( 800, 844, BUS100), @@ -757,7 +770,7 @@ static const u_int16_t C7M_771[] = { }; /* 1.50GHz Centaur C7-M 400 MHz FSB */ -static const u_int16_t C7M_754[] = { +static struct est_op C7M_754[] = { ID16(1500, 1004, BUS100), ID16(1400, 988, BUS100), ID16(1000, 940, BUS100), @@ -767,7 +780,7 @@ static const u_int16_t C7M_754[] = { }; /* 1.60GHz Centaur C7-M 400 MHz FSB */ -static const u_int16_t C7M_764[] = { +static struct est_op C7M_764[] = { ID16(1600, 1084, BUS100), ID16(1400, 1052, BUS100), ID16(1000, 1004, BUS100), @@ -777,7 +790,7 @@ static const u_int16_t C7M_764[] = { }; /* 1.80GHz Centaur C7-M 400 MHz FSB */ -static const u_int16_t C7M_784[] = { +static struct est_op C7M_784[] = { ID16(1800, 1148, BUS100), ID16(1600, 1100, BUS100), ID16(1400, 1052, BUS100), @@ -788,7 +801,7 @@ static const u_int16_t C7M_784[] = { }; /* 2.00GHz Centaur C7-M 400 MHz FSB */ -static const u_int16_t C7M_794[] = { +static struct est_op C7M_794[] = { ID16(2000, 1148, BUS100), ID16(1800, 1132, BUS100), ID16(1600, 1100, BUS100), @@ -800,7 +813,7 @@ static const u_int16_t C7M_794[] = { }; /* 1.60GHz Centaur C7-M 533 MHz FSB */ -static const u_int16_t C7M_765[] = { +static struct est_op C7M_765[] = { ID16(1600, 1084, BUS133), ID16(1467, 1052, BUS133), ID16(1200, 1004, BUS133), @@ -810,7 +823,7 @@ static const u_int16_t C7M_765[] = { }; /* 2.00GHz Centaur C7-M 533 MHz FSB */ -static const u_int16_t C7M_785[] = { +static struct est_op C7M_785[] = { ID16(1867, 1148, BUS133), ID16(1600, 1100, BUS133), ID16(1467, 1052, BUS133), @@ -821,7 +834,7 @@ static const u_int16_t C7M_785[] = { }; /* 2.00GHz Centaur C7-M 533 MHz FSB */ -static const u_int16_t C7M_795[] = { +static struct est_op C7M_795[] = { ID16(2000, 1148, BUS133), ID16(1867, 1132, BUS133), ID16(1600, 1100, BUS133), @@ -833,18 +846,19 @@ static const u_int16_t C7M_795[] = { }; /* 1.00GHz VIA Eden 90nm 'Esther' */ -static const u_int16_t eden90_1000[] = { +static struct est_op eden90_1000[] = { ID16(1000, 844, BUS100), ID16( 800, 844, BUS100), ID16( 600, 844, BUS100), ID16( 400, 844, BUS100), }; + struct fqlist { - int vendor : 5; + int vendor: 5; unsigned bus_clk : 1; unsigned n : 5; - const u_int16_t *table; + struct est_op *table; }; #define NELEM(x) (sizeof(x) / sizeof((x)[0])) @@ -854,7 +868,7 @@ struct fqlist { #define BUS_CLK(fqp) ((fqp)->bus_clk ? BUS133 : BUS100) -static const struct fqlist est_cpus[] = { +static struct fqlist est_cpus[] = { ENTRY(INTEL, BUS100, pm130_900_ulv), ENTRY(INTEL, BUS100, pm130_1000_ulv), ENTRY(INTEL, BUS100, pm130_1100_ulv), @@ -937,28 +951,109 @@ static const struct fqlist est_cpus[] = { ENTRY(VIA, BUS100, eden90_1000), }; - #define MSR2MHZ(msr, bus) \ (((((int) (msr) >> 8) & 0xff) * (bus) + 50) / 100) #define MSR2MV(msr) \ (((int) (msr) & 0xff) * 16 + 700) -static const struct fqlist *est_fqlist; - -static u_int16_t fake_table[3]; -static struct fqlist fake_fqlist; +static struct fqlist *est_fqlist; extern int setperf_prio; extern int perflevel; +#if NACPICPU > 0 +struct fqlist * est_acpi_init(void); +void est_acpi_pss_changed(struct acpicpu_pss *, int); + +struct fqlist * +est_acpi_init() +{ + struct acpicpu_pss *pss; + struct fqlist *acpilist; + int nstates, i; + + if ((nstates = acpicpu_fetch_pss(&pss)) == 0) + goto nolist; + + if ((acpilist = malloc(sizeof(struct fqlist), M_DEVBUF, M_NOWAIT)) + == NULL) + goto nolist; + + if ((acpilist->table = malloc(sizeof( struct est_op) * nstates, + M_DEVBUF, M_NOWAIT)) == NULL) + goto notable; + + acpilist->n = nstates; + + for (i = 0; i < nstates; i++) { + acpilist->table[i].mhz = pss[i].pss_core_freq; + acpilist->table[i].ctrl = pss[i].pss_ctrl; + } + + acpicpu_set_notify(est_acpi_pss_changed); + + return acpilist; + +notable: + free(acpilist, M_DEVBUF); + acpilist = NULL; +nolist: + return NULL; +} + +void +est_acpi_pss_changed(struct acpicpu_pss *pss, int npss) +{ + struct fqlist *acpilist; + int needtran = 1, nstates, i; + u_int64_t msr; + u_int16_t cur; + + msr = rdmsr(MSR_PERF_STATUS); + cur = msr & 0xffff; + + if ((acpilist = malloc(sizeof(struct fqlist), M_DEVBUF, M_NOWAIT)) + == NULL) { + printf("est_acpi_pss_changed: cannot allocate memory for new " + "est state"); + return; + } + + if ((acpilist->table = malloc(sizeof( struct est_op) * nstates, + M_DEVBUF, M_NOWAIT)) == NULL) { + printf("est_acpi_pss_changed: cannot allocate memory for new " + "operating points"); + free(acpilist, M_DEVBUF); + return; + } + + for (i = 0; i < nstates; i++) { + acpilist->table[i].mhz = pss[i].pss_core_freq; + acpilist->table[i].ctrl = pss[i].pss_ctrl; + if (pss[i].pss_ctrl == cur) + needtran = 0; + } + + free(est_fqlist->table, M_DEVBUF); + free(est_fqlist, M_DEVBUF); + est_fqlist = acpilist; + + if (needtran) { + est_setperf(perflevel); + } +} +#endif + void est_init(const char *cpu_device, int vendor) { - int i, mhz, mv, low, high; + int i, low, high; u_int64_t msr; u_int16_t idhi, idlo, cur; u_int8_t crhi, crlo, crcur; - const struct fqlist *fql; + struct fqlist *fql; + struct fqlist *fake_fqlist; + struct est_op *fake_table; if (setperf_prio > 3) return; @@ -966,11 +1061,6 @@ est_init(const char *cpu_device, int vendor) if ((cpu_ecxfeature & CPUIDECX_EST) == 0) return; - if (bus_clock == 0) { - printf("%s: EST: unknown system bus clock\n", cpu_device); - return; - } - msr = rdmsr(MSR_PERF_STATUS); idhi = (msr >> 32) & 0xffff; idlo = (msr >> 48) & 0xffff; @@ -978,90 +1068,118 @@ est_init(const char *cpu_device, int vendor) crhi = (idhi >> 8) & 0xff; crlo = (idlo >> 8) & 0xff; crcur = (cur >> 8) & 0xff; - if (crlo == 0 || crhi == crlo) { - /* - * Don't complain about these cases, and silently disable EST: - * - A lowest clock ratio of 0, which seems to happen on all - * Pentium 4's that report EST. - * - An equal highest and lowest clock ratio, which happens on - * at least the Core 2 Duo X6800, maybe on newer models too. - */ - return; - } - if (crhi == 0 || crcur == 0 || crlo > crhi || - crcur < crlo || crcur > crhi) { + +#if NACPICPU > 0 + est_fqlist = est_acpi_init(); +#endif + + if (est_fqlist == NULL) { /* - * Do complain about other weirdness, because we first want to - * know about it, before we decide what to do with it. + * Find an entry which matches (vendor, bus_clock, idhi, idlo) */ - printf("%s: EST: strange msr value 0x%016llx\n", - cpu_device, msr); - return; - } - /* - * Find an entry which matches (vendor, bus_clock, idhi, idlo) - */ - for (i = 0; i < NELEM(est_cpus); i++) { - fql = &est_cpus[i]; - if (vendor == fql->vendor && bus_clock == BUS_CLK(fql) && - idhi == fql->table[0] && idlo == fql->table[fql->n - 1]) { - est_fqlist = fql; - break; + for (i = 0; i < NELEM(est_cpus); i++) { + fql = &est_cpus[i]; + if (vendor == fql->vendor && bus_clock == BUS_CLK(fql) + && idhi == fql->table[0].ctrl + && idlo == fql->table[fql->n - 1].ctrl) { + est_fqlist = fql; + break; + } } } + if (est_fqlist == NULL) { + if (bus_clock == 0) { + printf("%s: EST: unknown system bus clock\n", + cpu_device); + return; + } + if (crhi == 0 || crcur == 0 || crlo > crhi || + crcur < crlo || crcur > crhi) { + /* + * Do complain about other weirdness, because we first + * want to know about it, before we decide what to do + * with it. + */ + printf("%s: EST: strange msr value 0x%016llx\n", + cpu_device, msr); + return; + } + if (crlo == 0 || crhi == crlo) { + /* + * Don't complain about these cases, and silently + * disable EST: - A lowest clock ratio of 0, which + * seems to happen on all Pentium 4's that report EST. + * - And equal highest and lowest clock ratio, which + * happens on at least the Core 2 Duo X6800, maybe on + * newer models too. + */ + return; + } + printf("%s: unknown Enhanced SpeedStep CPU, msr 0x%016llx\n", cpu_device, msr); - /* * Generate a fake table with the power states we know. */ - fake_table[0] = idhi; + + if ((fake_fqlist = malloc(sizeof(struct fqlist), M_DEVBUF, + M_NOWAIT)) == NULL) { + printf("%s: EST: cannot allocate memory for fake list", + cpu_device); + return; + } + + + if ((fake_table = malloc(sizeof(struct est_op) * 3, M_DEVBUF, + M_NOWAIT)) == NULL) { + free(fake_fqlist, M_DEVBUF); + printf("%s: EST: cannot allocate memory for fake " + "table\n", cpu_device); + return; + } + fake_table[0].ctrl = idhi; + fake_table[0].mhz = MSR2MHZ(idhi, bus_clock); if (cur == idhi || cur == idlo) { printf("%s: using only highest and lowest power " - "states\n", cpu_device); + "states\n", cpu_device); - fake_table[1] = idlo; - fake_fqlist.n = 2; + fake_table[1].ctrl = idlo; + fake_table[1].mhz = MSR2MHZ(idlo, bus_clock); + fake_fqlist->n = 2; } else { printf("%s: using only highest, current and lowest " "power states\n", cpu_device); - fake_table[1] = cur; - fake_table[2] = idlo; - fake_fqlist.n = 3; - } - fake_fqlist.vendor = vendor; - fake_fqlist.table = fake_table; - est_fqlist = &fake_fqlist; - } + fake_table[1].ctrl = cur; + fake_table[1].mhz = MSR2MHZ(cur, bus_clock); - mhz = MSR2MHZ(cur, bus_clock); - mv = MSR2MV(cur); - printf("%s: Enhanced SpeedStep %d MHz (%d mV)", cpu_device, mhz, mv); + fake_table[2].ctrl = idlo; + fake_table[2].mhz = MSR2MHZ(idlo, bus_clock); + fake_fqlist->n = 3; + } - /* - * Check that the current operating point is in our list. - */ - for (i = est_fqlist->n - 1; i >= 0; i--) { - if (cur == est_fqlist->table[i]) - break; + fake_fqlist->vendor = vendor; + fake_fqlist->table = fake_table; + est_fqlist = fake_fqlist; } - if (i < 0) { - printf(" (not in table, msr 0x%016llx)\n", msr); + + if (est_fqlist == NULL) return; - } - low = MSR2MHZ(est_fqlist->table[est_fqlist->n - 1], bus_clock); - high = MSR2MHZ(est_fqlist->table[0], bus_clock); - perflevel = (mhz - low) * 100 / (high - low); + + printf("%s: Enhanced SpeedStep %d MHz", cpu_device, cpuspeed); + + low = est_fqlist->table[est_fqlist->n - 1].mhz; + high = est_fqlist->table[0].mhz; + perflevel = (cpuspeed - low) * 100 / (high - low); /* * OK, tell the user the available frequencies. */ printf(": speeds: "); for (i = 0; i < est_fqlist->n; i++) - printf("%d%s", MSR2MHZ(est_fqlist->table[i], bus_clock), - i < est_fqlist->n - 1 ? ", " : " MHz\n"); + printf("%d%s", est_fqlist->table[i].mhz, i < est_fqlist->n - 1 + ? ", " : " MHz\n"); cpu_setperf = est_setperf; setperf_prio = 3; @@ -1083,7 +1201,8 @@ est_setperf(int level) msr = rdmsr(MSR_PERF_CTL); msr &= ~0xffffULL; - msr |= est_fqlist->table[i]; + msr |= est_fqlist->table[i].ctrl; + wrmsr(MSR_PERF_CTL, msr); - cpuspeed = MSR2MHZ(est_fqlist->table[i], bus_clock); + cpuspeed = est_fqlist->table[i].mhz; } |