summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2003-12-18 23:46:21 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2003-12-18 23:46:21 +0000
commit5e003feba9b898fea84451fb88281e082b5c6f76 (patch)
treebd9cb881f2cc727cd0356ab3f5af3ed669f88865 /sys
parentd4f77d8f88b7b64d13463adb7816adbae01ca8bc (diff)
add new hw sysctls, cpuspeed and setperf to control cpu frequency.
convert longrun support to use new sysctls. add enhanced speedstep support, based on code by Michael Eriksson. idea, help testing & ok deraadt@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/i386/conf/files.i3865
-rw-r--r--sys/arch/i386/i386/est.c304
-rw-r--r--sys/arch/i386/i386/longrun.c99
-rw-r--r--sys/arch/i386/i386/machdep.c35
-rw-r--r--sys/arch/i386/include/cpu.h19
-rw-r--r--sys/arch/i386/include/specialreg.h9
-rw-r--r--sys/kern/kern_sysctl.c13
-rw-r--r--sys/sys/sysctl.h8
8 files changed, 403 insertions, 89 deletions
diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386
index ace7202d277..0b11c68a493 100644
--- a/sys/arch/i386/conf/files.i386
+++ b/sys/arch/i386/conf/files.i386
@@ -1,4 +1,4 @@
-# $OpenBSD: files.i386,v 1.109 2003/11/03 03:35:40 tedu Exp $
+# $OpenBSD: files.i386,v 1.110 2003/12/18 23:46:19 tedu Exp $
# $NetBSD: files.i386,v 1.73 1996/05/07 00:58:36 thorpej Exp $
#
# new style config file for i386 architecture
@@ -19,12 +19,13 @@ file arch/i386/i386/db_memrw.c ddb | kgdb
file arch/i386/i386/db_trace.c ddb
file arch/i386/i386/db_magic.s ddb
file arch/i386/i386/disksubr.c disk
+file arch/i386/i386/est.c !small_kernel & i686_cpu
file arch/i386/i386/gdt.c
file arch/i386/i386/in_cksum.s inet
file arch/i386/i386/ipx_cksum.c ipx
file arch/i386/i386/machdep.c
file arch/i386/i386/kgdb_machdep.c kgdb
-file arch/i386/i386/longrun.c !small_kernel
+file arch/i386/i386/longrun.c !small_kernel & i586_cpu
file arch/i386/i386/mem.c
file arch/i386/i386/i686_mem.c mtrr
file arch/i386/i386/k6_mem.c mtrr
diff --git a/sys/arch/i386/i386/est.c b/sys/arch/i386/i386/est.c
new file mode 100644
index 00000000000..220e35f12fb
--- /dev/null
+++ b/sys/arch/i386/i386/est.c
@@ -0,0 +1,304 @@
+/* $OpenBSD: est.c,v 1.1 2003/12/18 23:46:19 tedu Exp $ */
+/*
+ * Copyright (c) 2003 Michael Eriksson.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/*
+ * This is a driver for Intel's Enhanced SpeedStep, as implemented in
+ * Pentium M processors.
+ *
+ * Reference documentation:
+ *
+ * - IA-32 Intel Architecture Software Developer's Manual, Volume 3:
+ * System Programming Guide.
+ * Section 13.14, Enhanced Intel SpeedStep technology.
+ * Table B-2, MSRs in Pentium M Processors.
+ * http://www.intel.com/design/pentium4/manuals/245472.htm
+ *
+ * - Intel Pentium M Processor Datasheet.
+ * Table 5, Voltage and Current Specifications.
+ * http://www.intel.com/design/mobile/datashts/252612.htm
+ *
+ * - Linux cpufreq patches, speedstep-centrino.c.
+ * Encoding of MSR_PERF_CTL and MSR_PERF_STATUS.
+ * http://www.codemonkey.org.uk/projects/cpufreq/cpufreq-2.4.22-pre6-1.gz
+ */
+
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysctl.h>
+
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/specialreg.h>
+
+
+struct fq_info {
+ u_short mhz;
+ u_short mv;
+};
+
+/* Ultra Low Voltage Intel Pentium M processor 900 MHz */
+static const struct fq_info pentium_m_900[] = {
+ { 900, 1004 },
+ { 800, 988 },
+ { 600, 844 },
+};
+
+/* Ultra Low Voltage Intel Pentium M processor 1.00 GHz */
+static const struct fq_info pentium_m_1000[] = {
+ { 1000, 1004 },
+ { 900, 988 },
+ { 800, 972 },
+ { 600, 844 },
+};
+
+/* Low Voltage Intel Pentium M processor 1.10 GHz */
+static const struct fq_info pentium_m_1100[] = {
+ { 1100, 1180 },
+ { 1000, 1164 },
+ { 900, 1100 },
+ { 800, 1020 },
+ { 600, 956 },
+};
+
+/* Low Voltage Intel Pentium M processor 1.20 GHz */
+static const struct fq_info pentium_m_1200[] = {
+ { 1200, 1180 },
+ { 1100, 1164 },
+ { 1000, 1100 },
+ { 900, 1020 },
+ { 800, 1004 },
+ { 600, 956 },
+};
+
+/* Intel Pentium M processor 1.30 GHz */
+static const struct fq_info pentium_m_1300[] = {
+ { 1300, 1388 },
+ { 1200, 1356 },
+ { 1000, 1292 },
+ { 800, 1260 },
+ { 600, 956 },
+};
+
+/* Intel Pentium M processor 1.40 GHz */
+static const struct fq_info pentium_m_1400[] = {
+ { 1400, 1484 },
+ { 1200, 1436 },
+ { 1000, 1308 },
+ { 800, 1180 },
+ { 600, 956 }
+};
+
+/* Intel Pentium M processor 1.50 GHz */
+static const struct fq_info pentium_m_1500[] = {
+ { 1500, 1484 },
+ { 1400, 1452 },
+ { 1200, 1356 },
+ { 1000, 1228 },
+ { 800, 1116 },
+ { 600, 956 }
+};
+
+/* Intel Pentium M processor 1.60 GHz */
+static const struct fq_info pentium_m_1600[] = {
+ { 1600, 1484 },
+ { 1400, 1420 },
+ { 1200, 1276 },
+ { 1000, 1164 },
+ { 800, 1036 },
+ { 600, 956 }
+};
+
+/* Intel Pentium M processor 1.70 GHz */
+static const struct fq_info pentium_m_1700[] = {
+ { 1700, 1484 },
+ { 1400, 1308 },
+ { 1200, 1228 },
+ { 1000, 1116 },
+ { 800, 1004 },
+ { 600, 956 }
+};
+
+
+struct fqlist {
+ const char *brand_tag;
+ const struct fq_info *table;
+ u_int n;
+};
+
+static const struct fqlist pentium_m[] = {
+#define ENTRY(s, v) { s, sizeof(v) / sizeof((v)[0]), v }
+ ENTRY(" 900", pentium_m_900),
+ ENTRY("1000", pentium_m_1000),
+ ENTRY("1100", pentium_m_1100),
+ ENTRY("1200", pentium_m_1200),
+ ENTRY("1300", pentium_m_1300),
+ ENTRY("1400", pentium_m_1400),
+ ENTRY("1500", pentium_m_1500),
+ ENTRY("1600", pentium_m_1600),
+ ENTRY("1700", pentium_m_1700),
+#undef ENTRY
+};
+
+
+struct est_cpu {
+ const char *brand_prefix;
+ const char *brand_suffix;
+ const struct fqlist *list;
+ int n;
+};
+
+static const struct est_cpu est_cpus[] = {
+ {
+ "Intel(R) Pentium(R) M processor ", "MHz",
+ (sizeof(pentium_m) / sizeof(pentium_m[0])),
+ pentium_m
+ },
+};
+
+#define NESTCPUS (sizeof(est_cpus) / sizeof(est_cpus[0]))
+
+
+#define MSRVALUE(mhz, mv) ((((mhz) / 100) << 8) | (((mv) - 700) / 16))
+#define MSR2MHZ(msr) ((((int) (msr) >> 8) & 0xff) * 100)
+#define MSR2MV(msr) (((int) (msr) & 0xff) * 16 + 700)
+
+static const struct fqlist *est_fqlist;
+
+extern int (*cpu_cpuspeed)(void *, size_t *, void *, size_t);
+extern int (*cpu_setperf)(void *, size_t *, void *, size_t);
+
+void
+est_init(const char *cpu_device)
+{
+ int i, j, n, mhz, mv;
+ const struct est_cpu *cpu;
+ u_int64_t msr;
+ char *tag;
+ const struct fqlist *fql;
+ extern int cpu_ecxfeature;
+ extern char cpu_brandstr[];
+
+ if ((cpu_ecxfeature & CPUIDECX_EST) == 0)
+ return;
+
+ msr = rdmsr(MSR_PERF_STATUS);
+ mhz = MSR2MHZ(msr);
+ mv = MSR2MV(msr);
+ printf("%s: Enhanced SpeedStep %d MHz (%d mV)",
+ cpu_device, mhz, mv);
+
+ /*
+ * Look for a CPU matching cpu_brandstr.
+ */
+ for (i = 0; est_fqlist == NULL && i < NESTCPUS; i++) {
+ cpu = &est_cpus[i];
+ n = strlen(cpu->brand_prefix);
+ if (strncmp(cpu->brand_prefix, cpu_brandstr, n) != 0)
+ continue;
+ tag = cpu_brandstr + n;
+ for (j = 0; j < cpu->n; j++) {
+ fql = &cpu->list[j];
+ n = strlen(fql->brand_tag);
+ if (!strncmp(fql->brand_tag, tag, n) &&
+ !strcmp(cpu->brand_suffix, tag + n)) {
+ est_fqlist = fql;
+ break;
+ }
+ }
+ }
+ if (est_fqlist == NULL) {
+ printf(": unknown EST cpu, no changes possible\n");
+ return;
+ }
+
+ /*
+ * Check that the current operating point is in our list.
+ */
+ for (i = est_fqlist->n - 1; i >= 0; i--)
+ if (est_fqlist->table[i].mhz == mhz &&
+ est_fqlist->table[i].mv == mv)
+ break;
+ if (i < 0) {
+ printf(" (not in table)\n");
+ return;
+ }
+
+ /*
+ * OK, tell the user the available frequencies.
+ */
+ printf(": speeds: ");
+ for (i = 0; i < est_fqlist->n; i++)
+ printf("%d%s", est_fqlist->table[i].mhz,
+ i < est_fqlist->n - 1 ? ", " : " MHz\n");
+
+ cpu_setperf = est_setperf;
+ cpu_cpuspeed = est_cpuspeed;
+}
+
+int
+est_setperf(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
+{
+ static uint level = 100;
+ int low, high, i, fq, error;
+ uint64_t msr;
+
+ if (est_fqlist == NULL)
+ return (EOPNOTSUPP);
+
+ error = sysctl_int(oldp, oldlenp, newp, newlen, &level);
+ if (error)
+ return (error);
+
+ if (level > 100)
+ level = 100;
+ low = est_fqlist->table[est_fqlist->n - 1].mhz;
+ high = est_fqlist->table[0].mhz;
+ fq = low + (high - low) * level / 100;
+
+ for (i = est_fqlist->n - 1; i > 0; i--)
+ if (est_fqlist->table[i].mhz >= fq)
+ break;
+ msr = (rdmsr(MSR_PERF_CTL) & ~0xffffULL) |
+ MSRVALUE(est_fqlist->table[i].mhz, est_fqlist->table[i].mv);
+ wrmsr(MSR_PERF_CTL, msr);
+
+ return (0);
+}
+
+
+int
+est_cpuspeed(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
+{
+ int freq;
+
+ freq = MSR2MHZ(rdmsr(MSR_PERF_STATUS));
+
+ return (sysctl_rdint(oldp, oldlenp, newp, freq));
+}
diff --git a/sys/arch/i386/i386/longrun.c b/sys/arch/i386/i386/longrun.c
index ef13a266eb4..9872eefb910 100644
--- a/sys/arch/i386/i386/longrun.c
+++ b/sys/arch/i386/i386/longrun.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: longrun.c,v 1.5 2003/10/24 09:03:20 grange Exp $ */
+/* $OpenBSD: longrun.c,v 1.6 2003/12/18 23:46:19 tedu Exp $ */
/*
* Copyright (c) 2003 Ted Unangst
* Copyright (c) 2001 Tamotsu Hattori
@@ -30,16 +30,9 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/sysctl.h>
#include <machine/cpufunc.h>
-#include <machine/longrun.h>
-
-static void longrun_getmode(u_int32_t *, u_int32_t *, u_int32_t *);
-static void longrun_setmode(u_int32_t, u_int32_t, u_int32_t);
-int longrun_sysctl(void *, size_t *, void *, size_t);
-
-int longrun_enabled;
-
union msrinfo {
u_int64_t msr;
uint32_t regs[2];
@@ -55,62 +48,27 @@ union msrinfo {
#define LONGRUN_MODE_RESERVED(x) ((x) & 0xffffff80)
#define LONGRUN_MODE_WRITE(x, y) (LONGRUN_MODE_RESERVED(x) | LONGRUN_MODE_MASK(y))
-/*
- * sysctl handler and entry point. Just call the right function
- */
-int longrun_sysctl(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
-{
- struct longrun oinfo;
- struct longrun ninfo;
- int error;
-
- if (!longrun_enabled)
- return (EINVAL);
-
- if (oldp && *oldlenp < sizeof(oinfo))
- return (ENOMEM);
- *oldlenp = sizeof(oinfo);
-
- if (newp != NULL) {
- error = copyin(newp, &ninfo, sizeof(ninfo));
- if (error)
- return (error);
- longrun_setmode(ninfo.low, ninfo.high, ninfo.mode);
- }
-
- if (oldp != NULL) {
- memset(&oinfo, 0, sizeof(oinfo));
- longrun_getmode(&oinfo.freq, &oinfo.voltage, &oinfo.percent);
- error = copyout(&oinfo, oldp, sizeof(oinfo));
- }
-
- return (error);
-
-}
-
/*
* These are the instantaneous values used by the CPU.
- * Frequency is self-evident.
- * Voltage is returned in millivolts.
- * Percent is amount of performance window being used, not percentage
- * of top megahertz. (0 values are typical.)
+ * regs[0] = Frequency is self-evident.
+ * regs[1] = Voltage is returned in millivolts.
+ * regs[2] = Percent is amount of performance window being used, not
+ * percentage of top megahertz. (0 values are typical.)
*/
-static void
-longrun_getmode(u_int32_t *freq, u_int32_t *voltage, u_int32_t *percent)
+int
+longrun_cpuspeed(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
{
- u_long eflags;
- u_int32_t regs[4];
+ uint32_t eflags, freq, regs[4];
eflags = read_eflags();
disable_intr();
-
cpuid(0x80860007, regs);
- *freq = regs[0];
- *voltage = regs[1];
- *percent = regs[2];
-
enable_intr();
write_eflags(eflags);
+
+ freq = regs[0];
+
+ return (sysctl_rdint(oldp, oldlenp, newp, freq));
}
/*
@@ -121,21 +79,32 @@ longrun_getmode(u_int32_t *freq, u_int32_t *voltage, u_int32_t *percent)
* limits it handles. Typically, there are about 5 performance
* levels selectable.
*/
-static void
-longrun_setmode(u_int32_t low, u_int32_t high, u_int32_t mode)
+int
+longrun_setperf(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
{
- u_long eflags;
- union msrinfo msrinfo;
+ int error;
+ uint32_t eflags, mode;
+ union msrinfo msrinfo;
+ static uint32_t high = 100;
- if (low > 100 || high > 100 || low > high)
- return;
- if (mode != 0 && mode != 1)
- return;
+ if (newp == NULL)
+ return (EINVAL);
+ if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &high)))
+ return (error);
+
+ if (high > 100)
+ high = 100;
+
+ if (high >= 50)
+ mode = 1; /* power */
+ else
+ mode = 0; /* battery */
eflags = read_eflags();
disable_intr();
+
msrinfo.msr = rdmsr(MSR_TMx86_LONGRUN);
- msrinfo.regs[0] = LONGRUN_MODE_WRITE(msrinfo.regs[0], low);
+ msrinfo.regs[0] = LONGRUN_MODE_WRITE(msrinfo.regs[0], 0); /* low */
msrinfo.regs[1] = LONGRUN_MODE_WRITE(msrinfo.regs[1], high);
wrmsr(MSR_TMx86_LONGRUN, msrinfo.msr);
@@ -145,5 +114,7 @@ longrun_setmode(u_int32_t low, u_int32_t high, u_int32_t mode)
enable_intr();
write_eflags(eflags);
+
+ return (0);
}
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c
index 361e3a5219c..ac728587618 100644
--- a/sys/arch/i386/i386/machdep.c
+++ b/sys/arch/i386/i386/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.253 2003/12/14 23:11:28 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.254 2003/12/18 23:46:19 tedu Exp $ */
/* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */
/*-
@@ -277,7 +277,8 @@ int bus_mem_add_mapping(bus_addr_t, bus_size_t,
int _bus_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *,
bus_size_t, struct proc *, int, paddr_t *, int *, int);
-int longrun_sysctl(void *, size_t *, void *, size_t);
+extern int (*cpu_cpuspeed)(void *, size_t *, void *, size_t);
+extern int (*cpu_setperf)(void *, size_t *, void *, size_t);
#ifdef KGDB
#ifndef KGDB_DEVNAME
@@ -1626,7 +1627,7 @@ intel686_cpu_setup(cpu_device, model, step)
const char *cpu_device;
int model, step;
{
- extern int cpu_feature, cpuid_level;
+ extern int cpu_feature, cpu_ecxfeature, cpuid_level;
u_quad_t msr119;
/*
@@ -1654,6 +1655,15 @@ intel686_cpu_setup(cpu_device, model, step)
cpu_feature &= ~CPUID_SER;
cpuid_level = 2;
}
+#if !defined(SMALL_KERNEL) && defined (I686_CPU)
+ if (cpu_ecxfeature & CPUIDECX_EST) {
+ if (rdmsr(MSR_MISC_ENABLE) & (1 << 16))
+ est_init(cpu_device);
+ else
+ printf("%s: Enhanced SpeedStep disabled by BIOS\n",
+ cpu_device);
+ }
+#endif
}
void
@@ -1661,10 +1671,9 @@ tm86_cpu_setup(cpu_device, model, step)
const char *cpu_device;
int model, step;
{
-#ifndef SMALL_KERNEL
- extern int longrun_enabled;
-
- longrun_enabled = 1;
+#if !defined(SMALL_KERNEL) && defined (I586_CPU)
+ cpu_cpuspeed = longrun_cpuspeed;
+ cpu_setperf = longrun_setperf;
#endif
}
@@ -1912,10 +1921,6 @@ identifycpu()
((*token) ? "\" " : ""), classnames[class]);
}
- /* configure the CPU if needed */
- if (cpu_setup != NULL)
- cpu_setup(cpu_device, model, step);
-
printf("%s: %s", cpu_device, cpu_model);
#if defined(I586_CPU) || defined(I686_CPU)
@@ -1962,6 +1967,10 @@ identifycpu()
printf("\n");
}
+ /* configure the CPU if needed */
+ if (cpu_setup != NULL)
+ cpu_setup(cpu_device, model, step);
+
cpu_class = class;
/*
@@ -3136,10 +3145,6 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
return (sysctl_int(oldp, oldlenp, newp, newlen,
&user_ldt_enable));
#endif
-#ifndef SMALL_KERNEL
- case CPU_LONGRUN:
- return (longrun_sysctl(oldp, oldlenp, newp, newlen));
-#endif
default:
return (EOPNOTSUPP);
}
diff --git a/sys/arch/i386/include/cpu.h b/sys/arch/i386/include/cpu.h
index d9f6fa63eaf..6bdea1fc2b6 100644
--- a/sys/arch/i386/include/cpu.h
+++ b/sys/arch/i386/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.51 2003/07/28 21:15:28 jason Exp $ */
+/* $OpenBSD: cpu.h,v 1.52 2003/12/18 23:46:19 tedu Exp $ */
/* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */
/*-
@@ -183,6 +183,19 @@ void initrtclock(void);
void startrtclock(void);
void rtcdrain(void *);
+/* est.c */
+#if !defined(SMALL_KERNEL) && defined(I686_CPU)
+void est_init(const char *);
+int est_cpuspeed(void *, size_t *, void *, size_t);
+int est_setperf(void *, size_t *, void *, size_t);
+#endif
+
+/* longrun.c */
+#if !defined(SMALL_KERNEL) && defined(I586_CPU)
+int longrun_cpuspeed(void *, size_t *, void *, size_t);
+int longrun_setperf(void *, size_t *, void *, size_t);
+#endif
+
/* npx.c */
void npxdrop(void);
void npxsave(void);
@@ -237,8 +250,7 @@ void setconf(void);
#define CPU_KBDRESET 10 /* keyboard reset under pcvt */
#define CPU_APMHALT 11 /* halt -p hack */
#define CPU_USERLDT 12
-#define CPU_LONGRUN 13 /* LongRun status */
-#define CPU_MAXID 14 /* number of valid machdep ids */
+#define CPU_MAXID 13 /* number of valid machdep ids */
#define CTL_MACHDEP_NAMES { \
{ 0, 0 }, \
@@ -254,7 +266,6 @@ void setconf(void);
{ "kbdreset", CTLTYPE_INT }, \
{ "apmhalt", CTLTYPE_INT }, \
{ "userldt", CTLTYPE_INT }, \
- { "longrun", CTLTYPE_STRUCT }, \
}
#endif /* !_I386_CPU_H_ */
diff --git a/sys/arch/i386/include/specialreg.h b/sys/arch/i386/include/specialreg.h
index 3c5dd045a57..5dbdb4cf155 100644
--- a/sys/arch/i386/include/specialreg.h
+++ b/sys/arch/i386/include/specialreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: specialreg.h,v 1.16 2003/07/25 21:42:02 mickey Exp $ */
+/* $OpenBSD: specialreg.h,v 1.17 2003/12/18 23:46:20 tedu Exp $ */
/* $NetBSD: specialreg.h,v 1.7 1994/10/27 04:16:26 cgd Exp $ */
/*-
@@ -168,6 +168,13 @@
#define MSR_MCG_CTL 0x17b
#define P6MSR_CTRSEL0 0x186
#define P6MSR_CTRSEL1 0x187
+#define MSR_PERF_STATUS 0x198 /* Pentium M */
+#define MSR_PERF_CTL 0x199 /* Pentium M */
+#define MSR_THERM_CONTROL 0x19a
+#define MSR_THERM_INTERRUPT 0x19b
+#define MSR_THERM_STATUS 0x19c
+#define MSR_THERM2_CTL 0x19d /* Pentium M */
+#define MSR_MISC_ENABLE 0x1a0
#define MSR_DEBUGCTLMSR 0x1d9
#define MSR_LASTBRANCHFROMIP 0x1db
#define MSR_LASTBRANCHTOIP 0x1dc
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 59c0af8f72d..bc60e59c35f 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.92 2003/11/23 20:17:14 millert Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.93 2003/12/18 23:46:20 tedu Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -94,6 +94,9 @@ int sysctl_intrcnt(int *, u_int, void *, size_t *);
int sysctl_sensors(int *, u_int, void *, size_t *, void *, size_t);
int sysctl_emul(int *, u_int, void *, size_t *, void *, size_t);
+int (*cpu_cpuspeed)(void *, size_t *, void *, size_t);
+int (*cpu_setperf)(void *, size_t *, void *, size_t);
+
/*
* Lock to avoid too many processes vslocking a large amount of memory
* at the same time.
@@ -548,6 +551,14 @@ hw_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
case HW_SENSORS:
return (sysctl_sensors(name + 1, namelen - 1, oldp, oldlenp,
newp, newlen));
+ case HW_CPUSPEED:
+ if (!cpu_cpuspeed)
+ return (EOPNOTSUPP);
+ return (cpu_cpuspeed(oldp, oldlenp, newp, newlen));
+ case HW_SETPERF:
+ if (!cpu_setperf)
+ return (EOPNOTSUPP);
+ return (cpu_setperf(oldp, oldlenp, newp, newlen));
default:
return (EOPNOTSUPP);
}
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index 38d9f3706a7..60f2e546033 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.h,v 1.65 2003/08/21 18:56:07 tedu Exp $ */
+/* $OpenBSD: sysctl.h,v 1.66 2003/12/18 23:46:20 tedu Exp $ */
/* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */
/*
@@ -384,7 +384,9 @@ struct kinfo_proc {
#define HW_DISKSTATS 9 /* struct: diskstats[] */
#define HW_DISKCOUNT 10 /* int: number of disks */
#define HW_SENSORS 11 /* node: hardware monitors */
-#define HW_MAXID 12 /* number of valid hw ids */
+#define HW_CPUSPEED 12 /* get CPU frequency */
+#define HW_SETPERF 13 /* set CPU performance % */
+#define HW_MAXID 14 /* number of valid hw ids */
#define CTL_HW_NAMES { \
{ 0, 0 }, \
@@ -399,6 +401,8 @@ struct kinfo_proc {
{ "diskstats", CTLTYPE_STRUCT }, \
{ "diskcount", CTLTYPE_INT }, \
{ "sensors", CTLTYPE_NODE}, \
+ { "cpuspeed", CTLTYPE_INT }, \
+ { "setperf", CTLTYPE_INT }, \
}
/*