viac7temp(4): rewrite temperature sensor to read value from MSR instead of using

documented cpuid instruction and eax register.

This approach is adapted from linux via-cputemp.c, no official documentation is
currently available. However, msr value seems to work on all tested CPUs while
documented cpuid instruction typically reports 0, even for my C7-D CPU.
msr value seems to have temperature in Celsius in lower 24-bits without fraction
(thus "msr & 0xffffff;" is used).

Tested on my personal systems based on CPUs below (i386 and amd64):
C7-D 1.6GHz (i386 only), Nano X2 L4350E, Nano X2 U4300, U2300 Nano, KX-U6580.
Also got one response via email which was based on Nano X2 L4050 (VE-900).
Nano reports independent values for each core.
KX-U6580 seems to show the same value for all cores but more testing is needed.

Since it works on amd64 capable CPUs, adding driver to GENERIC kernel config.
Also moving viac7temp man page to x86 instead of i386 (with updates).
In theory the change should add support for all VIA Nano CPUs and Zhaoxin CPUs
 at least up to KX-6000(G) series.

In the future I may need to introduce amd64 kernel module as well.

Plan to pullup to at least netbsd-10.

Patch mainly reviewed by riastradh.
This commit is contained in:
andvar 2024-04-30 19:35:28 +00:00
parent 75b0c31044
commit 4412324be5
10 changed files with 74 additions and 41 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1772 2024/04/09 15:17:24 nia Exp $
# $NetBSD: mi,v 1.1773 2024/04/30 19:35:28 andvar Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -1340,7 +1340,7 @@
./usr/share/man/cat4/i386/spic.0 man-sys-catman .cat
./usr/share/man/cat4/i386/vald.0 man-obsolete obsolete
./usr/share/man/cat4/i386/vesafb.0 man-obsolete obsolete
./usr/share/man/cat4/i386/viac7temp.0 man-sys-catman .cat
./usr/share/man/cat4/i386/viac7temp.0 man-obsolete obsolete
./usr/share/man/cat4/i4b.0 man-obsolete obsolete
./usr/share/man/cat4/i4bctl.0 man-obsolete obsolete
./usr/share/man/cat4/i4bipr.0 man-obsolete obsolete
@ -2158,6 +2158,7 @@
./usr/share/man/cat4/x86/tco.0 man-sys-catman .cat
./usr/share/man/cat4/x86/tprof_amdpmi.0 man-obsolete obsolete
./usr/share/man/cat4/x86/tprof_pmi.0 man-obsolete obsolete
./usr/share/man/cat4/x86/viac7temp.0 man-sys-catman .cat
./usr/share/man/cat4/x86/vmt.0 man-obsolete obsolete
./usr/share/man/cat4/x86/vmx.0 man-obsolete obsolete
./usr/share/man/cat4/xbd.0 man-sys-catman .cat
@ -4835,7 +4836,7 @@
./usr/share/man/man4/i386/spic.4 man-sys-man .man
./usr/share/man/man4/i386/vald.4 man-obsolete obsolete
./usr/share/man/man4/i386/vesafb.4 man-obsolete obsolete
./usr/share/man/man4/i386/viac7temp.4 man-sys-man .man
./usr/share/man/man4/i386/viac7temp.4 man-obsolete obsolete
./usr/share/man/man4/i4b.4 man-obsolete obsolete
./usr/share/man/man4/i4bctl.4 man-obsolete obsolete
./usr/share/man/man4/i4bipr.4 man-obsolete obsolete
@ -5653,6 +5654,7 @@
./usr/share/man/man4/x86/tco.4 man-sys-man .man
./usr/share/man/man4/x86/tprof_amdpmi.4 man-obsolete obsolete
./usr/share/man/man4/x86/tprof_pmi.4 man-obsolete obsolete
./usr/share/man/man4/x86/viac7temp.4 man-sys-man .man
./usr/share/man/man4/x86/vmt.4 man-obsolete obsolete
./usr/share/man/man4/x86/vmx.4 man-obsolete obsolete
./usr/share/man/man4/xbd.4 man-sys-man .man

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1 2024/04/09 15:17:24 nia Exp $
# $NetBSD: mi,v 1.2 2024/04/30 19:35:28 andvar Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -1201,7 +1201,7 @@
./usr/share/man/html4/i386/spic.html man-sys-htmlman html
./usr/share/man/html4/i386/vald.html man-obsolete obsolete
./usr/share/man/html4/i386/vesafb.html man-obsolete obsolete
./usr/share/man/html4/i386/viac7temp.html man-sys-htmlman html
./usr/share/man/html4/i386/viac7temp.html man-obsolete obsolete
./usr/share/man/html4/i915drm.html man-sys-htmlman html
./usr/share/man/html4/iavc.html man-obsolete obsolete
./usr/share/man/html4/iavf.html man-sys-htmlman html
@ -1961,6 +1961,7 @@
./usr/share/man/html4/x86/tco.html man-sys-htmlman html
./usr/share/man/html4/x86/tprof_amdpmi.html man-obsolete obsolete
./usr/share/man/html4/x86/tprof_pmi.html man-obsolete obsolete
./usr/share/man/html4/x86/viac7temp.html man-sys-htmlman html
./usr/share/man/html4/x86/vmt.html man-obsolete obsolete
./usr/share/man/html4/x86/vmx.html man-obsolete obsolete
./usr/share/man/html4/xbd.html man-sys-htmlman html

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.80 2021/08/01 21:56:27 andvar Exp $
# $NetBSD: Makefile,v 1.81 2024/04/30 19:35:28 andvar Exp $
# from: @(#)Makefile 8.1 (Berkeley) 6/5/93
MAN= apm.4 \
@ -6,7 +6,7 @@ MAN= apm.4 \
elanpar.4 elanpex.4 elansc.4 \
gcscide.4 gcscpcib.4 geodewdog.4 geodecntr.4 glxsb.4 gscpcib.4 \
intro.4 io.4 lms.4 mms.4 \
pcibios.4 pcmb.4 pnpbios.4 rdcide.4 rdcpcib.4 spic.4 viac7temp.4
pcibios.4 pcmb.4 pnpbios.4 rdcide.4 rdcpcib.4 spic.4
MLINKS+=pcibios.4 PCIBIOS.4
MANSUBDIR=/i386

