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

#include <stdio.h>
#include <string.h>
#include <endian.h>
#include <byteswap.h>
#include <linux/bitops.h>
#include <stdarg.h>

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

#if __BYTE_ORDER == __BIG_ENDIAN
#define le16_to_cpu bswap_16
#define le32_to_cpu bswap_32
#define le64_to_cpu bswap_64
#define memcpy_le64(d, s, n) do { \
	memcpy((d), (s), (n));    \
	*(d) = le64_to_cpu(*(d)); \
} while (0)
#else
#define le16_to_cpu
#define le32_to_cpu
#define le64_to_cpu
#define memcpy_le64 memcpy
#endif

static const char * const arm_spe_packet_name[] = {
	[ARM_SPE_PAD]		= "PAD",
	[ARM_SPE_END]		= "END",
	[ARM_SPE_TIMESTAMP]	= "TS",
	[ARM_SPE_ADDRESS]	= "ADDR",
	[ARM_SPE_COUNTER]	= "LAT",
	[ARM_SPE_CONTEXT]	= "CONTEXT",
	[ARM_SPE_OP_TYPE]	= "OP-TYPE",
	[ARM_SPE_EVENTS]	= "EVENTS",
	[ARM_SPE_DATA_SOURCE]	= "DATA-SOURCE",
};

const char *arm_spe_pkt_name(enum arm_spe_pkt_type type)
{
	return arm_spe_packet_name[type];
}

/*
 * Extracts the field "sz" from header bits and converts to bytes:
 *   00 : byte (1)
 *   01 : halfword (2)
 *   10 : word (4)
 *   11 : doubleword (8)
 */
static unsigned int arm_spe_payload_len(unsigned char hdr)
{
	return 1U << ((hdr & GENMASK_ULL(5, 4)) >> 4);
}

static int arm_spe_get_payload(const unsigned char *buf, size_t len,
			       unsigned char ext_hdr,
			       struct arm_spe_pkt *packet)
{
	size_t payload_len = arm_spe_payload_len(buf[ext_hdr]);

	if (len < 1 + ext_hdr + payload_len)
		return ARM_SPE_NEED_MORE_BYTES;

	buf += 1 + ext_hdr;

	switch (payload_len) {
	case 1: packet->payload = *(uint8_t *)buf; break;
	case 2: packet->payload = le16_to_cpu(*(uint16_t *)buf); break;
	case 4: packet->payload = le32_to_cpu(*(uint32_t *)buf); break;
	case 8: packet->payload = le64_to_cpu(*(uint64_t *)buf); break;
	default: return ARM_SPE_BAD_PACKET;
	}

	return 1 + ext_hdr + payload_len;
}

static int arm_spe_get_pad(struct arm_spe_pkt *packet)
{
	packet->type = ARM_SPE_PAD;
	return 1;
}

static int arm_spe_get_alignment(const unsigned char *buf, size_t len,
				 struct arm_spe_pkt *packet)
{
	unsigned int alignment = 1 << ((buf[0] & 0xf) + 1);

	if (len < alignment)
		return ARM_SPE_NEED_MORE_BYTES;

	packet->type = ARM_SPE_PAD;
	return alignment - (((uintptr_t)buf) & (alignment - 1));
}

static int arm_spe_get_end(struct arm_spe_pkt *packet)
{
	packet->type = ARM_SPE_END;
	return 1;
}

static int arm_spe_get_timestamp(const unsigned char *buf, size_t len,
				 struct arm_spe_pkt *packet)
{
	packet->type = ARM_SPE_TIMESTAMP;
	return arm_spe_get_payload(buf, len, 0, packet);
}

static int arm_spe_get_events(const unsigned char *buf, size_t len,
			      struct arm_spe_pkt *packet)
{
	packet->type = ARM_SPE_EVENTS;

