// SPDX-License-Identifier: GPL-2.0
/*
 * Arm Statistical Profiling Extensions (SPE) support
 * Copyright (c) 2017-2018, Arm Ltd.
 */

#include <byteswap.h>
#include <endian.h>
#include <errno.h>
#include <inttypes.h>
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/types.h>
#include <linux/zalloc.h>
#include <stdlib.h>
#include <unistd.h>

#include "auxtrace.h"
#include "color.h"
#include "debug.h"
#include "evlist.h"
#include "evsel.h"
#include "machine.h"
#include "session.h"
#include "symbol.h"
#include "thread.h"
#include "thread-stack.h"
#include "tsc.h"
#include "tool.h"
#include "util/synthetic-events.h"

#include "arm-spe.h"
#include "arm-spe-decoder/arm-spe-decoder.h"
#include "arm-spe-decoder/arm-spe-pkt-decoder.h"

#include "../../arch/arm64/include/asm/cputype.h"
#define MAX_TIMESTAMP (~0ULL)

#define is_ldst_op(op)		(!!((op) & ARM_SPE_OP_LDST))

#define is_simd_op(op)		(!!((op) & (ARM_SPE_OP_SIMD_FP | ARM_SPE_OP_SVE | \
					    ARM_SPE_OP_SME | ARM_SPE_OP_ASE)))

#define is_mem_op(op)		(is_ldst_op(op) || is_simd_op(op))

