forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
1.9 KiB
101 lines
1.9 KiB
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <perf/cpumap.h> |
|
#include <util/cpumap.h> |
|
#include <internal/cpumap.h> |
|
#include <api/fs/fs.h> |
|
#include <errno.h> |
|
#include "debug.h" |
|
#include "header.h" |
|
|
|
#define MIDR "/regs/identification/midr_el1" |
|
#define MIDR_SIZE 19 |
|
#define MIDR_REVISION_MASK 0xf |
|
#define MIDR_VARIANT_SHIFT 20 |
|
#define MIDR_VARIANT_MASK (0xf << MIDR_VARIANT_SHIFT) |
|
|
|
static int _get_cpuid(char *buf, size_t sz, struct perf_cpu_map *cpus) |
|
{ |
|
const char *sysfs = sysfs__mountpoint(); |
|
u64 midr = 0; |
|
int cpu; |
|
|
|
if (!sysfs || sz < MIDR_SIZE) |
|
return EINVAL; |
|
|
|
cpus = perf_cpu_map__get(cpus); |
|
|
|
for (cpu = 0; cpu < perf_cpu_map__nr(cpus); cpu++) { |
|
char path[PATH_MAX]; |
|
FILE *file; |
|
|
|
scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d"MIDR, |
|
sysfs, cpus->map[cpu]); |
|
|
|
file = fopen(path, "r"); |
|
if (!file) { |
|
pr_debug("fopen failed for file %s\n", path); |
|
continue; |
|
} |
|
|
|
if (!fgets(buf, MIDR_SIZE, file)) { |
|
fclose(file); |
|
continue; |
|
} |
|
fclose(file); |
|
|
|
/* Ignore/clear Variant[23:20] and |
|
* Revision[3:0] of MIDR |
|
*/ |
|
midr = strtoul(buf, NULL, 16); |
|
midr &= (~(MIDR_VARIANT_MASK | MIDR_REVISION_MASK)); |
|
scnprintf(buf, MIDR_SIZE, "0x%016lx", midr); |
|
/* got midr break loop */ |
|
break; |
|
} |
|
|
|
perf_cpu_map__put(cpus); |
|
|
|
if (!midr) |
|
return EINVAL; |
|
|
|
return 0; |
|
} |
|
|
|
int get_cpuid(char *buf, size_t sz) |
|
{ |
|
struct perf_cpu_map *cpus = perf_cpu_map__new(NULL); |
|
int ret; |
|
|
|
if (!cpus) |
|
return EINVAL; |
|
|
|
ret = _get_cpuid(buf, sz, cpus); |
|
|
|
perf_cpu_map__put(cpus); |
|
|
|
return ret; |
|
} |
|
|
|
char *get_cpuid_str(struct perf_pmu *pmu) |
|
{ |
|
char *buf = NULL; |
|
int res; |
|
|
|
if (!pmu || !pmu->cpus) |
|
return NULL; |
|
|
|
buf = malloc(MIDR_SIZE); |
|
if (!buf) |
|
return NULL; |
|
|
|
/* read midr from list of cpus mapped to this pmu */ |
|
res = _get_cpuid(buf, MIDR_SIZE, pmu->cpus); |
|
if (res) { |
|
pr_err("failed to get cpuid string for PMU %s\n", pmu->name); |
|
free(buf); |
|
buf = NULL; |
|
} |
|
|
|
return buf; |
|
}
|
|
|