[PATCH v2 07/14] perf arm-spe: Refactor address packet handling

From: Leo Yan
Date: Tue Sep 29 2020 - 09:41:05 EST


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 <leo.yan@xxxxxxxxxx>
---
.../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