#define ARM_SPE_CACHE_EVENT(lvl) \
	(ARM_SPE_##lvl##_ACCESS | ARM_SPE_##lvl##_MISS)

#define arm_spe_is_cache_level(type, lvl) \
	((type) & ARM_SPE_CACHE_EVENT(lvl))

#define arm_spe_is_cache_hit(type, lvl) \
	(((type) & ARM_SPE_CACHE_EVENT(lvl)) == ARM_SPE_##lvl##_ACCESS)

#define arm_spe_is_cache_miss(type, lvl) \
	((type) & ARM_SPE_##lvl##_MISS)

struct arm_spe {
	struct auxtrace			auxtrace;
	struct auxtrace_queues		queues;
	struct auxtrace_heap		heap;
	struct itrace_synth_opts        synth_opts;
	u32				auxtrace_type;
	struct perf_session		*session;
	struct machine			*machine;
	u32				pmu_type;

	struct perf_tsc_conversion	tc;

	u8				timeless_decoding;
	u8				data_queued;

	u64				sample_type;
	u8				sample_flc;
	u8				sample_llc;
	u8				sample_tlb;
	u8				sample_branch;
	u8				sample_remote_access;
	u8				sample_memory;
	u8				sample_instructions;

	u64				l1d_miss_id;
	u64				l1d_access_id;
	u64				llc_miss_id;
	u64				llc_access_id;
	u64				tlb_miss_id;
	u64				tlb_access_id;
	u64				branch_id;
	u64				remote_access_id;
	u64				memory_id;
	u64				instructions_id;

	u64				kernel_start;

	unsigned long			num_events;
	u8				use_ctx_pkt_for_pid;

	u64				**metadata;
	u64				metadata_ver;
	u64				metadata_nr_cpu;
	bool				is_homogeneous;
};

struct arm_spe_queue {
	struct arm_spe			*spe;
	unsigned int			queue_nr;
	struct auxtrace_buffer		*buffer;
	struct auxtrace_buffer		*old_buffer;
	union perf_event		*event_buf;
	bool				on_heap;
	bool				done;
	pid_t				pid;
	pid_t				tid;
	int				cpu;
	struct arm_spe_decoder		*decoder;
	u64				time;
	u64				timestamp;
	struct thread			*thread;
	u64				sample_count;
	u32				flags;
	struct branch_stack		*last_branch;
};

struct data_source_handle {
	const struct midr_range *midr_ranges;
	void (*ds_synth)(const struct arm_spe_record *record,
			 union perf_mem_data_src *data_src);
};

#define DS(range, func)					\
	{						\
		.midr_ranges = range,			\
		.ds_synth = arm_spe__synth_##func,	\
	}

static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
			 unsigned char *buf, size_t len)
{
	struct arm_spe_pkt packet;
	size_t pos = 0;
	int ret, pkt_len, i;
	char desc[ARM_SPE_PKT_DESC_MAX];
	const char *color = PERF_COLOR_BLUE;

	color_fprintf(stdout, color,
		      ". ... ARM SPE data: size %#zx bytes\n",
		      len);

	while (len) {
		ret = arm_spe_get_packet(buf, len, &packet);
		if (ret > 0)
			pkt_len = ret;
		else
			pkt_len = 1;
		printf(".");
		color_fprintf(stdout, color, "  %08zx: ", pos);
		for (i = 0; i < pkt_len; i++)
			color_fprintf(stdout, color, " %02x", buf[i]);
		for (; i < 16; i++)
			color_fprintf(stdout, color, "   ");
		if (ret > 0) {
			ret = arm_spe_pkt_desc(&packet, desc,
					       ARM_SPE_PKT_DESC_MAX);
			if (!ret)
				color_fprintf(stdout, color, " %s\n", desc);
		} else {
			color_fprintf(stdout, color, " Bad packet!\n");
		}
		pos += pkt_len;
		buf += pkt_len;
		len -= pkt_len;
	}
}

static void arm_spe_dump_event(struct arm_spe *spe, unsigned char *buf,
			       size_t len)
{
	printf(".\n");
	arm_spe_dump(spe, buf, len);
}

static int arm_spe_get_trace(struct arm_spe_buffer *b, void *data)
{
	struct arm_spe_queue *speq = data;
	struct auxtrace_buffer *buffer = speq->buffer;
	struct auxtrace_buffer *old_buffer = speq->old_buffer;
	struct auxtrace_queue *queue;

	queue = &speq->spe->queues.queue_array[speq->queue_nr];

	buffer = auxtrace_buffer__next(queue, buffer);
	/* If no more data, drop the previous auxtrace_buffer and return */
	if (!buffer) {
		if (old_buffer)
			auxtrace_buffer__drop_data(old_buffer);
		b->len = 0;
		return 0;
	}

	speq->buffer = buffer;

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

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

	b->len = buffer->size;
	b->buf = buffer->data;

	if (b->len) {
		if (old_buffer)
			auxtrace_buffer__drop_data(old_buffer);
		speq->old_buffer = buffer;
	} else {
		auxtrace_buffer__drop_data(buffer);
		return arm_spe_get_trace(b, data);
	}

	return 0;
}

static struct arm_spe_queue *arm_spe__alloc_queue(struct arm_spe *spe,
		unsigned int queue_nr)
{
	struct arm_spe_params params = { .get_trace = 0, };
	struct arm_spe_queue *speq;

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

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

	speq->spe = spe;
	speq->queue_nr = queue_nr;
	speq->pid = -1;
	speq->tid = -1;
	speq->cpu = -1;

	/* params set */
	params.get_trace = arm_spe_get_trace;
	params.data = speq;

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

		/* Allocate up to two entries for PBT + TGT */
		sz += sizeof(struct branch_entry) *
			min(spe->synth_opts.last_branch_sz, 2U);
		speq->last_branch = zalloc(sz);
		if (!speq->last_branch)
			goto out_free;
	}

	/* create new decoder */
	speq->decoder = arm_spe_decoder_new(&params);
	if (!speq->decoder)
		goto out_free;

	return speq;

out_free:
	zfree(&speq->event_buf);
	zfree(&speq->last_branch);
	free(speq);

	return NULL;
}

static inline u8 arm_spe_cpumode(struct arm_spe *spe, u64 ip)
{
	return ip >= spe->kernel_start ?
		PERF_RECORD_MISC_KERNEL :
		PERF_RECORD_MISC_USER;
}

static void arm_spe_set_pid_tid_cpu(struct arm_spe *spe,
				    struct auxtrace_queue *queue)
{
	struct arm_spe_queue *speq = queue->priv;
	pid_t tid;

	tid = machine__get_current_tid(spe->machine, speq->cpu);
	if (tid != -1) {
		speq->tid = tid;
		thread__zput(speq->thread);
	} else
		speq->tid = queue->tid;

	if ((!speq->thread) && (speq->tid != -1)) {
		speq->thread = machine__find_thread(spe->machine, -1,
						    speq->tid);
	}

	if (speq->thread) {
		speq->pid = thread__pid(speq->thread);
		if (queue->cpu == -1)
			speq->cpu = thread__cpu(speq->thread);
	}
}

static int arm_spe_set_tid(struct arm_spe_queue *speq, pid_t tid)
{
	struct arm_spe *spe = speq->spe;
	int err = machine__set_current_tid(spe->machine, speq->cpu, -1, tid);

	if (err)
		return err;

	arm_spe_set_pid_tid_cpu(spe, &spe->queues.queue_array[speq->queue_nr]);

	return 0;
}

static u64 *arm_spe__get_metadata_by_cpu(struct arm_spe *spe, int cpu)
{
	u64 i;

	if (!spe->metadata)
		return NULL;

	/* CPU ID is -1 for per-thread mode */
	if (cpu < 0) {
		/*
		 * On the heterogeneous system, due to CPU ID is -1,
		 * cannot confirm the data source packet is supported.
		 */
		if (!spe->is_homogeneous)
			return NULL;

		/* In homogeneous system, simply use CPU0's metadata */
		return spe->metadata[0];
	}

	for (i = 0; i < spe->metadata_nr_cpu; i++)
		if (spe->metadata[i][ARM_SPE_CPU] == (u64)cpu)
			return spe->metadata[i];

	return NULL;
}

static struct simd_flags arm_spe__synth_simd_flags(const struct arm_spe_record *record)
{
	struct simd_flags simd_flags = {};

	if (record->op & ARM_SPE_OP_SVE)
		simd_flags.arch |= SIMD_OP_FLAGS_ARCH_SVE;
	else if (record->op & ARM_SPE_OP_SME)
		simd_flags.arch |= SIMD_OP_FLAGS_ARCH_SME;
	else if (record->op & (ARM_SPE_OP_ASE | ARM_SPE_OP_SIMD_FP))
		simd_flags.arch |= SIMD_OP_FLAGS_ARCH_ASE;

	if (record->op & ARM_SPE_OP_SVE) {
		if (!(record->op & ARM_SPE_OP_PRED))
			simd_flags.pred = SIMD_OP_FLAGS_PRED_DISABLED;
		else if (record->type & ARM_SPE_SVE_PARTIAL_PRED)
			simd_flags.pred = SIMD_OP_FLAGS_PRED_PARTIAL;
		else if (record->type & ARM_SPE_SVE_EMPTY_PRED)
			simd_flags.pred = SIMD_OP_FLAGS_PRED_EMPTY;
		else
			simd_flags.pred = SIMD_OP_FLAGS_PRED_FULL;
	} else {
		if (record->type & ARM_SPE_SVE_PARTIAL_PRED)
			simd_flags.pred = SIMD_OP_FLAGS_PRED_PARTIAL;
		else if (record->type & ARM_SPE_SVE_EMPTY_PRED)
			simd_flags.pred = SIMD_OP_FLAGS_PRED_EMPTY;
	}

	return simd_flags;
}

static void arm_spe_prep_sample(struct arm_spe *spe,
				struct arm_spe_queue *speq,
				union perf_event *event,
				struct perf_sample *sample)
{
	struct arm_spe_record *record = &speq->decoder->record;

	if (!spe->timeless_decoding)
		sample->time = tsc_to_perf_time(record->timestamp, &spe->tc);

	sample->ip = record->from_ip;
	sample->cpumode = arm_spe_cpumode(spe, sample->ip);
	sample->pid = speq->pid;
	sample->tid = speq->tid;
	sample->period = spe->synth_opts.period;
	sample->cpu = speq->cpu;
	sample->simd_flags = arm_spe__synth_simd_flags(record);

	event->sample.header.type = PERF_RECORD_SAMPLE;
	event->sample.header.misc = sample->cpumode;
	event->sample.header.size = sizeof(struct perf_event_header);
}

static void arm_spe__prep_branch_stack(struct arm_spe_queue *speq)
{
	struct arm_spe *spe = speq->spe;
	struct arm_spe_record *record = &speq->decoder->record;
	struct branch_stack *bstack = speq->last_branch;
	struct branch_flags *bs_flags;
	unsigned int last_branch_sz = spe->synth_opts.last_branch_sz;
	bool have_tgt = !!(speq->flags & PERF_IP_FLAG_BRANCH);
	bool have_pbt = last_branch_sz >= (have_tgt + 1U) && record->prev_br_tgt;
	size_t sz = sizeof(struct branch_stack) +
		    sizeof(struct branch_entry) * min(last_branch_sz, 2U) /* PBT + TGT */;
	int i = 0;

	/* Clean up branch stack */
	memset(bstack, 0x0, sz);

	if (!have_tgt && !have_pbt)
		return;

	if (have_tgt) {
		bstack->entries[i].from = record->from_ip;
		bstack->entries[i].to = record->to_ip;

		bs_flags = &bstack->entries[i].flags;
		bs_flags->value = 0;

		if (record->op & ARM_SPE_OP_BR_CR_BL) {
			if (record->op & ARM_SPE_OP_BR_COND)
				bs_flags->type |= PERF_BR_COND_CALL;
			else
				bs_flags->type |= PERF_BR_CALL;
		/*
		 * Indirect branch instruction without link (e.g. BR),
		 * take this case as function return.
		 */
		} else if (record->op & ARM_SPE_OP_BR_CR_RET ||
			   record->op & ARM_SPE_OP_BR_INDIRECT) {
			if (record->op & ARM_SPE_OP_BR_COND)
				bs_flags->type |= PERF_BR_COND_RET;
			else
				bs_flags->type |= PERF_BR_RET;
		} else if (record->op & ARM_SPE_OP_BR_CR_NON_BL_RET) {
			if (record->op & ARM_SPE_OP_BR_COND)
				bs_flags->type |= PERF_BR_COND;
			else
				bs_flags->type |= PERF_BR_UNCOND;
		} else {
			if (record->op & ARM_SPE_OP_BR_COND)
				bs_flags->type |= PERF_BR_COND;
			else
				bs_flags->type |= PERF_BR_UNKNOWN;
		}

		if (record->type & ARM_SPE_BRANCH_MISS) {
			bs_flags->mispred = 1;
			bs_flags->predicted = 0;
		} else {
			bs_flags->mispred = 0;
			bs_flags->predicted = 1;
		}

		if (record->type & ARM_SPE_BRANCH_NOT_TAKEN)
			bs_flags->not_taken = 1;

		if (record->type & ARM_SPE_IN_TXN)
			bs_flags->in_tx = 1;

		bs_flags->cycles = min(record->latency, 0xFFFFU);
		i++;
	}

	if (have_pbt) {
		bs_flags = &bstack->entries[i].flags;
		bs_flags->type |= PERF_BR_UNKNOWN;
		bstack->entries[i].to = record->prev_br_tgt;
		i++;
	}

	bstack->nr = i;
	bstack->hw_idx = -1ULL;
}

static int arm_spe__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 inline int
arm_spe_deliver_synth_event(struct arm_spe *spe,
			    struct arm_spe_queue *speq __maybe_unused,
			    union perf_event *event,
			    struct perf_sample *sample)
{
	int ret;

	if (spe->synth_opts.inject) {
		ret = arm_spe__inject_event(event, sample, spe->sample_type);
		if (ret)
			return ret;
	}

	ret = perf_session__deliver_synth_event(spe->session, event, sample);
	if (ret)
		pr_err("ARM SPE: failed to deliver event, error %d\n", ret);

	return ret;
}

static int arm_spe__synth_mem_sample(struct arm_spe_queue *speq,
				     u64 spe_events_id,
				     union perf_mem_data_src data_src)
{
	struct arm_spe *spe = speq->spe;
	struct arm_spe_record *record = &speq->decoder->record;
	union perf_event *event = speq->event_buf;
	struct perf_sample sample;
	int ret;

	perf_sample__init(&sample, /*all=*/true);
	arm_spe_prep_sample(spe, speq, event, &sample);

	sample.id = spe_events_id;
	sample.stream_id = spe_events_id;
	sample.addr = record->virt_addr;
	sample.phys_addr = record->phys_addr;
	sample.data_src = data_src.val;
	sample.weight = record->latency;

	ret = arm_spe_deliver_synth_event(spe, speq, event, &sample);
	perf_sample__exit(&sample);
	return ret;
}

static int arm_spe__synth_branch_sample(struct arm_spe_queue *speq,
					u64 spe_events_id)
{
	struct arm_spe *spe = speq->spe;
	struct arm_spe_record *record = &speq->decoder->record;
	union perf_event *event = speq->event_buf;
	struct perf_sample sample;
	int ret;

	perf_sample__init(&sample, /*all=*/true);
	arm_spe_prep_sample(spe, speq, event, &sample);

	sample.id = spe_events_id;
	sample.stream_id = spe_events_id;
	sample.addr = record->to_ip;
	sample.weight = record->latency;
	sample.flags = speq->flags;
	sample.branch_stack = speq->last_branch;

	ret = arm_spe_deliver_synth_event(spe, speq, event, &sample);
	perf_sample__exit(&sample);
	return ret;
}

static int arm_spe__synth_instruction_sample(struct arm_spe_queue *speq,
					     u64 spe_events_id,
					     union perf_mem_data_src data_src)
{
	struct arm_spe *spe = speq->spe;
	struct arm_spe_record *record = &speq->decoder->record;
	union perf_event *event = speq->event_buf;
	struct perf_sample sample;
	int ret;

	perf_sample__init(&sample, /*all=*/true);
	arm_spe_prep_sample(spe, speq, event, &sample);

	sample.id = spe_events_id;
	sample.stream_id = spe_events_id;
	sample.addr = record->to_ip;
	sample.phys_addr = record->phys_addr;
	sample.data_src = data_src.val;
	sample.weight = record->latency;
	sample.flags = speq->flags;
	sample.branch_stack = speq->last_branch;

	ret = arm_spe_deliver_synth_event(spe, speq, event, &sample);
	perf_sample__exit(&sample);
	return ret;
}

static const struct midr_range common_ds_encoding_cpus[] = {
	MIDR_ALL_VERSIONS(MIDR_CORTEX_A715),
	MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
	MIDR_ALL_VERSIONS(MIDR_CORTEX_A720AE),
	MIDR_ALL_VERSIONS(MIDR_CORTEX_A725),
	MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
	MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
	MIDR_ALL_VERSIONS(MIDR_CORTEX_X1C),
	MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
	MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
	MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
	MIDR_ALL_VERSIONS(MIDR_NVIDIA_OLYMPUS),
	{},
};

static const struct midr_range ampereone_ds_encoding_cpus[] = {
	MIDR_ALL_VERSIONS(MIDR_AMPERE1A),
	{},
};

static const struct midr_range hisi_hip_ds_encoding_cpus[] = {
	MIDR_ALL_VERSIONS(MIDR_HISI_HIP12),
	{},
};

static void arm_spe__sample_flags(struct arm_spe_queue *speq)
{
	const struct arm_spe_record *record = &speq->decoder->record;

	speq->flags = 0;
	if (record->op & ARM_SPE_OP_BRANCH_ERET) {
		speq->flags = PERF_IP_FLAG_BRANCH;

		if (record->type & ARM_SPE_BRANCH_MISS)
			speq->flags |= PERF_IP_FLAG_BRANCH_MISS;

		if (record->type & ARM_SPE_BRANCH_NOT_TAKEN)
			speq->flags |= PERF_IP_FLAG_NOT_TAKEN;

		if (record->type & ARM_SPE_IN_TXN)
			speq->flags |= PERF_IP_FLAG_IN_TX;

		if (record->op & ARM_SPE_OP_BR_COND)
			speq->flags |= PERF_IP_FLAG_CONDITIONAL;

		if (record->op & ARM_SPE_OP_BR_CR_BL)
			speq->flags |= PERF_IP_FLAG_CALL;
		else if (record->op & ARM_SPE_OP_BR_CR_RET)
			speq->flags |= PERF_IP_FLAG_RETURN;
		/*
		 * Indirect branch instruction without link (e.g. BR),
		 * take it as a function return.
		 */
		else if (record->op & ARM_SPE_OP_BR_INDIRECT)
			speq->flags |= PERF_IP_FLAG_RETURN;
	}
}

static void arm_spe__synth_data_source_common(const struct arm_spe_record *record,
					      union perf_mem_data_src *data_src)
{
	/*
	 * Even though four levels of cache hierarchy are possible, no known
	 * production Neoverse systems currently include more than three levels
	 * so for the time being we assume three exist. If a production system
	 * is built with four the this function would have to be changed to
	 * detect the number of levels for reporting.
	 */

	/*
	 * We have no data on the hit level or data source for stores in the
	 * Neoverse SPE records.
	 */
	if (record->op & ARM_SPE_OP_ST) {
		data_src->mem_lvl = PERF_MEM_LVL_NA;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_NA;
		data_src->mem_snoop = PERF_MEM_SNOOP_NA;
		return;
	}

	switch (record->source) {
	case ARM_SPE_COMMON_DS_L1D:
		data_src->mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L1;
		data_src->mem_snoop = PERF_MEM_SNOOP_NONE;
		break;
	case ARM_SPE_COMMON_DS_L2:
		data_src->mem_lvl = PERF_MEM_LVL_L2 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L2;
		data_src->mem_snoop = PERF_MEM_SNOOP_NONE;
		break;
	case ARM_SPE_COMMON_DS_PEER_CORE:
		data_src->mem_lvl = PERF_MEM_LVL_L2 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L2;
		data_src->mem_snoopx = PERF_MEM_SNOOPX_PEER;
		break;
	/*
	 * We don't know if this is L1, L2 but we do know it was a cache-2-cache
	 * transfer, so set SNOOPX_PEER
	 */
	case ARM_SPE_COMMON_DS_LOCAL_CLUSTER:
	case ARM_SPE_COMMON_DS_PEER_CLUSTER:
		data_src->mem_lvl = PERF_MEM_LVL_L3 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L3;
		data_src->mem_snoopx = PERF_MEM_SNOOPX_PEER;
		break;
	/*
	 * System cache is assumed to be L3
	 */
	case ARM_SPE_COMMON_DS_SYS_CACHE:
		data_src->mem_lvl = PERF_MEM_LVL_L3 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L3;
		data_src->mem_snoop = PERF_MEM_SNOOP_HIT;
		break;
	/*
	 * We don't know what level it hit in, except it came from the other
	 * socket
	 */
	case ARM_SPE_COMMON_DS_REMOTE:
		data_src->mem_lvl = PERF_MEM_LVL_NA;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_NA;
		data_src->mem_remote = PERF_MEM_REMOTE_REMOTE;
		data_src->mem_snoopx = PERF_MEM_SNOOPX_PEER;
		break;
	case ARM_SPE_COMMON_DS_DRAM:
		data_src->mem_lvl = PERF_MEM_LVL_LOC_RAM | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_RAM;
		data_src->mem_snoop = PERF_MEM_SNOOP_NONE;
		break;
	default:
		break;
	}
}

/*
 * Source is IMPDEF. Here we convert the source code used on AmpereOne cores
 * to the common (Neoverse, Cortex) to avoid duplicating the decoding code.
 */
static void arm_spe__synth_data_source_ampereone(const struct arm_spe_record *record,
						 union perf_mem_data_src *data_src)
{
	struct arm_spe_record common_record;

	switch (record->source) {
	case ARM_SPE_AMPEREONE_LOCAL_CHIP_CACHE_OR_DEVICE:
		common_record.source = ARM_SPE_COMMON_DS_PEER_CORE;
		break;
	case ARM_SPE_AMPEREONE_SLC:
		common_record.source = ARM_SPE_COMMON_DS_SYS_CACHE;
		break;
	case ARM_SPE_AMPEREONE_REMOTE_CHIP_CACHE:
		common_record.source = ARM_SPE_COMMON_DS_REMOTE;
		break;
	case ARM_SPE_AMPEREONE_DDR:
		common_record.source = ARM_SPE_COMMON_DS_DRAM;
		break;
	case ARM_SPE_AMPEREONE_L1D:
		common_record.source = ARM_SPE_COMMON_DS_L1D;
		break;
	case ARM_SPE_AMPEREONE_L2D:
		common_record.source = ARM_SPE_COMMON_DS_L2;
		break;
	default:
		pr_warning_once("AmpereOne: Unknown data source (0x%x)\n",
				record->source);
		return;
	}

	common_record.op = record->op;
	arm_spe__synth_data_source_common(&common_record, data_src);
}

static void arm_spe__synth_data_source_hisi_hip(const struct arm_spe_record *record,
						union perf_mem_data_src *data_src)
{
	/* Use common synthesis method to handle store operations */
	if (record->op & ARM_SPE_OP_ST) {
		arm_spe__synth_data_source_common(record, data_src);
		return;
	}

	switch (record->source) {
	case ARM_SPE_HISI_HIP_PEER_CPU:
		data_src->mem_lvl = PERF_MEM_LVL_L2 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L2;
		data_src->mem_snoopx = PERF_MEM_SNOOPX_PEER;
		break;
	case ARM_SPE_HISI_HIP_PEER_CPU_HITM:
		data_src->mem_lvl = PERF_MEM_LVL_L2 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L2;
		data_src->mem_snoop = PERF_MEM_SNOOP_HITM;
		data_src->mem_snoopx = PERF_MEM_SNOOPX_PEER;
		break;
	case ARM_SPE_HISI_HIP_L3:
		data_src->mem_lvl = PERF_MEM_LVL_L3 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L3;
		data_src->mem_snoop = PERF_MEM_SNOOP_HIT;
		break;
	case ARM_SPE_HISI_HIP_L3_HITM:
		data_src->mem_lvl = PERF_MEM_LVL_L3 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L3;
		data_src->mem_snoop = PERF_MEM_SNOOP_HITM;
		break;
	case ARM_SPE_HISI_HIP_PEER_CLUSTER:
		data_src->mem_lvl = PERF_MEM_LVL_REM_CCE1 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L3;
		data_src->mem_snoopx = PERF_MEM_SNOOPX_PEER;
		break;
	case ARM_SPE_HISI_HIP_PEER_CLUSTER_HITM:
		data_src->mem_lvl = PERF_MEM_LVL_REM_CCE1 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L3;
		data_src->mem_snoop = PERF_MEM_SNOOP_HITM;
		data_src->mem_snoopx = PERF_MEM_SNOOPX_PEER;
		break;
	case ARM_SPE_HISI_HIP_REMOTE_SOCKET:
		data_src->mem_lvl = PERF_MEM_LVL_REM_CCE2;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_ANY_CACHE;
		data_src->mem_remote = PERF_MEM_REMOTE_REMOTE;
		data_src->mem_snoopx = PERF_MEM_SNOOPX_PEER;
		break;
	case ARM_SPE_HISI_HIP_REMOTE_SOCKET_HITM:
		data_src->mem_lvl = PERF_MEM_LVL_REM_CCE2;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_ANY_CACHE;
		data_src->mem_snoop = PERF_MEM_SNOOP_HITM;
		data_src->mem_remote = PERF_MEM_REMOTE_REMOTE;
		data_src->mem_snoopx = PERF_MEM_SNOOPX_PEER;
		break;
	case ARM_SPE_HISI_HIP_LOCAL_MEM:
		data_src->mem_lvl = PERF_MEM_LVL_LOC_RAM | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_RAM;
		data_src->mem_snoop = PERF_MEM_SNOOP_NONE;
		break;
	case ARM_SPE_HISI_HIP_REMOTE_MEM:
		data_src->mem_lvl = PERF_MEM_LVL_REM_RAM1 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_RAM;
		data_src->mem_remote = PERF_MEM_REMOTE_REMOTE;
		break;
	case ARM_SPE_HISI_HIP_NC_DEV:
		data_src->mem_lvl = PERF_MEM_LVL_IO | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_IO;
		data_src->mem_snoop = PERF_MEM_SNOOP_NONE;
		break;
	case ARM_SPE_HISI_HIP_L2:
		data_src->mem_lvl = PERF_MEM_LVL_L2 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L2;
		data_src->mem_snoop = PERF_MEM_SNOOP_NONE;
		break;
	case ARM_SPE_HISI_HIP_L2_HITM:
		data_src->mem_lvl = PERF_MEM_LVL_L2 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L2;
		data_src->mem_snoop = PERF_MEM_SNOOP_HITM;
		break;
	case ARM_SPE_HISI_HIP_L1:
		data_src->mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L1;
		data_src->mem_snoop = PERF_MEM_SNOOP_NONE;
		break;
	default:
		break;
	}
}

static const struct data_source_handle data_source_handles[] = {
	DS(common_ds_encoding_cpus, data_source_common),
	DS(ampereone_ds_encoding_cpus, data_source_ampereone),
	DS(hisi_hip_ds_encoding_cpus, data_source_hisi_hip),
};

static void arm_spe__synth_ld_memory_level(const struct arm_spe_record *record,
					   union perf_mem_data_src *data_src)
{
	/*
	 * To find a cache hit, search in ascending order from the lower level
	 * caches to the higher level caches. This reflects the best scenario
	 * for a cache hit.
	 */
	if (arm_spe_is_cache_hit(record->type, L1D)) {
		data_src->mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L1;
	} else if (record->type & ARM_SPE_RECENTLY_FETCHED) {
		data_src->mem_lvl = PERF_MEM_LVL_LFB | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_LFB;
	} else if (arm_spe_is_cache_hit(record->type, L2D)) {
		data_src->mem_lvl = PERF_MEM_LVL_L2 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L2;
	} else if (arm_spe_is_cache_hit(record->type, LLC)) {
		data_src->mem_lvl = PERF_MEM_LVL_L3 | PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L3;
	/*
	 * To find a cache miss, search in descending order from the higher
	 * level cache to the lower level cache. This represents the worst
	 * scenario for a cache miss.
	 */
	} else if (arm_spe_is_cache_miss(record->type, LLC)) {
		data_src->mem_lvl = PERF_MEM_LVL_L3 | PERF_MEM_LVL_MISS;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L3;
	} else if (arm_spe_is_cache_miss(record->type, L2D)) {
		data_src->mem_lvl = PERF_MEM_LVL_L2 | PERF_MEM_LVL_MISS;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L2;
	} else if (arm_spe_is_cache_miss(record->type, L1D)) {
		data_src->mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_MISS;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L1;
	}
}

static void arm_spe__synth_st_memory_level(const struct arm_spe_record *record,
					   union perf_mem_data_src *data_src)
{
	/* Record the greatest level info for a store operation. */
	if (arm_spe_is_cache_level(record->type, LLC)) {
		data_src->mem_lvl = PERF_MEM_LVL_L3;
		data_src->mem_lvl |= arm_spe_is_cache_miss(record->type, LLC) ?
				     PERF_MEM_LVL_MISS : PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L3;
	} else if (arm_spe_is_cache_level(record->type, L2D)) {
		data_src->mem_lvl = PERF_MEM_LVL_L2;
		data_src->mem_lvl |= arm_spe_is_cache_miss(record->type, L2D) ?
				     PERF_MEM_LVL_MISS : PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L2;
	} else if (arm_spe_is_cache_level(record->type, L1D)) {
		data_src->mem_lvl = PERF_MEM_LVL_L1;
		data_src->mem_lvl |= arm_spe_is_cache_miss(record->type, L1D) ?
				     PERF_MEM_LVL_MISS : PERF_MEM_LVL_HIT;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_L1;
	}
}

static void arm_spe__synth_memory_level(struct arm_spe_queue *speq,
					const struct arm_spe_record *record,
					union perf_mem_data_src *data_src)
{
	struct arm_spe *spe = speq->spe;

	/*
	 * The data source packet contains more info for cache levels for
	 * peer snooping. So respect the memory level if has been set by
	 * data source parsing.
	 */
	if (!data_src->mem_lvl) {
		if (data_src->mem_op == PERF_MEM_OP_LOAD)
			arm_spe__synth_ld_memory_level(record, data_src);
		if (data_src->mem_op == PERF_MEM_OP_STORE)
			arm_spe__synth_st_memory_level(record, data_src);
	}

	if (!data_src->mem_lvl) {
		data_src->mem_lvl = PERF_MEM_LVL_NA;
		data_src->mem_lvl_num = PERF_MEM_LVLNUM_NA;
	}

	/*
	 * If 'mem_snoop' has been set by data source packet, skip to set
	 * it at here.
	 */
	if (!data_src->mem_snoop) {
		if (record->type & ARM_SPE_DATA_SNOOPED) {
			if (record->type & ARM_SPE_HITM)
				data_src->mem_snoop = PERF_MEM_SNOOP_HITM;
			else
				data_src->mem_snoop = PERF_MEM_SNOOP_HIT;
		} else {
			u64 *metadata =
				arm_spe__get_metadata_by_cpu(spe, speq->cpu);

			/*
			 * Set NA ("Not available") mode if no meta data or the
			 * SNOOPED event is not supported.
			 */
			if (!metadata ||
			    !(metadata[ARM_SPE_CAP_EVENT_FILTER] & ARM_SPE_DATA_SNOOPED))
				data_src->mem_snoop = PERF_MEM_SNOOP_NA;
			else
				data_src->mem_snoop = PERF_MEM_SNOOP_NONE;
		}
	}

	if (!data_src->mem_remote) {
		if (record->type & ARM_SPE_REMOTE_ACCESS)
			data_src->mem_remote = PERF_MEM_REMOTE_REMOTE;
	}
}

static void arm_spe__synth_ds(struct arm_spe_queue *speq,
			      const struct arm_spe_record *record,
			      union perf_mem_data_src *data_src)
{
	struct arm_spe *spe = speq->spe;
	u64 *metadata = NULL;
	u64 midr;
	unsigned int i;

	/* Metadata version 1 assumes all CPUs are the same (old behavior) */
	if (spe->metadata_ver == 1) {
		const char *cpuid;

		pr_warning_once("Old SPE metadata, re-record to improve decode accuracy\n");
		cpuid = perf_env__cpuid(perf_session__env(spe->session));
		midr = strtol(cpuid, NULL, 16);
	} else {
		metadata = arm_spe__get_metadata_by_cpu(spe, speq->cpu);
		if (!metadata)
			return;

		midr = metadata[ARM_SPE_CPU_MIDR];
	}

	for (i = 0; i < ARRAY_SIZE(data_source_handles); i++) {
		if (is_midr_in_range_list(midr, data_source_handles[i].midr_ranges)) {
			return data_source_handles[i].ds_synth(record, data_src);
		}
	}

	return;
}

static union perf_mem_data_src
arm_spe__synth_data_source(struct arm_spe_queue *speq,
			   const struct arm_spe_record *record)
{
	union perf_mem_data_src	data_src = {};

	if (!is_mem_op(record->op))
		return data_src;

	if (record->op & ARM_SPE_OP_LD)
		data_src.mem_op = PERF_MEM_OP_LOAD;
	else if (record->op & ARM_SPE_OP_ST)
		data_src.mem_op = PERF_MEM_OP_STORE;
	else
		data_src.mem_op = PERF_MEM_OP_NA;

	arm_spe__synth_ds(speq, record, &data_src);
	arm_spe__synth_memory_level(speq, record, &data_src);

	if (record->type & (ARM_SPE_TLB_ACCESS | ARM_SPE_TLB_MISS)) {
		data_src.mem_dtlb = PERF_MEM_TLB_WK;

		if (record->type & ARM_SPE_TLB_MISS)
			data_src.mem_dtlb |= PERF_MEM_TLB_MISS;
		else
			data_src.mem_dtlb |= PERF_MEM_TLB_HIT;
	}

	return data_src;
}

static int arm_spe_sample(struct arm_spe_queue *speq)
{
	const struct arm_spe_record *record = &speq->decoder->record;
	struct arm_spe *spe = speq->spe;
	union perf_mem_data_src data_src;
	int err;

	/*
	 * Discard all samples until period is reached
	 */
	speq->sample_count++;
	if (speq->sample_count < spe->synth_opts.period)
		return 0;
	speq->sample_count = 0;

	arm_spe__sample_flags(speq);
	data_src = arm_spe__synth_data_source(speq, record);

	if (spe->sample_flc) {
		if (record->type & ARM_SPE_L1D_MISS) {
			err = arm_spe__synth_mem_sample(speq, spe->l1d_miss_id,
							data_src);
			if (err)
				return err;
		}

		if (record->type & ARM_SPE_L1D_ACCESS) {
			err = arm_spe__synth_mem_sample(speq, spe->l1d_access_id,
							data_src);
			if (err)
				return err;
		}
	}

	if (spe->sample_llc) {
		if (record->type & ARM_SPE_LLC_MISS) {
			err = arm_spe__synth_mem_sample(speq, spe->llc_miss_id,
							data_src);
			if (err)
				return err;
		}

		if (record->type & ARM_SPE_LLC_ACCESS) {
			err = arm_spe__synth_mem_sample(speq, spe->llc_access_id,
							data_src);
			if (err)
				return err;
		}
	}

	if (spe->sample_tlb) {
		if (record->type & ARM_SPE_TLB_MISS) {
			err = arm_spe__synth_mem_sample(speq, spe->tlb_miss_id,
							data_src);
			if (err)
				return err;
		}

		if (record->type & ARM_SPE_TLB_ACCESS) {
			err = arm_spe__synth_mem_sample(speq, spe->tlb_access_id,
							data_src);
			if (err)
				return err;
		}
	}

	if (spe->synth_opts.last_branch &&
	    (spe->sample_branch || spe->sample_instructions))
		arm_spe__prep_branch_stack(speq);

	if (spe->sample_branch && (record->op & ARM_SPE_OP_BRANCH_ERET)) {
		err = arm_spe__synth_branch_sample(speq, spe->branch_id);
		if (err)
			return err;
	}

	if (spe->sample_remote_access &&
	    (record->type & ARM_SPE_REMOTE_ACCESS)) {
		err = arm_spe__synth_mem_sample(speq, spe->remote_access_id,
						data_src);
		if (err)
			return err;
	}

	if (spe->sample_memory && is_mem_op(record->op)) {
		err = arm_spe__synth_mem_sample(speq, spe->memory_id, data_src);
		if (err)
			return err;
	}

	if (spe->sample_instructions) {
		err = arm_spe__synth_instruction_sample(speq, spe->instructions_id, data_src);
		if (err)
			return err;
	}

	return 0;
}

static int arm_spe_run_decoder(struct arm_spe_queue *speq, u64 *timestamp)
{
	struct arm_spe *spe = speq->spe;
	struct arm_spe_record *record;
	int ret;

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

	while (1) {
		/*
		 * The usual logic is firstly to decode the packets, and then
		 * based the record to synthesize sample; but here the flow is
		 * reversed: it calls arm_spe_sample() for synthesizing samples
		 * prior to arm_spe_decode().
		 *
		 * Two reasons for this code logic:
		 * 1. Firstly, when setup queue in arm_spe__setup_queue(), it
		 * has decoded trace data and generated a record, but the record
		 * is left to generate sample until run to here, so it's correct
		 * to synthesize sample for the left record.
		 * 2. After decoding trace data, it needs to compare the record
		 * timestamp with the coming perf event, if the record timestamp
		 * is later than the perf event, it needs bail out and pushs the
		 * record into auxtrace heap, thus the record can be deferred to
		 * synthesize sample until run to here at the next time; so this
		 * can correlate samples between Arm SPE trace data and other
		 * perf events with correct time ordering.
		 */

		/*
		 * Update pid/tid info.
		 */
		record = &speq->decoder->record;
		if (!spe->timeless_decoding && record->context_id != (u64)-1) {
			ret = arm_spe_set_tid(speq, record->context_id);
			if (ret)
				return ret;

			spe->use_ctx_pkt_for_pid = true;
		}

		ret = arm_spe_sample(speq);
		if (ret)
			return ret;

		ret = arm_spe_decode(speq->decoder);
		if (!ret) {
			pr_debug("No data or all data has been processed.\n");
			return 1;
		}

		/*
		 * Error is detected when decode SPE trace data, continue to
		 * the next trace data and find out more records.
		 */
		if (ret < 0)
			continue;

		record = &speq->decoder->record;

		/* Update timestamp for the last record */
		if (record->timestamp > speq->timestamp)
			speq->timestamp = record->timestamp;

		/*
		 * If the timestamp of the queue is later than timestamp of the
		 * coming perf event, bail out so can allow the perf event to
		 * be processed ahead.
		 */
		if (!spe->timeless_decoding && speq->timestamp >= *timestamp) {
			*timestamp = speq->timestamp;
			return 0;
		}
	}

	return 0;
}

static int arm_spe__setup_queue(struct arm_spe *spe,
			       struct auxtrace_queue *queue,
			       unsigned int queue_nr)
{
	struct arm_spe_queue *speq = queue->priv;
	struct arm_spe_record *record;

	if (list_empty(&queue->head) || speq)
		return 0;

	speq = arm_spe__alloc_queue(spe, queue_nr);

	if (!speq)
		return -ENOMEM;

	queue->priv = speq;

	if (queue->cpu != -1)
		speq->cpu = queue->cpu;

	if (!speq->on_heap) {
		int ret;

		if (spe->timeless_decoding)
			return 0;

retry:
		ret = arm_spe_decode(speq->decoder);

		if (!ret)
			return 0;

		if (ret < 0)
			goto retry;

		record = &speq->decoder->record;

		speq->timestamp = record->timestamp;
		ret = auxtrace_heap__add(&spe->heap, queue_nr, speq->timestamp);
		if (ret)
			return ret;
		speq->on_heap = true;
	}

	return 0;
}

static int arm_spe__setup_queues(struct arm_spe *spe)
{
	unsigned int i;
	int ret;

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

	return 0;
}

static int arm_spe__update_queues(struct arm_spe *spe)
{
	if (spe->queues.new_data) {
		spe->queues.new_data = false;
		return arm_spe__setup_queues(spe);
	}

	return 0;
}

static bool arm_spe__is_timeless_decoding(struct arm_spe *spe)
{
	struct evsel *evsel;
	struct evlist *evlist = spe->session->evlist;
	bool timeless_decoding = 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 int arm_spe_process_queues(struct arm_spe *spe, u64 timestamp)
{
	unsigned int queue_nr;
	u64 ts;
	int ret;

	while (1) {
		struct auxtrace_queue *queue;
		struct arm_spe_queue *speq;

		if (!spe->heap.heap_cnt)
			return 0;

		if (spe->heap.heap_array[0].ordinal >= timestamp)
			return 0;

		queue_nr = spe->heap.heap_array[0].queue_nr;
		queue = &spe->queues.queue_array[queue_nr];
		speq = queue->priv;

		auxtrace_heap__pop(&spe->heap);

		if (spe->heap.heap_cnt) {
			ts = spe->heap.heap_array[0].ordinal + 1;
			if (ts > timestamp)
				ts = timestamp;
		} else {
			ts = timestamp;
		}

		/*
		 * A previous context-switch event has set pid/tid in the machine's context, so
		 * here we need to update the pid/tid in the thread and SPE queue.
		 */
		if (!spe->use_ctx_pkt_for_pid)
			arm_spe_set_pid_tid_cpu(spe, queue);

		ret = arm_spe_run_decoder(speq, &ts);
		if (ret < 0) {
			auxtrace_heap__add(&spe->heap, queue_nr, ts);
			return ret;
		}

		if (!ret) {
			ret = auxtrace_heap__add(&spe->heap, queue_nr, ts);
			if (ret < 0)
				return ret;
		} else {
			speq->on_heap = false;
		}
	}

	return 0;
}

static int arm_spe_process_timeless_queues(struct arm_spe *spe, pid_t tid,
					    u64 time_)
{
	struct auxtrace_queues *queues = &spe->queues;
	unsigned int i;
	u64 ts = 0;

	for (i = 0; i < queues->nr_queues; i++) {
		struct auxtrace_queue *queue = &spe->queues.queue_array[i];
		struct arm_spe_queue *speq = queue->priv;

		if (speq && (tid == -1 || speq->tid == tid)) {
			speq->time = time_;
			arm_spe_set_pid_tid_cpu(spe, queue);
			arm_spe_run_decoder(speq, &ts);
		}
	}
	return 0;
}

static int arm_spe_context_switch(struct arm_spe *spe, union perf_event *event,
				  struct perf_sample *sample)
{
	pid_t pid, tid;
	int cpu;

	if (!(event->header.misc & PERF_RECORD_MISC_SWITCH_OUT))
		return 0;

	pid = event->context_switch.next_prev_pid;
	tid = event->context_switch.next_prev_tid;
	cpu = sample->cpu;

	if (tid == -1)
		pr_warning("context_switch event has no tid\n");

	return machine__set_current_tid(spe->machine, cpu, pid, tid);
}

static int arm_spe_process_event(struct perf_session *session,
				 union perf_event *event,
				 struct perf_sample *sample,
				 const struct perf_tool *tool)
{
	int err = 0;
	u64 timestamp;
	struct arm_spe *spe = container_of(session->auxtrace,
			struct arm_spe, auxtrace);

	if (dump_trace)
		return 0;

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

	if (sample->time && (sample->time != (u64) -1))
		timestamp = perf_time_to_tsc(sample->time, &spe->tc);
	else
		timestamp = 0;

	if (timestamp || spe->timeless_decoding) {
		err = arm_spe__update_queues(spe);
		if (err)
			return err;
	}

	if (spe->timeless_decoding) {
		if (event->header.type == PERF_RECORD_EXIT) {
			err = arm_spe_process_timeless_queues(spe,
					event->fork.tid,
					sample->time);
		}
	} else if (timestamp) {
		err = arm_spe_process_queues(spe, timestamp);
		if (err)
			return err;

		if (!spe->use_ctx_pkt_for_pid &&
		    (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE ||
		    event->header.type == PERF_RECORD_SWITCH))
			err = arm_spe_context_switch(spe, event, sample);
	}

	return err;
}

static int arm_spe_process_auxtrace_event(struct perf_session *session,
					  union perf_event *event,
					  const struct perf_tool *tool __maybe_unused)
{
	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
					     auxtrace);

	if (!spe->data_queued) {
		struct auxtrace_buffer *buffer;
		off_t data_offset;
		int fd = perf_data__fd(session->data);
		int err;

		if (perf_data__is_pipe(session->data)) {
			data_offset = 0;
		} else {
			data_offset = lseek(fd, 0, SEEK_CUR);
			if (data_offset == -1)
				return -errno;
		}

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

		/* Dump here now we have copied a piped trace out of the pipe */
		if (dump_trace) {
			if (auxtrace_buffer__get_data(buffer, fd)) {
				arm_spe_dump_event(spe, buffer->data,
						buffer->size);
				auxtrace_buffer__put_data(buffer);
			}
		}
	}

	return 0;
}

static int arm_spe_flush(struct perf_session *session __maybe_unused,
			 const struct perf_tool *tool __maybe_unused)
{
	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
			auxtrace);
	int ret;

	if (dump_trace)
		return 0;

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

	ret = arm_spe__update_queues(spe);
	if (ret < 0)
		return ret;

	if (spe->timeless_decoding)
		return arm_spe_process_timeless_queues(spe, -1,
				MAX_TIMESTAMP - 1);

	ret = arm_spe_process_queues(spe, MAX_TIMESTAMP);
	if (ret)
		return ret;

	if (!spe->use_ctx_pkt_for_pid)
		ui__warning("Arm SPE CONTEXT packets not found in the traces.\n"
			    "Matching of TIDs to SPE events could be inaccurate.\n");

	return 0;
}

