xref: /openbmc/linux/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c (revision 90af7555c36fa02e686a6a0db8be626ca7bb438f)
12025cf9eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2a4e92590SAdrian Hunter /*
3a4e92590SAdrian Hunter  * intel_pt_pkt_decoder.c: Intel Processor Trace support
4a4e92590SAdrian Hunter  * Copyright (c) 2013-2014, Intel Corporation.
5a4e92590SAdrian Hunter  */
6a4e92590SAdrian Hunter 
7a4e92590SAdrian Hunter #include <stdio.h>
8a4e92590SAdrian Hunter #include <string.h>
9a4e92590SAdrian Hunter #include <endian.h>
10a4e92590SAdrian Hunter #include <byteswap.h>
117ea6856dSArnaldo Carvalho de Melo #include <linux/compiler.h>
12a4e92590SAdrian Hunter 
13a4e92590SAdrian Hunter #include "intel-pt-pkt-decoder.h"
14a4e92590SAdrian Hunter 
15a4e92590SAdrian Hunter #define BIT(n)		(1 << (n))
16a4e92590SAdrian Hunter 
17a4e92590SAdrian Hunter #define BIT63		((uint64_t)1 << 63)
18a4e92590SAdrian Hunter 
19a4e92590SAdrian Hunter #if __BYTE_ORDER == __BIG_ENDIAN
20a4e92590SAdrian Hunter #define le16_to_cpu bswap_16
21a4e92590SAdrian Hunter #define le32_to_cpu bswap_32
22a4e92590SAdrian Hunter #define le64_to_cpu bswap_64
23a4e92590SAdrian Hunter #define memcpy_le64(d, s, n) do { \
24a4e92590SAdrian Hunter 	memcpy((d), (s), (n));    \
25a4e92590SAdrian Hunter 	*(d) = le64_to_cpu(*(d)); \
26a4e92590SAdrian Hunter } while (0)
27a4e92590SAdrian Hunter #else
28a4e92590SAdrian Hunter #define le16_to_cpu
29a4e92590SAdrian Hunter #define le32_to_cpu
30a4e92590SAdrian Hunter #define le64_to_cpu
31a4e92590SAdrian Hunter #define memcpy_le64 memcpy
32a4e92590SAdrian Hunter #endif
33a4e92590SAdrian Hunter 
34a4e92590SAdrian Hunter static const char * const packet_name[] = {
35a4e92590SAdrian Hunter 	[INTEL_PT_BAD]		= "Bad Packet!",
36a4e92590SAdrian Hunter 	[INTEL_PT_PAD]		= "PAD",
37a4e92590SAdrian Hunter 	[INTEL_PT_TNT]		= "TNT",
38a4e92590SAdrian Hunter 	[INTEL_PT_TIP_PGD]	= "TIP.PGD",
39a4e92590SAdrian Hunter 	[INTEL_PT_TIP_PGE]	= "TIP.PGE",
40a4e92590SAdrian Hunter 	[INTEL_PT_TSC]		= "TSC",
413d498078SAdrian Hunter 	[INTEL_PT_TMA]		= "TMA",
42a4e92590SAdrian Hunter 	[INTEL_PT_MODE_EXEC]	= "MODE.Exec",
43a4e92590SAdrian Hunter 	[INTEL_PT_MODE_TSX]	= "MODE.TSX",
443d498078SAdrian Hunter 	[INTEL_PT_MTC]		= "MTC",
45a4e92590SAdrian Hunter 	[INTEL_PT_TIP]		= "TIP",
46a4e92590SAdrian Hunter 	[INTEL_PT_FUP]		= "FUP",
473d498078SAdrian Hunter 	[INTEL_PT_CYC]		= "CYC",
483d498078SAdrian Hunter 	[INTEL_PT_VMCS]		= "VMCS",
49a4e92590SAdrian Hunter 	[INTEL_PT_PSB]		= "PSB",
50a4e92590SAdrian Hunter 	[INTEL_PT_PSBEND]	= "PSBEND",
51a4e92590SAdrian Hunter 	[INTEL_PT_CBR]		= "CBR",
523d498078SAdrian Hunter 	[INTEL_PT_TRACESTOP]	= "TraceSTOP",
53a4e92590SAdrian Hunter 	[INTEL_PT_PIP]		= "PIP",
54a4e92590SAdrian Hunter 	[INTEL_PT_OVF]		= "OVF",
553d498078SAdrian Hunter 	[INTEL_PT_MNT]		= "MNT",
56a472e65fSAdrian Hunter 	[INTEL_PT_PTWRITE]	= "PTWRITE",
57a472e65fSAdrian Hunter 	[INTEL_PT_PTWRITE_IP]	= "PTWRITE",
58a472e65fSAdrian Hunter 	[INTEL_PT_EXSTOP]	= "EXSTOP",
59a472e65fSAdrian Hunter 	[INTEL_PT_EXSTOP_IP]	= "EXSTOP",
60a472e65fSAdrian Hunter 	[INTEL_PT_MWAIT]	= "MWAIT",
61a472e65fSAdrian Hunter 	[INTEL_PT_PWRE]		= "PWRE",
62a472e65fSAdrian Hunter 	[INTEL_PT_PWRX]		= "PWRX",
63edff7809SAdrian Hunter 	[INTEL_PT_BBP]		= "BBP",
64edff7809SAdrian Hunter 	[INTEL_PT_BIP]		= "BIP",
65edff7809SAdrian Hunter 	[INTEL_PT_BEP]		= "BEP",
66edff7809SAdrian Hunter 	[INTEL_PT_BEP_IP]	= "BEP",
67a4e92590SAdrian Hunter };
68a4e92590SAdrian Hunter 
69a4e92590SAdrian Hunter const char *intel_pt_pkt_name(enum intel_pt_pkt_type type)
70a4e92590SAdrian Hunter {
71a4e92590SAdrian Hunter 	return packet_name[type];
72a4e92590SAdrian Hunter }
73a4e92590SAdrian Hunter 
74a4e92590SAdrian Hunter static int intel_pt_get_long_tnt(const unsigned char *buf, size_t len,
75a4e92590SAdrian Hunter 				 struct intel_pt_pkt *packet)
76a4e92590SAdrian Hunter {
77a4e92590SAdrian Hunter 	uint64_t payload;
78a4e92590SAdrian Hunter 	int count;
79a4e92590SAdrian Hunter 
80a4e92590SAdrian Hunter 	if (len < 8)
81a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
82a4e92590SAdrian Hunter 
83a4e92590SAdrian Hunter 	payload = le64_to_cpu(*(uint64_t *)buf);
84a4e92590SAdrian Hunter 
85a4e92590SAdrian Hunter 	for (count = 47; count; count--) {
86a4e92590SAdrian Hunter 		if (payload & BIT63)
87a4e92590SAdrian Hunter 			break;
88a4e92590SAdrian Hunter 		payload <<= 1;
89a4e92590SAdrian Hunter 	}
90a4e92590SAdrian Hunter 
91a4e92590SAdrian Hunter 	packet->type = INTEL_PT_TNT;
92a4e92590SAdrian Hunter 	packet->count = count;
93a4e92590SAdrian Hunter 	packet->payload = payload << 1;
94a4e92590SAdrian Hunter 	return 8;
95a4e92590SAdrian Hunter }
96a4e92590SAdrian Hunter 
97a4e92590SAdrian Hunter static int intel_pt_get_pip(const unsigned char *buf, size_t len,
98a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
99a4e92590SAdrian Hunter {
100a4e92590SAdrian Hunter 	uint64_t payload = 0;
101a4e92590SAdrian Hunter 
102a4e92590SAdrian Hunter 	if (len < 8)
103a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
104a4e92590SAdrian Hunter 
105a4e92590SAdrian Hunter 	packet->type = INTEL_PT_PIP;
106a4e92590SAdrian Hunter 	memcpy_le64(&payload, buf + 2, 6);
107*90af7555SAdrian Hunter 	packet->payload = payload;
108a4e92590SAdrian Hunter 
109a4e92590SAdrian Hunter 	return 8;
110a4e92590SAdrian Hunter }
111a4e92590SAdrian Hunter 
1123d498078SAdrian Hunter static int intel_pt_get_tracestop(struct intel_pt_pkt *packet)
1133d498078SAdrian Hunter {
1143d498078SAdrian Hunter 	packet->type = INTEL_PT_TRACESTOP;
1153d498078SAdrian Hunter 	return 2;
1163d498078SAdrian Hunter }
1173d498078SAdrian Hunter 
118a4e92590SAdrian Hunter static int intel_pt_get_cbr(const unsigned char *buf, size_t len,
119a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
120a4e92590SAdrian Hunter {
121a4e92590SAdrian Hunter 	if (len < 4)
122a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
123a4e92590SAdrian Hunter 	packet->type = INTEL_PT_CBR;
12426fb2fb1SAdrian Hunter 	packet->payload = le16_to_cpu(*(uint16_t *)(buf + 2));
125a4e92590SAdrian Hunter 	return 4;
126a4e92590SAdrian Hunter }
127a4e92590SAdrian Hunter 
1283d498078SAdrian Hunter static int intel_pt_get_vmcs(const unsigned char *buf, size_t len,
1293d498078SAdrian Hunter 			     struct intel_pt_pkt *packet)
1303d498078SAdrian Hunter {
1313d498078SAdrian Hunter 	unsigned int count = (52 - 5) >> 3;
1323d498078SAdrian Hunter 
1333d498078SAdrian Hunter 	if (count < 1 || count > 7)
1343d498078SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
1353d498078SAdrian Hunter 
1363d498078SAdrian Hunter 	if (len < count + 2)
1373d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
1383d498078SAdrian Hunter 
1393d498078SAdrian Hunter 	packet->type = INTEL_PT_VMCS;
1403d498078SAdrian Hunter 	packet->count = count;
1413d498078SAdrian Hunter 	memcpy_le64(&packet->payload, buf + 2, count);
1423d498078SAdrian Hunter 
1433d498078SAdrian Hunter 	return count + 2;
1443d498078SAdrian Hunter }
1453d498078SAdrian Hunter 
146a4e92590SAdrian Hunter static int intel_pt_get_ovf(struct intel_pt_pkt *packet)
147a4e92590SAdrian Hunter {
148a4e92590SAdrian Hunter 	packet->type = INTEL_PT_OVF;
149a4e92590SAdrian Hunter 	return 2;
150a4e92590SAdrian Hunter }
151a4e92590SAdrian Hunter 
152a4e92590SAdrian Hunter static int intel_pt_get_psb(const unsigned char *buf, size_t len,
153a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
154a4e92590SAdrian Hunter {
155a4e92590SAdrian Hunter 	int i;
156a4e92590SAdrian Hunter 
157a4e92590SAdrian Hunter 	if (len < 16)
158a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
159a4e92590SAdrian Hunter 
160a4e92590SAdrian Hunter 	for (i = 2; i < 16; i += 2) {
161a4e92590SAdrian Hunter 		if (buf[i] != 2 || buf[i + 1] != 0x82)
162a4e92590SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
163a4e92590SAdrian Hunter 	}
164a4e92590SAdrian Hunter 
165a4e92590SAdrian Hunter 	packet->type = INTEL_PT_PSB;
166a4e92590SAdrian Hunter 	return 16;
167a4e92590SAdrian Hunter }
168a4e92590SAdrian Hunter 
169a4e92590SAdrian Hunter static int intel_pt_get_psbend(struct intel_pt_pkt *packet)
170a4e92590SAdrian Hunter {
171a4e92590SAdrian Hunter 	packet->type = INTEL_PT_PSBEND;
172a4e92590SAdrian Hunter 	return 2;
173a4e92590SAdrian Hunter }
174a4e92590SAdrian Hunter 
1753d498078SAdrian Hunter static int intel_pt_get_tma(const unsigned char *buf, size_t len,
1763d498078SAdrian Hunter 			    struct intel_pt_pkt *packet)
1773d498078SAdrian Hunter {
1783d498078SAdrian Hunter 	if (len < 7)
1793d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
1803d498078SAdrian Hunter 
1813d498078SAdrian Hunter 	packet->type = INTEL_PT_TMA;
1823d498078SAdrian Hunter 	packet->payload = buf[2] | (buf[3] << 8);
1833d498078SAdrian Hunter 	packet->count = buf[5] | ((buf[6] & BIT(0)) << 8);
1843d498078SAdrian Hunter 	return 7;
1853d498078SAdrian Hunter }
1863d498078SAdrian Hunter 
187a4e92590SAdrian Hunter static int intel_pt_get_pad(struct intel_pt_pkt *packet)
188a4e92590SAdrian Hunter {
189a4e92590SAdrian Hunter 	packet->type = INTEL_PT_PAD;
190a4e92590SAdrian Hunter 	return 1;
191a4e92590SAdrian Hunter }
192a4e92590SAdrian Hunter 
1933d498078SAdrian Hunter static int intel_pt_get_mnt(const unsigned char *buf, size_t len,
1943d498078SAdrian Hunter 			    struct intel_pt_pkt *packet)
1953d498078SAdrian Hunter {
1963d498078SAdrian Hunter 	if (len < 11)
1973d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
1983d498078SAdrian Hunter 	packet->type = INTEL_PT_MNT;
1993d498078SAdrian Hunter 	memcpy_le64(&packet->payload, buf + 3, 8);
2003d498078SAdrian Hunter 	return 11
2013d498078SAdrian Hunter ;
2023d498078SAdrian Hunter }
2033d498078SAdrian Hunter 
2043d498078SAdrian Hunter static int intel_pt_get_3byte(const unsigned char *buf, size_t len,
2053d498078SAdrian Hunter 			      struct intel_pt_pkt *packet)
2063d498078SAdrian Hunter {
2073d498078SAdrian Hunter 	if (len < 3)
2083d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
2093d498078SAdrian Hunter 
2103d498078SAdrian Hunter 	switch (buf[2]) {
2113d498078SAdrian Hunter 	case 0x88: /* MNT */
2123d498078SAdrian Hunter 		return intel_pt_get_mnt(buf, len, packet);
2133d498078SAdrian Hunter 	default:
2143d498078SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
2153d498078SAdrian Hunter 	}
2163d498078SAdrian Hunter }
2173d498078SAdrian Hunter 
218a472e65fSAdrian Hunter static int intel_pt_get_ptwrite(const unsigned char *buf, size_t len,
219a472e65fSAdrian Hunter 				struct intel_pt_pkt *packet)
220a472e65fSAdrian Hunter {
221a472e65fSAdrian Hunter 	packet->count = (buf[1] >> 5) & 0x3;
222a472e65fSAdrian Hunter 	packet->type = buf[1] & BIT(7) ? INTEL_PT_PTWRITE_IP :
223a472e65fSAdrian Hunter 					 INTEL_PT_PTWRITE;
224a472e65fSAdrian Hunter 
225a472e65fSAdrian Hunter 	switch (packet->count) {
226a472e65fSAdrian Hunter 	case 0:
227a472e65fSAdrian Hunter 		if (len < 6)
228a472e65fSAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
229a472e65fSAdrian Hunter 		packet->payload = le32_to_cpu(*(uint32_t *)(buf + 2));
230a472e65fSAdrian Hunter 		return 6;
231a472e65fSAdrian Hunter 	case 1:
232a472e65fSAdrian Hunter 		if (len < 10)
233a472e65fSAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
234a472e65fSAdrian Hunter 		packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2));
235a472e65fSAdrian Hunter 		return 10;
236a472e65fSAdrian Hunter 	default:
237a472e65fSAdrian Hunter 		return INTEL_PT_BAD_PACKET;
238a472e65fSAdrian Hunter 	}
239a472e65fSAdrian Hunter }
240a472e65fSAdrian Hunter 
241a472e65fSAdrian Hunter static int intel_pt_get_exstop(struct intel_pt_pkt *packet)
242a472e65fSAdrian Hunter {
243a472e65fSAdrian Hunter 	packet->type = INTEL_PT_EXSTOP;
244a472e65fSAdrian Hunter 	return 2;
245a472e65fSAdrian Hunter }
246a472e65fSAdrian Hunter 
247a472e65fSAdrian Hunter static int intel_pt_get_exstop_ip(struct intel_pt_pkt *packet)
248a472e65fSAdrian Hunter {
249a472e65fSAdrian Hunter 	packet->type = INTEL_PT_EXSTOP_IP;
250a472e65fSAdrian Hunter 	return 2;
251a472e65fSAdrian Hunter }
252a472e65fSAdrian Hunter 
253a472e65fSAdrian Hunter static int intel_pt_get_mwait(const unsigned char *buf, size_t len,
254a472e65fSAdrian Hunter 			      struct intel_pt_pkt *packet)
255a472e65fSAdrian Hunter {
256a472e65fSAdrian Hunter 	if (len < 10)
257a472e65fSAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
258a472e65fSAdrian Hunter 	packet->type = INTEL_PT_MWAIT;
259a472e65fSAdrian Hunter 	packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2));
260a472e65fSAdrian Hunter 	return 10;
261a472e65fSAdrian Hunter }
262a472e65fSAdrian Hunter 
263a472e65fSAdrian Hunter static int intel_pt_get_pwre(const unsigned char *buf, size_t len,
264a472e65fSAdrian Hunter 			     struct intel_pt_pkt *packet)
265a472e65fSAdrian Hunter {
266a472e65fSAdrian Hunter 	if (len < 4)
267a472e65fSAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
268a472e65fSAdrian Hunter 	packet->type = INTEL_PT_PWRE;
269a472e65fSAdrian Hunter 	memcpy_le64(&packet->payload, buf + 2, 2);
270a472e65fSAdrian Hunter 	return 4;
271a472e65fSAdrian Hunter }
272a472e65fSAdrian Hunter 
273a472e65fSAdrian Hunter static int intel_pt_get_pwrx(const unsigned char *buf, size_t len,
274a472e65fSAdrian Hunter 			     struct intel_pt_pkt *packet)
275a472e65fSAdrian Hunter {
276a472e65fSAdrian Hunter 	if (len < 7)
277a472e65fSAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
278a472e65fSAdrian Hunter 	packet->type = INTEL_PT_PWRX;
279a472e65fSAdrian Hunter 	memcpy_le64(&packet->payload, buf + 2, 5);
280a472e65fSAdrian Hunter 	return 7;
281a472e65fSAdrian Hunter }
282a472e65fSAdrian Hunter 
283edff7809SAdrian Hunter static int intel_pt_get_bbp(const unsigned char *buf, size_t len,
284edff7809SAdrian Hunter 			    struct intel_pt_pkt *packet)
285edff7809SAdrian Hunter {
286edff7809SAdrian Hunter 	if (len < 3)
287edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
288edff7809SAdrian Hunter 	packet->type = INTEL_PT_BBP;
289edff7809SAdrian Hunter 	packet->count = buf[2] >> 7;
290edff7809SAdrian Hunter 	packet->payload = buf[2] & 0x1f;
291edff7809SAdrian Hunter 	return 3;
292edff7809SAdrian Hunter }
293edff7809SAdrian Hunter 
294edff7809SAdrian Hunter static int intel_pt_get_bip_4(const unsigned char *buf, size_t len,
295edff7809SAdrian Hunter 			      struct intel_pt_pkt *packet)
296edff7809SAdrian Hunter {
297edff7809SAdrian Hunter 	if (len < 5)
298edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
299edff7809SAdrian Hunter 	packet->type = INTEL_PT_BIP;
300edff7809SAdrian Hunter 	packet->count = buf[0] >> 3;
301edff7809SAdrian Hunter 	memcpy_le64(&packet->payload, buf + 1, 4);
302edff7809SAdrian Hunter 	return 5;
303edff7809SAdrian Hunter }
304edff7809SAdrian Hunter 
305edff7809SAdrian Hunter static int intel_pt_get_bip_8(const unsigned char *buf, size_t len,
306edff7809SAdrian Hunter 			      struct intel_pt_pkt *packet)
307edff7809SAdrian Hunter {
308edff7809SAdrian Hunter 	if (len < 9)
309edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
310edff7809SAdrian Hunter 	packet->type = INTEL_PT_BIP;
311edff7809SAdrian Hunter 	packet->count = buf[0] >> 3;
312edff7809SAdrian Hunter 	memcpy_le64(&packet->payload, buf + 1, 8);
313edff7809SAdrian Hunter 	return 9;
314edff7809SAdrian Hunter }
315edff7809SAdrian Hunter 
316edff7809SAdrian Hunter static int intel_pt_get_bep(size_t len, struct intel_pt_pkt *packet)
317edff7809SAdrian Hunter {
318edff7809SAdrian Hunter 	if (len < 2)
319edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
320edff7809SAdrian Hunter 	packet->type = INTEL_PT_BEP;
321edff7809SAdrian Hunter 	return 2;
322edff7809SAdrian Hunter }
323edff7809SAdrian Hunter 
324edff7809SAdrian Hunter static int intel_pt_get_bep_ip(size_t len, struct intel_pt_pkt *packet)
325edff7809SAdrian Hunter {
326edff7809SAdrian Hunter 	if (len < 2)
327edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
328edff7809SAdrian Hunter 	packet->type = INTEL_PT_BEP_IP;
329edff7809SAdrian Hunter 	return 2;
330edff7809SAdrian Hunter }
331edff7809SAdrian Hunter 
332a4e92590SAdrian Hunter static int intel_pt_get_ext(const unsigned char *buf, size_t len,
333a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
334a4e92590SAdrian Hunter {
335a4e92590SAdrian Hunter 	if (len < 2)
336a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
337a4e92590SAdrian Hunter 
338a472e65fSAdrian Hunter 	if ((buf[1] & 0x1f) == 0x12)
339a472e65fSAdrian Hunter 		return intel_pt_get_ptwrite(buf, len, packet);
340a472e65fSAdrian Hunter 
341a4e92590SAdrian Hunter 	switch (buf[1]) {
342a4e92590SAdrian Hunter 	case 0xa3: /* Long TNT */
343a4e92590SAdrian Hunter 		return intel_pt_get_long_tnt(buf, len, packet);
344a4e92590SAdrian Hunter 	case 0x43: /* PIP */
345a4e92590SAdrian Hunter 		return intel_pt_get_pip(buf, len, packet);
3463d498078SAdrian Hunter 	case 0x83: /* TraceStop */
3473d498078SAdrian Hunter 		return intel_pt_get_tracestop(packet);
348a4e92590SAdrian Hunter 	case 0x03: /* CBR */
349a4e92590SAdrian Hunter 		return intel_pt_get_cbr(buf, len, packet);
3503d498078SAdrian Hunter 	case 0xc8: /* VMCS */
3513d498078SAdrian Hunter 		return intel_pt_get_vmcs(buf, len, packet);
352a4e92590SAdrian Hunter 	case 0xf3: /* OVF */
353a4e92590SAdrian Hunter 		return intel_pt_get_ovf(packet);
354a4e92590SAdrian Hunter 	case 0x82: /* PSB */
355a4e92590SAdrian Hunter 		return intel_pt_get_psb(buf, len, packet);
356a4e92590SAdrian Hunter 	case 0x23: /* PSBEND */
357a4e92590SAdrian Hunter 		return intel_pt_get_psbend(packet);
3583d498078SAdrian Hunter 	case 0x73: /* TMA */
3593d498078SAdrian Hunter 		return intel_pt_get_tma(buf, len, packet);
3603d498078SAdrian Hunter 	case 0xC3: /* 3-byte header */
3613d498078SAdrian Hunter 		return intel_pt_get_3byte(buf, len, packet);
362a472e65fSAdrian Hunter 	case 0x62: /* EXSTOP no IP */
363a472e65fSAdrian Hunter 		return intel_pt_get_exstop(packet);
364a472e65fSAdrian Hunter 	case 0xE2: /* EXSTOP with IP */
365a472e65fSAdrian Hunter 		return intel_pt_get_exstop_ip(packet);
366a472e65fSAdrian Hunter 	case 0xC2: /* MWAIT */
367a472e65fSAdrian Hunter 		return intel_pt_get_mwait(buf, len, packet);
368a472e65fSAdrian Hunter 	case 0x22: /* PWRE */
369a472e65fSAdrian Hunter 		return intel_pt_get_pwre(buf, len, packet);
370a472e65fSAdrian Hunter 	case 0xA2: /* PWRX */
371a472e65fSAdrian Hunter 		return intel_pt_get_pwrx(buf, len, packet);
372edff7809SAdrian Hunter 	case 0x63: /* BBP */
373edff7809SAdrian Hunter 		return intel_pt_get_bbp(buf, len, packet);
374edff7809SAdrian Hunter 	case 0x33: /* BEP no IP */
375edff7809SAdrian Hunter 		return intel_pt_get_bep(len, packet);
376edff7809SAdrian Hunter 	case 0xb3: /* BEP with IP */
377edff7809SAdrian Hunter 		return intel_pt_get_bep_ip(len, packet);
378a4e92590SAdrian Hunter 	default:
379a4e92590SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
380a4e92590SAdrian Hunter 	}
381a4e92590SAdrian Hunter }
382a4e92590SAdrian Hunter 
383a4e92590SAdrian Hunter static int intel_pt_get_short_tnt(unsigned int byte,
384a4e92590SAdrian Hunter 				  struct intel_pt_pkt *packet)
385a4e92590SAdrian Hunter {
386a4e92590SAdrian Hunter 	int count;
387a4e92590SAdrian Hunter 
388a4e92590SAdrian Hunter 	for (count = 6; count; count--) {
389a4e92590SAdrian Hunter 		if (byte & BIT(7))
390a4e92590SAdrian Hunter 			break;
391a4e92590SAdrian Hunter 		byte <<= 1;
392a4e92590SAdrian Hunter 	}
393a4e92590SAdrian Hunter 
394a4e92590SAdrian Hunter 	packet->type = INTEL_PT_TNT;
395a4e92590SAdrian Hunter 	packet->count = count;
396a4e92590SAdrian Hunter 	packet->payload = (uint64_t)byte << 57;
397a4e92590SAdrian Hunter 
398a4e92590SAdrian Hunter 	return 1;
399a4e92590SAdrian Hunter }
400a4e92590SAdrian Hunter 
4013d498078SAdrian Hunter static int intel_pt_get_cyc(unsigned int byte, const unsigned char *buf,
4023d498078SAdrian Hunter 			    size_t len, struct intel_pt_pkt *packet)
4033d498078SAdrian Hunter {
4043d498078SAdrian Hunter 	unsigned int offs = 1, shift;
4053d498078SAdrian Hunter 	uint64_t payload = byte >> 3;
4063d498078SAdrian Hunter 
4073d498078SAdrian Hunter 	byte >>= 2;
4083d498078SAdrian Hunter 	len -= 1;
4093d498078SAdrian Hunter 	for (shift = 5; byte & 1; shift += 7) {
4103d498078SAdrian Hunter 		if (offs > 9)
4113d498078SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
4123d498078SAdrian Hunter 		if (len < offs)
4133d498078SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
4143d498078SAdrian Hunter 		byte = buf[offs++];
415621a5a32SAdrian Hunter 		payload |= ((uint64_t)byte >> 1) << shift;
4163d498078SAdrian Hunter 	}
4173d498078SAdrian Hunter 
4183d498078SAdrian Hunter 	packet->type = INTEL_PT_CYC;
4193d498078SAdrian Hunter 	packet->payload = payload;
4203d498078SAdrian Hunter 	return offs;
4213d498078SAdrian Hunter }
4223d498078SAdrian Hunter 
423a4e92590SAdrian Hunter static int intel_pt_get_ip(enum intel_pt_pkt_type type, unsigned int byte,
424a4e92590SAdrian Hunter 			   const unsigned char *buf, size_t len,
425a4e92590SAdrian Hunter 			   struct intel_pt_pkt *packet)
426a4e92590SAdrian Hunter {
427e1717e04SAdrian Hunter 	int ip_len;
428e1717e04SAdrian Hunter 
429e1717e04SAdrian Hunter 	packet->count = byte >> 5;
430e1717e04SAdrian Hunter 
431e1717e04SAdrian Hunter 	switch (packet->count) {
432a4e92590SAdrian Hunter 	case 0:
433e1717e04SAdrian Hunter 		ip_len = 0;
434a4e92590SAdrian Hunter 		break;
435a4e92590SAdrian Hunter 	case 1:
436a4e92590SAdrian Hunter 		if (len < 3)
437a4e92590SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
438e1717e04SAdrian Hunter 		ip_len = 2;
439a4e92590SAdrian Hunter 		packet->payload = le16_to_cpu(*(uint16_t *)(buf + 1));
440a4e92590SAdrian Hunter 		break;
441a4e92590SAdrian Hunter 	case 2:
442a4e92590SAdrian Hunter 		if (len < 5)
443a4e92590SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
444e1717e04SAdrian Hunter 		ip_len = 4;
445a4e92590SAdrian Hunter 		packet->payload = le32_to_cpu(*(uint32_t *)(buf + 1));
446a4e92590SAdrian Hunter 		break;
447a4e92590SAdrian Hunter 	case 3:
448e1717e04SAdrian Hunter 	case 4:
449a4e92590SAdrian Hunter 		if (len < 7)
450a4e92590SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
451e1717e04SAdrian Hunter 		ip_len = 6;
452a4e92590SAdrian Hunter 		memcpy_le64(&packet->payload, buf + 1, 6);
453a4e92590SAdrian Hunter 		break;
454e1717e04SAdrian Hunter 	case 6:
455e1717e04SAdrian Hunter 		if (len < 9)
456e1717e04SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
457e1717e04SAdrian Hunter 		ip_len = 8;
458e1717e04SAdrian Hunter 		packet->payload = le64_to_cpu(*(uint64_t *)(buf + 1));
459e1717e04SAdrian Hunter 		break;
460a4e92590SAdrian Hunter 	default:
461a4e92590SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
462a4e92590SAdrian Hunter 	}
463a4e92590SAdrian Hunter 
464a4e92590SAdrian Hunter 	packet->type = type;
465a4e92590SAdrian Hunter 
466e1717e04SAdrian Hunter 	return ip_len + 1;
467a4e92590SAdrian Hunter }
468a4e92590SAdrian Hunter 
469a4e92590SAdrian Hunter static int intel_pt_get_mode(const unsigned char *buf, size_t len,
470a4e92590SAdrian Hunter 			     struct intel_pt_pkt *packet)
471a4e92590SAdrian Hunter {
472a4e92590SAdrian Hunter 	if (len < 2)
473a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
474a4e92590SAdrian Hunter 
475a4e92590SAdrian Hunter 	switch (buf[1] >> 5) {
476a4e92590SAdrian Hunter 	case 0:
477a4e92590SAdrian Hunter 		packet->type = INTEL_PT_MODE_EXEC;
478a4e92590SAdrian Hunter 		switch (buf[1] & 3) {
479a4e92590SAdrian Hunter 		case 0:
480a4e92590SAdrian Hunter 			packet->payload = 16;
481a4e92590SAdrian Hunter 			break;
482a4e92590SAdrian Hunter 		case 1:
483a4e92590SAdrian Hunter 			packet->payload = 64;
484a4e92590SAdrian Hunter 			break;
485a4e92590SAdrian Hunter 		case 2:
486a4e92590SAdrian Hunter 			packet->payload = 32;
487a4e92590SAdrian Hunter 			break;
488a4e92590SAdrian Hunter 		default:
489a4e92590SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
490a4e92590SAdrian Hunter 		}
491a4e92590SAdrian Hunter 		break;
492a4e92590SAdrian Hunter 	case 1:
493a4e92590SAdrian Hunter 		packet->type = INTEL_PT_MODE_TSX;
494a4e92590SAdrian Hunter 		if ((buf[1] & 3) == 3)
495a4e92590SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
496a4e92590SAdrian Hunter 		packet->payload = buf[1] & 3;
497a4e92590SAdrian Hunter 		break;
498a4e92590SAdrian Hunter 	default:
499a4e92590SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
500a4e92590SAdrian Hunter 	}
501a4e92590SAdrian Hunter 
502a4e92590SAdrian Hunter 	return 2;
503a4e92590SAdrian Hunter }
504a4e92590SAdrian Hunter 
505a4e92590SAdrian Hunter static int intel_pt_get_tsc(const unsigned char *buf, size_t len,
506a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
507a4e92590SAdrian Hunter {
508a4e92590SAdrian Hunter 	if (len < 8)
509a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
510a4e92590SAdrian Hunter 	packet->type = INTEL_PT_TSC;
511a4e92590SAdrian Hunter 	memcpy_le64(&packet->payload, buf + 1, 7);
512a4e92590SAdrian Hunter 	return 8;
513a4e92590SAdrian Hunter }
514a4e92590SAdrian Hunter 
5153d498078SAdrian Hunter static int intel_pt_get_mtc(const unsigned char *buf, size_t len,
5163d498078SAdrian Hunter 			    struct intel_pt_pkt *packet)
5173d498078SAdrian Hunter {
5183d498078SAdrian Hunter 	if (len < 2)
5193d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
5203d498078SAdrian Hunter 	packet->type = INTEL_PT_MTC;
5213d498078SAdrian Hunter 	packet->payload = buf[1];
5223d498078SAdrian Hunter 	return 2;
5233d498078SAdrian Hunter }
5243d498078SAdrian Hunter 
525a4e92590SAdrian Hunter static int intel_pt_do_get_packet(const unsigned char *buf, size_t len,
526edff7809SAdrian Hunter 				  struct intel_pt_pkt *packet,
527edff7809SAdrian Hunter 				  enum intel_pt_pkt_ctx ctx)
528a4e92590SAdrian Hunter {
529a4e92590SAdrian Hunter 	unsigned int byte;
530a4e92590SAdrian Hunter 
531a4e92590SAdrian Hunter 	memset(packet, 0, sizeof(struct intel_pt_pkt));
532a4e92590SAdrian Hunter 
533a4e92590SAdrian Hunter 	if (!len)
534a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
535a4e92590SAdrian Hunter 
536a4e92590SAdrian Hunter 	byte = buf[0];
537edff7809SAdrian Hunter 
538edff7809SAdrian Hunter 	switch (ctx) {
539edff7809SAdrian Hunter 	case INTEL_PT_NO_CTX:
540edff7809SAdrian Hunter 		break;
541edff7809SAdrian Hunter 	case INTEL_PT_BLK_4_CTX:
542edff7809SAdrian Hunter 		if ((byte & 0x7) == 4)
543edff7809SAdrian Hunter 			return intel_pt_get_bip_4(buf, len, packet);
544edff7809SAdrian Hunter 		break;
545edff7809SAdrian Hunter 	case INTEL_PT_BLK_8_CTX:
546edff7809SAdrian Hunter 		if ((byte & 0x7) == 4)
547edff7809SAdrian Hunter 			return intel_pt_get_bip_8(buf, len, packet);
548edff7809SAdrian Hunter 		break;
549edff7809SAdrian Hunter 	default:
550edff7809SAdrian Hunter 		break;
5518284bbeaSZou Wei 	}
552edff7809SAdrian Hunter 
553a4e92590SAdrian Hunter 	if (!(byte & BIT(0))) {
554a4e92590SAdrian Hunter 		if (byte == 0)
555a4e92590SAdrian Hunter 			return intel_pt_get_pad(packet);
556a4e92590SAdrian Hunter 		if (byte == 2)
557a4e92590SAdrian Hunter 			return intel_pt_get_ext(buf, len, packet);
558a4e92590SAdrian Hunter 		return intel_pt_get_short_tnt(byte, packet);
559a4e92590SAdrian Hunter 	}
560a4e92590SAdrian Hunter 
5613d498078SAdrian Hunter 	if ((byte & 2))
5623d498078SAdrian Hunter 		return intel_pt_get_cyc(byte, buf, len, packet);
5633d498078SAdrian Hunter 
564a4e92590SAdrian Hunter 	switch (byte & 0x1f) {
565a4e92590SAdrian Hunter 	case 0x0D:
566a4e92590SAdrian Hunter 		return intel_pt_get_ip(INTEL_PT_TIP, byte, buf, len, packet);
567a4e92590SAdrian Hunter 	case 0x11:
568a4e92590SAdrian Hunter 		return intel_pt_get_ip(INTEL_PT_TIP_PGE, byte, buf, len,
569a4e92590SAdrian Hunter 				       packet);
570a4e92590SAdrian Hunter 	case 0x01:
571a4e92590SAdrian Hunter 		return intel_pt_get_ip(INTEL_PT_TIP_PGD, byte, buf, len,
572a4e92590SAdrian Hunter 				       packet);
573a4e92590SAdrian Hunter 	case 0x1D:
574a4e92590SAdrian Hunter 		return intel_pt_get_ip(INTEL_PT_FUP, byte, buf, len, packet);
575a4e92590SAdrian Hunter 	case 0x19:
576a4e92590SAdrian Hunter 		switch (byte) {
577a4e92590SAdrian Hunter 		case 0x99:
578a4e92590SAdrian Hunter 			return intel_pt_get_mode(buf, len, packet);
579a4e92590SAdrian Hunter 		case 0x19:
580a4e92590SAdrian Hunter 			return intel_pt_get_tsc(buf, len, packet);
5813d498078SAdrian Hunter 		case 0x59:
5823d498078SAdrian Hunter 			return intel_pt_get_mtc(buf, len, packet);
583a4e92590SAdrian Hunter 		default:
584a4e92590SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
585a4e92590SAdrian Hunter 		}
586a4e92590SAdrian Hunter 	default:
587a4e92590SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
588a4e92590SAdrian Hunter 	}
589a4e92590SAdrian Hunter }
590a4e92590SAdrian Hunter 
591edff7809SAdrian Hunter void intel_pt_upd_pkt_ctx(const struct intel_pt_pkt *packet,
592edff7809SAdrian Hunter 			  enum intel_pt_pkt_ctx *ctx)
593edff7809SAdrian Hunter {
594edff7809SAdrian Hunter 	switch (packet->type) {
595edff7809SAdrian Hunter 	case INTEL_PT_BAD:
596edff7809SAdrian Hunter 	case INTEL_PT_PAD:
597edff7809SAdrian Hunter 	case INTEL_PT_TSC:
598edff7809SAdrian Hunter 	case INTEL_PT_TMA:
599edff7809SAdrian Hunter 	case INTEL_PT_MTC:
600edff7809SAdrian Hunter 	case INTEL_PT_FUP:
601edff7809SAdrian Hunter 	case INTEL_PT_CYC:
602edff7809SAdrian Hunter 	case INTEL_PT_CBR:
603edff7809SAdrian Hunter 	case INTEL_PT_MNT:
604edff7809SAdrian Hunter 	case INTEL_PT_EXSTOP:
605edff7809SAdrian Hunter 	case INTEL_PT_EXSTOP_IP:
606edff7809SAdrian Hunter 	case INTEL_PT_PWRE:
607edff7809SAdrian Hunter 	case INTEL_PT_PWRX:
608edff7809SAdrian Hunter 	case INTEL_PT_BIP:
609edff7809SAdrian Hunter 		break;
610edff7809SAdrian Hunter 	case INTEL_PT_TNT:
611edff7809SAdrian Hunter 	case INTEL_PT_TIP:
612edff7809SAdrian Hunter 	case INTEL_PT_TIP_PGD:
613edff7809SAdrian Hunter 	case INTEL_PT_TIP_PGE:
614edff7809SAdrian Hunter 	case INTEL_PT_MODE_EXEC:
615edff7809SAdrian Hunter 	case INTEL_PT_MODE_TSX:
616edff7809SAdrian Hunter 	case INTEL_PT_PIP:
617edff7809SAdrian Hunter 	case INTEL_PT_OVF:
618edff7809SAdrian Hunter 	case INTEL_PT_VMCS:
619edff7809SAdrian Hunter 	case INTEL_PT_TRACESTOP:
620edff7809SAdrian Hunter 	case INTEL_PT_PSB:
621edff7809SAdrian Hunter 	case INTEL_PT_PSBEND:
622edff7809SAdrian Hunter 	case INTEL_PT_PTWRITE:
623edff7809SAdrian Hunter 	case INTEL_PT_PTWRITE_IP:
624edff7809SAdrian Hunter 	case INTEL_PT_MWAIT:
625edff7809SAdrian Hunter 	case INTEL_PT_BEP:
626edff7809SAdrian Hunter 	case INTEL_PT_BEP_IP:
627edff7809SAdrian Hunter 		*ctx = INTEL_PT_NO_CTX;
628edff7809SAdrian Hunter 		break;
629edff7809SAdrian Hunter 	case INTEL_PT_BBP:
630edff7809SAdrian Hunter 		if (packet->count)
631edff7809SAdrian Hunter 			*ctx = INTEL_PT_BLK_4_CTX;
632edff7809SAdrian Hunter 		else
633edff7809SAdrian Hunter 			*ctx = INTEL_PT_BLK_8_CTX;
634edff7809SAdrian Hunter 		break;
635edff7809SAdrian Hunter 	default:
636edff7809SAdrian Hunter 		break;
637edff7809SAdrian Hunter 	}
638edff7809SAdrian Hunter }
639edff7809SAdrian Hunter 
640a4e92590SAdrian Hunter int intel_pt_get_packet(const unsigned char *buf, size_t len,
641edff7809SAdrian Hunter 			struct intel_pt_pkt *packet, enum intel_pt_pkt_ctx *ctx)
642a4e92590SAdrian Hunter {
643a4e92590SAdrian Hunter 	int ret;
644a4e92590SAdrian Hunter 
645edff7809SAdrian Hunter 	ret = intel_pt_do_get_packet(buf, len, packet, *ctx);
646a4e92590SAdrian Hunter 	if (ret > 0) {
647a4e92590SAdrian Hunter 		while (ret < 8 && len > (size_t)ret && !buf[ret])
648a4e92590SAdrian Hunter 			ret += 1;
649edff7809SAdrian Hunter 		intel_pt_upd_pkt_ctx(packet, ctx);
650a4e92590SAdrian Hunter 	}
651a4e92590SAdrian Hunter 	return ret;
652a4e92590SAdrian Hunter }
653a4e92590SAdrian Hunter 
654a4e92590SAdrian Hunter int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf,
655a4e92590SAdrian Hunter 		      size_t buf_len)
656a4e92590SAdrian Hunter {
6573d498078SAdrian Hunter 	int ret, i, nr;
658a4e92590SAdrian Hunter 	unsigned long long payload = packet->payload;
659a4e92590SAdrian Hunter 	const char *name = intel_pt_pkt_name(packet->type);
660a4e92590SAdrian Hunter 
661a4e92590SAdrian Hunter 	switch (packet->type) {
662a4e92590SAdrian Hunter 	case INTEL_PT_BAD:
663a4e92590SAdrian Hunter 	case INTEL_PT_PAD:
664a4e92590SAdrian Hunter 	case INTEL_PT_PSB:
665a4e92590SAdrian Hunter 	case INTEL_PT_PSBEND:
6663d498078SAdrian Hunter 	case INTEL_PT_TRACESTOP:
667a4e92590SAdrian Hunter 	case INTEL_PT_OVF:
668a4e92590SAdrian Hunter 		return snprintf(buf, buf_len, "%s", name);
669a4e92590SAdrian Hunter 	case INTEL_PT_TNT: {
670a4e92590SAdrian Hunter 		size_t blen = buf_len;
671a4e92590SAdrian Hunter 
672a4e92590SAdrian Hunter 		ret = snprintf(buf, blen, "%s ", name);
673a4e92590SAdrian Hunter 		if (ret < 0)
674a4e92590SAdrian Hunter 			return ret;
675a4e92590SAdrian Hunter 		buf += ret;
676a4e92590SAdrian Hunter 		blen -= ret;
677a4e92590SAdrian Hunter 		for (i = 0; i < packet->count; i++) {
678a4e92590SAdrian Hunter 			if (payload & BIT63)
679a4e92590SAdrian Hunter 				ret = snprintf(buf, blen, "T");
680a4e92590SAdrian Hunter 			else
681a4e92590SAdrian Hunter 				ret = snprintf(buf, blen, "N");
682a4e92590SAdrian Hunter 			if (ret < 0)
683a4e92590SAdrian Hunter 				return ret;
684a4e92590SAdrian Hunter 			buf += ret;
685a4e92590SAdrian Hunter 			blen -= ret;
686a4e92590SAdrian Hunter 			payload <<= 1;
687a4e92590SAdrian Hunter 		}
688a4e92590SAdrian Hunter 		ret = snprintf(buf, blen, " (%d)", packet->count);
689a4e92590SAdrian Hunter 		if (ret < 0)
690a4e92590SAdrian Hunter 			return ret;
691a4e92590SAdrian Hunter 		blen -= ret;
692a4e92590SAdrian Hunter 		return buf_len - blen;
693a4e92590SAdrian Hunter 	}
694a4e92590SAdrian Hunter 	case INTEL_PT_TIP_PGD:
695a4e92590SAdrian Hunter 	case INTEL_PT_TIP_PGE:
696a4e92590SAdrian Hunter 	case INTEL_PT_TIP:
697a4e92590SAdrian Hunter 	case INTEL_PT_FUP:
698a4e92590SAdrian Hunter 		if (!(packet->count))
699a4e92590SAdrian Hunter 			return snprintf(buf, buf_len, "%s no ip", name);
7007ea6856dSArnaldo Carvalho de Melo 		__fallthrough;
7013d498078SAdrian Hunter 	case INTEL_PT_CYC:
7023d498078SAdrian Hunter 	case INTEL_PT_VMCS:
7033d498078SAdrian Hunter 	case INTEL_PT_MTC:
7043d498078SAdrian Hunter 	case INTEL_PT_MNT:
705a4e92590SAdrian Hunter 	case INTEL_PT_CBR:
706a4e92590SAdrian Hunter 	case INTEL_PT_TSC:
7073d498078SAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx", name, payload);
7083d498078SAdrian Hunter 	case INTEL_PT_TMA:
7093d498078SAdrian Hunter 		return snprintf(buf, buf_len, "%s CTC 0x%x FC 0x%x", name,
7103d498078SAdrian Hunter 				(unsigned)payload, packet->count);
711a4e92590SAdrian Hunter 	case INTEL_PT_MODE_EXEC:
712a4e92590SAdrian Hunter 		return snprintf(buf, buf_len, "%s %lld", name, payload);
713a4e92590SAdrian Hunter 	case INTEL_PT_MODE_TSX:
714a4e92590SAdrian Hunter 		return snprintf(buf, buf_len, "%s TXAbort:%u InTX:%u",
715a4e92590SAdrian Hunter 				name, (unsigned)(payload >> 1) & 1,
716a4e92590SAdrian Hunter 				(unsigned)payload & 1);
717a4e92590SAdrian Hunter 	case INTEL_PT_PIP:
718*90af7555SAdrian Hunter 		nr = packet->payload & INTEL_PT_VMX_NR_FLAG ? 1 : 0;
719*90af7555SAdrian Hunter 		payload &= ~INTEL_PT_VMX_NR_FLAG;
7203d498078SAdrian Hunter 		ret = snprintf(buf, buf_len, "%s 0x%llx (NR=%d)",
721*90af7555SAdrian Hunter 			       name, payload >> 1, nr);
722a4e92590SAdrian Hunter 		return ret;
723a472e65fSAdrian Hunter 	case INTEL_PT_PTWRITE:
724a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx IP:0", name, payload);
725a472e65fSAdrian Hunter 	case INTEL_PT_PTWRITE_IP:
726a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx IP:1", name, payload);
727edff7809SAdrian Hunter 	case INTEL_PT_BEP:
728a472e65fSAdrian Hunter 	case INTEL_PT_EXSTOP:
729a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s IP:0", name);
730edff7809SAdrian Hunter 	case INTEL_PT_BEP_IP:
731a472e65fSAdrian Hunter 	case INTEL_PT_EXSTOP_IP:
732a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s IP:1", name);
733a472e65fSAdrian Hunter 	case INTEL_PT_MWAIT:
734a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx Hints 0x%x Extensions 0x%x",
735a472e65fSAdrian Hunter 				name, payload, (unsigned int)(payload & 0xff),
736a472e65fSAdrian Hunter 				(unsigned int)((payload >> 32) & 0x3));
737a472e65fSAdrian Hunter 	case INTEL_PT_PWRE:
738a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx HW:%u CState:%u Sub-CState:%u",
739a472e65fSAdrian Hunter 				name, payload, !!(payload & 0x80),
740a472e65fSAdrian Hunter 				(unsigned int)((payload >> 12) & 0xf),
741a472e65fSAdrian Hunter 				(unsigned int)((payload >> 8) & 0xf));
742a472e65fSAdrian Hunter 	case INTEL_PT_PWRX:
743a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx Last CState:%u Deepest CState:%u Wake Reason 0x%x",
744a472e65fSAdrian Hunter 				name, payload,
745a472e65fSAdrian Hunter 				(unsigned int)((payload >> 4) & 0xf),
746a472e65fSAdrian Hunter 				(unsigned int)(payload & 0xf),
747a472e65fSAdrian Hunter 				(unsigned int)((payload >> 8) & 0xf));
748edff7809SAdrian Hunter 	case INTEL_PT_BBP:
749edff7809SAdrian Hunter 		return snprintf(buf, buf_len, "%s SZ %s-byte Type 0x%llx",
750edff7809SAdrian Hunter 				name, packet->count ? "4" : "8", payload);
751edff7809SAdrian Hunter 	case INTEL_PT_BIP:
752edff7809SAdrian Hunter 		return snprintf(buf, buf_len, "%s ID 0x%02x Value 0x%llx",
753edff7809SAdrian Hunter 				name, packet->count, payload);
754a4e92590SAdrian Hunter 	default:
755a4e92590SAdrian Hunter 		break;
756a4e92590SAdrian Hunter 	}
757a4e92590SAdrian Hunter 	return snprintf(buf, buf_len, "%s 0x%llx (%d)",
758a4e92590SAdrian Hunter 			name, payload, packet->count);
759a4e92590SAdrian Hunter }
760