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;
87 struct cs_etm_decoder *decoder;
93 static int cs_etm__get_trace(struct cs_etm_buffer *buff, struct cs_etm_queue *etmq);
94 static int cs_etm__update_queues(struct cs_etm_auxtrace *);
95 static int cs_etm__process_queues(struct cs_etm_auxtrace *, u64);
96 static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *, pid_t, u64);
97 static uint32_t cs_etm__mem_access(struct cs_etm_queue *, uint64_t , size_t , uint8_t *);
99 static void cs_etm__packet_dump(const char *pkt_string)
101 const char *color = PERF_COLOR_BLUE;
103 color_fprintf(stdout,color, " %s\n", pkt_string);
107 static void cs_etm__dump_event(struct cs_etm_auxtrace *etm,
108 struct auxtrace_buffer *buffer)
110 const char *color = PERF_COLOR_BLUE;
111 struct cs_etm_decoder_params d_params;
112 struct cs_etm_trace_params *t_params;
113 struct cs_etm_decoder *decoder;
114 size_t buffer_used = 0;
117 fprintf(stdout,"\n");
118 color_fprintf(stdout, color,
119 ". ... CoreSight ETM Trace data: size %zu bytes\n",
122 t_params = zalloc(sizeof(struct cs_etm_trace_params) * etm->num_cpu);
123 for (i = 0; i < etm->num_cpu; ++i) {
124 t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
125 t_params[i].reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0];
126 t_params[i].reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1];
127 t_params[i].reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2];
128 t_params[i].reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8];
129 t_params[i].reg_configr = etm->metadata[i][CS_ETMV4_TRCCONFIGR];
130 t_params[i].reg_traceidr = etm->metadata[i][CS_ETMV4_TRCTRACEIDR];
131 //[CS_ETMV4_TRCAUTHSTATUS] = " TRCAUTHSTATUS %"PRIx64"\n",
133 d_params.packet_printer = cs_etm__packet_dump;
134 d_params.operation = CS_ETM_OPERATION_PRINT;
135 d_params.formatted = true;
136 d_params.fsyncs = false;
137 d_params.hsyncs = false;
138 d_params.frame_aligned = true;
140 decoder = cs_etm_decoder__new(etm->num_cpu,&d_params, t_params);
144 if (decoder == NULL) {
149 cs_etm_decoder__process_data_block(decoder,buffer->offset,&(((uint8_t *)buffer->data)[buffer_used]),buffer->size - buffer_used, &consumed);
150 buffer_used += consumed;
151 } while(buffer_used < buffer->size);
152 cs_etm_decoder__free(decoder);
155 static int cs_etm__flush_events(struct perf_session *session, struct perf_tool *tool){
156 struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
157 struct cs_etm_auxtrace,
165 if (!tool->ordered_events)
168 ret = cs_etm__update_queues(etm);
173 if (etm->timeless_decoding)
174 return cs_etm__process_timeless_queues(etm,-1,MAX_TIMESTAMP - 1);
176 return cs_etm__process_queues(etm, MAX_TIMESTAMP);
179 static void cs_etm__set_pid_tid_cpu(struct cs_etm_auxtrace *etm,
180 struct auxtrace_queue *queue)
182 struct cs_etm_queue *etmq = queue->priv;
184 if ((queue->tid == -1) || (etm->have_sched_switch)) {
185 etmq->tid = machine__get_current_tid(etm->machine, etmq->cpu);
186 thread__zput(etmq->thread);
189 if ((!etmq->thread) && (etmq->tid != -1)) {
190 etmq->thread = machine__find_thread(etm->machine,-1,etmq->tid);
194 etmq->pid = etmq->thread->pid_;
195 if (queue->cpu == -1) {
196 etmq->cpu = etmq->thread->cpu;
201 static void cs_etm__free_queue(void *priv)
203 struct cs_etm_queue *etmq = priv;
208 thread__zput(etmq->thread);
209 cs_etm_decoder__free(etmq->decoder);
210 zfree(&etmq->event_buf);
215 static void cs_etm__free_events(struct perf_session *session)
217 struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
218 struct cs_etm_auxtrace,
221 struct auxtrace_queues *queues = &(aux->queues);
225 for (i = 0; i < queues->nr_queues; ++i) {
226 cs_etm__free_queue(queues->queue_array[i].priv);
227 queues->queue_array[i].priv = 0;
230 auxtrace_queues__free(queues);
234 static void cs_etm__free(struct perf_session *session)
238 struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
239 struct cs_etm_auxtrace,
241 auxtrace_heap__free(&aux->heap);
242 cs_etm__free_events(session);
243 session->auxtrace = NULL;
244 //thread__delete(aux->unknown_thread);
245 for (i = 0; i < aux->num_cpu; ++i) {
246 zfree(&aux->metadata[i]);
248 zfree(&aux->metadata);
252 static void cs_etm__use_buffer_pid_tid(struct cs_etm_queue *etmq,
253 struct auxtrace_queue *queue,
254 struct auxtrace_buffer *buffer)
256 if ((queue->cpu == -1) && (buffer->cpu != -1)) {
257 etmq->cpu = buffer->cpu;
260 etmq->pid = buffer->pid;
261 etmq->tid = buffer->tid;
263 thread__zput(etmq->thread);
265 if (etmq->tid != -1) {
266 if (etmq->pid != -1) {
267 etmq->thread = machine__findnew_thread(etmq->etm->machine,
271 etmq->thread = machine__findnew_thread(etmq->etm->machine,
279 static int cs_etm__get_trace(struct cs_etm_buffer *buff, struct cs_etm_queue *etmq)
281 struct auxtrace_buffer *aux_buffer = etmq->buffer;
282 struct auxtrace_buffer *old_buffer = aux_buffer;
283 struct auxtrace_queue *queue;
290 queue = &etmq->etm->queues.queue_array[etmq->queue_nr];
292 aux_buffer = auxtrace_buffer__next(queue,aux_buffer);
296 auxtrace_buffer__drop_data(old_buffer);
302 etmq->buffer = aux_buffer;
304 if (!aux_buffer->data) {
305 int fd = perf_data_file__fd(etmq->etm->session->file);
307 aux_buffer->data = auxtrace_buffer__get_data(aux_buffer, fd);
308 if (!aux_buffer->data)
313 auxtrace_buffer__drop_data(old_buffer);
315 if (aux_buffer->use_data) {
316 buff->offset = aux_buffer->offset;
317 buff->len = aux_buffer->use_size;
318 buff->buf = aux_buffer->use_data;
320 buff->offset = aux_buffer->offset;
321 buff->len = aux_buffer->size;
322 buff->buf = aux_buffer->data;
326 buff->len = sizeof(cstrace);
331 buff->ref_timestamp = aux_buffer->reference;
333 if (etmq->use_buffer_pid_tid &&
334 ((etmq->pid != aux_buffer->pid) ||
335 (etmq->tid != aux_buffer->tid))) {
336 cs_etm__use_buffer_pid_tid(etmq,queue,aux_buffer);
339 if (etmq->step_through_buffers)
343 return cs_etm__get_trace(buff,etmq);
348 static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm,
349 unsigned int queue_nr)
351 struct cs_etm_decoder_params d_params;
352 struct cs_etm_trace_params *t_params;
353 struct cs_etm_queue *etmq;
356 etmq = zalloc(sizeof(struct cs_etm_queue));
360 if (etm->synth_opts.callchain) {
361 size_t sz = sizeof(struct ip_callchain);
363 sz += etm->synth_opts.callchain_sz * sizeof(u64);
364 etmq->chain = zalloc(sz);
371 etmq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE);
372 if (!etmq->event_buf)
376 etmq->queue_nr = queue_nr;
381 etmq->kernel_mapped = false;
383 t_params = zalloc(sizeof(struct cs_etm_trace_params)*etm->num_cpu);
385 for (i = 0; i < etm->num_cpu; ++i) {
386 t_params[i].reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0];
387 t_params[i].reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1];
388 t_params[i].reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2];
389 t_params[i].reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8];
390 t_params[i].reg_configr = etm->metadata[i][CS_ETMV4_TRCCONFIGR];
391 t_params[i].reg_traceidr = etm->metadata[i][CS_ETMV4_TRCTRACEIDR];
392 t_params[i].protocol = CS_ETM_PROTO_ETMV4i;
394 d_params.packet_printer = cs_etm__packet_dump;
395 d_params.operation = CS_ETM_OPERATION_DECODE;
396 d_params.formatted = true;
397 d_params.fsyncs = false;
398 d_params.hsyncs = false;
399 d_params.frame_aligned = true;
400 d_params.data = etmq;
402 etmq->decoder = cs_etm_decoder__new(etm->num_cpu,&d_params,t_params);
416 zfree(&etmq->event_buf);
422 static int cs_etm__setup_queue(struct cs_etm_auxtrace *etm,
423 struct auxtrace_queue *queue,
424 unsigned int queue_nr)
426 struct cs_etm_queue *etmq = queue->priv;
428 if (list_empty(&(queue->head)))
432 etmq = cs_etm__alloc_queue(etm,queue_nr);
440 if (queue->cpu != -1) {
441 etmq->cpu = queue->cpu;
444 etmq->tid = queue->tid;
446 if (etm->sampling_mode) {
447 if (etm->timeless_decoding)
448 etmq->step_through_buffers = true;
449 if (etm->timeless_decoding || !etm->have_sched_switch)
450 etmq->use_buffer_pid_tid = true;
454 if (!etmq->on_heap &&
455 (!etm->sync_switch)) {
456 const struct cs_etm_state *state;
459 if (etm->timeless_decoding)
462 //cs_etm__log("queue %u getting timestamp\n",queue_nr);
463 //cs_etm__log("queue %u decoding cpu %d pid %d tid %d\n",
464 //queue_nr, etmq->cpu, etmq->pid, etmq->tid);
469 state = cs_etm_decoder__decode(etmq->decoder);
471 if (state->err == CS_ETM_ERR_NODATA) {
472 //cs_etm__log("queue %u has no timestamp\n",
478 if (state->timestamp)
482 etmq->timestamp = state->timestamp;
483 //cs_etm__log("queue %u timestamp 0x%"PRIx64 "\n",
484 //queue_nr, etmq->timestamp);
486 etmq->have_sample = true;
487 //cs_etm__sample_flags(etmq);
488 ret = auxtrace_heap__add(&etm->heap, queue_nr, etmq->timestamp);
491 etmq->on_heap = true;
499 static int cs_etm__setup_queues(struct cs_etm_auxtrace *etm)
504 for (i = 0; i < etm->queues.nr_queues; i++) {
505 ret = cs_etm__setup_queue(etm, &(etm->queues.queue_array[i]),i);
513 struct cs_etm_cache_entry {
514 struct auxtrace_cache_entry entry;
519 static size_t cs_etm__cache_divisor(void)
521 static size_t d = 64;
526 static size_t cs_etm__cache_size(struct dso *dso,
527 struct machine *machine)
531 size = dso__data_size(dso,machine);
532 size /= cs_etm__cache_divisor();
537 if (size > (1 << 21))
540 return 32 - __builtin_clz(size);
543 static struct auxtrace_cache *cs_etm__cache(struct dso *dso,
544 struct machine *machine)
546 struct auxtrace_cache *c;
549 if (dso->auxtrace_cache)
550 return dso->auxtrace_cache;
552 bits = cs_etm__cache_size(dso,machine);
554 c = auxtrace_cache__new(bits, sizeof(struct cs_etm_cache_entry), 200);
556 dso->auxtrace_cache = c;
561 static int cs_etm__cache_add(struct dso *dso, struct machine *machine,
562 uint64_t offset, uint64_t icount, uint64_t bcount)
564 struct auxtrace_cache *c = cs_etm__cache(dso, machine);
565 struct cs_etm_cache_entry *e;
571 e = auxtrace_cache__alloc_entry(c);
578 err = auxtrace_cache__add(c, offset, &e->entry);
581 auxtrace_cache__free_entry(c, e);
586 static struct cs_etm_cache_entry *cs_etm__cache_lookup(struct dso *dso,
587 struct machine *machine,
590 struct auxtrace_cache *c = cs_etm__cache(dso, machine);
595 return auxtrace_cache__lookup(dso->auxtrace_cache, offset);
599 static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
600 struct cs_etm_packet *packet)
603 struct cs_etm_auxtrace *etm = etmq->etm;
604 union perf_event *event = etmq->event_buf;
605 struct perf_sample sample = {.ip = 0,};
606 uint64_t start_addr = packet->start_addr;
607 uint64_t end_addr = packet->end_addr;
609 event->sample.header.type = PERF_RECORD_SAMPLE;
610 event->sample.header.misc = PERF_RECORD_MISC_USER;
611 event->sample.header.size = sizeof(struct perf_event_header);
614 sample.ip = start_addr;
615 sample.pid = etmq->pid;
616 sample.tid = etmq->tid;
617 sample.addr = end_addr;
618 sample.id = etmq->etm->instructions_id;
619 sample.stream_id = etmq->etm->instructions_id;
620 sample.period = (end_addr - start_addr) >> 2;
621 sample.cpu = etmq->cpu;
622 sample.flags = 0; // etmq->flags;
623 sample.insn_len = 1; // etmq->insn_len;
625 //etmq->last_insn_cnt = etmq->state->tot_insn_cnt;
629 struct addr_location al;
631 struct thread *thread;
632 struct machine *machine = etmq->etm->machine;
634 struct cs_etm_cache_entry *e;
638 thread = etmq->thread;
641 thread = etmq->etm->unknown_thread;
644 if (start_addr > 0xffffffc000000000UL) {
645 cpumode = PERF_RECORD_MISC_KERNEL;
647 cpumode = PERF_RECORD_MISC_USER;
650 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, start_addr,&al);
651 if (!al.map || !al.map->dso) {
654 if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR &&
655 dso__data_status_seen(al.map->dso,DSO_DATA_STATUS_SEEN_ITRACE)) {
659 offset = al.map->map_ip(al.map,start_addr);
662 e = cs_etm__cache_lookup(al.map->dso, machine, offset);
668 map__load(al.map, machine->symbol_filter);
671 len = dso__data_read_offset(al.map->dso, machine,
678 cs_etm__cache_add(al.map->dso, machine, offset, (end_addr - start_addr) >> 2, end_addr - start_addr);
686 ret = perf_session__deliver_synth_event(etm->session,event, &sample);
689 pr_err("CS ETM Trace: failed to deliver instruction event, error %d\n", ret);
695 struct cs_etm_synth {
696 struct perf_tool dummy_tool;
697 struct perf_session *session;
701 static int cs_etm__event_synth(struct perf_tool *tool,
702 union perf_event *event,
703 struct perf_sample *sample,
704 struct machine *machine)
706 struct cs_etm_synth *cs_etm_synth =
707 container_of(tool, struct cs_etm_synth, dummy_tool);
712 return perf_session__deliver_synth_event(cs_etm_synth->session, event, NULL);
717 static int cs_etm__synth_event(struct perf_session *session,
718 struct perf_event_attr *attr, u64 id)
720 struct cs_etm_synth cs_etm_synth;
722 memset(&cs_etm_synth, 0, sizeof(struct cs_etm_synth));
723 cs_etm_synth.session = session;
725 return perf_event__synthesize_attr(&cs_etm_synth.dummy_tool, attr, 1,
726 &id, cs_etm__event_synth);
729 static int cs_etm__synth_events(struct cs_etm_auxtrace *etm,
730 struct perf_session *session)
732 struct perf_evlist *evlist = session->evlist;
733 struct perf_evsel *evsel;
734 struct perf_event_attr attr;
739 evlist__for_each(evlist, evsel) {
741 if (evsel->attr.type == etm->pmu_type) {
748 pr_debug("There are no selected events with Core Sight Trace data\n");
752 memset(&attr, 0, sizeof(struct perf_event_attr));
753 attr.size = sizeof(struct perf_event_attr);
754 attr.type = PERF_TYPE_HARDWARE;
755 attr.sample_type = evsel->attr.sample_type & PERF_SAMPLE_MASK;
756 attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID |
758 if (etm->timeless_decoding)
759 attr.sample_type &= ~(u64)PERF_SAMPLE_TIME;
761 attr.sample_type |= PERF_SAMPLE_TIME;
763 attr.exclude_user = evsel->attr.exclude_user;
764 attr.exclude_kernel = evsel->attr.exclude_kernel;
765 attr.exclude_hv = evsel->attr.exclude_hv;
766 attr.exclude_host = evsel->attr.exclude_host;
767 attr.exclude_guest = evsel->attr.exclude_guest;
768 attr.sample_id_all = evsel->attr.sample_id_all;
769 attr.read_format = evsel->attr.read_format;
771 id = evsel->id[0] + 1000000000;
776 if (etm->synth_opts.instructions) {
777 attr.config = PERF_COUNT_HW_INSTRUCTIONS;
778 attr.sample_period = etm->synth_opts.period;
779 etm->instructions_sample_period = attr.sample_period;
780 err = cs_etm__synth_event(session, &attr, id);
783 pr_err("%s: failed to synthesize 'instructions' event type\n",
787 etm->sample_instructions = true;
788 etm->instructions_sample_type = attr.sample_type;
789 etm->instructions_id = id;
793 etm->synth_needs_swap = evsel->needs_swap;
797 static int cs_etm__sample(struct cs_etm_queue *etmq)
799 //const struct cs_etm_state *state = etmq->state;
800 struct cs_etm_packet packet;
801 //struct cs_etm_auxtrace *etm = etmq->etm;
804 if (!etmq->have_sample)
807 etmq->have_sample = false;
809 err = cs_etm_decoder__get_packet(etmq->decoder,&packet);
810 // if there is no sample, it returns err = -1, no real error
812 if (!err && packet.sample_type & CS_ETM_RANGE) {
813 err = cs_etm__synth_instruction_sample(etmq,&packet);
820 static int cs_etm__run_decoder(struct cs_etm_queue *etmq, u64 *timestamp)
822 struct cs_etm_buffer buffer = {.buf = 0,};
823 size_t buffer_used = 0;
826 err = cs_etm__get_trace(&buffer,etmq);
831 size_t processed = 0;
832 etmq->state = cs_etm_decoder__process_data_block(etmq->decoder,
834 &buffer.buf[buffer_used],
835 buffer.len-buffer_used,
837 err = etmq->state->err;
838 etmq->offset += processed;
839 buffer_used += processed;
841 etmq->have_sample = true;
842 cs_etm__sample(etmq);
844 } while (!etmq->eot && (buffer.len > buffer_used));
851 static int cs_etm__update_queues(struct cs_etm_auxtrace *etm)
853 if (etm->queues.new_data) {
854 etm->queues.new_data = false;
855 return cs_etm__setup_queues(etm);
860 static int cs_etm__process_queues(struct cs_etm_auxtrace *etm, u64 timestamp)
862 unsigned int queue_nr;
867 struct auxtrace_queue *queue;
868 struct cs_etm_queue *etmq;
870 if (!etm->heap.heap_cnt)
873 if (etm->heap.heap_array[0].ordinal >= timestamp)
876 queue_nr = etm->heap.heap_array[0].queue_nr;
877 queue = &etm->queues.queue_array[queue_nr];
880 //cs_etm__log("queue %u processing 0x%" PRIx64 " to 0x%" PRIx64 "\n",
881 //queue_nr, etm->heap.heap_array[0].ordinal,
884 auxtrace_heap__pop(&etm->heap);
886 if (etm->heap.heap_cnt) {
887 ts = etm->heap.heap_array[0].ordinal + 1;
894 cs_etm__set_pid_tid_cpu(etm, queue);
896 ret = cs_etm__run_decoder(etmq, &ts);
899 auxtrace_heap__add(&etm->heap, queue_nr, ts);
904 ret = auxtrace_heap__add(&etm->heap, queue_nr, ts);
908 etmq->on_heap = false;
914 static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
918 struct auxtrace_queues *queues = &etm->queues;
922 for (i = 0; i < queues->nr_queues; ++i) {
923 struct auxtrace_queue *queue = &(etm->queues.queue_array[i]);
924 struct cs_etm_queue *etmq = queue->priv;
926 if (etmq && ((tid == -1) || (etmq->tid == tid))) {
928 cs_etm__set_pid_tid_cpu(etm, queue);
929 cs_etm__run_decoder(etmq,&ts);
936 static struct cs_etm_queue *cs_etm__cpu_to_etmq(struct cs_etm_auxtrace *etm,
941 if (etm->queues.nr_queues == 0)
946 else if ((unsigned) cpu >= etm->queues.nr_queues)
947 q = etm->queues.nr_queues - 1;
951 if (etm->queues.queue_array[q].cpu == cpu)
952 return etm->queues.queue_array[q].priv;
954 for (j = 0; q > 0; j++) {
955 if (etm->queues.queue_array[--q].cpu == cpu)
956 return etm->queues.queue_array[q].priv;
959 for (; j < etm->queues.nr_queues; j++) {
960 if (etm->queues.queue_array[j].cpu == cpu)
961 return etm->queues.queue_array[j].priv;
968 static uint32_t cs_etm__mem_access(struct cs_etm_queue *etmq, uint64_t address, size_t size, uint8_t *buffer)
970 struct addr_location al;
972 struct thread *thread;
973 struct machine *machine;
980 machine = etmq->etm->machine;
981 thread = etmq->thread;
982 if (address > 0xffffffc000000000UL) {
983 cpumode = PERF_RECORD_MISC_KERNEL;
985 cpumode = PERF_RECORD_MISC_USER;
988 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, address,&al);
990 if (!al.map || !al.map->dso) {
994 if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR &&
995 dso__data_status_seen(al.map->dso,DSO_DATA_STATUS_SEEN_ITRACE)) {
999 offset = al.map->map_ip(al.map,address);
1001 map__load(al.map, machine->symbol_filter);
1003 len = dso__data_read_offset(al.map->dso, machine,
1004 offset, buffer, size);
1013 static bool check_need_swap(int file_endian)
1016 u8 *check = (u8 *)&data;
1020 host_endian = ELFDATA2LSB;
1022 host_endian = ELFDATA2MSB;
1024 return host_endian != file_endian;
1027 static int cs_etm__read_elf_info(const char *fname, uint64_t *foffset, uint64_t *fstart, uint64_t *fsize)
1030 u8 e_ident[EI_NIDENT];
1032 bool need_swap = false;
1037 fp = fopen(fname, "r");
1041 if (fread(e_ident, sizeof(e_ident), 1, fp) != 1)
1044 if (memcmp(e_ident, ELFMAG, SELFMAG) ||
1045 e_ident[EI_VERSION] != EV_CURRENT)
1048 need_swap = check_need_swap(e_ident[EI_DATA]);
1050 /* for simplicity */
1051 fseek(fp, 0, SEEK_SET);
1053 if (e_ident[EI_CLASS] == ELFCLASS32) {
1057 if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
1061 ehdr.e_phoff = bswap_32(ehdr.e_phoff);
1062 ehdr.e_phentsize = bswap_16(ehdr.e_phentsize);
1063 ehdr.e_phnum = bswap_16(ehdr.e_phnum);
1066 buf_size = ehdr.e_phentsize * ehdr.e_phnum;
1067 buf = malloc(buf_size);
1071 fseek(fp, ehdr.e_phoff, SEEK_SET);
1072 if (fread(buf, buf_size, 1, fp) != 1)
1075 for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
1078 phdr->p_type = bswap_32(phdr->p_type);
1079 phdr->p_offset = bswap_32(phdr->p_offset);
1080 phdr->p_filesz = bswap_32(phdr->p_filesz);
1083 if (phdr->p_type != PT_LOAD)
1086 *foffset = phdr->p_offset;
1087 *fstart = phdr->p_vaddr;
1088 *fsize = phdr->p_filesz;
1096 if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
1100 ehdr.e_phoff = bswap_64(ehdr.e_phoff);
1101 ehdr.e_phentsize = bswap_16(ehdr.e_phentsize);
1102 ehdr.e_phnum = bswap_16(ehdr.e_phnum);
1105 buf_size = ehdr.e_phentsize * ehdr.e_phnum;
1106 buf = malloc(buf_size);
1110 fseek(fp, ehdr.e_phoff, SEEK_SET);
1111 if (fread(buf, buf_size, 1, fp) != 1)
1114 for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
1117 phdr->p_type = bswap_32(phdr->p_type);
1118 phdr->p_offset = bswap_64(phdr->p_offset);
1119 phdr->p_filesz = bswap_64(phdr->p_filesz);
1122 if (phdr->p_type != PT_LOAD)
1125 *foffset = phdr->p_offset;
1126 *fstart = phdr->p_vaddr;
1127 *fsize = phdr->p_filesz;
1139 static int cs_etm__process_event(struct perf_session *session,
1140 union perf_event *event,
1141 struct perf_sample *sample,
1142 struct perf_tool *tool)
1144 struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
1145 struct cs_etm_auxtrace,
1154 if (!tool->ordered_events) {
1155 pr_err("CoreSight ETM Trace requires ordered events\n");
1159 if (sample->time && (sample->time != (u64)-1))
1160 timestamp = sample->time;
1164 if (timestamp || etm->timeless_decoding) {
1165 err = cs_etm__update_queues(etm);
1171 if (event->header.type == PERF_RECORD_MMAP2) {
1174 struct cs_etm_queue *etmq;
1178 etmq = cs_etm__cpu_to_etmq(etm,cpu);
1184 dso = dsos__find(&(etm->machine->dsos),event->mmap2.filename,false);
1186 err = cs_etm_decoder__add_mem_access_cb(
1190 cs_etm__mem_access);
1193 if ((symbol_conf.vmlinux_name != NULL) && (!etmq->kernel_mapped)) {
1198 err = cs_etm__read_elf_info(symbol_conf.vmlinux_name,
1199 &foffset,&fstart,&fsize);
1202 cs_etm_decoder__add_bin_file(
1207 symbol_conf.vmlinux_name);
1209 etmq->kernel_mapped = true;
1215 if (etm->timeless_decoding) {
1216 if (event->header.type == PERF_RECORD_EXIT) {
1217 err = cs_etm__process_timeless_queues(etm,
1221 } else if (timestamp) {
1222 err = cs_etm__process_queues(etm, timestamp);
1225 //cs_etm__log("event %s (%u): cpu %d time%"PRIu64" tsc %#"PRIx64"\n",
1226 //perf_event__name(event->header.type), event->header.type,
1227 //sample->cpu, sample->time, timestamp);
1231 static int cs_etm__process_auxtrace_event(struct perf_session *session,
1232 union perf_event *event,
1233 struct perf_tool *tool)
1235 struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
1236 struct cs_etm_auxtrace,
1241 if (!etm->data_queued) {
1242 struct auxtrace_buffer *buffer;
1244 int fd = perf_data_file__fd(session->file);
1245 bool is_pipe = perf_data_file__is_pipe(session->file);
1251 data_offset = lseek(fd, 0, SEEK_CUR);
1252 if (data_offset == -1) {
1257 err = auxtrace_queues__add_event(&etm->queues,
1267 if (auxtrace_buffer__get_data(buffer,fd)) {
1268 cs_etm__dump_event(etm,buffer);
1269 auxtrace_buffer__put_data(buffer);
1278 static const char * const cs_etm_global_header_fmts[] = {
1279 [CS_HEADER_VERSION_0] = " Header version %"PRIx64"\n",
1280 [CS_PMU_TYPE_CPUS] = " PMU type/num cpus %"PRIx64"\n",
1281 [CS_ETM_SNAPSHOT] = " Snapshot %"PRIx64"\n",
1284 static const char * const cs_etm_priv_fmts[] = {
1285 [CS_ETM_MAGIC] = " Magic number %"PRIx64"\n",
1286 [CS_ETM_CPU] = " CPU %"PRIx64"\n",
1287 [CS_ETM_ETMCR] = " ETMCR %"PRIx64"\n",
1288 [CS_ETM_ETMTRACEIDR] = " ETMTRACEIDR %"PRIx64"\n",
1289 [CS_ETM_ETMCCER] = " ETMCCER %"PRIx64"\n",
1290 [CS_ETM_ETMIDR] = " ETMIDR %"PRIx64"\n",
1293 static const char * const cs_etmv4_priv_fmts[] = {
1294 [CS_ETM_MAGIC] = " Magic number %"PRIx64"\n",
1295 [CS_ETM_CPU] = " CPU %"PRIx64"\n",
1296 [CS_ETMV4_TRCCONFIGR] = " TRCCONFIGR %"PRIx64"\n",
1297 [CS_ETMV4_TRCTRACEIDR] = " TRCTRACEIDR %"PRIx64"\n",
1298 [CS_ETMV4_TRCIDR0] = " TRCIDR0 %"PRIx64"\n",
1299 [CS_ETMV4_TRCIDR1] = " TRCIDR1 %"PRIx64"\n",
1300 [CS_ETMV4_TRCIDR2] = " TRCIDR2 %"PRIx64"\n",
1301 [CS_ETMV4_TRCIDR8] = " TRCIDR8 %"PRIx64"\n",
1302 [CS_ETMV4_TRCAUTHSTATUS] = " TRCAUTHSTATUS %"PRIx64"\n",
1305 static void cs_etm__print_auxtrace_info(u64 *val, size_t num)
1309 for (i = 0, cpu = 0; cpu < num; ++cpu) {
1311 if (val[i] == __perf_cs_etmv3_magic) {
1312 for (j = 0; j < CS_ETM_PRIV_MAX; ++j, ++i) {
1313 fprintf(stdout,cs_etm_priv_fmts[j],val[i]);
1315 } else if (val[i] == __perf_cs_etmv4_magic) {
1316 for (j = 0; j < CS_ETMV4_PRIV_MAX; ++j, ++i) {
1317 fprintf(stdout,cs_etmv4_priv_fmts[j],val[i]);
1326 int cs_etm__process_auxtrace_info(union perf_event *event,
1327 struct perf_session *session)
1329 struct auxtrace_info_event *auxtrace_info = &(event->auxtrace_info);
1330 size_t event_header_size = sizeof(struct perf_event_header);
1331 size_t info_header_size = 8;
1332 size_t total_size = auxtrace_info->header.size;
1333 size_t priv_size = 0;
1335 struct cs_etm_auxtrace *etm = 0;
1339 u64 **metadata = NULL;
1343 if (total_size < (event_header_size + info_header_size))
1346 priv_size = total_size - event_header_size - info_header_size;
1348 // First the global part
1350 ptr = (u64 *) auxtrace_info->priv;
1352 hdr = zalloc(sizeof(u64 *) * CS_HEADER_VERSION_0_MAX);
1356 for (i = 0; i < CS_HEADER_VERSION_0_MAX; ++i) {
1359 num_cpu = hdr[CS_PMU_TYPE_CPUS] & 0xffffffff;
1360 pmu_type = (unsigned) ((hdr[CS_PMU_TYPE_CPUS] >> 32) & 0xffffffff);
1365 metadata = zalloc(sizeof(u64 *) * num_cpu);
1367 if (metadata == NULL) {
1371 for (j = 0; j < num_cpu; ++j) {
1372 if (ptr[i] == __perf_cs_etmv3_magic) {
1373 metadata[j] = zalloc(sizeof(u64)*CS_ETM_PRIV_MAX);
1374 if (metadata == NULL)
1376 for (k = 0; k < CS_ETM_PRIV_MAX; k++) {
1377 metadata[j][k] = ptr[i+k];
1379 i += CS_ETM_PRIV_MAX;
1380 } else if (ptr[i] == __perf_cs_etmv4_magic) {
1381 metadata[j] = zalloc(sizeof(u64)*CS_ETMV4_PRIV_MAX);
1382 if (metadata == NULL)
1384 for (k = 0; k < CS_ETMV4_PRIV_MAX; k++) {
1385 metadata[j][k] = ptr[i+k];
1387 i += CS_ETMV4_PRIV_MAX;
1391 if (i*8 != priv_size)
1395 cs_etm__print_auxtrace_info(auxtrace_info->priv,num_cpu);
1397 etm = zalloc(sizeof(struct cs_etm_auxtrace));
1399 etm->num_cpu = num_cpu;
1400 etm->pmu_type = pmu_type;
1401 etm->snapshot_mode = (hdr[CS_ETM_SNAPSHOT] != 0);
1407 err = auxtrace_queues__init(&etm->queues);
1411 etm->unknown_thread = thread__new(999999999,999999999);
1412 if (etm->unknown_thread == NULL) {
1414 goto err_free_queues;
1416 err = thread__set_comm(etm->unknown_thread, "unknown", 0);
1418 goto err_delete_thread;
1421 if (thread__init_map_groups(etm->unknown_thread,
1424 goto err_delete_thread;
1427 etm->timeless_decoding = true;
1428 etm->sampling_mode = false;
1429 etm->metadata = metadata;
1430 etm->session = session;
1431 etm->machine = &session->machines.host;
1432 etm->auxtrace_type = auxtrace_info->type;
1434 etm->auxtrace.process_event = cs_etm__process_event;
1435 etm->auxtrace.process_auxtrace_event = cs_etm__process_auxtrace_event;
1436 etm->auxtrace.flush_events = cs_etm__flush_events;
1437 etm->auxtrace.free_events = cs_etm__free_events;
1438 etm->auxtrace.free = cs_etm__free;
1439 session->auxtrace = &(etm->auxtrace);
1444 if (session->itrace_synth_opts && session->itrace_synth_opts->set) {
1445 etm->synth_opts = *session->itrace_synth_opts;
1447 itrace_synth_opts__set_default(&etm->synth_opts);
1449 etm->synth_opts.branches = false;
1450 etm->synth_opts.callchain = false;
1451 etm->synth_opts.calls = false;
1452 etm->synth_opts.returns = false;
1454 err = cs_etm__synth_events(etm, session);
1456 goto err_delete_thread;
1458 err = auxtrace_queues__process_index(&etm->queues, session);
1460 goto err_delete_thread;
1462 etm->data_queued = etm->queues.populated;
1467 thread__delete(etm->unknown_thread);
1469 auxtrace_queues__free(&etm->queues);
1470 session->auxtrace = NULL;