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

#include <zephyr.h>
#include <ztest.h>
#include <tc_util.h>
#include <kernel_structs.h>
#include <irq_offload.h>
#include <kswap.h>

#if defined(CONFIG_X86) && defined(CONFIG_X86_MMU)
#define STACKSIZE (8192)
#else
#define  STACKSIZE (2048)
#endif
#define MAIN_PRIORITY 7
#define PRIORITY 5

static K_THREAD_STACK_DEFINE(alt_stack, STACKSIZE);

#ifdef CONFIG_STACK_SENTINEL
#define OVERFLOW_STACKSIZE (STACKSIZE / 2)
static k_thread_stack_t *overflow_stack =
		alt_stack + (STACKSIZE - OVERFLOW_STACKSIZE);
#else
#define OVERFLOW_STACKSIZE STACKSIZE
#endif

static struct k_thread alt_thread;
volatile int rv;

static volatile int crash_reason;

/* On some architectures, k_thread_abort(_current) will return instead
 * of _Swap'ing away.
 *
 * On ARM the PendSV exception is queued and immediately fires upon
 * completing the exception path; the faulting thread is never run
 * again.
 *
 * On Xtensa/asm2 the handler is running in interrupt context and on
 * the interrupt stack and needs to return through the interrupt exit
 * code.
 *
 * In both cases the thread is guaranteed never to run again once we
 * return from the _SysFatalErrorHandler().
 */
#if !(defined(CONFIG_ARM) || defined(CONFIG_XTENSA_ASM2) || defined(CONFIG_ARC))
#define ERR_IS_NORETURN 1
#endif

#ifdef ERR_IS_NORETURN
FUNC_NORETURN
#endif
void _SysFatalErrorHandler(unsigned int reason, const NANO_ESF *pEsf)
{
	TC_PRINT("Caught system error -- reason %d\n", reason);
	crash_reason = reason;

	k_thread_abort(_current);
#ifdef ERR_IS_NORETURN
	CODE_UNREACHABLE;
#endif
}

void alt_thread1(void)
{
#if defined(CONFIG_X86)
	__asm__ volatile ("ud2");
#elif defined(CONFIG_NIOS2)
	__asm__ volatile ("trap");
#elif defined(CONFIG_ARC)
	__asm__ volatile ("swi");
#else
	/* Triggers usage fault on ARM, illegal instruction on RISCV32
	 * and xtensa
	 */
	{
		int illegal = 0;
		((void(*)(void))&illegal)();
	}
#endif
	rv = TC_FAIL;
}


void alt_thread2(void)
{
	int key;

	key = irq_lock();
	k_oops();
	TC_ERROR("SHOULD NEVER SEE THIS\n");
	rv = TC_FAIL;
	irq_unlock(key);
}

void alt_thread3(void)
{
	int key;

	key = irq_lock();
	k_panic();
	TC_ERROR("SHOULD NEVER SEE THIS\n");
	rv = TC_FAIL;
	irq_unlock(key);
}

void blow_up_stack(void)
{
	char buf[OVERFLOW_STACKSIZE];

	TC_PRINT("posting %zu bytes of junk to stack...\n", sizeof(buf));
	memset(buf, 0xbb, sizeof(buf));
}

void stack_thread1(void)
{
	/* Test that stack overflow check due to timer interrupt works */
	blow_up_stack();
	TC_PRINT("busy waiting...\n");
	k_busy_wait(1024 * 1024);
	TC_ERROR("should never see this\n");
	rv = TC_FAIL;
}


void stack_thread2(void)
{
	int key = irq_lock();

	/* Test that stack overflow check due to swap works */
	blow_up_stack();
	TC_PRINT("swapping...\n");
	_Swap(irq_lock());
	TC_ERROR("should never see this\n");
	rv = TC_FAIL;
	irq_unlock(key);
}


