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