xref: /linux/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
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>
11f058fa5bSAdrian Hunter #include <linux/kernel.h>
127ea6856dSArnaldo Carvalho de Melo #include <linux/compiler.h>
133b4fa67fSAdrian Hunter #include <asm-generic/unaligned.h>
14a4e92590SAdrian Hunter 
15a4e92590SAdrian Hunter #include "intel-pt-pkt-decoder.h"
16a4e92590SAdrian Hunter 
17a4e92590SAdrian Hunter #define BIT(n)		(1 << (n))
18a4e92590SAdrian Hunter 
19a4e92590SAdrian Hunter #define BIT63		((uint64_t)1 << 63)
20a4e92590SAdrian Hunter 
214e88118cSIlya Leoshkevich #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
22a4e92590SAdrian Hunter #define memcpy_le64(d, s, n) do { \
23a4e92590SAdrian Hunter 	memcpy((d), (s), (n));    \
24a4e92590SAdrian Hunter 	*(d) = le64_to_cpu(*(d)); \
25a4e92590SAdrian Hunter } while (0)
26a4e92590SAdrian Hunter #else
27a4e92590SAdrian Hunter #define memcpy_le64 memcpy
28a4e92590SAdrian Hunter #endif
29a4e92590SAdrian Hunter 
30a4e92590SAdrian Hunter static const char * const packet_name[] = {
31a4e92590SAdrian Hunter 	[INTEL_PT_BAD]		= "Bad Packet!",
32a4e92590SAdrian Hunter 	[INTEL_PT_PAD]		= "PAD",
33a4e92590SAdrian Hunter 	[INTEL_PT_TNT]		= "TNT",
34a4e92590SAdrian Hunter 	[INTEL_PT_TIP_PGD]	= "TIP.PGD",
35a4e92590SAdrian Hunter 	[INTEL_PT_TIP_PGE]	= "TIP.PGE",
36a4e92590SAdrian Hunter 	[INTEL_PT_TSC]		= "TSC",
373d498078SAdrian Hunter 	[INTEL_PT_TMA]		= "TMA",
38a4e92590SAdrian Hunter 	[INTEL_PT_MODE_EXEC]	= "MODE.Exec",
39a4e92590SAdrian Hunter 	[INTEL_PT_MODE_TSX]	= "MODE.TSX",
403d498078SAdrian Hunter 	[INTEL_PT_MTC]		= "MTC",
41a4e92590SAdrian Hunter 	[INTEL_PT_TIP]		= "TIP",
42a4e92590SAdrian Hunter 	[INTEL_PT_FUP]		= "FUP",
433d498078SAdrian Hunter 	[INTEL_PT_CYC]		= "CYC",
443d498078SAdrian Hunter 	[INTEL_PT_VMCS]		= "VMCS",
45a4e92590SAdrian Hunter 	[INTEL_PT_PSB]		= "PSB",
46a4e92590SAdrian Hunter 	[INTEL_PT_PSBEND]	= "PSBEND",
47a4e92590SAdrian Hunter 	[INTEL_PT_CBR]		= "CBR",
483d498078SAdrian Hunter 	[INTEL_PT_TRACESTOP]	= "TraceSTOP",
49a4e92590SAdrian Hunter 	[INTEL_PT_PIP]		= "PIP",
50a4e92590SAdrian Hunter 	[INTEL_PT_OVF]		= "OVF",
513d498078SAdrian Hunter 	[INTEL_PT_MNT]		= "MNT",
52a472e65fSAdrian Hunter 	[INTEL_PT_PTWRITE]	= "PTWRITE",
53a472e65fSAdrian Hunter 	[INTEL_PT_PTWRITE_IP]	= "PTWRITE",
54a472e65fSAdrian Hunter 	[INTEL_PT_EXSTOP]	= "EXSTOP",
55a472e65fSAdrian Hunter 	[INTEL_PT_EXSTOP_IP]	= "EXSTOP",
56a472e65fSAdrian Hunter 	[INTEL_PT_MWAIT]	= "MWAIT",
57a472e65fSAdrian Hunter 	[INTEL_PT_PWRE]		= "PWRE",
58a472e65fSAdrian Hunter 	[INTEL_PT_PWRX]		= "PWRX",
59edff7809SAdrian Hunter 	[INTEL_PT_BBP]		= "BBP",
60edff7809SAdrian Hunter 	[INTEL_PT_BIP]		= "BIP",
61edff7809SAdrian Hunter 	[INTEL_PT_BEP]		= "BEP",
62edff7809SAdrian Hunter 	[INTEL_PT_BEP_IP]	= "BEP",
632750af50SAdrian Hunter 	[INTEL_PT_CFE]		= "CFE",
642750af50SAdrian Hunter 	[INTEL_PT_CFE_IP]	= "CFE",
652750af50SAdrian Hunter 	[INTEL_PT_EVD]		= "EVD",
66a4e92590SAdrian Hunter };
67a4e92590SAdrian Hunter 
intel_pt_pkt_name(enum intel_pt_pkt_type type)68a4e92590SAdrian Hunter const char *intel_pt_pkt_name(enum intel_pt_pkt_type type)
69a4e92590SAdrian Hunter {
70a4e92590SAdrian Hunter 	return packet_name[type];
71a4e92590SAdrian Hunter }
72a4e92590SAdrian Hunter 
intel_pt_get_long_tnt(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)73a4e92590SAdrian Hunter static int intel_pt_get_long_tnt(const unsigned char *buf, size_t len,
74a4e92590SAdrian Hunter 				 struct intel_pt_pkt *packet)
75a4e92590SAdrian Hunter {
76a4e92590SAdrian Hunter 	uint64_t payload;
77a4e92590SAdrian Hunter 	int count;
78a4e92590SAdrian Hunter 
79a4e92590SAdrian Hunter 	if (len < 8)
80a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
81a4e92590SAdrian Hunter 
823b4fa67fSAdrian Hunter 	payload = get_unaligned_le64(buf);
83a4e92590SAdrian Hunter 
84a4e92590SAdrian Hunter 	for (count = 47; count; count--) {
85a4e92590SAdrian Hunter 		if (payload & BIT63)
86a4e92590SAdrian Hunter 			break;
87a4e92590SAdrian Hunter 		payload <<= 1;
88a4e92590SAdrian Hunter 	}
89a4e92590SAdrian Hunter 
90a4e92590SAdrian Hunter 	packet->type = INTEL_PT_TNT;
91a4e92590SAdrian Hunter 	packet->count = count;
92a4e92590SAdrian Hunter 	packet->payload = payload << 1;
93a4e92590SAdrian Hunter 	return 8;
94a4e92590SAdrian Hunter }
95a4e92590SAdrian Hunter 
intel_pt_get_pip(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)96a4e92590SAdrian Hunter static int intel_pt_get_pip(const unsigned char *buf, size_t len,
97a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
98a4e92590SAdrian Hunter {
99a4e92590SAdrian Hunter 	uint64_t payload = 0;
100a4e92590SAdrian Hunter 
101a4e92590SAdrian Hunter 	if (len < 8)
102a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
103a4e92590SAdrian Hunter 
104a4e92590SAdrian Hunter 	packet->type = INTEL_PT_PIP;
105a4e92590SAdrian Hunter 	memcpy_le64(&payload, buf + 2, 6);
10690af7555SAdrian Hunter 	packet->payload = payload;
107a4e92590SAdrian Hunter 
108a4e92590SAdrian Hunter 	return 8;
109a4e92590SAdrian Hunter }
110a4e92590SAdrian Hunter 
intel_pt_get_tracestop(struct intel_pt_pkt * packet)1113d498078SAdrian Hunter static int intel_pt_get_tracestop(struct intel_pt_pkt *packet)
1123d498078SAdrian Hunter {
1133d498078SAdrian Hunter 	packet->type = INTEL_PT_TRACESTOP;
1143d498078SAdrian Hunter 	return 2;
1153d498078SAdrian Hunter }
1163d498078SAdrian Hunter 
intel_pt_get_cbr(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)117a4e92590SAdrian Hunter static int intel_pt_get_cbr(const unsigned char *buf, size_t len,
118a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
119a4e92590SAdrian Hunter {
120a4e92590SAdrian Hunter 	if (len < 4)
121a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
122a4e92590SAdrian Hunter 	packet->type = INTEL_PT_CBR;
1233b4fa67fSAdrian Hunter 	packet->payload = get_unaligned_le16(buf + 2);
124a4e92590SAdrian Hunter 	return 4;
125a4e92590SAdrian Hunter }
126a4e92590SAdrian Hunter 
intel_pt_get_vmcs(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)1273d498078SAdrian Hunter static int intel_pt_get_vmcs(const unsigned char *buf, size_t len,
1283d498078SAdrian Hunter 			     struct intel_pt_pkt *packet)
1293d498078SAdrian Hunter {
1301d2dbce9SAdrian Hunter 	if (len < 7)
1313d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
1323d498078SAdrian Hunter 
1333d498078SAdrian Hunter 	packet->type = INTEL_PT_VMCS;
1341d2dbce9SAdrian Hunter 	packet->count = 5;
1351d2dbce9SAdrian Hunter 	memcpy_le64(&packet->payload, buf + 2, 5);
1363d498078SAdrian Hunter 
1371d2dbce9SAdrian Hunter 	return 7;
1383d498078SAdrian Hunter }
1393d498078SAdrian Hunter 
intel_pt_get_ovf(struct intel_pt_pkt * packet)140a4e92590SAdrian Hunter static int intel_pt_get_ovf(struct intel_pt_pkt *packet)
141a4e92590SAdrian Hunter {
142a4e92590SAdrian Hunter 	packet->type = INTEL_PT_OVF;
143a4e92590SAdrian Hunter 	return 2;
144a4e92590SAdrian Hunter }
145a4e92590SAdrian Hunter 
intel_pt_get_psb(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)146a4e92590SAdrian Hunter static int intel_pt_get_psb(const unsigned char *buf, size_t len,
147a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
148a4e92590SAdrian Hunter {
149a4e92590SAdrian Hunter 	int i;
150a4e92590SAdrian Hunter 
151a4e92590SAdrian Hunter 	if (len < 16)
152a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
153a4e92590SAdrian Hunter 
154a4e92590SAdrian Hunter 	for (i = 2; i < 16; i += 2) {
155a4e92590SAdrian Hunter 		if (buf[i] != 2 || buf[i + 1] != 0x82)
156a4e92590SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
157a4e92590SAdrian Hunter 	}
158a4e92590SAdrian Hunter 
159a4e92590SAdrian Hunter 	packet->type = INTEL_PT_PSB;
160a4e92590SAdrian Hunter 	return 16;
161a4e92590SAdrian Hunter }
162a4e92590SAdrian Hunter 
intel_pt_get_psbend(struct intel_pt_pkt * packet)163a4e92590SAdrian Hunter static int intel_pt_get_psbend(struct intel_pt_pkt *packet)
164a4e92590SAdrian Hunter {
165a4e92590SAdrian Hunter 	packet->type = INTEL_PT_PSBEND;
166a4e92590SAdrian Hunter 	return 2;
167a4e92590SAdrian Hunter }
168a4e92590SAdrian Hunter 
intel_pt_get_tma(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)1693d498078SAdrian Hunter static int intel_pt_get_tma(const unsigned char *buf, size_t len,
1703d498078SAdrian Hunter 			    struct intel_pt_pkt *packet)
1713d498078SAdrian Hunter {
1723d498078SAdrian Hunter 	if (len < 7)
1733d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
1743d498078SAdrian Hunter 
1753d498078SAdrian Hunter 	packet->type = INTEL_PT_TMA;
1763d498078SAdrian Hunter 	packet->payload = buf[2] | (buf[3] << 8);
1773d498078SAdrian Hunter 	packet->count = buf[5] | ((buf[6] & BIT(0)) << 8);
1783d498078SAdrian Hunter 	return 7;
1793d498078SAdrian Hunter }
1803d498078SAdrian Hunter 
intel_pt_get_pad(struct intel_pt_pkt * packet)181a4e92590SAdrian Hunter static int intel_pt_get_pad(struct intel_pt_pkt *packet)
182a4e92590SAdrian Hunter {
183a4e92590SAdrian Hunter 	packet->type = INTEL_PT_PAD;
184a4e92590SAdrian Hunter 	return 1;
185a4e92590SAdrian Hunter }
186a4e92590SAdrian Hunter 
intel_pt_get_mnt(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)1873d498078SAdrian Hunter static int intel_pt_get_mnt(const unsigned char *buf, size_t len,
1883d498078SAdrian Hunter 			    struct intel_pt_pkt *packet)
1893d498078SAdrian Hunter {
1903d498078SAdrian Hunter 	if (len < 11)
1913d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
1923d498078SAdrian Hunter 	packet->type = INTEL_PT_MNT;
193*661ce781SAdrian Hunter 	packet->payload = get_unaligned_le64(buf + 3);
1946816c254SAdrian Hunter 	return 11;
1953d498078SAdrian Hunter }
1963d498078SAdrian Hunter 
intel_pt_get_3byte(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)1973d498078SAdrian Hunter static int intel_pt_get_3byte(const unsigned char *buf, size_t len,
1983d498078SAdrian Hunter 			      struct intel_pt_pkt *packet)
1993d498078SAdrian Hunter {
2003d498078SAdrian Hunter 	if (len < 3)
2013d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
2023d498078SAdrian Hunter 
2033d498078SAdrian Hunter 	switch (buf[2]) {
2043d498078SAdrian Hunter 	case 0x88: /* MNT */
2053d498078SAdrian Hunter 		return intel_pt_get_mnt(buf, len, packet);
2063d498078SAdrian Hunter 	default:
2073d498078SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
2083d498078SAdrian Hunter 	}
2093d498078SAdrian Hunter }
2103d498078SAdrian Hunter 
intel_pt_get_ptwrite(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)211a472e65fSAdrian Hunter static int intel_pt_get_ptwrite(const unsigned char *buf, size_t len,
212a472e65fSAdrian Hunter 				struct intel_pt_pkt *packet)
213a472e65fSAdrian Hunter {
214a472e65fSAdrian Hunter 	packet->count = (buf[1] >> 5) & 0x3;
215a472e65fSAdrian Hunter 	packet->type = buf[1] & BIT(7) ? INTEL_PT_PTWRITE_IP :
216a472e65fSAdrian Hunter 					 INTEL_PT_PTWRITE;
217a472e65fSAdrian Hunter 
218a472e65fSAdrian Hunter 	switch (packet->count) {
219a472e65fSAdrian Hunter 	case 0:
220a472e65fSAdrian Hunter 		if (len < 6)
221a472e65fSAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
2223b4fa67fSAdrian Hunter 		packet->payload = get_unaligned_le32(buf + 2);
223a472e65fSAdrian Hunter 		return 6;
224a472e65fSAdrian Hunter 	case 1:
225a472e65fSAdrian Hunter 		if (len < 10)
226a472e65fSAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
2273b4fa67fSAdrian Hunter 		packet->payload = get_unaligned_le64(buf + 2);
228a472e65fSAdrian Hunter 		return 10;
229a472e65fSAdrian Hunter 	default:
230a472e65fSAdrian Hunter 		return INTEL_PT_BAD_PACKET;
231a472e65fSAdrian Hunter 	}
232a472e65fSAdrian Hunter }
233a472e65fSAdrian Hunter 
intel_pt_get_exstop(struct intel_pt_pkt * packet)234a472e65fSAdrian Hunter static int intel_pt_get_exstop(struct intel_pt_pkt *packet)
235a472e65fSAdrian Hunter {
236a472e65fSAdrian Hunter 	packet->type = INTEL_PT_EXSTOP;
237a472e65fSAdrian Hunter 	return 2;
238a472e65fSAdrian Hunter }
239a472e65fSAdrian Hunter 
intel_pt_get_exstop_ip(struct intel_pt_pkt * packet)240a472e65fSAdrian Hunter static int intel_pt_get_exstop_ip(struct intel_pt_pkt *packet)
241a472e65fSAdrian Hunter {
242a472e65fSAdrian Hunter 	packet->type = INTEL_PT_EXSTOP_IP;
243a472e65fSAdrian Hunter 	return 2;
244a472e65fSAdrian Hunter }
245a472e65fSAdrian Hunter 
intel_pt_get_mwait(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)246a472e65fSAdrian Hunter static int intel_pt_get_mwait(const unsigned char *buf, size_t len,
247a472e65fSAdrian Hunter 			      struct intel_pt_pkt *packet)
248a472e65fSAdrian Hunter {
249a472e65fSAdrian Hunter 	if (len < 10)
250a472e65fSAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
251a472e65fSAdrian Hunter 	packet->type = INTEL_PT_MWAIT;
2523b4fa67fSAdrian Hunter 	packet->payload = get_unaligned_le64(buf + 2);
253a472e65fSAdrian Hunter 	return 10;
254a472e65fSAdrian Hunter }
255a472e65fSAdrian Hunter 
intel_pt_get_pwre(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)256a472e65fSAdrian Hunter static int intel_pt_get_pwre(const unsigned char *buf, size_t len,
257a472e65fSAdrian Hunter 			     struct intel_pt_pkt *packet)
258a472e65fSAdrian Hunter {
259a472e65fSAdrian Hunter 	if (len < 4)
260a472e65fSAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
261a472e65fSAdrian Hunter 	packet->type = INTEL_PT_PWRE;
262a472e65fSAdrian Hunter 	memcpy_le64(&packet->payload, buf + 2, 2);
263a472e65fSAdrian Hunter 	return 4;
264a472e65fSAdrian Hunter }
265a472e65fSAdrian Hunter 
intel_pt_get_pwrx(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)266a472e65fSAdrian Hunter static int intel_pt_get_pwrx(const unsigned char *buf, size_t len,
267a472e65fSAdrian Hunter 			     struct intel_pt_pkt *packet)
268a472e65fSAdrian Hunter {
269a472e65fSAdrian Hunter 	if (len < 7)
270a472e65fSAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
271a472e65fSAdrian Hunter 	packet->type = INTEL_PT_PWRX;
272a472e65fSAdrian Hunter 	memcpy_le64(&packet->payload, buf + 2, 5);
273a472e65fSAdrian Hunter 	return 7;
274a472e65fSAdrian Hunter }
275a472e65fSAdrian Hunter 
intel_pt_get_bbp(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)276edff7809SAdrian Hunter static int intel_pt_get_bbp(const unsigned char *buf, size_t len,
277edff7809SAdrian Hunter 			    struct intel_pt_pkt *packet)
278edff7809SAdrian Hunter {
279edff7809SAdrian Hunter 	if (len < 3)
280edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
281edff7809SAdrian Hunter 	packet->type = INTEL_PT_BBP;
282edff7809SAdrian Hunter 	packet->count = buf[2] >> 7;
283edff7809SAdrian Hunter 	packet->payload = buf[2] & 0x1f;
284edff7809SAdrian Hunter 	return 3;
285edff7809SAdrian Hunter }
286edff7809SAdrian Hunter 
intel_pt_get_bip_4(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)287edff7809SAdrian Hunter static int intel_pt_get_bip_4(const unsigned char *buf, size_t len,
288edff7809SAdrian Hunter 			      struct intel_pt_pkt *packet)
289edff7809SAdrian Hunter {
290edff7809SAdrian Hunter 	if (len < 5)
291edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
292edff7809SAdrian Hunter 	packet->type = INTEL_PT_BIP;
293edff7809SAdrian Hunter 	packet->count = buf[0] >> 3;
294edff7809SAdrian Hunter 	memcpy_le64(&packet->payload, buf + 1, 4);
295edff7809SAdrian Hunter 	return 5;
296edff7809SAdrian Hunter }
297edff7809SAdrian Hunter 
intel_pt_get_bip_8(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)298edff7809SAdrian Hunter static int intel_pt_get_bip_8(const unsigned char *buf, size_t len,
299edff7809SAdrian Hunter 			      struct intel_pt_pkt *packet)
300edff7809SAdrian Hunter {
301edff7809SAdrian Hunter 	if (len < 9)
302edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
303edff7809SAdrian Hunter 	packet->type = INTEL_PT_BIP;
304edff7809SAdrian Hunter 	packet->count = buf[0] >> 3;
305*661ce781SAdrian Hunter 	packet->payload = get_unaligned_le64(buf + 1);
306edff7809SAdrian Hunter 	return 9;
307edff7809SAdrian Hunter }
308edff7809SAdrian Hunter 
intel_pt_get_bep(size_t len,struct intel_pt_pkt * packet)309edff7809SAdrian Hunter static int intel_pt_get_bep(size_t len, struct intel_pt_pkt *packet)
310edff7809SAdrian Hunter {
311edff7809SAdrian Hunter 	if (len < 2)
312edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
313edff7809SAdrian Hunter 	packet->type = INTEL_PT_BEP;
314edff7809SAdrian Hunter 	return 2;
315edff7809SAdrian Hunter }
316edff7809SAdrian Hunter 
intel_pt_get_bep_ip(size_t len,struct intel_pt_pkt * packet)317edff7809SAdrian Hunter static int intel_pt_get_bep_ip(size_t len, struct intel_pt_pkt *packet)
318edff7809SAdrian Hunter {
319edff7809SAdrian Hunter 	if (len < 2)
320edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
321edff7809SAdrian Hunter 	packet->type = INTEL_PT_BEP_IP;
322edff7809SAdrian Hunter 	return 2;
323edff7809SAdrian Hunter }
324edff7809SAdrian Hunter 
intel_pt_get_cfe(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)3252750af50SAdrian Hunter static int intel_pt_get_cfe(const unsigned char *buf, size_t len,
3262750af50SAdrian Hunter 			    struct intel_pt_pkt *packet)
3272750af50SAdrian Hunter {
3282750af50SAdrian Hunter 	if (len < 4)
3292750af50SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
3302750af50SAdrian Hunter 	packet->type = buf[2] & 0x80 ? INTEL_PT_CFE_IP : INTEL_PT_CFE;
3312750af50SAdrian Hunter 	packet->count = buf[2] & 0x1f;
3322750af50SAdrian Hunter 	packet->payload = buf[3];
3332750af50SAdrian Hunter 	return 4;
3342750af50SAdrian Hunter }
3352750af50SAdrian Hunter 
intel_pt_get_evd(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)3362750af50SAdrian Hunter static int intel_pt_get_evd(const unsigned char *buf, size_t len,
3372750af50SAdrian Hunter 			    struct intel_pt_pkt *packet)
3382750af50SAdrian Hunter {
3392750af50SAdrian Hunter 	if (len < 11)
3402750af50SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
3412750af50SAdrian Hunter 	packet->type = INTEL_PT_EVD;
3422750af50SAdrian Hunter 	packet->count = buf[2] & 0x3f;
3432750af50SAdrian Hunter 	packet->payload = buf[3];
344*661ce781SAdrian Hunter 	packet->payload = get_unaligned_le64(buf + 3);
3452750af50SAdrian Hunter 	return 11;
3462750af50SAdrian Hunter }
3472750af50SAdrian Hunter 
intel_pt_get_ext(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)348a4e92590SAdrian Hunter static int intel_pt_get_ext(const unsigned char *buf, size_t len,
349a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
350a4e92590SAdrian Hunter {
351a4e92590SAdrian Hunter 	if (len < 2)
352a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
353a4e92590SAdrian Hunter 
354a472e65fSAdrian Hunter 	if ((buf[1] & 0x1f) == 0x12)
355a472e65fSAdrian Hunter 		return intel_pt_get_ptwrite(buf, len, packet);
356a472e65fSAdrian Hunter 
357a4e92590SAdrian Hunter 	switch (buf[1]) {
358a4e92590SAdrian Hunter 	case 0xa3: /* Long TNT */
359a4e92590SAdrian Hunter 		return intel_pt_get_long_tnt(buf, len, packet);
360a4e92590SAdrian Hunter 	case 0x43: /* PIP */
361a4e92590SAdrian Hunter 		return intel_pt_get_pip(buf, len, packet);
3623d498078SAdrian Hunter 	case 0x83: /* TraceStop */
3633d498078SAdrian Hunter 		return intel_pt_get_tracestop(packet);
364a4e92590SAdrian Hunter 	case 0x03: /* CBR */
365a4e92590SAdrian Hunter 		return intel_pt_get_cbr(buf, len, packet);
3663d498078SAdrian Hunter 	case 0xc8: /* VMCS */
3673d498078SAdrian Hunter 		return intel_pt_get_vmcs(buf, len, packet);
368a4e92590SAdrian Hunter 	case 0xf3: /* OVF */
369a4e92590SAdrian Hunter 		return intel_pt_get_ovf(packet);
370a4e92590SAdrian Hunter 	case 0x82: /* PSB */
371a4e92590SAdrian Hunter 		return intel_pt_get_psb(buf, len, packet);
372a4e92590SAdrian Hunter 	case 0x23: /* PSBEND */
373a4e92590SAdrian Hunter 		return intel_pt_get_psbend(packet);
3743d498078SAdrian Hunter 	case 0x73: /* TMA */
3753d498078SAdrian Hunter 		return intel_pt_get_tma(buf, len, packet);
3763d498078SAdrian Hunter 	case 0xC3: /* 3-byte header */
3773d498078SAdrian Hunter 		return intel_pt_get_3byte(buf, len, packet);
378a472e65fSAdrian Hunter 	case 0x62: /* EXSTOP no IP */
379a472e65fSAdrian Hunter 		return intel_pt_get_exstop(packet);
380a472e65fSAdrian Hunter 	case 0xE2: /* EXSTOP with IP */
381a472e65fSAdrian Hunter 		return intel_pt_get_exstop_ip(packet);
382a472e65fSAdrian Hunter 	case 0xC2: /* MWAIT */
383a472e65fSAdrian Hunter 		return intel_pt_get_mwait(buf, len, packet);
384a472e65fSAdrian Hunter 	case 0x22: /* PWRE */
385a472e65fSAdrian Hunter 		return intel_pt_get_pwre(buf, len, packet);
386a472e65fSAdrian Hunter 	case 0xA2: /* PWRX */
387a472e65fSAdrian Hunter 		return intel_pt_get_pwrx(buf, len, packet);
388edff7809SAdrian Hunter 	case 0x63: /* BBP */
389edff7809SAdrian Hunter 		return intel_pt_get_bbp(buf, len, packet);
390edff7809SAdrian Hunter 	case 0x33: /* BEP no IP */
391edff7809SAdrian Hunter 		return intel_pt_get_bep(len, packet);
392edff7809SAdrian Hunter 	case 0xb3: /* BEP with IP */
393edff7809SAdrian Hunter 		return intel_pt_get_bep_ip(len, packet);
3942750af50SAdrian Hunter 	case 0x13: /* CFE */
3952750af50SAdrian Hunter 		return intel_pt_get_cfe(buf, len, packet);
3962750af50SAdrian Hunter 	case 0x53: /* EVD */
3972750af50SAdrian Hunter 		return intel_pt_get_evd(buf, len, packet);
398a4e92590SAdrian Hunter 	default:
399a4e92590SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
400a4e92590SAdrian Hunter 	}
401a4e92590SAdrian Hunter }
402a4e92590SAdrian Hunter 
intel_pt_get_short_tnt(unsigned int byte,struct intel_pt_pkt * packet)403a4e92590SAdrian Hunter static int intel_pt_get_short_tnt(unsigned int byte,
404a4e92590SAdrian Hunter 				  struct intel_pt_pkt *packet)
405a4e92590SAdrian Hunter {
406a4e92590SAdrian Hunter 	int count;
407a4e92590SAdrian Hunter 
408a4e92590SAdrian Hunter 	for (count = 6; count; count--) {
409a4e92590SAdrian Hunter 		if (byte & BIT(7))
410a4e92590SAdrian Hunter 			break;
411a4e92590SAdrian Hunter 		byte <<= 1;
412a4e92590SAdrian Hunter 	}
413a4e92590SAdrian Hunter 
414a4e92590SAdrian Hunter 	packet->type = INTEL_PT_TNT;
415a4e92590SAdrian Hunter 	packet->count = count;
416a4e92590SAdrian Hunter 	packet->payload = (uint64_t)byte << 57;
417a4e92590SAdrian Hunter 
418a4e92590SAdrian Hunter 	return 1;
419a4e92590SAdrian Hunter }
420a4e92590SAdrian Hunter 
intel_pt_get_cyc(unsigned int byte,const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)4213d498078SAdrian Hunter static int intel_pt_get_cyc(unsigned int byte, const unsigned char *buf,
4223d498078SAdrian Hunter 			    size_t len, struct intel_pt_pkt *packet)
4233d498078SAdrian Hunter {
4243d498078SAdrian Hunter 	unsigned int offs = 1, shift;
4253d498078SAdrian Hunter 	uint64_t payload = byte >> 3;
4263d498078SAdrian Hunter 
4273d498078SAdrian Hunter 	byte >>= 2;
4283d498078SAdrian Hunter 	len -= 1;
4293d498078SAdrian Hunter 	for (shift = 5; byte & 1; shift += 7) {
4303d498078SAdrian Hunter 		if (offs > 9)
4313d498078SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
4323d498078SAdrian Hunter 		if (len < offs)
4333d498078SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
4343d498078SAdrian Hunter 		byte = buf[offs++];
435621a5a32SAdrian Hunter 		payload |= ((uint64_t)byte >> 1) << shift;
4363d498078SAdrian Hunter 	}
4373d498078SAdrian Hunter 
4383d498078SAdrian Hunter 	packet->type = INTEL_PT_CYC;
4393d498078SAdrian Hunter 	packet->payload = payload;
4403d498078SAdrian Hunter 	return offs;
4413d498078SAdrian Hunter }
4423d498078SAdrian Hunter 
intel_pt_get_ip(enum intel_pt_pkt_type type,unsigned int byte,const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)443a4e92590SAdrian Hunter static int intel_pt_get_ip(enum intel_pt_pkt_type type, unsigned int byte,
444a4e92590SAdrian Hunter 			   const unsigned char *buf, size_t len,
445a4e92590SAdrian Hunter 			   struct intel_pt_pkt *packet)
446a4e92590SAdrian Hunter {
447e1717e04SAdrian Hunter 	int ip_len;
448e1717e04SAdrian Hunter 
449e1717e04SAdrian Hunter 	packet->count = byte >> 5;
450e1717e04SAdrian Hunter 
451e1717e04SAdrian Hunter 	switch (packet->count) {
452a4e92590SAdrian Hunter 	case 0:
453e1717e04SAdrian Hunter 		ip_len = 0;
454a4e92590SAdrian Hunter 		break;
455a4e92590SAdrian Hunter 	case 1:
456a4e92590SAdrian Hunter 		if (len < 3)
457a4e92590SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
458e1717e04SAdrian Hunter 		ip_len = 2;
4593b4fa67fSAdrian Hunter 		packet->payload = get_unaligned_le16(buf + 1);
460a4e92590SAdrian Hunter 		break;
461a4e92590SAdrian Hunter 	case 2:
462a4e92590SAdrian Hunter 		if (len < 5)
463a4e92590SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
464e1717e04SAdrian Hunter 		ip_len = 4;
4653b4fa67fSAdrian Hunter 		packet->payload = get_unaligned_le32(buf + 1);
466a4e92590SAdrian Hunter 		break;
467a4e92590SAdrian Hunter 	case 3:
468e1717e04SAdrian Hunter 	case 4:
469a4e92590SAdrian Hunter 		if (len < 7)
470a4e92590SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
471e1717e04SAdrian Hunter 		ip_len = 6;
472a4e92590SAdrian Hunter 		memcpy_le64(&packet->payload, buf + 1, 6);
473a4e92590SAdrian Hunter 		break;
474e1717e04SAdrian Hunter 	case 6:
475e1717e04SAdrian Hunter 		if (len < 9)
476e1717e04SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
477e1717e04SAdrian Hunter 		ip_len = 8;
4783b4fa67fSAdrian Hunter 		packet->payload = get_unaligned_le64(buf + 1);
479e1717e04SAdrian Hunter 		break;
480a4e92590SAdrian Hunter 	default:
481a4e92590SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
482a4e92590SAdrian Hunter 	}
483a4e92590SAdrian Hunter 
484a4e92590SAdrian Hunter 	packet->type = type;
485a4e92590SAdrian Hunter 
486e1717e04SAdrian Hunter 	return ip_len + 1;
487a4e92590SAdrian Hunter }
488a4e92590SAdrian Hunter 
intel_pt_get_mode(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)489a4e92590SAdrian Hunter static int intel_pt_get_mode(const unsigned char *buf, size_t len,
490a4e92590SAdrian Hunter 			     struct intel_pt_pkt *packet)
491a4e92590SAdrian Hunter {
492a4e92590SAdrian Hunter 	if (len < 2)
493a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
494a4e92590SAdrian Hunter 
495a4e92590SAdrian Hunter 	switch (buf[1] >> 5) {
496a4e92590SAdrian Hunter 	case 0:
497a4e92590SAdrian Hunter 		packet->type = INTEL_PT_MODE_EXEC;
498f7934477SAdrian Hunter 		packet->count = buf[1];
499a4e92590SAdrian Hunter 		switch (buf[1] & 3) {
500a4e92590SAdrian Hunter 		case 0:
501a4e92590SAdrian Hunter 			packet->payload = 16;
502a4e92590SAdrian Hunter 			break;
503a4e92590SAdrian Hunter 		case 1:
504a4e92590SAdrian Hunter 			packet->payload = 64;
505a4e92590SAdrian Hunter 			break;
506a4e92590SAdrian Hunter 		case 2:
507a4e92590SAdrian Hunter 			packet->payload = 32;
508a4e92590SAdrian Hunter 			break;
509a4e92590SAdrian Hunter 		default:
510a4e92590SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
511a4e92590SAdrian Hunter 		}
512a4e92590SAdrian Hunter 		break;
513a4e92590SAdrian Hunter 	case 1:
514a4e92590SAdrian Hunter 		packet->type = INTEL_PT_MODE_TSX;
515a4e92590SAdrian Hunter 		if ((buf[1] & 3) == 3)
516a4e92590SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
517a4e92590SAdrian Hunter 		packet->payload = buf[1] & 3;
518a4e92590SAdrian Hunter 		break;
519a4e92590SAdrian Hunter 	default:
520a4e92590SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
521a4e92590SAdrian Hunter 	}
522a4e92590SAdrian Hunter 
523a4e92590SAdrian Hunter 	return 2;
524a4e92590SAdrian Hunter }
525a4e92590SAdrian Hunter 
intel_pt_get_tsc(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)526a4e92590SAdrian Hunter static int intel_pt_get_tsc(const unsigned char *buf, size_t len,
527a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
528a4e92590SAdrian Hunter {
529a4e92590SAdrian Hunter 	if (len < 8)
530a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
531a4e92590SAdrian Hunter 	packet->type = INTEL_PT_TSC;
532a4e92590SAdrian Hunter 	memcpy_le64(&packet->payload, buf + 1, 7);
533a4e92590SAdrian Hunter 	return 8;
534a4e92590SAdrian Hunter }
535a4e92590SAdrian Hunter 
intel_pt_get_mtc(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)5363d498078SAdrian Hunter static int intel_pt_get_mtc(const unsigned char *buf, size_t len,
5373d498078SAdrian Hunter 			    struct intel_pt_pkt *packet)
5383d498078SAdrian Hunter {
5393d498078SAdrian Hunter 	if (len < 2)
5403d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
5413d498078SAdrian Hunter 	packet->type = INTEL_PT_MTC;
5423d498078SAdrian Hunter 	packet->payload = buf[1];
5433d498078SAdrian Hunter 	return 2;
5443d498078SAdrian Hunter }
5453d498078SAdrian Hunter 
intel_pt_do_get_packet(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet,enum intel_pt_pkt_ctx ctx)546a4e92590SAdrian Hunter static int intel_pt_do_get_packet(const unsigned char *buf, size_t len,
547edff7809SAdrian Hunter 				  struct intel_pt_pkt *packet,
548edff7809SAdrian Hunter 				  enum intel_pt_pkt_ctx ctx)
549a4e92590SAdrian Hunter {
550a4e92590SAdrian Hunter 	unsigned int byte;
551a4e92590SAdrian Hunter 
552a4e92590SAdrian Hunter 	memset(packet, 0, sizeof(struct intel_pt_pkt));
553a4e92590SAdrian Hunter 
554a4e92590SAdrian Hunter 	if (!len)
555a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
556a4e92590SAdrian Hunter 
557a4e92590SAdrian Hunter 	byte = buf[0];
558edff7809SAdrian Hunter 
559edff7809SAdrian Hunter 	switch (ctx) {
560edff7809SAdrian Hunter 	case INTEL_PT_NO_CTX:
561edff7809SAdrian Hunter 		break;
562edff7809SAdrian Hunter 	case INTEL_PT_BLK_4_CTX:
563edff7809SAdrian Hunter 		if ((byte & 0x7) == 4)
564edff7809SAdrian Hunter 			return intel_pt_get_bip_4(buf, len, packet);
565edff7809SAdrian Hunter 		break;
566edff7809SAdrian Hunter 	case INTEL_PT_BLK_8_CTX:
567edff7809SAdrian Hunter 		if ((byte & 0x7) == 4)
568edff7809SAdrian Hunter 			return intel_pt_get_bip_8(buf, len, packet);
569edff7809SAdrian Hunter 		break;
570edff7809SAdrian Hunter 	default:
571edff7809SAdrian Hunter 		break;
5728284bbeaSZou Wei 	}
573edff7809SAdrian Hunter 
574a4e92590SAdrian Hunter 	if (!(byte & BIT(0))) {
575a4e92590SAdrian Hunter 		if (byte == 0)
576a4e92590SAdrian Hunter 			return intel_pt_get_pad(packet);
577a4e92590SAdrian Hunter 		if (byte == 2)
578a4e92590SAdrian Hunter 			return intel_pt_get_ext(buf, len, packet);
579a4e92590SAdrian Hunter 		return intel_pt_get_short_tnt(byte, packet);
580a4e92590SAdrian Hunter 	}
581a4e92590SAdrian Hunter 
5823d498078SAdrian Hunter 	if ((byte & 2))
5833d498078SAdrian Hunter 		return intel_pt_get_cyc(byte, buf, len, packet);
5843d498078SAdrian Hunter 
585a4e92590SAdrian Hunter 	switch (byte & 0x1f) {
586a4e92590SAdrian Hunter 	case 0x0D:
587a4e92590SAdrian Hunter 		return intel_pt_get_ip(INTEL_PT_TIP, byte, buf, len, packet);
588a4e92590SAdrian Hunter 	case 0x11:
589a4e92590SAdrian Hunter 		return intel_pt_get_ip(INTEL_PT_TIP_PGE, byte, buf, len,
590a4e92590SAdrian Hunter 				       packet);
591a4e92590SAdrian Hunter 	case 0x01:
592a4e92590SAdrian Hunter 		return intel_pt_get_ip(INTEL_PT_TIP_PGD, byte, buf, len,
593a4e92590SAdrian Hunter 				       packet);
594a4e92590SAdrian Hunter 	case 0x1D:
595a4e92590SAdrian Hunter 		return intel_pt_get_ip(INTEL_PT_FUP, byte, buf, len, packet);
596a4e92590SAdrian Hunter 	case 0x19:
597a4e92590SAdrian Hunter 		switch (byte) {
598a4e92590SAdrian Hunter 		case 0x99:
599a4e92590SAdrian Hunter 			return intel_pt_get_mode(buf, len, packet);
600a4e92590SAdrian Hunter 		case 0x19:
601a4e92590SAdrian Hunter 			return intel_pt_get_tsc(buf, len, packet);
6023d498078SAdrian Hunter 		case 0x59:
6033d498078SAdrian Hunter 			return intel_pt_get_mtc(buf, len, packet);
604a4e92590SAdrian Hunter 		default:
605a4e92590SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
606a4e92590SAdrian Hunter 		}
607a4e92590SAdrian Hunter 	default:
608a4e92590SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
609a4e92590SAdrian Hunter 	}
610a4e92590SAdrian Hunter }
611a4e92590SAdrian Hunter 
intel_pt_upd_pkt_ctx(const struct intel_pt_pkt * packet,enum intel_pt_pkt_ctx * ctx)612edff7809SAdrian Hunter void intel_pt_upd_pkt_ctx(const struct intel_pt_pkt *packet,
613edff7809SAdrian Hunter 			  enum intel_pt_pkt_ctx *ctx)
614edff7809SAdrian Hunter {
615edff7809SAdrian Hunter 	switch (packet->type) {
616edff7809SAdrian Hunter 	case INTEL_PT_BAD:
617edff7809SAdrian Hunter 	case INTEL_PT_PAD:
618edff7809SAdrian Hunter 	case INTEL_PT_TSC:
619edff7809SAdrian Hunter 	case INTEL_PT_TMA:
620edff7809SAdrian Hunter 	case INTEL_PT_MTC:
621edff7809SAdrian Hunter 	case INTEL_PT_FUP:
622edff7809SAdrian Hunter 	case INTEL_PT_CYC:
623edff7809SAdrian Hunter 	case INTEL_PT_CBR:
624edff7809SAdrian Hunter 	case INTEL_PT_MNT:
625edff7809SAdrian Hunter 	case INTEL_PT_EXSTOP:
626edff7809SAdrian Hunter 	case INTEL_PT_EXSTOP_IP:
627edff7809SAdrian Hunter 	case INTEL_PT_PWRE:
628edff7809SAdrian Hunter 	case INTEL_PT_PWRX:
629edff7809SAdrian Hunter 	case INTEL_PT_BIP:
630edff7809SAdrian Hunter 		break;
631edff7809SAdrian Hunter 	case INTEL_PT_TNT:
632edff7809SAdrian Hunter 	case INTEL_PT_TIP:
633edff7809SAdrian Hunter 	case INTEL_PT_TIP_PGD:
634edff7809SAdrian Hunter 	case INTEL_PT_TIP_PGE:
635edff7809SAdrian Hunter 	case INTEL_PT_MODE_EXEC:
636edff7809SAdrian Hunter 	case INTEL_PT_MODE_TSX:
637edff7809SAdrian Hunter 	case INTEL_PT_PIP:
638edff7809SAdrian Hunter 	case INTEL_PT_OVF:
639edff7809SAdrian Hunter 	case INTEL_PT_VMCS:
640edff7809SAdrian Hunter 	case INTEL_PT_TRACESTOP:
641edff7809SAdrian Hunter 	case INTEL_PT_PSB:
642edff7809SAdrian Hunter 	case INTEL_PT_PSBEND:
643edff7809SAdrian Hunter 	case INTEL_PT_PTWRITE:
644edff7809SAdrian Hunter 	case INTEL_PT_PTWRITE_IP:
645edff7809SAdrian Hunter 	case INTEL_PT_MWAIT:
646edff7809SAdrian Hunter 	case INTEL_PT_BEP:
647edff7809SAdrian Hunter 	case INTEL_PT_BEP_IP:
6482750af50SAdrian Hunter 	case INTEL_PT_CFE:
6492750af50SAdrian Hunter 	case INTEL_PT_CFE_IP:
6502750af50SAdrian Hunter 	case INTEL_PT_EVD:
651edff7809SAdrian Hunter 		*ctx = INTEL_PT_NO_CTX;
652edff7809SAdrian Hunter 		break;
653edff7809SAdrian Hunter 	case INTEL_PT_BBP:
654edff7809SAdrian Hunter 		if (packet->count)
655edff7809SAdrian Hunter 			*ctx = INTEL_PT_BLK_4_CTX;
656edff7809SAdrian Hunter 		else
657edff7809SAdrian Hunter 			*ctx = INTEL_PT_BLK_8_CTX;
658edff7809SAdrian Hunter 		break;
659edff7809SAdrian Hunter 	default:
660edff7809SAdrian Hunter 		break;
661edff7809SAdrian Hunter 	}
662edff7809SAdrian Hunter }
663edff7809SAdrian Hunter 
intel_pt_get_packet(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet,enum intel_pt_pkt_ctx * ctx)664a4e92590SAdrian Hunter int intel_pt_get_packet(const unsigned char *buf, size_t len,
665edff7809SAdrian Hunter 			struct intel_pt_pkt *packet, enum intel_pt_pkt_ctx *ctx)
666a4e92590SAdrian Hunter {
667a4e92590SAdrian Hunter 	int ret;
668a4e92590SAdrian Hunter 
669edff7809SAdrian Hunter 	ret = intel_pt_do_get_packet(buf, len, packet, *ctx);
670a4e92590SAdrian Hunter 	if (ret > 0) {
671a4e92590SAdrian Hunter 		while (ret < 8 && len > (size_t)ret && !buf[ret])
672a4e92590SAdrian Hunter 			ret += 1;
673edff7809SAdrian Hunter 		intel_pt_upd_pkt_ctx(packet, ctx);
674a4e92590SAdrian Hunter 	}
675a4e92590SAdrian Hunter 	return ret;
676a4e92590SAdrian Hunter }
677a4e92590SAdrian Hunter 
intel_pt_pkt_desc(const struct intel_pt_pkt * packet,char * buf,size_t buf_len)678a4e92590SAdrian Hunter int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf,
679a4e92590SAdrian Hunter 		      size_t buf_len)
680a4e92590SAdrian Hunter {
6813d498078SAdrian Hunter 	int ret, i, nr;
682a4e92590SAdrian Hunter 	unsigned long long payload = packet->payload;
683a4e92590SAdrian Hunter 	const char *name = intel_pt_pkt_name(packet->type);
684a4e92590SAdrian Hunter 
685a4e92590SAdrian Hunter 	switch (packet->type) {
686a4e92590SAdrian Hunter 	case INTEL_PT_BAD:
687a4e92590SAdrian Hunter 	case INTEL_PT_PAD:
688a4e92590SAdrian Hunter 	case INTEL_PT_PSB:
689a4e92590SAdrian Hunter 	case INTEL_PT_PSBEND:
6903d498078SAdrian Hunter 	case INTEL_PT_TRACESTOP:
691a4e92590SAdrian Hunter 	case INTEL_PT_OVF:
692a4e92590SAdrian Hunter 		return snprintf(buf, buf_len, "%s", name);
693a4e92590SAdrian Hunter 	case INTEL_PT_TNT: {
694a4e92590SAdrian Hunter 		size_t blen = buf_len;
695a4e92590SAdrian Hunter 
696a4e92590SAdrian Hunter 		ret = snprintf(buf, blen, "%s ", name);
697a4e92590SAdrian Hunter 		if (ret < 0)
698a4e92590SAdrian Hunter 			return ret;
699a4e92590SAdrian Hunter 		buf += ret;
700a4e92590SAdrian Hunter 		blen -= ret;
701a4e92590SAdrian Hunter 		for (i = 0; i < packet->count; i++) {
702a4e92590SAdrian Hunter 			if (payload & BIT63)
703a4e92590SAdrian Hunter 				ret = snprintf(buf, blen, "T");
704a4e92590SAdrian Hunter 			else
705a4e92590SAdrian Hunter 				ret = snprintf(buf, blen, "N");
706a4e92590SAdrian Hunter 			if (ret < 0)
707a4e92590SAdrian Hunter 				return ret;
708a4e92590SAdrian Hunter 			buf += ret;
709a4e92590SAdrian Hunter 			blen -= ret;
710a4e92590SAdrian Hunter 			payload <<= 1;
711a4e92590SAdrian Hunter 		}
712a4e92590SAdrian Hunter 		ret = snprintf(buf, blen, " (%d)", packet->count);
713a4e92590SAdrian Hunter 		if (ret < 0)
714a4e92590SAdrian Hunter 			return ret;
715a4e92590SAdrian Hunter 		blen -= ret;
716a4e92590SAdrian Hunter 		return buf_len - blen;
717a4e92590SAdrian Hunter 	}
718a4e92590SAdrian Hunter 	case INTEL_PT_TIP_PGD:
719a4e92590SAdrian Hunter 	case INTEL_PT_TIP_PGE:
720a4e92590SAdrian Hunter 	case INTEL_PT_TIP:
721a4e92590SAdrian Hunter 	case INTEL_PT_FUP:
722a4e92590SAdrian Hunter 		if (!(packet->count))
723a4e92590SAdrian Hunter 			return snprintf(buf, buf_len, "%s no ip", name);
724f7a858bfSLiam Howlett 		fallthrough;
7253d498078SAdrian Hunter 	case INTEL_PT_CYC:
7263d498078SAdrian Hunter 	case INTEL_PT_VMCS:
7273d498078SAdrian Hunter 	case INTEL_PT_MTC:
7283d498078SAdrian Hunter 	case INTEL_PT_MNT:
729a4e92590SAdrian Hunter 	case INTEL_PT_CBR:
730a4e92590SAdrian Hunter 	case INTEL_PT_TSC:
7313d498078SAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx", name, payload);
7323d498078SAdrian Hunter 	case INTEL_PT_TMA:
7333d498078SAdrian Hunter 		return snprintf(buf, buf_len, "%s CTC 0x%x FC 0x%x", name,
7343d498078SAdrian Hunter 				(unsigned)payload, packet->count);
735a4e92590SAdrian Hunter 	case INTEL_PT_MODE_EXEC:
736f7934477SAdrian Hunter 		return snprintf(buf, buf_len, "%s IF:%d %lld",
737f7934477SAdrian Hunter 				name, !!(packet->count & 4), payload);
738a4e92590SAdrian Hunter 	case INTEL_PT_MODE_TSX:
739a4e92590SAdrian Hunter 		return snprintf(buf, buf_len, "%s TXAbort:%u InTX:%u",
740a4e92590SAdrian Hunter 				name, (unsigned)(payload >> 1) & 1,
741a4e92590SAdrian Hunter 				(unsigned)payload & 1);
742a4e92590SAdrian Hunter 	case INTEL_PT_PIP:
74390af7555SAdrian Hunter 		nr = packet->payload & INTEL_PT_VMX_NR_FLAG ? 1 : 0;
74490af7555SAdrian Hunter 		payload &= ~INTEL_PT_VMX_NR_FLAG;
7453d498078SAdrian Hunter 		ret = snprintf(buf, buf_len, "%s 0x%llx (NR=%d)",
74690af7555SAdrian Hunter 			       name, payload >> 1, nr);
747a4e92590SAdrian Hunter 		return ret;
748a472e65fSAdrian Hunter 	case INTEL_PT_PTWRITE:
749a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx IP:0", name, payload);
750a472e65fSAdrian Hunter 	case INTEL_PT_PTWRITE_IP:
751a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx IP:1", name, payload);
752edff7809SAdrian Hunter 	case INTEL_PT_BEP:
753a472e65fSAdrian Hunter 	case INTEL_PT_EXSTOP:
754a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s IP:0", name);
755edff7809SAdrian Hunter 	case INTEL_PT_BEP_IP:
756a472e65fSAdrian Hunter 	case INTEL_PT_EXSTOP_IP:
757a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s IP:1", name);
758a472e65fSAdrian Hunter 	case INTEL_PT_MWAIT:
759a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx Hints 0x%x Extensions 0x%x",
760a472e65fSAdrian Hunter 				name, payload, (unsigned int)(payload & 0xff),
761a472e65fSAdrian Hunter 				(unsigned int)((payload >> 32) & 0x3));
762a472e65fSAdrian Hunter 	case INTEL_PT_PWRE:
763a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx HW:%u CState:%u Sub-CState:%u",
764a472e65fSAdrian Hunter 				name, payload, !!(payload & 0x80),
765a472e65fSAdrian Hunter 				(unsigned int)((payload >> 12) & 0xf),
766a472e65fSAdrian Hunter 				(unsigned int)((payload >> 8) & 0xf));
767a472e65fSAdrian Hunter 	case INTEL_PT_PWRX:
768a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx Last CState:%u Deepest CState:%u Wake Reason 0x%x",
769a472e65fSAdrian Hunter 				name, payload,
770a472e65fSAdrian Hunter 				(unsigned int)((payload >> 4) & 0xf),
771a472e65fSAdrian Hunter 				(unsigned int)(payload & 0xf),
772a472e65fSAdrian Hunter 				(unsigned int)((payload >> 8) & 0xf));
773edff7809SAdrian Hunter 	case INTEL_PT_BBP:
774edff7809SAdrian Hunter 		return snprintf(buf, buf_len, "%s SZ %s-byte Type 0x%llx",
775edff7809SAdrian Hunter 				name, packet->count ? "4" : "8", payload);
776edff7809SAdrian Hunter 	case INTEL_PT_BIP:
777edff7809SAdrian Hunter 		return snprintf(buf, buf_len, "%s ID 0x%02x Value 0x%llx",
778edff7809SAdrian Hunter 				name, packet->count, payload);
7792750af50SAdrian Hunter 	case INTEL_PT_CFE:
7802750af50SAdrian Hunter 	case INTEL_PT_CFE_IP:
7812750af50SAdrian Hunter 		return snprintf(buf, buf_len, "%s IP:%d Type 0x%02x Vector 0x%llx",
7822750af50SAdrian Hunter 				name, packet->type == INTEL_PT_CFE_IP, packet->count, payload);
7832750af50SAdrian Hunter 	case INTEL_PT_EVD:
7842750af50SAdrian Hunter 		return snprintf(buf, buf_len, "%s Type 0x%02x Payload 0x%llx",
7852750af50SAdrian Hunter 				name, packet->count, payload);
786a4e92590SAdrian Hunter 	default:
787a4e92590SAdrian Hunter 		break;
788a4e92590SAdrian Hunter 	}
789a4e92590SAdrian Hunter 	return snprintf(buf, buf_len, "%s 0x%llx (%d)",
790a4e92590SAdrian Hunter 			name, payload, packet->count);
791a4e92590SAdrian Hunter }
792