2 * SPDX-License-Identifier: GPL-2.0
4 * Copyright(C) 2015-2018 Linaro Limited.
6 * Author: Tor Jeremiassen <tor@ti.com>
7 * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
10 #include <linux/bitops.h>
11 #include <linux/err.h>
12 #include <linux/kernel.h>
13 #include <linux/log2.h>
14 #include <linux/types.h>
28 #include "thread_map.h"
29 #include "thread-stack.h"
32 #define MAX_TIMESTAMP (~0ULL)
34 struct cs_etm_auxtrace {
35 struct auxtrace auxtrace;
36 struct auxtrace_queues queues;
37 struct auxtrace_heap heap;
38 struct itrace_synth_opts synth_opts;
39 struct perf_session *session;
40 struct machine *machine;
41 struct thread *unknown_thread;
50 u64 branches_sample_type;
54 unsigned int pmu_type;
58 struct cs_etm_auxtrace *etm;
59 struct thread *thread;
60 struct cs_etm_decoder *decoder;
61 struct auxtrace_buffer *buffer;
62 const struct cs_etm_state *state;
63 union perf_event *event_buf;
64 unsigned int queue_nr;
72 static int cs_etm__flush_events(struct perf_session *session,
73 struct perf_tool *tool)
80 static void cs_etm__free_queue(void *priv)
82 struct cs_etm_queue *etmq = priv;
87 static void cs_etm__free_events(struct perf_session *session)
90 struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
91 struct cs_etm_auxtrace,
93 struct auxtrace_queues *queues = &aux->queues;
95 for (i = 0; i < queues->nr_queues; i++) {
96 cs_etm__free_queue(queues->queue_array[i].priv);
97 queues->queue_array[i].priv = NULL;
100 auxtrace_queues__free(queues);
103 static void cs_etm__free(struct perf_session *session)
105 struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
106 struct cs_etm_auxtrace,
108 cs_etm__free_events(session);
109 session->auxtrace = NULL;
114 static int cs_etm__process_event(struct perf_session *session,
115 union perf_event *event,
116 struct perf_sample *sample,
117 struct perf_tool *tool)
126 static int cs_etm__process_auxtrace_event(struct perf_session *session,
127 union perf_event *event,
128 struct perf_tool *tool)
136 static bool cs_etm__is_timeless_decoding(struct cs_etm_auxtrace *etm)
138 struct perf_evsel *evsel;
139 struct perf_evlist *evlist = etm->session->evlist;
140 bool timeless_decoding = true;
143 * Circle through the list of event and complain if we find one
144 * with the time bit set.
146 evlist__for_each_entry(evlist, evsel) {
147 if ((evsel->attr.sample_type & PERF_SAMPLE_TIME))
148 timeless_decoding = false;
151 return timeless_decoding;
154 int cs_etm__process_auxtrace_info(union perf_event *event,
155 struct perf_session *session)
157 struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info;
158 struct cs_etm_auxtrace *etm = NULL;
159 int event_header_size = sizeof(struct perf_event_header);
160 int info_header_size;
161 int total_size = auxtrace_info->header.size;
165 * sizeof(auxtrace_info_event::type) +
166 * sizeof(auxtrace_info_event::reserved) == 8
168 info_header_size = 8;
170 if (total_size < (event_header_size + info_header_size))
173 etm = zalloc(sizeof(*etm));
178 err = auxtrace_queues__init(&etm->queues);
182 etm->session = session;
183 etm->machine = &session->machines.host;
185 etm->auxtrace_type = auxtrace_info->type;
186 etm->timeless_decoding = cs_etm__is_timeless_decoding(etm);
188 etm->auxtrace.process_event = cs_etm__process_event;
189 etm->auxtrace.process_auxtrace_event = cs_etm__process_auxtrace_event;
190 etm->auxtrace.flush_events = cs_etm__flush_events;
191 etm->auxtrace.free_events = cs_etm__free_events;
192 etm->auxtrace.free = cs_etm__free;
193 session->auxtrace = &etm->auxtrace;
198 err = auxtrace_queues__process_index(&etm->queues, session);
200 goto err_free_queues;
202 etm->data_queued = etm->queues.populated;
207 auxtrace_queues__free(&etm->queues);
208 session->auxtrace = NULL;