// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright(C) 2015-2018 Linaro Limited.
 *
 * Author: Tor Jeremiassen <tor@ti.com>
 * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
 */

#include <linux/bitops.h>
#include <linux/coresight-pmu.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/types.h>
#include <linux/zalloc.h>

#include <opencsd/ocsd_if_types.h>
#include <stdlib.h>

#include "auxtrace.h"
#include "color.h"
#include "cs-etm.h"
#include "cs-etm-decoder/cs-etm-decoder.h"
#include "debug.h"
#include "dso.h"
#include "evlist.h"
#include "intlist.h"
#include "machine.h"
#include "map.h"
#include "perf.h"
#include "session.h"
#include "map_symbol.h"
#include "branch.h"
#include "symbol.h"
#include "tool.h"
#include "thread.h"
#include "thread-stack.h"
#include <tools/libc_compat.h>
#include "util/synthetic-events.h"

struct cs_etm_auxtrace {
	struct auxtrace auxtrace;
	struct auxtrace_queues queues;
	struct auxtrace_heap heap;
	struct itrace_synth_opts synth_opts;
	struct perf_session *session;
	struct machine *machine;
	struct thread *unknown_thread;

	u8 timeless_decoding;
	u8 snapshot_mode;
	u8 data_queued;
	u8 sample_branches;
	u8 sample_instructions;

	int num_cpu;
	u64 latest_kernel_timestamp;
	u32 auxtrace_type;
	u64 branches_sample_type;
	u64 branches_id;
	u64 instructions_sample_type;
	u64 instructions_sample_period;
	u64 instructions_id;
	u64 **metadata;
	u64 kernel_start;
	unsigned int pmu_type;
};

struct cs_etm_traceid_queue {
	u8 trace_chan_id;
	pid_t pid, tid;
	u64 period_instructions;
	size_t last_branch_pos;
	union perf_event *event_buf;
	struct thread *thread;
	struct branch_stack *last_branch;
	struct branch_stack *last_branch_rb;
	struct cs_etm_packet *prev_packet;
	struct cs_etm_packet *packet;
	struct cs_etm_packet_queue packet_queue;
};

struct cs_etm_queue {
	struct cs_etm_auxtrace *etm;
	struct cs_etm_decoder *decoder;
	struct auxtrace_buffer *buffer;
	unsigned int queue_nr;
	u8 pending_timestamp_chan_id;
	u64 offset;
	const unsigned char *buf;
	size_t buf_len, buf_used;
	/* Conversion between traceID and index in traceid_queues array */
	struct intlist *traceid_queues_list;
	struct cs_etm_traceid_queue **traceid_queues;
};

/* RB tree for quick conversion between traceID and metadata pointers */
static struct intlist *traceid_list;

static int cs_etm__update_queues(struct cs_etm_auxtrace *etm);
static int cs_etm__process_queues(struct cs_etm_auxtrace *etm);
static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
					   pid_t tid);
static int cs_etm__get_data_block(struct cs_etm_queue *etmq);
static int cs_etm__decode_data_block(struct cs_etm_queue *etmq);

/* PTMs ETMIDR [11:8] set to b0011 */
#define ETMIDR_PTM_VERSION 0x00000300

/*
 * A struct auxtrace_heap_item only has a queue_nr and a timestamp to
 * work with.  One option is to modify to auxtrace_heap_XYZ() API or simply
 * encode the etm queue number as the upper 16 bit and the channel as
 * the lower 16 bit.
 */
#define TO_CS_QUEUE_NR(queue_nr, trace_chan_id)	\
		      (queue_nr << 16 | trace_chan_id)
#define TO_QUEUE_NR(cs_queue_nr) (cs_queue_nr >> 16)
#define TO_TRACE_CHAN_ID(cs_queue_nr) (cs_queue_nr & 0x0000ffff)

static u32 cs_etm__get_v7_protocol_version(u32 etmidr)
{
	etmidr &= ETMIDR_PTM_VERSION;

	if (etmidr == ETMIDR_PTM_VERSION)
		return CS_ETM_PROTO_PTM;

	return CS_ETM_PROTO_ETMV3;
}

static int cs_etm__get_magic(u8 trace_chan_id, u64 *magic)
{
	struct int_node *inode;
	u64 *metadata;

	inode = intlist__find(traceid_list, trace_chan_id);
	if (!inode)
		return -EINVAL;

	metadata = inode->priv;
	*magic = metadata[CS_ETM_MAGIC];
	return 0;
}

int cs_etm__get_cpu(u8 trace_chan_id, int *cpu)
{
	struct int_node *inode;
	u64 *metadata;

	inode = intlist__find(traceid_list, trace_chan_id);
	if (!inode)
		return -EINVAL;

	metadata = inode->priv;
	*cpu = (int)metadata[CS_ETM_CPU];
	return 0;
}

/*
 * The returned PID format is presented by two bits:
 *
 *   Bit ETM_OPT_CTXTID: CONTEXTIDR or CONTEXTIDR_EL1 is traced;
 *   Bit ETM_OPT_CTXTID2: CONTEXTIDR_EL2 is traced.
 *
 * It's possible that the two bits ETM_OPT_CTXTID and ETM_OPT_CTXTID2
 * are enabled at the same time when the session runs on an EL2 kernel.
 * This means the CONTEXTIDR_EL1 and CONTEXTIDR_EL2 both will be
 * recorded in the trace data, the tool will selectively use
 * CONTEXTIDR_EL2 as PID.
 */
int cs_etm__get_pid_fmt(u8 trace_chan_id, u64 *pid_fmt)
{
	struct int_node *inode;
	u64 *metadata, val;

	inode = intlist__find(traceid_list, trace_chan_id);
	if (!inode)
		return -EINVAL;

	metadata = inode->priv;

	if (metadata[CS_ETM_MAGIC] == __perf_cs_etmv3_magic) {
		val = metadata[CS_ETM_ETMCR];
		/* CONTEXTIDR is traced */
		if (val & BIT(ETM_OPT_CTXTID))
			*pid_fmt = BIT(ETM_OPT_CTXTID);
	} else {
		val = metadata[CS_ETMV4_TRCCONFIGR];
		/* CONTEXTIDR_EL2 is traced */
		if (val & (BIT(ETM4_CFG_BIT_VMID) | BIT(ETM4_CFG_BIT_VMID_OPT)))
			*pid_fmt = BIT(ETM_OPT_CTXTID2);
		/* CONTEXTIDR_EL1 is traced */
		else if (val & BIT(ETM4_CFG_BIT_CTXTID))
			*pid_fmt = BIT(ETM_OPT_CTXTID);
	}

	return 0;
}

void cs_etm__etmq_set_traceid_queue_timestamp(struct cs_etm_queue *etmq,
					      u8 trace_chan_id)
{
	/*
	 * When a timestamp packet is encountered the backend code
	 * is stopped so that the front end has time to process packets
	 * that were accumulated in the traceID queue.  Since there can
	 * be more than one channel per cs_etm_queue, we need to specify
	 * what traceID queue needs servicing.
	 */
	etmq->pending_timestamp_chan_id = trace_chan_id;
}

static u64 cs_etm__etmq_get_timestamp(struct cs_etm_queue *etmq,
				      u8 *trace_chan_id)
{
	struct cs_etm_packet_queue *packet_queue;

	if (!etmq->pending_timestamp_chan_id)
		return 0;

	if (trace_chan_id)
		*trace_chan_id = etmq->pending_timestamp_chan_id;

	packet_queue = cs_etm__etmq_get_packet_queue(etmq,
						     etmq->pending_timestamp_chan_id);
	if (!packet_queue)
		return 0;

	/* Acknowledge pending status */
	etmq->pending_timestamp_chan_id = 0;

	/* See function cs_etm_decoder__do_{hard|soft}_timestamp() */
	return packet_queue->cs_timestamp;
}

static void cs_etm__clear_packet_queue(struct cs_etm_packet_queue *queue)
{
	int i;

	queue->head = 0;
	queue->tail = 0;
	queue->packet_count = 0;
	for (i = 0; i < CS_ETM_PACKET_MAX_BUFFER; i++) {
		queue->packet_buffer[i].isa = CS_ETM_ISA_UNKNOWN;
		queue->packet_buffer[i].start_addr = CS_ETM_INVAL_ADDR;
		queue->packet_buffer[i].end_addr = CS_ETM_INVAL_ADDR;
		queue->packet_buffer[i].instr_count = 0;
		queue->packet_buffer[i].last_instr_taken_branch = false;
		queue->packet_buffer[i].last_instr_size = 0;
		queue->packet_buffer[i].last_instr_type = 0;
		queue->packet_buffer[i].last_instr_subtype = 0;
		queue->packet_buffer[i].last_instr_cond = 0;
		queue->packet_buffer[i].flags = 0;
		queue->packet_buffer[i].exception_number = UINT32_MAX;
		queue->packet_buffer[i].trace_chan_id = UINT8_MAX;
		queue->packet_buffer[i].cpu = INT_MIN;
	}
}

static void cs_etm__clear_all_packet_queues(struct cs_etm_queue *etmq)
{
	int idx;
	struct int_node *inode;
	struct cs_etm_traceid_queue *tidq;
	struct intlist *traceid_queues_list = etmq->traceid_queues_list;

	intlist__for_each_entry(inode, traceid_queues_list) {
		idx = (int)(intptr_t)inode->priv;
		tidq = etmq->traceid_queues[idx];
		cs_etm__clear_packet_queue(&tidq->packet_queue);
	}
}

static int cs_etm__init_traceid_queue(struct cs_etm_queue *etmq,
				      struct cs_etm_traceid_queue *tidq,
				      u8 trace_chan_id)
{
	int rc = -ENOMEM;
	struct auxtrace_queue *queue;
	struct cs_etm_auxtrace *etm = etmq->etm;

	cs_etm__clear_packet_queue(&tidq->packet_queue);

	queue = &etmq->etm->queues.queue_array[etmq->queue_nr];
	tidq->tid = queue->tid;
	tidq->pid = -1;
	tidq->trace_chan_id = trace_chan_id;

	tidq->packet = zalloc(sizeof(struct cs_etm_packet));
	if (!tidq->packet)
		goto out;

	tidq->prev_packet = zalloc(sizeof(struct cs_etm_packet));
	if (!tidq->prev_packet)
		goto out_free;

	if (etm->synth_opts.last_branch) {
		size_t sz = sizeof(struct branch_stack);

		sz += etm->synth_opts.last_branch_sz *
		      sizeof(struct branch_entry);
		tidq->last_branch = zalloc(sz);
		if (!tidq->last_branch)
			goto out_free;
		tidq->last_branch_rb = zalloc(sz);
		if (!tidq->last_branch_rb)
			goto out_free;
	}

	tidq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE);
	if (!tidq->event_buf)
		goto out_free;

	return 0;

out_free:
	zfree(&tidq->last_branch_rb);
	zfree(&tidq->last_branch);
	zfree(&tidq->prev_packet);
	zfree(&tidq->packet);
out:
	return rc;
}

static struct cs_etm_traceid_queue
*cs_etm__etmq_get_traceid_queue(struct cs_etm_queue *etmq, u8 trace_chan_id)
{
	int idx;
	struct int_node *inode;
	struct intlist *traceid_queues_list;
	struct cs_etm_traceid_queue *tidq, **traceid_queues;
	struct cs_etm_auxtrace *etm = etmq->etm;

	if (etm->timeless_decoding)
		trace_chan_id = CS_ETM_PER_THREAD_TRACEID;

	traceid_queues_list = etmq->traceid_queues_list;

	/*
	 * Check if the traceid_queue exist for this traceID by looking
	 * in the queue list.
	 */
	inode = intlist__find(traceid_queues_list, trace_chan_id);
	if (inode) {
		idx = (int)(intptr_t)inode->priv;
		return etmq->traceid_queues[idx];
	}

	/* We couldn't find a traceid_queue for this traceID, allocate one */
	tidq = malloc(sizeof(*tidq));
	if (!tidq)
		return NULL;

	memset(tidq, 0, sizeof(*tidq));

	/* Get a valid index for the new traceid_queue */
	idx = intlist__nr_entries(traceid_queues_list);
	/* Memory for the inode is free'ed in cs_etm_free_traceid_queues () */
	inode = intlist__findnew(traceid_queues_list, trace_chan_id);
	if (!inode)
		goto out_free;

	/* Associate this traceID with this index */
	inode->priv = (void *)(intptr_t)idx;

	if (cs_etm__init_traceid_queue(etmq, tidq, trace_chan_id))
		goto out_free;

	/* Grow the traceid_queues array by one unit */
	traceid_queues = etmq->traceid_queues;
	traceid_queues = reallocarray(traceid_queues,
				      idx + 1,
				      sizeof(*traceid_queues));

	/*
	 * On failure reallocarray() returns NULL and the original block of
	 * memory is left untouched.
	 */
	if (!traceid_queues)
		goto out_free;

	traceid_queues[idx] = tidq;
	etmq->traceid_queues = traceid_queues;

	return etmq->traceid_queues[idx];

out_free:
	/*
	 * Function intlist__remove() removes the inode from the list
	 * and delete the memory associated to it.
	 */
	intlist__remove(traceid_queues_list, inode);
	free(tidq);

	return NULL;
}