	/* we use index to identify Events with a less number of
	 * comparisons in arm_spe_pkt_desc(): E.g., the LLC-ACCESS,
	 * LLC-REFILL, and REMOTE-ACCESS events are identified if
	 * index > 1.
	 */
	packet->index = arm_spe_payload_len(buf[0]);

	return arm_spe_get_payload(buf, len, 0, packet);
}

static int arm_spe_get_data_source(const unsigned char *buf, size_t len,
				   struct arm_spe_pkt *packet)
{
	packet->type = ARM_SPE_DATA_SOURCE;
	return arm_spe_get_payload(buf, len, 0, packet);
}

static int arm_spe_get_context(const unsigned char *buf, size_t len,
			       struct arm_spe_pkt *packet)
{
	packet->type = ARM_SPE_CONTEXT;
	packet->index = SPE_CTX_PKT_HDR_INDEX(buf[0]);
	return arm_spe_get_payload(buf, len, 0, packet);
}

static int arm_spe_get_op_type(const unsigned char *buf, size_t len,
			       struct arm_spe_pkt *packet)
{
	packet->type = ARM_SPE_OP_TYPE;
	packet->index = SPE_OP_PKT_HDR_CLASS(buf[0]);
	return arm_spe_get_payload(buf, len, 0, packet);
}

static int arm_spe_get_counter(const unsigned char *buf, size_t len,
			       const unsigned char ext_hdr, struct arm_spe_pkt *packet)
{
	packet->type = ARM_SPE_COUNTER;

	if (ext_hdr)
		packet->index = SPE_HDR_EXTENDED_INDEX(buf[0], buf[1]);
	else
		packet->index = SPE_HDR_SHORT_INDEX(buf[0]);

	return arm_spe_get_payload(buf, len, ext_hdr, packet);
}

static int arm_spe_get_addr(const unsigned char *buf, size_t len,
			    const unsigned char ext_hdr, struct arm_spe_pkt *packet)
{
	packet->type = ARM_SPE_ADDRESS;

	if (ext_hdr)
		packet->index = SPE_HDR_EXTENDED_INDEX(buf[0], buf[1]);
	else
		packet->index = SPE_HDR_SHORT_INDEX(buf[0]);

	return arm_spe_get_payload(buf, len, ext_hdr, packet);
}

static int arm_spe_do_get_packet(const unsigned char *buf, size_t len,
				 struct arm_spe_pkt *packet)
{
	unsigned int hdr;
	unsigned char ext_hdr = 0;

	memset(packet, 0, sizeof(struct arm_spe_pkt));

	if (!len)
		return ARM_SPE_NEED_MORE_BYTES;

	hdr = buf[0];

	if (hdr == SPE_HEADER0_PAD)
		return arm_spe_get_pad(packet);

	if (hdr == SPE_HEADER0_END) /* no timestamp at end of record */
		return arm_spe_get_end(packet);

	if (hdr == SPE_HEADER0_TIMESTAMP)
		return arm_spe_get_timestamp(buf, len, packet);

	if ((hdr & SPE_HEADER0_MASK1) == SPE_HEADER0_EVENTS)
		return arm_spe_get_events(buf, len, packet);

	if ((hdr & SPE_HEADER0_MASK1) == SPE_HEADER0_SOURCE)
		return arm_spe_get_data_source(buf, len, packet);

	if ((hdr & SPE_HEADER0_MASK2) == SPE_HEADER0_CONTEXT)
		return arm_spe_get_context(buf, len, packet);

	if ((hdr & SPE_HEADER0_MASK2) == SPE_HEADER0_OP_TYPE)
		return arm_spe_get_op_type(buf, len, packet);

	if ((hdr & SPE_HEADER0_MASK2) == SPE_HEADER0_EXTENDED) {
		/* 16-bit extended format header */
		ext_hdr = 1;

		hdr = buf[1];
		if (hdr == SPE_HEADER1_ALIGNMENT)
			return arm_spe_get_alignment(buf, len, packet);
	}

