This patch is to refactor address packet handling, it defines macros for address packet's header and payload, these macros are used by decoder and the dump flow.
Signed-off-by: Leo Yan <[email protected]> --- .../util/arm-spe-decoder/arm-spe-decoder.c | 33 ++++++++++--------- .../arm-spe-decoder/arm-spe-pkt-decoder.c | 25 +++++++------- .../arm-spe-decoder/arm-spe-pkt-decoder.h | 27 ++++++++++----- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c index cc18a1e8c212..9d3de163d47c 100644 --- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c +++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c @@ -24,36 +24,37 @@ static u64 arm_spe_calc_ip(int index, u64 payload) { - u8 *addr = (u8 *)&payload; - int ns, el; + u64 ns, el; /* Instruction virtual address or Branch target address */ if (index == SPE_ADDR_PKT_HDR_INDEX_INS || index == SPE_ADDR_PKT_HDR_INDEX_BRANCH) { - ns = addr[7] & SPE_ADDR_PKT_NS; - el = (addr[7] & SPE_ADDR_PKT_EL_MASK) >> SPE_ADDR_PKT_EL_OFFSET; + ns = payload & SPE_ADDR_PKT_INST_VA_NS; + el = (payload & SPE_ADDR_PKT_INST_VA_EL_MASK) + >> SPE_ADDR_PKT_INST_VA_EL_SHIFT; + + /* Clean highest byte */ + payload &= SPE_ADDR_PKT_ADDR_MASK; /* Fill highest byte for EL1 or EL2 (VHE) mode */ - if (ns && (el == SPE_ADDR_PKT_EL1 || el == SPE_ADDR_PKT_EL2)) - addr[7] = 0xff; - /* Clean highest byte for other cases */ - else - addr[7] = 0x0; + if (ns && (el == SPE_ADDR_PKT_INST_VA_EL1 || + el == SPE_ADDR_PKT_INST_VA_EL2)) + payload |= 0xffULL << SPE_ADDR_PKT_ADDR_BYTE7_SHIFT; /* Data access virtual address */ } else if (index == SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT) { + /* Clean tags */ + payload &= SPE_ADDR_PKT_ADDR_MASK; + /* Fill highest byte if bits [48..55] is 0xff */ - if (addr[6] == 0xff) - addr[7] = 0xff; - /* Otherwise, cleanup tags */ - else - addr[7] = 0x0; + if ((payload >> 48) == 0xffULL) + payload |= 0xffULL << SPE_ADDR_PKT_ADDR_BYTE7_SHIFT; /* Data access physical address */ } else if (index == SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS) { - /* Cleanup byte 7 */ - addr[7] = 0x0; + /* Clean highest byte */ + payload &= SPE_ADDR_PKT_ADDR_MASK; } else { pr_err("unsupported address packet index: 0x%x\n", index); } diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c index e738bd04f209..b51a2207e4a0 100644 --- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c @@ -13,9 +13,6 @@ #include "arm-spe-pkt-decoder.h" -#define NS_FLAG BIT(63) -#define EL_FLAG (BIT(62) | BIT(61)) - #if __BYTE_ORDER == __BIG_ENDIAN #define le16_to_cpu bswap_16 #define le32_to_cpu bswap_32 @@ -166,9 +163,10 @@ static int arm_spe_get_addr(const unsigned char *buf, size_t len, { packet->type = ARM_SPE_ADDRESS; if (ext_hdr) - packet->index = ((buf[0] & 0x3) << 3) | (buf[1] & 0x7); + packet->index = (((buf[0] & SPE_ADDR_PKT_HDR_EXT_INDEX_MASK) << 3) | + (buf[1] & SPE_ADDR_PKT_HDR_INDEX_MASK)); else - packet->index = buf[0] & 0x7; + packet->index = buf[0] & SPE_ADDR_PKT_HDR_INDEX_MASK; return arm_spe_get_payload(buf, len, ext_hdr, packet); } @@ -403,18 +401,21 @@ int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf, return arm_spe_pkt_snprintf(&buf, &blen, "%s %lld", name, payload); case ARM_SPE_ADDRESS: switch (idx) { - case 0: - case 1: ns = !!(packet->payload & NS_FLAG); - el = (packet->payload & EL_FLAG) >> 61; - payload &= ~(0xffULL << 56); + case SPE_ADDR_PKT_HDR_INDEX_INS: + case SPE_ADDR_PKT_HDR_INDEX_BRANCH: + ns = !!(packet->payload & SPE_ADDR_PKT_INST_VA_NS); + el = (packet->payload & SPE_ADDR_PKT_INST_VA_EL_MASK) + >> SPE_ADDR_PKT_INST_VA_EL_SHIFT; + payload &= SPE_ADDR_PKT_ADDR_MASK; return arm_spe_pkt_snprintf(&buf, &blen, "%s 0x%llx el%d ns=%d", (idx == 1) ? "TGT" : "PC", payload, el, ns); - case 2: + case SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT: return arm_spe_pkt_snprintf(&buf, &blen, "VA 0x%llx", payload); - case 3: ns = !!(packet->payload & NS_FLAG); - payload &= ~(0xffULL << 56); + case SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS: + ns = !!(packet->payload & SPE_ADDR_PKT_INST_VA_NS); + payload &= SPE_ADDR_PKT_ADDR_MASK; return arm_spe_pkt_snprintf(&buf, &blen, "PA 0x%llx ns=%d", payload, ns); default: diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h index a30fe3c5ab67..88d2231c76da 100644 --- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h +++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h @@ -61,19 +61,30 @@ struct arm_spe_pkt { #define SPE_HEADER_SZ_SHIFT (4) #define SPE_HEADER_SZ_MASK GENMASK_ULL(5, 4) +/* Address packet header */ +#define SPE_ADDR_PKT_HDR_INDEX_MASK GENMASK_ULL(2, 0) #define SPE_ADDR_PKT_HDR_INDEX_INS (0x0) #define SPE_ADDR_PKT_HDR_INDEX_BRANCH (0x1) #define SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT (0x2) #define SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS (0x3) -#define SPE_ADDR_PKT_NS BIT(7) -#define SPE_ADDR_PKT_CH BIT(6) -#define SPE_ADDR_PKT_EL_OFFSET (5) -#define SPE_ADDR_PKT_EL_MASK (0x3 << SPE_ADDR_PKT_EL_OFFSET) -#define SPE_ADDR_PKT_EL0 (0) -#define SPE_ADDR_PKT_EL1 (1) -#define SPE_ADDR_PKT_EL2 (2) -#define SPE_ADDR_PKT_EL3 (3) +#define SPE_ADDR_PKT_HDR_EXT_INDEX_MASK GENMASK_ULL(1, 0) + +/* Address packet payload for data access physical address */ +#define SPE_ADDR_PKT_ADDR_BYTE7_SHIFT (56) +#define SPE_ADDR_PKT_ADDR_MASK GENMASK_ULL(55, 0) + +#define SPE_ADDR_PKT_DATA_PA_NS BIT(63) +#define SPE_ADDR_PKT_DATA_PA_CH BIT(62) + +/* Address packet payload for instrcution virtual address */ +#define SPE_ADDR_PKT_INST_VA_NS BIT(63) +#define SPE_ADDR_PKT_INST_VA_EL_SHIFT (61) +#define SPE_ADDR_PKT_INST_VA_EL_MASK GENMASK_ULL(62, 61) +#define SPE_ADDR_PKT_INST_VA_EL0 (0) +#define SPE_ADDR_PKT_INST_VA_EL1 (1) +#define SPE_ADDR_PKT_INST_VA_EL2 (2) +#define SPE_ADDR_PKT_INST_VA_EL3 (3) const char *arm_spe_pkt_name(enum arm_spe_pkt_type); -- 2.20.1

