[PATCH RESEND v1 06/13] perf arm-spe: Refactor address packet handling

From: Leo Yan
Date: Mon Aug 17 2020 - 10:54:51 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 | 31 +++++++++--------
.../arm-spe-decoder/arm-spe-pkt-decoder.h | 28 +++++++++++-----
3 files changed, 54 insertions(+), 38 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..f7cda4a3cf1a 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_SHIFT;
+ el &= SPE_ADDR_PKT_INST_VA_EL_MASK;
+
+ /* Clean highest byte */
+ payload &= GENMASK(SPE_ADDR_PKT_ADDR_MSB, 0);

/* 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_MSB + 1);

/* Data access virtual address */
} else if (index == SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT) {

+ /* Clean tags */
+ payload &= GENMASK(SPE_ADDR_PKT_ADDR_MSB, 0);
+
/* 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 & GENMASK(SPE_ADDR_PKT_ADDR_MSB, 48)) == (0xffULL << 48))
+ payload |= 0xffULL << (SPE_ADDR_PKT_ADDR_MSB + 1);

/* Data access physical address */
} else if (index == SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS) {
- /* Cleanup byte 7 */
- addr[7] = 0x0;
+ /* Clean highest byte */
+ payload &= GENMASK(SPE_ADDR_PKT_ADDR_MSB, 0);
} 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 5f4f900a9980..bbc8b0178f67 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
@@ -12,9 +12,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
@@ -165,9 +162,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);
}
@@ -394,18 +392,23 @@ int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
return snprintf(buf, buf_len, "%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_SHIFT;
+ el &= SPE_ADDR_PKT_INST_VA_EL_MASK;
+ payload &= GENMASK(SPE_ADDR_PKT_ADDR_MSB, 0);
return snprintf(buf, buf_len, "%s 0x%llx el%d ns=%d",
- (idx == 1) ? "TGT" : "PC", payload, el, ns);
- case 2: return snprintf(buf, buf_len, "VA 0x%llx", payload);
- case 3: ns = !!(packet->payload & NS_FLAG);
- payload &= ~(0xffULL << 56);
+ (idx == 1) ? "TGT" : "PC", payload, el, ns);
+ case SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT:
+ return snprintf(buf, buf_len, "VA 0x%llx", payload);
+ case SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS:
+ ns = !!(packet->payload & SPE_ADDR_PKT_INST_VA_NS);
+ payload &= GENMASK(SPE_ADDR_PKT_ADDR_MSB, 0);
return snprintf(buf, buf_len, "PA 0x%llx ns=%d",
payload, ns);
- default: return 0;
+ default:
+ return 0;
}
case ARM_SPE_CONTEXT:
return snprintf(buf, buf_len, "%s 0x%lx el%d", name,
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 9df5ebe02c5d..d09082fc9853 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
@@ -56,19 +56,31 @@ struct arm_spe_pkt {
#define SPE_HEADER_SZ_SHIFT (4)
#define SPE_HEADER_SZ_MASK (0x30)

+/* Address packet header */
+#define SPE_ADDR_PKT_HDR_INDEX_MASK (0x7)
#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 (0x3)
+
+#define SPE_ADDR_PKT_ADDR_MSB (55)
+
+/* Address packet payload for data access physical address */
+#define SPE_ADDR_PKT_DATA_PA_NS BIT(63)
+#define SPE_ADDR_PKT_DATA_PA_CH BIT(62)
+#define SPE_ADDR_PKT_DATA_PA_PAT_SHIFT (56)
+#define SPE_ADDR_PKT_DATA_PA_PAT_MASK (0xf)
+
+/* 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 (0x3)
+#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.17.1