Skip to content

Commit 5e91e57

Browse files
77liuqiacmel
authored andcommitted
perf auxtrace arm64: Add support for parsing HiSilicon PCIe Trace packet
Add support for using 'perf report --dump-raw-trace' to parse PTT packet. Example usage: Output will contain raw PTT data and its textual representation, such as (8DW format): 0 0 0x5810 [0x30]: PERF_RECORD_AUXTRACE size: 0x400000 offset: 0 ref: 0xa5d50c725 idx: 0 tid: -1 cpu: 0 . . ... HISI PTT data: size 4194304 bytes . 00000000: 00 00 00 00 Prefix . 00000004: 08 20 00 60 Header DW0 . 00000008: ff 02 00 01 Header DW1 . 0000000c: 20 08 00 00 Header DW2 . 00000010: 10 e7 44 ab Header DW3 . 00000014: 2a a8 1e 01 Time . 00000020: 00 00 00 00 Prefix . 00000024: 01 00 00 60 Header DW0 . 00000028: 0f 1e 00 01 Header DW1 . 0000002c: 04 00 00 00 Header DW2 . 00000030: 40 00 81 02 Header DW3 . 00000034: ee 02 00 00 Time .... This patch only add basic parsing support according to the definition of the PTT packet described in Documentation/trace/hisi-ptt.rst. And the fields of each packet can be further decoded following the PCIe Spec's definition of TLP packet. Signed-off-by: Qi Liu <[email protected]> Signed-off-by: Yicong Yang <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Bjorn Helgaas <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: James Clark <[email protected]> Cc: John Garry <[email protected]> Cc: Jonathan Cameron <[email protected]> Cc: Leo Yan <[email protected]> Cc: Lorenzo Pieralisi <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Mathieu Poirier <[email protected]> Cc: Mike Leach <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Qi Liu <[email protected]> Cc: Shameerali Kolothum Thodi <[email protected]> Cc: Shaokun Zhang <[email protected]> Cc: Suzuki Poulouse <[email protected]> Cc: Will Deacon <[email protected]> Cc: Zeng Prime <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 057381a commit 5e91e57

File tree

7 files changed

+396
-0
lines changed

7 files changed

+396
-0
lines changed

tools/perf/util/Build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ perf-$(CONFIG_AUXTRACE) += intel-pt.o
118118
perf-$(CONFIG_AUXTRACE) += intel-bts.o
119119
perf-$(CONFIG_AUXTRACE) += arm-spe.o
120120
perf-$(CONFIG_AUXTRACE) += arm-spe-decoder/
121+
perf-$(CONFIG_AUXTRACE) += hisi-ptt.o
122+
perf-$(CONFIG_AUXTRACE) += hisi-ptt-decoder/
121123
perf-$(CONFIG_AUXTRACE) += s390-cpumsf.o
122124

123125
ifdef CONFIG_LIBOPENCSD

tools/perf/util/auxtrace.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include "intel-pt.h"
5353
#include "intel-bts.h"
5454
#include "arm-spe.h"
55+
#include "hisi-ptt.h"
5556
#include "s390-cpumsf.h"
5657
#include "util/mmap.h"
5758