struct cs_etm_packet_queue
*cs_etm__etmq_get_packet_queue(struct cs_etm_queue *etmq, u8 trace_chan_id)
{
	struct cs_etm_traceid_queue *tidq;

	tidq = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id);
	if (tidq)
		return &tidq->packet_queue;

	return NULL;
}

static void cs_etm__packet_swap(struct cs_etm_auxtrace *etm,
				struct cs_etm_traceid_queue *tidq)
{
	struct cs_etm_packet *tmp;

	if (etm->sample_branches || etm->synth_opts.last_branch ||
	    etm->sample_instructions) {
		/*
		 * Swap PACKET with PREV_PACKET: PACKET becomes PREV_PACKET for
		 * the next incoming packet.
		 */
		tmp = tidq->packet;
		tidq->packet = tidq->prev_packet;
		tidq->prev_packet = tmp;
	}
}

static void cs_etm__packet_dump(const char *pkt_string)
{
	const char *color = PERF_COLOR_BLUE;
	int len = strlen(pkt_string);

	if (len && (pkt_string[len-1] == '\n'))
		color_fprintf(stdout, color, "	%s", pkt_string);
	else
		color_fprintf(stdout, color, "	%s\n", pkt_string);

	fflush(stdout);
}

static void cs_etm__set_trace_param_etmv3(struct cs_etm_trace_params *t_params,
					  struct cs_etm_auxtrace *etm, int idx,
					  u32 etmidr)
{
	u64 **metadata = etm->metadata;

	t_params[idx].protocol = cs_etm__get_v7_protocol_version(etmidr);
	t_params[idx].etmv3.reg_ctrl = metadata[idx][CS_ETM_ETMCR];
	t_params[idx].etmv3.reg_trc_id = metadata[idx][CS_ETM_ETMTRACEIDR];
}

static void cs_etm__set_trace_param_etmv4(struct cs_etm_trace_params *t_params,
					  struct cs_etm_auxtrace *etm, int idx)
{
	u64 **metadata = etm->metadata;

	t_params[idx].protocol = CS_ETM_PROTO_ETMV4i;
	t_params[idx].etmv4.reg_idr0 = metadata[idx][CS_ETMV4_TRCIDR0];
	t_params[idx].etmv4.reg_idr1 = metadata[idx][CS_ETMV4_TRCIDR1];
	t_params[idx].etmv4.reg_idr2 = metadata[idx][CS_ETMV4_TRCIDR2];
	t_params[idx].etmv4.reg_idr8 = metadata[idx][CS_ETMV4_TRCIDR8];
	t_params[idx].etmv4.reg_configr = metadata[idx][CS_ETMV4_TRCCONFIGR];
	t_params[idx].etmv4.reg_traceidr = metadata[idx][CS_ETMV4_TRCTRACEIDR];
}

static int cs_etm__init_trace_params(struct cs_etm_trace_params *t_params,
				     struct cs_etm_auxtrace *etm)
{
	int i;
	u32 etmidr;
	u64 architecture;

	for (i = 0; i < etm->num_cpu; i++) {
		architecture = etm->metadata[i][CS_ETM_MAGIC];

		switch (architecture) {
		case __perf_cs_etmv3_magic:
			etmidr = etm->metadata[i][CS_ETM_ETMIDR];
			cs_etm__set_trace_param_etmv3(t_params, etm, i, etmidr);
			break;
		case __perf_cs_etmv4_magic:
			cs_etm__set_trace_param_etmv4(t_params, etm, i);
			break;
		default:
			return -EINVAL;
		}
	}

	return 0;
}

static int cs_etm__init_decoder_params(struct cs_etm_decoder_params *d_params,
				       struct cs_etm_queue *etmq,
				       enum cs_etm_decoder_operation mode)
{
	int ret = -EINVAL;

	if (!(mode < CS_ETM_OPERATION_MAX))
		goto out;

	d_params->packet_printer = cs_etm__packet_dump;
	d_params->operation = mode;
	d_params->data = etmq;
	d_params->formatted = true;
	d_params->fsyncs = false;
	d_params->hsyncs = false;
	d_params->frame_aligned = true;

	ret = 0;
out:
	return ret;
}

static void cs_etm__dump_event(struct cs_etm_auxtrace *etm,
			       struct auxtrace_buffer *buffer)
{
	int ret;
	const char *color = PERF_COLOR_BLUE;
	struct cs_etm_decoder_params d_params;
	struct cs_etm_trace_params *t_params;
	struct cs_etm_decoder *decoder;
	size_t buffer_used = 0;

	fprintf(stdout, "\n");
	color_fprintf(stdout, color,
		     ". ... CoreSight ETM Trace data: size %zu bytes\n",
		     buffer->size);

	/* Use metadata to fill in trace parameters for trace decoder */
	t_params = zalloc(sizeof(*t_params) * etm->num_cpu);

	if (!t_params)
		return;

	if (cs_etm__init_trace_params(t_params, etm))
		goto out_free;

	/* Set decoder parameters to simply print the trace packets */
	if (cs_etm__init_decoder_params(&d_params, NULL,
					CS_ETM_OPERATION_PRINT))
		goto out_free;

	decoder = cs_etm_decoder__new(etm->num_cpu, &d_params, t_params);

	if (!decoder)
		goto out_free;
	do {
		size_t consumed;

		ret = cs_etm_decoder__process_data_block(
				decoder, buffer->offset,
				&((u8 *)buffer->data)[buffer_used],
				buffer->size - buffer_used, &consumed);
		if (ret)
			break;

		buffer_used += consumed;
	} while (buffer_used < buffer->size);

	cs_etm_decoder__free(decoder);

out_free:
	zfree(&t_params);
}

static int cs_etm__flush_events(struct perf_session *session,
				struct perf_tool *tool)
{
	int ret;
	struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
						   struct cs_etm_auxtrace,
						   auxtrace);
	if (dump_trace)
		return 0;

	if (!tool->ordered_events)
		return -EINVAL;

	ret = cs_etm__update_queues(etm);

	if (ret < 0)
		return ret;

	if (etm->timeless_decoding)
		return cs_etm__process_timeless_queues(etm, -1);

	return cs_etm__process_queues(etm);
}

static void cs_etm__free_traceid_queues(struct cs_etm_queue *etmq)
{
	int idx;
	uintptr_t priv;
	struct int_node *inode, *tmp;
	struct cs_etm_traceid_queue *tidq;
	struct intlist *traceid_queues_list = etmq->traceid_queues_list;

	intlist__for_each_entry_safe(inode, tmp, traceid_queues_list) {
		priv = (uintptr_t)inode->priv;
		idx = priv;

		/* Free this traceid_queue from the array */
		tidq = etmq->traceid_queues[idx];
		thread__zput(tidq->thread);
		zfree(&tidq->event_buf);
		zfree(&tidq->last_branch);
		zfree(&tidq->last_branch_rb);
		zfree(&tidq->prev_packet);
		zfree(&tidq->packet);
		zfree(&tidq);

		/*
		 * Function intlist__remove() removes the inode from the list
		 * and delete the memory associated to it.
		 */
		intlist__remove(traceid_queues_list, inode);
	}

	/* Then the RB tree itself */
	intlist__delete(traceid_queues_list);
	etmq->traceid_queues_list = NULL;

	/* finally free the traceid_queues array */
	zfree(&etmq->traceid_queues);
}

static void cs_etm__free_queue(void *priv)
{
	struct cs_etm_queue *etmq = priv;

	if (!etmq)
		return;

	cs_etm_decoder__free(etmq->decoder);
	cs_etm__free_traceid_queues(etmq);
	free(etmq);
}

static void cs_etm__free_events(struct perf_session *session)
{
	unsigned int i;
	struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
						   struct cs_etm_auxtrace,
						   auxtrace);
	struct auxtrace_queues *queues = &aux->queues;

	for (i = 0; i < queues->nr_queues; i++) {
		cs_etm__free_queue(queues->queue_array[i].priv);
		queues->queue_array[i].priv = NULL;
	}

	auxtrace_queues__free(queues);
}

static void cs_etm__free(struct perf_session *session)
{
	int i;
	struct int_node *inode, *tmp;
	struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
						   struct cs_etm_auxtrace,
						   auxtrace);
	cs_etm__free_events(session);
	session->auxtrace = NULL;

	/* First remove all traceID/metadata nodes for the RB tree */
	intlist__for_each_entry_safe(inode, tmp, traceid_list)
		intlist__remove(traceid_list, inode);
	/* Then the RB tree itself */
	intlist__delete(traceid_list);

	for (i = 0; i < aux->num_cpu; i++)
		zfree(&aux->metadata[i]);

	thread__zput(aux->unknown_thread);
	zfree(&aux->metadata);
	zfree(&aux);
}

static bool cs_etm__evsel_is_auxtrace(struct perf_session *session,
				      struct evsel *evsel)
{
	struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
						   struct cs_etm_auxtrace,
						   auxtrace);

	return evsel->core.attr.type == aux->pmu_type;
}

static u8 cs_etm__cpu_mode(struct cs_etm_queue *etmq, u64 address)
{
	struct machine *machine;

	machine = etmq->etm->machine;

	if (address >= etmq->etm->kernel_start) {
		if (machine__is_host(machine))
			return PERF_RECORD_MISC_KERNEL;
		else
			return PERF_RECORD_MISC_GUEST_KERNEL;
	} else {
		if (machine__is_host(machine))
			return PERF_RECORD_MISC_USER;
		else if (perf_guest)
			return PERF_RECORD_MISC_GUEST_USER;
		else
			return PERF_RECORD_MISC_HYPERVISOR;
	}
}

static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
			      u64 address, size_t size, u8 *buffer)
{
	u8  cpumode;
	u64 offset;
	int len;
	struct thread *thread;
	struct machine *machine;
	struct addr_location al;
	struct cs_etm_traceid_queue *tidq;

	if (!etmq)
		return 0;

	machine = etmq->etm->machine;
	cpumode = cs_etm__cpu_mode(etmq, address);
	tidq = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id);
	if (!tidq)
		return 0;

	thread = tidq->thread;
	if (!thread) {
		if (cpumode != PERF_RECORD_MISC_KERNEL)
			return 0;
		thread = etmq->etm->unknown_thread;
	}

	if (!thread__find_map(thread, cpumode, address, &al) || !al.map->dso)
		return 0;

	if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR &&
	    dso__data_status_seen(al.map->dso, DSO_DATA_STATUS_SEEN_ITRACE))
		return 0;

	offset = al.map->map_ip(al.map, address);

	map__load(al.map);

	len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size);

	if (len <= 0)
		return 0;

	return len;
}

static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm)
{
	struct cs_etm_decoder_params d_params;
	struct cs_etm_trace_params  *t_params = NULL;
	struct cs_etm_queue *etmq;

	etmq = zalloc(sizeof(*etmq));
	if (!etmq)
		return NULL;

	etmq->traceid_queues_list = intlist__new(NULL);
	if (!etmq->traceid_queues_list)
		goto out_free;

	/* Use metadata to fill in trace parameters for trace decoder */
	t_params = zalloc(sizeof(*t_params) * etm->num_cpu);

	if (!t_params)
		goto out_free;

	if (cs_etm__init_trace_params(t_params, etm))
		goto out_free;

	/* Set decoder parameters to decode trace packets */
	if (cs_etm__init_decoder_params(&d_params, etmq,
					CS_ETM_OPERATION_DECODE))
		goto out_free;

	etmq->decoder = cs_etm_decoder__new(etm->num_cpu, &d_params, t_params);

	if (!etmq->decoder)
		goto out_free;

	/*
	 * Register a function to handle all memory accesses required by
	 * the trace decoder library.
	 */
	if (cs_etm_decoder__add_mem_access_cb(etmq->decoder,
					      0x0L, ((u64) -1L),
					      cs_etm__mem_access))
		goto out_free_decoder;

	zfree(&t_params);
	return etmq;

out_free_decoder:
	cs_etm_decoder__free(etmq->decoder);
out_free:
	intlist__delete(etmq->traceid_queues_list);
	free(etmq);

	return NULL;
}

