cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

k10temp.c (13713B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * k10temp.c - AMD Family 10h/11h/12h/14h/15h/16h/17h
      4 *		processor hardware monitoring
      5 *
      6 * Copyright (c) 2009 Clemens Ladisch <clemens@ladisch.de>
      7 * Copyright (c) 2020 Guenter Roeck <linux@roeck-us.net>
      8 *
      9 * Implementation notes:
     10 * - CCD register address information as well as the calculation to
     11 *   convert raw register values is from https://github.com/ocerman/zenpower.
     12 *   The information is not confirmed from chip datasheets, but experiments
     13 *   suggest that it provides reasonable temperature values.
     14 */
     15
     16#include <linux/bitops.h>
     17#include <linux/err.h>
     18#include <linux/hwmon.h>
     19#include <linux/init.h>
     20#include <linux/module.h>
     21#include <linux/pci.h>
     22#include <linux/pci_ids.h>
     23#include <asm/amd_nb.h>
     24#include <asm/processor.h>
     25
     26MODULE_DESCRIPTION("AMD Family 10h+ CPU core temperature monitor");
     27MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
     28MODULE_LICENSE("GPL");
     29
     30static bool force;
     31module_param(force, bool, 0444);
     32MODULE_PARM_DESC(force, "force loading on processors with erratum 319");
     33
     34/* Provide lock for writing to NB_SMU_IND_ADDR */
     35static DEFINE_MUTEX(nb_smu_ind_mutex);
     36
     37#ifndef PCI_DEVICE_ID_AMD_15H_M70H_NB_F3
     38#define PCI_DEVICE_ID_AMD_15H_M70H_NB_F3	0x15b3
     39#endif
     40
     41/* CPUID function 0x80000001, ebx */
     42#define CPUID_PKGTYPE_MASK	GENMASK(31, 28)
     43#define CPUID_PKGTYPE_F		0x00000000
     44#define CPUID_PKGTYPE_AM2R2_AM3	0x10000000
     45
     46/* DRAM controller (PCI function 2) */
     47#define REG_DCT0_CONFIG_HIGH		0x094
     48#define  DDR3_MODE			BIT(8)
     49
     50/* miscellaneous (PCI function 3) */
     51#define REG_HARDWARE_THERMAL_CONTROL	0x64
     52#define  HTC_ENABLE			BIT(0)
     53
     54#define REG_REPORTED_TEMPERATURE	0xa4
     55
     56#define REG_NORTHBRIDGE_CAPABILITIES	0xe8
     57#define  NB_CAP_HTC			BIT(10)
     58
     59/*
     60 * For F15h M60h and M70h, REG_HARDWARE_THERMAL_CONTROL
     61 * and REG_REPORTED_TEMPERATURE have been moved to
     62 * D0F0xBC_xD820_0C64 [Hardware Temperature Control]
     63 * D0F0xBC_xD820_0CA4 [Reported Temperature Control]
     64 */
     65#define F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET	0xd8200c64
     66#define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET	0xd8200ca4
     67
     68/* Common for Zen CPU families (Family 17h and 18h and 19h) */
     69#define ZEN_REPORTED_TEMP_CTRL_BASE		0x00059800
     70
     71#define ZEN_CCD_TEMP(offset, x)			(ZEN_REPORTED_TEMP_CTRL_BASE + \
     72						 (offset) + ((x) * 4))
     73#define ZEN_CCD_TEMP_VALID			BIT(11)
     74#define ZEN_CCD_TEMP_MASK			GENMASK(10, 0)
     75
     76#define ZEN_CUR_TEMP_SHIFT			21
     77#define ZEN_CUR_TEMP_RANGE_SEL_MASK		BIT(19)
     78
     79struct k10temp_data {
     80	struct pci_dev *pdev;
     81	void (*read_htcreg)(struct pci_dev *pdev, u32 *regval);
     82	void (*read_tempreg)(struct pci_dev *pdev, u32 *regval);
     83	int temp_offset;
     84	u32 temp_adjust_mask;
     85	u32 show_temp;
     86	bool is_zen;
     87	u32 ccd_offset;
     88};
     89
     90#define TCTL_BIT	0
     91#define TDIE_BIT	1
     92#define TCCD_BIT(x)	((x) + 2)
     93
     94#define HAVE_TEMP(d, channel)	((d)->show_temp & BIT(channel))
     95#define HAVE_TDIE(d)		HAVE_TEMP(d, TDIE_BIT)
     96
     97struct tctl_offset {
     98	u8 model;
     99	char const *id;
    100	int offset;
    101};
    102
    103static const struct tctl_offset tctl_offset_table[] = {
    104	{ 0x17, "AMD Ryzen 5 1600X", 20000 },
    105	{ 0x17, "AMD Ryzen 7 1700X", 20000 },
    106	{ 0x17, "AMD Ryzen 7 1800X", 20000 },
    107	{ 0x17, "AMD Ryzen 7 2700X", 10000 },
    108	{ 0x17, "AMD Ryzen Threadripper 19", 27000 }, /* 19{00,20,50}X */
    109	{ 0x17, "AMD Ryzen Threadripper 29", 27000 }, /* 29{20,50,70,90}[W]X */
    110};
    111
    112static void read_htcreg_pci(struct pci_dev *pdev, u32 *regval)
    113{
    114	pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, regval);
    115}
    116
    117static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval)
    118{
    119	pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval);
    120}
    121
    122static void amd_nb_index_read(struct pci_dev *pdev, unsigned int devfn,
    123			      unsigned int base, int offset, u32 *val)
    124{
    125	mutex_lock(&nb_smu_ind_mutex);
    126	pci_bus_write_config_dword(pdev->bus, devfn,
    127				   base, offset);
    128	pci_bus_read_config_dword(pdev->bus, devfn,
    129				  base + 4, val);
    130	mutex_unlock(&nb_smu_ind_mutex);
    131}
    132
    133static void read_htcreg_nb_f15(struct pci_dev *pdev, u32 *regval)
    134{
    135	amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
    136			  F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET, regval);
    137}
    138
    139static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval)
    140{
    141	amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
    142			  F15H_M60H_REPORTED_TEMP_CTRL_OFFSET, regval);
    143}
    144
    145static void read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval)
    146{
    147	amd_smn_read(amd_pci_dev_to_node_id(pdev),
    148		     ZEN_REPORTED_TEMP_CTRL_BASE, regval);
    149}
    150
    151static long get_raw_temp(struct k10temp_data *data)
    152{
    153	u32 regval;
    154	long temp;
    155
    156	data->read_tempreg(data->pdev, &regval);
    157	temp = (regval >> ZEN_CUR_TEMP_SHIFT) * 125;
    158	if (regval & data->temp_adjust_mask)
    159		temp -= 49000;
    160	return temp;
    161}
    162
    163static const char *k10temp_temp_label[] = {
    164	"Tctl",
    165	"Tdie",
    166	"Tccd1",
    167	"Tccd2",
    168	"Tccd3",
    169	"Tccd4",
    170	"Tccd5",
    171	"Tccd6",
    172	"Tccd7",
    173	"Tccd8",
    174	"Tccd9",
    175	"Tccd10",
    176	"Tccd11",
    177	"Tccd12",
    178};
    179
    180static int k10temp_read_labels(struct device *dev,
    181			       enum hwmon_sensor_types type,
    182			       u32 attr, int channel, const char **str)
    183{
    184	switch (type) {
    185	case hwmon_temp:
    186		*str = k10temp_temp_label[channel];
    187		break;
    188	default:
    189		return -EOPNOTSUPP;
    190	}
    191	return 0;
    192}
    193
    194static int k10temp_read_temp(struct device *dev, u32 attr, int channel,
    195			     long *val)
    196{
    197	struct k10temp_data *data = dev_get_drvdata(dev);
    198	u32 regval;
    199
    200	switch (attr) {
    201	case hwmon_temp_input:
    202		switch (channel) {
    203		case 0:		/* Tctl */
    204			*val = get_raw_temp(data);
    205			if (*val < 0)
    206				*val = 0;
    207			break;
    208		case 1:		/* Tdie */
    209			*val = get_raw_temp(data) - data->temp_offset;
    210			if (*val < 0)
    211				*val = 0;
    212			break;
    213		case 2 ... 13:		/* Tccd{1-12} */
    214			amd_smn_read(amd_pci_dev_to_node_id(data->pdev),
    215				     ZEN_CCD_TEMP(data->ccd_offset, channel - 2),
    216						  &regval);
    217			*val = (regval & ZEN_CCD_TEMP_MASK) * 125 - 49000;
    218			break;
    219		default:
    220			return -EOPNOTSUPP;
    221		}
    222		break;
    223	case hwmon_temp_max:
    224		*val = 70 * 1000;
    225		break;
    226	case hwmon_temp_crit:
    227		data->read_htcreg(data->pdev, &regval);
    228		*val = ((regval >> 16) & 0x7f) * 500 + 52000;
    229		break;
    230	case hwmon_temp_crit_hyst:
    231		data->read_htcreg(data->pdev, &regval);
    232		*val = (((regval >> 16) & 0x7f)
    233			- ((regval >> 24) & 0xf)) * 500 + 52000;
    234		break;
    235	default:
    236		return -EOPNOTSUPP;
    237	}
    238	return 0;
    239}
    240
    241static int k10temp_read(struct device *dev, enum hwmon_sensor_types type,
    242			u32 attr, int channel, long *val)
    243{
    244	switch (type) {
    245	case hwmon_temp:
    246		return k10temp_read_temp(dev, attr, channel, val);
    247	default:
    248		return -EOPNOTSUPP;
    249	}
    250}
    251
    252static umode_t k10temp_is_visible(const void *_data,
    253				  enum hwmon_sensor_types type,
    254				  u32 attr, int channel)
    255{
    256	const struct k10temp_data *data = _data;
    257	struct pci_dev *pdev = data->pdev;
    258	u32 reg;
    259
    260	switch (type) {
    261	case hwmon_temp:
    262		switch (attr) {
    263		case hwmon_temp_input:
    264			if (!HAVE_TEMP(data, channel))
    265				return 0;
    266			break;
    267		case hwmon_temp_max:
    268			if (channel || data->is_zen)
    269				return 0;
    270			break;
    271		case hwmon_temp_crit:
    272		case hwmon_temp_crit_hyst:
    273			if (channel || !data->read_htcreg)
    274				return 0;
    275
    276			pci_read_config_dword(pdev,
    277					      REG_NORTHBRIDGE_CAPABILITIES,
    278					      &reg);
    279			if (!(reg & NB_CAP_HTC))
    280				return 0;
    281
    282			data->read_htcreg(data->pdev, &reg);
    283			if (!(reg & HTC_ENABLE))
    284				return 0;
    285			break;
    286		case hwmon_temp_label:
    287			/* Show temperature labels only on Zen CPUs */
    288			if (!data->is_zen || !HAVE_TEMP(data, channel))
    289				return 0;
    290			break;
    291		default:
    292			return 0;
    293		}
    294		break;
    295	default:
    296		return 0;
    297	}
    298	return 0444;
    299}
    300
    301static bool has_erratum_319(struct pci_dev *pdev)
    302{
    303	u32 pkg_type, reg_dram_cfg;
    304
    305	if (boot_cpu_data.x86 != 0x10)
    306		return false;
    307
    308	/*
    309	 * Erratum 319: The thermal sensor of Socket F/AM2+ processors
    310	 *              may be unreliable.
    311	 */
    312	pkg_type = cpuid_ebx(0x80000001) & CPUID_PKGTYPE_MASK;
    313	if (pkg_type == CPUID_PKGTYPE_F)
    314		return true;
    315	if (pkg_type != CPUID_PKGTYPE_AM2R2_AM3)
    316		return false;
    317
    318	/* DDR3 memory implies socket AM3, which is good */
    319	pci_bus_read_config_dword(pdev->bus,
    320				  PCI_DEVFN(PCI_SLOT(pdev->devfn), 2),
    321				  REG_DCT0_CONFIG_HIGH, &reg_dram_cfg);
    322	if (reg_dram_cfg & DDR3_MODE)
    323		return false;
    324
    325	/*
    326	 * Unfortunately it is possible to run a socket AM3 CPU with DDR2
    327	 * memory. We blacklist all the cores which do exist in socket AM2+
    328	 * format. It still isn't perfect, as RB-C2 cores exist in both AM2+
    329	 * and AM3 formats, but that's the best we can do.
    330	 */
    331	return boot_cpu_data.x86_model < 4 ||
    332	       (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_stepping <= 2);
    333}
    334
    335static const struct hwmon_channel_info *k10temp_info[] = {
    336	HWMON_CHANNEL_INFO(temp,
    337			   HWMON_T_INPUT | HWMON_T_MAX |
    338			   HWMON_T_CRIT | HWMON_T_CRIT_HYST |
    339			   HWMON_T_LABEL,
    340			   HWMON_T_INPUT | HWMON_T_LABEL,
    341			   HWMON_T_INPUT | HWMON_T_LABEL,
    342			   HWMON_T_INPUT | HWMON_T_LABEL,
    343			   HWMON_T_INPUT | HWMON_T_LABEL,
    344			   HWMON_T_INPUT | HWMON_T_LABEL,
    345			   HWMON_T_INPUT | HWMON_T_LABEL,
    346			   HWMON_T_INPUT | HWMON_T_LABEL,
    347			   HWMON_T_INPUT | HWMON_T_LABEL,
    348			   HWMON_T_INPUT | HWMON_T_LABEL,
    349			   HWMON_T_INPUT | HWMON_T_LABEL,
    350			   HWMON_T_INPUT | HWMON_T_LABEL,
    351			   HWMON_T_INPUT | HWMON_T_LABEL,
    352			   HWMON_T_INPUT | HWMON_T_LABEL),
    353	NULL
    354};
    355
    356static const struct hwmon_ops k10temp_hwmon_ops = {
    357	.is_visible = k10temp_is_visible,
    358	.read = k10temp_read,
    359	.read_string = k10temp_read_labels,
    360};
    361
    362static const struct hwmon_chip_info k10temp_chip_info = {
    363	.ops = &k10temp_hwmon_ops,
    364	.info = k10temp_info,
    365};
    366
    367static void k10temp_get_ccd_support(struct pci_dev *pdev,
    368				    struct k10temp_data *data, int limit)
    369{
    370	u32 regval;
    371	int i;
    372
    373	for (i = 0; i < limit; i++) {
    374		amd_smn_read(amd_pci_dev_to_node_id(pdev),
    375			     ZEN_CCD_TEMP(data->ccd_offset, i), &regval);
    376		if (regval & ZEN_CCD_TEMP_VALID)
    377			data->show_temp |= BIT(TCCD_BIT(i));
    378	}
    379}
    380
    381static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
    382{
    383	int unreliable = has_erratum_319(pdev);
    384	struct device *dev = &pdev->dev;
    385	struct k10temp_data *data;
    386	struct device *hwmon_dev;
    387	int i;
    388
    389	if (unreliable) {
    390		if (!force) {
    391			dev_err(dev,
    392				"unreliable CPU thermal sensor; monitoring disabled\n");
    393			return -ENODEV;
    394		}
    395		dev_warn(dev,
    396			 "unreliable CPU thermal sensor; check erratum 319\n");
    397	}
    398
    399	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
    400	if (!data)
    401		return -ENOMEM;
    402
    403	data->pdev = pdev;
    404	data->show_temp |= BIT(TCTL_BIT);	/* Always show Tctl */
    405
    406	if (boot_cpu_data.x86 == 0x15 &&
    407	    ((boot_cpu_data.x86_model & 0xf0) == 0x60 ||
    408	     (boot_cpu_data.x86_model & 0xf0) == 0x70)) {
    409		data->read_htcreg = read_htcreg_nb_f15;
    410		data->read_tempreg = read_tempreg_nb_f15;
    411	} else if (boot_cpu_data.x86 == 0x17 || boot_cpu_data.x86 == 0x18) {
    412		data->temp_adjust_mask = ZEN_CUR_TEMP_RANGE_SEL_MASK;
    413		data->read_tempreg = read_tempreg_nb_zen;
    414		data->is_zen = true;
    415
    416		switch (boot_cpu_data.x86_model) {
    417		case 0x1:	/* Zen */
    418		case 0x8:	/* Zen+ */
    419		case 0x11:	/* Zen APU */
    420		case 0x18:	/* Zen+ APU */
    421			data->ccd_offset = 0x154;
    422			k10temp_get_ccd_support(pdev, data, 4);
    423			break;
    424		case 0x31:	/* Zen2 Threadripper */
    425		case 0x60:	/* Renoir */
    426		case 0x68:	/* Lucienne */
    427		case 0x71:	/* Zen2 */
    428			data->ccd_offset = 0x154;
    429			k10temp_get_ccd_support(pdev, data, 8);
    430			break;
    431		}
    432	} else if (boot_cpu_data.x86 == 0x19) {
    433		data->temp_adjust_mask = ZEN_CUR_TEMP_RANGE_SEL_MASK;
    434		data->read_tempreg = read_tempreg_nb_zen;
    435		data->is_zen = true;
    436
    437		switch (boot_cpu_data.x86_model) {
    438		case 0x0 ... 0x1:	/* Zen3 SP3/TR */
    439		case 0x21:		/* Zen3 Ryzen Desktop */
    440		case 0x50 ... 0x5f:	/* Green Sardine */
    441			data->ccd_offset = 0x154;
    442			k10temp_get_ccd_support(pdev, data, 8);
    443			break;
    444		case 0x40 ... 0x4f:	/* Yellow Carp */
    445			data->ccd_offset = 0x300;
    446			k10temp_get_ccd_support(pdev, data, 8);
    447			break;
    448		case 0x10 ... 0x1f:
    449		case 0xa0 ... 0xaf:
    450			data->ccd_offset = 0x300;
    451			k10temp_get_ccd_support(pdev, data, 12);
    452			break;
    453		}
    454	} else {
    455		data->read_htcreg = read_htcreg_pci;
    456		data->read_tempreg = read_tempreg_pci;
    457	}
    458
    459	for (i = 0; i < ARRAY_SIZE(tctl_offset_table); i++) {
    460		const struct tctl_offset *entry = &tctl_offset_table[i];
    461
    462		if (boot_cpu_data.x86 == entry->model &&
    463		    strstr(boot_cpu_data.x86_model_id, entry->id)) {
    464			data->show_temp |= BIT(TDIE_BIT);	/* show Tdie */
    465			data->temp_offset = entry->offset;
    466			break;
    467		}
    468	}
    469
    470	hwmon_dev = devm_hwmon_device_register_with_info(dev, "k10temp", data,
    471							 &k10temp_chip_info,
    472							 NULL);
    473	return PTR_ERR_OR_ZERO(hwmon_dev);
    474}
    475
    476static const struct pci_device_id k10temp_id_table[] = {
    477	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
    478	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) },
    479	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
    480	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) },
    481	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) },
    482	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F3) },
    483	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F3) },
    484	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M70H_NB_F3) },
    485	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
    486	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
    487	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
    488	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
    489	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) },
    490	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) },
    491	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) },
    492	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_DF_F3) },
    493	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M10H_DF_F3) },
    494	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M40H_DF_F3) },
    495	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F3) },
    496	{ PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
    497	{}
    498};
    499MODULE_DEVICE_TABLE(pci, k10temp_id_table);
    500
    501static struct pci_driver k10temp_driver = {
    502	.name = "k10temp",
    503	.id_table = k10temp_id_table,
    504	.probe = k10temp_probe,
    505};
    506
    507module_pci_driver(k10temp_driver);