Module Name: src Committed By: martin Date: Fri Apr 24 17:46:44 UTC 2020
Modified Files: src/share/man/man4/man4.x86 [netbsd-9]: amdsmn.4 amdzentemp.4 src/sys/arch/x86/pci [netbsd-9]: amdsmn.c amdzentemp.c Log Message: Pull up following revision(s) (requested by simonb in ticket #851): share/man/man4/man4.x86/amdzentemp.4: revision 1.7 share/man/man4/man4.x86/amdsmn.4: revision 1.4 sys/arch/x86/pci/amdsmn.c: revision 1.7 sys/arch/x86/pci/amdsmn.c: revision 1.8 sys/arch/x86/pci/amdsmn.c: revision 1.9 sys/arch/x86/pci/amdzentemp.c: revision 1.10 Update to support Family 15h Model 60 temperature sensors. Changes based on FreeBSD amdtemp driver changes by Conrad Meyer. XXX: Some code duplication between this driver and amdtemp as parts of the 15h refresh code share more in common with older CPUs while accessing the device more like 17h. -- Note that these drivers are present on some newer AMD Family 15h processors. -- Don't mix sign and unsigned operands. Just use size_t for the loop. -- Apply previous change ("Don't mix sign and unsigned operands. Just use size_t for the loop.") to another loop variable. -- To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.3.8.1 src/share/man/man4/man4.x86/amdsmn.4 cvs rdiff -u -r1.6 -r1.6.8.1 src/share/man/man4/man4.x86/amdzentemp.4 cvs rdiff -u -r1.5 -r1.5.2.1 src/sys/arch/x86/pci/amdsmn.c cvs rdiff -u -r1.9 -r1.9.2.1 src/sys/arch/x86/pci/amdzentemp.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/share/man/man4/man4.x86/amdsmn.4 diff -u src/share/man/man4/man4.x86/amdsmn.4:1.3 src/share/man/man4/man4.x86/amdsmn.4:1.3.8.1 --- src/share/man/man4/man4.x86/amdsmn.4:1.3 Fri Jan 26 15:12:37 2018 +++ src/share/man/man4/man4.x86/amdsmn.4 Fri Apr 24 17:46:44 2020 @@ -1,4 +1,4 @@ -.\" $NetBSD: amdsmn.4,v 1.3 2018/01/26 15:12:37 wiz Exp $ +.\" $NetBSD: amdsmn.4,v 1.3.8.1 2020/04/24 17:46:44 martin Exp $ .\" .\" Copyright (c) 2018 Ian Clark <mrroos...@gmail.com> .\" All rights reserved. @@ -54,7 +54,7 @@ .\" .\" $FreeBSD: head/share/man/man4/amdsmn.4 323184 2017-09-05 15:13:41Z cem $ .\" -.Dd January 22, 2018 +.Dd April 20, 2020 .Dt AMDSMN 4 x86 .Os .Sh NAME @@ -66,7 +66,7 @@ The .Nm driver provides support for resources on the System Management Network bus -in AMD Family 17h processors. +in AMD Family 17h processors and some later AMD Family 15h processors. .Sh SEE ALSO .Xr amdzentemp 4 .Sh HISTORY Index: src/share/man/man4/man4.x86/amdzentemp.4 diff -u src/share/man/man4/man4.x86/amdzentemp.4:1.6 src/share/man/man4/man4.x86/amdzentemp.4:1.6.8.1 --- src/share/man/man4/man4.x86/amdzentemp.4:1.6 Sat Jan 27 21:39:06 2018 +++ src/share/man/man4/man4.x86/amdzentemp.4 Fri Apr 24 17:46:44 2020 @@ -1,4 +1,4 @@ -.\" $NetBSD: amdzentemp.4,v 1.6 2018/01/27 21:39:06 pgoyette Exp $ +.\" $NetBSD: amdzentemp.4,v 1.6.8.1 2020/04/24 17:46:44 martin Exp $ .\"- .\" Copyright (c) 2008 Christoph Egger .\" All rights reserved. @@ -26,7 +26,7 @@ .\" .\" $FreeBSD: src/share/man/man4/coretemp.4,v 1.4 2007/10/15 20:00:19 netchild Exp $ .\" -.Dd January 28, 2018 +.Dd April 20, 2020 .Dt AMDZENTEMP 4 x86 .Os .Sh NAME @@ -38,7 +38,7 @@ The .Nm driver provides support for the on-die digital thermal sensor present -on AMD Ryzen CPUs +on AMD Ryzen CPUs and some later AMD Opteron CPUs. .Pp These sensors provide 0.125\(deC accuracy. There is one sensor for each CPU socket. Index: src/sys/arch/x86/pci/amdsmn.c diff -u src/sys/arch/x86/pci/amdsmn.c:1.5 src/sys/arch/x86/pci/amdsmn.c:1.5.2.1 --- src/sys/arch/x86/pci/amdsmn.c:1.5 Thu Jul 18 12:04:16 2019 +++ src/sys/arch/x86/pci/amdsmn.c Fri Apr 24 17:46:44 2020 @@ -1,7 +1,7 @@ -/* $NetBSD: amdsmn.c,v 1.5 2019/07/18 12:04:16 msaitoh Exp $ */ +/* $NetBSD: amdsmn.c,v 1.5.2.1 2020/04/24 17:46:44 martin Exp $ */ /*- - * Copyright (c) 2017 Conrad Meyer <c...@freebsd.org> + * Copyright (c) 2017, 2019 Conrad Meyer <c...@freebsd.org> * All rights reserved. * * NetBSD port by Ian Clark <mrroos...@gmail.com> @@ -29,10 +29,11 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: amdsmn.c,v 1.5 2019/07/18 12:04:16 msaitoh Exp $ "); +__KERNEL_RCSID(0, "$NetBSD: amdsmn.c,v 1.5.2.1 2020/04/24 17:46:44 martin Exp $ "); /* - * Driver for the AMD Family 17h CPU System Management Network. + * Driver for the AMD Family 15h (model 60+) and 17h CPU + * System Management Network. */ #include <sys/param.h> @@ -52,11 +53,15 @@ __KERNEL_RCSID(0, "$NetBSD: amdsmn.c,v 1 #include "amdsmn.h" #include "ioconf.h" -#define SMN_ADDR_REG 0x60 -#define SMN_DATA_REG 0x64 +#define F15H_SMN_ADDR_REG 0xb8 +#define F15H_SMN_DATA_REG 0xbc +#define F17H_SMN_ADDR_REG 0x60 +#define F17H_SMN_DATA_REG 0x64 struct amdsmn_softc { kmutex_t smn_lock; + uint8_t smn_addr_reg; + uint8_t smn_data_reg; struct pci_attach_args pa; pci_chipset_tag_t pc; pcitag_t pcitag; @@ -64,10 +69,29 @@ struct amdsmn_softc { static const struct pciid { uint16_t amdsmn_deviceid; + uint8_t amdsmn_addr_reg; + uint8_t amdsmn_data_reg; } amdsmn_ids[] = { - { PCI_PRODUCT_AMD_F17_RC }, - { PCI_PRODUCT_AMD_F17_1X_RC }, - { PCI_PRODUCT_AMD_F17_7X_RC }, + { + .amdsmn_deviceid = PCI_PRODUCT_AMD_F15_60_RC, + .amdsmn_addr_reg = F15H_SMN_ADDR_REG, + .amdsmn_data_reg = F15H_SMN_DATA_REG, + }, + { + .amdsmn_deviceid = PCI_PRODUCT_AMD_F17_RC, + .amdsmn_addr_reg = F17H_SMN_ADDR_REG, + .amdsmn_data_reg = F17H_SMN_DATA_REG, + }, + { + .amdsmn_deviceid = PCI_PRODUCT_AMD_F17_1X_RC, + .amdsmn_addr_reg = F17H_SMN_ADDR_REG, + .amdsmn_data_reg = F17H_SMN_DATA_REG, + }, + { + .amdsmn_deviceid = PCI_PRODUCT_AMD_F17_7X_RC, + .amdsmn_addr_reg = F17H_SMN_ADDR_REG, + .amdsmn_data_reg = F17H_SMN_DATA_REG, + }, }; static int amdsmn_match(device_t, cfdata_t, void *); @@ -83,7 +107,7 @@ static int amdsmn_match(device_t parent, cfdata_t match, void *aux) { struct pci_attach_args *pa = aux; - unsigned int i; + size_t i; if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_AMD) return 0; @@ -110,12 +134,21 @@ amdsmn_attach(device_t parent, device_t struct amdsmn_softc *sc = device_private(self); struct pci_attach_args *pa = aux; int flags = 0; + size_t i; mutex_init(&sc->smn_lock, MUTEX_DEFAULT, IPL_NONE); sc->pa = *pa; sc->pc = pa->pa_pc; sc->pcitag = pa->pa_tag; - aprint_normal(": AMD Family 17h System Management Network\n"); + + for (i = 0; i < __arraycount(amdsmn_ids); i++) + if (PCI_PRODUCT(pa->pa_id) == amdsmn_ids[i].amdsmn_deviceid) { + sc->smn_addr_reg = amdsmn_ids[i].amdsmn_addr_reg; + sc->smn_data_reg = amdsmn_ids[i].amdsmn_data_reg; + } + + // aprint_normal(": AMD Family 17h System Management Network\n"); + aprint_normal(": AMD System Management Network\n"); amdsmn_rescan(self, "amdsmnbus", &flags); } @@ -146,8 +179,8 @@ amdsmn_read(device_t dev, uint32_t addr, struct amdsmn_softc *sc = device_private(dev); mutex_enter(&sc->smn_lock); - pci_conf_write(sc->pc, sc->pcitag, SMN_ADDR_REG, addr); - *value = pci_conf_read(sc->pc, sc->pcitag, SMN_DATA_REG); + pci_conf_write(sc->pc, sc->pcitag, sc->smn_addr_reg, addr); + *value = pci_conf_read(sc->pc, sc->pcitag, sc->smn_data_reg); mutex_exit(&sc->smn_lock); return 0; @@ -159,8 +192,8 @@ amdsmn_write(device_t dev, uint32_t addr struct amdsmn_softc *sc = device_private(dev); mutex_enter(&sc->smn_lock); - pci_conf_write(sc->pc, sc->pcitag, SMN_ADDR_REG, addr); - pci_conf_write(sc->pc, sc->pcitag, SMN_DATA_REG, value); + pci_conf_write(sc->pc, sc->pcitag, sc->smn_addr_reg, addr); + pci_conf_write(sc->pc, sc->pcitag, sc->smn_data_reg, value); mutex_exit(&sc->smn_lock); return 0; Index: src/sys/arch/x86/pci/amdzentemp.c diff -u src/sys/arch/x86/pci/amdzentemp.c:1.9 src/sys/arch/x86/pci/amdzentemp.c:1.9.2.1 --- src/sys/arch/x86/pci/amdzentemp.c:1.9 Sun Jun 16 09:12:51 2019 +++ src/sys/arch/x86/pci/amdzentemp.c Fri Apr 24 17:46:44 2020 @@ -1,8 +1,11 @@ -/* $NetBSD: amdzentemp.c,v 1.9 2019/06/16 09:12:51 mlelstv Exp $ */ +/* $NetBSD: amdzentemp.c,v 1.9.2.1 2020/04/24 17:46:44 martin Exp $ */ /* $OpenBSD: kate.c,v 1.2 2008/03/27 04:52:03 cnst Exp $ */ /* - * Copyright (c) 2008 The NetBSD Foundation, Inc. + * Copyright (c) 2008, 2020 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Copyright (c) 2019 Conrad Meyer <c...@freebsd.org> * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -50,7 +53,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: amdzentemp.c,v 1.9 2019/06/16 09:12:51 mlelstv Exp $ "); +__KERNEL_RCSID(0, "$NetBSD: amdzentemp.c,v 1.9.2.1 2020/04/24 17:46:44 martin Exp $ "); #include <sys/param.h> #include <sys/bus.h> @@ -70,17 +73,35 @@ __KERNEL_RCSID(0, "$NetBSD: amdzentemp.c #include "amdsmn.h" -/* Address to query for temp on family 17h */ -#define AMD_17H_CUR_TMP 0x59800 +#define AMD_CURTMP_RANGE_ADJUST 49000000 /* in microKelvins (ie, 49C) */ +#define AMD_CURTMP_RANGE_CHECK __BIT(19) +#define F10_TEMP_CURTMP __BITS(31,21) /* XXX same as amdtemp.c */ +#define F15M60_CURTMP_TJSEL __BITS(17,16) + +/* + * Reported Temperature, Family 15h, M60+ + * + * Same register bit definitions as other Family 15h CPUs, but access is + * indirect via SMN, like Family 17h. + */ +#define AMD_15H_M60H_REPTMP_CTRL 0xd8200ca4 + +/* + * Reported Temperature, Family 17h + * + * According to AMD OSRR for 17H, section 4.2.1, bits 31-21 of this register + * provide the current temp. bit 19, when clear, means the temp is reported in + * a range 0.."225C" (probable typo for 255C), and when set changes the range + * to -49..206C. + */ +#define AMD_17H_CUR_TMP 0x59800 struct amdzentemp_softc { - pci_chipset_tag_t sc_pc; - pcitag_t sc_pcitag; struct sysmon_envsys *sc_sme; device_t sc_smn; envsys_data_t *sc_sensor; size_t sc_sensor_len; - size_t sc_numsensors; + size_t sc_numsensors; int32_t sc_offset; }; @@ -89,8 +110,9 @@ static int amdzentemp_match(device_t, c static void amdzentemp_attach(device_t, device_t, void *); static int amdzentemp_detach(device_t, int); -static void amdzentemp_family17_init(struct amdzentemp_softc *); -static void amdzentemp_family17_setup_sensors(struct amdzentemp_softc *, int); +static void amdzentemp_init(struct amdzentemp_softc *); +static void amdzentemp_setup_sensors(struct amdzentemp_softc *, int); +static void amdzentemp_family15_refresh(struct sysmon_envsys *, envsys_data_t *); static void amdzentemp_family17_refresh(struct sysmon_envsys *, envsys_data_t *); CFATTACH_DECL_NEW(amdzentemp, sizeof(struct amdzentemp_softc), @@ -114,18 +136,19 @@ static void amdzentemp_attach(device_t parent, device_t self, void *aux) { struct amdzentemp_softc *sc = device_private(self); - struct pci_attach_args *pa = aux; + struct cpu_info *ci = curcpu(); + int family; int error; size_t i; + family = CPUID_TO_FAMILY(ci->ci_signature); aprint_naive("\n"); - aprint_normal(": AMD CPU Temperature Sensors (Family17h)"); + aprint_normal(": AMD CPU Temperature Sensors (Family%xh)", + family); - sc->sc_pc = pa->pa_pc; - sc->sc_pcitag = pa->pa_tag; sc->sc_smn = parent; - amdzentemp_family17_init(sc); + amdzentemp_init(sc); aprint_normal("\n"); @@ -133,7 +156,7 @@ amdzentemp_attach(device_t parent, devic sc->sc_sensor_len = sizeof(envsys_data_t) * sc->sc_numsensors; sc->sc_sensor = kmem_zalloc(sc->sc_sensor_len, KM_SLEEP); - amdzentemp_family17_setup_sensors(sc, device_unit(self)); + amdzentemp_setup_sensors(sc, device_unit(self)); /* * Set properties in sensors. @@ -149,7 +172,17 @@ amdzentemp_attach(device_t parent, devic sc->sc_sme->sme_name = device_xname(self); sc->sc_sme->sme_cookie = sc; - sc->sc_sme->sme_refresh = amdzentemp_family17_refresh; + switch (family) { + case 0x15: + sc->sc_sme->sme_refresh = amdzentemp_family15_refresh; + break; + case 0x17: + sc->sc_sme->sme_refresh = amdzentemp_family17_refresh; + break; + default: + /* XXX panic */ + break; + } error = sysmon_envsys_register(sc->sc_sme); if (error) { @@ -189,7 +222,7 @@ amdzentemp_detach(device_t self, int fla static void -amdzentemp_family17_init(struct amdzentemp_softc *sc) +amdzentemp_init(struct amdzentemp_softc *sc) { sc->sc_numsensors = 1; @@ -207,7 +240,7 @@ amdzentemp_family17_init(struct amdzente } static void -amdzentemp_family17_setup_sensors(struct amdzentemp_softc *sc, int dv_unit) +amdzentemp_setup_sensors(struct amdzentemp_softc *sc, int dv_unit) { sc->sc_sensor[0].units = ENVSYS_STEMP; sc->sc_sensor[0].state = ENVSYS_SVALID; @@ -218,6 +251,40 @@ amdzentemp_family17_setup_sensors(struct } static void +amdzentemp_family15_refresh(struct sysmon_envsys *sme, + envsys_data_t *edata) +{ + struct amdzentemp_softc *sc = sme->sme_cookie; + uint32_t val, temp; + int error; + + error = amdsmn_read(sc->sc_smn, AMD_15H_M60H_REPTMP_CTRL, &val); + if (error) { + edata->state = ENVSYS_SINVALID; + return; + } + + /* from amdtemp.c:amdtemp_family10_refresh() */ + temp = __SHIFTOUT(val, F10_TEMP_CURTMP); + + /* From Celsius to micro-Kelvin. */ + edata->value_cur = (temp * 125000) + 273150000; + + /* + * On Family 15h and higher, if CurTmpTjSel is 11b, the range is + * adjusted down by 49.0 degrees Celsius. (This adjustment is not + * documented in BKDGs prior to family 15h model 00h.) + * + * XXX should be in amdtemp.c:amdtemp_family10_refresh() for f15 + * as well?? + */ + if (__SHIFTOUT(val, F15M60_CURTMP_TJSEL) == 0x3) + edata->value_cur -= AMD_CURTMP_RANGE_ADJUST; + + edata->state = ENVSYS_SVALID; +} + +static void amdzentemp_family17_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) { struct amdzentemp_softc *sc = sme->sme_cookie; @@ -233,8 +300,8 @@ amdzentemp_family17_refresh(struct sysmo /* From C to uK. */ edata->value_cur = ((temp >> 21) * 125000) + 273150000; /* adjust for possible offset of 49K */ - if (temp & 0x80000) - edata->value_cur -= 49000000; + if (temp & AMD_CURTMP_RANGE_CHECK) + edata->value_cur -= AMD_CURTMP_RANGE_ADJUST; edata->value_cur += sc->sc_offset; } @@ -266,4 +333,3 @@ amdzentemp_modcmd(modcmd_t cmd, void *au return ENOTTY; } } -