	/*
	 * The short format header's byte 0 or the extended format header's
	 * byte 1 has been assigned to 'hdr', which uses the same encoding for
	 * address packet and counter packet, so don't need to distinguish if
	 * it's short format or extended format and handle in once.
	 */
	if ((hdr & SPE_HEADER0_MASK3) == SPE_HEADER0_ADDRESS)
		return arm_spe_get_addr(buf, len, ext_hdr, packet);

	if ((hdr & SPE_HEADER0_MASK3) == SPE_HEADER0_COUNTER)
		return arm_spe_get_counter(buf, len, ext_hdr, packet);

	return ARM_SPE_BAD_PACKET;
}

int arm_spe_get_packet(const unsigned char *buf, size_t len,
		       struct arm_spe_pkt *packet)
{
	int ret;

	ret = arm_spe_do_get_packet(buf, len, packet);
	/* put multiple consecutive PADs on the same line, up to
	 * the fixed-width output format of 16 bytes per line.
	 */
	if (ret > 0 && packet->type == ARM_SPE_PAD) {
		while (ret < 16 && len > (size_t)ret && !buf[ret])
			ret += 1;
	}
	return ret;
}

static int arm_spe_pkt_out_string(int *err, char **buf_p, size_t *blen,
				  const char *fmt, ...)
{
	va_list ap;
	int ret;

	/* Bail out if any error occurred */
	if (err && *err)
		return *err;

	va_start(ap, fmt);
	ret = vsnprintf(*buf_p, *blen, fmt, ap);
	va_end(ap);

	if (ret < 0) {
		if (err && !*err)
			*err = ret;

	/*
	 * A return value of *blen or more means that the output was
	 * truncated and the buffer is overrun.
	 */
	} else if ((size_t)ret >= *blen) {
		(*buf_p)[*blen - 1] = '\0';

		/*
		 * Set *err to 'ret' to avoid overflow if tries to
		 * fill this buffer sequentially.
		 */
		if (err && !*err)
			*err = ret;
	} else {
		*buf_p += ret;
		*blen -= ret;
	}

	return ret;
}

static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
				  char *buf, size_t buf_len)
{
	u64 payload = packet->payload;
	int err = 0;

	arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");

	if (payload & BIT(EV_EXCEPTION_GEN))
		arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCEPTION-GEN");
	if (payload & BIT(EV_RETIRED))
		arm_spe_pkt_out_string(&err, &buf, &buf_len, " RETIRED");
	if (payload & BIT(EV_L1D_ACCESS))
		arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-ACCESS");
	if (payload & BIT(EV_L1D_REFILL))
		arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-REFILL");
	if (payload & BIT(EV_TLB_ACCESS))
		arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-ACCESS");
	if (payload & BIT(EV_TLB_WALK))
		arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-REFILL");
	if (payload & BIT(EV_NOT_TAKEN))
		arm_spe_pkt_out_string(&err, &buf, &buf_len, " NOT-TAKEN");
	if (payload & BIT(EV_MISPRED))
		arm_spe_pkt_out_string(&err, &buf, &buf_len, " MISPRED");
	if (payload & BIT(EV_LLC_ACCESS))
		arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-ACCESS");
	if (payload & BIT(EV_LLC_MISS))
		arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-REFILL");
	if (payload & BIT(EV_REMOTE_ACCESS))
		arm_spe_pkt_out_string(&err, &buf, &buf_len, " REMOTE-ACCESS");
	if (payload & BIT(EV_ALIGNMENT))
		arm_spe_pkt_out_string(&err, &buf, &buf_len, " ALIGNMENT");
	if (payload & BIT(EV_PARTIAL_PREDICATE))
		arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-PARTIAL-PRED");
	if (payload & BIT(EV_EMPTY_PREDICATE))
		arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-EMPTY-PRED");

	return err;
}

