1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <perf/cpumap.h> 4 #include <util/cpumap.h> 5 #include <internal/cpumap.h> 6 #include <api/fs/fs.h> 7 #include <errno.h> 8 #include "debug.h" 9 #include "header.h" 10 11 #define MIDR "/regs/identification/midr_el1" 12 #define MIDR_SIZE 19 13 #define MIDR_REVISION_MASK 0xf 14 #define MIDR_VARIANT_SHIFT 20 15 #define MIDR_VARIANT_MASK (0xf << MIDR_VARIANT_SHIFT) 16 17 static int _get_cpuid(char *buf, size_t sz, struct perf_cpu_map *cpus) 18 { 19 const char *sysfs = sysfs__mountpoint(); 20 u64 midr = 0; 21 int cpu; 22 23 if (!sysfs || sz < MIDR_SIZE) 24 return EINVAL; 25 26 cpus = perf_cpu_map__get(cpus); 27 28 for (cpu = 0; cpu < perf_cpu_map__nr(cpus); cpu++) { 29 char path[PATH_MAX]; 30 FILE *file; 31 32 scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d"MIDR, 33 sysfs, cpus->map[cpu]); 34 35 file = fopen(path, "r"); 36 if (!file) { 37 pr_debug("fopen failed for file %s\n", path); 38 continue; 39 } 40 41 if (!fgets(buf, MIDR_SIZE, file)) { 42 fclose(file); 43 continue; 44 } 45 fclose(file); 46 47 /* Ignore/clear Variant[23:20] and 48 * Revision[3:0] of MIDR 49 */ 50 midr = strtoul(buf, NULL, 16); 51 midr &= (~(MIDR_VARIANT_MASK | MIDR_REVISION_MASK)); 52 scnprintf(buf, MIDR_SIZE, "0x%016lx", midr); 53 /* got midr break loop */ 54 break; 55 } 56 57 perf_cpu_map__put(cpus); 58 59 if (!midr) 60 return EINVAL; 61 62 return 0; 63 } 64 65 int get_cpuid(char *buf, size_t sz) 66 { 67 struct perf_cpu_map *cpus = perf_cpu_map__new(NULL); 68 int ret; 69 70 if (!cpus) 71 return EINVAL; 72 73 ret = _get_cpuid(buf, sz, cpus); 74 75 perf_cpu_map__put(cpus); 76 77 return ret; 78 } 79 80 char *get_cpuid_str(struct perf_pmu *pmu) 81 { 82 char *buf = NULL; 83 int res; 84 85 if (!pmu || !pmu->cpus) 86 return NULL; 87 88 buf = malloc(MIDR_SIZE); 89 if (!buf) 90 return NULL; 91 92 /* read midr from list of cpus mapped to this pmu */ 93 res = _get_cpuid(buf, MIDR_SIZE, pmu->cpus); 94 if (res) { 95 pr_err("failed to get cpuid string for PMU %s\n", pmu->name); 96 free(buf); 97 buf = NULL; 98 } 99 100 return buf; 101 } 102