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

#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/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

K_THREAD_STACK_DECLARE(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");
	}
}
