/* context.c - test context and thread APIs */

/*
 * Copyright (c) 2012-2015 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * DESCRIPTION
 * This module tests the following CPU and thread related routines:
 * k_thread_create, k_yield(), k_is_in_isr(),
 * k_current_get(), k_cpu_idle(), k_cpu_atomic_idle(),
 * irq_lock(), irq_unlock(),
 * irq_offload(), irq_enable(), irq_disable(),
 */

#include <tc_util.h>
#include <kernel_structs.h>
#include <arch/cpu.h>
#include <irq_offload.h>

#include <util_test_common.h>

/*
 * Include board.h from platform to get IRQ number.
 * NOTE: Cortex-M does not need IRQ numbers
 */
#if !defined(CONFIG_CPU_CORTEX_M)
#include <board.h>
#endif

#define THREAD_STACKSIZE    (384 + CONFIG_TEST_EXTRA_STACKSIZE)
#define THREAD_PRIORITY     4

#define THREAD_SELF_CMD    0
#define EXEC_CTX_TYPE_CMD  1

#define UNKNOWN_COMMAND    -1

/*
 * Get the timer type dependent IRQ number. If timer type
 * is not defined in platform, generate an error
 */
#if defined(CONFIG_HPET_TIMER)
#define TICK_IRQ CONFIG_HPET_TIMER_IRQ
#elif defined(CONFIG_LOAPIC_TIMER)
#if defined(CONFIG_LOAPIC)
#define TICK_IRQ CONFIG_LOAPIC_TIMER_IRQ
#else
/* MVIC case */
#define TICK_IRQ CONFIG_MVIC_TIMER_IRQ
#endif
#elif defined(CONFIG_XTENSA)
#include <xtensa_timer.h>
#define TICK_IRQ XT_TIMER_INTNUM
#elif defined(CONFIG_ALTERA_AVALON_TIMER)
#define TICK_IRQ TIMER_0_IRQ
#elif defined(CONFIG_ARCV2_TIMER)
#define TICK_IRQ IRQ_TIMER0
#elif defined(CONFIG_PULPINO_TIMER)
#define TICK_IRQ PULP_TIMER_A_CMP_IRQ
#elif defined(CONFIG_RISCV_MACHINE_TIMER)
#define TICK_IRQ RISCV_MACHINE_TIMER_IRQ
#elif defined(CONFIG_CPU_CORTEX_M)
/*
 * The Cortex-M use the SYSTICK exception for the system timer, which is
 * not considered an IRQ by the irq_enable/Disable APIs.
 */
#else
/* generate an error */
#error Timer type is not defined for this platform
#endif

/* Nios II and RISCV32 without CONFIG_RISCV_HAS_CPU_IDLE
 * do have a power saving instruction, so k_cpu_idle() returns immediately
 */
#if !defined(CONFIG_NIOS2) && \
	(!defined(CONFIG_RISCV32) || defined(CONFIG_RISCV_HAS_CPU_IDLE))
#define HAS_POWERSAVE_INSTRUCTION
#endif



extern u32_t _tick_get_32(void);
extern s64_t _tick_get(void);

typedef struct {
	int command;            /* command to process   */
	int error;              /* error value (if any) */
	union {
		void *data;     /* pointer to data to use or return */
		int value;      /* value to be passed or returned   */
	};
} ISR_INFO;

typedef int (*disable_int_func) (int);
typedef void (*enable_int_func) (int);

static struct k_sem sem_thread;
static struct k_timer timer;
static struct k_sem reply_timeout;
struct k_fifo timeout_order_fifo;

static int thread_detected_error;
static int thread_evidence;

static K_THREAD_STACK_DEFINE(thread_stack1, THREAD_STACKSIZE);
static K_THREAD_STACK_DEFINE(thread_stack2, THREAD_STACKSIZE);
static struct k_thread thread_data1;
static struct k_thread thread_data2;

static ISR_INFO isr_info;

/**
 *
 * @brief Handler to perform various actions from within an ISR context
 *
 * This routine is the ISR handler for isr_handler_trigger().  It performs
 * the command requested in <isr_info.command>.
 *
 * @return N/A
 */
