diff options
Diffstat (limited to 'tools/perf/arch/powerpc/util/header.c')
-rw-r--r-- | tools/perf/arch/powerpc/util/header.c | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index d4870074f14c..0be74f048f96 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -7,19 +7,24 @@ #include <string.h> #include <linux/stringify.h> #include "header.h" +#include "utils_header.h" #include "metricgroup.h" #include <api/fs/fs.h> +#include <sys/auxv.h> -#define mfspr(rn) ({unsigned long rval; \ - asm volatile("mfspr %0," __stringify(rn) \ - : "=r" (rval)); rval; }) +static bool is_compat_mode(void) +{ + unsigned long base_platform = getauxval(AT_BASE_PLATFORM); + unsigned long platform = getauxval(AT_PLATFORM); + + if (!strcmp((char *)platform, (char *)base_platform)) + return false; -#define SPRN_PVR 0x11F /* Processor Version Register */ -#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */ -#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */ + return true; +} int -get_cpuid(char *buffer, size_t sz) +get_cpuid(char *buffer, size_t sz, struct perf_cpu cpu __maybe_unused) { unsigned long pvr; int nb; @@ -37,18 +42,39 @@ get_cpuid(char *buffer, size_t sz) } char * -get_cpuid_str(struct perf_pmu *pmu __maybe_unused) +get_cpuid_str(struct perf_cpu cpu __maybe_unused) { char *bufp; + unsigned long pvr; + + /* + * IBM Power System supports compatible mode. That is + * Nth generation platform can support previous generation + * OS in a mode called compatibile mode. For ex. LPAR can be + * booted in a Power9 mode when the system is a Power10. + * + * In the compatible mode, care must be taken when generating + * PVR value. When read, PVR will be of the AT_BASE_PLATFORM + * To support generic events, return 0x00ffffff as pvr when + * booted in compat mode. Based on this pvr value, json will + * pick events from pmu-events/arch/powerpc/compat + */ + if (!is_compat_mode()) + pvr = mfspr(SPRN_PVR); + else + pvr = 0x00ffffff; - if (asprintf(&bufp, "%.8lx", mfspr(SPRN_PVR)) < 0) + if (asprintf(&bufp, "0x%.8lx", pvr) < 0) bufp = NULL; return bufp; } -int arch_get_runtimeparam(void) +int arch_get_runtimeparam(const struct pmu_metric *pm) { int count; - return sysfs__read_int("/devices/hv_24x7/interface/sockets", &count) < 0 ? 1 : count; + char path[PATH_MAX] = "/devices/hv_24x7/interface/"; + + strcat(path, pm->aggr_mode == PerChip ? "sockets" : "coresperchip"); + return sysfs__read_int(path, &count) < 0 ? 1 : count; } |