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

/**
 * @file
 *
 * This test case verifies the correctness of irq_offload(), an important
 * routine used in many other test cases for running a function in interrupt
 * context, on the IRQ stack.
 *
 */
#include <zephyr.h>
#include <ztest.h>
#include <kernel_structs.h>
#include <irq_offload.h>

volatile uint32_t sentinel;
#define SENTINEL_VALUE 0xDEADBEEF

static void offload_function(const void *param)
{
	uint32_t x = POINTER_TO_INT(param);

	/* Make sure we're in IRQ context */
	zassert_true(k_is_in_isr(), "Not in IRQ context!");

	sentinel = x;
}

/**
 * @brief Verify thread context
 *
 * @ingroup kernel_interrupt_tests
 *
 * @details Check whether offloaded running function is in interrupt
 * context, on the IRQ stack or not.
 */
void test_irq_offload(void)
{
	/* Simple validation of nested locking. */
	unsigned int key1, key2;

	key1 = arch_irq_lock();
	zassert_true(arch_irq_unlocked(key1),
		     "IRQs should have been unlocked, but key is 0x%x\n",
		     key1);
	key2 = arch_irq_lock();
	zassert_false(arch_irq_unlocked(key2),
		      "IRQs should have been locked, but key is 0x%x\n",
		      key2);
	arch_irq_unlock(key2);
	arch_irq_unlock(key1);

	/**TESTPOINT: Offload to IRQ context*/
	irq_offload(offload_function, (const void *)SENTINEL_VALUE);

	zassert_equal(sentinel, SENTINEL_VALUE,
		      "irq_offload() didn't work properly");
}

/**
 * @brief Test the arch_nop() by invoking and measure it.
 *
 * @details This test is mainly for coverage of the code. arch_nop()
 * is a special implementation and it will behave differently on
 * different platforms. By the way, this also measures how many
 * cycles it spends for platforms that support it.
 *
 * FYI: The potential uses of arch_nop() could be:
 * - Code alignment: Although in this case it's much more likely the
 *   compiler doing so (or you're in an assembly file, in which case
 *   you're not calling arch_nop() anyway). And this would require
 *   that arch_nop() be ALWAYS_INLINE.
 * - Giving you a guaranteed place to put a breakpoint / trace trigger
 *   / etc. when debugging. This is on main usage of arch_nop(); it
 *   inherently is generally debugging code removed before actually
 *   pushing.
 * - Giving you a guaranteed place to put a patchpoint. E.g. ARMv7
 *   allows nop (and a few other instructions) to be modified
 *   concurrently with execution, but not most other instructions.
 * - Delaying a few instructions, e.g. for tight timing loops on
 *   M-cores.
 *
 * Our test here mainly aims at the 4th scenario mentioned above but
 * also potentially tests the 1st scenario. So no optimization here to
 * prevent arch_nop() has optimized by the compiler is necessary.
 *
 * @ingroup kernel_common_tests
 *
 * @see arch_nop()
 */
__no_optimization void test_nop(void)
{
	uint32_t t_get_time, t_before, t_after, diff;

	t_before = k_cycle_get_32();
	t_after = k_cycle_get_32();

	/* calculate time spent between two k_cycle_get_32() call */
	t_get_time = t_after - t_before;

	printk("time k_cycle_get_32() takes %d cycles\n", t_get_time);

	/*
	 *  If two k_cycle_get_32() call take zero cycle here, this
	 *  means it cannot comes out a correct result, in these
	 *  case, we skip this test, such as native posix.
	 */
	if (t_get_time == 0) {
		ztest_test_skip();
	}

	t_before = k_cycle_get_32();

	arch_nop();

#if defined(CONFIG_RISCV)
	/* do 2 nop instructions more to cost cycles */
	arch_nop();
	arch_nop();
#if defined(CONFIG_RISCV_MACHINE_TIMER_SYSTEM_CLOCK_DIVIDER)
	/* When the case machine timer clock uses the divided system clock,
	 * k_cycle_get_32() can't measure accurately how many cycles elapsed.
	 *
	 * For example, use the value as timer clock obtained by dividing
	 * the system clock by 4.
	 * In this case, measuring a duration with k_cycle_get32() has up to 3
	 * (4-1) cycles systematic error.
	 *
	 * To run this test, we need to insert an appropriate of nops
	 * with consideration for the errors.
	 * 'nop' can not repeat with for loop.
	 * Must insert as separated statement.
	 * But we don't have a convenient function such as
	 * BOOST_PP_REPEAT in C++.
	 *
	 * At this time, Implementing a generic test is a bit difficult.
	 * Skipping this test in the case.
	 */
	ztest_test_skip();
#endif
#elif defined(CONFIG_ARC)
	/* do 7 nop instructions more to cost cycles */
	arch_nop();
	arch_nop();
	arch_nop();
	arch_nop();
	arch_nop();
	arch_nop();
	arch_nop();
#elif defined(CONFIG_SPARC)
	/* do 9 nop instructions more to cost cycles */
	arch_nop();
	arch_nop();
	arch_nop();
	arch_nop();
	arch_nop();
	arch_nop();
	arch_nop();
	arch_nop();
	arch_nop();
#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)			\
	|| defined(CONFIG_BOARD_EHL_CRB) || (CONFIG_BOARD_UP_SQUARED)	\
	|| (CONFIG_SOC_FAMILY_INTEL_ADSP)
	/* ARM states the following:
	 * No Operation does nothing, other than advance the value of
	 * the program counter by 4. This instruction can be used for
	 * instruction alignment purposes.
	 * Note: The timing effects of including a NOP instruction in
	 * a program are not guaranteed. It can increase execution time
	 * ,leave it unchanged, or even reduce it. Therefore, NOP
	 * instructions are not suitable for timing loops.
	 *
	 * So we skip this test, it will get a negative cycles.
	 *
	 * And on physical EHL_CRB, up squared and INTEL ADSP boards,
	 * we also got a similar situation, we skip the check as well.
	 */
	ztest_test_skip();
#endif

	t_after = k_cycle_get_32();

	/* Calculate delta time of arch_nop(). */
	diff = t_after - t_before - t_get_time;
	printk("arch_nop() takes %d cycles\n", diff);

	/* An arch_nop() call should spend actual cpu cycles */
	zassert_true(diff > 0,
			"arch_nop() takes %d cpu cycles", diff);
}

static struct k_timer nestoff_timer;
static bool timer_executed, nested_executed;

void nestoff_offload(const void *parameter)
{
	nested_executed = true;
}


static void nestoff_timer_fn(struct k_timer *timer)
{
	zassert_false(nested_executed, "nested irq_offload ran too soon");
	irq_offload(nestoff_offload, NULL);
	zassert_true(nested_executed, "nested irq_offload did not run");

	/* Set this last, to be sure we return to this context and not
	 * the enclosing interrupt
	 */
	timer_executed = true;
}


/* Invoke irq_offload() from an interrupt and verify that the
 * resulting nested interrupt doesn't explode
 */
void test_nested_irq_offload(void)
{
	if (!IS_ENABLED(CONFIG_IRQ_OFFLOAD_NESTED)) {
		ztest_test_skip();
	}

	k_timer_init(&nestoff_timer, nestoff_timer_fn, NULL);

	zassert_false(timer_executed, "timer ran too soon");
	zassert_false(nested_executed, "nested irq_offload ran too soon");

	k_timer_start(&nestoff_timer, K_TICKS(1), K_FOREVER);
	k_timer_status_sync(&nestoff_timer);

	zassert_true(timer_executed, "timer did not run");
	zassert_true(nested_executed, "nested irq_offload did not run");
}