static void isr_handler(void *data)
{
	ARG_UNUSED(data);

	switch (isr_info.command) {
	case THREAD_SELF_CMD:
		isr_info.data = (void *)k_current_get();
		break;

	case EXEC_CTX_TYPE_CMD:
		if (k_is_in_isr()) {
			isr_info.value = K_ISR;
			break;
		}

		if (_current->base.prio < 0) {
			isr_info.value = K_COOP_THREAD;
			break;
		}

		isr_info.value = K_PREEMPT_THREAD;

		break;

	default:
		isr_info.error = UNKNOWN_COMMAND;
		break;
	}
}

static void isr_handler_trigger(void)
{
	irq_offload(isr_handler, NULL);
}

/**
 *
 * @brief Initialize kernel objects
 *
 * This routine initializes the kernel objects used in this module's tests.
 *
 * @return TC_PASS
 */
static int kernel_init_objects(void)
{
	k_sem_init(&sem_thread, 0, UINT_MAX);
	k_sem_init(&reply_timeout, 0, UINT_MAX);
	k_timer_init(&timer, NULL, NULL);
	k_fifo_init(&timeout_order_fifo);

	return TC_PASS;
}

#ifdef HAS_POWERSAVE_INSTRUCTION
/**
 *
 * @brief Test the k_cpu_idle() routine
 *
 * This tests the k_cpu_idle() routine.  The first thing it does is align to
 * a tick boundary.  The only source of interrupts while the test is running is
 * expected to be the tick clock timer which should wake the CPU.  Thus after
 * each call to k_cpu_idle(), the tick count should be one higher.
 *
 * @return TC_PASS on success
 * @return TC_FAIL on failure
 */
static int test_kernel_cpu_idle(int atomic)
{
	int tms, tms2;;         /* current time in millisecond */
	int i;                  /* loop variable */

	/* Align to a "ms boundary". */
	tms = k_uptime_get_32();
	while (tms == k_uptime_get_32()) {
	}

	tms = k_uptime_get_32();
	for (i = 0; i < 5; i++) {       /* Repeat the test five times */
		if (atomic) {
			unsigned int key = irq_lock();

			k_cpu_atomic_idle(key);
		} else {
			k_cpu_idle();
		}
		/* calculating milliseconds per tick*/
		tms += sys_clock_us_per_tick / USEC_PER_MSEC;
		tms2 = k_uptime_get_32();
		if (tms2 < tms) {
			TC_ERROR("Bad ms per tick value computed, got %d which is less than %d\n",
				 tms2, tms);
			return TC_FAIL;
		}
	}
	return TC_PASS;
}
#endif

/**
 *
 * @brief A wrapper for irq_lock()
 *
 * @return irq_lock() return value
 */
int irq_lock_wrapper(int unused)
{
	ARG_UNUSED(unused);

	return irq_lock();
}

/**
 *
 * @brief A wrapper for irq_unlock()
 *
 * @return N/A
 */
void irq_unlock_wrapper(int imask)
{
	irq_unlock(imask);
}

/**
 *
 * @brief A wrapper for irq_disable()
 *
 * @return <irq>
 */
int irq_disable_wrapper(int irq)
{
	irq_disable(irq);
	return irq;
}

/**
 *
 * @brief A wrapper for irq_enable()
 *
 * @return N/A
 */
void irq_enable_wrapper(int irq)
{
	irq_enable(irq);
}

/**
 *
 * @brief Test routines for disabling and enabling ints
 *
 * This routine tests the routines for disabling and enabling interrupts.
 * These include irq_lock() and irq_unlock(), irq_disable() and irq_enable().
 *
 * @return TC_PASS on success
 * @return TC_FAIL on failure
 */
