/*
 * Copyright (c) 2017, Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <misc/printk.h>
#include <string.h>
#include <xtensa-asm2.h>
#include <kernel.h>
#include <ksched.h>
#include <kernel_structs.h>
#include <kernel_internal.h>
#include <kswap.h>
#include <_soc_inthandlers.h>

void *xtensa_init_stack(int *stack_top,
			void (*entry)(void *, void *, void *),
			void *arg1, void *arg2, void *arg3)
{
	/* We cheat and shave 16 bytes off, the top four words are the
	 * A0-A3 spill area for the caller of the entry function,
	 * which doesn't exist.  It will never be touched, so we
	 * arrange to enter the function with a CALLINC of 1 and a
	 * stack pointer 16 bytes above the top, so its ENTRY at the
	 * start will decrement the stack pointer by 16.
	 */
	const int bsasz = BASE_SAVE_AREA_SIZE - 16;
	void **bsa = (void **) (((char *) stack_top) - bsasz);

	memset(bsa, 0, bsasz);

	bsa[BSA_PC_OFF/4] = _thread_entry;
	bsa[BSA_PS_OFF/4] = (void *)(PS_WOE | PS_UM | PS_CALLINC(1));

	/* Arguments to _thread_entry().  Remember these start at A6,
	 * which will be rotated into A2 by the ENTRY instruction that
	 * begins the C function.  And A4-A7 and A8-A11 are optional
	 * quads that live below the BSA!
	 */
	bsa[-1] = arg1;  /* a7 */
	bsa[-2] = entry; /* a6 */
	bsa[-3] = 0;     /* a5 */
	bsa[-4] = 0;     /* a4 */

	bsa[-5] = 0;     /* a11 */
	bsa[-6] = 0;     /* a10 */
	bsa[-7] = arg3;  /* a9 */
	bsa[-8] = arg2;  /* a8 */

	/* Finally push the BSA pointer and return the stack pointer
	 * as the handle
	 */
	bsa[-9] = bsa;
	return &bsa[-9];
}

/* This is a kernel hook, just a wrapper around other APIs.  Build
 * only if we're using asm2 as the core OS interface and not just as
 * utilities/testables.
 */
#ifdef CONFIG_XTENSA_ASM2
void _new_thread(struct k_thread *thread, k_thread_stack_t *stack, size_t sz,
		 k_thread_entry_t entry, void *p1, void *p2, void *p3,
		 int prio, unsigned int opts)
{
	char *base = K_THREAD_STACK_BUFFER(stack);
	char *top = base + sz;

	/* Align downward.  The API as specified requires a runtime check. */
	top = (char *)(((unsigned int)top) & ~3);

	_new_thread_init(thread, base, sz, prio, opts);

#ifdef CONFIG_THREAD_MONITOR
	top -= sizeof(struct __thread_entry);
	thread->entry = (void *)top;
	thread->entry->pEntry = entry;

	thread_monitor_init(thread);
#endif


	thread->switch_handle = xtensa_init_stack((void *)top, entry,
						  p1, p2, p3);
}
#endif

#ifdef CONFIG_XTENSA_ASM2
void _irq_spurious(void *arg)
{
	int irqs, ie;

	ARG_UNUSED(arg);

	__asm__ volatile("rsr.interrupt %0" : "=r"(irqs));
	__asm__ volatile("rsr.intenable %0" : "=r"(ie));
	printk(" ** Spurious INTERRUPT(s) %p, INTENABLE = %p\n",
	       (void *)irqs, (void *)ie);
	_NanoFatalErrorHandler(_NANO_ERR_RESERVED_IRQ, &_default_esf);
}
#endif

