diff options
Diffstat (limited to 'sys/arch/i386/i386/machdep.c')
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 66 |
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); |