/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <kernel.h>
#include <sys/printk.h>
#include <sys/__assert.h>
#include <arch/arm/aarch32/cortex_m/cmsis.h>

#if !defined(CONFIG_CPU_CORTEX_M)
  #error test can only run on Cortex-M MCUs
#endif

#if defined(CONFIG_ARMV8_1_M_MAINLINE)
/*
 * For ARMv8.1-M, the FPSCR[18:16] LTPSIZE field may always read 0b010 if MVE
 * is not implemented, so mask it when validating the value of the FPSCR.
 */
#define FPSCR_MASK		(~FPU_FPDSCR_LTPSIZE_Msk)
#else
#define FPSCR_MASK		(0xffffffffU)
#endif

extern K_THREAD_STACK_DEFINE(z_main_stack, CONFIG_MAIN_STACK_SIZE);

static volatile int test_flag;
static unsigned int expected_reason;

void arm_isr_handler(const void *args)
{
	ARG_UNUSED(args);

	test_flag++;
}

void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *pEsf)
{
	printk("Caught system error -- reason %d\n", reason);

	if (expected_reason == -1) {
		printk("Was not expecting a crash\n");
		k_fatal_halt(reason);
	}

	if (reason != expected_reason) {
		printk("Wrong crash type got %d expected %d\n", reason,
			expected_reason);
		k_fatal_halt(reason);
	}

	expected_reason = -1;
}

void test_main(void)
{
	printk("ARM no-multithreading test\n");

	uint32_t psp = (uint32_t)__get_PSP();
	uint32_t main_stack_base = (uint32_t)Z_THREAD_STACK_BUFFER(z_main_stack);
	uint32_t main_stack_top = (uint32_t)(Z_THREAD_STACK_BUFFER(z_main_stack) +
		K_THREAD_STACK_SIZEOF(z_main_stack));

	__ASSERT(
		(psp >= main_stack_base) && (psp <= main_stack_top),
			"PSP out of bounds: 0x%x (0x%x - 0x%x)",
			psp, main_stack_base, main_stack_top);

#if defined(CONFIG_FPU)
	__ASSERT((__get_FPSCR() & FPSCR_MASK) == 0,
		"FPSCR not zero (0x%x)", __get_FPSCR());
#endif

#if defined(CONFIG_BUILTIN_STACK_GUARD)
	uint32_t psplim = (uint32_t)__get_PSPLIM();
	__ASSERT(
		(psplim == main_stack_base),
			"PSPLIM not set to main stack base: (0x%x)",
			psplim);
#endif

	int key = arch_irq_lock();
	__ASSERT(arch_irq_unlocked(key),
		"IRQs locked in main()");

	arch_irq_unlock(key);

	/* Verify activating the PendSV IRQ triggers a K_ERR_SPURIOUS_IRQ */
	expected_reason = K_ERR_CPU_EXCEPTION;
	SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
	__DSB();
	__ISB();

	/* Determine an NVIC IRQ line that is not currently in use. */
	int i, flag = test_flag;

	__ASSERT(flag == 0, "Test flag not initialized to 0\n");

	for (i = CONFIG_NUM_IRQS - 1; i >= 0; i--) {
		if (NVIC_GetEnableIRQ(i) == 0) {
			/*
			 * Interrupts configured statically with IRQ_CONNECT(.)
			 * are automatically enabled. NVIC_GetEnableIRQ()
			 * returning false, here, implies that the IRQ line is
			 * either not implemented or it is not enabled, thus,
			 * currently not in use by Zephyr.
			 */

			/* Set the NVIC line to pending. */
			NVIC_SetPendingIRQ(i);

			if (NVIC_GetPendingIRQ(i)) {
				/* If the NVIC line is pending, it is
				 * guaranteed that it is implemented; clear the
				 * line.
				 */
				NVIC_ClearPendingIRQ(i);

				if (!NVIC_GetPendingIRQ(i)) {
					/*
					 * If the NVIC line can be successfully
					 * un-pended, it is guaranteed that it
					 * can be used for software interrupt
					 * triggering. Trigger it.
					 */
					NVIC_SetPendingIRQ(i);
					break;
				}
			}
		}
	}

	if (i >= 0) {

		printk("Available IRQ line: %u\n", i);

		arch_irq_connect_dynamic(i, 0 /* highest priority */,
			arm_isr_handler,
			NULL,
			0);

		NVIC_EnableIRQ(i);

		__DSB();
		__ISB();

		flag = test_flag;

		__ASSERT(flag > 0, "Test flag not set by IRQ\n");

		printk("ARM no multithreading test successful\n");
	} else {
		__ASSERT(0, "No available IRQ line to use in the test\n");
	}
}