static int test_kernel_interrupts(disable_int_func disable_int,
				  enable_int_func enable_int, int irq)
{
	unsigned long long count = 0;
	unsigned long long i = 0;
	int tick;
	int tick2;
	int imask;

	/* Align to a "tick boundary" */
	tick = _tick_get_32();
	while (_tick_get_32() == tick) {
	}

	tick++;
	while (_tick_get_32() == tick) {
		count++;
	}

	/*
	 * Inflate <count> so that when we loop later, many ticks should have
	 * elapsed during the loop.  This later loop will not exactly match the
	 * previous loop, but it should be close enough in structure that when
	 * combined with the inflated count, many ticks will have passed.
	 */

	count <<= 4;

	imask = disable_int(irq);
	tick = _tick_get_32();
	for (i = 0; i < count; i++) {
		_tick_get_32();
	}

	tick2 = _tick_get_32();

	/*
	 * Re-enable interrupts before returning (for both success and failure
	 * cases).
	 */

	enable_int(imask);

	if (tick2 != tick) {
		TC_ERROR("tick advanced with interrupts locked\n");
		return TC_FAIL;
	}

	/* Now repeat with interrupts unlocked. */
	for (i = 0; i < count; i++) {
		_tick_get_32();
	}

	tick2 = _tick_get_32();
	if (tick == tick2) {
		TC_ERROR("tick didn't advance as expected\n");
		return TC_FAIL;
	}

	return TC_PASS;
}

/**
 *
 * @brief Test some context routines from a preemptible thread
 *
 * This routines tests the k_current_get() and
 * k_is_in_isr() routines from both a preemptible thread  and an ISR (that
 * interrupted a preemptible thread). Checking those routines with cooperative
 * threads are done elsewhere.
 *
 * @return TC_PASS on success
 * @return TC_FAIL on failure
 */
static int test_kernel_ctx_task(void)
{
	k_tid_t self_thread_id;

	TC_PRINT("Testing k_current_get() from an ISR and task\n");

	self_thread_id = k_current_get();
	isr_info.command = THREAD_SELF_CMD;
	isr_info.error = 0;
	/* isr_info is modified by the isr_handler routine */
	isr_handler_trigger();

	if (isr_info.error) {
		TC_ERROR("ISR detected an error\n");
		return TC_FAIL;
	}

	if (isr_info.data != (void *)self_thread_id) {
		TC_ERROR("ISR context ID mismatch\n");
		return TC_FAIL;
	}

	TC_PRINT("Testing k_is_in_isr() from an ISR\n");
	isr_info.command = EXEC_CTX_TYPE_CMD;
	isr_info.error = 0;
	isr_handler_trigger();

	if (isr_info.error) {
		TC_ERROR("ISR detected an error\n");
		return TC_FAIL;
	}

	if (isr_info.value != K_ISR) {
		TC_ERROR("isr_info.value was not K_ISR\n");
		return TC_FAIL;
	}

	TC_PRINT("Testing k_is_in_isr() from a preemptible thread\n");
	if (k_is_in_isr()) {
		TC_ERROR("Should not be in ISR context\n");
		return TC_FAIL;
	}
	if (_current->base.prio < 0) {
		TC_ERROR("Current thread should have preemptible priority\n");
		return TC_FAIL;
	}

	return TC_PASS;
}

/**
 *
 * @brief Test the various context/thread routines from a cooperative thread
 *
 * This routines tests the k_current_get and
 * k_is_in_isr() routines from both a thread and an ISR (that interrupted a
 * cooperative thread).  Checking those routines with preemptible threads are
 * done elsewhere.
 *
 * This routine may set <thread_detected_error> to the following values:
 *   1 - if thread ID matches that of the task
 *   2 - if thread ID taken during ISR does not match that of the thread
 *   3 - k_is_in_isr() when called from an ISR is false
 *   4 - k_is_in_isr() when called from a thread is true
 *   5 - if thread is not a cooperative thread
 *
 * @return TC_PASS on success
 * @return TC_FAIL on failure
 */