@@ -1321,6 +1322,8 @@ int perf_event__process_auxtrace_info(struct perf_session *session,
13211322
err = s390_cpumsf_process_auxtrace_info(event, session);
13221323
break;
13231324
case PERF_AUXTRACE_HISI_PTT:
1325+
err = hisi_ptt_process_auxtrace_info(event, session);
1326+
break;
13241327
case PERF_AUXTRACE_UNKNOWN:
13251328
default:
13261329
return -EINVAL;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
perf-$(CONFIG_AUXTRACE) += hisi-ptt-pkt-decoder.o
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* HiSilicon PCIe Trace and Tuning (PTT) support
4+
* Copyright (c) 2022 HiSilicon Technologies Co., Ltd.
5+
*/
6+
7+
#include <stdlib.h>
8+
#include <stdio.h>
9+
#include <string.h>
10+
#include <endian.h>
11+
#include <byteswap.h>
12+
#include <linux/bitops.h>
13+
#include <stdarg.h>
14+
15+
#include "../color.h"
16+
#include "hisi-ptt-pkt-decoder.h"
17+
18+
/*
19+
* For 8DW format, the bit[31:11] of DW0 is always 0x1fffff, which can be
20+
* used to distinguish the data format.
21+
* 8DW format is like:
22+
* bits [ 31:11 ][ 10:0 ]
23+
* |---------------------------------------|-------------------|
24+
* DW0 [ 0x1fffff ][ Reserved (0x7ff) ]
25+
* DW1 [ Prefix ]
26+
* DW2 [ Header DW0 ]
27+
* DW3 [ Header DW1 ]
28+
* DW4 [ Header DW2 ]
29+
* DW5 [ Header DW3 ]
30+
* DW6 [ Reserved (0x0) ]
31+
* DW7 [ Time ]
32+
*
33+
* 4DW format is like:
34+
* bits [31:30] [ 29:25 ][24][23][22][21][ 20:11 ][ 10:0 ]
35+
* |-----|---------|---|---|---|---|-------------|-------------|
36+
* DW0 [ Fmt ][ Type ][T9][T8][TH][SO][ Length ][ Time ]
37+
* DW1 [ Header DW1 ]
38+
* DW2 [ Header DW2 ]
39+
* DW3 [ Header DW3 ]
40+
*/
41+
42+
enum hisi_ptt_8dw_pkt_field_type {
43+
HISI_PTT_8DW_CHK_AND_RSV0,
44+
HISI_PTT_8DW_PREFIX,
45+
HISI_PTT_8DW_HEAD0,
46+
HISI_PTT_8DW_HEAD1,
47+
HISI_PTT_8DW_HEAD2,
48+
HISI_PTT_8DW_HEAD3,
49+
HISI_PTT_8DW_RSV1,
50+
HISI_PTT_8DW_TIME,
51+
HISI_PTT_8DW_TYPE_MAX
52+
};
53+
54+
enum hisi_ptt_4dw_pkt_field_type {
55+
HISI_PTT_4DW_HEAD1,
56+
HISI_PTT_4DW_HEAD2,
57+
HISI_PTT_4DW_HEAD3,
58+
HISI_PTT_4DW_TYPE_MAX
59+
};
60+
61+
static const char * const hisi_ptt_8dw_pkt_field_name[] = {
62+
[HISI_PTT_8DW_PREFIX] = "Prefix",
63+
[HISI_PTT_8DW_HEAD0] = "Header DW0",
64+
[HISI_PTT_8DW_HEAD1] = "Header DW1",
65+
[HISI_PTT_8DW_HEAD2] = "Header DW2",
66+
[HISI_PTT_8DW_HEAD3] = "Header DW3",
67+
[HISI_PTT_8DW_TIME] = "Time"
68+
};
69+
70+
static const char * const hisi_ptt_4dw_pkt_field_name[] = {
71+
[HISI_PTT_4DW_HEAD1] = "Header DW1",
72+
[HISI_PTT_4DW_HEAD2] = "Header DW2",
73+
[HISI_PTT_4DW_HEAD3] = "Header DW3",
74+
};
75+
76+
union hisi_ptt_4dw {
77+
struct {
78+
uint32_t format : 2;
79+
uint32_t type : 5;
80+
uint32_t t9 : 1;
81+
uint32_t t8 : 1;
82+
uint32_t th : 1;
83+
uint32_t so : 1;
84+
uint32_t len : 10;
85+
uint32_t time : 11;
86+
};
87+
uint32_t value;
88+
};
89+
90+
static void hisi_ptt_print_pkt(const unsigned char *buf, int pos, const char *desc)
91+
{
92+
const char *color = PERF_COLOR_BLUE;
93+
int i;
94+
95+
printf(".");
96+
color_fprintf(stdout, color, " %08x: ", pos);
97+
for (i = 0; i < HISI_PTT_FIELD_LENTH; i++)
98+
color_fprintf(stdout, color, "%02x ", buf[pos + i]);
99+
for (i = 0; i < HISI_PTT_MAX_SPACE_LEN; i++)
100+
color_fprintf(stdout, color, " ");
101+
color_fprintf(stdout, color, " %s\n", desc);
102+
}
103+
104+
static int hisi_ptt_8dw_kpt_desc(const unsigned char *buf, int pos)
105+
{
106+
int i;
107+
108+
for (i = 0; i < HISI_PTT_8DW_TYPE_MAX; i++) {
109+
/* Do not show 8DW check field and reserved fields */
110+
if (i == HISI_PTT_8DW_CHK_AND_RSV0 || i == HISI_PTT_8DW_RSV1) {
111+
pos += HISI_PTT_FIELD_LENTH;
112+
continue;
113+
}
114+
115+
hisi_ptt_print_pkt(buf, pos, hisi_ptt_8dw_pkt_field_name[i]);
116+
pos += HISI_PTT_FIELD_LENTH;
117+
}
118+
119+
return hisi_ptt_pkt_size[HISI_PTT_8DW_PKT];
120+
}
121+
122+
static void hisi_ptt_4dw_print_dw0(const unsigned char *buf, int pos)
123+
{
124+
const char *color = PERF_COLOR_BLUE;
125+
union hisi_ptt_4dw dw0;
126+
int i;
127+
128+
dw0.value = *(uint32_t *)(buf + pos);
129+
printf(".");
130+
color_fprintf(stdout, color, " %08x: ", pos);
131+
for (i = 0; i < HISI_PTT_FIELD_LENTH; i++)
132+
color_fprintf(stdout, color, "%02x ", buf[pos + i]);
133+
for (i = 0; i < HISI_PTT_MAX_SPACE_LEN; i++)
134+
color_fprintf(stdout, color, " ");
135+
136+
color_fprintf(stdout, color,
137+
" %s %x %s %x %s %x %s %x %s %x %s %x %s %x %s %x\n",
138+
"Format", dw0.format, "Type", dw0.type, "T9", dw0.t9,
139+
"T8", dw0.t8, "TH", dw0.th, "SO", dw0.so, "Length",
140+
dw0.len, "Time", dw0.time);
141+
}
142+
143+
static int hisi_ptt_4dw_kpt_desc(const unsigned char *buf, int pos)
144+
{
145+
int i;
146+
147+
hisi_ptt_4dw_print_dw0(buf, pos);
148+
pos += HISI_PTT_FIELD_LENTH;
149+
150+
for (i = 0; i < HISI_PTT_4DW_TYPE_MAX; i++) {
151+
hisi_ptt_print_pkt(buf, pos, hisi_ptt_4dw_pkt_field_name[i]);
152+
pos += HISI_PTT_FIELD_LENTH;
153+
}
154+
155+
return hisi_ptt_pkt_size[HISI_PTT_4DW_PKT];
156+
}
157+
158+
int hisi_ptt_pkt_desc(const unsigned char *buf, int pos, enum hisi_ptt_pkt_type type)
159+
{
160+
if (type == HISI_PTT_8DW_PKT)
161+
return hisi_ptt_8dw_kpt_desc(buf, pos);
162+
163+
return hisi_ptt_4dw_kpt_desc(buf, pos);
164+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* HiSilicon PCIe Trace and Tuning (PTT) support
4+
* Copyright (c) 2022 HiSilicon Technologies Co., Ltd.
5+
*/
6+
7+
#ifndef INCLUDE__HISI_PTT_PKT_DECODER_H__
8+
#define INCLUDE__HISI_PTT_PKT_DECODER_H__
9+
10+
#include <stddef.h>
11+
#include <stdint.h>
12+
13+
#define HISI_PTT_8DW_CHECK_MASK GENMASK(31, 11)
14+
#define HISI_PTT_IS_8DW_PKT GENMASK(31, 11)
15+
#define HISI_PTT_MAX_SPACE_LEN 10
16+
#define HISI_PTT_FIELD_LENTH 4
17+
18+
enum hisi_ptt_pkt_type {
19+
HISI_PTT_4DW_PKT,
20+
HISI_PTT_8DW_PKT,
21+
HISI_PTT_PKT_MAX
22+
};
23+
24+
static int hisi_ptt_pkt_size[] = {
25+
[HISI_PTT_4DW_PKT] = 16,
26+
[HISI_PTT_8DW_PKT] = 32,
27+
};
28+
29+
int hisi_ptt_pkt_desc(const unsigned char *buf, int pos, enum hisi_ptt_pkt_type type);
30+
31+
#endif

0 commit comments

Comments
 (0)