Index: sys/conf/files.amd64 =================================================================== RCS file: /home/ncvs/src/sys/conf/files.amd64,v retrieving revision 1.106 diff -u -r1.106 files.amd64 --- sys/conf/files.amd64 5 Jul 2007 06:12:40 -0000 1.106 +++ sys/conf/files.amd64 9 Aug 2007 22:51:35 -0000 @@ -145,6 +145,7 @@ dev/atkbdc/atkbdc_isa.c optional atkbdc isa dev/atkbdc/atkbdc_subr.c optional atkbdc dev/atkbdc/psm.c optional psm atkbdc +dev/coretemp/coretemp.c optional coretemp # There are no systems with isa slots, so all ed isa entries should go.. dev/ed/if_ed_3c503.c optional ed isa ed_3c503 dev/ed/if_ed_isa.c optional ed isa Index: sys/conf/files.i386 =================================================================== RCS file: /home/ncvs/src/sys/conf/files.i386,v retrieving revision 1.579 diff -u -r1.579 files.i386 --- sys/conf/files.i386 5 Jul 2007 06:12:40 -0000 1.579 +++ sys/conf/files.i386 9 Aug 2007 22:51:35 -0000 @@ -158,6 +158,7 @@ dev/ce/if_ce.c optional ce dev/ce/tau32-ddk.c optional ce dev/cm/if_cm_isa.c optional cm isa +dev/coretemp/coretemp.c optional coretemp dev/cp/cpddk.c optional cp dev/cp/if_cp.c optional cp dev/ctau/ctau.c optional ctau Index: sys/dev/coretemp/coretemp.c =================================================================== RCS file: sys/dev/coretemp/coretemp.c diff -N sys/dev/coretemp/coretemp.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/dev/coretemp/coretemp.c 9 Aug 2007 22:51:35 -0000 @@ -0,0 +1,157 @@ +/*- + * Copyright (c) 2007 Dag-Erling Coïdan Smørgrav + * 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 + * in this position and unchanged. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define IA32_THERM_INTERRUPT 0x019b +#define IA32_THERM_STATUS 0x019c + +#define TS_READING_VALID 0x80000000 +#define TS_READOUT_MASK 0x007f0000 +#define TS_READOUT_SHIFT 16 + +static struct sysctl_ctx_list coretemp_ctx; + +/* + * Tj(max) is normally 100°C, but may be 85°C on some CPUs. We should be + * able to detect that with some CPUID + MSR fiddling. + */ +static int coretemp_tjmax = 100; + +static int +coretemp_sysctl_delta(SYSCTL_HANDLER_ARGS) +{ + uint64_t msr; + int delta, retry; + + for (retry = 5; retry; --retry) { + msr = rdmsr(IA32_THERM_STATUS); + if (msr & TS_READING_VALID) + break; + DELAY(1000); + } + if (retry == 0) { + printf("%s(): unable to get a valid reading\n", __func__); + return (EIO); + } + delta = -((msr & TS_READOUT_MASK) >> TS_READOUT_SHIFT); + SYSCTL_OUT(req, &delta, sizeof(delta)); + return (0); +} + +static int +coretemp_sysctl_msr(SYSCTL_HANDLER_ARGS) +{ + uint64_t msr; + uint32_t low; + + msr = rdmsr(arg2); + low = msr & 0xffffffff; + SYSCTL_OUT(req, &low, sizeof(low)); + return (0); +} + +/* + * XXX on systems with multiple physically distinct processors, you need + * to run this on each of them... + */ +static int +coretemp_attach(void) +{ + struct sysctl_oid *node; + u_int regs[4]; + + sysctl_ctx_init(&coretemp_ctx); + +#ifdef __i386__ + /* don't even bother on pre-686 */ + if (cpu_class < CPUCLASS_686) + return (ENXIO); +#endif + + /* check CPUID.06H.EAX[0] */ + do_cpuid(0x6, regs); + if ((regs[0] & 1) == 0) + return (ENXIO); + + printf("CPU supports digital thermal sensor\n"); + + node = SYSCTL_ADD_NODE(&coretemp_ctx, SYSCTL_STATIC_CHILDREN(_hw), + OID_AUTO, "coretemp", CTLFLAG_RW, 0, "core temperature"); + SYSCTL_ADD_INT(&coretemp_ctx, SYSCTL_CHILDREN(node), + OID_AUTO, "tjmax", CTLFLAG_RD, + &coretemp_tjmax, 0, "Tj(max)"); + SYSCTL_ADD_OID(&coretemp_ctx, SYSCTL_CHILDREN(node), + OID_AUTO, "delta", CTLTYPE_INT|CTLFLAG_RD, + 0, 0, coretemp_sysctl_delta, "I", "delta"); + SYSCTL_ADD_OID(&coretemp_ctx, SYSCTL_CHILDREN(node), + OID_AUTO, "interrupt", CTLTYPE_UINT|CTLFLAG_RD, + 0, IA32_THERM_INTERRUPT, coretemp_sysctl_msr, "IU", "delta"); + SYSCTL_ADD_OID(&coretemp_ctx, SYSCTL_CHILDREN(node), + OID_AUTO, "status", CTLTYPE_UINT|CTLFLAG_RD, + 0, IA32_THERM_STATUS, coretemp_sysctl_msr, "IU", "delta"); + return (0); +} + +static int +coretemp_detach(void) +{ + + sysctl_ctx_free(&coretemp_ctx); + return (0); +} + +static int +coretemp_modevent(module_t mode, int type, void *data) +{ + int error = EOPNOTSUPP; + + (void)mode; + (void)data; + switch (type) { + case MOD_LOAD: + error = coretemp_attach(); + break; + case MOD_UNLOAD: + error = coretemp_detach(); + break; + } + return (error); +} + +DEV_MODULE(coretemp, coretemp_modevent, NULL); +MODULE_VERSION(coretemp, 1); Index: sys/modules/Makefile =================================================================== RCS file: /home/ncvs/src/sys/modules/Makefile,v retrieving revision 1.538 diff -u -r1.538 Makefile --- sys/modules/Makefile 24 Jul 2007 16:58:18 -0000 1.538 +++ sys/modules/Makefile 9 Aug 2007 22:51:35 -0000 @@ -54,6 +54,7 @@ coda \ coda5 \ ${_coff} \ + ${_coretemp} \ ${_cp} \ ${_cpufreq} \ ${_crypto} \ @@ -370,6 +371,7 @@ _cbb= cbb _ce= ce _coff= coff +_coretemp= coretemp _cp= cp _cpufreq= cpufreq _cs= cs @@ -489,6 +491,7 @@ _cardbus= cardbus _cbb= cbb _ciss= ciss +_coretemp= coretemp _cpufreq= cpufreq _digi= digi _drm= drm Index: sys/modules/coretemp/Makefile =================================================================== RCS file: sys/modules/coretemp/Makefile diff -N sys/modules/coretemp/Makefile --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/modules/coretemp/Makefile 9 Aug 2007 22:51:35 -0000 @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/coretemp + +KMOD= coretemp +SRCS= coretemp.c + +.include