static int test_kernel_thread(k_tid_t task_thread_id)
{
	k_tid_t self_thread_id;

	self_thread_id = k_current_get();
	if (self_thread_id == task_thread_id) {
		thread_detected_error = 1;
		return TC_FAIL;
	}

	isr_info.command = THREAD_SELF_CMD;
	isr_info.error = 0;
	isr_handler_trigger();
	if (isr_info.error || isr_info.data != (void *)self_thread_id) {
		/*
		 * Either the ISR detected an error, or the ISR context ID
		 * does not match the interrupted thread's thread ID.
		 */
		thread_detected_error = 2;
		return TC_FAIL;
	}

	isr_info.command = EXEC_CTX_TYPE_CMD;
	isr_info.error = 0;
	isr_handler_trigger();
	if (isr_info.error || (isr_info.value != K_ISR)) {
		thread_detected_error = 3;
		return TC_FAIL;
	}

	if (k_is_in_isr()) {
		thread_detected_error = 4;
		return TC_FAIL;
	}

	if (_current->base.prio >= 0) {
		thread_detected_error = 5;
		return TC_FAIL;
	}

	return TC_PASS;
}

/**
 *
 * @brief Entry point to the thread's helper
 *
 * This routine is the entry point to the thread's helper thread.  It is used to
 * help test the behavior of the k_yield() routine.
 *
 * @param arg1    unused
 * @param arg2    unused
 *
 * @return N/A
 */

static void thread_helper(void *arg1, void *arg2, void *arg3)
{
	k_tid_t self_thread_id;

	ARG_UNUSED(arg1);
	ARG_UNUSED(arg2);
	ARG_UNUSED(arg3);

	/*
	 * This thread starts off at a higher priority than thread_entry().
	 * Thus, it should execute immediately.
	 */

	thread_evidence++;

	/* Test that helper will yield to a thread of equal priority */
	self_thread_id = k_current_get();

	/* Lower priority to that of thread_entry() */
	k_thread_priority_set(self_thread_id, self_thread_id->base.prio + 1);

	k_yield();              /* Yield to thread of equal priority */

	thread_evidence++;
	/* <thread_evidence> should now be 2 */

}

/**
 *
 * @brief Test the k_yield() routine
 *
 * This routine tests the k_yield() routine.  It starts another thread
 * (thus also testing k_thread_create() and checks that behavior of
 * k_yield() against the cases of there being a higher priority thread,
 * a lower priority thread, and another thread of equal priority.
 *
 * On error, it may set <thread_detected_error> to one of the following values:
 *   10 - helper thread ran prematurely
 *   11 - k_yield() did not yield to a higher priority thread
 *   12 - k_yield() did not yield to an equal priority thread
 *   13 - k_yield() yielded to a lower priority thread
 *
 * @return TC_PASS on success
 * @return TC_FAIL on failure
 */
static int test_k_yield(void)
{
	k_tid_t self_thread_id;

	/*
	 * Start a thread of higher priority.  Note that since the new thread is
	 * being started from a thread, it will not automatically switch to the
	 * thread as it would if done from a task.
	 */

	self_thread_id = k_current_get();
	thread_evidence = 0;

	k_thread_create(&thread_data2, thread_stack2, THREAD_STACKSIZE,
			thread_helper, NULL, NULL, NULL,
			K_PRIO_COOP(THREAD_PRIORITY - 1), 0, 0);

	if (thread_evidence != 0) {
		/* ERROR! Helper created at higher */
		thread_detected_error = 10;     /* priority ran prematurely. */
		return TC_FAIL;
	}

	/*
	 * Test that the thread will yield to the higher priority helper.
	 * <thread_evidence> is still 0.
	 */

	k_yield();

	if (thread_evidence == 0) {
		/* ERROR! Did not yield to higher */
		thread_detected_error = 11;     /* priority thread. */
		return TC_FAIL;
	}

	if (thread_evidence > 1) {
		/* ERROR! Helper did not yield to */
		thread_detected_error = 12;     /* equal priority thread. */
		return TC_FAIL;
	}

	/*
	 * Raise the priority of thread_entry().  Calling k_yield() should
	 * not result in switching to the helper.
	 */

	k_thread_priority_set(self_thread_id, self_thread_id->base.prio - 1);
	k_yield();

	if (thread_evidence != 1) {
		/* ERROR! Context switched to a lower */
		thread_detected_error = 13;     /* priority thread! */
		return TC_FAIL;
	}

	/*
	 * Block on <sem_thread>.  This will allow the helper thread to
	 * complete. The main task will wake this thread.
	 */

	k_sem_take(&sem_thread, K_FOREVER);

	return TC_PASS;
}

