102 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#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;
 | 
						|
}
 |