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

soc-imx.c (4679B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright 2020 NXP
      4 */
      5
      6#include <linux/mfd/syscon.h>
      7#include <linux/of.h>
      8#include <linux/of_address.h>
      9#include <linux/regmap.h>
     10#include <linux/slab.h>
     11#include <linux/sys_soc.h>
     12
     13#include <soc/imx/cpu.h>
     14#include <soc/imx/revision.h>
     15
     16#define IIM_UID		0x820
     17
     18#define OCOTP_UID_H	0x420
     19#define OCOTP_UID_L	0x410
     20
     21#define OCOTP_ULP_UID_1		0x4b0
     22#define OCOTP_ULP_UID_2		0x4c0
     23#define OCOTP_ULP_UID_3		0x4d0
     24#define OCOTP_ULP_UID_4		0x4e0
     25
     26static int __init imx_soc_device_init(void)
     27{
     28	struct soc_device_attribute *soc_dev_attr;
     29	const char *ocotp_compat = NULL;
     30	struct soc_device *soc_dev;
     31	struct device_node *root;
     32	struct regmap *ocotp = NULL;
     33	const char *soc_id;
     34	u64 soc_uid = 0;
     35	u32 val;
     36	int ret;
     37	int i;
     38
     39	/* Return early if this is running on devices with different SoCs */
     40	if (!__mxc_cpu_type)
     41		return 0;
     42
     43	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
     44	if (!soc_dev_attr)
     45		return -ENOMEM;
     46
     47	soc_dev_attr->family = "Freescale i.MX";
     48
     49	root = of_find_node_by_path("/");
     50	ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
     51	of_node_put(root);
     52	if (ret)
     53		goto free_soc;
     54
     55	switch (__mxc_cpu_type) {
     56	case MXC_CPU_MX1:
     57		soc_id = "i.MX1";
     58		break;
     59	case MXC_CPU_MX21:
     60		soc_id = "i.MX21";
     61		break;
     62	case MXC_CPU_MX25:
     63		soc_id = "i.MX25";
     64		break;
     65	case MXC_CPU_MX27:
     66		soc_id = "i.MX27";
     67		break;
     68	case MXC_CPU_MX31:
     69		soc_id = "i.MX31";
     70		break;
     71	case MXC_CPU_MX35:
     72		soc_id = "i.MX35";
     73		break;
     74	case MXC_CPU_MX50:
     75		soc_id = "i.MX50";
     76		break;
     77	case MXC_CPU_MX51:
     78		ocotp_compat = "fsl,imx51-iim";
     79		soc_id = "i.MX51";
     80		break;
     81	case MXC_CPU_MX53:
     82		ocotp_compat = "fsl,imx53-iim";
     83		soc_id = "i.MX53";
     84		break;
     85	case MXC_CPU_IMX6SL:
     86		ocotp_compat = "fsl,imx6sl-ocotp";
     87		soc_id = "i.MX6SL";
     88		break;
     89	case MXC_CPU_IMX6DL:
     90		ocotp_compat = "fsl,imx6q-ocotp";
     91		soc_id = "i.MX6DL";
     92		break;
     93	case MXC_CPU_IMX6SX:
     94		ocotp_compat = "fsl,imx6sx-ocotp";
     95		soc_id = "i.MX6SX";
     96		break;
     97	case MXC_CPU_IMX6Q:
     98		ocotp_compat = "fsl,imx6q-ocotp";
     99		soc_id = "i.MX6Q";
    100		break;
    101	case MXC_CPU_IMX6UL:
    102		ocotp_compat = "fsl,imx6ul-ocotp";
    103		soc_id = "i.MX6UL";
    104		break;
    105	case MXC_CPU_IMX6ULL:
    106		ocotp_compat = "fsl,imx6ull-ocotp";
    107		soc_id = "i.MX6ULL";
    108		break;
    109	case MXC_CPU_IMX6ULZ:
    110		ocotp_compat = "fsl,imx6ull-ocotp";
    111		soc_id = "i.MX6ULZ";
    112		break;
    113	case MXC_CPU_IMX6SLL:
    114		ocotp_compat = "fsl,imx6sll-ocotp";
    115		soc_id = "i.MX6SLL";
    116		break;
    117	case MXC_CPU_IMX7D:
    118		ocotp_compat = "fsl,imx7d-ocotp";
    119		soc_id = "i.MX7D";
    120		break;
    121	case MXC_CPU_IMX7ULP:
    122		ocotp_compat = "fsl,imx7ulp-ocotp";
    123		soc_id = "i.MX7ULP";
    124		break;
    125	case MXC_CPU_VF500:
    126		ocotp_compat = "fsl,vf610-ocotp";
    127		soc_id = "VF500";
    128		break;
    129	case MXC_CPU_VF510:
    130		ocotp_compat = "fsl,vf610-ocotp";
    131		soc_id = "VF510";
    132		break;
    133	case MXC_CPU_VF600:
    134		ocotp_compat = "fsl,vf610-ocotp";
    135		soc_id = "VF600";
    136		break;
    137	case MXC_CPU_VF610:
    138		ocotp_compat = "fsl,vf610-ocotp";
    139		soc_id = "VF610";
    140		break;
    141	default:
    142		soc_id = "Unknown";
    143	}
    144	soc_dev_attr->soc_id = soc_id;
    145
    146	if (ocotp_compat) {
    147		ocotp = syscon_regmap_lookup_by_compatible(ocotp_compat);
    148		if (IS_ERR(ocotp))
    149			pr_err("%s: failed to find %s regmap!\n", __func__, ocotp_compat);
    150	}
    151
    152	if (!IS_ERR_OR_NULL(ocotp)) {
    153		if (__mxc_cpu_type == MXC_CPU_IMX7ULP) {
    154			regmap_read(ocotp, OCOTP_ULP_UID_4, &val);
    155			soc_uid = val & 0xffff;
    156			regmap_read(ocotp, OCOTP_ULP_UID_3, &val);
    157			soc_uid <<= 16;
    158			soc_uid |= val & 0xffff;
    159			regmap_read(ocotp, OCOTP_ULP_UID_2, &val);
    160			soc_uid <<= 16;
    161			soc_uid |= val & 0xffff;
    162			regmap_read(ocotp, OCOTP_ULP_UID_1, &val);
    163			soc_uid <<= 16;
    164			soc_uid |= val & 0xffff;
    165		} else if (__mxc_cpu_type == MXC_CPU_MX51 ||
    166			   __mxc_cpu_type == MXC_CPU_MX53) {
    167			for (i=0; i < 8; i++) {
    168				regmap_read(ocotp, IIM_UID + i*4, &val);
    169				soc_uid <<= 8;
    170				soc_uid |= (val & 0xff);
    171			}
    172		} else {
    173			regmap_read(ocotp, OCOTP_UID_H, &val);
    174			soc_uid = val;
    175			regmap_read(ocotp, OCOTP_UID_L, &val);
    176			soc_uid <<= 32;
    177			soc_uid |= val;
    178		}
    179	}
    180
    181	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d.%d",
    182					   (imx_get_soc_revision() >> 4) & 0xf,
    183					   imx_get_soc_revision() & 0xf);
    184	if (!soc_dev_attr->revision) {
    185		ret = -ENOMEM;
    186		goto free_soc;
    187	}
    188
    189	soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX", soc_uid);
    190	if (!soc_dev_attr->serial_number) {
    191		ret = -ENOMEM;
    192		goto free_rev;
    193	}
    194
    195	soc_dev = soc_device_register(soc_dev_attr);
    196	if (IS_ERR(soc_dev)) {
    197		ret = PTR_ERR(soc_dev);
    198		goto free_serial_number;
    199	}
    200
    201	return 0;
    202
    203free_serial_number:
    204	kfree(soc_dev_attr->serial_number);
    205free_rev:
    206	kfree(soc_dev_attr->revision);
    207free_soc:
    208	kfree(soc_dev_attr);
    209	return ret;
    210}
    211device_initcall(imx_soc_device_init);