tools/perf/arch/arm64/util/header.c

Source file repositories/reference/linux-study-clean/tools/perf/arch/arm64/util/header.c

File Facts

System
Linux kernel
Corpus path
tools/perf/arch/arm64/util/header.c
Extension
.c
Size
2970 bytes
Lines
126
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/bits.h>
#include <linux/bitfield.h>
#include <stdio.h>
#include <stdlib.h>
#include <perf/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      GENMASK(3, 0)
#define MIDR_VARIANT_MASK	GENMASK(23, 20)

static int _get_cpuid(char *buf, size_t sz, struct perf_cpu cpu)
{
	char path[PATH_MAX];
	FILE *file;
	const char *sysfs = sysfs__mountpoint();

	assert(cpu.cpu != -1);
	if (!sysfs || sz < MIDR_SIZE)
		return EINVAL;

	scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d" MIDR, sysfs, cpu.cpu);

	file = fopen(path, "r");
	if (!file) {
		pr_debug("fopen failed for file %s\n", path);
		return EINVAL;
	}

	if (!fgets(buf, MIDR_SIZE, file)) {
		pr_debug("Failed to read file %s\n", path);
		fclose(file);
		return EINVAL;
	}
	fclose(file);
	return 0;
}

int get_cpuid(char *buf, size_t sz, struct perf_cpu cpu)
{
	struct perf_cpu_map *cpus;
	unsigned int idx;

	if (cpu.cpu != -1)
		return _get_cpuid(buf, sz, cpu);

	cpus = perf_cpu_map__new_online_cpus();
	if (!cpus)
		return EINVAL;

	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
		int ret = _get_cpuid(buf, sz, cpu);

		if (ret == 0)
			return 0;
	}
	return EINVAL;
}

char *get_cpuid_str(struct perf_cpu cpu)
{
	char *buf = malloc(MIDR_SIZE);
	int res;

	if (!buf)
		return NULL;

	/* read midr from list of cpus mapped to this pmu */
	res = get_cpuid(buf, MIDR_SIZE, cpu);
	if (res) {
		pr_err("failed to get cpuid string for CPU %d\n", cpu.cpu);
		free(buf);
		buf = NULL;
	}

	return buf;
}

/*
 * Return 0 if idstr is a higher or equal to version of the same part as
 * mapcpuid. Therefore, if mapcpuid has 0 for revision and variant then any
 * version of idstr will match as long as it's the same CPU type.
 *
 * Return 1 if the CPU type is different or the version of idstr is lower.
 */
int strcmp_cpuid_str(const char *mapcpuid, const char *idstr)

Annotation

Implementation Notes