[PATCH v3 5/8] perf hisi-ptt: Add parsing of supported message types
flat view
COLD33d
REVIEWED: 2 (2M)
From: Sizhe Liu <liusizhe5@huawei.com>
Date: 2026-09-03 07:53:17
Also in:
linux-doc, linux-pci, linux-perf-users, lkml
Subsystem:
hisilicon ptt driver, performance events subsystem, the rest · Maintainers:
Sizhe Liu, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Linus Torvalds
1 review trailer.
Classify TLP messages by Header DW0 Format field and Type field for both 4DW and 8DW formats, according to PCIe r6.4 sec 2.2.1.1 & 2.2.1.2. Parsing packets into: - MWr (Posted Memory Write request) - Msg (Posted Message request) - Atom (Non-Posted Atomic request) - IO (Non-Posted IO request) - CFG (Non-Posted Configuration request) - CPL (Completion request) The parsed message type is stored in pkt_buf->pkt_msg_type and will be used by subsequent patches to select the correct field layout for DW2 and DW3 printing. Reviewed-by: Yushan Wang <wangyushan12@huawei.com> Signed-off-by: Sizhe Liu <liusizhe5@huawei.com> --- .../hisi-ptt-decoder/hisi-ptt-pkt-decoder.c | 62 +++++++++++++++++++ .../hisi-ptt-decoder/hisi-ptt-pkt-decoder.h | 17 +++++ tools/perf/util/hisi-ptt.c | 1 + 3 files changed, 80 insertions(+)
diff --git a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
index 00bd9309df68..e63fe1534693 100644
--- a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
+++ b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c@@ -79,6 +79,66 @@ static const char * const hisi_ptt_4dw_pkt_field_name[] = { [HISI_PTT_4DW_HEAD3] = "Header DW3", }; +/* TLP message parsers below according to PCIe r6.4 sec 2.2.1.1 & 2.2.1.2 */ +static bool hisi_ptt_is_mwr_tlp(uint32_t format, uint32_t type) +{ + return (format == 0x2 || format == 0x3) && (type == 0); +} + +static bool hisi_ptt_is_msg_tlp(uint32_t format, uint32_t type) +{ + return (format == 0x1 || format == 0x3) && ((type & 0x18) == 0x10); +} + +static bool hisi_ptt_is_io_tlp(uint32_t format, uint32_t type) +{ + return (format == 0 || format == 0x2) && (type == 0x2); +} + +static bool hisi_ptt_is_atomic_tlp(uint32_t format, uint32_t type) +{ + return (format == 0x2 || format == 0x3) && + (type == 0xc || type == 0xd || type == 0xe); +} + +static bool hisi_ptt_is_cfg_tlp(uint32_t format, uint32_t type) +{ + return (format == 0 || format == 0x2) && (type == 0x4 || type == 0x5); +} + +static bool hisi_ptt_is_cpl_tlp(uint32_t format, uint32_t type) +{ + return (format == 0 || format == 0x2) && (type == 0xa || type == 0xb); +} + +static int hisi_ptt_parse_pkt_msg_type(uint32_t dw, + enum hisi_ptt_pkt_type pkt_type) +{ + uint32_t format, type; + + format = (pkt_type == HISI_PTT_4DW_PKT) ? + FIELD_GET(HISI_PTT_HEAD0_4DW_FORMAT, dw) : + FIELD_GET(HISI_PTT_HEAD0_8DW_FORMAT, dw); + type = (pkt_type == HISI_PTT_4DW_PKT) ? + FIELD_GET(HISI_PTT_HEAD0_4DW_TYPE, dw) : + FIELD_GET(HISI_PTT_HEAD0_8DW_TYPE, dw); + + if (hisi_ptt_is_mwr_tlp(format, type)) + return HISI_PTT_PKT_TYPE_MWR; + else if (hisi_ptt_is_msg_tlp(format, type)) + return HISI_PTT_PKT_TYPE_MSG; + else if (hisi_ptt_is_atomic_tlp(format, type)) + return HISI_PTT_PKT_TYPE_ATOM; + else if (hisi_ptt_is_io_tlp(format, type)) + return HISI_PTT_PKT_TYPE_IO; + else if (hisi_ptt_is_cfg_tlp(format, type)) + return HISI_PTT_PKT_TYPE_CFG; + else if (hisi_ptt_is_cpl_tlp(format, type)) + return HISI_PTT_PKT_TYPE_CPL; + + return HISI_PTT_PKT_TYPE_UNKNOWN; +} + static void hisi_ptt_print_raw_record(size_t offset, uint32_t value) { const char *color = PERF_COLOR_BLUE;
@@ -114,6 +174,8 @@ static void hisi_ptt_print_head0(struct hisi_ptt_pkt_buf *pkt_buf) uint32_t dw; dw = get_unaligned_le32(pkt_buf->buf + pkt_buf->pos); + pkt_buf->pkt_msg_type = hisi_ptt_parse_pkt_msg_type(dw, + pkt_buf->pkt_type); hisi_ptt_print_raw_record(pkt_buf->pos, dw); if (pkt_buf->pkt_type == HISI_PTT_4DW_PKT)
diff --git a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h
index 6747878b030e..436712e67a6f 100644
--- a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h
+++ b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h@@ -7,6 +7,7 @@ #ifndef INCLUDE__HISI_PTT_PKT_DECODER_H__ #define INCLUDE__HISI_PTT_PKT_DECODER_H__ +#include <stdbool.h> #include <stddef.h> #include <stdint.h> #include <linux/bits.h>
@@ -27,6 +28,10 @@ #define HISI_PTT_HEAD0_4DW_TYPE GENMASK_U32(29, 25) #define HISI_PTT_HEAD0_4DW_FORMAT GENMASK_U32(31, 30) +/* Header DW0 fields for 8DW format */ +#define HISI_PTT_HEAD0_8DW_TYPE GENMASK_U32(28, 24) +#define HISI_PTT_HEAD0_8DW_FORMAT GENMASK_U32(31, 29) + enum hisi_ptt_pkt_type { HISI_PTT_4DW_PKT, HISI_PTT_8DW_PKT,
@@ -38,11 +43,23 @@ static int hisi_ptt_pkt_size[] = { [HISI_PTT_8DW_PKT] = 32, }; +enum hisi_ptt_pkt_msg_type { + HISI_PTT_PKT_TYPE_UNKNOWN, /* Types do not support analysis */ + HISI_PTT_PKT_TYPE_MWR, /* P-(MemWr) */ + HISI_PTT_PKT_TYPE_MSG, /* P-(Message) */ + HISI_PTT_PKT_TYPE_ATOM, /* NP-(Atomic) */ + HISI_PTT_PKT_TYPE_IO, /* NP-(IO) */ + HISI_PTT_PKT_TYPE_CFG, /* NP-(CFG) */ + HISI_PTT_PKT_TYPE_CPL, /* CPL-(CPL) */ + HISI_PTT_PKT_TYPE_MAX +}; + struct hisi_ptt_pkt_buf { const unsigned char *buf; size_t pos; size_t len; enum hisi_ptt_pkt_type pkt_type; + enum hisi_ptt_pkt_msg_type pkt_msg_type; }; int hisi_ptt_pkt_desc(struct hisi_ptt_pkt_buf *pkt_buf);
diff --git a/tools/perf/util/hisi-ptt.c b/tools/perf/util/hisi-ptt.c
index ea659947c27f..78817ae7a8ea 100644
--- a/tools/perf/util/hisi-ptt.c
+++ b/tools/perf/util/hisi-ptt.c@@ -63,6 +63,7 @@ static void hisi_ptt_dump(struct hisi_ptt *ptt __maybe_unused, pkt_buf.pos = 0; pkt_buf.pkt_type = hisi_ptt_check_packet_type(buf, len); pkt_buf.len = round_down(len, hisi_ptt_pkt_size[pkt_buf.pkt_type]); + pkt_buf.pkt_msg_type = HISI_PTT_PKT_TYPE_UNKNOWN; color_fprintf(stdout, color, ". ... HISI PTT data: size %zu bytes\n", pkt_buf.len);
--
2.33.0