View File

@ -1,8 +1,8 @@
# $NetBSD: Makefile,v 1.23 2021/07/25 07:35:55 nia Exp $
# $NetBSD: Makefile,v 1.24 2024/04/30 19:35:29 andvar Exp $
MAN= amdccp.4 amdpcib.4 apic.4 autoconf.4 balloon.4 console.4 coretemp.4 \
est.4 fdc.4 fwhrng.4 hpet.4 ichlpcib.4 imcsmb.4 lpt.4 mem.4 odcm.4 \
powernow.4 soekrisgpio.4 tco.4 amdsmn.4 amdzentemp.4
powernow.4 soekrisgpio.4 tco.4 amdsmn.4 amdzentemp.4 viac7temp.4
MLINKS+=apic.4 ioapic.4 \
apic.4 lapic.4

View File

@ -1,4 +1,4 @@
.\" $NetBSD: viac7temp.4,v 1.3 2014/03/18 18:20:40 riastradh Exp $
.\" $NetBSD: viac7temp.4,v 1.1 2024/04/30 19:35:29 andvar Exp $
.\"
.\" Copyright (c) 2011 Jukka Ruohonen <jruohonen@iki.fi>
.\" All rights reserved.
@ -24,12 +24,12 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd February 24, 2011
.Dd April 30, 2024
.Dt VIAC7TEMP 4
.Os
.Sh NAME
.Nm viac7temp
.Nd VIA C7 temperature sensor
.Nd VIA C7, VIA Nano and Zhaoxin CPU temperature sensor
.Sh SYNOPSIS
.Cd "viac7temp* at cpu?"
.Sh DESCRIPTION
@ -37,7 +37,11 @@ The
.Nm
driver supports temperature sensors found in
.Tn VIA
.Tn C7
.Tn C7,
.Tn VIA
.Tn Nano
and
.Tn Zhaoxin
processors.
The available information is available through the
.Xr envsys 4

View File

