18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright(C) 2015 Linaro Limited. All rights reserved. 48c2ecf20Sopenharmony_ci * Author: Mathieu Poirier <mathieu.poirier@linaro.org> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef INCLUDE__UTIL_PERF_CS_ETM_H__ 88c2ecf20Sopenharmony_ci#define INCLUDE__UTIL_PERF_CS_ETM_H__ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include "util/event.h" 118c2ecf20Sopenharmony_ci#include <linux/bits.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_cistruct perf_session; 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci/* Versionning header in case things need tro change in the future. That way 168c2ecf20Sopenharmony_ci * decoding of old snapshot is still possible. 178c2ecf20Sopenharmony_ci */ 188c2ecf20Sopenharmony_cienum { 198c2ecf20Sopenharmony_ci /* Starting with 0x0 */ 208c2ecf20Sopenharmony_ci CS_HEADER_VERSION_0, 218c2ecf20Sopenharmony_ci /* PMU->type (32 bit), total # of CPUs (32 bit) */ 228c2ecf20Sopenharmony_ci CS_PMU_TYPE_CPUS, 238c2ecf20Sopenharmony_ci CS_ETM_SNAPSHOT, 248c2ecf20Sopenharmony_ci CS_HEADER_VERSION_0_MAX, 258c2ecf20Sopenharmony_ci}; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci/* Beginning of header common to both ETMv3 and V4 */ 288c2ecf20Sopenharmony_cienum { 298c2ecf20Sopenharmony_ci CS_ETM_MAGIC, 308c2ecf20Sopenharmony_ci CS_ETM_CPU, 318c2ecf20Sopenharmony_ci}; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci/* ETMv3/PTM metadata */ 348c2ecf20Sopenharmony_cienum { 358c2ecf20Sopenharmony_ci /* Dynamic, configurable parameters */ 368c2ecf20Sopenharmony_ci CS_ETM_ETMCR = CS_ETM_CPU + 1, 378c2ecf20Sopenharmony_ci CS_ETM_ETMTRACEIDR, 388c2ecf20Sopenharmony_ci /* RO, taken from sysFS */ 398c2ecf20Sopenharmony_ci CS_ETM_ETMCCER, 408c2ecf20Sopenharmony_ci CS_ETM_ETMIDR, 418c2ecf20Sopenharmony_ci CS_ETM_PRIV_MAX, 428c2ecf20Sopenharmony_ci}; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci/* ETMv4 metadata */ 458c2ecf20Sopenharmony_cienum { 468c2ecf20Sopenharmony_ci /* Dynamic, configurable parameters */ 478c2ecf20Sopenharmony_ci CS_ETMV4_TRCCONFIGR = CS_ETM_CPU + 1, 488c2ecf20Sopenharmony_ci CS_ETMV4_TRCTRACEIDR, 498c2ecf20Sopenharmony_ci /* RO, taken from sysFS */ 508c2ecf20Sopenharmony_ci CS_ETMV4_TRCIDR0, 518c2ecf20Sopenharmony_ci CS_ETMV4_TRCIDR1, 528c2ecf20Sopenharmony_ci CS_ETMV4_TRCIDR2, 538c2ecf20Sopenharmony_ci CS_ETMV4_TRCIDR8, 548c2ecf20Sopenharmony_ci CS_ETMV4_TRCAUTHSTATUS, 558c2ecf20Sopenharmony_ci CS_ETMV4_PRIV_MAX, 568c2ecf20Sopenharmony_ci}; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci/* 598c2ecf20Sopenharmony_ci * ETMv3 exception encoding number: 608c2ecf20Sopenharmony_ci * See Embedded Trace Macrocell spcification (ARM IHI 0014Q) 618c2ecf20Sopenharmony_ci * table 7-12 Encoding of Exception[3:0] for non-ARMv7-M processors. 628c2ecf20Sopenharmony_ci */ 638c2ecf20Sopenharmony_cienum { 648c2ecf20Sopenharmony_ci CS_ETMV3_EXC_NONE = 0, 658c2ecf20Sopenharmony_ci CS_ETMV3_EXC_DEBUG_HALT = 1, 668c2ecf20Sopenharmony_ci CS_ETMV3_EXC_SMC = 2, 678c2ecf20Sopenharmony_ci CS_ETMV3_EXC_HYP = 3, 688c2ecf20Sopenharmony_ci CS_ETMV3_EXC_ASYNC_DATA_ABORT = 4, 698c2ecf20Sopenharmony_ci CS_ETMV3_EXC_JAZELLE_THUMBEE = 5, 708c2ecf20Sopenharmony_ci CS_ETMV3_EXC_PE_RESET = 8, 718c2ecf20Sopenharmony_ci CS_ETMV3_EXC_UNDEFINED_INSTR = 9, 728c2ecf20Sopenharmony_ci CS_ETMV3_EXC_SVC = 10, 738c2ecf20Sopenharmony_ci CS_ETMV3_EXC_PREFETCH_ABORT = 11, 748c2ecf20Sopenharmony_ci CS_ETMV3_EXC_DATA_FAULT = 12, 758c2ecf20Sopenharmony_ci CS_ETMV3_EXC_GENERIC = 13, 768c2ecf20Sopenharmony_ci CS_ETMV3_EXC_IRQ = 14, 778c2ecf20Sopenharmony_ci CS_ETMV3_EXC_FIQ = 15, 788c2ecf20Sopenharmony_ci}; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci/* 818c2ecf20Sopenharmony_ci * ETMv4 exception encoding number: 828c2ecf20Sopenharmony_ci * See ARM Embedded Trace Macrocell Architecture Specification (ARM IHI 0064D) 838c2ecf20Sopenharmony_ci * table 6-12 Possible values for the TYPE field in an Exception instruction 848c2ecf20Sopenharmony_ci * trace packet, for ARMv7-A/R and ARMv8-A/R PEs. 858c2ecf20Sopenharmony_ci */ 868c2ecf20Sopenharmony_cienum { 878c2ecf20Sopenharmony_ci CS_ETMV4_EXC_RESET = 0, 888c2ecf20Sopenharmony_ci CS_ETMV4_EXC_DEBUG_HALT = 1, 898c2ecf20Sopenharmony_ci CS_ETMV4_EXC_CALL = 2, 908c2ecf20Sopenharmony_ci CS_ETMV4_EXC_TRAP = 3, 918c2ecf20Sopenharmony_ci CS_ETMV4_EXC_SYSTEM_ERROR = 4, 928c2ecf20Sopenharmony_ci CS_ETMV4_EXC_INST_DEBUG = 6, 938c2ecf20Sopenharmony_ci CS_ETMV4_EXC_DATA_DEBUG = 7, 948c2ecf20Sopenharmony_ci CS_ETMV4_EXC_ALIGNMENT = 10, 958c2ecf20Sopenharmony_ci CS_ETMV4_EXC_INST_FAULT = 11, 968c2ecf20Sopenharmony_ci CS_ETMV4_EXC_DATA_FAULT = 12, 978c2ecf20Sopenharmony_ci CS_ETMV4_EXC_IRQ = 14, 988c2ecf20Sopenharmony_ci CS_ETMV4_EXC_FIQ = 15, 998c2ecf20Sopenharmony_ci CS_ETMV4_EXC_END = 31, 1008c2ecf20Sopenharmony_ci}; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_cienum cs_etm_sample_type { 1038c2ecf20Sopenharmony_ci CS_ETM_EMPTY, 1048c2ecf20Sopenharmony_ci CS_ETM_RANGE, 1058c2ecf20Sopenharmony_ci CS_ETM_DISCONTINUITY, 1068c2ecf20Sopenharmony_ci CS_ETM_EXCEPTION, 1078c2ecf20Sopenharmony_ci CS_ETM_EXCEPTION_RET, 1088c2ecf20Sopenharmony_ci}; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cienum cs_etm_isa { 1118c2ecf20Sopenharmony_ci CS_ETM_ISA_UNKNOWN, 1128c2ecf20Sopenharmony_ci CS_ETM_ISA_A64, 1138c2ecf20Sopenharmony_ci CS_ETM_ISA_A32, 1148c2ecf20Sopenharmony_ci CS_ETM_ISA_T32, 1158c2ecf20Sopenharmony_ci}; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_cistruct cs_etm_queue; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_cistruct cs_etm_packet { 1208c2ecf20Sopenharmony_ci enum cs_etm_sample_type sample_type; 1218c2ecf20Sopenharmony_ci enum cs_etm_isa isa; 1228c2ecf20Sopenharmony_ci u64 start_addr; 1238c2ecf20Sopenharmony_ci u64 end_addr; 1248c2ecf20Sopenharmony_ci u32 instr_count; 1258c2ecf20Sopenharmony_ci u32 last_instr_type; 1268c2ecf20Sopenharmony_ci u32 last_instr_subtype; 1278c2ecf20Sopenharmony_ci u32 flags; 1288c2ecf20Sopenharmony_ci u32 exception_number; 1298c2ecf20Sopenharmony_ci u8 last_instr_cond; 1308c2ecf20Sopenharmony_ci u8 last_instr_taken_branch; 1318c2ecf20Sopenharmony_ci u8 last_instr_size; 1328c2ecf20Sopenharmony_ci u8 trace_chan_id; 1338c2ecf20Sopenharmony_ci int cpu; 1348c2ecf20Sopenharmony_ci}; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci#define CS_ETM_PACKET_MAX_BUFFER 1024 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci/* 1398c2ecf20Sopenharmony_ci * When working with per-thread scenarios the process under trace can 1408c2ecf20Sopenharmony_ci * be scheduled on any CPU and as such, more than one traceID may be 1418c2ecf20Sopenharmony_ci * associated with the same process. Since a traceID of '0' is illegal 1428c2ecf20Sopenharmony_ci * as per the CoreSight architecture, use that specific value to 1438c2ecf20Sopenharmony_ci * identify the queue where all packets (with any traceID) are 1448c2ecf20Sopenharmony_ci * aggregated. 1458c2ecf20Sopenharmony_ci */ 1468c2ecf20Sopenharmony_ci#define CS_ETM_PER_THREAD_TRACEID 0 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistruct cs_etm_packet_queue { 1498c2ecf20Sopenharmony_ci u32 packet_count; 1508c2ecf20Sopenharmony_ci u32 head; 1518c2ecf20Sopenharmony_ci u32 tail; 1528c2ecf20Sopenharmony_ci u32 instr_count; 1538c2ecf20Sopenharmony_ci u64 timestamp; 1548c2ecf20Sopenharmony_ci u64 next_timestamp; 1558c2ecf20Sopenharmony_ci struct cs_etm_packet packet_buffer[CS_ETM_PACKET_MAX_BUFFER]; 1568c2ecf20Sopenharmony_ci}; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci#define KiB(x) ((x) * 1024) 1598c2ecf20Sopenharmony_ci#define MiB(x) ((x) * 1024 * 1024) 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci#define CS_ETM_INVAL_ADDR 0xdeadbeefdeadbeefUL 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci#define BMVAL(val, lsb, msb) ((val & GENMASK(msb, lsb)) >> lsb) 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci#define CS_ETM_HEADER_SIZE (CS_HEADER_VERSION_0_MAX * sizeof(u64)) 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci#define __perf_cs_etmv3_magic 0x3030303030303030ULL 1688c2ecf20Sopenharmony_ci#define __perf_cs_etmv4_magic 0x4040404040404040ULL 1698c2ecf20Sopenharmony_ci#define CS_ETMV3_PRIV_SIZE (CS_ETM_PRIV_MAX * sizeof(u64)) 1708c2ecf20Sopenharmony_ci#define CS_ETMV4_PRIV_SIZE (CS_ETMV4_PRIV_MAX * sizeof(u64)) 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci#ifdef HAVE_CSTRACE_SUPPORT 1738c2ecf20Sopenharmony_ciint cs_etm__process_auxtrace_info(union perf_event *event, 1748c2ecf20Sopenharmony_ci struct perf_session *session); 1758c2ecf20Sopenharmony_ciint cs_etm__get_cpu(u8 trace_chan_id, int *cpu); 1768c2ecf20Sopenharmony_ciint cs_etm__etmq_set_tid(struct cs_etm_queue *etmq, 1778c2ecf20Sopenharmony_ci pid_t tid, u8 trace_chan_id); 1788c2ecf20Sopenharmony_cibool cs_etm__etmq_is_timeless(struct cs_etm_queue *etmq); 1798c2ecf20Sopenharmony_civoid cs_etm__etmq_set_traceid_queue_timestamp(struct cs_etm_queue *etmq, 1808c2ecf20Sopenharmony_ci u8 trace_chan_id); 1818c2ecf20Sopenharmony_cistruct cs_etm_packet_queue 1828c2ecf20Sopenharmony_ci*cs_etm__etmq_get_packet_queue(struct cs_etm_queue *etmq, u8 trace_chan_id); 1838c2ecf20Sopenharmony_ci#else 1848c2ecf20Sopenharmony_cistatic inline int 1858c2ecf20Sopenharmony_cics_etm__process_auxtrace_info(union perf_event *event __maybe_unused, 1868c2ecf20Sopenharmony_ci struct perf_session *session __maybe_unused) 1878c2ecf20Sopenharmony_ci{ 1888c2ecf20Sopenharmony_ci return -1; 1898c2ecf20Sopenharmony_ci} 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_cistatic inline int cs_etm__get_cpu(u8 trace_chan_id __maybe_unused, 1928c2ecf20Sopenharmony_ci int *cpu __maybe_unused) 1938c2ecf20Sopenharmony_ci{ 1948c2ecf20Sopenharmony_ci return -1; 1958c2ecf20Sopenharmony_ci} 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_cistatic inline int cs_etm__etmq_set_tid( 1988c2ecf20Sopenharmony_ci struct cs_etm_queue *etmq __maybe_unused, 1998c2ecf20Sopenharmony_ci pid_t tid __maybe_unused, 2008c2ecf20Sopenharmony_ci u8 trace_chan_id __maybe_unused) 2018c2ecf20Sopenharmony_ci{ 2028c2ecf20Sopenharmony_ci return -1; 2038c2ecf20Sopenharmony_ci} 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_cistatic inline bool cs_etm__etmq_is_timeless( 2068c2ecf20Sopenharmony_ci struct cs_etm_queue *etmq __maybe_unused) 2078c2ecf20Sopenharmony_ci{ 2088c2ecf20Sopenharmony_ci /* What else to return? */ 2098c2ecf20Sopenharmony_ci return true; 2108c2ecf20Sopenharmony_ci} 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_cistatic inline void cs_etm__etmq_set_traceid_queue_timestamp( 2138c2ecf20Sopenharmony_ci struct cs_etm_queue *etmq __maybe_unused, 2148c2ecf20Sopenharmony_ci u8 trace_chan_id __maybe_unused) {} 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_cistatic inline struct cs_etm_packet_queue *cs_etm__etmq_get_packet_queue( 2178c2ecf20Sopenharmony_ci struct cs_etm_queue *etmq __maybe_unused, 2188c2ecf20Sopenharmony_ci u8 trace_chan_id __maybe_unused) 2198c2ecf20Sopenharmony_ci{ 2208c2ecf20Sopenharmony_ci return NULL; 2218c2ecf20Sopenharmony_ci} 2228c2ecf20Sopenharmony_ci#endif 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci#endif 225