2 * Copyright(C) 2016 Linaro Limited. All rights reserved.
3 * Author: Tor Jeremiassen <tor.jeremiassen@linaro.org>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
18 #include <linux/kernel.h>
19 #include <linux/types.h>
20 #include <linux/bitops.h>
21 #include <linux/log2.h>
24 #include "thread_map.h"
26 #include "thread-stack.h"
27 #include "callchain.h"
34 #include "cs-etm-decoder/cs-etm-decoder.h"
39 #define KiB(x) ((x) * 1024)
40 #define MiB(x) ((x) * 1024 * 1024)
41 #define MAX_TIMESTAMP (~0ULL)
43 struct cs_etm_auxtrace {
44 struct auxtrace auxtrace;
45 struct auxtrace_queues queues;
46 struct auxtrace_heap heap;
49 struct perf_session *session;
50 struct machine *machine;
51 struct perf_evsel *switch_evsel;
52 struct thread *unknown_thread;
54 bool timeless_decoding;
59 bool synth_needs_swap;
60 int have_sched_switch;
62 bool sample_instructions;
63 u64 instructions_sample_type;
64 u64 instructions_sample_period;
66 struct itrace_synth_opts synth_opts;
71 struct cs_etm_auxtrace *etm;
73 struct auxtrace_buffer *buffer;
74 const struct cs_etm_state *state;
75 struct ip_callchain *chain;
76 union perf_event *event_buf;
78 bool step_through_buffers;
79 bool use_buffer_pid_tid;
82 struct thread *thread;
86 struct cs_etm_decoder *decoder;
92 static int cs_etm__get_trace(struct cs_etm_buffer *buff, struct cs_etm_queue *etmq);
93 static int cs_etm__update_queues(struct cs_etm_auxtrace *);
94 static int cs_etm__process_queues(struct cs_etm_auxtrace *, u64);
95 static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *, pid_t, u64);
96 static uint32_t cs_etm__mem_access(struct cs_etm_queue *, uint64_t , size_t , uint8_t *);
98 static void cs_etm__packet_dump(const char *pkt_string)
100 const char *color = PERF_COLOR_BLUE;
102 color_fprintf(stdout,color, " %s\n", pkt_string);
106 static void cs_etm__dump_event(struct cs_etm_auxtrace *etm,
107 struct auxtrace_buffer *buffer)
109 const char *color = PERF_COLOR_BLUE;
110 struct cs_etm_decoder_params d_params;
111 struct cs_etm_trace_params *t_params;
112 struct cs_etm_decoder *decoder;
113 size_t buffer_used = 0;
116 fprintf(stdout,"\n");
117 color_fprintf(stdout, color,
118 ". ... CoreSight ETM Trace data: size %zu bytes\n",
121 t_params = zalloc(sizeof(struct cs_etm_trace_params) * etm->num_cpu);
122 for (i = 0; i < etm->num_cpu; ++i) {
123 t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
124 t_params[i].reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0];
125 t_params[i].reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1];
126 t_params[i].reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2];
127 t_params[i].reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8];
128 t_params[i].reg_configr = etm->metadata[i][CS_ETMV4_TRCCONFIGR];
129 t_params[i].reg_traceidr = etm->metadata[i][CS_ETMV4_TRCTRACEIDR];
130 //[CS_ETMV4_TRCAUTHSTATUS] = " TRCAUTHSTATUS %"PRIx64"\n",
132 d_params.packet_printer = cs_etm__packet_dump;
133 d_params.operation = CS_ETM_OPERATION_PRINT;
134 d_params.formatted = true;
135 d_params.fsyncs = false;
136 d_params.hsyncs = false;
137 d_params.frame_aligned = true;
139 decoder = cs_etm_decoder__new(etm->num_cpu,&d_params, t_params);
143 if (decoder == NULL) {
148 cs_etm_decoder__process_data_block(decoder,buffer->offset,&(((uint8_t *)buffer->data)[buffer_used]),buffer->size - buffer_used, &consumed);
149 buffer_used += consumed;
150 } while(buffer_used < buffer->size);
151 cs_etm_decoder__free(decoder);
154 static int cs_etm__flush_events(struct perf_session *session, struct perf_tool *tool){
155 struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
156 struct cs_etm_auxtrace,
164 if (!tool->ordered_events)
167 ret = cs_etm__update_queues(etm);
172 if (etm->timeless_decoding)
173 return cs_etm__process_timeless_queues(etm,-1,MAX_TIMESTAMP - 1);
175 return cs_etm__process_queues(etm, MAX_TIMESTAMP);
178 static void cs_etm__set_pid_tid_cpu(struct cs_etm_auxtrace *etm,
179 struct auxtrace_queue *queue)
181 struct cs_etm_queue *etmq = queue->priv;
183 if ((queue->tid == -1) || (etm->have_sched_switch)) {
184 etmq->tid = machine__get_current_tid(etm->machine, etmq->cpu);
185 thread__zput(etmq->thread);
188 if ((!etmq->thread) && (etmq->tid != -1)) {
189 etmq->thread = machine__find_thread(etm->machine,-1,etmq->tid);
193 etmq->pid = etmq->thread->pid_;
194 if (queue->cpu == -1) {
195 etmq->cpu = etmq->thread->cpu;
200 static void cs_etm__free_queue(void *priv)
202 struct cs_etm_queue *etmq = priv;
207 thread__zput(etmq->thread);
208 cs_etm_decoder__free(etmq->decoder);
209 zfree(&etmq->event_buf);
214 static void cs_etm__free_events(struct perf_session *session)
216 struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
217 struct cs_etm_auxtrace,
220 struct auxtrace_queues *queues = &(aux->queues);
224 for (i = 0; i < queues->nr_queues; ++i) {
225 cs_etm__free_queue(queues->queue_array[i].priv);
226 queues->queue_array[i].priv = 0;
229 auxtrace_queues__free(queues);
233 static void cs_etm__free(struct perf_session *session)
237 struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
238 struct cs_etm_auxtrace,
240 auxtrace_heap__free(&aux->heap);
241 cs_etm__free_events(session);
242 session->auxtrace = NULL;
243 //thread__delete(aux->unknown_thread);
244 for (i = 0; i < aux->num_cpu; ++i) {
245 zfree(&aux->metadata[i]);
247 zfree(&aux->metadata);
251 static void cs_etm__use_buffer_pid_tid(struct cs_etm_queue *etmq,
252 struct auxtrace_queue *queue,
253 struct auxtrace_buffer *buffer)
255 if ((queue->cpu == -1) && (buffer->cpu != -1)) {
256 etmq->cpu = buffer->cpu;
259 etmq->pid = buffer->pid;
260 etmq->tid = buffer->tid;
262 thread__zput(etmq->thread);
264 if (etmq->tid != -1) {
265 if (etmq->pid != -1) {
266 etmq->thread = machine__findnew_thread(etmq->etm->machine,
270 etmq->thread = machine__findnew_thread(etmq->etm->machine,
278 static int cs_etm__get_trace(struct cs_etm_buffer *buff, struct cs_etm_queue *etmq)
280 struct auxtrace_buffer *aux_buffer = etmq->buffer;
281 struct auxtrace_buffer *old_buffer = aux_buffer;
282 struct auxtrace_queue *queue;
289 queue = &etmq->etm->queues.queue_array[etmq->queue_nr];
291 aux_buffer = auxtrace_buffer__next(queue,aux_buffer);
295 auxtrace_buffer__drop_data(old_buffer);
301 etmq->buffer = aux_buffer;
303 if (!aux_buffer->data) {
304 int fd = perf_data_file__fd(etmq->etm->session->file);
306 aux_buffer->data = auxtrace_buffer__get_data(aux_buffer, fd);
307 if (!aux_buffer->data)
312 auxtrace_buffer__drop_data(old_buffer);
314 if (aux_buffer->use_data) {
315 buff->offset = aux_buffer->offset;
316 buff->len = aux_buffer->use_size;
317 buff->buf = aux_buffer->use_data;
319 buff->offset = aux_buffer->offset;
320 buff->len = aux_buffer->size;
321 buff->buf = aux_buffer->data;
325 buff->len = sizeof(cstrace);
329 buff->ref_timestamp = aux_buffer->reference;
331 if (etmq->use_buffer_pid_tid &&
332 ((etmq->pid != aux_buffer->pid) ||
333 (etmq->tid != aux_buffer->tid))) {
334 cs_etm__use_buffer_pid_tid(etmq,queue,aux_buffer);
337 if (etmq->step_through_buffers)
343 static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm,
344 unsigned int queue_nr)
346 struct cs_etm_decoder_params d_params;
347 struct cs_etm_trace_params *t_params;
348 struct cs_etm_queue *etmq;
351 etmq = zalloc(sizeof(struct cs_etm_queue));
355 if (etm->synth_opts.callchain) {
356 size_t sz = sizeof(struct ip_callchain);
358 sz += etm->synth_opts.callchain_sz * sizeof(u64);
359 etmq->chain = zalloc(sz);
366 etmq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE);
367 if (!etmq->event_buf)
371 etmq->queue_nr = queue_nr;
376 etmq->kernel_mapped = false;
378 t_params = zalloc(sizeof(struct cs_etm_trace_params)*etm->num_cpu);
380 for (i = 0; i < etm->num_cpu; ++i) {
381 t_params[i].reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0];
382 t_params[i].reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1];
383 t_params[i].reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2];
384 t_params[i].reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8];
385 t_params[i].reg_configr = etm->metadata[i][CS_ETMV4_TRCCONFIGR];
386 t_params[i].reg_traceidr = etm->metadata[i][CS_ETMV4_TRCTRACEIDR];
387 t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
389 d_params.packet_printer = cs_etm__packet_dump;
390 d_params.operation = CS_ETM_OPERATION_DECODE;
391 d_params.formatted = true;
392 d_params.fsyncs = false;
393 d_params.hsyncs = false;
394 d_params.frame_aligned = true;
395 d_params.data = etmq;
397 etmq->decoder = cs_etm_decoder__new(etm->num_cpu,&d_params,t_params);
411 zfree(&etmq->event_buf);
417 static int cs_etm__setup_queue(struct cs_etm_auxtrace *etm,
418 struct auxtrace_queue *queue,
419 unsigned int queue_nr)
421 struct cs_etm_queue *etmq = queue->priv;
423 if (list_empty(&(queue->head)))
427 etmq = cs_etm__alloc_queue(etm,queue_nr);
435 if (queue->cpu != -1) {
436 etmq->cpu = queue->cpu;
439 etmq->tid = queue->tid;
441 if (etm->sampling_mode) {
442 if (etm->timeless_decoding)
443 etmq->step_through_buffers = true;
444 if (etm->timeless_decoding || !etm->have_sched_switch)
445 etmq->use_buffer_pid_tid = true;
449 if (!etmq->on_heap &&
450 (!etm->sync_switch)) {
451 const struct cs_etm_state *state;
454 if (etm->timeless_decoding)
457 //cs_etm__log("queue %u getting timestamp\n",queue_nr);
458 //cs_etm__log("queue %u decoding cpu %d pid %d tid %d\n",
459 //queue_nr, etmq->cpu, etmq->pid, etmq->tid);
464 state = cs_etm_decoder__decode(etmq->decoder);
466 if (state->err == CS_ETM_ERR_NODATA) {
467 //cs_etm__log("queue %u has no timestamp\n",
473 if (state->timestamp)
477 etmq->timestamp = state->timestamp;
478 //cs_etm__log("queue %u timestamp 0x%"PRIx64 "\n",
479 //queue_nr, etmq->timestamp);
481 etmq->have_sample = true;
482 //cs_etm__sample_flags(etmq);
483 ret = auxtrace_heap__add(&etm->heap, queue_nr, etmq->timestamp);
486 etmq->on_heap = true;
494 static int cs_etm__setup_queues(struct cs_etm_auxtrace *etm)
499 for (i = 0; i < etm->queues.nr_queues; i++) {
500 ret = cs_etm__setup_queue(etm, &(etm->queues.queue_array[i]),i);
508 struct cs_etm_cache_entry {
509 struct auxtrace_cache_entry entry;
514 static size_t cs_etm__cache_divisor(void)
516 static size_t d = 64;
521 static size_t cs_etm__cache_size(struct dso *dso,
522 struct machine *machine)
526 size = dso__data_size(dso,machine);
527 size /= cs_etm__cache_divisor();
532 if (size > (1 << 21))
535 return 32 - __builtin_clz(size);
538 static struct auxtrace_cache *cs_etm__cache(struct dso *dso,
539 struct machine *machine)
541 struct auxtrace_cache *c;
544 if (dso->auxtrace_cache)
545 return dso->auxtrace_cache;
547 bits = cs_etm__cache_size(dso,machine);
549 c = auxtrace_cache__new(bits, sizeof(struct cs_etm_cache_entry), 200);
551 dso->auxtrace_cache = c;
556 static int cs_etm__cache_add(struct dso *dso, struct machine *machine,
557 uint64_t offset, uint64_t icount, uint64_t bcount)
559 struct auxtrace_cache *c = cs_etm__cache(dso, machine);
560 struct cs_etm_cache_entry *e;
566 e = auxtrace_cache__alloc_entry(c);
573 err = auxtrace_cache__add(c, offset, &e->entry);
576 auxtrace_cache__free_entry(c, e);
581 static struct cs_etm_cache_entry *cs_etm__cache_lookup(struct dso *dso,
582 struct machine *machine,
585 struct auxtrace_cache *c = cs_etm__cache(dso, machine);
590 return auxtrace_cache__lookup(dso->auxtrace_cache, offset);
594 static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
595 struct cs_etm_packet *packet)
598 struct cs_etm_auxtrace *etm = etmq->etm;
599 union perf_event *event = etmq->event_buf;
600 struct perf_sample sample = {.ip = 0,};
601 uint64_t start_addr = packet->start_addr;
602 uint64_t end_addr = packet->end_addr;
604 event->sample.header.type = PERF_RECORD_SAMPLE;
605 event->sample.header.misc = PERF_RECORD_MISC_USER;
606 event->sample.header.size = sizeof(struct perf_event_header);
609 sample.ip = start_addr;
610 sample.pid = etmq->pid;
611 sample.tid = etmq->tid;
612 sample.addr = end_addr;
613 sample.id = etmq->etm->instructions_id;
614 sample.stream_id = etmq->etm->instructions_id;
615 sample.period = (end_addr - start_addr) >> 2;
616 sample.cpu = etmq->cpu;
617 sample.flags = 0; // etmq->flags;
618 sample.insn_len = 1; // etmq->insn_len;
620 //etmq->last_insn_cnt = etmq->state->tot_insn_cnt;
624 struct addr_location al;
626 struct thread *thread;
627 struct machine *machine = etmq->etm->machine;
629 struct cs_etm_cache_entry *e;
633 thread = etmq->thread;
636 thread = etmq->etm->unknown_thread;
639 if (start_addr > 0xffffffc000000000UL) {
640 cpumode = PERF_RECORD_MISC_KERNEL;
642 cpumode = PERF_RECORD_MISC_USER;
645 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, start_addr,&al);
646 if (!al.map || !al.map->dso) {
649 if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR &&
650 dso__data_status_seen(al.map->dso,DSO_DATA_STATUS_SEEN_ITRACE)) {
654 offset = al.map->map_ip(al.map,start_addr);
657 e = cs_etm__cache_lookup(al.map->dso, machine, offset);
663 map__load(al.map, machine->symbol_filter);
666 len = dso__data_read_offset(al.map->dso, machine,
673 cs_etm__cache_add(al.map->dso, machine, offset, (end_addr - start_addr) >> 2, end_addr - start_addr);
681 ret = perf_session__deliver_synth_event(etm->session,event, &sample);
684 pr_err("CS ETM Trace: failed to deliver instruction event, error %d\n", ret);
690 struct cs_etm_synth {
691 struct perf_tool dummy_tool;
692 struct perf_session *session;
696 static int cs_etm__event_synth(struct perf_tool *tool,
697 union perf_event *event,
698 struct perf_sample *sample,
699 struct machine *machine)
701 struct cs_etm_synth *cs_etm_synth =
702 container_of(tool, struct cs_etm_synth, dummy_tool);
707 return perf_session__deliver_synth_event(cs_etm_synth->session, event, NULL);
712 static int cs_etm__synth_event(struct perf_session *session,
713 struct perf_event_attr *attr, u64 id)
715 struct cs_etm_synth cs_etm_synth;
717 memset(&cs_etm_synth, 0, sizeof(struct cs_etm_synth));
718 cs_etm_synth.session = session;
720 return perf_event__synthesize_attr(&cs_etm_synth.dummy_tool, attr, 1,
721 &id, cs_etm__event_synth);
724 static int cs_etm__synth_events(struct cs_etm_auxtrace *etm,
725 struct perf_session *session)
727 struct perf_evlist *evlist = session->evlist;
728 struct perf_evsel *evsel;
729 struct perf_event_attr attr;
734 evlist__for_each(evlist, evsel) {
736 if (evsel->attr.type == etm->pmu_type) {
743 pr_debug("There are no selected events with Core Sight Trace data\n");
747 memset(&attr, 0, sizeof(struct perf_event_attr));
748 attr.size = sizeof(struct perf_event_attr);
749 attr.type = PERF_TYPE_HARDWARE;
750 attr.sample_type = evsel->attr.sample_type & PERF_SAMPLE_MASK;
751 attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID |
753 if (etm->timeless_decoding)
754 attr.sample_type &= ~(u64)PERF_SAMPLE_TIME;
756 attr.sample_type |= PERF_SAMPLE_TIME;
758 attr.exclude_user = evsel->attr.exclude_user;
759 attr.exclude_kernel = evsel->attr.exclude_kernel;
760 attr.exclude_hv = evsel->attr.exclude_hv;
761 attr.exclude_host = evsel->attr.exclude_host;
762 attr.exclude_guest = evsel->attr.exclude_guest;
763 attr.sample_id_all = evsel->attr.sample_id_all;
764 attr.read_format = evsel->attr.read_format;
766 id = evsel->id[0] + 1000000000;
771 if (etm->synth_opts.instructions) {
772 attr.config = PERF_COUNT_HW_INSTRUCTIONS;
773 attr.sample_period = etm->synth_opts.period;
774 etm->instructions_sample_period = attr.sample_period;
775 err = cs_etm__synth_event(session, &attr, id);
778 pr_err("%s: failed to synthesize 'instructions' event type\n",
782 etm->sample_instructions = true;
783 etm->instructions_sample_type = attr.sample_type;
784 etm->instructions_id = id;
788 etm->synth_needs_swap = evsel->needs_swap;
792 static int cs_etm__sample(struct cs_etm_queue *etmq)
794 //const struct cs_etm_state *state = etmq->state;
795 struct cs_etm_packet packet;
796 //struct cs_etm_auxtrace *etm = etmq->etm;
799 err = cs_etm_decoder__get_packet(etmq->decoder,&packet);
800 // if there is no sample, it returns err = -1, no real error
802 if (!err && packet.sample_type & CS_ETM_RANGE) {
803 err = cs_etm__synth_instruction_sample(etmq,&packet);
810 static int cs_etm__run_decoder(struct cs_etm_queue *etmq, u64 *timestamp)
812 struct cs_etm_buffer buffer;
816 /* Go through each buffer in the queue and decode them one by one */
819 memset(&buffer, 0, sizeof(buffer));
820 err = cs_etm__get_trace(&buffer,etmq);
825 size_t processed = 0;
826 etmq->state = cs_etm_decoder__process_data_block(etmq->decoder,
828 &buffer.buf[buffer_used],
829 buffer.len-buffer_used,
831 err = etmq->state->err;
832 etmq->offset += processed;
833 buffer_used += processed;
835 cs_etm__sample(etmq);
836 } while (!etmq->eot && (buffer.len > buffer_used));
844 static int cs_etm__update_queues(struct cs_etm_auxtrace *etm)
846 if (etm->queues.new_data) {
847 etm->queues.new_data = false;
848 return cs_etm__setup_queues(etm);
853 static int cs_etm__process_queues(struct cs_etm_auxtrace *etm, u64 timestamp)
855 unsigned int queue_nr;
860 struct auxtrace_queue *queue;
861 struct cs_etm_queue *etmq;
863 if (!etm->heap.heap_cnt)
866 if (etm->heap.heap_array[0].ordinal >= timestamp)
869 queue_nr = etm->heap.heap_array[0].queue_nr;
870 queue = &etm->queues.queue_array[queue_nr];
873 //cs_etm__log("queue %u processing 0x%" PRIx64 " to 0x%" PRIx64 "\n",
874 //queue_nr, etm->heap.heap_array[0].ordinal,
877 auxtrace_heap__pop(&etm->heap);
879 if (etm->heap.heap_cnt) {
880 ts = etm->heap.heap_array[0].ordinal + 1;
887 cs_etm__set_pid_tid_cpu(etm, queue);
889 ret = cs_etm__run_decoder(etmq, &ts);
892 auxtrace_heap__add(&etm->heap, queue_nr, ts);
897 ret = auxtrace_heap__add(&etm->heap, queue_nr, ts);
901 etmq->on_heap = false;
907 static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
911 struct auxtrace_queues *queues = &etm->queues;
915 for (i = 0; i < queues->nr_queues; ++i) {
916 struct auxtrace_queue *queue = &(etm->queues.queue_array[i]);
917 struct cs_etm_queue *etmq = queue->priv;
919 if (etmq && ((tid == -1) || (etmq->tid == tid))) {
921 cs_etm__set_pid_tid_cpu(etm, queue);
922 cs_etm__run_decoder(etmq,&ts);
929 static struct cs_etm_queue *cs_etm__cpu_to_etmq(struct cs_etm_auxtrace *etm,
934 if (etm->queues.nr_queues == 0)
939 else if ((unsigned) cpu >= etm->queues.nr_queues)
940 q = etm->queues.nr_queues - 1;
944 if (etm->queues.queue_array[q].cpu == cpu)
945 return etm->queues.queue_array[q].priv;
947 for (j = 0; q > 0; j++) {
948 if (etm->queues.queue_array[--q].cpu == cpu)
949 return etm->queues.queue_array[q].priv;
952 for (; j < etm->queues.nr_queues; j++) {
953 if (etm->queues.queue_array[j].cpu == cpu)
954 return etm->queues.queue_array[j].priv;
961 static uint32_t cs_etm__mem_access(struct cs_etm_queue *etmq, uint64_t address, size_t size, uint8_t *buffer)
963 struct addr_location al;
965 struct thread *thread;
966 struct machine *machine;
973 machine = etmq->etm->machine;
974 thread = etmq->thread;
975 if (address > 0xffffffc000000000UL) {
976 cpumode = PERF_RECORD_MISC_KERNEL;
978 cpumode = PERF_RECORD_MISC_USER;
981 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, address,&al);
983 if (!al.map || !al.map->dso) {
987 if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR &&
988 dso__data_status_seen(al.map->dso,DSO_DATA_STATUS_SEEN_ITRACE)) {
992 offset = al.map->map_ip(al.map,address);
994 map__load(al.map, machine->symbol_filter);
996 len = dso__data_read_offset(al.map->dso, machine,
997 offset, buffer, size);
1006 static bool check_need_swap(int file_endian)
1009 u8 *check = (u8 *)&data;
1013 host_endian = ELFDATA2LSB;
1015 host_endian = ELFDATA2MSB;
1017 return host_endian != file_endian;
1020 static int cs_etm__read_elf_info(const char *fname, uint64_t *foffset, uint64_t *fstart, uint64_t *fsize)
1023 u8 e_ident[EI_NIDENT];
1025 bool need_swap = false;
1030 fp = fopen(fname, "r");
1034 if (fread(e_ident, sizeof(e_ident), 1, fp) != 1)
1037 if (memcmp(e_ident, ELFMAG, SELFMAG) ||
1038 e_ident[EI_VERSION] != EV_CURRENT)
1041 need_swap = check_need_swap(e_ident[EI_DATA]);
1043 /* for simplicity */
1044 fseek(fp, 0, SEEK_SET);
1046 if (e_ident[EI_CLASS] == ELFCLASS32) {
1050 if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
1054 ehdr.e_phoff = bswap_32(ehdr.e_phoff);
1055 ehdr.e_phentsize = bswap_16(ehdr.e_phentsize);
1056 ehdr.e_phnum = bswap_16(ehdr.e_phnum);
1059 buf_size = ehdr.e_phentsize * ehdr.e_phnum;
1060 buf = malloc(buf_size);
1064 fseek(fp, ehdr.e_phoff, SEEK_SET);
1065 if (fread(buf, buf_size, 1, fp) != 1)
1068 for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
1071 phdr->p_type = bswap_32(phdr->p_type);
1072 phdr->p_offset = bswap_32(phdr->p_offset);
1073 phdr->p_filesz = bswap_32(phdr->p_filesz);
1076 if (phdr->p_type != PT_LOAD)
1079 *foffset = phdr->p_offset;
1080 *fstart = phdr->p_vaddr;
1081 *fsize = phdr->p_filesz;
1089 if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
1093 ehdr.e_phoff = bswap_64(ehdr.e_phoff);
1094 ehdr.e_phentsize = bswap_16(ehdr.e_phentsize);
1095 ehdr.e_phnum = bswap_16(ehdr.e_phnum);
1098 buf_size = ehdr.e_phentsize * ehdr.e_phnum;
1099 buf = malloc(buf_size);
1103 fseek(fp, ehdr.e_phoff, SEEK_SET);
1104 if (fread(buf, buf_size, 1, fp) != 1)
1107 for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
1110 phdr->p_type = bswap_32(phdr->p_type);
1111 phdr->p_offset = bswap_64(phdr->p_offset);
1112 phdr->p_filesz = bswap_64(phdr->p_filesz);
1115 if (phdr->p_type != PT_LOAD)
1118 *foffset = phdr->p_offset;
1119 *fstart = phdr->p_vaddr;
1120 *fsize = phdr->p_filesz;
1132 static int cs_etm__process_event(struct perf_session *session,
1133 union perf_event *event,
1134 struct perf_sample *sample,
1135 struct perf_tool *tool)
1137 struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
1138 struct cs_etm_auxtrace,
1147 if (!tool->ordered_events) {
1148 pr_err("CoreSight ETM Trace requires ordered events\n");
1152 if (sample->time && (sample->time != (u64)-1))
1153 timestamp = sample->time;
1157 if (timestamp || etm->timeless_decoding) {
1158 err = cs_etm__update_queues(etm);
1164 if (event->header.type == PERF_RECORD_MMAP2) {
1167 struct cs_etm_queue *etmq;
1171 etmq = cs_etm__cpu_to_etmq(etm,cpu);
1177 dso = dsos__find(&(etm->machine->dsos),event->mmap2.filename,false);
1179 err = cs_etm_decoder__add_mem_access_cb(
1183 cs_etm__mem_access);
1186 if ((symbol_conf.vmlinux_name != NULL) && (!etmq->kernel_mapped)) {
1191 err = cs_etm__read_elf_info(symbol_conf.vmlinux_name,
1192 &foffset,&fstart,&fsize);
1195 cs_etm_decoder__add_bin_file(
1200 symbol_conf.vmlinux_name);
1202 etmq->kernel_mapped = true;
1208 if (etm->timeless_decoding) {
1209 if (event->header.type == PERF_RECORD_EXIT) {
1210 err = cs_etm__process_timeless_queues(etm,
1214 } else if (timestamp) {
1215 err = cs_etm__process_queues(etm, timestamp);
1218 //cs_etm__log("event %s (%u): cpu %d time%"PRIu64" tsc %#"PRIx64"\n",
1219 //perf_event__name(event->header.type), event->header.type,
1220 //sample->cpu, sample->time, timestamp);
1224 static int cs_etm__process_auxtrace_event(struct perf_session *session,
1225 union perf_event *event,
1226 struct perf_tool *tool)
1228 struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
1229 struct cs_etm_auxtrace,
1234 if (!etm->data_queued) {
1235 struct auxtrace_buffer *buffer;
1237 int fd = perf_data_file__fd(session->file);
1238 bool is_pipe = perf_data_file__is_pipe(session->file);
1244 data_offset = lseek(fd, 0, SEEK_CUR);
1245 if (data_offset == -1) {
1250 err = auxtrace_queues__add_event(&etm->queues,
1260 if (auxtrace_buffer__get_data(buffer,fd)) {
1261 cs_etm__dump_event(etm,buffer);
1262 auxtrace_buffer__put_data(buffer);
1271 static const char * const cs_etm_global_header_fmts[] = {
1272 [CS_HEADER_VERSION_0] = " Header version %"PRIx64"\n",
1273 [CS_PMU_TYPE_CPUS] = " PMU type/num cpus %"PRIx64"\n",
1274 [CS_ETM_SNAPSHOT] = " Snapshot %"PRIx64"\n",
1277 static const char * const cs_etm_priv_fmts[] = {
1278 [CS_ETM_MAGIC] = " Magic number %"PRIx64"\n",
1279 [CS_ETM_CPU] = " CPU %"PRIx64"\n",
1280 [CS_ETM_ETMCR] = " ETMCR %"PRIx64"\n",
1281 [CS_ETM_ETMTRACEIDR] = " ETMTRACEIDR %"PRIx64"\n",
1282 [CS_ETM_ETMCCER] = " ETMCCER %"PRIx64"\n",
1283 [CS_ETM_ETMIDR] = " ETMIDR %"PRIx64"\n",
1286 static const char * const cs_etmv4_priv_fmts[] = {
1287 [CS_ETM_MAGIC] = " Magic number %"PRIx64"\n",
1288 [CS_ETM_CPU] = " CPU %"PRIx64"\n",
1289 [CS_ETMV4_TRCCONFIGR] = " TRCCONFIGR %"PRIx64"\n",
1290 [CS_ETMV4_TRCTRACEIDR] = " TRCTRACEIDR %"PRIx64"\n",
1291 [CS_ETMV4_TRCIDR0] = " TRCIDR0 %"PRIx64"\n",
1292 [CS_ETMV4_TRCIDR1] = " TRCIDR1 %"PRIx64"\n",
1293 [CS_ETMV4_TRCIDR2] = " TRCIDR2 %"PRIx64"\n",
1294 [CS_ETMV4_TRCIDR8] = " TRCIDR8 %"PRIx64"\n",
1295 [CS_ETMV4_TRCAUTHSTATUS] = " TRCAUTHSTATUS %"PRIx64"\n",
1298 static void cs_etm__print_auxtrace_info(u64 *val, size_t num)
1302 for (i = 0, cpu = 0; cpu < num; ++cpu) {
1304 if (val[i] == __perf_cs_etmv3_magic) {
1305 for (j = 0; j < CS_ETM_PRIV_MAX; ++j, ++i) {
1306 fprintf(stdout,cs_etm_priv_fmts[j],val[i]);
1308 } else if (val[i] == __perf_cs_etmv4_magic) {
1309 for (j = 0; j < CS_ETMV4_PRIV_MAX; ++j, ++i) {
1310 fprintf(stdout,cs_etmv4_priv_fmts[j],val[i]);
1319 int cs_etm__process_auxtrace_info(union perf_event *event,
1320 struct perf_session *session)
1322 struct auxtrace_info_event *auxtrace_info = &(event->auxtrace_info);
1323 size_t event_header_size = sizeof(struct perf_event_header);
1324 size_t info_header_size = 8;
1325 size_t total_size = auxtrace_info->header.size;
1326 size_t priv_size = 0;
1328 struct cs_etm_auxtrace *etm = 0;
1332 u64 **metadata = NULL;
1336 if (total_size < (event_header_size + info_header_size))
1339 priv_size = total_size - event_header_size - info_header_size;
1341 // First the global part
1343 ptr = (u64 *) auxtrace_info->priv;
1345 hdr = zalloc(sizeof(u64 *) * CS_HEADER_VERSION_0_MAX);
1349 for (i = 0; i < CS_HEADER_VERSION_0_MAX; ++i) {
1352 num_cpu = hdr[CS_PMU_TYPE_CPUS] & 0xffffffff;
1353 pmu_type = (unsigned) ((hdr[CS_PMU_TYPE_CPUS] >> 32) & 0xffffffff);
1358 metadata = zalloc(sizeof(u64 *) * num_cpu);
1360 if (metadata == NULL) {
1364 for (j = 0; j < num_cpu; ++j) {
1365 if (ptr[i] == __perf_cs_etmv3_magic) {
1366 metadata[j] = zalloc(sizeof(u64)*CS_ETM_PRIV_MAX);
1367 if (metadata == NULL)
1369 for (k = 0; k < CS_ETM_PRIV_MAX; k++) {
1370 metadata[j][k] = ptr[i+k];
1372 i += CS_ETM_PRIV_MAX;
1373 } else if (ptr[i] == __perf_cs_etmv4_magic) {
1374 metadata[j] = zalloc(sizeof(u64)*CS_ETMV4_PRIV_MAX);
1375 if (metadata == NULL)
1377 for (k = 0; k < CS_ETMV4_PRIV_MAX; k++) {
1378 metadata[j][k] = ptr[i+k];
1380 i += CS_ETMV4_PRIV_MAX;
1384 if (i*8 != priv_size)
1388 cs_etm__print_auxtrace_info(auxtrace_info->priv,num_cpu);
1390 etm = zalloc(sizeof(struct cs_etm_auxtrace));
1392 etm->num_cpu = num_cpu;
1393 etm->pmu_type = pmu_type;
1394 etm->snapshot_mode = (hdr[CS_ETM_SNAPSHOT] != 0);
1400 err = auxtrace_queues__init(&etm->queues);
1404 etm->unknown_thread = thread__new(999999999,999999999);
1405 if (etm->unknown_thread == NULL) {
1407 goto err_free_queues;
1409 err = thread__set_comm(etm->unknown_thread, "unknown", 0);
1411 goto err_delete_thread;
1414 if (thread__init_map_groups(etm->unknown_thread,
1417 goto err_delete_thread;
1420 etm->timeless_decoding = true;
1421 etm->sampling_mode = false;
1422 etm->metadata = metadata;
1423 etm->session = session;
1424 etm->machine = &session->machines.host;
1425 etm->auxtrace_type = auxtrace_info->type;
1427 etm->auxtrace.process_event = cs_etm__process_event;
1428 etm->auxtrace.process_auxtrace_event = cs_etm__process_auxtrace_event;
1429 etm->auxtrace.flush_events = cs_etm__flush_events;
1430 etm->auxtrace.free_events = cs_etm__free_events;
1431 etm->auxtrace.free = cs_etm__free;
1432 session->auxtrace = &(etm->auxtrace);
1437 if (session->itrace_synth_opts && session->itrace_synth_opts->set) {
1438 etm->synth_opts = *session->itrace_synth_opts;
1440 itrace_synth_opts__set_default(&etm->synth_opts);
1442 etm->synth_opts.branches = false;
1443 etm->synth_opts.callchain = false;
1444 etm->synth_opts.calls = false;
1445 etm->synth_opts.returns = false;
1447 err = cs_etm__synth_events(etm, session);
1449 goto err_delete_thread;
1451 err = auxtrace_queues__process_index(&etm->queues, session);
1453 goto err_delete_thread;
1455 etm->data_queued = etm->queues.populated;
1460 thread__delete(etm->unknown_thread);
1462 auxtrace_queues__free(&etm->queues);
1463 session->auxtrace = NULL;