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

sysfs.c (11603B)


      1// SPDX-License-Identifier: GPL-2.0
      2
      3/*
      4 * Copyright 2016-2022 HabanaLabs, Ltd.
      5 * All Rights Reserved.
      6 */
      7
      8#include "habanalabs.h"
      9
     10#include <linux/pci.h>
     11
     12static ssize_t clk_max_freq_mhz_show(struct device *dev, struct device_attribute *attr, char *buf)
     13{
     14	struct hl_device *hdev = dev_get_drvdata(dev);
     15	long value;
     16
     17	if (!hl_device_operational(hdev, NULL))
     18		return -ENODEV;
     19
     20	value = hl_fw_get_frequency(hdev, hdev->asic_prop.clk_pll_index, false);
     21	if (value < 0)
     22		return value;
     23
     24	hdev->asic_prop.max_freq_value = value;
     25
     26	return sprintf(buf, "%lu\n", (value / 1000 / 1000));
     27}
     28
     29static ssize_t clk_max_freq_mhz_store(struct device *dev, struct device_attribute *attr,
     30					const char *buf, size_t count)
     31{
     32	struct hl_device *hdev = dev_get_drvdata(dev);
     33	int rc;
     34	u64 value;
     35
     36	if (!hl_device_operational(hdev, NULL)) {
     37		count = -ENODEV;
     38		goto fail;
     39	}
     40
     41	rc = kstrtoull(buf, 0, &value);
     42	if (rc) {
     43		count = -EINVAL;
     44		goto fail;
     45	}
     46
     47	hdev->asic_prop.max_freq_value = value * 1000 * 1000;
     48
     49	hl_fw_set_frequency(hdev, hdev->asic_prop.clk_pll_index, hdev->asic_prop.max_freq_value);
     50
     51fail:
     52	return count;
     53}
     54
     55static ssize_t clk_cur_freq_mhz_show(struct device *dev, struct device_attribute *attr, char *buf)
     56{
     57	struct hl_device *hdev = dev_get_drvdata(dev);
     58	long value;
     59
     60	if (!hl_device_operational(hdev, NULL))
     61		return -ENODEV;
     62
     63	value = hl_fw_get_frequency(hdev, hdev->asic_prop.clk_pll_index, true);
     64	if (value < 0)
     65		return value;
     66
     67	return sprintf(buf, "%lu\n", (value / 1000 / 1000));
     68}
     69
     70static DEVICE_ATTR_RW(clk_max_freq_mhz);
     71static DEVICE_ATTR_RO(clk_cur_freq_mhz);
     72
     73static struct attribute *hl_dev_clk_attrs[] = {
     74	&dev_attr_clk_max_freq_mhz.attr,
     75	&dev_attr_clk_cur_freq_mhz.attr,
     76};
     77
     78static ssize_t vrm_ver_show(struct device *dev, struct device_attribute *attr, char *buf)
     79{
     80	struct hl_device *hdev = dev_get_drvdata(dev);
     81	struct cpucp_info *cpucp_info;
     82
     83	cpucp_info = &hdev->asic_prop.cpucp_info;
     84
     85	if (cpucp_info->infineon_second_stage_version)
     86		return sprintf(buf, "%#04x %#04x\n", le32_to_cpu(cpucp_info->infineon_version),
     87				le32_to_cpu(cpucp_info->infineon_second_stage_version));
     88	else
     89		return sprintf(buf, "%#04x\n", le32_to_cpu(cpucp_info->infineon_version));
     90}
     91
     92static DEVICE_ATTR_RO(vrm_ver);
     93
     94static struct attribute *hl_dev_vrm_attrs[] = {
     95	&dev_attr_vrm_ver.attr,
     96};
     97
     98static ssize_t uboot_ver_show(struct device *dev, struct device_attribute *attr,
     99				char *buf)
    100{
    101	struct hl_device *hdev = dev_get_drvdata(dev);
    102
    103	return sprintf(buf, "%s\n", hdev->asic_prop.uboot_ver);
    104}
    105
    106static ssize_t armcp_kernel_ver_show(struct device *dev,
    107				struct device_attribute *attr, char *buf)
    108{
    109	struct hl_device *hdev = dev_get_drvdata(dev);
    110
    111	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.kernel_version);
    112}
    113
    114static ssize_t armcp_ver_show(struct device *dev, struct device_attribute *attr,
    115				char *buf)
    116{
    117	struct hl_device *hdev = dev_get_drvdata(dev);
    118
    119	return sprintf(buf, "%s\n", hdev->asic_prop.cpucp_info.cpucp_version);
    120}
    121
    122static ssize_t cpld_ver_show(struct device *dev, struct device_attribute *attr,
    123				char *buf)
    124{
    125	struct hl_device *hdev = dev_get_drvdata(dev);
    126
    127	return sprintf(buf, "0x%08x\n",
    128			le32_to_cpu(hdev->asic_prop.cpucp_info.cpld_version));
    129}
    130
    131static ssize_t cpucp_kernel_ver_show(struct device *dev,
    132				struct device_attribute *attr, char *buf)
    133{
    134	struct hl_device *hdev = dev_get_drvdata(dev);
    135
    136	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.kernel_version);
    137}
    138
    139static ssize_t cpucp_ver_show(struct device *dev, struct device_attribute *attr,
    140				char *buf)
    141{
    142	struct hl_device *hdev = dev_get_drvdata(dev);
    143
    144	return sprintf(buf, "%s\n", hdev->asic_prop.cpucp_info.cpucp_version);
    145}
    146
    147static ssize_t fuse_ver_show(struct device *dev, struct device_attribute *attr,
    148				char *buf)
    149{
    150	struct hl_device *hdev = dev_get_drvdata(dev);
    151
    152	return sprintf(buf, "%s\n", hdev->asic_prop.cpucp_info.fuse_version);
    153}
    154
    155static ssize_t thermal_ver_show(struct device *dev,
    156				struct device_attribute *attr, char *buf)
    157{
    158	struct hl_device *hdev = dev_get_drvdata(dev);
    159
    160	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.thermal_version);
    161}
    162
    163static ssize_t fw_os_ver_show(struct device *dev,
    164				struct device_attribute *attr, char *buf)
    165{
    166	struct hl_device *hdev = dev_get_drvdata(dev);
    167
    168	return sprintf(buf, "%s", hdev->asic_prop.cpucp_info.fw_os_version);
    169}
    170
    171static ssize_t preboot_btl_ver_show(struct device *dev,
    172				struct device_attribute *attr, char *buf)
    173{
    174	struct hl_device *hdev = dev_get_drvdata(dev);
    175
    176	return sprintf(buf, "%s\n", hdev->asic_prop.preboot_ver);
    177}
    178
    179static ssize_t soft_reset_store(struct device *dev,
    180				struct device_attribute *attr, const char *buf,
    181				size_t count)
    182{
    183	struct hl_device *hdev = dev_get_drvdata(dev);
    184	long value;
    185	int rc;
    186
    187	rc = kstrtoul(buf, 0, &value);
    188
    189	if (rc) {
    190		count = -EINVAL;
    191		goto out;
    192	}
    193
    194	if (!hdev->asic_prop.allow_inference_soft_reset) {
    195		dev_err(hdev->dev, "Device does not support inference soft-reset\n");
    196		goto out;
    197	}
    198
    199	dev_warn(hdev->dev, "Inference Soft-Reset requested through sysfs\n");
    200
    201	hl_device_reset(hdev, 0);
    202
    203out:
    204	return count;
    205}
    206
    207static ssize_t hard_reset_store(struct device *dev,
    208				struct device_attribute *attr,
    209				const char *buf, size_t count)
    210{
    211	struct hl_device *hdev = dev_get_drvdata(dev);
    212	long value;
    213	int rc;
    214
    215	rc = kstrtoul(buf, 0, &value);
    216
    217	if (rc) {
    218		count = -EINVAL;
    219		goto out;
    220	}
    221
    222	dev_warn(hdev->dev, "Hard-Reset requested through sysfs\n");
    223
    224	hl_device_reset(hdev, HL_DRV_RESET_HARD);
    225
    226out:
    227	return count;
    228}
    229
    230static ssize_t device_type_show(struct device *dev,
    231		struct device_attribute *attr, char *buf)
    232{
    233	struct hl_device *hdev = dev_get_drvdata(dev);
    234	char *str;
    235
    236	switch (hdev->asic_type) {
    237	case ASIC_GOYA:
    238		str = "GOYA";
    239		break;
    240	case ASIC_GAUDI:
    241		str = "GAUDI";
    242		break;
    243	case ASIC_GAUDI_SEC:
    244		str = "GAUDI SEC";
    245		break;
    246	default:
    247		dev_err(hdev->dev, "Unrecognized ASIC type %d\n",
    248				hdev->asic_type);
    249		return -EINVAL;
    250	}
    251
    252	return sprintf(buf, "%s\n", str);
    253}
    254
    255static ssize_t pci_addr_show(struct device *dev, struct device_attribute *attr,
    256				char *buf)
    257{
    258	struct hl_device *hdev = dev_get_drvdata(dev);
    259
    260	return sprintf(buf, "%04x:%02x:%02x.%x\n",
    261			pci_domain_nr(hdev->pdev->bus),
    262			hdev->pdev->bus->number,
    263			PCI_SLOT(hdev->pdev->devfn),
    264			PCI_FUNC(hdev->pdev->devfn));
    265}
    266
    267static ssize_t status_show(struct device *dev, struct device_attribute *attr,
    268				char *buf)
    269{
    270	struct hl_device *hdev = dev_get_drvdata(dev);
    271	char str[HL_STR_MAX];
    272
    273	strscpy(str, hdev->status[hl_device_status(hdev)], HL_STR_MAX);
    274
    275	/* use uppercase for backward compatibility */
    276	str[0] = 'A' + (str[0] - 'a');
    277
    278	return sprintf(buf, "%s\n", str);
    279}
    280
    281static ssize_t soft_reset_cnt_show(struct device *dev,
    282		struct device_attribute *attr, char *buf)
    283{
    284	struct hl_device *hdev = dev_get_drvdata(dev);
    285
    286	return sprintf(buf, "%d\n", hdev->reset_info.soft_reset_cnt);
    287}
    288
    289static ssize_t hard_reset_cnt_show(struct device *dev,
    290		struct device_attribute *attr, char *buf)
    291{
    292	struct hl_device *hdev = dev_get_drvdata(dev);
    293
    294	return sprintf(buf, "%d\n", hdev->reset_info.hard_reset_cnt);
    295}
    296
    297static ssize_t max_power_show(struct device *dev, struct device_attribute *attr,
    298				char *buf)
    299{
    300	struct hl_device *hdev = dev_get_drvdata(dev);
    301	long val;
    302
    303	if (!hl_device_operational(hdev, NULL))
    304		return -ENODEV;
    305
    306	val = hl_fw_get_max_power(hdev);
    307	if (val < 0)
    308		return val;
    309
    310	return sprintf(buf, "%lu\n", val);
    311}
    312
    313static ssize_t max_power_store(struct device *dev,
    314		struct device_attribute *attr, const char *buf, size_t count)
    315{
    316	struct hl_device *hdev = dev_get_drvdata(dev);
    317	unsigned long value;
    318	int rc;
    319
    320	if (!hl_device_operational(hdev, NULL)) {
    321		count = -ENODEV;
    322		goto out;
    323	}
    324
    325	rc = kstrtoul(buf, 0, &value);
    326
    327	if (rc) {
    328		count = -EINVAL;
    329		goto out;
    330	}
    331
    332	hdev->max_power = value;
    333	hl_fw_set_max_power(hdev);
    334
    335out:
    336	return count;
    337}
    338
    339static ssize_t eeprom_read_handler(struct file *filp, struct kobject *kobj,
    340			struct bin_attribute *attr, char *buf, loff_t offset,
    341			size_t max_size)
    342{
    343	struct device *dev = kobj_to_dev(kobj);
    344	struct hl_device *hdev = dev_get_drvdata(dev);
    345	char *data;
    346	int rc;
    347
    348	if (!hl_device_operational(hdev, NULL))
    349		return -ENODEV;
    350
    351	if (!max_size)
    352		return -EINVAL;
    353
    354	data = kzalloc(max_size, GFP_KERNEL);
    355	if (!data)
    356		return -ENOMEM;
    357
    358	rc = hdev->asic_funcs->get_eeprom_data(hdev, data, max_size);
    359	if (rc)
    360		goto out;
    361
    362	memcpy(buf, data, max_size);
    363
    364out:
    365	kfree(data);
    366
    367	return max_size;
    368}
    369
    370static DEVICE_ATTR_RO(armcp_kernel_ver);
    371static DEVICE_ATTR_RO(armcp_ver);
    372static DEVICE_ATTR_RO(cpld_ver);
    373static DEVICE_ATTR_RO(cpucp_kernel_ver);
    374static DEVICE_ATTR_RO(cpucp_ver);
    375static DEVICE_ATTR_RO(device_type);
    376static DEVICE_ATTR_RO(fuse_ver);
    377static DEVICE_ATTR_WO(hard_reset);
    378static DEVICE_ATTR_RO(hard_reset_cnt);
    379static DEVICE_ATTR_RW(max_power);
    380static DEVICE_ATTR_RO(pci_addr);
    381static DEVICE_ATTR_RO(preboot_btl_ver);
    382static DEVICE_ATTR_WO(soft_reset);
    383static DEVICE_ATTR_RO(soft_reset_cnt);
    384static DEVICE_ATTR_RO(status);
    385static DEVICE_ATTR_RO(thermal_ver);
    386static DEVICE_ATTR_RO(uboot_ver);
    387static DEVICE_ATTR_RO(fw_os_ver);
    388
    389static struct bin_attribute bin_attr_eeprom = {
    390	.attr = {.name = "eeprom", .mode = (0444)},
    391	.size = PAGE_SIZE,
    392	.read = eeprom_read_handler
    393};
    394
    395static struct attribute *hl_dev_attrs[] = {
    396	&dev_attr_armcp_kernel_ver.attr,
    397	&dev_attr_armcp_ver.attr,
    398	&dev_attr_cpld_ver.attr,
    399	&dev_attr_cpucp_kernel_ver.attr,
    400	&dev_attr_cpucp_ver.attr,
    401	&dev_attr_device_type.attr,
    402	&dev_attr_fuse_ver.attr,
    403	&dev_attr_hard_reset.attr,
    404	&dev_attr_hard_reset_cnt.attr,
    405	&dev_attr_max_power.attr,
    406	&dev_attr_pci_addr.attr,
    407	&dev_attr_preboot_btl_ver.attr,
    408	&dev_attr_status.attr,
    409	&dev_attr_thermal_ver.attr,
    410	&dev_attr_uboot_ver.attr,
    411	&dev_attr_fw_os_ver.attr,
    412	NULL,
    413};
    414
    415static struct bin_attribute *hl_dev_bin_attrs[] = {
    416	&bin_attr_eeprom,
    417	NULL
    418};
    419
    420static struct attribute_group hl_dev_attr_group = {
    421	.attrs = hl_dev_attrs,
    422	.bin_attrs = hl_dev_bin_attrs,
    423};
    424
    425static struct attribute_group hl_dev_clks_attr_group;
    426static struct attribute_group hl_dev_vrm_attr_group;
    427
    428static const struct attribute_group *hl_dev_attr_groups[] = {
    429	&hl_dev_attr_group,
    430	&hl_dev_clks_attr_group,
    431	&hl_dev_vrm_attr_group,
    432	NULL,
    433};
    434
    435static struct attribute *hl_dev_inference_attrs[] = {
    436	&dev_attr_soft_reset.attr,
    437	&dev_attr_soft_reset_cnt.attr,
    438	NULL,
    439};
    440
    441static struct attribute_group hl_dev_inference_attr_group = {
    442	.attrs = hl_dev_inference_attrs,
    443};
    444
    445static const struct attribute_group *hl_dev_inference_attr_groups[] = {
    446	&hl_dev_inference_attr_group,
    447	NULL,
    448};
    449
    450void hl_sysfs_add_dev_clk_attr(struct hl_device *hdev, struct attribute_group *dev_clk_attr_grp)
    451{
    452	dev_clk_attr_grp->attrs = hl_dev_clk_attrs;
    453}
    454
    455void hl_sysfs_add_dev_vrm_attr(struct hl_device *hdev, struct attribute_group *dev_vrm_attr_grp)
    456{
    457	dev_vrm_attr_grp->attrs = hl_dev_vrm_attrs;
    458}
    459
    460int hl_sysfs_init(struct hl_device *hdev)
    461{
    462	int rc;
    463
    464	hdev->max_power = hdev->asic_prop.max_power_default;
    465
    466	hdev->asic_funcs->add_device_attr(hdev, &hl_dev_clks_attr_group, &hl_dev_vrm_attr_group);
    467
    468	rc = device_add_groups(hdev->dev, hl_dev_attr_groups);
    469	if (rc) {
    470		dev_err(hdev->dev,
    471			"Failed to add groups to device, error %d\n", rc);
    472		return rc;
    473	}
    474
    475	if (!hdev->asic_prop.allow_inference_soft_reset)
    476		return 0;
    477
    478	rc = device_add_groups(hdev->dev, hl_dev_inference_attr_groups);
    479	if (rc) {
    480		dev_err(hdev->dev,
    481			"Failed to add groups to device, error %d\n", rc);
    482		return rc;
    483	}
    484
    485	return 0;
    486}
    487
    488void hl_sysfs_fini(struct hl_device *hdev)
    489{
    490	device_remove_groups(hdev->dev, hl_dev_attr_groups);
    491
    492	if (!hdev->asic_prop.allow_inference_soft_reset)
    493		return;
    494
    495	device_remove_groups(hdev->dev, hl_dev_inference_attr_groups);
    496}