/*
 * Copyright (c) 2021 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <zephyr/debug/coredump.h>
#include <xtensa-asm2.h>

#define ARCH_HDR_VER			1
#define XTENSA_BLOCK_HDR_VER		2

enum xtensa_soc_code {
	XTENSA_SOC_UNKNOWN = 0,
	XTENSA_SOC_SAMPLE_CONTROLLER,
	XTENSA_SOC_ESP32,
	XTENSA_SOC_INTEL_ADSP,
};

struct xtensa_arch_block {
	/* Each Xtensa SOC can omit registers (e.g. loop
	 * registers) or assign different index numbers
	 * in xtensa-config.c. GDB identifies registers
	 * based on these indices
	 *
	 * (This must be the first field or the GDB server
	 * won't be able to unpack the struct while parsing)
	 */
	uint8_t		soc;

	/* Future versions of Xtensa coredump may expand
	 * minimum set of registers
	 *
	 * (This should stay the second field for the same
	 * reason as the first once we have more versions)
	 */
	uint16_t	version;

	uint8_t		toolchain;

	struct {
		/* Minimum set shown by GDB 'info registers',
		 * skipping user-defined register EXPSTATE
		 *
		 * WARNING: IF YOU CHANGE THE ORDER OF THE REGISTERS,
		 * YOU MUST UPDATE THE ORDER OF THE REGISTERS IN
		 * EACH OF THE XtensaSoc_ RegNum enums IN
		 * scripts/coredump/gdbstubs/arch/xtensa.py TO MATCH.
		 * See xtensa.py's map_register function for details
		 */
		uint32_t	pc;
		uint32_t	exccause;
		uint32_t	excvaddr;
		uint32_t	sar;
		uint32_t	ps;
#if XCHAL_HAVE_S32C1I
		uint32_t	scompare1;
#endif
		uint32_t	a0;
		uint32_t	a1;
		uint32_t	a2;
		uint32_t	a3;
		uint32_t	a4;
		uint32_t	a5;
		uint32_t	a6;
		uint32_t	a7;
		uint32_t	a8;
		uint32_t	a9;
		uint32_t	a10;
		uint32_t	a11;
		uint32_t	a12;
		uint32_t	a13;
		uint32_t	a14;
		uint32_t	a15;
#if XCHAL_HAVE_LOOPS
		uint32_t	lbeg;
		uint32_t	lend;
		uint32_t	lcount;
#endif
	} r;
} __packed;

/*
 * This might be too large for stack space if defined
 * inside function. So do it here.
 */
static struct xtensa_arch_block arch_blk;

void arch_coredump_info_dump(const z_arch_esf_t *esf)
{
	struct coredump_arch_hdr_t hdr = {
		.id = COREDUMP_ARCH_HDR_ID,
		.hdr_version = ARCH_HDR_VER,
		.num_bytes = sizeof(arch_blk),
	};

	/* Nothing to process */
	if (esf == NULL) {
		return;
	}

	(void)memset(&arch_blk, 0, sizeof(arch_blk));

	arch_blk.version = XTENSA_BLOCK_HDR_VER;

	#if CONFIG_SOC_XTENSA_SAMPLE_CONTROLLER
		arch_blk.soc = XTENSA_SOC_SAMPLE_CONTROLLER;
	#elif CONFIG_SOC_ESP32
		arch_blk.soc = XTENSA_SOC_ESP32;
	#elif CONFIG_SOC_FAMILY_INTEL_ADSP
		arch_blk.soc = XTENSA_SOC_INTEL_ADSP;
	#else
		arch_blk.soc = XTENSA_SOC_UNKNOWN;
	#endif

	/* Set in top-level CMakeLists.txt for use with Xtensa coredump */
	arch_blk.toolchain = XTENSA_TOOLCHAIN_VARIANT;

	__asm__ volatile("rsr.exccause %0" : "=r"(arch_blk.r.exccause));

	int *bsa = *(int **)esf;

	arch_blk.r.pc = bsa[BSA_PC_OFF/4];
	__asm__ volatile("rsr.excvaddr %0" : "=r"(arch_blk.r.excvaddr));
	arch_blk.r.ps = bsa[BSA_PS_OFF/4];
#if XCHAL_HAVE_S32C1I
	arch_blk.r.scompare1 = bsa[BSA_SCOMPARE1_OFF];
#endif
	arch_blk.r.sar = bsa[BSA_SAR_OFF/4];
	arch_blk.r.a0 = bsa[BSA_A0_OFF/4];
	arch_blk.r.a1 =  (uint32_t)((char *)bsa) + BASE_SAVE_AREA_SIZE;
	arch_blk.r.a2 = bsa[BSA_A2_OFF/4];
	arch_blk.r.a3 = bsa[BSA_A3_OFF/4];
	if (bsa - esf > 4) {
		arch_blk.r.a4 = bsa[-4];
		arch_blk.r.a5 = bsa[-3];
		arch_blk.r.a6 = bsa[-2];
		arch_blk.r.a7 = bsa[-1];
	}
	if (bsa - esf > 8) {
		arch_blk.r.a8 = bsa[-8];
		arch_blk.r.a9 = bsa[-7];
		arch_blk.r.a10 = bsa[-6];
		arch_blk.r.a11 = bsa[-5];
	}
	if (bsa - esf > 12) {
		arch_blk.r.a12 = bsa[-12];
		arch_blk.r.a13 = bsa[-11];
		arch_blk.r.a14 = bsa[-10];
		arch_blk.r.a15 = bsa[-9];
	}
	#if XCHAL_HAVE_LOOPS
	arch_blk.r.lbeg = bsa[BSA_LBEG_OFF/4];
	arch_blk.r.lend = bsa[BSA_LEND_OFF/4];
	arch_blk.r.lcount = bsa[BSA_LCOUNT_OFF/4];
	#endif

	/* Send for output */
	coredump_buffer_output((uint8_t *)&hdr, sizeof(hdr));
	coredump_buffer_output((uint8_t *)&arch_blk, sizeof(arch_blk));
}

uint16_t arch_coredump_tgt_code_get(void)
{
	return COREDUMP_TGT_XTENSA;
}
