162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * intel_pt_pkt_decoder.c: Intel Processor Trace support 462306a36Sopenharmony_ci * Copyright (c) 2013-2014, Intel Corporation. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <stdio.h> 862306a36Sopenharmony_ci#include <string.h> 962306a36Sopenharmony_ci#include <endian.h> 1062306a36Sopenharmony_ci#include <byteswap.h> 1162306a36Sopenharmony_ci#include <linux/compiler.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include "intel-pt-pkt-decoder.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#define BIT(n) (1 << (n)) 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define BIT63 ((uint64_t)1 << 63) 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 2062306a36Sopenharmony_ci#define le16_to_cpu bswap_16 2162306a36Sopenharmony_ci#define le32_to_cpu bswap_32 2262306a36Sopenharmony_ci#define le64_to_cpu bswap_64 2362306a36Sopenharmony_ci#define memcpy_le64(d, s, n) do { \ 2462306a36Sopenharmony_ci memcpy((d), (s), (n)); \ 2562306a36Sopenharmony_ci *(d) = le64_to_cpu(*(d)); \ 2662306a36Sopenharmony_ci} while (0) 2762306a36Sopenharmony_ci#else 2862306a36Sopenharmony_ci#define le16_to_cpu 2962306a36Sopenharmony_ci#define le32_to_cpu 3062306a36Sopenharmony_ci#define le64_to_cpu 3162306a36Sopenharmony_ci#define memcpy_le64 memcpy 3262306a36Sopenharmony_ci#endif 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cistatic const char * const packet_name[] = { 3562306a36Sopenharmony_ci [INTEL_PT_BAD] = "Bad Packet!", 3662306a36Sopenharmony_ci [INTEL_PT_PAD] = "PAD", 3762306a36Sopenharmony_ci [INTEL_PT_TNT] = "TNT", 3862306a36Sopenharmony_ci [INTEL_PT_TIP_PGD] = "TIP.PGD", 3962306a36Sopenharmony_ci [INTEL_PT_TIP_PGE] = "TIP.PGE", 4062306a36Sopenharmony_ci [INTEL_PT_TSC] = "TSC", 4162306a36Sopenharmony_ci [INTEL_PT_TMA] = "TMA", 4262306a36Sopenharmony_ci [INTEL_PT_MODE_EXEC] = "MODE.Exec", 4362306a36Sopenharmony_ci [INTEL_PT_MODE_TSX] = "MODE.TSX", 4462306a36Sopenharmony_ci [INTEL_PT_MTC] = "MTC", 4562306a36Sopenharmony_ci [INTEL_PT_TIP] = "TIP", 4662306a36Sopenharmony_ci [INTEL_PT_FUP] = "FUP", 4762306a36Sopenharmony_ci [INTEL_PT_CYC] = "CYC", 4862306a36Sopenharmony_ci [INTEL_PT_VMCS] = "VMCS", 4962306a36Sopenharmony_ci [INTEL_PT_PSB] = "PSB", 5062306a36Sopenharmony_ci [INTEL_PT_PSBEND] = "PSBEND", 5162306a36Sopenharmony_ci [INTEL_PT_CBR] = "CBR", 5262306a36Sopenharmony_ci [INTEL_PT_TRACESTOP] = "TraceSTOP", 5362306a36Sopenharmony_ci [INTEL_PT_PIP] = "PIP", 5462306a36Sopenharmony_ci [INTEL_PT_OVF] = "OVF", 5562306a36Sopenharmony_ci [INTEL_PT_MNT] = "MNT", 5662306a36Sopenharmony_ci [INTEL_PT_PTWRITE] = "PTWRITE", 5762306a36Sopenharmony_ci [INTEL_PT_PTWRITE_IP] = "PTWRITE", 5862306a36Sopenharmony_ci [INTEL_PT_EXSTOP] = "EXSTOP", 5962306a36Sopenharmony_ci [INTEL_PT_EXSTOP_IP] = "EXSTOP", 6062306a36Sopenharmony_ci [INTEL_PT_MWAIT] = "MWAIT", 6162306a36Sopenharmony_ci [INTEL_PT_PWRE] = "PWRE", 6262306a36Sopenharmony_ci [INTEL_PT_PWRX] = "PWRX", 6362306a36Sopenharmony_ci [INTEL_PT_BBP] = "BBP", 6462306a36Sopenharmony_ci [INTEL_PT_BIP] = "BIP", 6562306a36Sopenharmony_ci [INTEL_PT_BEP] = "BEP", 6662306a36Sopenharmony_ci [INTEL_PT_BEP_IP] = "BEP", 6762306a36Sopenharmony_ci [INTEL_PT_CFE] = "CFE", 6862306a36Sopenharmony_ci [INTEL_PT_CFE_IP] = "CFE", 6962306a36Sopenharmony_ci [INTEL_PT_EVD] = "EVD", 7062306a36Sopenharmony_ci}; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ciconst char *intel_pt_pkt_name(enum intel_pt_pkt_type type) 7362306a36Sopenharmony_ci{ 7462306a36Sopenharmony_ci return packet_name[type]; 7562306a36Sopenharmony_ci} 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic int intel_pt_get_long_tnt(const unsigned char *buf, size_t len, 7862306a36Sopenharmony_ci struct intel_pt_pkt *packet) 7962306a36Sopenharmony_ci{ 8062306a36Sopenharmony_ci uint64_t payload; 8162306a36Sopenharmony_ci int count; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci if (len < 8) 8462306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci payload = le64_to_cpu(*(uint64_t *)buf); 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci for (count = 47; count; count--) { 8962306a36Sopenharmony_ci if (payload & BIT63) 9062306a36Sopenharmony_ci break; 9162306a36Sopenharmony_ci payload <<= 1; 9262306a36Sopenharmony_ci } 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci packet->type = INTEL_PT_TNT; 9562306a36Sopenharmony_ci packet->count = count; 9662306a36Sopenharmony_ci packet->payload = payload << 1; 9762306a36Sopenharmony_ci return 8; 9862306a36Sopenharmony_ci} 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cistatic int intel_pt_get_pip(const unsigned char *buf, size_t len, 10162306a36Sopenharmony_ci struct intel_pt_pkt *packet) 10262306a36Sopenharmony_ci{ 10362306a36Sopenharmony_ci uint64_t payload = 0; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci if (len < 8) 10662306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci packet->type = INTEL_PT_PIP; 10962306a36Sopenharmony_ci memcpy_le64(&payload, buf + 2, 6); 11062306a36Sopenharmony_ci packet->payload = payload; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci return 8; 11362306a36Sopenharmony_ci} 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_cistatic int intel_pt_get_tracestop(struct intel_pt_pkt *packet) 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci packet->type = INTEL_PT_TRACESTOP; 11862306a36Sopenharmony_ci return 2; 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cistatic int intel_pt_get_cbr(const unsigned char *buf, size_t len, 12262306a36Sopenharmony_ci struct intel_pt_pkt *packet) 12362306a36Sopenharmony_ci{ 12462306a36Sopenharmony_ci if (len < 4) 12562306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 12662306a36Sopenharmony_ci packet->type = INTEL_PT_CBR; 12762306a36Sopenharmony_ci packet->payload = le16_to_cpu(*(uint16_t *)(buf + 2)); 12862306a36Sopenharmony_ci return 4; 12962306a36Sopenharmony_ci} 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cistatic int intel_pt_get_vmcs(const unsigned char *buf, size_t len, 13262306a36Sopenharmony_ci struct intel_pt_pkt *packet) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci unsigned int count = (52 - 5) >> 3; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci if (count < 1 || count > 7) 13762306a36Sopenharmony_ci return INTEL_PT_BAD_PACKET; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci if (len < count + 2) 14062306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci packet->type = INTEL_PT_VMCS; 14362306a36Sopenharmony_ci packet->count = count; 14462306a36Sopenharmony_ci memcpy_le64(&packet->payload, buf + 2, count); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci return count + 2; 14762306a36Sopenharmony_ci} 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cistatic int intel_pt_get_ovf(struct intel_pt_pkt *packet) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci packet->type = INTEL_PT_OVF; 15262306a36Sopenharmony_ci return 2; 15362306a36Sopenharmony_ci} 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistatic int intel_pt_get_psb(const unsigned char *buf, size_t len, 15662306a36Sopenharmony_ci struct intel_pt_pkt *packet) 15762306a36Sopenharmony_ci{ 15862306a36Sopenharmony_ci int i; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci if (len < 16) 16162306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci for (i = 2; i < 16; i += 2) { 16462306a36Sopenharmony_ci if (buf[i] != 2 || buf[i + 1] != 0x82) 16562306a36Sopenharmony_ci return INTEL_PT_BAD_PACKET; 16662306a36Sopenharmony_ci } 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci packet->type = INTEL_PT_PSB; 16962306a36Sopenharmony_ci return 16; 17062306a36Sopenharmony_ci} 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_cistatic int intel_pt_get_psbend(struct intel_pt_pkt *packet) 17362306a36Sopenharmony_ci{ 17462306a36Sopenharmony_ci packet->type = INTEL_PT_PSBEND; 17562306a36Sopenharmony_ci return 2; 17662306a36Sopenharmony_ci} 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cistatic int intel_pt_get_tma(const unsigned char *buf, size_t len, 17962306a36Sopenharmony_ci struct intel_pt_pkt *packet) 18062306a36Sopenharmony_ci{ 18162306a36Sopenharmony_ci if (len < 7) 18262306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci packet->type = INTEL_PT_TMA; 18562306a36Sopenharmony_ci packet->payload = buf[2] | (buf[3] << 8); 18662306a36Sopenharmony_ci packet->count = buf[5] | ((buf[6] & BIT(0)) << 8); 18762306a36Sopenharmony_ci return 7; 18862306a36Sopenharmony_ci} 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_cistatic int intel_pt_get_pad(struct intel_pt_pkt *packet) 19162306a36Sopenharmony_ci{ 19262306a36Sopenharmony_ci packet->type = INTEL_PT_PAD; 19362306a36Sopenharmony_ci return 1; 19462306a36Sopenharmony_ci} 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_cistatic int intel_pt_get_mnt(const unsigned char *buf, size_t len, 19762306a36Sopenharmony_ci struct intel_pt_pkt *packet) 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci if (len < 11) 20062306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 20162306a36Sopenharmony_ci packet->type = INTEL_PT_MNT; 20262306a36Sopenharmony_ci memcpy_le64(&packet->payload, buf + 3, 8); 20362306a36Sopenharmony_ci return 11; 20462306a36Sopenharmony_ci} 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_cistatic int intel_pt_get_3byte(const unsigned char *buf, size_t len, 20762306a36Sopenharmony_ci struct intel_pt_pkt *packet) 20862306a36Sopenharmony_ci{ 20962306a36Sopenharmony_ci if (len < 3) 21062306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci switch (buf[2]) { 21362306a36Sopenharmony_ci case 0x88: /* MNT */ 21462306a36Sopenharmony_ci return intel_pt_get_mnt(buf, len, packet); 21562306a36Sopenharmony_ci default: 21662306a36Sopenharmony_ci return INTEL_PT_BAD_PACKET; 21762306a36Sopenharmony_ci } 21862306a36Sopenharmony_ci} 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_cistatic int intel_pt_get_ptwrite(const unsigned char *buf, size_t len, 22162306a36Sopenharmony_ci struct intel_pt_pkt *packet) 22262306a36Sopenharmony_ci{ 22362306a36Sopenharmony_ci packet->count = (buf[1] >> 5) & 0x3; 22462306a36Sopenharmony_ci packet->type = buf[1] & BIT(7) ? INTEL_PT_PTWRITE_IP : 22562306a36Sopenharmony_ci INTEL_PT_PTWRITE; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci switch (packet->count) { 22862306a36Sopenharmony_ci case 0: 22962306a36Sopenharmony_ci if (len < 6) 23062306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 23162306a36Sopenharmony_ci packet->payload = le32_to_cpu(*(uint32_t *)(buf + 2)); 23262306a36Sopenharmony_ci return 6; 23362306a36Sopenharmony_ci case 1: 23462306a36Sopenharmony_ci if (len < 10) 23562306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 23662306a36Sopenharmony_ci packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2)); 23762306a36Sopenharmony_ci return 10; 23862306a36Sopenharmony_ci default: 23962306a36Sopenharmony_ci return INTEL_PT_BAD_PACKET; 24062306a36Sopenharmony_ci } 24162306a36Sopenharmony_ci} 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_cistatic int intel_pt_get_exstop(struct intel_pt_pkt *packet) 24462306a36Sopenharmony_ci{ 24562306a36Sopenharmony_ci packet->type = INTEL_PT_EXSTOP; 24662306a36Sopenharmony_ci return 2; 24762306a36Sopenharmony_ci} 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_cistatic int intel_pt_get_exstop_ip(struct intel_pt_pkt *packet) 25062306a36Sopenharmony_ci{ 25162306a36Sopenharmony_ci packet->type = INTEL_PT_EXSTOP_IP; 25262306a36Sopenharmony_ci return 2; 25362306a36Sopenharmony_ci} 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_cistatic int intel_pt_get_mwait(const unsigned char *buf, size_t len, 25662306a36Sopenharmony_ci struct intel_pt_pkt *packet) 25762306a36Sopenharmony_ci{ 25862306a36Sopenharmony_ci if (len < 10) 25962306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 26062306a36Sopenharmony_ci packet->type = INTEL_PT_MWAIT; 26162306a36Sopenharmony_ci packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2)); 26262306a36Sopenharmony_ci return 10; 26362306a36Sopenharmony_ci} 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_cistatic int intel_pt_get_pwre(const unsigned char *buf, size_t len, 26662306a36Sopenharmony_ci struct intel_pt_pkt *packet) 26762306a36Sopenharmony_ci{ 26862306a36Sopenharmony_ci if (len < 4) 26962306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 27062306a36Sopenharmony_ci packet->type = INTEL_PT_PWRE; 27162306a36Sopenharmony_ci memcpy_le64(&packet->payload, buf + 2, 2); 27262306a36Sopenharmony_ci return 4; 27362306a36Sopenharmony_ci} 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_cistatic int intel_pt_get_pwrx(const unsigned char *buf, size_t len, 27662306a36Sopenharmony_ci struct intel_pt_pkt *packet) 27762306a36Sopenharmony_ci{ 27862306a36Sopenharmony_ci if (len < 7) 27962306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 28062306a36Sopenharmony_ci packet->type = INTEL_PT_PWRX; 28162306a36Sopenharmony_ci memcpy_le64(&packet->payload, buf + 2, 5); 28262306a36Sopenharmony_ci return 7; 28362306a36Sopenharmony_ci} 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_cistatic int intel_pt_get_bbp(const unsigned char *buf, size_t len, 28662306a36Sopenharmony_ci struct intel_pt_pkt *packet) 28762306a36Sopenharmony_ci{ 28862306a36Sopenharmony_ci if (len < 3) 28962306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 29062306a36Sopenharmony_ci packet->type = INTEL_PT_BBP; 29162306a36Sopenharmony_ci packet->count = buf[2] >> 7; 29262306a36Sopenharmony_ci packet->payload = buf[2] & 0x1f; 29362306a36Sopenharmony_ci return 3; 29462306a36Sopenharmony_ci} 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_cistatic int intel_pt_get_bip_4(const unsigned char *buf, size_t len, 29762306a36Sopenharmony_ci struct intel_pt_pkt *packet) 29862306a36Sopenharmony_ci{ 29962306a36Sopenharmony_ci if (len < 5) 30062306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 30162306a36Sopenharmony_ci packet->type = INTEL_PT_BIP; 30262306a36Sopenharmony_ci packet->count = buf[0] >> 3; 30362306a36Sopenharmony_ci memcpy_le64(&packet->payload, buf + 1, 4); 30462306a36Sopenharmony_ci return 5; 30562306a36Sopenharmony_ci} 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_cistatic int intel_pt_get_bip_8(const unsigned char *buf, size_t len, 30862306a36Sopenharmony_ci struct intel_pt_pkt *packet) 30962306a36Sopenharmony_ci{ 31062306a36Sopenharmony_ci if (len < 9) 31162306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 31262306a36Sopenharmony_ci packet->type = INTEL_PT_BIP; 31362306a36Sopenharmony_ci packet->count = buf[0] >> 3; 31462306a36Sopenharmony_ci memcpy_le64(&packet->payload, buf + 1, 8); 31562306a36Sopenharmony_ci return 9; 31662306a36Sopenharmony_ci} 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_cistatic int intel_pt_get_bep(size_t len, struct intel_pt_pkt *packet) 31962306a36Sopenharmony_ci{ 32062306a36Sopenharmony_ci if (len < 2) 32162306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 32262306a36Sopenharmony_ci packet->type = INTEL_PT_BEP; 32362306a36Sopenharmony_ci return 2; 32462306a36Sopenharmony_ci} 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_cistatic int intel_pt_get_bep_ip(size_t len, struct intel_pt_pkt *packet) 32762306a36Sopenharmony_ci{ 32862306a36Sopenharmony_ci if (len < 2) 32962306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 33062306a36Sopenharmony_ci packet->type = INTEL_PT_BEP_IP; 33162306a36Sopenharmony_ci return 2; 33262306a36Sopenharmony_ci} 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_cistatic int intel_pt_get_cfe(const unsigned char *buf, size_t len, 33562306a36Sopenharmony_ci struct intel_pt_pkt *packet) 33662306a36Sopenharmony_ci{ 33762306a36Sopenharmony_ci if (len < 4) 33862306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 33962306a36Sopenharmony_ci packet->type = buf[2] & 0x80 ? INTEL_PT_CFE_IP : INTEL_PT_CFE; 34062306a36Sopenharmony_ci packet->count = buf[2] & 0x1f; 34162306a36Sopenharmony_ci packet->payload = buf[3]; 34262306a36Sopenharmony_ci return 4; 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_cistatic int intel_pt_get_evd(const unsigned char *buf, size_t len, 34662306a36Sopenharmony_ci struct intel_pt_pkt *packet) 34762306a36Sopenharmony_ci{ 34862306a36Sopenharmony_ci if (len < 11) 34962306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 35062306a36Sopenharmony_ci packet->type = INTEL_PT_EVD; 35162306a36Sopenharmony_ci packet->count = buf[2] & 0x3f; 35262306a36Sopenharmony_ci packet->payload = buf[3]; 35362306a36Sopenharmony_ci memcpy_le64(&packet->payload, buf + 3, 8); 35462306a36Sopenharmony_ci return 11; 35562306a36Sopenharmony_ci} 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_cistatic int intel_pt_get_ext(const unsigned char *buf, size_t len, 35862306a36Sopenharmony_ci struct intel_pt_pkt *packet) 35962306a36Sopenharmony_ci{ 36062306a36Sopenharmony_ci if (len < 2) 36162306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci if ((buf[1] & 0x1f) == 0x12) 36462306a36Sopenharmony_ci return intel_pt_get_ptwrite(buf, len, packet); 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci switch (buf[1]) { 36762306a36Sopenharmony_ci case 0xa3: /* Long TNT */ 36862306a36Sopenharmony_ci return intel_pt_get_long_tnt(buf, len, packet); 36962306a36Sopenharmony_ci case 0x43: /* PIP */ 37062306a36Sopenharmony_ci return intel_pt_get_pip(buf, len, packet); 37162306a36Sopenharmony_ci case 0x83: /* TraceStop */ 37262306a36Sopenharmony_ci return intel_pt_get_tracestop(packet); 37362306a36Sopenharmony_ci case 0x03: /* CBR */ 37462306a36Sopenharmony_ci return intel_pt_get_cbr(buf, len, packet); 37562306a36Sopenharmony_ci case 0xc8: /* VMCS */ 37662306a36Sopenharmony_ci return intel_pt_get_vmcs(buf, len, packet); 37762306a36Sopenharmony_ci case 0xf3: /* OVF */ 37862306a36Sopenharmony_ci return intel_pt_get_ovf(packet); 37962306a36Sopenharmony_ci case 0x82: /* PSB */ 38062306a36Sopenharmony_ci return intel_pt_get_psb(buf, len, packet); 38162306a36Sopenharmony_ci case 0x23: /* PSBEND */ 38262306a36Sopenharmony_ci return intel_pt_get_psbend(packet); 38362306a36Sopenharmony_ci case 0x73: /* TMA */ 38462306a36Sopenharmony_ci return intel_pt_get_tma(buf, len, packet); 38562306a36Sopenharmony_ci case 0xC3: /* 3-byte header */ 38662306a36Sopenharmony_ci return intel_pt_get_3byte(buf, len, packet); 38762306a36Sopenharmony_ci case 0x62: /* EXSTOP no IP */ 38862306a36Sopenharmony_ci return intel_pt_get_exstop(packet); 38962306a36Sopenharmony_ci case 0xE2: /* EXSTOP with IP */ 39062306a36Sopenharmony_ci return intel_pt_get_exstop_ip(packet); 39162306a36Sopenharmony_ci case 0xC2: /* MWAIT */ 39262306a36Sopenharmony_ci return intel_pt_get_mwait(buf, len, packet); 39362306a36Sopenharmony_ci case 0x22: /* PWRE */ 39462306a36Sopenharmony_ci return intel_pt_get_pwre(buf, len, packet); 39562306a36Sopenharmony_ci case 0xA2: /* PWRX */ 39662306a36Sopenharmony_ci return intel_pt_get_pwrx(buf, len, packet); 39762306a36Sopenharmony_ci case 0x63: /* BBP */ 39862306a36Sopenharmony_ci return intel_pt_get_bbp(buf, len, packet); 39962306a36Sopenharmony_ci case 0x33: /* BEP no IP */ 40062306a36Sopenharmony_ci return intel_pt_get_bep(len, packet); 40162306a36Sopenharmony_ci case 0xb3: /* BEP with IP */ 40262306a36Sopenharmony_ci return intel_pt_get_bep_ip(len, packet); 40362306a36Sopenharmony_ci case 0x13: /* CFE */ 40462306a36Sopenharmony_ci return intel_pt_get_cfe(buf, len, packet); 40562306a36Sopenharmony_ci case 0x53: /* EVD */ 40662306a36Sopenharmony_ci return intel_pt_get_evd(buf, len, packet); 40762306a36Sopenharmony_ci default: 40862306a36Sopenharmony_ci return INTEL_PT_BAD_PACKET; 40962306a36Sopenharmony_ci } 41062306a36Sopenharmony_ci} 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_cistatic int intel_pt_get_short_tnt(unsigned int byte, 41362306a36Sopenharmony_ci struct intel_pt_pkt *packet) 41462306a36Sopenharmony_ci{ 41562306a36Sopenharmony_ci int count; 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci for (count = 6; count; count--) { 41862306a36Sopenharmony_ci if (byte & BIT(7)) 41962306a36Sopenharmony_ci break; 42062306a36Sopenharmony_ci byte <<= 1; 42162306a36Sopenharmony_ci } 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci packet->type = INTEL_PT_TNT; 42462306a36Sopenharmony_ci packet->count = count; 42562306a36Sopenharmony_ci packet->payload = (uint64_t)byte << 57; 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci return 1; 42862306a36Sopenharmony_ci} 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_cistatic int intel_pt_get_cyc(unsigned int byte, const unsigned char *buf, 43162306a36Sopenharmony_ci size_t len, struct intel_pt_pkt *packet) 43262306a36Sopenharmony_ci{ 43362306a36Sopenharmony_ci unsigned int offs = 1, shift; 43462306a36Sopenharmony_ci uint64_t payload = byte >> 3; 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci byte >>= 2; 43762306a36Sopenharmony_ci len -= 1; 43862306a36Sopenharmony_ci for (shift = 5; byte & 1; shift += 7) { 43962306a36Sopenharmony_ci if (offs > 9) 44062306a36Sopenharmony_ci return INTEL_PT_BAD_PACKET; 44162306a36Sopenharmony_ci if (len < offs) 44262306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 44362306a36Sopenharmony_ci byte = buf[offs++]; 44462306a36Sopenharmony_ci payload |= ((uint64_t)byte >> 1) << shift; 44562306a36Sopenharmony_ci } 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci packet->type = INTEL_PT_CYC; 44862306a36Sopenharmony_ci packet->payload = payload; 44962306a36Sopenharmony_ci return offs; 45062306a36Sopenharmony_ci} 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_cistatic int intel_pt_get_ip(enum intel_pt_pkt_type type, unsigned int byte, 45362306a36Sopenharmony_ci const unsigned char *buf, size_t len, 45462306a36Sopenharmony_ci struct intel_pt_pkt *packet) 45562306a36Sopenharmony_ci{ 45662306a36Sopenharmony_ci int ip_len; 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci packet->count = byte >> 5; 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci switch (packet->count) { 46162306a36Sopenharmony_ci case 0: 46262306a36Sopenharmony_ci ip_len = 0; 46362306a36Sopenharmony_ci break; 46462306a36Sopenharmony_ci case 1: 46562306a36Sopenharmony_ci if (len < 3) 46662306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 46762306a36Sopenharmony_ci ip_len = 2; 46862306a36Sopenharmony_ci packet->payload = le16_to_cpu(*(uint16_t *)(buf + 1)); 46962306a36Sopenharmony_ci break; 47062306a36Sopenharmony_ci case 2: 47162306a36Sopenharmony_ci if (len < 5) 47262306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 47362306a36Sopenharmony_ci ip_len = 4; 47462306a36Sopenharmony_ci packet->payload = le32_to_cpu(*(uint32_t *)(buf + 1)); 47562306a36Sopenharmony_ci break; 47662306a36Sopenharmony_ci case 3: 47762306a36Sopenharmony_ci case 4: 47862306a36Sopenharmony_ci if (len < 7) 47962306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 48062306a36Sopenharmony_ci ip_len = 6; 48162306a36Sopenharmony_ci memcpy_le64(&packet->payload, buf + 1, 6); 48262306a36Sopenharmony_ci break; 48362306a36Sopenharmony_ci case 6: 48462306a36Sopenharmony_ci if (len < 9) 48562306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 48662306a36Sopenharmony_ci ip_len = 8; 48762306a36Sopenharmony_ci packet->payload = le64_to_cpu(*(uint64_t *)(buf + 1)); 48862306a36Sopenharmony_ci break; 48962306a36Sopenharmony_ci default: 49062306a36Sopenharmony_ci return INTEL_PT_BAD_PACKET; 49162306a36Sopenharmony_ci } 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_ci packet->type = type; 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci return ip_len + 1; 49662306a36Sopenharmony_ci} 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_cistatic int intel_pt_get_mode(const unsigned char *buf, size_t len, 49962306a36Sopenharmony_ci struct intel_pt_pkt *packet) 50062306a36Sopenharmony_ci{ 50162306a36Sopenharmony_ci if (len < 2) 50262306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci switch (buf[1] >> 5) { 50562306a36Sopenharmony_ci case 0: 50662306a36Sopenharmony_ci packet->type = INTEL_PT_MODE_EXEC; 50762306a36Sopenharmony_ci packet->count = buf[1]; 50862306a36Sopenharmony_ci switch (buf[1] & 3) { 50962306a36Sopenharmony_ci case 0: 51062306a36Sopenharmony_ci packet->payload = 16; 51162306a36Sopenharmony_ci break; 51262306a36Sopenharmony_ci case 1: 51362306a36Sopenharmony_ci packet->payload = 64; 51462306a36Sopenharmony_ci break; 51562306a36Sopenharmony_ci case 2: 51662306a36Sopenharmony_ci packet->payload = 32; 51762306a36Sopenharmony_ci break; 51862306a36Sopenharmony_ci default: 51962306a36Sopenharmony_ci return INTEL_PT_BAD_PACKET; 52062306a36Sopenharmony_ci } 52162306a36Sopenharmony_ci break; 52262306a36Sopenharmony_ci case 1: 52362306a36Sopenharmony_ci packet->type = INTEL_PT_MODE_TSX; 52462306a36Sopenharmony_ci if ((buf[1] & 3) == 3) 52562306a36Sopenharmony_ci return INTEL_PT_BAD_PACKET; 52662306a36Sopenharmony_ci packet->payload = buf[1] & 3; 52762306a36Sopenharmony_ci break; 52862306a36Sopenharmony_ci default: 52962306a36Sopenharmony_ci return INTEL_PT_BAD_PACKET; 53062306a36Sopenharmony_ci } 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci return 2; 53362306a36Sopenharmony_ci} 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_cistatic int intel_pt_get_tsc(const unsigned char *buf, size_t len, 53662306a36Sopenharmony_ci struct intel_pt_pkt *packet) 53762306a36Sopenharmony_ci{ 53862306a36Sopenharmony_ci if (len < 8) 53962306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 54062306a36Sopenharmony_ci packet->type = INTEL_PT_TSC; 54162306a36Sopenharmony_ci memcpy_le64(&packet->payload, buf + 1, 7); 54262306a36Sopenharmony_ci return 8; 54362306a36Sopenharmony_ci} 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_cistatic int intel_pt_get_mtc(const unsigned char *buf, size_t len, 54662306a36Sopenharmony_ci struct intel_pt_pkt *packet) 54762306a36Sopenharmony_ci{ 54862306a36Sopenharmony_ci if (len < 2) 54962306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 55062306a36Sopenharmony_ci packet->type = INTEL_PT_MTC; 55162306a36Sopenharmony_ci packet->payload = buf[1]; 55262306a36Sopenharmony_ci return 2; 55362306a36Sopenharmony_ci} 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_cistatic int intel_pt_do_get_packet(const unsigned char *buf, size_t len, 55662306a36Sopenharmony_ci struct intel_pt_pkt *packet, 55762306a36Sopenharmony_ci enum intel_pt_pkt_ctx ctx) 55862306a36Sopenharmony_ci{ 55962306a36Sopenharmony_ci unsigned int byte; 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci memset(packet, 0, sizeof(struct intel_pt_pkt)); 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci if (!len) 56462306a36Sopenharmony_ci return INTEL_PT_NEED_MORE_BYTES; 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci byte = buf[0]; 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ci switch (ctx) { 56962306a36Sopenharmony_ci case INTEL_PT_NO_CTX: 57062306a36Sopenharmony_ci break; 57162306a36Sopenharmony_ci case INTEL_PT_BLK_4_CTX: 57262306a36Sopenharmony_ci if ((byte & 0x7) == 4) 57362306a36Sopenharmony_ci return intel_pt_get_bip_4(buf, len, packet); 57462306a36Sopenharmony_ci break; 57562306a36Sopenharmony_ci case INTEL_PT_BLK_8_CTX: 57662306a36Sopenharmony_ci if ((byte & 0x7) == 4) 57762306a36Sopenharmony_ci return intel_pt_get_bip_8(buf, len, packet); 57862306a36Sopenharmony_ci break; 57962306a36Sopenharmony_ci default: 58062306a36Sopenharmony_ci break; 58162306a36Sopenharmony_ci } 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci if (!(byte & BIT(0))) { 58462306a36Sopenharmony_ci if (byte == 0) 58562306a36Sopenharmony_ci return intel_pt_get_pad(packet); 58662306a36Sopenharmony_ci if (byte == 2) 58762306a36Sopenharmony_ci return intel_pt_get_ext(buf, len, packet); 58862306a36Sopenharmony_ci return intel_pt_get_short_tnt(byte, packet); 58962306a36Sopenharmony_ci } 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ci if ((byte & 2)) 59262306a36Sopenharmony_ci return intel_pt_get_cyc(byte, buf, len, packet); 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ci switch (byte & 0x1f) { 59562306a36Sopenharmony_ci case 0x0D: 59662306a36Sopenharmony_ci return intel_pt_get_ip(INTEL_PT_TIP, byte, buf, len, packet); 59762306a36Sopenharmony_ci case 0x11: 59862306a36Sopenharmony_ci return intel_pt_get_ip(INTEL_PT_TIP_PGE, byte, buf, len, 59962306a36Sopenharmony_ci packet); 60062306a36Sopenharmony_ci case 0x01: 60162306a36Sopenharmony_ci return intel_pt_get_ip(INTEL_PT_TIP_PGD, byte, buf, len, 60262306a36Sopenharmony_ci packet); 60362306a36Sopenharmony_ci case 0x1D: 60462306a36Sopenharmony_ci return intel_pt_get_ip(INTEL_PT_FUP, byte, buf, len, packet); 60562306a36Sopenharmony_ci case 0x19: 60662306a36Sopenharmony_ci switch (byte) { 60762306a36Sopenharmony_ci case 0x99: 60862306a36Sopenharmony_ci return intel_pt_get_mode(buf, len, packet); 60962306a36Sopenharmony_ci case 0x19: 61062306a36Sopenharmony_ci return intel_pt_get_tsc(buf, len, packet); 61162306a36Sopenharmony_ci case 0x59: 61262306a36Sopenharmony_ci return intel_pt_get_mtc(buf, len, packet); 61362306a36Sopenharmony_ci default: 61462306a36Sopenharmony_ci return INTEL_PT_BAD_PACKET; 61562306a36Sopenharmony_ci } 61662306a36Sopenharmony_ci default: 61762306a36Sopenharmony_ci return INTEL_PT_BAD_PACKET; 61862306a36Sopenharmony_ci } 61962306a36Sopenharmony_ci} 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_civoid intel_pt_upd_pkt_ctx(const struct intel_pt_pkt *packet, 62262306a36Sopenharmony_ci enum intel_pt_pkt_ctx *ctx) 62362306a36Sopenharmony_ci{ 62462306a36Sopenharmony_ci switch (packet->type) { 62562306a36Sopenharmony_ci case INTEL_PT_BAD: 62662306a36Sopenharmony_ci case INTEL_PT_PAD: 62762306a36Sopenharmony_ci case INTEL_PT_TSC: 62862306a36Sopenharmony_ci case INTEL_PT_TMA: 62962306a36Sopenharmony_ci case INTEL_PT_MTC: 63062306a36Sopenharmony_ci case INTEL_PT_FUP: 63162306a36Sopenharmony_ci case INTEL_PT_CYC: 63262306a36Sopenharmony_ci case INTEL_PT_CBR: 63362306a36Sopenharmony_ci case INTEL_PT_MNT: 63462306a36Sopenharmony_ci case INTEL_PT_EXSTOP: 63562306a36Sopenharmony_ci case INTEL_PT_EXSTOP_IP: 63662306a36Sopenharmony_ci case INTEL_PT_PWRE: 63762306a36Sopenharmony_ci case INTEL_PT_PWRX: 63862306a36Sopenharmony_ci case INTEL_PT_BIP: 63962306a36Sopenharmony_ci break; 64062306a36Sopenharmony_ci case INTEL_PT_TNT: 64162306a36Sopenharmony_ci case INTEL_PT_TIP: 64262306a36Sopenharmony_ci case INTEL_PT_TIP_PGD: 64362306a36Sopenharmony_ci case INTEL_PT_TIP_PGE: 64462306a36Sopenharmony_ci case INTEL_PT_MODE_EXEC: 64562306a36Sopenharmony_ci case INTEL_PT_MODE_TSX: 64662306a36Sopenharmony_ci case INTEL_PT_PIP: 64762306a36Sopenharmony_ci case INTEL_PT_OVF: 64862306a36Sopenharmony_ci case INTEL_PT_VMCS: 64962306a36Sopenharmony_ci case INTEL_PT_TRACESTOP: 65062306a36Sopenharmony_ci case INTEL_PT_PSB: 65162306a36Sopenharmony_ci case INTEL_PT_PSBEND: 65262306a36Sopenharmony_ci case INTEL_PT_PTWRITE: 65362306a36Sopenharmony_ci case INTEL_PT_PTWRITE_IP: 65462306a36Sopenharmony_ci case INTEL_PT_MWAIT: 65562306a36Sopenharmony_ci case INTEL_PT_BEP: 65662306a36Sopenharmony_ci case INTEL_PT_BEP_IP: 65762306a36Sopenharmony_ci case INTEL_PT_CFE: 65862306a36Sopenharmony_ci case INTEL_PT_CFE_IP: 65962306a36Sopenharmony_ci case INTEL_PT_EVD: 66062306a36Sopenharmony_ci *ctx = INTEL_PT_NO_CTX; 66162306a36Sopenharmony_ci break; 66262306a36Sopenharmony_ci case INTEL_PT_BBP: 66362306a36Sopenharmony_ci if (packet->count) 66462306a36Sopenharmony_ci *ctx = INTEL_PT_BLK_4_CTX; 66562306a36Sopenharmony_ci else 66662306a36Sopenharmony_ci *ctx = INTEL_PT_BLK_8_CTX; 66762306a36Sopenharmony_ci break; 66862306a36Sopenharmony_ci default: 66962306a36Sopenharmony_ci break; 67062306a36Sopenharmony_ci } 67162306a36Sopenharmony_ci} 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_ciint intel_pt_get_packet(const unsigned char *buf, size_t len, 67462306a36Sopenharmony_ci struct intel_pt_pkt *packet, enum intel_pt_pkt_ctx *ctx) 67562306a36Sopenharmony_ci{ 67662306a36Sopenharmony_ci int ret; 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci ret = intel_pt_do_get_packet(buf, len, packet, *ctx); 67962306a36Sopenharmony_ci if (ret > 0) { 68062306a36Sopenharmony_ci while (ret < 8 && len > (size_t)ret && !buf[ret]) 68162306a36Sopenharmony_ci ret += 1; 68262306a36Sopenharmony_ci intel_pt_upd_pkt_ctx(packet, ctx); 68362306a36Sopenharmony_ci } 68462306a36Sopenharmony_ci return ret; 68562306a36Sopenharmony_ci} 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ciint intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf, 68862306a36Sopenharmony_ci size_t buf_len) 68962306a36Sopenharmony_ci{ 69062306a36Sopenharmony_ci int ret, i, nr; 69162306a36Sopenharmony_ci unsigned long long payload = packet->payload; 69262306a36Sopenharmony_ci const char *name = intel_pt_pkt_name(packet->type); 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_ci switch (packet->type) { 69562306a36Sopenharmony_ci case INTEL_PT_BAD: 69662306a36Sopenharmony_ci case INTEL_PT_PAD: 69762306a36Sopenharmony_ci case INTEL_PT_PSB: 69862306a36Sopenharmony_ci case INTEL_PT_PSBEND: 69962306a36Sopenharmony_ci case INTEL_PT_TRACESTOP: 70062306a36Sopenharmony_ci case INTEL_PT_OVF: 70162306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s", name); 70262306a36Sopenharmony_ci case INTEL_PT_TNT: { 70362306a36Sopenharmony_ci size_t blen = buf_len; 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_ci ret = snprintf(buf, blen, "%s ", name); 70662306a36Sopenharmony_ci if (ret < 0) 70762306a36Sopenharmony_ci return ret; 70862306a36Sopenharmony_ci buf += ret; 70962306a36Sopenharmony_ci blen -= ret; 71062306a36Sopenharmony_ci for (i = 0; i < packet->count; i++) { 71162306a36Sopenharmony_ci if (payload & BIT63) 71262306a36Sopenharmony_ci ret = snprintf(buf, blen, "T"); 71362306a36Sopenharmony_ci else 71462306a36Sopenharmony_ci ret = snprintf(buf, blen, "N"); 71562306a36Sopenharmony_ci if (ret < 0) 71662306a36Sopenharmony_ci return ret; 71762306a36Sopenharmony_ci buf += ret; 71862306a36Sopenharmony_ci blen -= ret; 71962306a36Sopenharmony_ci payload <<= 1; 72062306a36Sopenharmony_ci } 72162306a36Sopenharmony_ci ret = snprintf(buf, blen, " (%d)", packet->count); 72262306a36Sopenharmony_ci if (ret < 0) 72362306a36Sopenharmony_ci return ret; 72462306a36Sopenharmony_ci blen -= ret; 72562306a36Sopenharmony_ci return buf_len - blen; 72662306a36Sopenharmony_ci } 72762306a36Sopenharmony_ci case INTEL_PT_TIP_PGD: 72862306a36Sopenharmony_ci case INTEL_PT_TIP_PGE: 72962306a36Sopenharmony_ci case INTEL_PT_TIP: 73062306a36Sopenharmony_ci case INTEL_PT_FUP: 73162306a36Sopenharmony_ci if (!(packet->count)) 73262306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s no ip", name); 73362306a36Sopenharmony_ci fallthrough; 73462306a36Sopenharmony_ci case INTEL_PT_CYC: 73562306a36Sopenharmony_ci case INTEL_PT_VMCS: 73662306a36Sopenharmony_ci case INTEL_PT_MTC: 73762306a36Sopenharmony_ci case INTEL_PT_MNT: 73862306a36Sopenharmony_ci case INTEL_PT_CBR: 73962306a36Sopenharmony_ci case INTEL_PT_TSC: 74062306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s 0x%llx", name, payload); 74162306a36Sopenharmony_ci case INTEL_PT_TMA: 74262306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s CTC 0x%x FC 0x%x", name, 74362306a36Sopenharmony_ci (unsigned)payload, packet->count); 74462306a36Sopenharmony_ci case INTEL_PT_MODE_EXEC: 74562306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s IF:%d %lld", 74662306a36Sopenharmony_ci name, !!(packet->count & 4), payload); 74762306a36Sopenharmony_ci case INTEL_PT_MODE_TSX: 74862306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s TXAbort:%u InTX:%u", 74962306a36Sopenharmony_ci name, (unsigned)(payload >> 1) & 1, 75062306a36Sopenharmony_ci (unsigned)payload & 1); 75162306a36Sopenharmony_ci case INTEL_PT_PIP: 75262306a36Sopenharmony_ci nr = packet->payload & INTEL_PT_VMX_NR_FLAG ? 1 : 0; 75362306a36Sopenharmony_ci payload &= ~INTEL_PT_VMX_NR_FLAG; 75462306a36Sopenharmony_ci ret = snprintf(buf, buf_len, "%s 0x%llx (NR=%d)", 75562306a36Sopenharmony_ci name, payload >> 1, nr); 75662306a36Sopenharmony_ci return ret; 75762306a36Sopenharmony_ci case INTEL_PT_PTWRITE: 75862306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s 0x%llx IP:0", name, payload); 75962306a36Sopenharmony_ci case INTEL_PT_PTWRITE_IP: 76062306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s 0x%llx IP:1", name, payload); 76162306a36Sopenharmony_ci case INTEL_PT_BEP: 76262306a36Sopenharmony_ci case INTEL_PT_EXSTOP: 76362306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s IP:0", name); 76462306a36Sopenharmony_ci case INTEL_PT_BEP_IP: 76562306a36Sopenharmony_ci case INTEL_PT_EXSTOP_IP: 76662306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s IP:1", name); 76762306a36Sopenharmony_ci case INTEL_PT_MWAIT: 76862306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s 0x%llx Hints 0x%x Extensions 0x%x", 76962306a36Sopenharmony_ci name, payload, (unsigned int)(payload & 0xff), 77062306a36Sopenharmony_ci (unsigned int)((payload >> 32) & 0x3)); 77162306a36Sopenharmony_ci case INTEL_PT_PWRE: 77262306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s 0x%llx HW:%u CState:%u Sub-CState:%u", 77362306a36Sopenharmony_ci name, payload, !!(payload & 0x80), 77462306a36Sopenharmony_ci (unsigned int)((payload >> 12) & 0xf), 77562306a36Sopenharmony_ci (unsigned int)((payload >> 8) & 0xf)); 77662306a36Sopenharmony_ci case INTEL_PT_PWRX: 77762306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s 0x%llx Last CState:%u Deepest CState:%u Wake Reason 0x%x", 77862306a36Sopenharmony_ci name, payload, 77962306a36Sopenharmony_ci (unsigned int)((payload >> 4) & 0xf), 78062306a36Sopenharmony_ci (unsigned int)(payload & 0xf), 78162306a36Sopenharmony_ci (unsigned int)((payload >> 8) & 0xf)); 78262306a36Sopenharmony_ci case INTEL_PT_BBP: 78362306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s SZ %s-byte Type 0x%llx", 78462306a36Sopenharmony_ci name, packet->count ? "4" : "8", payload); 78562306a36Sopenharmony_ci case INTEL_PT_BIP: 78662306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s ID 0x%02x Value 0x%llx", 78762306a36Sopenharmony_ci name, packet->count, payload); 78862306a36Sopenharmony_ci case INTEL_PT_CFE: 78962306a36Sopenharmony_ci case INTEL_PT_CFE_IP: 79062306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s IP:%d Type 0x%02x Vector 0x%llx", 79162306a36Sopenharmony_ci name, packet->type == INTEL_PT_CFE_IP, packet->count, payload); 79262306a36Sopenharmony_ci case INTEL_PT_EVD: 79362306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s Type 0x%02x Payload 0x%llx", 79462306a36Sopenharmony_ci name, packet->count, payload); 79562306a36Sopenharmony_ci default: 79662306a36Sopenharmony_ci break; 79762306a36Sopenharmony_ci } 79862306a36Sopenharmony_ci return snprintf(buf, buf_len, "%s 0x%llx (%d)", 79962306a36Sopenharmony_ci name, payload, packet->count); 80062306a36Sopenharmony_ci} 801