perf arm_spe: Decode Arm N1 IMPDEF events

>From the TRM [1], N1 has one IMPDEF event which isn't covered by the
common list. Add a framework so that more cores can be added in the
future and that the N1 IMPDEF event can be decoded. Also increase the
size of the buffer because we're adding more strings and if it gets
truncated it falls back to a hex dump only.

[1]: https://developer.arm.com/documentation/100616/0401/Statistical-Profiling-Extension/implementation-defined-features-of-SPE

Suggested-by: Al Grant <al.grant@arm.com>
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Leo Yan <leo.yan@linux.dev>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mike Leach <mike.leach@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Link: https://developer.arm.com/documentation/100616/0401/Statistical-Profiling-Extension/implementation-defined-features-of-SPE
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
James Clark 2026-04-14 13:48:03 +01:00 committed by Arnaldo Carvalho de Melo
parent 96b4910c3c
commit b566a74041
3 changed files with 41 additions and 2 deletions

View File

@ -1 +1,3 @@
perf-util-y += arm-spe-pkt-decoder.o arm-spe-decoder.o
CFLAGS_arm-spe-pkt-decoder.o += -I$(srctree)/tools/arch/arm64/include/ -I$(OUTPUT)arch/arm64/include/generated/

View File

@ -15,6 +15,8 @@
#include "arm-spe-pkt-decoder.h"
#include "../../arm64/include/asm/cputype.h"
static const char * const arm_spe_packet_name[] = {
[ARM_SPE_PAD] = "PAD",
[ARM_SPE_END] = "END",
@ -308,6 +310,11 @@ static const struct ev_string common_ev_strings[] = {
{ .event = 0, .desc = NULL },
};
static const struct ev_string n1_event_strings[] = {
{ .event = 12, .desc = "LATE-PREFETCH" },
{ .event = 0, .desc = NULL },
};
static u64 print_event_list(int *err, char **buf, size_t *buf_len,
const struct ev_string *ev_strings, u64 payload)
{
@ -319,6 +326,26 @@ static u64 print_event_list(int *err, char **buf, size_t *buf_len,
return payload;
}
struct event_print_handle {
const struct midr_range *midr_ranges;
const struct ev_string *ev_strings;
};
#define EV_PRINT(range, strings) \
{ \
.midr_ranges = range, \
.ev_strings = strings, \
}
static const struct midr_range n1_event_encoding_cpus[] = {
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
{},
};
static const struct event_print_handle event_print_handles[] = {
EV_PRINT(n1_event_encoding_cpus, n1_event_strings),
};
static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
char *buf, size_t buf_len)
{
@ -326,7 +353,17 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
int err = 0;
arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");
print_event_list(&err, &buf, &buf_len, common_ev_strings, payload);
payload = print_event_list(&err, &buf, &buf_len, common_ev_strings,
payload);
/* Try to decode IMPDEF bits for known CPUs */
for (unsigned int i = 0; i < ARRAY_SIZE(event_print_handles); i++) {
if (is_midr_in_range_list(packet->midr,
event_print_handles[i].midr_ranges))
payload = print_event_list(&err, &buf, &buf_len,
event_print_handles[i].ev_strings,
payload);
}
return err;
}

View File

@ -11,7 +11,7 @@
#include <stddef.h>
#include <stdint.h>
#define ARM_SPE_PKT_DESC_MAX 256
#define ARM_SPE_PKT_DESC_MAX 512
#define ARM_SPE_NEED_MORE_BYTES -1
#define ARM_SPE_BAD_PACKET -2