static void dump_stack(int *stack)
{
	int *bsa = *(int **)stack;

	printk(" **  A0 %p  SP %p  A2 %p  A3 %p\n",
	       (void *)bsa[BSA_A0_OFF/4], ((char *)bsa) + BASE_SAVE_AREA_SIZE,
	       (void *)bsa[BSA_A2_OFF/4], (void *)bsa[BSA_A3_OFF/4]);

	if (bsa - stack > 4) {
		printk(" **  A4 %p  A5 %p  A6 %p  A7 %p\n",
		       (void *)bsa[-4], (void *)bsa[-3],
		       (void *)bsa[-2], (void *)bsa[-1]);
	}

	if (bsa - stack > 8) {
		printk(" **  A8 %p  A9 %p A10 %p A11 %p\n",
		       (void *)bsa[-8], (void *)bsa[-7],
		       (void *)bsa[-6], (void *)bsa[-5]);
	}

	if (bsa - stack > 12) {
		printk(" ** A12 %p A13 %p A14 %p A15 %p\n",
		       (void *)bsa[-12], (void *)bsa[-11],
		       (void *)bsa[-10], (void *)bsa[-9]);
	}

#if XCHAL_HAVE_LOOPS
	printk(" ** LBEG %p LEND %p LCOUNT %p\n",
	       (void *)bsa[BSA_LBEG_OFF/4],
	       (void *)bsa[BSA_LEND_OFF/4],
	       (void *)bsa[BSA_LCOUNT_OFF/4]);

#endif

	printk(" ** SAR %p\n", (void *)bsa[BSA_SAR_OFF/4]);
}

#if CONFIG_XTENSA_ASM2
static inline void *restore_stack(void *interrupted_stack)
{
	if (!_is_preempt(_current) &&
	    !(_current->base.thread_state & _THREAD_DEAD)) {
		return interrupted_stack;
	}

	int key = irq_lock();

	_current->switch_handle = interrupted_stack;
	_current = _get_next_ready_thread();

	void *ret = _current->switch_handle;

	irq_unlock(key);

	_check_stack_sentinel();

	return ret;
}
#endif

/* The wrapper code lives here instead of in the python script that
 * generates _xtensa_handle_one_int*().  Seems cleaner, still kind of
 * ugly.
 */
#define DEF_INT_C_HANDLER(l)				\
void *xtensa_int##l##_c(void *interrupted_stack)	\
{							   \
	int irqs, m;					   \
	__asm__ volatile("rsr.interrupt %0" : "=r"(irqs)); \
							   \
	while ((m = _xtensa_handle_one_int##l(irqs))) {		\
		irqs ^= m;					\
		__asm__ volatile("wsr.intclear %0" : : "r"(m)); \
	}							\
	return restore_stack(interrupted_stack);		\
}

DEF_INT_C_HANDLER(2)
DEF_INT_C_HANDLER(3)
DEF_INT_C_HANDLER(4)
DEF_INT_C_HANDLER(5)
DEF_INT_C_HANDLER(6)
DEF_INT_C_HANDLER(7)

static inline DEF_INT_C_HANDLER(1)

/* C handler for level 1 exceptions/interrupts.  Hooked from the
 * DEF_EXCINT 1 vector declaration in assembly code.  This one looks
 * different because exceptions and interrupts land at the same
 * vector; other interrupt levels have their own vectors.
 */
void *xtensa_excint1_c(int *interrupted_stack)
{
	int cause, vaddr, *bsa = *(int **)interrupted_stack;

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

	if (cause == EXCCAUSE_LEVEL1_INTERRUPT) {

		return xtensa_int1_c(interrupted_stack);

	} else if (cause == EXCCAUSE_SYSCALL) {

		/* Just report it to the console for now */
		printk(" ** SYSCALL PS %p PC %p\n",
		       (void *)bsa[BSA_PS_OFF/4], (void *)bsa[BSA_PC_OFF/4]);
		dump_stack(interrupted_stack);

		/* Xtensa exceptions don't automatically advance PC,
		 * have to skip the SYSCALL instruction manually or
		 * else it will just loop forever
		 */
		bsa[BSA_PC_OFF/4] += 3;

	} else {
		__asm__ volatile("rsr.excvaddr %0" : "=r"(vaddr));

		/* Wouldn't hurt to translate EXCCAUSE to a string for
		 * the user...
		 */
		printk(" ** FATAL EXCEPTION\n");
		printk(" ** CPU %d EXCCAUSE %d PS %p PC %p VADDR %p\n",
		       _arch_curr_cpu()->id, cause, (void *)bsa[BSA_PS_OFF/4],
		       (void *)bsa[BSA_PC_OFF/4], (void *)vaddr);

		dump_stack(interrupted_stack);

		/* FIXME: legacy xtensa port reported "HW" exception
		 * for all unhandled exceptions, which seems incorrect
		 * as these are software errors.  Should clean this
		 * up.
		 */
		_NanoFatalErrorHandler(_NANO_ERR_HW_EXCEPTION, &_default_esf);
	}

	return restore_stack(interrupted_stack);
}

