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;
 	}
 }
-

Reply via email to