@ -1,4 +1,4 @@
# $NetBSD: ALL,v 1.187 2024/04/02 22:30:03 charlotte Exp $
# $NetBSD: ALL,v 1.188 2024/04/30 19:35:29 andvar Exp $
# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
#
# ALL machine description file
@ -17,7 +17,7 @@ include "arch/amd64/conf/std.amd64"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "ALL-$Revision: 1.187 $"
#ident "ALL-$Revision: 1.188 $"
maxusers 64 # estimated number of users
@ -38,7 +38,7 @@ est0 at cpu0 # Intel Enhanced SpeedStep (non-ACPI)
odcm0 at cpu0 # On-demand clock modulation
padlock0 at cpu0 # VIA PadLock
powernow0 at cpu0 # AMD PowerNow! and Cool'n'Quiet (non-ACPI)
viac7temp* at cpu? # VIA C7 temperature sensor
viac7temp* at cpu? # VIA C7, Nano and Zhaoxin temperature sensor
vmt0 at cpu0 # VMware Tools
# Beep when it is safe to power down the system (requires sysbeep)

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC,v 1.611 2024/04/21 14:11:12 riastradh Exp $
# $NetBSD: GENERIC,v 1.612 2024/04/30 19:35:29 andvar Exp $
#
# GENERIC machine description file
#
@ -22,7 +22,7 @@ include "arch/amd64/conf/std.amd64"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "GENERIC-$Revision: 1.611 $"
#ident "GENERIC-$Revision: 1.612 $"
maxusers 64 # estimated number of users
@ -89,6 +89,7 @@ est0 at cpu0 # Intel Enhanced SpeedStep (non-ACPI)
hyperv0 at cpu0 # Microsoft Hyper-V
#odcm0 at cpu0 # On-demand clock modulation
powernow0 at cpu0 # AMD PowerNow! and Cool'n'Quiet (non-ACPI)
viac7temp* at cpu? # VIA C7, Nano and Zhaoxin temperature sensor
vmt0 at cpu0 # VMware Tools
#Xen PV support for PVH and HVM guests

View File

@ -1,4 +1,4 @@
# $NetBSD: ALL,v 1.518 2024/04/02 22:30:03 charlotte Exp $
# $NetBSD: ALL,v 1.519 2024/04/30 19:35:28 andvar Exp $
# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
#
# ALL machine description file
@ -17,7 +17,7 @@ include "arch/i386/conf/std.i386"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "ALL-$Revision: 1.518 $"
#ident "ALL-$Revision: 1.519 $"
maxusers 64 # estimated number of users
@ -38,7 +38,7 @@ est0 at cpu0 # Intel Enhanced SpeedStep (non-ACPI)
odcm0 at cpu0 # On-demand clock modulation
padlock0 at cpu0 # VIA PadLock
powernow0 at cpu0 # AMD PowerNow! and Cool'n'Quiet (non-ACPI)
viac7temp* at cpu? # VIA C7 temperature sensor
viac7temp* at cpu? # VIA C7, Nano and Zhaoxin temperature sensor
vmt0 at cpu0 # VMware Tools
options MTRR # memory-type range register syscall support

View File

@ -1,4 +1,4 @@
# $NetBSD: GENERIC,v 1.1255 2024/04/21 14:11:12 riastradh Exp $
# $NetBSD: GENERIC,v 1.1256 2024/04/30 19:35:28 andvar Exp $
#
# GENERIC machine description file
#
@ -22,7 +22,7 @@ include "arch/i386/conf/std.i386"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "GENERIC-$Revision: 1.1255 $"
#ident "GENERIC-$Revision: 1.1256 $"
maxusers 64 # estimated number of users
@ -41,7 +41,7 @@ hyperv0 at cpu0 # Microsoft Hyper-V
#odcm0 at cpu0 # On-demand clock modulation
#padlock0 at cpu0 # VIA PadLock
powernow0 at cpu0 # AMD PowerNow! and Cool'n'Quiet (non-ACPI)
viac7temp* at cpu? # VIA C7 temperature sensor
viac7temp* at cpu? # VIA C7, Nano and Zhaoxin temperature sensor
vmt0 at cpu0 # VMware Tools
#Xen PV support for HVM guests

View File