static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet,
				    char *buf, size_t buf_len)
{
	u64 payload = packet->payload;
	int err = 0;

	switch (packet->index) {
	case SPE_OP_PKT_HDR_CLASS_OTHER:
		if (SPE_OP_PKT_IS_OTHER_SVE_OP(payload)) {
			arm_spe_pkt_out_string(&err, &buf, &buf_len, "SVE-OTHER");

			/* SVE effective vector length */
			arm_spe_pkt_out_string(&err, &buf, &buf_len, " EVLEN %d",
					       SPE_OP_PKG_SVE_EVL(payload));

			if (payload & SPE_OP_PKT_SVE_FP)
				arm_spe_pkt_out_string(&err, &buf, &buf_len, " FP");
			if (payload & SPE_OP_PKT_SVE_PRED)
				arm_spe_pkt_out_string(&err, &buf, &buf_len, " PRED");
		} else {
			arm_spe_pkt_out_string(&err, &buf, &buf_len, "OTHER");
			arm_spe_pkt_out_string(&err, &buf, &buf_len, " %s",
					       payload & SPE_OP_PKT_COND ?
					       "COND-SELECT" : "INSN-OTHER");
		}
		break;
	case SPE_OP_PKT_HDR_CLASS_LD_ST_ATOMIC:
		arm_spe_pkt_out_string(&err, &buf, &buf_len,
				       payload & 0x1 ? "ST" : "LD");

		if (SPE_OP_PKT_IS_LDST_ATOMIC(payload)) {
			if (payload & SPE_OP_PKT_AT)
				arm_spe_pkt_out_string(&err, &buf, &buf_len, " AT");
			if (payload & SPE_OP_PKT_EXCL)
				arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCL");
			if (payload & SPE_OP_PKT_AR)
				arm_spe_pkt_out_string(&err, &buf, &buf_len, " AR");
		}

		switch (SPE_OP_PKT_LDST_SUBCLASS_GET(payload)) {
		case SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP:
			arm_spe_pkt_out_string(&err, &buf, &buf_len, " SIMD-FP");
			break;
		case SPE_OP_PKT_LDST_SUBCLASS_GP_REG:
			arm_spe_pkt_out_string(&err, &buf, &buf_len, " GP-REG");
			break;
		case SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG:
			arm_spe_pkt_out_string(&err, &buf, &buf_len, " UNSPEC-REG");
			break;
		case SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG:
			arm_spe_pkt_out_string(&err, &buf, &buf_len, " NV-SYSREG");
			break;
		default:
			break;
		}

		if (SPE_OP_PKT_IS_LDST_SVE(payload)) {
			/* SVE effective vector length */
			arm_spe_pkt_out_string(&err, &buf, &buf_len, " EVLEN %d",
					       SPE_OP_PKG_SVE_EVL(payload));

			if (payload & SPE_OP_PKT_SVE_PRED)
				arm_spe_pkt_out_string(&err, &buf, &buf_len, " PRED");
			if (payload & SPE_OP_PKT_SVE_SG)
				arm_spe_pkt_out_string(&err, &buf, &buf_len, " SG");
		}
		break;
	case SPE_OP_PKT_HDR_CLASS_BR_ERET:
		arm_spe_pkt_out_string(&err, &buf, &buf_len, "B");

		if (payload & SPE_OP_PKT_COND)
			arm_spe_pkt_out_string(&err, &buf, &buf_len, " COND");

		if (SPE_OP_PKT_IS_INDIRECT_BRANCH(payload))
			arm_spe_pkt_out_string(&err, &buf, &buf_len, " IND");

		break;
	default:
		/* Unknown index */
		err = -1;
		break;
	}

	return err;
}

