Back to home page

OSCL-LXR

 
 

    


0001 #include <stdio.h>
0002 #include <stdlib.h>
0003 #include <perf/cpumap.h>
0004 #include <util/cpumap.h>
0005 #include <internal/cpumap.h>
0006 #include <api/fs/fs.h>
0007 #include <errno.h>
0008 #include "debug.h"
0009 #include "header.h"
0010 
0011 #define MIDR "/regs/identification/midr_el1"
0012 #define MIDR_SIZE 19
0013 #define MIDR_REVISION_MASK      0xf
0014 #define MIDR_VARIANT_SHIFT      20
0015 #define MIDR_VARIANT_MASK       (0xf << MIDR_VARIANT_SHIFT)
0016 
0017 static int _get_cpuid(char *buf, size_t sz, struct perf_cpu_map *cpus)
0018 {
0019     const char *sysfs = sysfs__mountpoint();
0020     u64 midr = 0;
0021     int cpu;
0022 
0023     if (!sysfs || sz < MIDR_SIZE)
0024         return EINVAL;
0025 
0026     cpus = perf_cpu_map__get(cpus);
0027 
0028     for (cpu = 0; cpu < perf_cpu_map__nr(cpus); cpu++) {
0029         char path[PATH_MAX];
0030         FILE *file;
0031 
0032         scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d"MIDR,
0033                 sysfs, cpus->map[cpu]);
0034 
0035         file = fopen(path, "r");
0036         if (!file) {
0037             pr_debug("fopen failed for file %s\n", path);
0038             continue;
0039         }
0040 
0041         if (!fgets(buf, MIDR_SIZE, file)) {
0042             fclose(file);
0043             continue;
0044         }
0045         fclose(file);
0046 
0047         /* Ignore/clear Variant[23:20] and
0048          * Revision[3:0] of MIDR
0049          */
0050         midr = strtoul(buf, NULL, 16);
0051         midr &= (~(MIDR_VARIANT_MASK | MIDR_REVISION_MASK));
0052         scnprintf(buf, MIDR_SIZE, "0x%016lx", midr);
0053         /* got midr break loop */
0054         break;
0055     }
0056 
0057     perf_cpu_map__put(cpus);
0058 
0059     if (!midr)
0060         return EINVAL;
0061 
0062     return 0;
0063 }
0064 
0065 int get_cpuid(char *buf, size_t sz)
0066 {
0067     struct perf_cpu_map *cpus = perf_cpu_map__new(NULL);
0068     int ret;
0069 
0070     if (!cpus)
0071         return EINVAL;
0072 
0073     ret = _get_cpuid(buf, sz, cpus);
0074 
0075     perf_cpu_map__put(cpus);
0076 
0077     return ret;
0078 }
0079 
0080 char *get_cpuid_str(struct perf_pmu *pmu)
0081 {
0082     char *buf = NULL;
0083     int res;
0084 
0085     if (!pmu || !pmu->cpus)
0086         return NULL;
0087 
0088     buf = malloc(MIDR_SIZE);
0089     if (!buf)
0090         return NULL;
0091 
0092     /* read midr from list of cpus mapped to this pmu */
0093     res = _get_cpuid(buf, MIDR_SIZE, pmu->cpus);
0094     if (res) {
0095         pr_err("failed to get cpuid string for PMU %s\n", pmu->name);
0096         free(buf);
0097         buf = NULL;
0098     }
0099 
0100     return buf;
0101 }