/**
 * @brief Entry point to thread started by the task
 *
 * This routine is the entry point to the thread started by the task.
 *
 * @param task_thread_id	thread ID of the spawning task
 * @param arg1			unused
 * @param arg2			unused
 *
 * @return N/A
 */
static void thread_entry(void *task_thread_id, void *arg1, void *arg2)
{
	int rv;

	ARG_UNUSED(arg1);
	ARG_UNUSED(arg2);

	thread_evidence++;      /* Prove to the task that the thread has run */
	k_sem_take(&sem_thread, K_FOREVER);

	rv = test_kernel_thread((k_tid_t) task_thread_id);
	if (rv != TC_PASS) {
		return;
	}

	/* Allow the task to print any messages before the next test runs */
	k_sem_take(&sem_thread, K_FOREVER);

	rv = test_k_yield();
	if (rv != TC_PASS) {
		return;
	}
}

/*
 * Timeout tests
 *
 * Test the k_sleep() API, as well as the k_thread_create() ones.
 */

struct timeout_order {
	void *link_in_fifo;
	s32_t timeout;
	int timeout_order;
	int q_order;
};

struct timeout_order timeouts[] = {
	{ 0, 1000, 2, 0 },
	{ 0, 1500, 4, 1 },
	{ 0, 500, 0, 2 },
	{ 0, 750, 1, 3 },
	{ 0, 1750, 5, 4 },
	{ 0, 2000, 6, 5 },
	{ 0, 1250, 3, 6 },
};

#define NUM_TIMEOUT_THREADS ARRAY_SIZE(timeouts)
static K_THREAD_STACK_ARRAY_DEFINE(timeout_stacks, NUM_TIMEOUT_THREADS,
				   THREAD_STACKSIZE);
static struct k_thread timeout_threads[NUM_TIMEOUT_THREADS];

/* a thread busy waits, then reports through a fifo */
static void test_busy_wait(void *mseconds, void *arg2, void *arg3)
{
	u32_t usecs;

	ARG_UNUSED(arg2);
	ARG_UNUSED(arg3);

	usecs = (int)mseconds * 1000;

	TC_PRINT("Thread busy waiting for %d usecs\n", usecs);
	k_busy_wait(usecs);
	TC_PRINT("Thread busy waiting completed\n");

	/*
	 * Ideally the test should verify that the correct number of ticks
	 * have elapsed. However, when running under QEMU, the tick interrupt
	 * may be processed on a very irregular basis, meaning that far
	 * fewer than the expected number of ticks may occur for a given
	 * number of clock cycles vs. what would ordinarily be expected.
	 *
	 * Consequently, the best we can do for now to test busy waiting is
	 * to invoke the API and verify that it returns. (If it takes way
	 * too long, or never returns, the main test task may be able to
	 * time out and report an error.)
	 */

	k_sem_give(&reply_timeout);
}

/* a thread sleeps and times out, then reports through a fifo */
static void test_thread_sleep(void *delta, void *arg2, void *arg3)
{
	s64_t timestamp;
	int timeout = (int)delta;

	ARG_UNUSED(arg2);
	ARG_UNUSED(arg3);

	TC_PRINT(" thread sleeping for %d milliseconds\n", timeout);
	timestamp = k_uptime_get();
	k_sleep(timeout);
	timestamp = k_uptime_get() - timestamp;
	TC_PRINT(" thread back from sleep\n");

	if (timestamp < timeout || timestamp > timeout + __ticks_to_ms(2)) {
		TC_ERROR("timestamp out of range, got %d\n", (int)timestamp);
		return;
	}

	k_sem_give(&reply_timeout);
}

/* a thread is started with a delay, then it reports that it ran via a fifo */
static void delayed_thread(void *num, void *arg2, void *arg3)
{
	struct timeout_order *timeout = &timeouts[(int)num];

	ARG_UNUSED(arg2);
	ARG_UNUSED(arg3);

	TC_PRINT(" thread (q order: %d, t/o: %d) is running\n",
		 timeout->q_order, timeout->timeout);

	k_fifo_put(&timeout_order_fifo, timeout);
}