static u64 *arm_spe__alloc_per_cpu_metadata(u64 *buf, int per_cpu_size)
{
	u64 *metadata;

	metadata = zalloc(per_cpu_size);
	if (!metadata)
		return NULL;

	memcpy(metadata, buf, per_cpu_size);
	return metadata;
}

static void arm_spe__free_metadata(u64 **metadata, int nr_cpu)
{
	int i;

	for (i = 0; i < nr_cpu; i++)
		zfree(&metadata[i]);
	free(metadata);
}

static u64 **arm_spe__alloc_metadata(struct perf_record_auxtrace_info *info,
				     u64 *ver, int *nr_cpu)
{
	u64 *ptr = (u64 *)info->priv;
	u64 metadata_size;
	u64 **metadata = NULL;
	int hdr_sz, per_cpu_sz, i;

	metadata_size = info->header.size -
		sizeof(struct perf_record_auxtrace_info);

	/* Metadata version 1 */
	if (metadata_size == ARM_SPE_AUXTRACE_V1_PRIV_SIZE) {
		*ver = 1;
		*nr_cpu = 0;
		/* No per CPU metadata */
		return NULL;
	}

	*ver = ptr[ARM_SPE_HEADER_VERSION];
	hdr_sz = ptr[ARM_SPE_HEADER_SIZE];
	*nr_cpu = ptr[ARM_SPE_CPUS_NUM];

	metadata = calloc(*nr_cpu, sizeof(*metadata));
	if (!metadata)
		return NULL;

	/* Locate the start address of per CPU metadata */
	ptr += hdr_sz;
	per_cpu_sz = (metadata_size - (hdr_sz * sizeof(u64))) / (*nr_cpu);

	for (i = 0; i < *nr_cpu; i++) {
		metadata[i] = arm_spe__alloc_per_cpu_metadata(ptr, per_cpu_sz);
		if (!metadata[i])
			goto err_per_cpu_metadata;

		ptr += per_cpu_sz / sizeof(u64);
	}

	return metadata;

err_per_cpu_metadata:
	arm_spe__free_metadata(metadata, *nr_cpu);
	return NULL;
}