@ -1,4 +1,4 @@
/* $NetBSD: viac7temp.c,v 1.10 2024/04/13 09:12:09 andvar Exp $ */
/* $NetBSD: viac7temp.c,v 1.11 2024/04/30 19:35:29 andvar Exp $ */
/*-
* Copyright (c) 2009 Jared D. McNeill <jmcneill@invisible.ca>
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: viac7temp.c,v 1.10 2024/04/13 09:12:09 andvar Exp $");
__KERNEL_RCSID(0, "$NetBSD: viac7temp.c,v 1.11 2024/04/30 19:35:29 andvar Exp $");
#include <sys/param.h>
#include <sys/device.h>
@ -42,11 +42,15 @@ __KERNEL_RCSID(0, "$NetBSD: viac7temp.c,v 1.10 2024/04/13 09:12:09 andvar Exp $"
#include <machine/cputypes.h>
#include <machine/specialreg.h>
#define MSR_TEMP_NANO 0x1423 /* VIA Nano and Zhaoxin CPUs */
#define MSR_TEMP_C7 0x1169 /* VIA C7 CPUs */
struct viac7temp_softc {
device_t sc_dev;
struct cpu_info *sc_ci;
struct sysmon_envsys *sc_sme;
envsys_data_t sc_sensor;
uint32_t sc_temp_msr;
};
static int viac7temp_match(device_t, cfdata_t, void *);
@ -54,6 +58,7 @@ static void viac7temp_attach(device_t, device_t, void *);
static int viac7temp_detach(device_t, int);
static void viac7temp_refresh(struct sysmon_envsys *, envsys_data_t *);
static void viac7temp_refresh_xcall(void *, void *);
static uint32_t viac7temp_msr_register(struct cpu_info *ci);
CFATTACH_DECL_NEW(viac7temp, sizeof(struct viac7temp_softc),
viac7temp_match, viac7temp_attach, viac7temp_detach, NULL);
@ -63,8 +68,8 @@ viac7temp_match(device_t parent, cfdata_t cf, void *aux)
{
struct cpufeature_attach_args *cfaa = aux;
struct cpu_info *ci = cfaa->ci;
uint32_t family, model;
uint32_t descs[4];
uint32_t temp_msr;
uint64_t val;
if (strcmp(cfaa->name, "temperature") != 0)
return 0;
@ -72,18 +77,12 @@ viac7temp_match(device_t parent, cfdata_t cf, void *aux)
if (cpu_vendor != CPUVENDOR_IDT)
return 0;
model = CPUID_TO_MODEL(ci->ci_signature);
family = CPUID_TO_FAMILY(ci->ci_signature);
temp_msr = viac7temp_msr_register(ci);
if (family != 0x06 || model < 0x09)
if (!temp_msr || rdmsr_safe(temp_msr, &val) == EFAULT)
return 0;
x86_cpuid(0xc0000000, descs);
if (descs[0] >= 0xc0000002)
return 1;
return 0;
return 1;
}
static void
@ -100,6 +99,8 @@ viac7temp_attach(device_t parent, device_t self, void *aux)
sc->sc_sensor.flags = ENVSYS_FMONLIMITS|ENVSYS_FHAS_ENTROPY;
sc->sc_sensor.state = ENVSYS_SINVALID;
sc->sc_temp_msr = viac7temp_msr_register(ci);
(void)strlcpy(sc->sc_sensor.desc, "temperature",
sizeof(sc->sc_sensor.desc));
@ -116,7 +117,7 @@ viac7temp_attach(device_t parent, device_t self, void *aux)
goto fail;
aprint_naive("\n");
aprint_normal(": VIA C7 temperature sensor\n");
aprint_normal(": VIA C7/Nano temperature sensor\n");
(void)pmf_device_register(self, NULL, NULL);
@ -153,17 +154,41 @@ viac7temp_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
static void
viac7temp_refresh_xcall(void *arg0, void *arg1)
{
struct viac7temp_softc *sc = arg0;
envsys_data_t *edata = arg1;
uint32_t descs[4];
uint64_t msr;
x86_cpuid(0xc0000002, descs);
if (rdmsr_safe(sc->sc_temp_msr, &msr) == EFAULT) {
edata->value_cur = 0;
edata->state = ENVSYS_SINVALID;
aprint_error_dev(sc->sc_dev, "Reading temperature failed\n");
return;
}
edata->value_cur = descs[0] >> 8;
/* Lower 24-bits hold value in Celsius */
edata->value_cur = msr & 0xffffff;
edata->value_cur *= 1000000;
edata->value_cur += 273150000;
edata->state = ENVSYS_SVALID;
}
static uint32_t viac7temp_msr_register(struct cpu_info *ci)
{
uint32_t family, model;
uint32_t reg;
reg = 0;
model = CPUID_TO_MODEL(ci->ci_signature);
family = CPUID_TO_FAMILY(ci->ci_signature);
if (family == 0x07 || (family == 0x06 && model >= 0x0f))
reg = MSR_TEMP_NANO;
else if (family == 0x06 && model > 0x09)
reg = MSR_TEMP_C7;
return reg;
}
MODULE(MODULE_CLASS_DRIVER, viac7temp, NULL);
#ifdef _MODULE