static int test_timeout(void)
{
	struct timeout_order *data;
	s32_t timeout;
	int rv;
	int i;

	/* test k_busy_wait() */
	TC_PRINT("Testing k_busy_wait()\n");
	timeout = 20;           /* in ms */

	k_thread_create(&timeout_threads[0], timeout_stacks[0],
			THREAD_STACKSIZE, test_busy_wait,
			(void *)(intptr_t) timeout, NULL,
			NULL, K_PRIO_COOP(THREAD_PRIORITY), 0, 0);

	rv = k_sem_take(&reply_timeout, timeout * 2);

	if (rv) {
		TC_ERROR(" *** task timed out waiting for " "k_busy_wait()\n");
		return TC_FAIL;
	}

	/* test k_sleep() */

	TC_PRINT("Testing k_sleep()\n");
	timeout = 50;

	k_thread_create(&timeout_threads[0], timeout_stacks[0],
			THREAD_STACKSIZE, test_thread_sleep,
			(void *)(intptr_t) timeout, NULL,
			NULL, K_PRIO_COOP(THREAD_PRIORITY), 0, 0);

	rv = k_sem_take(&reply_timeout, timeout * 2);
	if (rv) {
		TC_ERROR(" *** task timed out waiting for thread on "
			 "k_sleep().\n");
		return TC_FAIL;
	}

	/* test k_thread_create() without cancellation */
	TC_PRINT("Testing k_thread_create() without cancellation\n");

	for (i = 0; i < NUM_TIMEOUT_THREADS; i++) {
		k_thread_create(&timeout_threads[i], timeout_stacks[i],
				THREAD_STACKSIZE,
				delayed_thread,
				(void *)i,
				NULL, NULL,
				K_PRIO_COOP(5), 0, timeouts[i].timeout);
	}
	for (i = 0; i < NUM_TIMEOUT_THREADS; i++) {
		data = k_fifo_get(&timeout_order_fifo, 750);
		if (!data) {
			TC_ERROR
				(" *** timeout while waiting for delayed thread\n");
			return TC_FAIL;
		}

		if (data->timeout_order != i) {
			TC_ERROR(" *** wrong delayed thread ran (got %d, "
				 "expected %d)\n", data->timeout_order, i);
			return TC_FAIL;
		}

		TC_PRINT(" got thread (q order: %d, t/o: %d) as expected\n",
			 data->q_order, data->timeout);
	}

	/* ensure no more thread fire */
	data = k_fifo_get(&timeout_order_fifo, 750);

	if (data) {
		TC_ERROR(" *** got something unexpected in the fifo\n");
		return TC_FAIL;
	}

	/* test k_thread_create() with cancellation */
	TC_PRINT("Testing k_thread_create() with cancellations\n");

	int cancellations[] = { 0, 3, 4, 6 };
	int num_cancellations = ARRAY_SIZE(cancellations);
	int next_cancellation = 0;

	k_tid_t delayed_threads[NUM_TIMEOUT_THREADS];

	for (i = 0; i < NUM_TIMEOUT_THREADS; i++) {
		k_tid_t id;

		id = k_thread_create(&timeout_threads[i], timeout_stacks[i],
				     THREAD_STACKSIZE, delayed_thread,
				     (void *)i, NULL, NULL,
				     K_PRIO_COOP(5), 0, timeouts[i].timeout);

		delayed_threads[i] = id;
	}

	for (i = 0; i < NUM_TIMEOUT_THREADS; i++) {
		int j;

		if (i == cancellations[next_cancellation]) {
			TC_PRINT(" cancelling "
				 "[q order: %d, t/o: %d, t/o order: %d]\n",
				 timeouts[i].q_order, timeouts[i].timeout, i);

			for (j = 0; j < NUM_TIMEOUT_THREADS; j++) {
				if (timeouts[j].timeout_order == i) {
					break;
				}
			}

			if (j < NUM_TIMEOUT_THREADS) {
				k_thread_cancel(delayed_threads[j]);
				++next_cancellation;
				continue;
			}
		}

		data = k_fifo_get(&timeout_order_fifo, 2750);

		if (!data) {
			TC_ERROR
				(" *** timeout while waiting for delayed thread\n");
			return TC_FAIL;
		}

		if (data->timeout_order != i) {
			TC_ERROR(" *** wrong delayed thread ran (got %d, "
				 "expected %d)\n", data->timeout_order, i);
			return TC_FAIL;
		}

		TC_PRINT(" got (q order: %d, t/o: %d, t/o order %d) "
			 "as expected\n", data->q_order, data->timeout,
			 data->timeout_order);
	}

	if (num_cancellations != next_cancellation) {
		TC_ERROR(" *** wrong number of cancellations (expected %d, "
			 "got %d\n", num_cancellations, next_cancellation);
		return TC_FAIL;
	}

	/* ensure no more thread fire */
	data = k_fifo_get(&timeout_order_fifo, 750);
	if (data) {
		TC_ERROR(" *** got something unexpected in the fifo\n");
		return TC_FAIL;
	}

	return TC_PASS;
}

