/*
 * Copyright (c) 2019-2020 Cobham Gaisler AB
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);

/*
 * EXAMPLE OUTPUT
 *
 * ---------------------------------------------------------------------
 *
 *  tt = 0x02, illegal_instruction
 *
 *        INS        LOCALS     OUTS       GLOBALS
 *    0:  00000000   f3900fc0   40007c50   00000000
 *    1:  00000000   40004bf0   40008d30   40008c00
 *    2:  00000000   40004bf4   40008000   00000003
 *    3:  40009158   00000000   40009000   00000002
 *    4:  40008fa8   40003c00   40008fa8   00000008
 *    5:  40009000   f3400fc0   00000000   00000080
 *    6:  4000a1f8   40000050   4000a190   00000000
 *    7:  40002308   00000000   40001fb8   000000c1
 *
 *  psr: f30000c7   wim: 00000008   tbr: 40000020   y: 00000000
 *   pc: 4000a1f4   npc: 4000a1f8
 *
 *        pc         sp
 *   #0   4000a1f4   4000a190
 *   #1   40002308   4000a1f8
 *   #2   40003b24   4000a258
 *
 * ---------------------------------------------------------------------
 *
 *
 * INTERPRETATION
 *
 * INS, LOCALS, OUTS and GLOBALS represent the %i, %l, %o and %g
 * registers before the trap was taken.
 *
 * wim, y, pc and npc are the values before the trap was taken.
 * tbr has the tbr.tt field (bits 11..4) filled in by hardware
 * representing the current trap type. psr is read immediately
 * after the trap was taken so it will have the new CWP and ET=0.
 *
 * The "#i pc sp" rows is the stack backtrace. All register
 * windows are flushed to the stack prior to printing. First row
 * is the trapping pc and sp (o6).
 *
 *
 * HOW TO USE
 *
 * When investigating a crashed program, the first things to look
 * at is typically the tt, pc and sp (o6). You can lookup the pc
 * in the assembly list file or use addr2line. In the listing, the
 * register values in the table above can be used. The linker map
 * file will give a hint on which stack is active and if it has
 * overflowed.
 *
 * psr bits 11..8 is the processor interrupt (priority) level. 0
 * is lowest priority level (all can be taken), and 0xf is the
 * highest level where only non-maskable interrupts are taken.
 *
 * g0 is always zero. g5, g6 are never accessed by the compiler.
 * g7 is the TLS pointer if enabled. A SAVE instruction decreases
 * the current window pointer (psr bits 4..0) which results in %o
 * registers becoming %i registers and a new set of %l registers
 * appear. RESTORE does the opposite.
 */


/*
 * The SPARC V8 ABI guarantees that the stack pointer register
 * (o6) points to an area organized as "struct savearea" below at
 * all times when traps are enabled. This is the register save
 * area where register window registers can be flushed to the
 * stack.
 *
 * We flushed registers to this space in the fault trap entry
 * handler. Note that the space is allocated by the ABI (compiler)
 * for each stack frame.
 *
 * When printing the registers, we get the "local" and "in"
 * registers from the ABI stack save area, while the "out" and
 * "global" registers are taken from the exception stack frame
 * generated in the fault trap entry.
 */
struct savearea {
	uint32_t local[8];
	uint32_t in[8];
};


/*
 * Exception trap type (tt) values according to The SPARC V8
 * manual, Table 7-1.
 */
static const struct {
	int tt;
	const char *desc;
} TTDESC[] = {
	{ .tt = 0x02, .desc = "illegal_instruction", },
	{ .tt = 0x07, .desc = "mem_address_not_aligned", },
	{ .tt = 0x2B, .desc = "data_store_error", },
	{ .tt = 0x29, .desc = "data_access_error", },
	{ .tt = 0x09, .desc = "data_access_exception", },
	{ .tt = 0x21, .desc = "instruction_access_error", },
	{ .tt = 0x01, .desc = "instruction_access_exception", },
	{ .tt = 0x04, .desc = "fp_disabled", },
	{ .tt = 0x08, .desc = "fp_exception", },
	{ .tt = 0x2A, .desc = "division_by_zero", },
	{ .tt = 0x03, .desc = "privileged_instruction", },
	{ .tt = 0x20, .desc = "r_register_access_error", },
	{ .tt = 0x0B, .desc = "watchpoint_detected", },
	{ .tt = 0x2C, .desc = "data_access_MMU_miss", },
	{ .tt = 0x3C, .desc = "instruction_access_MMU_miss", },
	{ .tt = 0x05, .desc = "window_overflow", },
	{ .tt = 0x06, .desc = "window_underflow", },
	{ .tt = 0x0A, .desc = "tag_overflow", },
};

static void print_trap_type(const z_arch_esf_t *esf)
{
	const int tt = (esf->tbr & TBR_TT) >> TBR_TT_BIT;
	const char *desc = "unknown";

	if (tt & 0x80) {
		desc = "trap_instruction";
	} else if (tt >= 0x11 && tt <= 0x1F) {
		desc = "interrupt";
	} else {
		for (int i = 0; i < ARRAY_SIZE(TTDESC); i++) {
			if (TTDESC[i].tt == tt) {
				desc = TTDESC[i].desc;
				break;
			}
		}
	}
	LOG_ERR("tt = 0x%02X, %s", tt, desc);
}

static void print_integer_registers(const z_arch_esf_t *esf)
{
	const struct savearea *flushed = (struct savearea *) esf->out[6];

	LOG_ERR("      INS        LOCALS     OUTS       GLOBALS");
	for (int i = 0; i < 8; i++) {
		LOG_ERR(
			"  %d:  %08x   %08x   %08x   %08x",
			i,
			flushed ? flushed->in[i] : 0,
			flushed ? flushed->local[i] : 0,
			esf->out[i],
			esf->global[i]
		);
	}
}

static void print_special_registers(const z_arch_esf_t *esf)
{
	LOG_ERR(
		"psr: %08x   wim: %08x   tbr: %08x   y: %08x",
		esf->psr, esf->wim, esf->tbr, esf->y
	);
	LOG_ERR(" pc: %08x   npc: %08x", esf->pc, esf->npc);
}

static void print_backtrace(const z_arch_esf_t *esf)
{
	const int MAX_LOGLINES = 40;
	const struct savearea *s = (struct savearea *) esf->out[6];

	LOG_ERR("      pc         sp");
	LOG_ERR(" #0   %08x   %08x", esf->pc, (unsigned int) s);
	for (int i = 1; s && i < MAX_LOGLINES; i++) {
		const uint32_t pc = s->in[7];
		const uint32_t sp = s->in[6];

		if (sp == 0U && pc == 0U) {
			break;
		}
		LOG_ERR(" #%-2d  %08x   %08x", i, pc, sp);
		if (sp == 0U || sp & 7U) {
			break;
		}
		s = (const struct savearea *) sp;
	}
}

static void print_all(const z_arch_esf_t *esf)
{
	LOG_ERR("");
	print_trap_type(esf);
	LOG_ERR("");
	print_integer_registers(esf);
	LOG_ERR("");
	print_special_registers(esf);
	LOG_ERR("");
	print_backtrace(esf);
	LOG_ERR("");
}

FUNC_NORETURN void z_sparc_fatal_error(unsigned int reason,
				       const z_arch_esf_t *esf)
{
	if (esf != NULL) {
		if (IS_ENABLED(CONFIG_EXTRA_EXCEPTION_INFO)) {
			print_all(esf);
		} else {
			print_special_registers(esf);
		}
	}
	z_fatal_error(reason, esf);
	CODE_UNREACHABLE;
}
