1 // SPDX-License-Identifier: GPL-2.0
3 * HiSilicon PCIe Trace and Tuning (PTT) support
4 * Copyright (c) 2022 HiSilicon Technologies Co., Ltd.
12 #include <linux/bitops.h>
16 #include "hisi-ptt-pkt-decoder.h"
19 * For 8DW format, the bit[31:11] of DW0 is always 0x1fffff, which can be
20 * used to distinguish the data format.
22 * bits [ 31:11 ][ 10:0 ]
23 * |---------------------------------------|-------------------|
24 * DW0 [ 0x1fffff ][ Reserved (0x7ff) ]
30 * DW6 [ Reserved (0x0) ]
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 ]
42 enum hisi_ptt_8dw_pkt_field_type
{
43 HISI_PTT_8DW_CHK_AND_RSV0
,
54 enum hisi_ptt_4dw_pkt_field_type
{
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"
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",
90 static void hisi_ptt_print_pkt(const unsigned char *buf
, int pos
, const char *desc
)
92 const char *color
= PERF_COLOR_BLUE
;
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
);
104 static int hisi_ptt_8dw_kpt_desc(const unsigned char *buf
, int pos
)
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
;
115 hisi_ptt_print_pkt(buf
, pos
, hisi_ptt_8dw_pkt_field_name
[i
]);
116 pos
+= HISI_PTT_FIELD_LENTH
;
119 return hisi_ptt_pkt_size
[HISI_PTT_8DW_PKT
];
122 static void hisi_ptt_4dw_print_dw0(const unsigned char *buf
, int pos
)
124 const char *color
= PERF_COLOR_BLUE
;
125 union hisi_ptt_4dw dw0
;
128 dw0
.value
= *(uint32_t *)(buf
+ pos
);
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
, " ");
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
);
143 static int hisi_ptt_4dw_kpt_desc(const unsigned char *buf
, int pos
)
147 hisi_ptt_4dw_print_dw0(buf
, pos
);
148 pos
+= HISI_PTT_FIELD_LENTH
;
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
;
155 return hisi_ptt_pkt_size
[HISI_PTT_4DW_PKT
];
158 int hisi_ptt_pkt_desc(const unsigned char *buf
, int pos
, enum hisi_ptt_pkt_type type
)
160 if (type
== HISI_PTT_8DW_PKT
)
161 return hisi_ptt_8dw_kpt_desc(buf
, pos
);
163 return hisi_ptt_4dw_kpt_desc(buf
, pos
);