@@ -29,6 +29,7 @@ struct cpuinfo_arm64 {
u32 reg_cntfrq;
u32 reg_dczid;
u32 reg_midr;
+ u32 reg_revidr;
u64 reg_id_aa64dfr0;
u64 reg_id_aa64dfr1;
@@ -199,6 +199,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
info->reg_ctr = read_cpuid_cachetype();
info->reg_dczid = read_cpuid(DCZID_EL0);
info->reg_midr = read_cpuid_id();
+ info->reg_revidr = read_cpuid(REVIDR_EL1);
info->reg_id_aa64dfr0 = read_cpuid(ID_AA64DFR0_EL1);
info->reg_id_aa64dfr1 = read_cpuid(ID_AA64DFR1_EL1);
@@ -247,3 +248,50 @@ void __init cpuinfo_store_boot_cpu(void)
boot_cpu_data = *info;
init_cpu_features(&boot_cpu_data);
}
+
+#define CPUINFO_ATTR_RO(_name) \
+ static ssize_t show_##_name (struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+ { \
+ struct cpuinfo_arm64 *info = &per_cpu(cpu_data, dev->id); \
+ \
+ if (info->reg_midr) \
+ return sprintf(buf, "0x%016x\n", info->reg_##_name); \
+ else \
+ return 0; \
+ } \
+ static DEVICE_ATTR(_name, 0444, show_##_name, NULL)
+
+CPUINFO_ATTR_RO(midr);
+CPUINFO_ATTR_RO(revidr);
+
+static struct attribute *cpuregs_attrs[] = {
+ &dev_attr_midr.attr,
+ &dev_attr_revidr.attr,
+ NULL
+};
+
+static struct attribute_group cpuregs_attr_group = {
+ .attrs = cpuregs_attrs,
+ .name = "identification"
+};
+
+static int __init cpuinfo_regs_init(void)
+{
+ int cpu, ret;
+
+ for_each_present_cpu(cpu) {
+ struct device *dev = get_cpu_device(cpu);
+
+ if (!dev)
+ return -1;
+
+ ret = sysfs_create_group(&dev->kobj, &cpuregs_attr_group);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+device_initcall(cpuinfo_regs_init);