static int cs_etm__setup_queue(struct cs_etm_auxtrace *etm,
			       struct auxtrace_queue *queue,
			       unsigned int queue_nr)
{
	int ret = 0;
	unsigned int cs_queue_nr;
	u8 trace_chan_id;
	u64 cs_timestamp;
	struct cs_etm_queue *etmq = queue->priv;

	if (list_empty(&queue->head) || etmq)
		goto out;

	etmq = cs_etm__alloc_queue(etm);

	if (!etmq) {
		ret = -ENOMEM;
		goto out;
	}

	queue->priv = etmq;
	etmq->etm = etm;
	etmq->queue_nr = queue_nr;
	etmq->offset = 0;

	if (etm->timeless_decoding)
		goto out;

	/*
	 * We are under a CPU-wide trace scenario.  As such we need to know
	 * when the code that generated the traces started to execute so that
	 * it can be correlated with execution on other CPUs.  So we get a
	 * handle on the beginning of traces and decode until we find a
	 * timestamp.  The timestamp is then added to the auxtrace min heap
	 * in order to know what nibble (of all the etmqs) to decode first.
	 */
	while (1) {
		/*
		 * Fetch an aux_buffer from this etmq.  Bail if no more
		 * blocks or an error has been encountered.
		 */
		ret = cs_etm__get_data_block(etmq);
		if (ret <= 0)
			goto out;

		/*
		 * Run decoder on the trace block.  The decoder will stop when
		 * encountering a CS timestamp, a full packet queue or the end of
		 * trace for that block.
		 */
		ret = cs_etm__decode_data_block(etmq);
		if (ret)
			goto out;

		/*
		 * Function cs_etm_decoder__do_{hard|soft}_timestamp() does all
		 * the timestamp calculation for us.
		 */
		cs_timestamp = cs_etm__etmq_get_timestamp(etmq, &trace_chan_id);

		/* We found a timestamp, no need to continue. */
		if (cs_timestamp)
			break;

		/*
		 * We didn't find a timestamp so empty all the traceid packet
		 * queues before looking for another timestamp packet, either
		 * in the current data block or a new one.  Packets that were
		 * just decoded are useless since no timestamp has been
		 * associated with them.  As such simply discard them.
		 */
		cs_etm__clear_all_packet_queues(etmq);
	}

	/*
	 * We have a timestamp.  Add it to the min heap to reflect when
	 * instructions conveyed by the range packets of this traceID queue
	 * started to execute.  Once the same has been done for all the traceID
	 * queues of each etmq, redenring and decoding can start in
	 * chronological order.
	 *
	 * Note that packets decoded above are still in the traceID's packet
	 * queue and will be processed in cs_etm__process_queues().
	 */
	cs_queue_nr = TO_CS_QUEUE_NR(queue_nr, trace_chan_id);
	ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, cs_timestamp);
out:
	return ret;
}

static int cs_etm__setup_queues(struct cs_etm_auxtrace *etm)
{
	unsigned int i;
	int ret;

	if (!etm->kernel_start)
		etm->kernel_start = machine__kernel_start(etm->machine);

	for (i = 0; i < etm->queues.nr_queues; i++) {
		ret = cs_etm__setup_queue(etm, &etm->queues.queue_array[i], i);
		if (ret)
			return ret;
	}

	return 0;
}

static int cs_etm__update_queues(struct cs_etm_auxtrace *etm)
{
	if (etm->queues.new_data) {
		etm->queues.new_data = false;
		return cs_etm__setup_queues(etm);
	}

	return 0;
}

static inline
void cs_etm__copy_last_branch_rb(struct cs_etm_queue *etmq,
				 struct cs_etm_traceid_queue *tidq)
{
	struct branch_stack *bs_src = tidq->last_branch_rb;
	struct branch_stack *bs_dst = tidq->last_branch;
	size_t nr = 0;

	/*
	 * Set the number of records before early exit: ->nr is used to
	 * determine how many branches to copy from ->entries.
	 */
	bs_dst->nr = bs_src->nr;

	/*
	 * Early exit when there is nothing to copy.
	 */
	if (!bs_src->nr)
		return;

	/*
	 * As bs_src->entries is a circular buffer, we need to copy from it in
	 * two steps.  First, copy the branches from the most recently inserted
	 * branch ->last_branch_pos until the end of bs_src->entries buffer.
	 */
	nr = etmq->etm->synth_opts.last_branch_sz - tidq->last_branch_pos;
	memcpy(&bs_dst->entries[0],
	       &bs_src->entries[tidq->last_branch_pos],
	       sizeof(struct branch_entry) * nr);

	/*
	 * If we wrapped around at least once, the branches from the beginning
	 * of the bs_src->entries buffer and until the ->last_branch_pos element
	 * are older valid branches: copy them over.  The total number of
	 * branches copied over will be equal to the number of branches asked by
	 * the user in last_branch_sz.
	 */
	if (bs_src->nr >= etmq->etm->synth_opts.last_branch_sz) {
		memcpy(&bs_dst->entries[nr],
		       &bs_src->entries[0],
		       sizeof(struct branch_entry) * tidq->last_branch_pos);
	}
}

static inline
void cs_etm__reset_last_branch_rb(struct cs_etm_traceid_queue *tidq)
{
	tidq->last_branch_pos = 0;
	tidq->last_branch_rb->nr = 0;
}

static inline int cs_etm__t32_instr_size(struct cs_etm_queue *etmq,
					 u8 trace_chan_id, u64 addr)
{
	u8 instrBytes[2];

	cs_etm__mem_access(etmq, trace_chan_id, addr,
			   ARRAY_SIZE(instrBytes), instrBytes);
	/*
	 * T32 instruction size is indicated by bits[15:11] of the first
	 * 16-bit word of the instruction: 0b11101, 0b11110 and 0b11111
	 * denote a 32-bit instruction.
	 */
	return ((instrBytes[1] & 0xF8) >= 0xE8) ? 4 : 2;
}

static inline u64 cs_etm__first_executed_instr(struct cs_etm_packet *packet)
{
	/* Returns 0 for the CS_ETM_DISCONTINUITY packet */
	if (packet->sample_type == CS_ETM_DISCONTINUITY)
		return 0;

	return packet->start_addr;
}

static inline
u64 cs_etm__last_executed_instr(const struct cs_etm_packet *packet)
{
	/* Returns 0 for the CS_ETM_DISCONTINUITY packet */
	if (packet->sample_type == CS_ETM_DISCONTINUITY)
		return 0;

	return packet->end_addr - packet->last_instr_size;
}

static inline u64 cs_etm__instr_addr(struct cs_etm_queue *etmq,
				     u64 trace_chan_id,
				     const struct cs_etm_packet *packet,
				     u64 offset)
{
	if (packet->isa == CS_ETM_ISA_T32) {
		u64 addr = packet->start_addr;

		while (offset) {
			addr += cs_etm__t32_instr_size(etmq,
						       trace_chan_id, addr);
			offset--;
		}
		return addr;
	}

	/* Assume a 4 byte instruction size (A32/A64) */
	return packet->start_addr + offset * 4;
}

static void cs_etm__update_last_branch_rb(struct cs_etm_queue *etmq,
					  struct cs_etm_traceid_queue *tidq)
{
	struct branch_stack *bs = tidq->last_branch_rb;
	struct branch_entry *be;

	/*
	 * The branches are recorded in a circular buffer in reverse
	 * chronological order: we start recording from the last element of the
	 * buffer down.  After writing the first element of the stack, move the
	 * insert position back to the end of the buffer.
	 */
	if (!tidq->last_branch_pos)
		tidq->last_branch_pos = etmq->etm->synth_opts.last_branch_sz;

	tidq->last_branch_pos -= 1;

	be       = &bs->entries[tidq->last_branch_pos];
	be->from = cs_etm__last_executed_instr(tidq->prev_packet);
	be->to	 = cs_etm__first_executed_instr(tidq->packet);
	/* No support for mispredict */
	be->flags.mispred = 0;
	be->flags.predicted = 1;

	/*
	 * Increment bs->nr until reaching the number of last branches asked by
	 * the user on the command line.
	 */
	if (bs->nr < etmq->etm->synth_opts.last_branch_sz)
		bs->nr += 1;
}

static int cs_etm__inject_event(union perf_event *event,
			       struct perf_sample *sample, u64 type)
{
	event->header.size = perf_event__sample_event_size(sample, type, 0);
	return perf_event__synthesize_sample(event, type, 0, sample);
}


static int
cs_etm__get_trace(struct cs_etm_queue *etmq)
{
	struct auxtrace_buffer *aux_buffer = etmq->buffer;
	struct auxtrace_buffer *old_buffer = aux_buffer;
	struct auxtrace_queue *queue;

	queue = &etmq->etm->queues.queue_array[etmq->queue_nr];

	aux_buffer = auxtrace_buffer__next(queue, aux_buffer);

	/* If no more data, drop the previous auxtrace_buffer and return */
	if (!aux_buffer) {
		if (old_buffer)
			auxtrace_buffer__drop_data(old_buffer);
		etmq->buf_len = 0;
		return 0;
	}

	etmq->buffer = aux_buffer;

	/* If the aux_buffer doesn't have data associated, try to load it */
	if (!aux_buffer->data) {
		/* get the file desc associated with the perf data file */
		int fd = perf_data__fd(etmq->etm->session->data);

		aux_buffer->data = auxtrace_buffer__get_data(aux_buffer, fd);
		if (!aux_buffer->data)
			return -ENOMEM;
	}

	/* If valid, drop the previous buffer */
	if (old_buffer)
		auxtrace_buffer__drop_data(old_buffer);

	etmq->buf_used = 0;
	etmq->buf_len = aux_buffer->size;
	etmq->buf = aux_buffer->data;

	return etmq->buf_len;
}

static void cs_etm__set_pid_tid_cpu(struct cs_etm_auxtrace *etm,
				    struct cs_etm_traceid_queue *tidq)
{
	if ((!tidq->thread) && (tidq->tid != -1))
		tidq->thread = machine__find_thread(etm->machine, -1,
						    tidq->tid);

	if (tidq->thread)
		tidq->pid = tidq->thread->pid_;
}

int cs_etm__etmq_set_tid(struct cs_etm_queue *etmq,
			 pid_t tid, u8 trace_chan_id)
{
	int cpu, err = -EINVAL;
	struct cs_etm_auxtrace *etm = etmq->etm;
	struct cs_etm_traceid_queue *tidq;

	tidq = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id);
	if (!tidq)
		return err;

	if (cs_etm__get_cpu(trace_chan_id, &cpu) < 0)
		return err;

	err = machine__set_current_tid(etm->machine, cpu, tid, tid);
	if (err)
		return err;

	tidq->tid = tid;
	thread__zput(tidq->thread);

	cs_etm__set_pid_tid_cpu(etm, tidq);
	return 0;
}

bool cs_etm__etmq_is_timeless(struct cs_etm_queue *etmq)
{
	return !!etmq->etm->timeless_decoding;
}

static void cs_etm__copy_insn(struct cs_etm_queue *etmq,
			      u64 trace_chan_id,
			      const struct cs_etm_packet *packet,
			      struct perf_sample *sample)
{
	/*
	 * It's pointless to read instructions for the CS_ETM_DISCONTINUITY
	 * packet, so directly bail out with 'insn_len' = 0.
	 */
	if (packet->sample_type == CS_ETM_DISCONTINUITY) {
		sample->insn_len = 0;
		return;
	}

	/*
	 * T32 instruction size might be 32-bit or 16-bit, decide by calling
	 * cs_etm__t32_instr_size().
	 */
	if (packet->isa == CS_ETM_ISA_T32)
		sample->insn_len = cs_etm__t32_instr_size(etmq, trace_chan_id,
							  sample->ip);
	/* Otherwise, A64 and A32 instruction size are always 32-bit. */
	else
		sample->insn_len = 4;

	cs_etm__mem_access(etmq, trace_chan_id, sample->ip,
			   sample->insn_len, (void *)sample->insn);
}

static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
					    struct cs_etm_traceid_queue *tidq,
					    u64 addr, u64 period)
{
	int ret = 0;
	struct cs_etm_auxtrace *etm = etmq->etm;
	union perf_event *event = tidq->event_buf;
	struct perf_sample sample = {.ip = 0,};

	event->sample.header.type = PERF_RECORD_SAMPLE;
	event->sample.header.misc = cs_etm__cpu_mode(etmq, addr);
	event->sample.header.size = sizeof(struct perf_event_header);

	if (!etm->timeless_decoding)
		sample.time = etm->latest_kernel_timestamp;
	sample.ip = addr;
	sample.pid = tidq->pid;
	sample.tid = tidq->tid;
	sample.id = etmq->etm->instructions_id;
	sample.stream_id = etmq->etm->instructions_id;
	sample.period = period;
	sample.cpu = tidq->packet->cpu;
	sample.flags = tidq->prev_packet->flags;
	sample.cpumode = event->sample.header.misc;

	cs_etm__copy_insn(etmq, tidq->trace_chan_id, tidq->packet, &sample);

	if (etm->synth_opts.last_branch)
		sample.branch_stack = tidq->last_branch;

	if (etm->synth_opts.inject) {
		ret = cs_etm__inject_event(event, &sample,
					   etm->instructions_sample_type);
		if (ret)
			return ret;
	}

	ret = perf_session__deliver_synth_event(etm->session, event, &sample);

	if (ret)
		pr_err(
			"CS ETM Trace: failed to deliver instruction event, error %d\n",
			ret);

	return ret;
}