void test_fatal(void)
{
	int expected_reason;

#if defined(CONFIG_ARCH_POSIX)
	ARG_UNUSED(expected_reason);
	ARG_UNUSED(overflow_stack);
#endif

	rv = TC_PASS;

	/*
	 * Main thread(test_main) priority was 10 but ztest thread runs at
	 * priority -1. To run the test smoothly make both main and ztest
	 * threads run at same priority level.
	 */
	k_thread_priority_set(_current, K_PRIO_PREEMPT(MAIN_PRIORITY));

#ifndef CONFIG_ARCH_POSIX
	TC_PRINT("test alt thread 1: generic CPU exception\n");
	k_thread_create(&alt_thread, alt_stack,
			K_THREAD_STACK_SIZEOF(alt_stack),
			(k_thread_entry_t)alt_thread1,
			NULL, NULL, NULL, K_PRIO_COOP(PRIORITY), 0,
			K_NO_WAIT);
	zassert_not_equal(rv, TC_FAIL, "thread was not aborted\n");
#else
	/*
	 * We want the native OS to handle segfaults so we can debug it
	 * with the normal linux tools
	 */
	TC_PRINT("test alt thread 1: skipped for POSIX ARCH\n");
#endif

	TC_PRINT("test alt thread 2: initiate kernel oops\n");
	k_thread_create(&alt_thread, alt_stack,
			K_THREAD_STACK_SIZEOF(alt_stack),
			(k_thread_entry_t)alt_thread2,
			NULL, NULL, NULL, K_PRIO_COOP(PRIORITY), 0,
			K_NO_WAIT);
	k_thread_abort(&alt_thread);
	zassert_equal(crash_reason, _NANO_ERR_KERNEL_OOPS,
		      "bad reason code got %d expected %d\n",
		      crash_reason, _NANO_ERR_KERNEL_OOPS);
	zassert_not_equal(rv, TC_FAIL, "thread was not aborted\n");

	TC_PRINT("test alt thread 3: initiate kernel panic\n");
	k_thread_create(&alt_thread, alt_stack,
			K_THREAD_STACK_SIZEOF(alt_stack),
			(k_thread_entry_t)alt_thread3,
			NULL, NULL, NULL, K_PRIO_COOP(PRIORITY), 0,
			K_NO_WAIT);
	k_thread_abort(&alt_thread);
	zassert_equal(crash_reason, _NANO_ERR_KERNEL_PANIC,
		      "bad reason code got %d expected %d\n",
		      crash_reason, _NANO_ERR_KERNEL_PANIC);
	zassert_not_equal(rv, TC_FAIL, "thread was not aborted\n");

#ifndef CONFIG_ARCH_POSIX
	TC_PRINT("test stack overflow - timer irq\n");
#ifdef CONFIG_STACK_SENTINEL
	/* When testing stack sentinel feature, the overflow stack is a
	 * smaller section of alt_stack near the end.
	 * In this way when it gets overflowed by blow_up_stack() we don't
	 * corrupt anything else and prevent the test case from completing.
	 */
	k_thread_create(&alt_thread, overflow_stack, OVERFLOW_STACKSIZE,
#else
	k_thread_create(&alt_thread, alt_stack,
			K_THREAD_STACK_SIZEOF(alt_stack),
#endif
			(k_thread_entry_t)stack_thread1,
			NULL, NULL, NULL, K_PRIO_PREEMPT(PRIORITY), 0,
			K_NO_WAIT);

	expected_reason = _NANO_ERR_STACK_CHK_FAIL;

	zassert_equal(crash_reason, expected_reason,
		      "bad reason code got %d expected %d\n",
		      crash_reason, expected_reason);
	zassert_not_equal(rv, TC_FAIL, "thread was not aborted\n");

	/* Stack sentinel has to be invoked, make sure it happens during
	 * a context switch. Also ensure HW-based solutions can run more
	 * than once.
	 */
	TC_PRINT("test stack overflow - swap\n");
#ifdef CONFIG_STACK_SENTINEL
	k_thread_create(&alt_thread, overflow_stack, OVERFLOW_STACKSIZE,
#else
	k_thread_create(&alt_thread, alt_stack,
			K_THREAD_STACK_SIZEOF(alt_stack),
#endif
			(k_thread_entry_t)stack_thread2,
			NULL, NULL, NULL, K_PRIO_PREEMPT(PRIORITY), 0,
			K_NO_WAIT);
	zassert_equal(crash_reason, _NANO_ERR_STACK_CHK_FAIL,
		      "bad reason code got %d expected %d\n",
		      crash_reason, _NANO_ERR_STACK_CHK_FAIL);

	zassert_not_equal(rv, TC_FAIL, "thread was not aborted\n");
#else
	TC_PRINT("test stack overflow - skipped for POSIX arch\n");
	/*
	 * We do not have a stack check for the posix ARCH
	 * again we relay on the native OS
	 */
#endif
}

/*test case main entry*/
void test_main(void)
{
	ztest_test_suite(fatal,
			ztest_unit_test(test_fatal));
	ztest_run_test_suite(fatal);
}