static int arm_spe_pkt_desc_addr(const struct arm_spe_pkt *packet,
				 char *buf, size_t buf_len)
{
	int ns, el, idx = packet->index;
	int ch, pat;
	u64 payload = packet->payload;
	int err = 0;

	switch (idx) {
	case SPE_ADDR_PKT_HDR_INDEX_INS:
	case SPE_ADDR_PKT_HDR_INDEX_BRANCH:
		ns = !!SPE_ADDR_PKT_GET_NS(payload);
		el = SPE_ADDR_PKT_GET_EL(payload);
		payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
		arm_spe_pkt_out_string(&err, &buf, &buf_len,
				"%s 0x%llx el%d ns=%d",
				(idx == 1) ? "TGT" : "PC", payload, el, ns);
		break;
	case SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT:
		arm_spe_pkt_out_string(&err, &buf, &buf_len,
				       "VA 0x%llx", payload);
		break;
	case SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS:
		ns = !!SPE_ADDR_PKT_GET_NS(payload);
		ch = !!SPE_ADDR_PKT_GET_CH(payload);
		pat = SPE_ADDR_PKT_GET_PAT(payload);
		payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
		arm_spe_pkt_out_string(&err, &buf, &buf_len,
				       "PA 0x%llx ns=%d ch=%d pat=%x",
				       payload, ns, ch, pat);
		break;
	default:
		/* Unknown index */
		err = -1;
		break;
	}

	return err;
}

static int arm_spe_pkt_desc_counter(const struct arm_spe_pkt *packet,
				    char *buf, size_t buf_len)
{
	u64 payload = packet->payload;
	const char *name = arm_spe_pkt_name(packet->type);
	int err = 0;

	arm_spe_pkt_out_string(&err, &buf, &buf_len, "%s %d ", name,
			       (unsigned short)payload);

	switch (packet->index) {
	case SPE_CNT_PKT_HDR_INDEX_TOTAL_LAT:
		arm_spe_pkt_out_string(&err, &buf, &buf_len, "TOT");
		break;
	case SPE_CNT_PKT_HDR_INDEX_ISSUE_LAT:
		arm_spe_pkt_out_string(&err, &buf, &buf_len, "ISSUE");
		break;
	case SPE_CNT_PKT_HDR_INDEX_TRANS_LAT:
		arm_spe_pkt_out_string(&err, &buf, &buf_len, "XLAT");
		break;
	default:
		break;
	}

	return err;
}

int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
		     size_t buf_len)
{
	int idx = packet->index;
	unsigned long long payload = packet->payload;
	const char *name = arm_spe_pkt_name(packet->type);
	char *buf_orig = buf;
	size_t blen = buf_len;
	int err = 0;

	switch (packet->type) {
	case ARM_SPE_BAD:
	case ARM_SPE_PAD:
	case ARM_SPE_END:
		arm_spe_pkt_out_string(&err, &buf, &blen, "%s", name);
		break;
	case ARM_SPE_EVENTS:
		err = arm_spe_pkt_desc_event(packet, buf, buf_len);
		break;
	case ARM_SPE_OP_TYPE:
		err = arm_spe_pkt_desc_op_type(packet, buf, buf_len);
		break;
	case ARM_SPE_DATA_SOURCE:
	case ARM_SPE_TIMESTAMP:
		arm_spe_pkt_out_string(&err, &buf, &blen, "%s %lld", name, payload);
		break;
	case ARM_SPE_ADDRESS:
		err = arm_spe_pkt_desc_addr(packet, buf, buf_len);
		break;
	case ARM_SPE_CONTEXT:
		arm_spe_pkt_out_string(&err, &buf, &blen, "%s 0x%lx el%d",
				       name, (unsigned long)payload, idx + 1);
		break;
	case ARM_SPE_COUNTER:
		err = arm_spe_pkt_desc_counter(packet, buf, buf_len);
		break;
	default:
		/* Unknown packet type */
		err = -1;
		break;
	}

	/* Output raw data if detect any error */
	if (err) {
		err = 0;
		arm_spe_pkt_out_string(&err, &buf_orig, &buf_len, "%s 0x%llx (%d)",
				       name, payload, packet->index);
	}

	return err;
}