/**
 * @brief Entry point to timer tests
 *
 * This is the entry point to the CPU and thread tests.
 *
 * @return N/A
 */
void main(void)
{
	int rv;                 /* return value from tests */

	thread_detected_error = 0;
	thread_evidence = 0;

	TC_START("Test kernel CPU and thread routines");

	TC_PRINT("Initializing kernel objects\n");
	rv = kernel_init_objects();
	if (rv != TC_PASS) {
		goto tests_done;
	}

	TC_PRINT("Testing interrupt locking and unlocking\n");
	rv = test_kernel_interrupts(irq_lock_wrapper, irq_unlock_wrapper, -1);
	if (rv != TC_PASS) {
		goto tests_done;
	}
#ifdef TICK_IRQ
	/* Disable interrupts coming from the timer. */

	TC_PRINT("Testing irq_disable() and irq_enable()\n");
	rv = test_kernel_interrupts(irq_disable_wrapper, irq_enable_wrapper,
				    TICK_IRQ);
	if (rv != TC_PASS) {
		goto tests_done;
	}
#endif

	TC_PRINT("Testing some kernel context routines\n");
	rv = test_kernel_ctx_task();
	if (rv != TC_PASS) {
		goto tests_done;
	}

	TC_PRINT("Spawning a thread from a task\n");
	thread_evidence = 0;

	k_thread_create(&thread_data1, thread_stack1, THREAD_STACKSIZE,
			thread_entry, k_current_get(), NULL,
			NULL, K_PRIO_COOP(THREAD_PRIORITY), 0, 0);

	if (thread_evidence != 1) {
		rv = TC_FAIL;
		TC_ERROR("  - thread did not execute as expected!\n");
		goto tests_done;
	}

	/*
	 * The thread ran, now wake it so it can test k_current_get and
	 * k_is_in_isr.
	 */
	TC_PRINT("Thread to test k_current_get() and " "k_is_in_isr()\n");
	k_sem_give(&sem_thread);

	if (thread_detected_error != 0) {
		rv = TC_FAIL;
		TC_ERROR("  - failure detected in thread; "
			 "thread_detected_error = %d\n", thread_detected_error);
		goto tests_done;
	}

	TC_PRINT("Thread to test k_yield()\n");
	k_sem_give(&sem_thread);

	if (thread_detected_error != 0) {
		rv = TC_FAIL;
		TC_ERROR("  - failure detected in thread; "
			 "thread_detected_error = %d\n", thread_detected_error);
		goto tests_done;
	}

	k_sem_give(&sem_thread);

	rv = test_timeout();
	if (rv != TC_PASS) {
		goto tests_done;
	}

#ifdef HAS_POWERSAVE_INSTRUCTION
	TC_PRINT("Testing k_cpu_idle()\n");
	rv = test_kernel_cpu_idle(0);
	if (rv != TC_PASS) {
		goto tests_done;
	}
#ifndef CONFIG_ARM
	TC_PRINT("Testing k_cpu_atomic_idle()\n");
	rv = test_kernel_cpu_idle(1);
	if (rv != TC_PASS) {
		goto tests_done;
	}
#endif
#endif

tests_done:
	TC_END_RESULT(rv);
	TC_END_REPORT(rv);
}
