summaryrefslogtreecommitdiff
path: root/sys/arch/i386/i386/machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/i386/i386/machdep.c')
-rw-r--r--sys/arch/i386/i386/machdep.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c
index f38be5e30e3..75a4c3bc0ac 100644
--- a/sys/arch/i386/i386/machdep.c
+++ b/sys/arch/i386/i386/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.397 2007/05/29 21:00:50 jason Exp $ */
+/* $OpenBSD: machdep.c,v 1.398 2007/05/29 21:01:56 tedu Exp $ */
/* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */
/*-
@@ -97,6 +97,7 @@
#include <sys/syscallargs.h>
#include <sys/core.h>
#include <sys/kcore.h>
+#include <sys/sensors.h>
#ifdef SYSVMSG
#include <sys/msg.h>
#endif
@@ -244,6 +245,8 @@ int bus_clock;
void (*setperf_setup)(struct cpu_info *);
int setperf_prio = 0; /* for concurrent handlers */
+void (*cpusensors_setup)(struct cpu_info *);
+
void (*delay_func)(int) = i8254_delay;
void (*initclock_func)(void) = i8254_initclocks;
@@ -322,10 +325,12 @@ void cyrix3_cpu_setup(struct cpu_info *);
void cyrix6x86_cpu_setup(struct cpu_info *);
void natsem6x86_cpu_setup(struct cpu_info *);
void intel586_cpu_setup(struct cpu_info *);
+void intel686_cpusensors_setup(struct cpu_info *);
void intel686_setperf_setup(struct cpu_info *);
void intel686_common_cpu_setup(struct cpu_info *);
void intel686_cpu_setup(struct cpu_info *);
void intel686_p4_cpu_setup(struct cpu_info *);
+void intelcore_update_sensor(void *);
void tm86_cpu_setup(struct cpu_info *);
char * intel686_cpu_name(int);
char * cyrix3_cpu_name(int, int);
@@ -1317,6 +1322,64 @@ amd_family6_setup(struct cpu_info *ci)
}
#if !defined(SMALL_KERNEL) && defined(I686_CPU)
+/*
+ * Temperature read on the CPU is relative to the maximum
+ * temperature supported by the CPU, Tj(Max).
+ * Poorly documented, refer to:
+ * http://softwarecommunity.intel.com/isn/Community/
+ * en-US/forums/thread/30228638.aspx
+ * Basically, depending on a bit in one msr, the max is either 85 or 100.
+ * Then we subtract the temperature portion of thermal status from
+ * max to get current temperature.
+ */
+void
+intelcore_update_sensor(void *args)
+{
+ struct cpu_info *ci = (struct cpu_info *) args;
+ u_int64_t msr;
+ int max = 100;
+
+ if (rdmsr(MSR_TEMPERATURE_TARGET) & MSR_TEMPERATURE_TARGET_LOW_BIT)
+ max = 85;
+
+ msr = rdmsr(MSR_THERM_STATUS);
+ if (msr & MSR_THERM_STATUS_VALID_BIT) {
+ ci->ci_sensor.value = max - MSR_THERM_STATUS_TEMP(msr);
+ /* micro degrees */
+ ci->ci_sensor.value *= 1000000;
+ /* kelvin */
+ ci->ci_sensor.value += 273150000;
+ ci->ci_sensor.flags &= ~SENSOR_FINVALID;
+ } else {
+ ci->ci_sensor.value = 0;
+ ci->ci_sensor.flags |= SENSOR_FINVALID;
+ }
+}
+
+void
+intel686_cpusensors_setup(struct cpu_info *ci)
+{
+ u_int regs[4];
+
+ if (cpuid_level < 0x06)
+ return;
+
+ /* CPUID.06H.EAX[0] = 1 tells us if we have on-die sensor */
+ cpuid(0x06, regs);
+ if ((regs[0] & 0x01) != 1)
+ return;
+
+ /* Setup the sensors structures */
+ strlcpy(ci->ci_sensordev.xname, ci->ci_dev.dv_xname,
+ sizeof(ci->ci_sensordev.xname));
+ ci->ci_sensor.type = SENSOR_TEMP;
+ sensor_task_register(ci, intelcore_update_sensor, 5);
+ sensor_attach(&ci->ci_sensordev, &ci->ci_sensor);
+ sensordev_install(&ci->ci_sensordev);
+}
+#endif
+
+#if !defined(SMALL_KERNEL) && defined(I686_CPU)
void
intel686_setperf_setup(struct cpu_info *ci)
{
@@ -1341,6 +1404,7 @@ intel686_common_cpu_setup(struct cpu_info *ci)
#if !defined(SMALL_KERNEL) && defined(I686_CPU)
setperf_setup = intel686_setperf_setup;
+ cpusensors_setup = intel686_cpusensors_setup;
{
extern void (*pagezero)(void *, size_t);
extern void sse2_pagezero(void *, size_t);