static void arm_spe_free_queue(void *priv)
{
	struct arm_spe_queue *speq = priv;

	if (!speq)
		return;
	thread__zput(speq->thread);
	arm_spe_decoder_free(speq->decoder);
	zfree(&speq->event_buf);
	zfree(&speq->last_branch);
	free(speq);
}

static void arm_spe_free_events(struct perf_session *session)
{
	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
					     auxtrace);
	struct auxtrace_queues *queues = &spe->queues;
	unsigned int i;

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

static void arm_spe_free(struct perf_session *session)
{
	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe,
					     auxtrace);

	auxtrace_heap__free(&spe->heap);
	arm_spe_free_events(session);
	session->auxtrace = NULL;
	arm_spe__free_metadata(spe->metadata, spe->metadata_nr_cpu);
	free(spe);
}

static bool arm_spe_evsel_is_auxtrace(struct perf_session *session,
				      struct evsel *evsel)
{
	struct arm_spe *spe = container_of(session->auxtrace, struct arm_spe, auxtrace);

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

static const char * const metadata_hdr_v1_fmts[] = {
	[ARM_SPE_PMU_TYPE]		= "  PMU Type           :%"PRId64"\n",
	[ARM_SPE_PER_CPU_MMAPS]		= "  Per CPU mmaps      :%"PRId64"\n",
};

static const char * const metadata_hdr_fmts[] = {
	[ARM_SPE_HEADER_VERSION]	= "  Header version     :%"PRId64"\n",
	[ARM_SPE_HEADER_SIZE]		= "  Header size        :%"PRId64"\n",
	[ARM_SPE_PMU_TYPE_V2]		= "  PMU type v2        :%"PRId64"\n",
	[ARM_SPE_CPUS_NUM]		= "  CPU number         :%"PRId64"\n",
};

static const char * const metadata_per_cpu_fmts[] = {
	[ARM_SPE_MAGIC]			= "    Magic            :0x%"PRIx64"\n",
	[ARM_SPE_CPU]			= "    CPU #            :%"PRId64"\n",
	[ARM_SPE_CPU_NR_PARAMS]		= "    Num of params    :%"PRId64"\n",
	[ARM_SPE_CPU_MIDR]		= "    MIDR             :0x%"PRIx64"\n",
	[ARM_SPE_CPU_PMU_TYPE]		= "    PMU Type         :%"PRId64"\n",
	[ARM_SPE_CAP_MIN_IVAL]		= "    Min Interval     :%"PRId64"\n",
	[ARM_SPE_CAP_EVENT_FILTER]	= "    Event Filter     :0x%"PRIx64"\n",
};

static void arm_spe_print_info(struct arm_spe *spe, __u64 *arr)
{
	unsigned int i, cpu, hdr_size, cpu_num, cpu_size;
	const char * const *hdr_fmts;

	if (!dump_trace)
		return;

	if (spe->metadata_ver == 1) {
		cpu_num = 0;
		hdr_size = ARM_SPE_AUXTRACE_V1_PRIV_MAX;
		hdr_fmts = metadata_hdr_v1_fmts;
	} else {
		cpu_num = arr[ARM_SPE_CPUS_NUM];
		hdr_size = arr[ARM_SPE_HEADER_SIZE];
		hdr_fmts = metadata_hdr_fmts;
	}

	for (i = 0; i < hdr_size; i++)
		fprintf(stdout, hdr_fmts[i], arr[i]);

	arr += hdr_size;
	for (cpu = 0; cpu < cpu_num; cpu++) {
		/*
		 * The parameters from ARM_SPE_MAGIC to ARM_SPE_CPU_NR_PARAMS
		 * are fixed. The sequential parameter size is decided by the
		 * field 'ARM_SPE_CPU_NR_PARAMS'.
		 */
		cpu_size = (ARM_SPE_CPU_NR_PARAMS + 1) + arr[ARM_SPE_CPU_NR_PARAMS];
		for (i = 0; i < cpu_size; i++)
			fprintf(stdout, metadata_per_cpu_fmts[i], arr[i]);
		arr += cpu_size;
	}
}

static void arm_spe_set_event_name(struct evlist *evlist, u64 id,
				    const char *name)
{
	struct evsel *evsel;

	evlist__for_each_entry(evlist, evsel) {
		if (evsel->core.id && evsel->core.id[0] == id) {
			if (evsel->name)
				zfree(&evsel->name);
			evsel->name = strdup(name);
			break;
		}
	}
}

static int
arm_spe_synth_events(struct arm_spe *spe, 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 == spe->pmu_type) {
			found = true;
			break;
		}
	}

	if (!found) {
		pr_debug("No selected events with SPE 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 | PERF_SAMPLE_PHYS_ADDR);
	attr.sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID |
			    PERF_SAMPLE_PERIOD | PERF_SAMPLE_DATA_SRC |
			    PERF_SAMPLE_WEIGHT | PERF_SAMPLE_ADDR;
	if (spe->timeless_decoding)
		attr.sample_type &= ~(u64)PERF_SAMPLE_TIME;
	else
		attr.sample_type |= PERF_SAMPLE_TIME;

	spe->sample_type = attr.sample_type;

	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;
	attr.sample_period = spe->synth_opts.period;

	/* create new id val to be a fixed offset from evsel id */
	id = auxtrace_synth_id_range_start(evsel);

	if (spe->synth_opts.flc) {
		spe->sample_flc = true;

		/* Level 1 data cache miss */
		err = perf_session__deliver_synth_attr_event(session, &attr, id);
		if (err)
			return err;
		spe->l1d_miss_id = id;
		arm_spe_set_event_name(evlist, id, "l1d-miss");
		id += 1;

		/* Level 1 data cache access */
		err = perf_session__deliver_synth_attr_event(session, &attr, id);
		if (err)
			return err;
		spe->l1d_access_id = id;
		arm_spe_set_event_name(evlist, id, "l1d-access");
		id += 1;
	}

	if (spe->synth_opts.llc) {
		spe->sample_llc = true;

		/* Last level cache miss */
		err = perf_session__deliver_synth_attr_event(session, &attr, id);
		if (err)
			return err;
		spe->llc_miss_id = id;
		arm_spe_set_event_name(evlist, id, "llc-miss");
		id += 1;

		/* Last level cache access */
		err = perf_session__deliver_synth_attr_event(session, &attr, id);
		if (err)
			return err;
		spe->llc_access_id = id;
		arm_spe_set_event_name(evlist, id, "llc-access");
		id += 1;
	}

	if (spe->synth_opts.tlb) {
		spe->sample_tlb = true;

		/* TLB miss */
		err = perf_session__deliver_synth_attr_event(session, &attr, id);
		if (err)
			return err;
		spe->tlb_miss_id = id;
		arm_spe_set_event_name(evlist, id, "tlb-miss");
		id += 1;

		/* TLB access */
		err = perf_session__deliver_synth_attr_event(session, &attr, id);
		if (err)
			return err;
		spe->tlb_access_id = id;
		arm_spe_set_event_name(evlist, id, "tlb-access");
		id += 1;
	}

	if (spe->synth_opts.last_branch) {
		if (spe->synth_opts.last_branch_sz > 2)
			pr_debug("Arm SPE supports only two bstack entries (PBT+TGT).\n");

		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 (spe->synth_opts.branches) {
		spe->sample_branch = true;

		/* Branch */
		err = perf_session__deliver_synth_attr_event(session, &attr, id);
		if (err)
			return err;
		spe->branch_id = id;
		arm_spe_set_event_name(evlist, id, "branch");
		id += 1;
	}

	if (spe->synth_opts.remote_access) {
		spe->sample_remote_access = true;

		/* Remote access */
		err = perf_session__deliver_synth_attr_event(session, &attr, id);
		if (err)
			return err;
		spe->remote_access_id = id;
		arm_spe_set_event_name(evlist, id, "remote-access");
		id += 1;
	}

	if (spe->synth_opts.mem) {
		spe->sample_memory = true;

		err = perf_session__deliver_synth_attr_event(session, &attr, id);
		if (err)
			return err;
		spe->memory_id = id;
		arm_spe_set_event_name(evlist, id, "memory");
		id += 1;
	}

	if (spe->synth_opts.instructions) {
		spe->sample_instructions = true;
		attr.config = PERF_COUNT_HW_INSTRUCTIONS;

		err = perf_session__deliver_synth_attr_event(session, &attr, id);
		if (err)
			return err;
		spe->instructions_id = id;
		arm_spe_set_event_name(evlist, id, "instructions");
	}

	return 0;
}

static bool arm_spe__is_homogeneous(u64 **metadata, int nr_cpu)
{
	u64 midr;
	int i;

	if (!nr_cpu)
		return false;

	for (i = 0; i < nr_cpu; i++) {
		if (!metadata[i])
			return false;

		if (i == 0) {
			midr = metadata[i][ARM_SPE_CPU_MIDR];
			continue;
		}

		if (midr != metadata[i][ARM_SPE_CPU_MIDR])
			return false;
	}

	return true;
}

int arm_spe_process_auxtrace_info(union perf_event *event,
				  struct perf_session *session)
{
	struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
	size_t min_sz = ARM_SPE_AUXTRACE_V1_PRIV_SIZE;
	struct perf_record_time_conv *tc = &session->time_conv;
	struct arm_spe *spe;
	u64 **metadata = NULL;
	u64 metadata_ver;
	int nr_cpu, err;

	if (auxtrace_info->header.size < sizeof(struct perf_record_auxtrace_info) +
					min_sz)
		return -EINVAL;

	metadata = arm_spe__alloc_metadata(auxtrace_info, &metadata_ver,
					   &nr_cpu);
	if (!metadata && metadata_ver != 1) {
		pr_err("Failed to parse Arm SPE metadata.\n");
		return -EINVAL;
	}

	spe = zalloc(sizeof(struct arm_spe));
	if (!spe) {
		err = -ENOMEM;
		goto err_free_metadata;
	}

	err = auxtrace_queues__init(&spe->queues);
	if (err)
		goto err_free;

	spe->session = session;
	spe->machine = &session->machines.host; /* No kvm support */
	spe->auxtrace_type = auxtrace_info->type;
	if (metadata_ver == 1)
		spe->pmu_type = auxtrace_info->priv[ARM_SPE_PMU_TYPE];
	else
		spe->pmu_type = auxtrace_info->priv[ARM_SPE_PMU_TYPE_V2];
	spe->metadata = metadata;
	spe->metadata_ver = metadata_ver;
	spe->metadata_nr_cpu = nr_cpu;
	spe->is_homogeneous = arm_spe__is_homogeneous(metadata, nr_cpu);

	spe->timeless_decoding = arm_spe__is_timeless_decoding(spe);

	/*
	 * The synthesized event PERF_RECORD_TIME_CONV has been handled ahead
	 * and the parameters for hardware clock are stored in the session
	 * context.  Passes these parameters to the struct perf_tsc_conversion
	 * in "spe->tc", which is used for later conversion between clock
	 * counter and timestamp.
	 *
	 * For backward compatibility, copies the fields starting from
	 * "time_cycles" only if they are contained in the event.
	 */
	spe->tc.time_shift = tc->time_shift;
	spe->tc.time_mult = tc->time_mult;
	spe->tc.time_zero = tc->time_zero;

	if (event_contains(*tc, time_cycles)) {
		spe->tc.time_cycles = tc->time_cycles;
		spe->tc.time_mask = tc->time_mask;
		spe->tc.cap_user_time_zero = tc->cap_user_time_zero;
		spe->tc.cap_user_time_short = tc->cap_user_time_short;
	}

	spe->auxtrace.process_event = arm_spe_process_event;
	spe->auxtrace.process_auxtrace_event = arm_spe_process_auxtrace_event;
	spe->auxtrace.flush_events = arm_spe_flush;
	spe->auxtrace.free_events = arm_spe_free_events;
	spe->auxtrace.free = arm_spe_free;
	spe->auxtrace.evsel_is_auxtrace = arm_spe_evsel_is_auxtrace;
	session->auxtrace = &spe->auxtrace;

	arm_spe_print_info(spe, &auxtrace_info->priv[0]);

	if (dump_trace)
		return 0;

	if (session->itrace_synth_opts && session->itrace_synth_opts->set) {
		spe->synth_opts = *session->itrace_synth_opts;
	} else {
		itrace_synth_opts__set_default(&spe->synth_opts, false);
		/* Default nanoseconds period not supported */
		spe->synth_opts.period_type = PERF_ITRACE_PERIOD_INSTRUCTIONS;
		spe->synth_opts.period = 1;
	}

	if (spe->synth_opts.period_type != PERF_ITRACE_PERIOD_INSTRUCTIONS) {
		ui__error("You must only use i (instructions) --itrace period with Arm SPE. e.g --itrace=i1i\n");
		err = -EINVAL;
		goto err_free_queues;
	}
	if (spe->synth_opts.period > 1)
		ui__warning("Arm SPE has a hardware-based sampling period.\n\n"
			    "--itrace periods > 1i downsample by an interval of n SPE samples rather than n instructions.\n");

	err = arm_spe_synth_events(spe, session);
	if (err)
		goto err_free_queues;

	err = auxtrace_queues__process_index(&spe->queues, session);
	if (err)
		goto err_free_queues;

	if (spe->queues.populated)
		spe->data_queued = true;

	return 0;

err_free_queues:
	auxtrace_queues__free(&spe->queues);
	session->auxtrace = NULL;
err_free:
	free(spe);
err_free_metadata:
	arm_spe__free_metadata(metadata, nr_cpu);
	return err;
}
