.. | .. |
---|
8 | 8 | #define INCLUDE__UTIL_PERF_CS_ETM_H__ |
---|
9 | 9 | |
---|
10 | 10 | #include "util/event.h" |
---|
11 | | -#include "util/session.h" |
---|
| 11 | +#include <linux/bits.h> |
---|
| 12 | + |
---|
| 13 | +struct perf_session; |
---|
12 | 14 | |
---|
13 | 15 | /* Versionning header in case things need tro change in the future. That way |
---|
14 | 16 | * decoding of old snapshot is still possible. |
---|
.. | .. |
---|
53 | 55 | CS_ETMV4_PRIV_MAX, |
---|
54 | 56 | }; |
---|
55 | 57 | |
---|
| 58 | +/* |
---|
| 59 | + * ETMv3 exception encoding number: |
---|
| 60 | + * See Embedded Trace Macrocell spcification (ARM IHI 0014Q) |
---|
| 61 | + * table 7-12 Encoding of Exception[3:0] for non-ARMv7-M processors. |
---|
| 62 | + */ |
---|
| 63 | +enum { |
---|
| 64 | + CS_ETMV3_EXC_NONE = 0, |
---|
| 65 | + CS_ETMV3_EXC_DEBUG_HALT = 1, |
---|
| 66 | + CS_ETMV3_EXC_SMC = 2, |
---|
| 67 | + CS_ETMV3_EXC_HYP = 3, |
---|
| 68 | + CS_ETMV3_EXC_ASYNC_DATA_ABORT = 4, |
---|
| 69 | + CS_ETMV3_EXC_JAZELLE_THUMBEE = 5, |
---|
| 70 | + CS_ETMV3_EXC_PE_RESET = 8, |
---|
| 71 | + CS_ETMV3_EXC_UNDEFINED_INSTR = 9, |
---|
| 72 | + CS_ETMV3_EXC_SVC = 10, |
---|
| 73 | + CS_ETMV3_EXC_PREFETCH_ABORT = 11, |
---|
| 74 | + CS_ETMV3_EXC_DATA_FAULT = 12, |
---|
| 75 | + CS_ETMV3_EXC_GENERIC = 13, |
---|
| 76 | + CS_ETMV3_EXC_IRQ = 14, |
---|
| 77 | + CS_ETMV3_EXC_FIQ = 15, |
---|
| 78 | +}; |
---|
| 79 | + |
---|
| 80 | +/* |
---|
| 81 | + * ETMv4 exception encoding number: |
---|
| 82 | + * See ARM Embedded Trace Macrocell Architecture Specification (ARM IHI 0064D) |
---|
| 83 | + * table 6-12 Possible values for the TYPE field in an Exception instruction |
---|
| 84 | + * trace packet, for ARMv7-A/R and ARMv8-A/R PEs. |
---|
| 85 | + */ |
---|
| 86 | +enum { |
---|
| 87 | + CS_ETMV4_EXC_RESET = 0, |
---|
| 88 | + CS_ETMV4_EXC_DEBUG_HALT = 1, |
---|
| 89 | + CS_ETMV4_EXC_CALL = 2, |
---|
| 90 | + CS_ETMV4_EXC_TRAP = 3, |
---|
| 91 | + CS_ETMV4_EXC_SYSTEM_ERROR = 4, |
---|
| 92 | + CS_ETMV4_EXC_INST_DEBUG = 6, |
---|
| 93 | + CS_ETMV4_EXC_DATA_DEBUG = 7, |
---|
| 94 | + CS_ETMV4_EXC_ALIGNMENT = 10, |
---|
| 95 | + CS_ETMV4_EXC_INST_FAULT = 11, |
---|
| 96 | + CS_ETMV4_EXC_DATA_FAULT = 12, |
---|
| 97 | + CS_ETMV4_EXC_IRQ = 14, |
---|
| 98 | + CS_ETMV4_EXC_FIQ = 15, |
---|
| 99 | + CS_ETMV4_EXC_END = 31, |
---|
| 100 | +}; |
---|
| 101 | + |
---|
| 102 | +enum cs_etm_sample_type { |
---|
| 103 | + CS_ETM_EMPTY, |
---|
| 104 | + CS_ETM_RANGE, |
---|
| 105 | + CS_ETM_DISCONTINUITY, |
---|
| 106 | + CS_ETM_EXCEPTION, |
---|
| 107 | + CS_ETM_EXCEPTION_RET, |
---|
| 108 | +}; |
---|
| 109 | + |
---|
| 110 | +enum cs_etm_isa { |
---|
| 111 | + CS_ETM_ISA_UNKNOWN, |
---|
| 112 | + CS_ETM_ISA_A64, |
---|
| 113 | + CS_ETM_ISA_A32, |
---|
| 114 | + CS_ETM_ISA_T32, |
---|
| 115 | +}; |
---|
| 116 | + |
---|
| 117 | +struct cs_etm_queue; |
---|
| 118 | + |
---|
| 119 | +struct cs_etm_packet { |
---|
| 120 | + enum cs_etm_sample_type sample_type; |
---|
| 121 | + enum cs_etm_isa isa; |
---|
| 122 | + u64 start_addr; |
---|
| 123 | + u64 end_addr; |
---|
| 124 | + u32 instr_count; |
---|
| 125 | + u32 last_instr_type; |
---|
| 126 | + u32 last_instr_subtype; |
---|
| 127 | + u32 flags; |
---|
| 128 | + u32 exception_number; |
---|
| 129 | + u8 last_instr_cond; |
---|
| 130 | + u8 last_instr_taken_branch; |
---|
| 131 | + u8 last_instr_size; |
---|
| 132 | + u8 trace_chan_id; |
---|
| 133 | + int cpu; |
---|
| 134 | +}; |
---|
| 135 | + |
---|
| 136 | +#define CS_ETM_PACKET_MAX_BUFFER 1024 |
---|
| 137 | + |
---|
| 138 | +/* |
---|
| 139 | + * When working with per-thread scenarios the process under trace can |
---|
| 140 | + * be scheduled on any CPU and as such, more than one traceID may be |
---|
| 141 | + * associated with the same process. Since a traceID of '0' is illegal |
---|
| 142 | + * as per the CoreSight architecture, use that specific value to |
---|
| 143 | + * identify the queue where all packets (with any traceID) are |
---|
| 144 | + * aggregated. |
---|
| 145 | + */ |
---|
| 146 | +#define CS_ETM_PER_THREAD_TRACEID 0 |
---|
| 147 | + |
---|
| 148 | +struct cs_etm_packet_queue { |
---|
| 149 | + u32 packet_count; |
---|
| 150 | + u32 head; |
---|
| 151 | + u32 tail; |
---|
| 152 | + u32 instr_count; |
---|
| 153 | + u64 timestamp; |
---|
| 154 | + u64 next_timestamp; |
---|
| 155 | + struct cs_etm_packet packet_buffer[CS_ETM_PACKET_MAX_BUFFER]; |
---|
| 156 | +}; |
---|
| 157 | + |
---|
56 | 158 | #define KiB(x) ((x) * 1024) |
---|
57 | 159 | #define MiB(x) ((x) * 1024 * 1024) |
---|
58 | 160 | |
---|
| 161 | +#define CS_ETM_INVAL_ADDR 0xdeadbeefdeadbeefUL |
---|
| 162 | + |
---|
| 163 | +#define BMVAL(val, lsb, msb) ((val & GENMASK(msb, lsb)) >> lsb) |
---|
| 164 | + |
---|
59 | 165 | #define CS_ETM_HEADER_SIZE (CS_HEADER_VERSION_0_MAX * sizeof(u64)) |
---|
60 | 166 | |
---|
61 | | -static const u64 __perf_cs_etmv3_magic = 0x3030303030303030ULL; |
---|
62 | | -static const u64 __perf_cs_etmv4_magic = 0x4040404040404040ULL; |
---|
| 167 | +#define __perf_cs_etmv3_magic 0x3030303030303030ULL |
---|
| 168 | +#define __perf_cs_etmv4_magic 0x4040404040404040ULL |
---|
63 | 169 | #define CS_ETMV3_PRIV_SIZE (CS_ETM_PRIV_MAX * sizeof(u64)) |
---|
64 | 170 | #define CS_ETMV4_PRIV_SIZE (CS_ETMV4_PRIV_MAX * sizeof(u64)) |
---|
65 | 171 | |
---|
.. | .. |
---|
67 | 173 | int cs_etm__process_auxtrace_info(union perf_event *event, |
---|
68 | 174 | struct perf_session *session); |
---|
69 | 175 | int cs_etm__get_cpu(u8 trace_chan_id, int *cpu); |
---|
| 176 | +int cs_etm__etmq_set_tid(struct cs_etm_queue *etmq, |
---|
| 177 | + pid_t tid, u8 trace_chan_id); |
---|
| 178 | +bool cs_etm__etmq_is_timeless(struct cs_etm_queue *etmq); |
---|
| 179 | +void cs_etm__etmq_set_traceid_queue_timestamp(struct cs_etm_queue *etmq, |
---|
| 180 | + u8 trace_chan_id); |
---|
| 181 | +struct cs_etm_packet_queue |
---|
| 182 | +*cs_etm__etmq_get_packet_queue(struct cs_etm_queue *etmq, u8 trace_chan_id); |
---|
70 | 183 | #else |
---|
71 | 184 | static inline int |
---|
72 | 185 | cs_etm__process_auxtrace_info(union perf_event *event __maybe_unused, |
---|
.. | .. |
---|
80 | 193 | { |
---|
81 | 194 | return -1; |
---|
82 | 195 | } |
---|
| 196 | + |
---|
| 197 | +static inline int cs_etm__etmq_set_tid( |
---|
| 198 | + struct cs_etm_queue *etmq __maybe_unused, |
---|
| 199 | + pid_t tid __maybe_unused, |
---|
| 200 | + u8 trace_chan_id __maybe_unused) |
---|
| 201 | +{ |
---|
| 202 | + return -1; |
---|
| 203 | +} |
---|
| 204 | + |
---|
| 205 | +static inline bool cs_etm__etmq_is_timeless( |
---|
| 206 | + struct cs_etm_queue *etmq __maybe_unused) |
---|
| 207 | +{ |
---|
| 208 | + /* What else to return? */ |
---|
| 209 | + return true; |
---|
| 210 | +} |
---|
| 211 | + |
---|
| 212 | +static inline void cs_etm__etmq_set_traceid_queue_timestamp( |
---|
| 213 | + struct cs_etm_queue *etmq __maybe_unused, |
---|
| 214 | + u8 trace_chan_id __maybe_unused) {} |
---|
| 215 | + |
---|
| 216 | +static inline struct cs_etm_packet_queue *cs_etm__etmq_get_packet_queue( |
---|
| 217 | + struct cs_etm_queue *etmq __maybe_unused, |
---|
| 218 | + u8 trace_chan_id __maybe_unused) |
---|
| 219 | +{ |
---|
| 220 | + return NULL; |
---|
| 221 | +} |
---|
83 | 222 | #endif |
---|
84 | 223 | |
---|
85 | 224 | #endif |
---|