/*
 * The cs etm packet encodes an instruction range between a branch target
 * and the next taken branch. Generate sample accordingly.
 */
static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
				       struct cs_etm_traceid_queue *tidq)
{
	int ret = 0;
	struct cs_etm_auxtrace *etm = etmq->etm;
	struct perf_sample sample = {.ip = 0,};
	union perf_event *event = tidq->event_buf;
	struct dummy_branch_stack {
		u64			nr;
		u64			hw_idx;
		struct branch_entry	entries;
	} dummy_bs;
	u64 ip;

	ip = cs_etm__last_executed_instr(tidq->prev_packet);

	event->sample.header.type = PERF_RECORD_SAMPLE;
	event->sample.header.misc = cs_etm__cpu_mode(etmq, ip);
	event->sample.header.size = sizeof(struct perf_event_header);

	if (!etm->timeless_decoding)
		sample.time = etm->latest_kernel_timestamp;
	sample.ip = ip;
	sample.pid = tidq->pid;
	sample.tid = tidq->tid;
	sample.addr = cs_etm__first_executed_instr(tidq->packet);
	sample.id = etmq->etm->branches_id;
	sample.stream_id = etmq->etm->branches_id;
	sample.period = 1;
	sample.cpu = tidq->packet->cpu;
	sample.flags = tidq->prev_packet->flags;
	sample.cpumode = event->sample.header.misc;

	cs_etm__copy_insn(etmq, tidq->trace_chan_id, tidq->prev_packet,
			  &sample);

	/*
	 * perf report cannot handle events without a branch stack
	 */
	if (etm->synth_opts.last_branch) {
		dummy_bs = (struct dummy_branch_stack){
			.nr = 1,
			.hw_idx = -1ULL,
			.entries = {
				.from = sample.ip,
				.to = sample.addr,
			},
		};
		sample.branch_stack = (struct branch_stack *)&dummy_bs;
	}

	if (etm->synth_opts.inject) {
		ret = cs_etm__inject_event(event, &sample,
					   etm->branches_sample_type);
		if (ret)
			return ret;
	}

	ret = perf_session__deliver_synth_event(etm->session, event, &sample);

	if (ret)
		pr_err(
		"CS ETM Trace: failed to deliver instruction event, error %d\n",
		ret);

	return ret;
}

struct cs_etm_synth {
	struct perf_tool dummy_tool;
	struct perf_session *session;
};

static int cs_etm__event_synth(struct perf_tool *tool,
			       union perf_event *event,
			       struct perf_sample *sample __maybe_unused,
			       struct machine *machine __maybe_unused)
{
	struct cs_etm_synth *cs_etm_synth =
		      container_of(tool, struct cs_etm_synth, dummy_tool);

	return perf_session__deliver_synth_event(cs_etm_synth->session,
						 event, NULL);
}

static int cs_etm__synth_event(struct perf_session *session,
			       struct perf_event_attr *attr, u64 id)
{
	struct cs_etm_synth cs_etm_synth;

	memset(&cs_etm_synth, 0, sizeof(struct cs_etm_synth));
	cs_etm_synth.session = session;

	return perf_event__synthesize_attr(&cs_etm_synth.dummy_tool, attr, 1,
					   &id, cs_etm__event_synth);
}

static int cs_etm__synth_events(struct cs_etm_auxtrace *etm,
				struct perf_session *session)
{
	struct evlist *evlist = session->evlist;
	struct evsel *evsel;
	struct perf_event_attr attr;
	bool found = false;
	u64 id;
	int err;

	evlist__for_each_entry(evlist, evsel) {
		if (evsel->core.attr.type == etm->pmu_type) {
			found = true;
			break;
		}
	}

	if (!found) {
		pr_debug("No selected events with CoreSight Trace data\n");
		return 0;
	}

	memset(&attr, 0, sizeof(struct perf_event_attr));
	attr.size = sizeof(struct perf_event_attr);
	attr.type = PERF_TYPE_HARDWARE;
	attr.sample_type = evsel->core.attr.sample_type & PERF_SAMPLE_MASK;
	attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID |
			    PERF_SAMPLE_PERIOD;
	if (etm->timeless_decoding)
		attr.sample_type &= ~(u64)PERF_SAMPLE_TIME;
	else
		attr.sample_type |= PERF_SAMPLE_TIME;

	attr.exclude_user = evsel->core.attr.exclude_user;
	attr.exclude_kernel = evsel->core.attr.exclude_kernel;
	attr.exclude_hv = evsel->core.attr.exclude_hv;
	attr.exclude_host = evsel->core.attr.exclude_host;
	attr.exclude_guest = evsel->core.attr.exclude_guest;
	attr.sample_id_all = evsel->core.attr.sample_id_all;
	attr.read_format = evsel->core.attr.read_format;

	/* create new id val to be a fixed offset from evsel id */
	id = evsel->core.id[0] + 1000000000;

	if (!id)
		id = 1;

	if (etm->synth_opts.branches) {
		attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
		attr.sample_period = 1;
		attr.sample_type |= PERF_SAMPLE_ADDR;
		err = cs_etm__synth_event(session, &attr, id);
		if (err)
			return err;
		etm->sample_branches = true;
		etm->branches_sample_type = attr.sample_type;
		etm->branches_id = id;
		id += 1;
		attr.sample_type &= ~(u64)PERF_SAMPLE_ADDR;
	}

	if (etm->synth_opts.last_branch) {
		attr.sample_type |= PERF_SAMPLE_BRANCH_STACK;
		/*
		 * We don't use the hardware index, but the sample generation
		 * code uses the new format branch_stack with this field,
		 * so the event attributes must indicate that it's present.
		 */
		attr.branch_sample_type |= PERF_SAMPLE_BRANCH_HW_INDEX;
	}

	if (etm->synth_opts.instructions) {
		attr.config = PERF_COUNT_HW_INSTRUCTIONS;
		attr.sample_period = etm->synth_opts.period;
		etm->instructions_sample_period = attr.sample_period;
		err = cs_etm__synth_event(session, &attr, id);
		if (err)
			return err;
		etm->sample_instructions = true;
		etm->instructions_sample_type = attr.sample_type;
		etm->instructions_id = id;
		id += 1;
	}

	return 0;
}

static int cs_etm__sample(struct cs_etm_queue *etmq,
			  struct cs_etm_traceid_queue *tidq)
{
	struct cs_etm_auxtrace *etm = etmq->etm;
	int ret;
	u8 trace_chan_id = tidq->trace_chan_id;
	u64 instrs_prev;

	/* Get instructions remainder from previous packet */
	instrs_prev = tidq->period_instructions;

	tidq->period_instructions += tidq->packet->instr_count;

	/*
	 * Record a branch when the last instruction in
	 * PREV_PACKET is a branch.
	 */
	if (etm->synth_opts.last_branch &&
	    tidq->prev_packet->sample_type == CS_ETM_RANGE &&
	    tidq->prev_packet->last_instr_taken_branch)
		cs_etm__update_last_branch_rb(etmq, tidq);

	if (etm->sample_instructions &&
	    tidq->period_instructions >= etm->instructions_sample_period) {
		/*
		 * Emit instruction sample periodically
		 * TODO: allow period to be defined in cycles and clock time
		 */

		/*
		 * Below diagram demonstrates the instruction samples
		 * generation flows:
		 *
		 *    Instrs     Instrs       Instrs       Instrs
		 *   Sample(n)  Sample(n+1)  Sample(n+2)  Sample(n+3)
		 *    |            |            |            |
		 *    V            V            V            V
		 *   --------------------------------------------------
		 *            ^                                  ^
		 *            |                                  |
		 *         Period                             Period
		 *    instructions(Pi)                   instructions(Pi')
		 *
		 *            |                                  |
		 *            \---------------- -----------------/
		 *                             V
		 *                 tidq->packet->instr_count
		 *
		 * Instrs Sample(n...) are the synthesised samples occurring
		 * every etm->instructions_sample_period instructions - as
		 * defined on the perf command line.  Sample(n) is being the
		 * last sample before the current etm packet, n+1 to n+3
		 * samples are generated from the current etm packet.
		 *
		 * tidq->packet->instr_count represents the number of
		 * instructions in the current etm packet.
		 *
		 * Period instructions (Pi) contains the the number of
		 * instructions executed after the sample point(n) from the
		 * previous etm packet.  This will always be less than
		 * etm->instructions_sample_period.
		 *
		 * When generate new samples, it combines with two parts
		 * instructions, one is the tail of the old packet and another
		 * is the head of the new coming packet, to generate
		 * sample(n+1); sample(n+2) and sample(n+3) consume the
		 * instructions with sample period.  After sample(n+3), the rest
		 * instructions will be used by later packet and it is assigned
		 * to tidq->period_instructions for next round calculation.
		 */

		/*
		 * Get the initial offset into the current packet instructions;
		 * entry conditions ensure that instrs_prev is less than
		 * etm->instructions_sample_period.
		 */
		u64 offset = etm->instructions_sample_period - instrs_prev;
		u64 addr;

		/* Prepare last branches for instruction sample */
		if (etm->synth_opts.last_branch)
			cs_etm__copy_last_branch_rb(etmq, tidq);

		while (tidq->period_instructions >=
				etm->instructions_sample_period) {
			/*
			 * Calculate the address of the sampled instruction (-1
			 * as sample is reported as though instruction has just
			 * been executed, but PC has not advanced to next
			 * instruction)
			 */
			addr = cs_etm__instr_addr(etmq, trace_chan_id,
						  tidq->packet, offset - 1);
			ret = cs_etm__synth_instruction_sample(
				etmq, tidq, addr,
				etm->instructions_sample_period);
			if (ret)
				return ret;

			offset += etm->instructions_sample_period;
			tidq->period_instructions -=
				etm->instructions_sample_period;
		}
	}

	if (etm->sample_branches) {
		bool generate_sample = false;

		/* Generate sample for tracing on packet */
		if (tidq->prev_packet->sample_type == CS_ETM_DISCONTINUITY)
			generate_sample = true;

		/* Generate sample for branch taken packet */
		if (tidq->prev_packet->sample_type == CS_ETM_RANGE &&
		    tidq->prev_packet->last_instr_taken_branch)
			generate_sample = true;

		if (generate_sample) {
			ret = cs_etm__synth_branch_sample(etmq, tidq);
			if (ret)
				return ret;
		}
	}

	cs_etm__packet_swap(etm, tidq);

	return 0;
}

static int cs_etm__exception(struct cs_etm_traceid_queue *tidq)
{
	/*
	 * When the exception packet is inserted, whether the last instruction
	 * in previous range packet is taken branch or not, we need to force
	 * to set 'prev_packet->last_instr_taken_branch' to true.  This ensures
	 * to generate branch sample for the instruction range before the
	 * exception is trapped to kernel or before the exception returning.
	 *
	 * The exception packet includes the dummy address values, so don't
	 * swap PACKET with PREV_PACKET.  This keeps PREV_PACKET to be useful
	 * for generating instruction and branch samples.
	 */
	if (tidq->prev_packet->sample_type == CS_ETM_RANGE)
		tidq->prev_packet->last_instr_taken_branch = true;

	return 0;
}

static int cs_etm__flush(struct cs_etm_queue *etmq,
			 struct cs_etm_traceid_queue *tidq)
{
	int err = 0;
	struct cs_etm_auxtrace *etm = etmq->etm;

	/* Handle start tracing packet */
	if (tidq->prev_packet->sample_type == CS_ETM_EMPTY)
		goto swap_packet;

	if (etmq->etm->synth_opts.last_branch &&
	    tidq->prev_packet->sample_type == CS_ETM_RANGE) {
		u64 addr;

		/* Prepare last branches for instruction sample */
		cs_etm__copy_last_branch_rb(etmq, tidq);

		/*
		 * Generate a last branch event for the branches left in the
		 * circular buffer at the end of the trace.
		 *
		 * Use the address of the end of the last reported execution
		 * range
		 */
		addr = cs_etm__last_executed_instr(tidq->prev_packet);

		err = cs_etm__synth_instruction_sample(
			etmq, tidq, addr,
			tidq->period_instructions);
		if (err)
			return err;

		tidq->period_instructions = 0;

	}

	if (etm->sample_branches &&
	    tidq->prev_packet->sample_type == CS_ETM_RANGE) {
		err = cs_etm__synth_branch_sample(etmq, tidq);
		if (err)
			return err;
	}

swap_packet:
	cs_etm__packet_swap(etm, tidq);

	/* Reset last branches after flush the trace */
	if (etm->synth_opts.last_branch)
		cs_etm__reset_last_branch_rb(tidq);

	return err;
}

static int cs_etm__end_block(struct cs_etm_queue *etmq,
			     struct cs_etm_traceid_queue *tidq)
{
	int err;

