/*
 * Copyright (c) 2020 Espressif Systems (Shanghai) Co., Ltd.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "xtensa/corebits.h"
#include "xtensa_backtrace.h"
#include <zephyr/sys/printk.h>
#if defined(CONFIG_SOC_SERIES_ESP32)
#include "soc/soc_memory_layout.h"
#elif defined(CONFIG_SOC_FAMILY_INTEL_ADSP)
#include "debug_helpers.h"
#elif defined(CONFIG_SOC_XTENSA_DC233C)
#include "backtrace_helpers.h"
#endif
static int mask, cause;

static inline uint32_t xtensa_cpu_process_stack_pc(uint32_t pc)
{
	if (pc & 0x80000000) {
		/* Top two bits of a0 (return address) specify window increment.
		 * Overwrite to map to address space.
		 */
		if (cause != EXCCAUSE_INSTR_PROHIBITED) {
			pc = (pc & 0x3fffffff) | mask;
		} else {
			pc = (pc & 0x3fffffff) | 0x40000000;
		}
	}
	/* Minus 3 to get PC of previous instruction
	 * (i.e. instruction executed before return address)
	 */
	return pc - 3;
}

static inline bool xtensa_stack_ptr_is_sane(uint32_t sp)
{
#if defined(CONFIG_SOC_SERIES_ESP32)
	return esp_stack_ptr_is_sane(sp);
#elif defined(CONFIG_SOC_FAMILY_INTEL_ADSP)
	return intel_adsp_ptr_is_sane(sp);
#elif defined(CONFIG_SOC_XTENSA_DC233C)
	return xtensa_dc233c_stack_ptr_is_sane(sp);
#else
#warning "xtensa_stack_ptr_is_sane is not defined for this platform"
#endif
}

static inline bool xtensa_ptr_executable(const void *p)
{
#if defined(CONFIG_SOC_SERIES_ESP32)
	return esp_ptr_executable(p);
#elif defined(CONFIG_SOC_FAMILY_INTEL_ADSP)
	return intel_adsp_ptr_executable(p);
#elif defined(CONFIG_SOC_XTENSA_DC233C)
	return xtensa_dc233c_ptr_executable(p);
#else
#warning "xtensa_ptr_executable is not defined for this platform"
#endif
}

bool xtensa_backtrace_get_next_frame(struct xtensa_backtrace_frame_t *frame)
{
	/* Use frame(i-1)'s BS area located below frame(i)'s
	 * sp to get frame(i-1)'s sp and frame(i-2)'s pc
	 */

	/* Base save area consists of 4 words under SP */
	char *base_save = (char *)frame->sp;

	frame->pc = frame->next_pc;
	/* If next_pc = 0, indicates frame(i-1) is the last
	 * frame on the stack
	 */
	frame->next_pc = *((uint32_t *)(base_save - 16));
	frame->sp =  *((uint32_t *)(base_save - 12));

	/* Return true if both sp and pc of frame(i-1) are sane,
	 * false otherwise
	 */
	return (xtensa_stack_ptr_is_sane(frame->sp) &&
			xtensa_ptr_executable((void *)
				xtensa_cpu_process_stack_pc(frame->pc)));
}

int xtensa_backtrace_print(int depth, int *interrupted_stack)
{
	/* Check arguments */
	if (depth <= 0) {
		return -1;
	}

	/* Initialize stk_frame with first frame of stack */
	struct xtensa_backtrace_frame_t stk_frame;

	xtensa_backtrace_get_start(&(stk_frame.pc), &(stk_frame.sp),
			&(stk_frame.next_pc), interrupted_stack);
	__asm__ volatile("l32i a4, a3, 0");
	__asm__ volatile("l32i a4, a4, 4");
	__asm__ volatile("mov %0, a4" : "=r"(cause));
	if (cause != EXCCAUSE_INSTR_PROHIBITED) {
		mask = stk_frame.pc & 0xc0000000;
	}
	printk("\r\n\r\nBacktrace:");
	printk("0x%08x:0x%08x ",
			xtensa_cpu_process_stack_pc(stk_frame.pc),
			stk_frame.sp);

	/* Check if first frame is valid */
	bool corrupted = !(xtensa_stack_ptr_is_sane(stk_frame.sp) &&
				(xtensa_ptr_executable((void *)
				xtensa_cpu_process_stack_pc(stk_frame.pc)) ||
	/* Ignore the first corrupted PC in case of InstrFetchProhibited */
				cause == EXCCAUSE_INSTR_PROHIBITED));

	while (depth-- > 0 && stk_frame.next_pc != 0 && !corrupted) {
		/* Get previous stack frame */
		if (!xtensa_backtrace_get_next_frame(&stk_frame)) {
			corrupted = true;
		}
		printk("0x%08x:0x%08x ", xtensa_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
	}

	/* Print backtrace termination marker */
	int ret = 0;

	if (corrupted) {
		printk(" |<-CORRUPTED");
		ret =  -1;
	} else if (stk_frame.next_pc != 0) {    /* Backtrace continues */
		printk(" |<-CONTINUES");
	}
	printk("\r\n\r\n");
	return ret;
}
