1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Record and handle CPU attributes. 4 * 5 * Copyright (C) 2014 ARM Ltd. 6 */ 7 #include <asm/arch_timer.h> 8 #include <asm/cache.h> 9 #include <asm/cpu.h> 10 #include <asm/cputype.h> 11 #include <asm/cpufeature.h> 12 #include <asm/fpsimd.h> 13 14 #include <linux/bitops.h> 15 #include <linux/bug.h> 16 #include <linux/compat.h> 17 #include <linux/elf.h> 18 #include <linux/init.h> 19 #include <linux/kernel.h> 20 #include <linux/personality.h> 21 #include <linux/preempt.h> 22 #include <linux/printk.h> 23 #include <linux/seq_file.h> 24 #include <linux/sched.h> 25 #include <linux/smp.h> 26 #include <linux/delay.h> 27 28 /* 29 * In case the boot CPU is hotpluggable, we record its initial state and 30 * current state separately. Certain system registers may contain different 31 * values depending on configuration at or after reset. 32 */ 33 DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data); 34 static struct cpuinfo_arm64 boot_cpu_data; 35 36 static const char *icache_policy_str[] = { 37 [0 ... ICACHE_POLICY_PIPT] = "RESERVED/UNKNOWN", 38 [ICACHE_POLICY_VIPT] = "VIPT", 39 [ICACHE_POLICY_PIPT] = "PIPT", 40 [ICACHE_POLICY_VPIPT] = "VPIPT", 41 }; 42 43 unsigned long __icache_flags; 44 45 static const char *const hwcap_str[] = { 46 "fp", 47 "asimd", 48 "evtstrm", 49 "aes", 50 "pmull", 51 "sha1", 52 "sha2", 53 "crc32", 54 "atomics", 55 "fphp", 56 "asimdhp", 57 "cpuid", 58 "asimdrdm", 59 "jscvt", 60 "fcma", 61 "lrcpc", 62 "dcpop", 63 "sha3", 64 "sm3", 65 "sm4", 66 "asimddp", 67 "sha512", 68 "sve", 69 "asimdfhm", 70 "dit", 71 "uscat", 72 "ilrcpc", 73 "flagm", 74 "ssbs", 75 "sb", 76 "paca", 77 "pacg", 78 "dcpodp", 79 "sve2", 80 "sveaes", 81 "svepmull", 82 "svebitperm", 83 "svesha3", 84 "svesm4", 85 "flagm2", 86 "frint", 87 NULL 88 }; 89 90 #ifdef CONFIG_COMPAT 91 static const char *const compat_hwcap_str[] = { 92 "swp", 93 "half", 94 "thumb", 95 "26bit", 96 "fastmult", 97 "fpa", 98 "vfp", 99 "edsp", 100 "java", 101 "iwmmxt", 102 "crunch", 103 "thumbee", 104 "neon", 105 "vfpv3", 106 "vfpv3d16", 107 "tls", 108 "vfpv4", 109 "idiva", 110 "idivt", 111 "vfpd32", 112 "lpae", 113 "evtstrm", 114 NULL 115 }; 116 117 static const char *const compat_hwcap2_str[] = { 118 "aes", 119 "pmull", 120 "sha1", 121 "sha2", 122 "crc32", 123 NULL 124 }; 125 #endif /* CONFIG_COMPAT */ 126 127 static int c_show(struct seq_file *m, void *v) 128 { 129 int i, j; 130 bool compat = personality(current->personality) == PER_LINUX32; 131 132 for_each_online_cpu(i) { 133 struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i); 134 u32 midr = cpuinfo->reg_midr; 135 136 /* 137 * glibc reads /proc/cpuinfo to determine the number of 138 * online processors, looking for lines beginning with 139 * "processor". Give glibc what it expects. 140 */ 141 seq_printf(m, "processor\t: %d\n", i); 142 if (compat) 143 seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n", 144 MIDR_REVISION(midr), COMPAT_ELF_PLATFORM); 145 146 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", 147 loops_per_jiffy / (500000UL/HZ), 148 loops_per_jiffy / (5000UL/HZ) % 100); 149 150 /* 151 * Dump out the common processor features in a single line. 152 * Userspace should read the hwcaps with getauxval(AT_HWCAP) 153 * rather than attempting to parse this, but there's a body of 154 * software which does already (at least for 32-bit). 155 */ 156 seq_puts(m, "Features\t:"); 157 if (compat) { 158 #ifdef CONFIG_COMPAT 159 for (j = 0; compat_hwcap_str[j]; j++) 160 if (compat_elf_hwcap & (1 << j)) 161 seq_printf(m, " %s", compat_hwcap_str[j]); 162 163 for (j = 0; compat_hwcap2_str[j]; j++) 164 if (compat_elf_hwcap2 & (1 << j)) 165 seq_printf(m, " %s", compat_hwcap2_str[j]); 166 #endif /* CONFIG_COMPAT */ 167 } else { 168 for (j = 0; hwcap_str[j]; j++) 169 if (cpu_have_feature(j)) 170 seq_printf(m, " %s", hwcap_str[j]); 171 } 172 seq_puts(m, "\n"); 173 174 seq_printf(m, "CPU implementer\t: 0x%02x\n", 175 MIDR_IMPLEMENTOR(midr)); 176 seq_printf(m, "CPU architecture: 8\n"); 177 seq_printf(m, "CPU variant\t: 0x%x\n", MIDR_VARIANT(midr)); 178 seq_printf(m, "CPU part\t: 0x%03x\n", MIDR_PARTNUM(midr)); 179 seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr)); 180 } 181 182 return 0; 183 } 184 185 static void *c_start(struct seq_file *m, loff_t *pos) 186 { 187 return *pos < 1 ? (void *)1 : NULL; 188 } 189 190 static void *c_next(struct seq_file *m, void *v, loff_t *pos) 191 { 192 ++*pos; 193 return NULL; 194 } 195 196 static void c_stop(struct seq_file *m, void *v) 197 { 198 } 199 200 const struct seq_operations cpuinfo_op = { 201 .start = c_start, 202 .next = c_next, 203 .stop = c_stop, 204 .show = c_show 205 }; 206 207 208 static struct kobj_type cpuregs_kobj_type = { 209 .sysfs_ops = &kobj_sysfs_ops, 210 }; 211 212 /* 213 * The ARM ARM uses the phrase "32-bit register" to describe a register 214 * whose upper 32 bits are RES0 (per C5.1.1, ARM DDI 0487A.i), however 215 * no statement is made as to whether the upper 32 bits will or will not 216 * be made use of in future, and between ARM DDI 0487A.c and ARM DDI 217 * 0487A.d CLIDR_EL1 was expanded from 32-bit to 64-bit. 218 * 219 * Thus, while both MIDR_EL1 and REVIDR_EL1 are described as 32-bit 220 * registers, we expose them both as 64 bit values to cater for possible 221 * future expansion without an ABI break. 222 */ 223 #define kobj_to_cpuinfo(kobj) container_of(kobj, struct cpuinfo_arm64, kobj) 224 #define CPUREGS_ATTR_RO(_name, _field) \ 225 static ssize_t _name##_show(struct kobject *kobj, \ 226 struct kobj_attribute *attr, char *buf) \ 227 { \ 228 struct cpuinfo_arm64 *info = kobj_to_cpuinfo(kobj); \ 229 \ 230 if (info->reg_midr) \ 231 return sprintf(buf, "0x%016x\n", info->reg_##_field); \ 232 else \ 233 return 0; \ 234 } \ 235 static struct kobj_attribute cpuregs_attr_##_name = __ATTR_RO(_name) 236 237 CPUREGS_ATTR_RO(midr_el1, midr); 238 CPUREGS_ATTR_RO(revidr_el1, revidr); 239 240 static struct attribute *cpuregs_id_attrs[] = { 241 &cpuregs_attr_midr_el1.attr, 242 &cpuregs_attr_revidr_el1.attr, 243 NULL 244 }; 245 246 static const struct attribute_group cpuregs_attr_group = { 247 .attrs = cpuregs_id_attrs, 248 .name = "identification" 249 }; 250 251 static int cpuid_cpu_online(unsigned int cpu) 252 { 253 int rc; 254 struct device *dev; 255 struct cpuinfo_arm64 *info = &per_cpu(cpu_data, cpu); 256 257 dev = get_cpu_device(cpu); 258 if (!dev) { 259 rc = -ENODEV; 260 goto out; 261 } 262 rc = kobject_add(&info->kobj, &dev->kobj, "regs"); 263 if (rc) 264 goto out; 265 rc = sysfs_create_group(&info->kobj, &cpuregs_attr_group); 266 if (rc) 267 kobject_del(&info->kobj); 268 out: 269 return rc; 270 } 271 272 static int cpuid_cpu_offline(unsigned int cpu) 273 { 274 struct device *dev; 275 struct cpuinfo_arm64 *info = &per_cpu(cpu_data, cpu); 276 277 dev = get_cpu_device(cpu); 278 if (!dev) 279 return -ENODEV; 280 if (info->kobj.parent) { 281 sysfs_remove_group(&info->kobj, &cpuregs_attr_group); 282 kobject_del(&info->kobj); 283 } 284 285 return 0; 286 } 287 288 static int __init cpuinfo_regs_init(void) 289 { 290 int cpu, ret; 291 292 for_each_possible_cpu(cpu) { 293 struct cpuinfo_arm64 *info = &per_cpu(cpu_data, cpu); 294 295 kobject_init(&info->kobj, &cpuregs_kobj_type); 296 } 297 298 ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm64/cpuinfo:online", 299 cpuid_cpu_online, cpuid_cpu_offline); 300 if (ret < 0) { 301 pr_err("cpuinfo: failed to register hotplug callbacks.\n"); 302 return ret; 303 } 304 return 0; 305 } 306 static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info) 307 { 308 unsigned int cpu = smp_processor_id(); 309 u32 l1ip = CTR_L1IP(info->reg_ctr); 310 311 switch (l1ip) { 312 case ICACHE_POLICY_PIPT: 313 break; 314 case ICACHE_POLICY_VPIPT: 315 set_bit(ICACHEF_VPIPT, &__icache_flags); 316 break; 317 default: 318 /* Fallthrough */ 319 case ICACHE_POLICY_VIPT: 320 /* Assume aliasing */ 321 set_bit(ICACHEF_ALIASING, &__icache_flags); 322 } 323 324 pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu); 325 } 326 327 static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) 328 { 329 info->reg_cntfrq = arch_timer_get_cntfrq(); 330 /* 331 * Use the effective value of the CTR_EL0 than the raw value 332 * exposed by the CPU. CTR_E0.IDC field value must be interpreted 333 * with the CLIDR_EL1 fields to avoid triggering false warnings 334 * when there is a mismatch across the CPUs. Keep track of the 335 * effective value of the CTR_EL0 in our internal records for 336 * acurate sanity check and feature enablement. 337 */ 338 info->reg_ctr = read_cpuid_effective_cachetype(); 339 info->reg_dczid = read_cpuid(DCZID_EL0); 340 info->reg_midr = read_cpuid_id(); 341 info->reg_revidr = read_cpuid(REVIDR_EL1); 342 343 info->reg_id_aa64dfr0 = read_cpuid(ID_AA64DFR0_EL1); 344 info->reg_id_aa64dfr1 = read_cpuid(ID_AA64DFR1_EL1); 345 info->reg_id_aa64isar0 = read_cpuid(ID_AA64ISAR0_EL1); 346 info->reg_id_aa64isar1 = read_cpuid(ID_AA64ISAR1_EL1); 347 info->reg_id_aa64mmfr0 = read_cpuid(ID_AA64MMFR0_EL1); 348 info->reg_id_aa64mmfr1 = read_cpuid(ID_AA64MMFR1_EL1); 349 info->reg_id_aa64mmfr2 = read_cpuid(ID_AA64MMFR2_EL1); 350 info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1); 351 info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1); 352 info->reg_id_aa64zfr0 = read_cpuid(ID_AA64ZFR0_EL1); 353 354 /* Update the 32bit ID registers only if AArch32 is implemented */ 355 if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) { 356 info->reg_id_dfr0 = read_cpuid(ID_DFR0_EL1); 357 info->reg_id_isar0 = read_cpuid(ID_ISAR0_EL1); 358 info->reg_id_isar1 = read_cpuid(ID_ISAR1_EL1); 359 info->reg_id_isar2 = read_cpuid(ID_ISAR2_EL1); 360 info->reg_id_isar3 = read_cpuid(ID_ISAR3_EL1); 361 info->reg_id_isar4 = read_cpuid(ID_ISAR4_EL1); 362 info->reg_id_isar5 = read_cpuid(ID_ISAR5_EL1); 363 info->reg_id_mmfr0 = read_cpuid(ID_MMFR0_EL1); 364 info->reg_id_mmfr1 = read_cpuid(ID_MMFR1_EL1); 365 info->reg_id_mmfr2 = read_cpuid(ID_MMFR2_EL1); 366 info->reg_id_mmfr3 = read_cpuid(ID_MMFR3_EL1); 367 info->reg_id_pfr0 = read_cpuid(ID_PFR0_EL1); 368 info->reg_id_pfr1 = read_cpuid(ID_PFR1_EL1); 369 370 info->reg_mvfr0 = read_cpuid(MVFR0_EL1); 371 info->reg_mvfr1 = read_cpuid(MVFR1_EL1); 372 info->reg_mvfr2 = read_cpuid(MVFR2_EL1); 373 } 374 375 if (IS_ENABLED(CONFIG_ARM64_SVE) && 376 id_aa64pfr0_sve(info->reg_id_aa64pfr0)) 377 info->reg_zcr = read_zcr_features(); 378 379 cpuinfo_detect_icache_policy(info); 380 } 381 382 void cpuinfo_store_cpu(void) 383 { 384 struct cpuinfo_arm64 *info = this_cpu_ptr(&cpu_data); 385 __cpuinfo_store_cpu(info); 386 update_cpu_features(smp_processor_id(), info, &boot_cpu_data); 387 } 388 389 void __init cpuinfo_store_boot_cpu(void) 390 { 391 struct cpuinfo_arm64 *info = &per_cpu(cpu_data, 0); 392 __cpuinfo_store_cpu(info); 393 394 boot_cpu_data = *info; 395 init_cpu_features(&boot_cpu_data); 396 } 397 398 device_initcall(cpuinfo_regs_init); 399