	/*
	 * It has no new packet coming and 'etmq->packet' contains the stale
	 * packet which was set at the previous time with packets swapping;
	 * so skip to generate branch sample to avoid stale packet.
	 *
	 * For this case only flush branch stack and generate a last branch
	 * event for the branches left in the circular buffer at the end of
	 * the trace.
	 */
	if (etmq->etm->synth_opts.last_branch &&
	    tidq->prev_packet->sample_type == CS_ETM_RANGE) {
		u64 addr;

		/* Prepare last branches for instruction sample */
		cs_etm__copy_last_branch_rb(etmq, tidq);

		/*
		 * Use the address of the end of the last reported execution
		 * range.
		 */
		addr = cs_etm__last_executed_instr(tidq->prev_packet);

		err = cs_etm__synth_instruction_sample(
			etmq, tidq, addr,
			tidq->period_instructions);
		if (err)
			return err;

		tidq->period_instructions = 0;
	}

	return 0;
}
/*
 * cs_etm__get_data_block: Fetch a block from the auxtrace_buffer queue
 *			   if need be.
 * Returns:	< 0	if error
 *		= 0	if no more auxtrace_buffer to read
 *		> 0	if the current buffer isn't empty yet
 */
static int cs_etm__get_data_block(struct cs_etm_queue *etmq)
{
	int ret;

	if (!etmq->buf_len) {
		ret = cs_etm__get_trace(etmq);
		if (ret <= 0)
			return ret;
		/*
		 * We cannot assume consecutive blocks in the data file
		 * are contiguous, reset the decoder to force re-sync.
		 */
		ret = cs_etm_decoder__reset(etmq->decoder);
		if (ret)
			return ret;
	}

	return etmq->buf_len;
}

static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id,
				 struct cs_etm_packet *packet,
				 u64 end_addr)
{
	/* Initialise to keep compiler happy */
	u16 instr16 = 0;
	u32 instr32 = 0;
	u64 addr;

	switch (packet->isa) {
	case CS_ETM_ISA_T32:
		/*
		 * The SVC of T32 is defined in ARM DDI 0487D.a, F5.1.247:
		 *
		 *  b'15         b'8
		 * +-----------------+--------+
		 * | 1 1 0 1 1 1 1 1 |  imm8  |
		 * +-----------------+--------+
		 *
		 * According to the specification, it only defines SVC for T32
		 * with 16 bits instruction and has no definition for 32bits;
		 * so below only read 2 bytes as instruction size for T32.
		 */
		addr = end_addr - 2;
		cs_etm__mem_access(etmq, trace_chan_id, addr,
				   sizeof(instr16), (u8 *)&instr16);
		if ((instr16 & 0xFF00) == 0xDF00)
			return true;

		break;
	case CS_ETM_ISA_A32:
		/*
		 * The SVC of A32 is defined in ARM DDI 0487D.a, F5.1.247:
		 *
		 *  b'31 b'28 b'27 b'24
		 * +---------+---------+-------------------------+
		 * |  !1111  | 1 1 1 1 |        imm24            |
		 * +---------+---------+-------------------------+
		 */
		addr = end_addr - 4;
		cs_etm__mem_access(etmq, trace_chan_id, addr,
				   sizeof(instr32), (u8 *)&instr32);
		if ((instr32 & 0x0F000000) == 0x0F000000 &&
		    (instr32 & 0xF0000000) != 0xF0000000)
			return true;

		break;
	case CS_ETM_ISA_A64:
		/*
		 * The SVC of A64 is defined in ARM DDI 0487D.a, C6.2.294:
		 *
		 *  b'31               b'21           b'4     b'0
		 * +-----------------------+---------+-----------+
		 * | 1 1 0 1 0 1 0 0 0 0 0 |  imm16  | 0 0 0 0 1 |
		 * +-----------------------+---------+-----------+
		 */
		addr = end_addr - 4;
		cs_etm__mem_access(etmq, trace_chan_id, addr,
				   sizeof(instr32), (u8 *)&instr32);
		if ((instr32 & 0xFFE0001F) == 0xd4000001)
			return true;

		break;
	case CS_ETM_ISA_UNKNOWN:
	default:
		break;
	}

	return false;
}

static bool cs_etm__is_syscall(struct cs_etm_queue *etmq,
			       struct cs_etm_traceid_queue *tidq, u64 magic)
{
	u8 trace_chan_id = tidq->trace_chan_id;
	struct cs_etm_packet *packet = tidq->packet;
	struct cs_etm_packet *prev_packet = tidq->prev_packet;

	if (magic == __perf_cs_etmv3_magic)
		if (packet->exception_number == CS_ETMV3_EXC_SVC)
			return true;

	/*
	 * ETMv4 exception type CS_ETMV4_EXC_CALL covers SVC, SMC and
	 * HVC cases; need to check if it's SVC instruction based on
	 * packet address.
	 */
	if (magic == __perf_cs_etmv4_magic) {
		if (packet->exception_number == CS_ETMV4_EXC_CALL &&
		    cs_etm__is_svc_instr(etmq, trace_chan_id, prev_packet,
					 prev_packet->end_addr))
			return true;
	}

	return false;
}

static bool cs_etm__is_async_exception(struct cs_etm_traceid_queue *tidq,
				       u64 magic)
{
	struct cs_etm_packet *packet = tidq->packet;

	if (magic == __perf_cs_etmv3_magic)
		if (packet->exception_number == CS_ETMV3_EXC_DEBUG_HALT ||
		    packet->exception_number == CS_ETMV3_EXC_ASYNC_DATA_ABORT ||
		    packet->exception_number == CS_ETMV3_EXC_PE_RESET ||
		    packet->exception_number == CS_ETMV3_EXC_IRQ ||
		    packet->exception_number == CS_ETMV3_EXC_FIQ)
			return true;

	if (magic == __perf_cs_etmv4_magic)
		if (packet->exception_number == CS_ETMV4_EXC_RESET ||
		    packet->exception_number == CS_ETMV4_EXC_DEBUG_HALT ||
		    packet->exception_number == CS_ETMV4_EXC_SYSTEM_ERROR ||
		    packet->exception_number == CS_ETMV4_EXC_INST_DEBUG ||
		    packet->exception_number == CS_ETMV4_EXC_DATA_DEBUG ||
		    packet->exception_number == CS_ETMV4_EXC_IRQ ||
		    packet->exception_number == CS_ETMV4_EXC_FIQ)
			return true;

	return false;
}

static bool cs_etm__is_sync_exception(struct cs_etm_queue *etmq,
				      struct cs_etm_traceid_queue *tidq,
				      u64 magic)
{
	u8 trace_chan_id = tidq->trace_chan_id;
	struct cs_etm_packet *packet = tidq->packet;
	struct cs_etm_packet *prev_packet = tidq->prev_packet;

	if (magic == __perf_cs_etmv3_magic)
		if (packet->exception_number == CS_ETMV3_EXC_SMC ||
		    packet->exception_number == CS_ETMV3_EXC_HYP ||
		    packet->exception_number == CS_ETMV3_EXC_JAZELLE_THUMBEE ||
		    packet->exception_number == CS_ETMV3_EXC_UNDEFINED_INSTR ||
		    packet->exception_number == CS_ETMV3_EXC_PREFETCH_ABORT ||
		    packet->exception_number == CS_ETMV3_EXC_DATA_FAULT ||
		    packet->exception_number == CS_ETMV3_EXC_GENERIC)
			return true;

	if (magic == __perf_cs_etmv4_magic) {
		if (packet->exception_number == CS_ETMV4_EXC_TRAP ||
		    packet->exception_number == CS_ETMV4_EXC_ALIGNMENT ||
		    packet->exception_number == CS_ETMV4_EXC_INST_FAULT ||
		    packet->exception_number == CS_ETMV4_EXC_DATA_FAULT)
			return true;

		/*
		 * For CS_ETMV4_EXC_CALL, except SVC other instructions
		 * (SMC, HVC) are taken as sync exceptions.
		 */
		if (packet->exception_number == CS_ETMV4_EXC_CALL &&
		    !cs_etm__is_svc_instr(etmq, trace_chan_id, prev_packet,
					  prev_packet->end_addr))
			return true;

		/*
		 * ETMv4 has 5 bits for exception number; if the numbers
		 * are in the range ( CS_ETMV4_EXC_FIQ, CS_ETMV4_EXC_END ]
		 * they are implementation defined exceptions.
		 *
		 * For this case, simply take it as sync exception.
		 */
		if (packet->exception_number > CS_ETMV4_EXC_FIQ &&
		    packet->exception_number <= CS_ETMV4_EXC_END)
			return true;
	}

	return false;
}

static int cs_etm__set_sample_flags(struct cs_etm_queue *etmq,
				    struct cs_etm_traceid_queue *tidq)
{
	struct cs_etm_packet *packet = tidq->packet;
	struct cs_etm_packet *prev_packet = tidq->prev_packet;
	u8 trace_chan_id = tidq->trace_chan_id;
	u64 magic;
	int ret;

	switch (packet->sample_type) {
	case CS_ETM_RANGE:
		/*
		 * Immediate branch instruction without neither link nor
		 * return flag, it's normal branch instruction within
		 * the function.
		 */
		if (packet->last_instr_type == OCSD_INSTR_BR &&
		    packet->last_instr_subtype == OCSD_S_INSTR_NONE) {
			packet->flags = PERF_IP_FLAG_BRANCH;

			if (packet->last_instr_cond)
				packet->flags |= PERF_IP_FLAG_CONDITIONAL;
		}

		/*
		 * Immediate branch instruction with link (e.g. BL), this is
		 * branch instruction for function call.
		 */
		if (packet->last_instr_type == OCSD_INSTR_BR &&
		    packet->last_instr_subtype == OCSD_S_INSTR_BR_LINK)
			packet->flags = PERF_IP_FLAG_BRANCH |
					PERF_IP_FLAG_CALL;

		/*
		 * Indirect branch instruction with link (e.g. BLR), this is
		 * branch instruction for function call.
		 */
		if (packet->last_instr_type == OCSD_INSTR_BR_INDIRECT &&
		    packet->last_instr_subtype == OCSD_S_INSTR_BR_LINK)
			packet->flags = PERF_IP_FLAG_BRANCH |
					PERF_IP_FLAG_CALL;

		/*
		 * Indirect branch instruction with subtype of
		 * OCSD_S_INSTR_V7_IMPLIED_RET, this is explicit hint for
		 * function return for A32/T32.
		 */
		if (packet->last_instr_type == OCSD_INSTR_BR_INDIRECT &&
		    packet->last_instr_subtype == OCSD_S_INSTR_V7_IMPLIED_RET)
			packet->flags = PERF_IP_FLAG_BRANCH |
					PERF_IP_FLAG_RETURN;

		/*
		 * Indirect branch instruction without link (e.g. BR), usually
		 * this is used for function return, especially for functions
		 * within dynamic link lib.
		 */
		if (packet->last_instr_type == OCSD_INSTR_BR_INDIRECT &&
		    packet->last_instr_subtype == OCSD_S_INSTR_NONE)
			packet->flags = PERF_IP_FLAG_BRANCH |
					PERF_IP_FLAG_RETURN;

		/* Return instruction for function return. */
		if (packet->last_instr_type == OCSD_INSTR_BR_INDIRECT &&
		    packet->last_instr_subtype == OCSD_S_INSTR_V8_RET)
			packet->flags = PERF_IP_FLAG_BRANCH |
					PERF_IP_FLAG_RETURN;

		/*
		 * Decoder might insert a discontinuity in the middle of
		 * instruction packets, fixup prev_packet with flag
		 * PERF_IP_FLAG_TRACE_BEGIN to indicate restarting trace.
		 */
		if (prev_packet->sample_type == CS_ETM_DISCONTINUITY)
			prev_packet->flags |= PERF_IP_FLAG_BRANCH |
					      PERF_IP_FLAG_TRACE_BEGIN;

		/*
		 * If the previous packet is an exception return packet
		 * and the return address just follows SVC instruction,
		 * it needs to calibrate the previous packet sample flags
		 * as PERF_IP_FLAG_SYSCALLRET.
		 */
		if (prev_packet->flags == (PERF_IP_FLAG_BRANCH |
					   PERF_IP_FLAG_RETURN |
					   PERF_IP_FLAG_INTERRUPT) &&
		    cs_etm__is_svc_instr(etmq, trace_chan_id,
					 packet, packet->start_addr))
			prev_packet->flags = PERF_IP_FLAG_BRANCH |
					     PERF_IP_FLAG_RETURN |
					     PERF_IP_FLAG_SYSCALLRET;
		break;
	case CS_ETM_DISCONTINUITY:
		/*
		 * The trace is discontinuous, if the previous packet is
		 * instruction packet, set flag PERF_IP_FLAG_TRACE_END
		 * for previous packet.
		 */
		if (prev_packet->sample_type == CS_ETM_RANGE)
			prev_packet->flags |= PERF_IP_FLAG_BRANCH |
					      PERF_IP_FLAG_TRACE_END;
		break;
	case CS_ETM_EXCEPTION:
		ret = cs_etm__get_magic(packet->trace_chan_id, &magic);
		if (ret)
			return ret;

		/* The exception is for system call. */
		if (cs_etm__is_syscall(etmq, tidq, magic))
			packet->flags = PERF_IP_FLAG_BRANCH |
					PERF_IP_FLAG_CALL |
					PERF_IP_FLAG_SYSCALLRET;
		/*
		 * The exceptions are triggered by external signals from bus,
		 * interrupt controller, debug module, PE reset or halt.
		 */
		else if (cs_etm__is_async_exception(tidq, magic))
			packet->flags = PERF_IP_FLAG_BRANCH |
					PERF_IP_FLAG_CALL |
					PERF_IP_FLAG_ASYNC |
					PERF_IP_FLAG_INTERRUPT;
		/*
		 * Otherwise, exception is caused by trap, instruction &
		 * data fault, or alignment errors.
		 */
		else if (cs_etm__is_sync_exception(etmq, tidq, magic))
			packet->flags = PERF_IP_FLAG_BRANCH |
					PERF_IP_FLAG_CALL |
					PERF_IP_FLAG_INTERRUPT;

		/*
		 * When the exception packet is inserted, since exception
		 * packet is not used standalone for generating samples
		 * and it's affiliation to the previous instruction range
		 * packet; so set previous range packet flags to tell perf
		 * it is an exception taken branch.
		 */
		if (prev_packet->sample_type == CS_ETM_RANGE)
			prev_packet->flags = packet->flags;
		break;
	case CS_ETM_EXCEPTION_RET:
		/*
		 * When the exception return packet is inserted, since
		 * exception return packet is not used standalone for
		 * generating samples and it's affiliation to the previous
		 * instruction range packet; so set previous range packet
		 * flags to tell perf it is an exception return branch.
		 *
		 * The exception return can be for either system call or
		 * other exception types; unfortunately the packet doesn't
		 * contain exception type related info so we cannot decide
		 * the exception type purely based on exception return packet.
		 * If we record the exception number from exception packet and
		 * reuse it for exception return packet, this is not reliable
		 * due the trace can be discontinuity or the interrupt can
		 * be nested, thus the recorded exception number cannot be
		 * used for exception return packet for these two cases.
		 *
		 * For exception return packet, we only need to distinguish the
		 * packet is for system call or for other types.  Thus the
		 * decision can be deferred when receive the next packet which
		 * contains the return address, based on the return address we
		 * can read out the previous instruction and check if it's a
		 * system call instruction and then calibrate the sample flag
		 * as needed.
		 */
		if (prev_packet->sample_type == CS_ETM_RANGE)
			prev_packet->flags = PERF_IP_FLAG_BRANCH |
					     PERF_IP_FLAG_RETURN |
					     PERF_IP_FLAG_INTERRUPT;
		break;
	case CS_ETM_EMPTY:
	default:
		break;
	}

