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

#include <ztest.h>
#include <arch/cpu.h>
#include <arch/arm/aarch32/cortex_m/cmsis.h>
#include <kernel_structs.h>
#include <offsets_short_arch.h>
#include <ksched.h>

#if !defined(__GNUC__)
#error __FILE__ goes only with Cortex-M GCC
#endif

#if !defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) && \
	!defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
#error "Unsupported architecture"
#endif

#if defined(CONFIG_USERSPACE)

#define PRIORITY 0

static struct k_thread user_thread;
static K_THREAD_STACK_DEFINE(user_thread_stack, 1024);

#include <syscall_handler.h>
#include "test_syscalls.h"

void z_impl_test_arm_user_syscall(void)
{
	/* User thread system call
	 *
	 * Verify the following
	 * - mode variable indicates PRIV mode
	 * - the PSP is inside the thread's privileged stack
	 * - PSPLIM register guards the privileged stack
	 * - MSPLIM register still guards the interrupt stack
	 */
	zassert_true((_current->arch.mode & CONTROL_nPRIV_Msk) == 0,
	"mode variable not set to PRIV mode in system call\n");

	zassert_false(arch_is_user_context(),
	"arch_is_user_context() indicates nPRIV\n");

	zassert_true(
		((__get_PSP() >= _current->arch.priv_stack_start) &&
		(__get_PSP() < (_current->arch.priv_stack_start +
			CONFIG_PRIVILEGED_STACK_SIZE))),
	"Process SP outside thread privileged stack limits\n");

#if defined(CONFIG_BUILTIN_STACK_GUARD)
	zassert_true(__get_PSPLIM() == _current->arch.priv_stack_start,
	"PSPLIM not guarding the thread's privileged stack\n");
	zassert_true(__get_MSPLIM() == (u32_t)z_interrupt_stacks,
	"MSPLIM not guarding the interrupt stack\n");
#endif
}

static inline void z_vrfy_test_arm_user_syscall(void)
{
	z_impl_test_arm_user_syscall();
}
#include <syscalls/test_arm_user_syscall_mrsh.c>


void arm_isr_handler(void *args)
{
	/* Interrupt triggered while running a user thread
	 *
	 * Verify the following
	 * - mode variable indicates nPRIV mode
	 * - the PSP is inside the thread's default (user) stack
	 * - PSPLIM register is not set (applies on the second ISR call)
	 * - MSPLIM register still guards the interrupt stack
	 */

	zassert_true((_current->arch.mode & CONTROL_nPRIV_Msk) != 0,
	"mode variable not set to nPRIV mode for user thread\n");

	zassert_false(arch_is_user_context(),
	"arch_is_user_context() indicates nPRIV in ISR\n");

	zassert_true(
		((__get_PSP() >= _current->stack_info.start) &&
		(__get_PSP() < (_current->stack_info.start +
			_current->stack_info.size))),
	"Process SP outside thread stack limits\n");

	static int first_call = 1;

	if (first_call == 1) {
		first_call = 0;

		/* Trigger thread yield() manually */
		(void)irq_lock();
		z_move_thread_to_end_of_prio_q(_current);
		SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
		irq_unlock(0);

	} else if (first_call == 0) {
#if defined(CONFIG_BUILTIN_STACK_GUARD)
		/* Second ISR run occurs after thread context-switch.
		 * We expect PSPLIM to be clear at this point.
		 */
		zassert_true(__get_PSPLIM() == 0,
		"PSPLIM not clear\n");
		zassert_true(__get_MSPLIM() == (u32_t)z_interrupt_stacks,
		"MSPLIM not guarding the interrupt stack\n");
#endif
	}
}

static void user_thread_entry(u32_t irq_line)
{
	/* User Thread */
#if !defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
	ARG_UNUSED(irq_line);
#endif
	/* Trigger a system call to switch to supervisor thread
	 * mode and verify the thread state during system calls.
	 */
	test_arm_user_syscall();

#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)

	/*
	 * Trigger an ISR to switch to handler mode, to inspect
	 * the kernel structs and verify the thread state.
	 */
	TC_PRINT("USR Thread: IRQ Line: %u\n", (u32_t)irq_line);

	NVIC->STIR = irq_line;
	__DSB();
	__ISB();

	/* ISR is set to cause thread to context-switch -out and -in again.
	 * We inspect for a second time, to verlfy the status, after
	 * the user thread is switch back in.
	 */
	NVIC->STIR = irq_line;
	__DSB();
	__ISB();
#endif
}

void test_arm_syscalls(void)
{
	int i = 0;

	/* Supervisor Thread (ztest thread)
	 *
	 * Verify the following:
	 * - the "mode" variable indicates PRIV mode
	 * - arch_is_user_context() is negative
	 * - the PSP is inside the default thread stack
	 * - PSPLIM register guards the default stack
	 * - MSPLIM register guards the interrupt stack
	 */

	zassert_true((_current->arch.mode & CONTROL_nPRIV_Msk) == 0,
	"mode variable not set to PRIV mode for supervisor thread\n");

	zassert_false(arch_is_user_context(),
	"arch_is_user_context() indicates nPRIV\n");

	zassert_true(
		((__get_PSP() >= _current->stack_info.start) &&
		(__get_PSP() < (_current->stack_info.start +
			_current->stack_info.size))),
	"Process SP outside thread stack limits\n");

#if defined(CONFIG_BUILTIN_STACK_GUARD)
	zassert_true(__get_PSPLIM() == _current->stack_info.start,
	"PSPLIM not guarding the default stack\n");
	zassert_true(__get_MSPLIM() == (u32_t)z_interrupt_stacks,
	"MSPLIM not guarding the interrupt stack\n");
#endif

#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
	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.
				 */
				break;
			}
		}
	}

	zassert_true(i >= 0,
		 "No available IRQ line to use in the test\n");

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

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

	NVIC_ClearPendingIRQ(i);
	NVIC_EnableIRQ(i);

	/* Allow the user thread to trigger an interrupt;
	 * this is *ONLY* done for testing purposes, here,
	 * i.e. to allow the inspection of the thread state
	 * while running in user mode.
	 */
	 SCB->CCR |= SCB_CCR_USERSETMPEND_Msk;
#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE*/

	/* Create and switch to a user thread, passing
	 * as argument the IRQ line to used in the test.
	 */
	k_thread_create(&user_thread,
		user_thread_stack,
		K_THREAD_STACK_SIZEOF(user_thread_stack),
		(k_thread_entry_t)user_thread_entry,
		(u32_t *)i, NULL, NULL,
		K_PRIO_COOP(PRIORITY), K_USER,
		K_NO_WAIT);
}
#endif /* CONFIG_USERSPACE */
/**
 * @}
 */
