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