	return 0;
}

static int cs_etm__decode_data_block(struct cs_etm_queue *etmq)
{
	int ret = 0;
	size_t processed = 0;

	/*
	 * Packets are decoded and added to the decoder's packet queue
	 * until the decoder packet processing callback has requested that
	 * processing stops or there is nothing left in the buffer.  Normal
	 * operations that stop processing are a timestamp packet or a full
	 * decoder buffer queue.
	 */
	ret = cs_etm_decoder__process_data_block(etmq->decoder,
						 etmq->offset,
						 &etmq->buf[etmq->buf_used],
						 etmq->buf_len,
						 &processed);
	if (ret)
		goto out;

	etmq->offset += processed;
	etmq->buf_used += processed;
	etmq->buf_len -= processed;

out:
	return ret;
}

static int cs_etm__process_traceid_queue(struct cs_etm_queue *etmq,
					 struct cs_etm_traceid_queue *tidq)
{
	int ret;
	struct cs_etm_packet_queue *packet_queue;

	packet_queue = &tidq->packet_queue;

	/* Process each packet in this chunk */
	while (1) {
		ret = cs_etm_decoder__get_packet(packet_queue,
						 tidq->packet);
		if (ret <= 0)
			/*
			 * Stop processing this chunk on
			 * end of data or error
			 */
			break;

		/*
		 * Since packet addresses are swapped in packet
		 * handling within below switch() statements,
		 * thus setting sample flags must be called
		 * prior to switch() statement to use address
		 * information before packets swapping.
		 */
		ret = cs_etm__set_sample_flags(etmq, tidq);
		if (ret < 0)
			break;

		switch (tidq->packet->sample_type) {
		case CS_ETM_RANGE:
			/*
			 * If the packet contains an instruction
			 * range, generate instruction sequence
			 * events.
			 */
			cs_etm__sample(etmq, tidq);
			break;
		case CS_ETM_EXCEPTION:
		case CS_ETM_EXCEPTION_RET:
			/*
			 * If the exception packet is coming,
			 * make sure the previous instruction
			 * range packet to be handled properly.
			 */
			cs_etm__exception(tidq);
			break;
		case CS_ETM_DISCONTINUITY:
			/*
			 * Discontinuity in trace, flush
			 * previous branch stack
			 */
			cs_etm__flush(etmq, tidq);
			break;
		case CS_ETM_EMPTY:
			/*
			 * Should not receive empty packet,
			 * report error.
			 */
			pr_err("CS ETM Trace: empty packet\n");
			return -EINVAL;
		default:
			break;
		}
	}

	return ret;
}

static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq)
{
	int idx;
	struct int_node *inode;
	struct cs_etm_traceid_queue *tidq;
	struct intlist *traceid_queues_list = etmq->traceid_queues_list;

	intlist__for_each_entry(inode, traceid_queues_list) {
		idx = (int)(intptr_t)inode->priv;
		tidq = etmq->traceid_queues[idx];

		/* Ignore return value */
		cs_etm__process_traceid_queue(etmq, tidq);

		/*
		 * Generate an instruction sample with the remaining
		 * branchstack entries.
		 */
		cs_etm__flush(etmq, tidq);
	}
}

static int cs_etm__run_decoder(struct cs_etm_queue *etmq)
{
	int err = 0;
	struct cs_etm_traceid_queue *tidq;

	tidq = cs_etm__etmq_get_traceid_queue(etmq, CS_ETM_PER_THREAD_TRACEID);
	if (!tidq)
		return -EINVAL;

	/* Go through each buffer in the queue and decode them one by one */
	while (1) {
		err = cs_etm__get_data_block(etmq);
		if (err <= 0)
			return err;

		/* Run trace decoder until buffer consumed or end of trace */
		do {
			err = cs_etm__decode_data_block(etmq);
			if (err)
				return err;

			/*
			 * Process each packet in this chunk, nothing to do if
			 * an error occurs other than hoping the next one will
			 * be better.
			 */
			err = cs_etm__process_traceid_queue(etmq, tidq);

		} while (etmq->buf_len);

		if (err == 0)
			/* Flush any remaining branch stack entries */
			err = cs_etm__end_block(etmq, tidq);
	}

	return err;
}

static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
					   pid_t tid)
{
	unsigned int i;
	struct auxtrace_queues *queues = &etm->queues;

	for (i = 0; i < queues->nr_queues; i++) {
		struct auxtrace_queue *queue = &etm->queues.queue_array[i];
		struct cs_etm_queue *etmq = queue->priv;
		struct cs_etm_traceid_queue *tidq;

		if (!etmq)
			continue;

		tidq = cs_etm__etmq_get_traceid_queue(etmq,
						CS_ETM_PER_THREAD_TRACEID);

		if (!tidq)
			continue;

		if ((tid == -1) || (tidq->tid == tid)) {
			cs_etm__set_pid_tid_cpu(etm, tidq);
			cs_etm__run_decoder(etmq);
		}
	}

	return 0;
}

static int cs_etm__process_queues(struct cs_etm_auxtrace *etm)
{
	int ret = 0;
	unsigned int cs_queue_nr, queue_nr;
	u8 trace_chan_id;
	u64 cs_timestamp;
	struct auxtrace_queue *queue;
	struct cs_etm_queue *etmq;
	struct cs_etm_traceid_queue *tidq;

	while (1) {
		if (!etm->heap.heap_cnt)
			goto out;

		/* Take the entry at the top of the min heap */
		cs_queue_nr = etm->heap.heap_array[0].queue_nr;
		queue_nr = TO_QUEUE_NR(cs_queue_nr);
		trace_chan_id = TO_TRACE_CHAN_ID(cs_queue_nr);
		queue = &etm->queues.queue_array[queue_nr];
		etmq = queue->priv;

		/*
		 * Remove the top entry from the heap since we are about
		 * to process it.
		 */
		auxtrace_heap__pop(&etm->heap);

		tidq  = cs_etm__etmq_get_traceid_queue(etmq, trace_chan_id);
		if (!tidq) {
			/*
			 * No traceID queue has been allocated for this traceID,
			 * which means something somewhere went very wrong.  No
			 * other choice than simply exit.
			 */
			ret = -EINVAL;
			goto out;
		}

		/*
		 * Packets associated with this timestamp are already in
		 * the etmq's traceID queue, so process them.
		 */
		ret = cs_etm__process_traceid_queue(etmq, tidq);
		if (ret < 0)
			goto out;

		/*
		 * Packets for this timestamp have been processed, time to
		 * move on to the next timestamp, fetching a new auxtrace_buffer
		 * if need be.
		 */
refetch:
		ret = cs_etm__get_data_block(etmq);
		if (ret < 0)
			goto out;

		/*
		 * No more auxtrace_buffers to process in this etmq, simply
		 * move on to another entry in the auxtrace_heap.
		 */
		if (!ret)
			continue;

		ret = cs_etm__decode_data_block(etmq);
		if (ret)
			goto out;

		cs_timestamp = cs_etm__etmq_get_timestamp(etmq, &trace_chan_id);

		if (!cs_timestamp) {
			/*
			 * Function cs_etm__decode_data_block() returns when
			 * there is no more traces to decode in the current
			 * auxtrace_buffer OR when a timestamp has been
			 * encountered on any of the traceID queues.  Since we
			 * did not get a timestamp, there is no more traces to
			 * process in this auxtrace_buffer.  As such empty and
			 * flush all traceID queues.
			 */
			cs_etm__clear_all_traceid_queues(etmq);

			/* Fetch another auxtrace_buffer for this etmq */
			goto refetch;
		}

		/*
		 * Add to the min heap the timestamp for packets that have
		 * just been decoded.  They will be processed and synthesized
		 * during the next call to cs_etm__process_traceid_queue() for
		 * this queue/traceID.
		 */
		cs_queue_nr = TO_CS_QUEUE_NR(queue_nr, trace_chan_id);
		ret = auxtrace_heap__add(&etm->heap, cs_queue_nr, cs_timestamp);
	}

out:
	return ret;
}

static int cs_etm__process_itrace_start(struct cs_etm_auxtrace *etm,
					union perf_event *event)
{
	struct thread *th;

	if (etm->timeless_decoding)
		return 0;

	/*
	 * Add the tid/pid to the log so that we can get a match when
	 * we get a contextID from the decoder.
	 */
	th = machine__findnew_thread(etm->machine,
				     event->itrace_start.pid,
				     event->itrace_start.tid);
	if (!th)
		return -ENOMEM;

	thread__put(th);

	return 0;
}

static int cs_etm__process_switch_cpu_wide(struct cs_etm_auxtrace *etm,
					   union perf_event *event)
{
	struct thread *th;
	bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;

	/*
	 * Context switch in per-thread mode are irrelevant since perf
	 * will start/stop tracing as the process is scheduled.
	 */
	if (etm->timeless_decoding)
		return 0;

	/*
	 * SWITCH_IN events carry the next process to be switched out while
	 * SWITCH_OUT events carry the process to be switched in.  As such
	 * we don't care about IN events.
	 */
	if (!out)
		return 0;

	/*
	 * Add the tid/pid to the log so that we can get a match when
	 * we get a contextID from the decoder.
	 */
	th = machine__findnew_thread(etm->machine,
				     event->context_switch.next_prev_pid,
				     event->context_switch.next_prev_tid);
	if (!th)
		return -ENOMEM;

	thread__put(th);

	return 0;
}

