linux/tools/perf/arch/arm64/util/header.c
<<
>>
Prefs
   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
  17static 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
  65int 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
  80char *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