xref: /openbmc/linux/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
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 
194e88118cSIlya Leoshkevich #if __BYTE_ORDER__ == __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",
672750af50SAdrian Hunter 	[INTEL_PT_CFE]		= "CFE",
682750af50SAdrian Hunter 	[INTEL_PT_CFE_IP]	= "CFE",
692750af50SAdrian Hunter 	[INTEL_PT_EVD]		= "EVD",
70a4e92590SAdrian Hunter };
71a4e92590SAdrian Hunter 
intel_pt_pkt_name(enum intel_pt_pkt_type type)72a4e92590SAdrian Hunter const char *intel_pt_pkt_name(enum intel_pt_pkt_type type)
73a4e92590SAdrian Hunter {
74a4e92590SAdrian Hunter 	return packet_name[type];
75a4e92590SAdrian Hunter }
76a4e92590SAdrian Hunter 
intel_pt_get_long_tnt(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)77a4e92590SAdrian Hunter static int intel_pt_get_long_tnt(const unsigned char *buf, size_t len,
78a4e92590SAdrian Hunter 				 struct intel_pt_pkt *packet)
79a4e92590SAdrian Hunter {
80a4e92590SAdrian Hunter 	uint64_t payload;
81a4e92590SAdrian Hunter 	int count;
82a4e92590SAdrian Hunter 
83a4e92590SAdrian Hunter 	if (len < 8)
84a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
85a4e92590SAdrian Hunter 
86a4e92590SAdrian Hunter 	payload = le64_to_cpu(*(uint64_t *)buf);
87a4e92590SAdrian Hunter 
88a4e92590SAdrian Hunter 	for (count = 47; count; count--) {
89a4e92590SAdrian Hunter 		if (payload & BIT63)
90a4e92590SAdrian Hunter 			break;
91a4e92590SAdrian Hunter 		payload <<= 1;
92a4e92590SAdrian Hunter 	}
93a4e92590SAdrian Hunter 
94a4e92590SAdrian Hunter 	packet->type = INTEL_PT_TNT;
95a4e92590SAdrian Hunter 	packet->count = count;
96a4e92590SAdrian Hunter 	packet->payload = payload << 1;
97a4e92590SAdrian Hunter 	return 8;
98a4e92590SAdrian Hunter }
99a4e92590SAdrian Hunter 
intel_pt_get_pip(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)100a4e92590SAdrian Hunter static int intel_pt_get_pip(const unsigned char *buf, size_t len,
101a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
102a4e92590SAdrian Hunter {
103a4e92590SAdrian Hunter 	uint64_t payload = 0;
104a4e92590SAdrian Hunter 
105a4e92590SAdrian Hunter 	if (len < 8)
106a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
107a4e92590SAdrian Hunter 
108a4e92590SAdrian Hunter 	packet->type = INTEL_PT_PIP;
109a4e92590SAdrian Hunter 	memcpy_le64(&payload, buf + 2, 6);
11090af7555SAdrian Hunter 	packet->payload = payload;
111a4e92590SAdrian Hunter 
112a4e92590SAdrian Hunter 	return 8;
113a4e92590SAdrian Hunter }
114a4e92590SAdrian Hunter 
intel_pt_get_tracestop(struct intel_pt_pkt * packet)1153d498078SAdrian Hunter static int intel_pt_get_tracestop(struct intel_pt_pkt *packet)
1163d498078SAdrian Hunter {
1173d498078SAdrian Hunter 	packet->type = INTEL_PT_TRACESTOP;
1183d498078SAdrian Hunter 	return 2;
1193d498078SAdrian Hunter }
1203d498078SAdrian Hunter 
intel_pt_get_cbr(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)121a4e92590SAdrian Hunter static int intel_pt_get_cbr(const unsigned char *buf, size_t len,
122a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
123a4e92590SAdrian Hunter {
124a4e92590SAdrian Hunter 	if (len < 4)
125a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
126a4e92590SAdrian Hunter 	packet->type = INTEL_PT_CBR;
12726fb2fb1SAdrian Hunter 	packet->payload = le16_to_cpu(*(uint16_t *)(buf + 2));
128a4e92590SAdrian Hunter 	return 4;
129a4e92590SAdrian Hunter }
130a4e92590SAdrian Hunter 
intel_pt_get_vmcs(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)1313d498078SAdrian Hunter static int intel_pt_get_vmcs(const unsigned char *buf, size_t len,
1323d498078SAdrian Hunter 			     struct intel_pt_pkt *packet)
1333d498078SAdrian Hunter {
1343d498078SAdrian Hunter 	unsigned int count = (52 - 5) >> 3;
1353d498078SAdrian Hunter 
1363d498078SAdrian Hunter 	if (count < 1 || count > 7)
1373d498078SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
1383d498078SAdrian Hunter 
1393d498078SAdrian Hunter 	if (len < count + 2)
1403d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
1413d498078SAdrian Hunter 
1423d498078SAdrian Hunter 	packet->type = INTEL_PT_VMCS;
1433d498078SAdrian Hunter 	packet->count = count;
1443d498078SAdrian Hunter 	memcpy_le64(&packet->payload, buf + 2, count);
1453d498078SAdrian Hunter 
1463d498078SAdrian Hunter 	return count + 2;
1473d498078SAdrian Hunter }
1483d498078SAdrian Hunter 
intel_pt_get_ovf(struct intel_pt_pkt * packet)149a4e92590SAdrian Hunter static int intel_pt_get_ovf(struct intel_pt_pkt *packet)
150a4e92590SAdrian Hunter {
151a4e92590SAdrian Hunter 	packet->type = INTEL_PT_OVF;
152a4e92590SAdrian Hunter 	return 2;
153a4e92590SAdrian Hunter }
154a4e92590SAdrian Hunter 
intel_pt_get_psb(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)155a4e92590SAdrian Hunter static int intel_pt_get_psb(const unsigned char *buf, size_t len,
156a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
157a4e92590SAdrian Hunter {
158a4e92590SAdrian Hunter 	int i;
159a4e92590SAdrian Hunter 
160a4e92590SAdrian Hunter 	if (len < 16)
161a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
162a4e92590SAdrian Hunter 
163a4e92590SAdrian Hunter 	for (i = 2; i < 16; i += 2) {
164a4e92590SAdrian Hunter 		if (buf[i] != 2 || buf[i + 1] != 0x82)
165a4e92590SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
166a4e92590SAdrian Hunter 	}
167a4e92590SAdrian Hunter 
168a4e92590SAdrian Hunter 	packet->type = INTEL_PT_PSB;
169a4e92590SAdrian Hunter 	return 16;
170a4e92590SAdrian Hunter }
171a4e92590SAdrian Hunter 
intel_pt_get_psbend(struct intel_pt_pkt * packet)172a4e92590SAdrian Hunter static int intel_pt_get_psbend(struct intel_pt_pkt *packet)
173a4e92590SAdrian Hunter {
174a4e92590SAdrian Hunter 	packet->type = INTEL_PT_PSBEND;
175a4e92590SAdrian Hunter 	return 2;
176a4e92590SAdrian Hunter }
177a4e92590SAdrian Hunter 
intel_pt_get_tma(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)1783d498078SAdrian Hunter static int intel_pt_get_tma(const unsigned char *buf, size_t len,
1793d498078SAdrian Hunter 			    struct intel_pt_pkt *packet)
1803d498078SAdrian Hunter {
1813d498078SAdrian Hunter 	if (len < 7)
1823d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
1833d498078SAdrian Hunter 
1843d498078SAdrian Hunter 	packet->type = INTEL_PT_TMA;
1853d498078SAdrian Hunter 	packet->payload = buf[2] | (buf[3] << 8);
1863d498078SAdrian Hunter 	packet->count = buf[5] | ((buf[6] & BIT(0)) << 8);
1873d498078SAdrian Hunter 	return 7;
1883d498078SAdrian Hunter }
1893d498078SAdrian Hunter 
intel_pt_get_pad(struct intel_pt_pkt * packet)190a4e92590SAdrian Hunter static int intel_pt_get_pad(struct intel_pt_pkt *packet)
191a4e92590SAdrian Hunter {
192a4e92590SAdrian Hunter 	packet->type = INTEL_PT_PAD;
193a4e92590SAdrian Hunter 	return 1;
194a4e92590SAdrian Hunter }
195a4e92590SAdrian Hunter 
intel_pt_get_mnt(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)1963d498078SAdrian Hunter static int intel_pt_get_mnt(const unsigned char *buf, size_t len,
1973d498078SAdrian Hunter 			    struct intel_pt_pkt *packet)
1983d498078SAdrian Hunter {
1993d498078SAdrian Hunter 	if (len < 11)
2003d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
2013d498078SAdrian Hunter 	packet->type = INTEL_PT_MNT;
2023d498078SAdrian Hunter 	memcpy_le64(&packet->payload, buf + 3, 8);
2036816c254SAdrian Hunter 	return 11;
2043d498078SAdrian Hunter }
2053d498078SAdrian Hunter 
intel_pt_get_3byte(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)2063d498078SAdrian Hunter static int intel_pt_get_3byte(const unsigned char *buf, size_t len,
2073d498078SAdrian Hunter 			      struct intel_pt_pkt *packet)
2083d498078SAdrian Hunter {
2093d498078SAdrian Hunter 	if (len < 3)
2103d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
2113d498078SAdrian Hunter 
2123d498078SAdrian Hunter 	switch (buf[2]) {
2133d498078SAdrian Hunter 	case 0x88: /* MNT */
2143d498078SAdrian Hunter 		return intel_pt_get_mnt(buf, len, packet);
2153d498078SAdrian Hunter 	default:
2163d498078SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
2173d498078SAdrian Hunter 	}
2183d498078SAdrian Hunter }
2193d498078SAdrian Hunter 
intel_pt_get_ptwrite(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)220a472e65fSAdrian Hunter static int intel_pt_get_ptwrite(const unsigned char *buf, size_t len,
221a472e65fSAdrian Hunter 				struct intel_pt_pkt *packet)
222a472e65fSAdrian Hunter {
223a472e65fSAdrian Hunter 	packet->count = (buf[1] >> 5) & 0x3;
224a472e65fSAdrian Hunter 	packet->type = buf[1] & BIT(7) ? INTEL_PT_PTWRITE_IP :
225a472e65fSAdrian Hunter 					 INTEL_PT_PTWRITE;
226a472e65fSAdrian Hunter 
227a472e65fSAdrian Hunter 	switch (packet->count) {
228a472e65fSAdrian Hunter 	case 0:
229a472e65fSAdrian Hunter 		if (len < 6)
230a472e65fSAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
231a472e65fSAdrian Hunter 		packet->payload = le32_to_cpu(*(uint32_t *)(buf + 2));
232a472e65fSAdrian Hunter 		return 6;
233a472e65fSAdrian Hunter 	case 1:
234a472e65fSAdrian Hunter 		if (len < 10)
235a472e65fSAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
236a472e65fSAdrian Hunter 		packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2));
237a472e65fSAdrian Hunter 		return 10;
238a472e65fSAdrian Hunter 	default:
239a472e65fSAdrian Hunter 		return INTEL_PT_BAD_PACKET;
240a472e65fSAdrian Hunter 	}
241a472e65fSAdrian Hunter }
242a472e65fSAdrian Hunter 
intel_pt_get_exstop(struct intel_pt_pkt * packet)243a472e65fSAdrian Hunter static int intel_pt_get_exstop(struct intel_pt_pkt *packet)
244a472e65fSAdrian Hunter {
245a472e65fSAdrian Hunter 	packet->type = INTEL_PT_EXSTOP;
246a472e65fSAdrian Hunter 	return 2;
247a472e65fSAdrian Hunter }
248a472e65fSAdrian Hunter 
intel_pt_get_exstop_ip(struct intel_pt_pkt * packet)249a472e65fSAdrian Hunter static int intel_pt_get_exstop_ip(struct intel_pt_pkt *packet)
250a472e65fSAdrian Hunter {
251a472e65fSAdrian Hunter 	packet->type = INTEL_PT_EXSTOP_IP;
252a472e65fSAdrian Hunter 	return 2;
253a472e65fSAdrian Hunter }
254a472e65fSAdrian Hunter 
intel_pt_get_mwait(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)255a472e65fSAdrian Hunter static int intel_pt_get_mwait(const unsigned char *buf, size_t len,
256a472e65fSAdrian Hunter 			      struct intel_pt_pkt *packet)
257a472e65fSAdrian Hunter {
258a472e65fSAdrian Hunter 	if (len < 10)
259a472e65fSAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
260a472e65fSAdrian Hunter 	packet->type = INTEL_PT_MWAIT;
261a472e65fSAdrian Hunter 	packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2));
262a472e65fSAdrian Hunter 	return 10;
263a472e65fSAdrian Hunter }
264a472e65fSAdrian Hunter 
intel_pt_get_pwre(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)265a472e65fSAdrian Hunter static int intel_pt_get_pwre(const unsigned char *buf, size_t len,
266a472e65fSAdrian Hunter 			     struct intel_pt_pkt *packet)
267a472e65fSAdrian Hunter {
268a472e65fSAdrian Hunter 	if (len < 4)
269a472e65fSAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
270a472e65fSAdrian Hunter 	packet->type = INTEL_PT_PWRE;
271a472e65fSAdrian Hunter 	memcpy_le64(&packet->payload, buf + 2, 2);
272a472e65fSAdrian Hunter 	return 4;
273a472e65fSAdrian Hunter }
274a472e65fSAdrian Hunter 
intel_pt_get_pwrx(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)275a472e65fSAdrian Hunter static int intel_pt_get_pwrx(const unsigned char *buf, size_t len,
276a472e65fSAdrian Hunter 			     struct intel_pt_pkt *packet)
277a472e65fSAdrian Hunter {
278a472e65fSAdrian Hunter 	if (len < 7)
279a472e65fSAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
280a472e65fSAdrian Hunter 	packet->type = INTEL_PT_PWRX;
281a472e65fSAdrian Hunter 	memcpy_le64(&packet->payload, buf + 2, 5);
282a472e65fSAdrian Hunter 	return 7;
283a472e65fSAdrian Hunter }
284a472e65fSAdrian Hunter 
intel_pt_get_bbp(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)285edff7809SAdrian Hunter static int intel_pt_get_bbp(const unsigned char *buf, size_t len,
286edff7809SAdrian Hunter 			    struct intel_pt_pkt *packet)
287edff7809SAdrian Hunter {
288edff7809SAdrian Hunter 	if (len < 3)
289edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
290edff7809SAdrian Hunter 	packet->type = INTEL_PT_BBP;
291edff7809SAdrian Hunter 	packet->count = buf[2] >> 7;
292edff7809SAdrian Hunter 	packet->payload = buf[2] & 0x1f;
293edff7809SAdrian Hunter 	return 3;
294edff7809SAdrian Hunter }
295edff7809SAdrian Hunter 
intel_pt_get_bip_4(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)296edff7809SAdrian Hunter static int intel_pt_get_bip_4(const unsigned char *buf, size_t len,
297edff7809SAdrian Hunter 			      struct intel_pt_pkt *packet)
298edff7809SAdrian Hunter {
299edff7809SAdrian Hunter 	if (len < 5)
300edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
301edff7809SAdrian Hunter 	packet->type = INTEL_PT_BIP;
302edff7809SAdrian Hunter 	packet->count = buf[0] >> 3;
303edff7809SAdrian Hunter 	memcpy_le64(&packet->payload, buf + 1, 4);
304edff7809SAdrian Hunter 	return 5;
305edff7809SAdrian Hunter }
306edff7809SAdrian Hunter 
intel_pt_get_bip_8(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)307edff7809SAdrian Hunter static int intel_pt_get_bip_8(const unsigned char *buf, size_t len,
308edff7809SAdrian Hunter 			      struct intel_pt_pkt *packet)
309edff7809SAdrian Hunter {
310edff7809SAdrian Hunter 	if (len < 9)
311edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
312edff7809SAdrian Hunter 	packet->type = INTEL_PT_BIP;
313edff7809SAdrian Hunter 	packet->count = buf[0] >> 3;
314edff7809SAdrian Hunter 	memcpy_le64(&packet->payload, buf + 1, 8);
315edff7809SAdrian Hunter 	return 9;
316edff7809SAdrian Hunter }
317edff7809SAdrian Hunter 
intel_pt_get_bep(size_t len,struct intel_pt_pkt * packet)318edff7809SAdrian Hunter static int intel_pt_get_bep(size_t len, struct intel_pt_pkt *packet)
319edff7809SAdrian Hunter {
320edff7809SAdrian Hunter 	if (len < 2)
321edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
322edff7809SAdrian Hunter 	packet->type = INTEL_PT_BEP;
323edff7809SAdrian Hunter 	return 2;
324edff7809SAdrian Hunter }
325edff7809SAdrian Hunter 
intel_pt_get_bep_ip(size_t len,struct intel_pt_pkt * packet)326edff7809SAdrian Hunter static int intel_pt_get_bep_ip(size_t len, struct intel_pt_pkt *packet)
327edff7809SAdrian Hunter {
328edff7809SAdrian Hunter 	if (len < 2)
329edff7809SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
330edff7809SAdrian Hunter 	packet->type = INTEL_PT_BEP_IP;
331edff7809SAdrian Hunter 	return 2;
332edff7809SAdrian Hunter }
333edff7809SAdrian Hunter 
intel_pt_get_cfe(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)3342750af50SAdrian Hunter static int intel_pt_get_cfe(const unsigned char *buf, size_t len,
3352750af50SAdrian Hunter 			    struct intel_pt_pkt *packet)
3362750af50SAdrian Hunter {
3372750af50SAdrian Hunter 	if (len < 4)
3382750af50SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
3392750af50SAdrian Hunter 	packet->type = buf[2] & 0x80 ? INTEL_PT_CFE_IP : INTEL_PT_CFE;
3402750af50SAdrian Hunter 	packet->count = buf[2] & 0x1f;
3412750af50SAdrian Hunter 	packet->payload = buf[3];
3422750af50SAdrian Hunter 	return 4;
3432750af50SAdrian Hunter }
3442750af50SAdrian Hunter 
intel_pt_get_evd(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)3452750af50SAdrian Hunter static int intel_pt_get_evd(const unsigned char *buf, size_t len,
3462750af50SAdrian Hunter 			    struct intel_pt_pkt *packet)
3472750af50SAdrian Hunter {
3482750af50SAdrian Hunter 	if (len < 11)
3492750af50SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
3502750af50SAdrian Hunter 	packet->type = INTEL_PT_EVD;
3512750af50SAdrian Hunter 	packet->count = buf[2] & 0x3f;
3522750af50SAdrian Hunter 	packet->payload = buf[3];
3532750af50SAdrian Hunter 	memcpy_le64(&packet->payload, buf + 3, 8);
3542750af50SAdrian Hunter 	return 11;
3552750af50SAdrian Hunter }
3562750af50SAdrian Hunter 
intel_pt_get_ext(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)357a4e92590SAdrian Hunter static int intel_pt_get_ext(const unsigned char *buf, size_t len,
358a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
359a4e92590SAdrian Hunter {
360a4e92590SAdrian Hunter 	if (len < 2)
361a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
362a4e92590SAdrian Hunter 
363a472e65fSAdrian Hunter 	if ((buf[1] & 0x1f) == 0x12)
364a472e65fSAdrian Hunter 		return intel_pt_get_ptwrite(buf, len, packet);
365a472e65fSAdrian Hunter 
366a4e92590SAdrian Hunter 	switch (buf[1]) {
367a4e92590SAdrian Hunter 	case 0xa3: /* Long TNT */
368a4e92590SAdrian Hunter 		return intel_pt_get_long_tnt(buf, len, packet);
369a4e92590SAdrian Hunter 	case 0x43: /* PIP */
370a4e92590SAdrian Hunter 		return intel_pt_get_pip(buf, len, packet);
3713d498078SAdrian Hunter 	case 0x83: /* TraceStop */
3723d498078SAdrian Hunter 		return intel_pt_get_tracestop(packet);
373a4e92590SAdrian Hunter 	case 0x03: /* CBR */
374a4e92590SAdrian Hunter 		return intel_pt_get_cbr(buf, len, packet);
3753d498078SAdrian Hunter 	case 0xc8: /* VMCS */
3763d498078SAdrian Hunter 		return intel_pt_get_vmcs(buf, len, packet);
377a4e92590SAdrian Hunter 	case 0xf3: /* OVF */
378a4e92590SAdrian Hunter 		return intel_pt_get_ovf(packet);
379a4e92590SAdrian Hunter 	case 0x82: /* PSB */
380a4e92590SAdrian Hunter 		return intel_pt_get_psb(buf, len, packet);
381a4e92590SAdrian Hunter 	case 0x23: /* PSBEND */
382a4e92590SAdrian Hunter 		return intel_pt_get_psbend(packet);
3833d498078SAdrian Hunter 	case 0x73: /* TMA */
3843d498078SAdrian Hunter 		return intel_pt_get_tma(buf, len, packet);
3853d498078SAdrian Hunter 	case 0xC3: /* 3-byte header */
3863d498078SAdrian Hunter 		return intel_pt_get_3byte(buf, len, packet);
387a472e65fSAdrian Hunter 	case 0x62: /* EXSTOP no IP */
388a472e65fSAdrian Hunter 		return intel_pt_get_exstop(packet);
389a472e65fSAdrian Hunter 	case 0xE2: /* EXSTOP with IP */
390a472e65fSAdrian Hunter 		return intel_pt_get_exstop_ip(packet);
391a472e65fSAdrian Hunter 	case 0xC2: /* MWAIT */
392a472e65fSAdrian Hunter 		return intel_pt_get_mwait(buf, len, packet);
393a472e65fSAdrian Hunter 	case 0x22: /* PWRE */
394a472e65fSAdrian Hunter 		return intel_pt_get_pwre(buf, len, packet);
395a472e65fSAdrian Hunter 	case 0xA2: /* PWRX */
396a472e65fSAdrian Hunter 		return intel_pt_get_pwrx(buf, len, packet);
397edff7809SAdrian Hunter 	case 0x63: /* BBP */
398edff7809SAdrian Hunter 		return intel_pt_get_bbp(buf, len, packet);
399edff7809SAdrian Hunter 	case 0x33: /* BEP no IP */
400edff7809SAdrian Hunter 		return intel_pt_get_bep(len, packet);
401edff7809SAdrian Hunter 	case 0xb3: /* BEP with IP */
402edff7809SAdrian Hunter 		return intel_pt_get_bep_ip(len, packet);
4032750af50SAdrian Hunter 	case 0x13: /* CFE */
4042750af50SAdrian Hunter 		return intel_pt_get_cfe(buf, len, packet);
4052750af50SAdrian Hunter 	case 0x53: /* EVD */
4062750af50SAdrian Hunter 		return intel_pt_get_evd(buf, len, packet);
407a4e92590SAdrian Hunter 	default:
408a4e92590SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
409a4e92590SAdrian Hunter 	}
410a4e92590SAdrian Hunter }
411a4e92590SAdrian Hunter 
intel_pt_get_short_tnt(unsigned int byte,struct intel_pt_pkt * packet)412a4e92590SAdrian Hunter static int intel_pt_get_short_tnt(unsigned int byte,
413a4e92590SAdrian Hunter 				  struct intel_pt_pkt *packet)
414a4e92590SAdrian Hunter {
415a4e92590SAdrian Hunter 	int count;
416a4e92590SAdrian Hunter 
417a4e92590SAdrian Hunter 	for (count = 6; count; count--) {
418a4e92590SAdrian Hunter 		if (byte & BIT(7))
419a4e92590SAdrian Hunter 			break;
420a4e92590SAdrian Hunter 		byte <<= 1;
421a4e92590SAdrian Hunter 	}
422a4e92590SAdrian Hunter 
423a4e92590SAdrian Hunter 	packet->type = INTEL_PT_TNT;
424a4e92590SAdrian Hunter 	packet->count = count;
425a4e92590SAdrian Hunter 	packet->payload = (uint64_t)byte << 57;
426a4e92590SAdrian Hunter 
427a4e92590SAdrian Hunter 	return 1;
428a4e92590SAdrian Hunter }
429a4e92590SAdrian Hunter 
intel_pt_get_cyc(unsigned int byte,const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)4303d498078SAdrian Hunter static int intel_pt_get_cyc(unsigned int byte, const unsigned char *buf,
4313d498078SAdrian Hunter 			    size_t len, struct intel_pt_pkt *packet)
4323d498078SAdrian Hunter {
4333d498078SAdrian Hunter 	unsigned int offs = 1, shift;
4343d498078SAdrian Hunter 	uint64_t payload = byte >> 3;
4353d498078SAdrian Hunter 
4363d498078SAdrian Hunter 	byte >>= 2;
4373d498078SAdrian Hunter 	len -= 1;
4383d498078SAdrian Hunter 	for (shift = 5; byte & 1; shift += 7) {
4393d498078SAdrian Hunter 		if (offs > 9)
4403d498078SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
4413d498078SAdrian Hunter 		if (len < offs)
4423d498078SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
4433d498078SAdrian Hunter 		byte = buf[offs++];
444621a5a32SAdrian Hunter 		payload |= ((uint64_t)byte >> 1) << shift;
4453d498078SAdrian Hunter 	}
4463d498078SAdrian Hunter 
4473d498078SAdrian Hunter 	packet->type = INTEL_PT_CYC;
4483d498078SAdrian Hunter 	packet->payload = payload;
4493d498078SAdrian Hunter 	return offs;
4503d498078SAdrian Hunter }
4513d498078SAdrian 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)452a4e92590SAdrian Hunter static int intel_pt_get_ip(enum intel_pt_pkt_type type, unsigned int byte,
453a4e92590SAdrian Hunter 			   const unsigned char *buf, size_t len,
454a4e92590SAdrian Hunter 			   struct intel_pt_pkt *packet)
455a4e92590SAdrian Hunter {
456e1717e04SAdrian Hunter 	int ip_len;
457e1717e04SAdrian Hunter 
458e1717e04SAdrian Hunter 	packet->count = byte >> 5;
459e1717e04SAdrian Hunter 
460e1717e04SAdrian Hunter 	switch (packet->count) {
461a4e92590SAdrian Hunter 	case 0:
462e1717e04SAdrian Hunter 		ip_len = 0;
463a4e92590SAdrian Hunter 		break;
464a4e92590SAdrian Hunter 	case 1:
465a4e92590SAdrian Hunter 		if (len < 3)
466a4e92590SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
467e1717e04SAdrian Hunter 		ip_len = 2;
468a4e92590SAdrian Hunter 		packet->payload = le16_to_cpu(*(uint16_t *)(buf + 1));
469a4e92590SAdrian Hunter 		break;
470a4e92590SAdrian Hunter 	case 2:
471a4e92590SAdrian Hunter 		if (len < 5)
472a4e92590SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
473e1717e04SAdrian Hunter 		ip_len = 4;
474a4e92590SAdrian Hunter 		packet->payload = le32_to_cpu(*(uint32_t *)(buf + 1));
475a4e92590SAdrian Hunter 		break;
476a4e92590SAdrian Hunter 	case 3:
477e1717e04SAdrian Hunter 	case 4:
478a4e92590SAdrian Hunter 		if (len < 7)
479a4e92590SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
480e1717e04SAdrian Hunter 		ip_len = 6;
481a4e92590SAdrian Hunter 		memcpy_le64(&packet->payload, buf + 1, 6);
482a4e92590SAdrian Hunter 		break;
483e1717e04SAdrian Hunter 	case 6:
484e1717e04SAdrian Hunter 		if (len < 9)
485e1717e04SAdrian Hunter 			return INTEL_PT_NEED_MORE_BYTES;
486e1717e04SAdrian Hunter 		ip_len = 8;
487e1717e04SAdrian Hunter 		packet->payload = le64_to_cpu(*(uint64_t *)(buf + 1));
488e1717e04SAdrian Hunter 		break;
489a4e92590SAdrian Hunter 	default:
490a4e92590SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
491a4e92590SAdrian Hunter 	}
492a4e92590SAdrian Hunter 
493a4e92590SAdrian Hunter 	packet->type = type;
494a4e92590SAdrian Hunter 
495e1717e04SAdrian Hunter 	return ip_len + 1;
496a4e92590SAdrian Hunter }
497a4e92590SAdrian Hunter 
intel_pt_get_mode(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)498a4e92590SAdrian Hunter static int intel_pt_get_mode(const unsigned char *buf, size_t len,
499a4e92590SAdrian Hunter 			     struct intel_pt_pkt *packet)
500a4e92590SAdrian Hunter {
501a4e92590SAdrian Hunter 	if (len < 2)
502a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
503a4e92590SAdrian Hunter 
504a4e92590SAdrian Hunter 	switch (buf[1] >> 5) {
505a4e92590SAdrian Hunter 	case 0:
506a4e92590SAdrian Hunter 		packet->type = INTEL_PT_MODE_EXEC;
507f7934477SAdrian Hunter 		packet->count = buf[1];
508a4e92590SAdrian Hunter 		switch (buf[1] & 3) {
509a4e92590SAdrian Hunter 		case 0:
510a4e92590SAdrian Hunter 			packet->payload = 16;
511a4e92590SAdrian Hunter 			break;
512a4e92590SAdrian Hunter 		case 1:
513a4e92590SAdrian Hunter 			packet->payload = 64;
514a4e92590SAdrian Hunter 			break;
515a4e92590SAdrian Hunter 		case 2:
516a4e92590SAdrian Hunter 			packet->payload = 32;
517a4e92590SAdrian Hunter 			break;
518a4e92590SAdrian Hunter 		default:
519a4e92590SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
520a4e92590SAdrian Hunter 		}
521a4e92590SAdrian Hunter 		break;
522a4e92590SAdrian Hunter 	case 1:
523a4e92590SAdrian Hunter 		packet->type = INTEL_PT_MODE_TSX;
524a4e92590SAdrian Hunter 		if ((buf[1] & 3) == 3)
525a4e92590SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
526a4e92590SAdrian Hunter 		packet->payload = buf[1] & 3;
527a4e92590SAdrian Hunter 		break;
528a4e92590SAdrian Hunter 	default:
529a4e92590SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
530a4e92590SAdrian Hunter 	}
531a4e92590SAdrian Hunter 
532a4e92590SAdrian Hunter 	return 2;
533a4e92590SAdrian Hunter }
534a4e92590SAdrian Hunter 
intel_pt_get_tsc(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)535a4e92590SAdrian Hunter static int intel_pt_get_tsc(const unsigned char *buf, size_t len,
536a4e92590SAdrian Hunter 			    struct intel_pt_pkt *packet)
537a4e92590SAdrian Hunter {
538a4e92590SAdrian Hunter 	if (len < 8)
539a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
540a4e92590SAdrian Hunter 	packet->type = INTEL_PT_TSC;
541a4e92590SAdrian Hunter 	memcpy_le64(&packet->payload, buf + 1, 7);
542a4e92590SAdrian Hunter 	return 8;
543a4e92590SAdrian Hunter }
544a4e92590SAdrian Hunter 
intel_pt_get_mtc(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet)5453d498078SAdrian Hunter static int intel_pt_get_mtc(const unsigned char *buf, size_t len,
5463d498078SAdrian Hunter 			    struct intel_pt_pkt *packet)
5473d498078SAdrian Hunter {
5483d498078SAdrian Hunter 	if (len < 2)
5493d498078SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
5503d498078SAdrian Hunter 	packet->type = INTEL_PT_MTC;
5513d498078SAdrian Hunter 	packet->payload = buf[1];
5523d498078SAdrian Hunter 	return 2;
5533d498078SAdrian Hunter }
5543d498078SAdrian Hunter 
intel_pt_do_get_packet(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet,enum intel_pt_pkt_ctx ctx)555a4e92590SAdrian Hunter static int intel_pt_do_get_packet(const unsigned char *buf, size_t len,
556edff7809SAdrian Hunter 				  struct intel_pt_pkt *packet,
557edff7809SAdrian Hunter 				  enum intel_pt_pkt_ctx ctx)
558a4e92590SAdrian Hunter {
559a4e92590SAdrian Hunter 	unsigned int byte;
560a4e92590SAdrian Hunter 
561a4e92590SAdrian Hunter 	memset(packet, 0, sizeof(struct intel_pt_pkt));
562a4e92590SAdrian Hunter 
563a4e92590SAdrian Hunter 	if (!len)
564a4e92590SAdrian Hunter 		return INTEL_PT_NEED_MORE_BYTES;
565a4e92590SAdrian Hunter 
566a4e92590SAdrian Hunter 	byte = buf[0];
567edff7809SAdrian Hunter 
568edff7809SAdrian Hunter 	switch (ctx) {
569edff7809SAdrian Hunter 	case INTEL_PT_NO_CTX:
570edff7809SAdrian Hunter 		break;
571edff7809SAdrian Hunter 	case INTEL_PT_BLK_4_CTX:
572edff7809SAdrian Hunter 		if ((byte & 0x7) == 4)
573edff7809SAdrian Hunter 			return intel_pt_get_bip_4(buf, len, packet);
574edff7809SAdrian Hunter 		break;
575edff7809SAdrian Hunter 	case INTEL_PT_BLK_8_CTX:
576edff7809SAdrian Hunter 		if ((byte & 0x7) == 4)
577edff7809SAdrian Hunter 			return intel_pt_get_bip_8(buf, len, packet);
578edff7809SAdrian Hunter 		break;
579edff7809SAdrian Hunter 	default:
580edff7809SAdrian Hunter 		break;
5818284bbeaSZou Wei 	}
582edff7809SAdrian Hunter 
583a4e92590SAdrian Hunter 	if (!(byte & BIT(0))) {
584a4e92590SAdrian Hunter 		if (byte == 0)
585a4e92590SAdrian Hunter 			return intel_pt_get_pad(packet);
586a4e92590SAdrian Hunter 		if (byte == 2)
587a4e92590SAdrian Hunter 			return intel_pt_get_ext(buf, len, packet);
588a4e92590SAdrian Hunter 		return intel_pt_get_short_tnt(byte, packet);
589a4e92590SAdrian Hunter 	}
590a4e92590SAdrian Hunter 
5913d498078SAdrian Hunter 	if ((byte & 2))
5923d498078SAdrian Hunter 		return intel_pt_get_cyc(byte, buf, len, packet);
5933d498078SAdrian Hunter 
594a4e92590SAdrian Hunter 	switch (byte & 0x1f) {
595a4e92590SAdrian Hunter 	case 0x0D:
596a4e92590SAdrian Hunter 		return intel_pt_get_ip(INTEL_PT_TIP, byte, buf, len, packet);
597a4e92590SAdrian Hunter 	case 0x11:
598a4e92590SAdrian Hunter 		return intel_pt_get_ip(INTEL_PT_TIP_PGE, byte, buf, len,
599a4e92590SAdrian Hunter 				       packet);
600a4e92590SAdrian Hunter 	case 0x01:
601a4e92590SAdrian Hunter 		return intel_pt_get_ip(INTEL_PT_TIP_PGD, byte, buf, len,
602a4e92590SAdrian Hunter 				       packet);
603a4e92590SAdrian Hunter 	case 0x1D:
604a4e92590SAdrian Hunter 		return intel_pt_get_ip(INTEL_PT_FUP, byte, buf, len, packet);
605a4e92590SAdrian Hunter 	case 0x19:
606a4e92590SAdrian Hunter 		switch (byte) {
607a4e92590SAdrian Hunter 		case 0x99:
608a4e92590SAdrian Hunter 			return intel_pt_get_mode(buf, len, packet);
609a4e92590SAdrian Hunter 		case 0x19:
610a4e92590SAdrian Hunter 			return intel_pt_get_tsc(buf, len, packet);
6113d498078SAdrian Hunter 		case 0x59:
6123d498078SAdrian Hunter 			return intel_pt_get_mtc(buf, len, packet);
613a4e92590SAdrian Hunter 		default:
614a4e92590SAdrian Hunter 			return INTEL_PT_BAD_PACKET;
615a4e92590SAdrian Hunter 		}
616a4e92590SAdrian Hunter 	default:
617a4e92590SAdrian Hunter 		return INTEL_PT_BAD_PACKET;
618a4e92590SAdrian Hunter 	}
619a4e92590SAdrian Hunter }
620a4e92590SAdrian Hunter 
intel_pt_upd_pkt_ctx(const struct intel_pt_pkt * packet,enum intel_pt_pkt_ctx * ctx)621edff7809SAdrian Hunter void intel_pt_upd_pkt_ctx(const struct intel_pt_pkt *packet,
622edff7809SAdrian Hunter 			  enum intel_pt_pkt_ctx *ctx)
623edff7809SAdrian Hunter {
624edff7809SAdrian Hunter 	switch (packet->type) {
625edff7809SAdrian Hunter 	case INTEL_PT_BAD:
626edff7809SAdrian Hunter 	case INTEL_PT_PAD:
627edff7809SAdrian Hunter 	case INTEL_PT_TSC:
628edff7809SAdrian Hunter 	case INTEL_PT_TMA:
629edff7809SAdrian Hunter 	case INTEL_PT_MTC:
630edff7809SAdrian Hunter 	case INTEL_PT_FUP:
631edff7809SAdrian Hunter 	case INTEL_PT_CYC:
632edff7809SAdrian Hunter 	case INTEL_PT_CBR:
633edff7809SAdrian Hunter 	case INTEL_PT_MNT:
634edff7809SAdrian Hunter 	case INTEL_PT_EXSTOP:
635edff7809SAdrian Hunter 	case INTEL_PT_EXSTOP_IP:
636edff7809SAdrian Hunter 	case INTEL_PT_PWRE:
637edff7809SAdrian Hunter 	case INTEL_PT_PWRX:
638edff7809SAdrian Hunter 	case INTEL_PT_BIP:
639edff7809SAdrian Hunter 		break;
640edff7809SAdrian Hunter 	case INTEL_PT_TNT:
641edff7809SAdrian Hunter 	case INTEL_PT_TIP:
642edff7809SAdrian Hunter 	case INTEL_PT_TIP_PGD:
643edff7809SAdrian Hunter 	case INTEL_PT_TIP_PGE:
644edff7809SAdrian Hunter 	case INTEL_PT_MODE_EXEC:
645edff7809SAdrian Hunter 	case INTEL_PT_MODE_TSX:
646edff7809SAdrian Hunter 	case INTEL_PT_PIP:
647edff7809SAdrian Hunter 	case INTEL_PT_OVF:
648edff7809SAdrian Hunter 	case INTEL_PT_VMCS:
649edff7809SAdrian Hunter 	case INTEL_PT_TRACESTOP:
650edff7809SAdrian Hunter 	case INTEL_PT_PSB:
651edff7809SAdrian Hunter 	case INTEL_PT_PSBEND:
652edff7809SAdrian Hunter 	case INTEL_PT_PTWRITE:
653edff7809SAdrian Hunter 	case INTEL_PT_PTWRITE_IP:
654edff7809SAdrian Hunter 	case INTEL_PT_MWAIT:
655edff7809SAdrian Hunter 	case INTEL_PT_BEP:
656edff7809SAdrian Hunter 	case INTEL_PT_BEP_IP:
6572750af50SAdrian Hunter 	case INTEL_PT_CFE:
6582750af50SAdrian Hunter 	case INTEL_PT_CFE_IP:
6592750af50SAdrian Hunter 	case INTEL_PT_EVD:
660edff7809SAdrian Hunter 		*ctx = INTEL_PT_NO_CTX;
661edff7809SAdrian Hunter 		break;
662edff7809SAdrian Hunter 	case INTEL_PT_BBP:
663edff7809SAdrian Hunter 		if (packet->count)
664edff7809SAdrian Hunter 			*ctx = INTEL_PT_BLK_4_CTX;
665edff7809SAdrian Hunter 		else
666edff7809SAdrian Hunter 			*ctx = INTEL_PT_BLK_8_CTX;
667edff7809SAdrian Hunter 		break;
668edff7809SAdrian Hunter 	default:
669edff7809SAdrian Hunter 		break;
670edff7809SAdrian Hunter 	}
671edff7809SAdrian Hunter }
672edff7809SAdrian Hunter 
intel_pt_get_packet(const unsigned char * buf,size_t len,struct intel_pt_pkt * packet,enum intel_pt_pkt_ctx * ctx)673a4e92590SAdrian Hunter int intel_pt_get_packet(const unsigned char *buf, size_t len,
674edff7809SAdrian Hunter 			struct intel_pt_pkt *packet, enum intel_pt_pkt_ctx *ctx)
675a4e92590SAdrian Hunter {
676a4e92590SAdrian Hunter 	int ret;
677a4e92590SAdrian Hunter 
678edff7809SAdrian Hunter 	ret = intel_pt_do_get_packet(buf, len, packet, *ctx);
679a4e92590SAdrian Hunter 	if (ret > 0) {
680a4e92590SAdrian Hunter 		while (ret < 8 && len > (size_t)ret && !buf[ret])
681a4e92590SAdrian Hunter 			ret += 1;
682edff7809SAdrian Hunter 		intel_pt_upd_pkt_ctx(packet, ctx);
683a4e92590SAdrian Hunter 	}
684a4e92590SAdrian Hunter 	return ret;
685a4e92590SAdrian Hunter }
686a4e92590SAdrian Hunter 
intel_pt_pkt_desc(const struct intel_pt_pkt * packet,char * buf,size_t buf_len)687a4e92590SAdrian Hunter int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf,
688a4e92590SAdrian Hunter 		      size_t buf_len)
689a4e92590SAdrian Hunter {
6903d498078SAdrian Hunter 	int ret, i, nr;
691a4e92590SAdrian Hunter 	unsigned long long payload = packet->payload;
692a4e92590SAdrian Hunter 	const char *name = intel_pt_pkt_name(packet->type);
693a4e92590SAdrian Hunter 
694a4e92590SAdrian Hunter 	switch (packet->type) {
695a4e92590SAdrian Hunter 	case INTEL_PT_BAD:
696a4e92590SAdrian Hunter 	case INTEL_PT_PAD:
697a4e92590SAdrian Hunter 	case INTEL_PT_PSB:
698a4e92590SAdrian Hunter 	case INTEL_PT_PSBEND:
6993d498078SAdrian Hunter 	case INTEL_PT_TRACESTOP:
700a4e92590SAdrian Hunter 	case INTEL_PT_OVF:
701a4e92590SAdrian Hunter 		return snprintf(buf, buf_len, "%s", name);
702a4e92590SAdrian Hunter 	case INTEL_PT_TNT: {
703a4e92590SAdrian Hunter 		size_t blen = buf_len;
704a4e92590SAdrian Hunter 
705a4e92590SAdrian Hunter 		ret = snprintf(buf, blen, "%s ", name);
706a4e92590SAdrian Hunter 		if (ret < 0)
707a4e92590SAdrian Hunter 			return ret;
708a4e92590SAdrian Hunter 		buf += ret;
709a4e92590SAdrian Hunter 		blen -= ret;
710a4e92590SAdrian Hunter 		for (i = 0; i < packet->count; i++) {
711a4e92590SAdrian Hunter 			if (payload & BIT63)
712a4e92590SAdrian Hunter 				ret = snprintf(buf, blen, "T");
713a4e92590SAdrian Hunter 			else
714a4e92590SAdrian Hunter 				ret = snprintf(buf, blen, "N");
715a4e92590SAdrian Hunter 			if (ret < 0)
716a4e92590SAdrian Hunter 				return ret;
717a4e92590SAdrian Hunter 			buf += ret;
718a4e92590SAdrian Hunter 			blen -= ret;
719a4e92590SAdrian Hunter 			payload <<= 1;
720a4e92590SAdrian Hunter 		}
721a4e92590SAdrian Hunter 		ret = snprintf(buf, blen, " (%d)", packet->count);
722a4e92590SAdrian Hunter 		if (ret < 0)
723a4e92590SAdrian Hunter 			return ret;
724a4e92590SAdrian Hunter 		blen -= ret;
725a4e92590SAdrian Hunter 		return buf_len - blen;
726a4e92590SAdrian Hunter 	}
727a4e92590SAdrian Hunter 	case INTEL_PT_TIP_PGD:
728a4e92590SAdrian Hunter 	case INTEL_PT_TIP_PGE:
729a4e92590SAdrian Hunter 	case INTEL_PT_TIP:
730a4e92590SAdrian Hunter 	case INTEL_PT_FUP:
731a4e92590SAdrian Hunter 		if (!(packet->count))
732a4e92590SAdrian Hunter 			return snprintf(buf, buf_len, "%s no ip", name);
733*f7a858bfSLiam Howlett 		fallthrough;
7343d498078SAdrian Hunter 	case INTEL_PT_CYC:
7353d498078SAdrian Hunter 	case INTEL_PT_VMCS:
7363d498078SAdrian Hunter 	case INTEL_PT_MTC:
7373d498078SAdrian Hunter 	case INTEL_PT_MNT:
738a4e92590SAdrian Hunter 	case INTEL_PT_CBR:
739a4e92590SAdrian Hunter 	case INTEL_PT_TSC:
7403d498078SAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx", name, payload);
7413d498078SAdrian Hunter 	case INTEL_PT_TMA:
7423d498078SAdrian Hunter 		return snprintf(buf, buf_len, "%s CTC 0x%x FC 0x%x", name,
7433d498078SAdrian Hunter 				(unsigned)payload, packet->count);
744a4e92590SAdrian Hunter 	case INTEL_PT_MODE_EXEC:
745f7934477SAdrian Hunter 		return snprintf(buf, buf_len, "%s IF:%d %lld",
746f7934477SAdrian Hunter 				name, !!(packet->count & 4), payload);
747a4e92590SAdrian Hunter 	case INTEL_PT_MODE_TSX:
748a4e92590SAdrian Hunter 		return snprintf(buf, buf_len, "%s TXAbort:%u InTX:%u",
749a4e92590SAdrian Hunter 				name, (unsigned)(payload >> 1) & 1,
750a4e92590SAdrian Hunter 				(unsigned)payload & 1);
751a4e92590SAdrian Hunter 	case INTEL_PT_PIP:
75290af7555SAdrian Hunter 		nr = packet->payload & INTEL_PT_VMX_NR_FLAG ? 1 : 0;
75390af7555SAdrian Hunter 		payload &= ~INTEL_PT_VMX_NR_FLAG;
7543d498078SAdrian Hunter 		ret = snprintf(buf, buf_len, "%s 0x%llx (NR=%d)",
75590af7555SAdrian Hunter 			       name, payload >> 1, nr);
756a4e92590SAdrian Hunter 		return ret;
757a472e65fSAdrian Hunter 	case INTEL_PT_PTWRITE:
758a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx IP:0", name, payload);
759a472e65fSAdrian Hunter 	case INTEL_PT_PTWRITE_IP:
760a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx IP:1", name, payload);
761edff7809SAdrian Hunter 	case INTEL_PT_BEP:
762a472e65fSAdrian Hunter 	case INTEL_PT_EXSTOP:
763a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s IP:0", name);
764edff7809SAdrian Hunter 	case INTEL_PT_BEP_IP:
765a472e65fSAdrian Hunter 	case INTEL_PT_EXSTOP_IP:
766a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s IP:1", name);
767a472e65fSAdrian Hunter 	case INTEL_PT_MWAIT:
768a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx Hints 0x%x Extensions 0x%x",
769a472e65fSAdrian Hunter 				name, payload, (unsigned int)(payload & 0xff),
770a472e65fSAdrian Hunter 				(unsigned int)((payload >> 32) & 0x3));
771a472e65fSAdrian Hunter 	case INTEL_PT_PWRE:
772a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx HW:%u CState:%u Sub-CState:%u",
773a472e65fSAdrian Hunter 				name, payload, !!(payload & 0x80),
774a472e65fSAdrian Hunter 				(unsigned int)((payload >> 12) & 0xf),
775a472e65fSAdrian Hunter 				(unsigned int)((payload >> 8) & 0xf));
776a472e65fSAdrian Hunter 	case INTEL_PT_PWRX:
777a472e65fSAdrian Hunter 		return snprintf(buf, buf_len, "%s 0x%llx Last CState:%u Deepest CState:%u Wake Reason 0x%x",
778a472e65fSAdrian Hunter 				name, payload,
779a472e65fSAdrian Hunter 				(unsigned int)((payload >> 4) & 0xf),
780a472e65fSAdrian Hunter 				(unsigned int)(payload & 0xf),
781a472e65fSAdrian Hunter 				(unsigned int)((payload >> 8) & 0xf));
782edff7809SAdrian Hunter 	case INTEL_PT_BBP:
783edff7809SAdrian Hunter 		return snprintf(buf, buf_len, "%s SZ %s-byte Type 0x%llx",
784edff7809SAdrian Hunter 				name, packet->count ? "4" : "8", payload);
785edff7809SAdrian Hunter 	case INTEL_PT_BIP:
786edff7809SAdrian Hunter 		return snprintf(buf, buf_len, "%s ID 0x%02x Value 0x%llx",
787edff7809SAdrian Hunter 				name, packet->count, payload);
7882750af50SAdrian Hunter 	case INTEL_PT_CFE:
7892750af50SAdrian Hunter 	case INTEL_PT_CFE_IP:
7902750af50SAdrian Hunter 		return snprintf(buf, buf_len, "%s IP:%d Type 0x%02x Vector 0x%llx",
7912750af50SAdrian Hunter 				name, packet->type == INTEL_PT_CFE_IP, packet->count, payload);
7922750af50SAdrian Hunter 	case INTEL_PT_EVD:
7932750af50SAdrian Hunter 		return snprintf(buf, buf_len, "%s Type 0x%02x Payload 0x%llx",
7942750af50SAdrian Hunter 				name, packet->count, payload);
795a4e92590SAdrian Hunter 	default:
796a4e92590SAdrian Hunter 		break;
797a4e92590SAdrian Hunter 	}
798a4e92590SAdrian Hunter 	return snprintf(buf, buf_len, "%s 0x%llx (%d)",
799a4e92590SAdrian Hunter 			name, payload, packet->count);
800a4e92590SAdrian Hunter }
801