static int cs_etm__process_event(struct perf_session *session,
				 union perf_event *event,
				 struct perf_sample *sample,
				 struct perf_tool *tool)
{
	int err = 0;
	u64 sample_kernel_timestamp;
	struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
						   struct cs_etm_auxtrace,
						   auxtrace);

	if (dump_trace)
		return 0;

	if (!tool->ordered_events) {
		pr_err("CoreSight ETM Trace requires ordered events\n");
		return -EINVAL;
	}

	if (sample->time && (sample->time != (u64) -1))
		sample_kernel_timestamp = sample->time;
	else
		sample_kernel_timestamp = 0;

	if (sample_kernel_timestamp || etm->timeless_decoding) {
		err = cs_etm__update_queues(etm);
		if (err)
			return err;
	}

	/*
	 * Don't wait for cs_etm__flush_events() in per-thread/timeless mode to start the decode. We
	 * need the tid of the PERF_RECORD_EXIT event to assign to the synthesised samples because
	 * ETM_OPT_CTXTID is not enabled.
	 */
	if (etm->timeless_decoding &&
	    event->header.type == PERF_RECORD_EXIT)
		return cs_etm__process_timeless_queues(etm,
						       event->fork.tid);

	if (event->header.type == PERF_RECORD_ITRACE_START)
		return cs_etm__process_itrace_start(etm, event);
	else if (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE)
		return cs_etm__process_switch_cpu_wide(etm, event);

	if (!etm->timeless_decoding && event->header.type == PERF_RECORD_AUX) {
		/*
		 * Record the latest kernel timestamp available in the header
		 * for samples so that synthesised samples occur from this point
		 * onwards.
		 */
		etm->latest_kernel_timestamp = sample_kernel_timestamp;
	}

	return 0;
}

static void dump_queued_data(struct cs_etm_auxtrace *etm,
			     struct perf_record_auxtrace *event)
{
	struct auxtrace_buffer *buf;
	unsigned int i;
	/*
	 * Find all buffers with same reference in the queues and dump them.
	 * This is because the queues can contain multiple entries of the same
	 * buffer that were split on aux records.
	 */
	for (i = 0; i < etm->queues.nr_queues; ++i)
		list_for_each_entry(buf, &etm->queues.queue_array[i].head, list)
			if (buf->reference == event->reference)
				cs_etm__dump_event(etm, buf);
}

static int cs_etm__process_auxtrace_event(struct perf_session *session,
					  union perf_event *event,
					  struct perf_tool *tool __maybe_unused)
{
	struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
						   struct cs_etm_auxtrace,
						   auxtrace);
	if (!etm->data_queued) {
		struct auxtrace_buffer *buffer;
		off_t  data_offset;
		int fd = perf_data__fd(session->data);
		bool is_pipe = perf_data__is_pipe(session->data);
		int err;

		if (is_pipe)
			data_offset = 0;
		else {
			data_offset = lseek(fd, 0, SEEK_CUR);
			if (data_offset == -1)
				return -errno;
		}

		err = auxtrace_queues__add_event(&etm->queues, session,
						 event, data_offset, &buffer);
		if (err)
			return err;

		if (dump_trace)
			if (auxtrace_buffer__get_data(buffer, fd)) {
				cs_etm__dump_event(etm, buffer);
				auxtrace_buffer__put_data(buffer);
			}
	} else if (dump_trace)
		dump_queued_data(etm, &event->auxtrace);

	return 0;
}

static bool cs_etm__is_timeless_decoding(struct cs_etm_auxtrace *etm)
{
	struct evsel *evsel;
	struct evlist *evlist = etm->session->evlist;
	bool timeless_decoding = true;

	/* Override timeless mode with user input from --itrace=Z */
	if (etm->synth_opts.timeless_decoding)
		return true;

	/*
	 * Circle through the list of event and complain if we find one
	 * with the time bit set.
	 */
	evlist__for_each_entry(evlist, evsel) {
		if ((evsel->core.attr.sample_type & PERF_SAMPLE_TIME))
			timeless_decoding = false;
	}

	return timeless_decoding;
}

static const char * const cs_etm_global_header_fmts[] = {
	[CS_HEADER_VERSION]	= "	Header version		       %llx\n",
	[CS_PMU_TYPE_CPUS]	= "	PMU type/num cpus	       %llx\n",
	[CS_ETM_SNAPSHOT]	= "	Snapshot		       %llx\n",
};

static const char * const cs_etm_priv_fmts[] = {
	[CS_ETM_MAGIC]		= "	Magic number		       %llx\n",
	[CS_ETM_CPU]		= "	CPU			       %lld\n",
	[CS_ETM_NR_TRC_PARAMS]	= "	NR_TRC_PARAMS		       %llx\n",
	[CS_ETM_ETMCR]		= "	ETMCR			       %llx\n",
	[CS_ETM_ETMTRACEIDR]	= "	ETMTRACEIDR		       %llx\n",
	[CS_ETM_ETMCCER]	= "	ETMCCER			       %llx\n",
	[CS_ETM_ETMIDR]		= "	ETMIDR			       %llx\n",
};

static const char * const cs_etmv4_priv_fmts[] = {
	[CS_ETM_MAGIC]		= "	Magic number		       %llx\n",
	[CS_ETM_CPU]		= "	CPU			       %lld\n",
	[CS_ETM_NR_TRC_PARAMS]	= "	NR_TRC_PARAMS		       %llx\n",
	[CS_ETMV4_TRCCONFIGR]	= "	TRCCONFIGR		       %llx\n",
	[CS_ETMV4_TRCTRACEIDR]	= "	TRCTRACEIDR		       %llx\n",
	[CS_ETMV4_TRCIDR0]	= "	TRCIDR0			       %llx\n",
	[CS_ETMV4_TRCIDR1]	= "	TRCIDR1			       %llx\n",
	[CS_ETMV4_TRCIDR2]	= "	TRCIDR2			       %llx\n",
	[CS_ETMV4_TRCIDR8]	= "	TRCIDR8			       %llx\n",
	[CS_ETMV4_TRCAUTHSTATUS] = "	TRCAUTHSTATUS		       %llx\n",
};

static const char * const param_unk_fmt =
	"	Unknown parameter [%d]	       %llx\n";
static const char * const magic_unk_fmt =
	"	Magic number Unknown	       %llx\n";

static int cs_etm__print_cpu_metadata_v0(__u64 *val, int *offset)
{
	int i = *offset, j, nr_params = 0, fmt_offset;
	__u64 magic;

	/* check magic value */
	magic = val[i + CS_ETM_MAGIC];
	if ((magic != __perf_cs_etmv3_magic) &&
	    (magic != __perf_cs_etmv4_magic)) {
		/* failure - note bad magic value */
		fprintf(stdout, magic_unk_fmt, magic);
		return -EINVAL;
	}

	/* print common header block */
	fprintf(stdout, cs_etm_priv_fmts[CS_ETM_MAGIC], val[i++]);
	fprintf(stdout, cs_etm_priv_fmts[CS_ETM_CPU], val[i++]);

	if (magic == __perf_cs_etmv3_magic) {
		nr_params = CS_ETM_NR_TRC_PARAMS_V0;
		fmt_offset = CS_ETM_ETMCR;
		/* after common block, offset format index past NR_PARAMS */
		for (j = fmt_offset; j < nr_params + fmt_offset; j++, i++)
			fprintf(stdout, cs_etm_priv_fmts[j], val[i]);
	} else if (magic == __perf_cs_etmv4_magic) {
		nr_params = CS_ETMV4_NR_TRC_PARAMS_V0;
		fmt_offset = CS_ETMV4_TRCCONFIGR;
		/* after common block, offset format index past NR_PARAMS */
		for (j = fmt_offset; j < nr_params + fmt_offset; j++, i++)
			fprintf(stdout, cs_etmv4_priv_fmts[j], val[i]);
	}
	*offset = i;
	return 0;
}

static int cs_etm__print_cpu_metadata_v1(__u64 *val, int *offset)
{
	int i = *offset, j, total_params = 0;
	__u64 magic;

	magic = val[i + CS_ETM_MAGIC];
	/* total params to print is NR_PARAMS + common block size for v1 */
	total_params = val[i + CS_ETM_NR_TRC_PARAMS] + CS_ETM_COMMON_BLK_MAX_V1;

	if (magic == __perf_cs_etmv3_magic) {
		for (j = 0; j < total_params; j++, i++) {
			/* if newer record - could be excess params */
			if (j >= CS_ETM_PRIV_MAX)
				fprintf(stdout, param_unk_fmt, j, val[i]);
			else
				fprintf(stdout, cs_etm_priv_fmts[j], val[i]);
		}
	} else if (magic == __perf_cs_etmv4_magic) {
		for (j = 0; j < total_params; j++, i++) {
			/* if newer record - could be excess params */
			if (j >= CS_ETMV4_PRIV_MAX)
				fprintf(stdout, param_unk_fmt, j, val[i]);
			else
				fprintf(stdout, cs_etmv4_priv_fmts[j], val[i]);
		}
	} else {
		/* failure - note bad magic value and error out */
		fprintf(stdout, magic_unk_fmt, magic);
		return -EINVAL;
	}
	*offset = i;
	return 0;
}

static void cs_etm__print_auxtrace_info(__u64 *val, int num)
{
	int i, cpu = 0, version, err;

	/* bail out early on bad header version */
	version = val[0];
	if (version > CS_HEADER_CURRENT_VERSION) {
		/* failure.. return */
		fprintf(stdout, "	Unknown Header Version = %x, ", version);
		fprintf(stdout, "Version supported <= %x\n", CS_HEADER_CURRENT_VERSION);
		return;
	}

	for (i = 0; i < CS_HEADER_VERSION_MAX; i++)
		fprintf(stdout, cs_etm_global_header_fmts[i], val[i]);

	for (i = CS_HEADER_VERSION_MAX; cpu < num; cpu++) {
		if (version == 0)
			err = cs_etm__print_cpu_metadata_v0(val, &i);
		else if (version == 1)
			err = cs_etm__print_cpu_metadata_v1(val, &i);
		if (err)
			return;
	}
}

/*
 * Read a single cpu parameter block from the auxtrace_info priv block.
 *
 * For version 1 there is a per cpu nr_params entry. If we are handling
 * version 1 file, then there may be less, the same, or more params
 * indicated by this value than the compile time number we understand.
 *
 * For a version 0 info block, there are a fixed number, and we need to
 * fill out the nr_param value in the metadata we create.
 */
static u64 *cs_etm__create_meta_blk(u64 *buff_in, int *buff_in_offset,
				    int out_blk_size, int nr_params_v0)
{
	u64 *metadata = NULL;
	int hdr_version;
	int nr_in_params, nr_out_params, nr_cmn_params;
	int i, k;

	metadata = zalloc(sizeof(*metadata) * out_blk_size);
	if (!metadata)
		return NULL;

	/* read block current index & version */
	i = *buff_in_offset;
	hdr_version = buff_in[CS_HEADER_VERSION];

	if (!hdr_version) {
	/* read version 0 info block into a version 1 metadata block  */
		nr_in_params = nr_params_v0;
		metadata[CS_ETM_MAGIC] = buff_in[i + CS_ETM_MAGIC];
		metadata[CS_ETM_CPU] = buff_in[i + CS_ETM_CPU];
		metadata[CS_ETM_NR_TRC_PARAMS] = nr_in_params;
		/* remaining block params at offset +1 from source */
		for (k = CS_ETM_COMMON_BLK_MAX_V1 - 1; k < nr_in_params; k++)
			metadata[k + 1] = buff_in[i + k];
		/* version 0 has 2 common params */
		nr_cmn_params = 2;
	} else {
	/* read version 1 info block - input and output nr_params may differ */
		/* version 1 has 3 common params */
		nr_cmn_params = 3;
		nr_in_params = buff_in[i + CS_ETM_NR_TRC_PARAMS];

		/* if input has more params than output - skip excess */
		nr_out_params = nr_in_params + nr_cmn_params;
		if (nr_out_params > out_blk_size)
			nr_out_params = out_blk_size;

		for (k = CS_ETM_MAGIC; k < nr_out_params; k++)
			metadata[k] = buff_in[i + k];

		/* record the actual nr params we copied */
		metadata[CS_ETM_NR_TRC_PARAMS] = nr_out_params - nr_cmn_params;
	}

	/* adjust in offset by number of in params used */
	i += nr_in_params + nr_cmn_params;
	*buff_in_offset = i;
	return metadata;
}

/**
 * Puts a fragment of an auxtrace buffer into the auxtrace queues based
 * on the bounds of aux_event, if it matches with the buffer that's at
 * file_offset.
 *
 * Normally, whole auxtrace buffers would be added to the queue. But we
 * want to reset the decoder for every PERF_RECORD_AUX event, and the decoder
 * is reset across each buffer, so splitting the buffers up in advance has
 * the same effect.
 */
static int cs_etm__queue_aux_fragment(struct perf_session *session, off_t file_offset, size_t sz,
				      struct perf_record_aux *aux_event, struct perf_sample *sample)
{
	int err;
	char buf[PERF_SAMPLE_MAX_SIZE];
	union perf_event *auxtrace_event_union;
	struct perf_record_auxtrace *auxtrace_event;
	union perf_event auxtrace_fragment;
	__u64 aux_offset, aux_size;

	struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
						   struct cs_etm_auxtrace,
						   auxtrace);

	/*
	 * There should be a PERF_RECORD_AUXTRACE event at the file_offset that we got
	 * from looping through the auxtrace index.
	 */
	err = perf_session__peek_event(session, file_offset, buf,
				       PERF_SAMPLE_MAX_SIZE, &auxtrace_event_union, NULL);
	if (err)
		return err;
	auxtrace_event = &auxtrace_event_union->auxtrace;
	if (auxtrace_event->header.type != PERF_RECORD_AUXTRACE)
		return -EINVAL;

	if (auxtrace_event->header.size < sizeof(struct perf_record_auxtrace) ||
		auxtrace_event->header.size != sz) {
		return -EINVAL;
	}

	/*
	 * In per-thread mode, CPU is set to -1, but TID will be set instead. See
	 * auxtrace_mmap_params__set_idx(). Return 'not found' if neither CPU nor TID match.
	 */
	if ((auxtrace_event->cpu == (__u32) -1 && auxtrace_event->tid != sample->tid) ||
			auxtrace_event->cpu != sample->cpu)
		return 1;

	if (aux_event->flags & PERF_AUX_FLAG_OVERWRITE) {
		/*
		 * Clamp size in snapshot mode. The buffer size is clamped in
		 * __auxtrace_mmap__read() for snapshots, so the aux record size doesn't reflect
		 * the buffer size.
		 */
		aux_size = min(aux_event->aux_size, auxtrace_event->size);

		/*
		 * In this mode, the head also points to the end of the buffer so aux_offset
		 * needs to have the size subtracted so it points to the beginning as in normal mode
		 */
		aux_offset = aux_event->aux_offset - aux_size;
	} else {
		aux_size = aux_event->aux_size;
		aux_offset = aux_event->aux_offset;
	}

	if (aux_offset >= auxtrace_event->offset &&
	    aux_offset + aux_size <= auxtrace_event->offset + auxtrace_event->size) {
		/*
		 * If this AUX event was inside this buffer somewhere, create a new auxtrace event
		 * based on the sizes of the aux event, and queue that fragment.
		 */
		auxtrace_fragment.auxtrace = *auxtrace_event;
		auxtrace_fragment.auxtrace.size = aux_size;
		auxtrace_fragment.auxtrace.offset = aux_offset;
		file_offset += aux_offset - auxtrace_event->offset + auxtrace_event->header.size;

		pr_debug3("CS ETM: Queue buffer size: %#"PRI_lx64" offset: %#"PRI_lx64
			  " tid: %d cpu: %d\n", aux_size, aux_offset, sample->tid, sample->cpu);
		return auxtrace_queues__add_event(&etm->queues, session, &auxtrace_fragment,
						  file_offset, NULL);
	}

	/* Wasn't inside this buffer, but there were no parse errors. 1 == 'not found' */
	return 1;
}

static int cs_etm__queue_aux_records_cb(struct perf_session *session, union perf_event *event,
					u64 offset __maybe_unused, void *data __maybe_unused)
{
	struct perf_sample sample;
	int ret;
	struct auxtrace_index_entry *ent;
	struct auxtrace_index *auxtrace_index;
	struct evsel *evsel;
	size_t i;

	/* Don't care about any other events, we're only queuing buffers for AUX events */
	if (event->header.type != PERF_RECORD_AUX)
		return 0;

	if (event->header.size < sizeof(struct perf_record_aux))
		return -EINVAL;

	/* Truncated Aux records can have 0 size and shouldn't result in anything being queued. */
	if (!event->aux.aux_size)
		return 0;

	/*
	 * Parse the sample, we need the sample_id_all data that comes after the event so that the
	 * CPU or PID can be matched to an AUXTRACE buffer's CPU or PID.
	 */
	evsel = evlist__event2evsel(session->evlist, event);
	if (!evsel)
		return -EINVAL;
	ret = evsel__parse_sample(evsel, event, &sample);
	if (ret)
		return ret;

	/*
	 * Loop through the auxtrace index to find the buffer that matches up with this aux event.
	 */
	list_for_each_entry(auxtrace_index, &session->auxtrace_index, list) {
		for (i = 0; i < auxtrace_index->nr; i++) {
			ent = &auxtrace_index->entries[i];
			ret = cs_etm__queue_aux_fragment(session, ent->file_offset,
							 ent->sz, &event->aux, &sample);
			/*
			 * Stop search on error or successful values. Continue search on
			 * 1 ('not found')
			 */
			if (ret != 1)
				return ret;
		}
	}

	/*
	 * Couldn't find the buffer corresponding to this aux record, something went wrong. Warn but
	 * don't exit with an error because it will still be possible to decode other aux records.
	 */
	pr_err("CS ETM: Couldn't find auxtrace buffer for aux_offset: %#"PRI_lx64
	       " tid: %d cpu: %d\n", event->aux.aux_offset, sample.tid, sample.cpu);
	return 0;
}

static int cs_etm__queue_aux_records(struct perf_session *session)
{
	struct auxtrace_index *index = list_first_entry_or_null(&session->auxtrace_index,
								struct auxtrace_index, list);
	if (index && index->nr > 0)
		return perf_session__peek_events(session, session->header.data_offset,
						 session->header.data_size,
						 cs_etm__queue_aux_records_cb, NULL);

	/*
	 * We would get here if there are no entries in the index (either no auxtrace
	 * buffers or no index at all). Fail silently as there is the possibility of
	 * queueing them in cs_etm__process_auxtrace_event() if etm->data_queued is still
	 * false.
	 *
	 * In that scenario, buffers will not be split by AUX records.
	 */
	return 0;
}

int cs_etm__process_auxtrace_info(union perf_event *event,
				  struct perf_session *session)
{
	struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
	struct cs_etm_auxtrace *etm = NULL;
	struct int_node *inode;
	unsigned int pmu_type;
	int event_header_size = sizeof(struct perf_event_header);
	int info_header_size;
	int total_size = auxtrace_info->header.size;
	int priv_size = 0;
	int num_cpu, trcidr_idx;
	int err = 0;
	int i, j;
	u64 *ptr, *hdr = NULL;
	u64 **metadata = NULL;
	u64 hdr_version;

	/*
	 * sizeof(auxtrace_info_event::type) +
	 * sizeof(auxtrace_info_event::reserved) == 8
	 */
	info_header_size = 8;

	if (total_size < (event_header_size + info_header_size))
		return -EINVAL;

	priv_size = total_size - event_header_size - info_header_size;

	/* First the global part */
	ptr = (u64 *) auxtrace_info->priv;

	/* Look for version of the header */
	hdr_version = ptr[0];
	if (hdr_version > CS_HEADER_CURRENT_VERSION) {
		/* print routine will print an error on bad version */
		if (dump_trace)
			cs_etm__print_auxtrace_info(auxtrace_info->priv, 0);
		return -EINVAL;
	}

	hdr = zalloc(sizeof(*hdr) * CS_HEADER_VERSION_MAX);
	if (!hdr)
		return -ENOMEM;

	/* Extract header information - see cs-etm.h for format */
	for (i = 0; i < CS_HEADER_VERSION_MAX; i++)
		hdr[i] = ptr[i];
	num_cpu = hdr[CS_PMU_TYPE_CPUS] & 0xffffffff;
	pmu_type = (unsigned int) ((hdr[CS_PMU_TYPE_CPUS] >> 32) &
				    0xffffffff);

	/*
	 * Create an RB tree for traceID-metadata tuple.  Since the conversion
	 * has to be made for each packet that gets decoded, optimizing access
	 * in anything other than a sequential array is worth doing.
	 */
	traceid_list = intlist__new(NULL);
	if (!traceid_list) {
		err = -ENOMEM;
		goto err_free_hdr;
	}

	metadata = zalloc(sizeof(*metadata) * num_cpu);
	if (!metadata) {
		err = -ENOMEM;
		goto err_free_traceid_list;
	}

	/*
	 * The metadata is stored in the auxtrace_info section and encodes
	 * the configuration of the ARM embedded trace macrocell which is
	 * required by the trace decoder to properly decode the trace due
	 * to its highly compressed nature.
	 */
	for (j = 0; j < num_cpu; j++) {
		if (ptr[i] == __perf_cs_etmv3_magic) {
			metadata[j] =
				cs_etm__create_meta_blk(ptr, &i,
							CS_ETM_PRIV_MAX,
							CS_ETM_NR_TRC_PARAMS_V0);

			/* The traceID is our handle */
			trcidr_idx = CS_ETM_ETMTRACEIDR;

		} else if (ptr[i] == __perf_cs_etmv4_magic) {
			metadata[j] =
				cs_etm__create_meta_blk(ptr, &i,
							CS_ETMV4_PRIV_MAX,
							CS_ETMV4_NR_TRC_PARAMS_V0);

			/* The traceID is our handle */
			trcidr_idx = CS_ETMV4_TRCTRACEIDR;
		}

		if (!metadata[j]) {
			err = -ENOMEM;
			goto err_free_metadata;
		}

		/* Get an RB node for this CPU */
		inode = intlist__findnew(traceid_list, metadata[j][trcidr_idx]);

		/* Something went wrong, no need to continue */
		if (!inode) {
			err = -ENOMEM;
			goto err_free_metadata;
		}

		/*
		 * The node for that CPU should not be taken.
		 * Back out if that's the case.
		 */
		if (inode->priv) {
			err = -EINVAL;
			goto err_free_metadata;
		}
		/* All good, associate the traceID with the metadata pointer */
		inode->priv = metadata[j];
	}

	/*
	 * Each of CS_HEADER_VERSION_MAX, CS_ETM_PRIV_MAX and
	 * CS_ETMV4_PRIV_MAX mark how many double words are in the
	 * global metadata, and each cpu's metadata respectively.
	 * The following tests if the correct number of double words was
	 * present in the auxtrace info section.
	 */
	if (i * 8 != priv_size) {
		err = -EINVAL;
		goto err_free_metadata;
	}

	etm = zalloc(sizeof(*etm));

	if (!etm) {
		err = -ENOMEM;
		goto err_free_metadata;
	}

	err = auxtrace_queues__init(&etm->queues);
	if (err)
		goto err_free_etm;

	if (session->itrace_synth_opts->set) {
		etm->synth_opts = *session->itrace_synth_opts;
	} else {
		itrace_synth_opts__set_default(&etm->synth_opts,
				session->itrace_synth_opts->default_no_sample);
		etm->synth_opts.callchain = false;
	}

	etm->session = session;
	etm->machine = &session->machines.host;

	etm->num_cpu = num_cpu;
	etm->pmu_type = pmu_type;
	etm->snapshot_mode = (hdr[CS_ETM_SNAPSHOT] != 0);
	etm->metadata = metadata;
	etm->auxtrace_type = auxtrace_info->type;
	etm->timeless_decoding = cs_etm__is_timeless_decoding(etm);

	etm->auxtrace.process_event = cs_etm__process_event;
	etm->auxtrace.process_auxtrace_event = cs_etm__process_auxtrace_event;
	etm->auxtrace.flush_events = cs_etm__flush_events;
	etm->auxtrace.free_events = cs_etm__free_events;
	etm->auxtrace.free = cs_etm__free;
	etm->auxtrace.evsel_is_auxtrace = cs_etm__evsel_is_auxtrace;
	session->auxtrace = &etm->auxtrace;

	etm->unknown_thread = thread__new(999999999, 999999999);
	if (!etm->unknown_thread) {
		err = -ENOMEM;
		goto err_free_queues;
	}

	/*
	 * Initialize list node so that at thread__zput() we can avoid
	 * segmentation fault at list_del_init().
	 */
	INIT_LIST_HEAD(&etm->unknown_thread->node);

	err = thread__set_comm(etm->unknown_thread, "unknown", 0);
	if (err)
		goto err_delete_thread;

	if (thread__init_maps(etm->unknown_thread, etm->machine)) {
		err = -ENOMEM;
		goto err_delete_thread;
	}

	if (dump_trace) {
		cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu);
	}

	err = cs_etm__synth_events(etm, session);
	if (err)
		goto err_delete_thread;

	err = cs_etm__queue_aux_records(session);
	if (err)
		goto err_delete_thread;

	etm->data_queued = etm->queues.populated;

	return 0;

err_delete_thread:
	thread__zput(etm->unknown_thread);
err_free_queues:
	auxtrace_queues__free(&etm->queues);
	session->auxtrace = NULL;
err_free_etm:
	zfree(&etm);
err_free_metadata:
	/* No need to check @metadata[j], free(NULL) is supported */
	for (j = 0; j < num_cpu; j++)
		zfree(&metadata[j]);
	zfree(&metadata);
err_free_traceid_list:
	intlist__delete(traceid_list);
err_free_hdr:
	zfree(&hdr);
	/*
	 * At this point, as a minimum we have valid header. Dump the rest of
	 * the info section - the print routines will error out on structural
	 * issues.
	 */
	if (dump_trace)
		cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu);
	return err;
}
