/* thread.c - test nanokernel CPU and thread APIs */

/*
 * Copyright (c) 2012-2015 Wind River Systems, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
DESCRIPTION
This module tests the following CPU and thread related routines:
  fiber_fiber_start(), task_fiber_start(), fiber_yield(),
  sys_thread_self_get(), sys_execution_context_type_get(), nano_cpu_idle(),
  irq_lock(), irq_unlock(),
  irq_offload(), nanoCpuExcConnect(),
  irq_enable(), irq_disable(),
 */

#include <tc_util.h>
#include <nano_private.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-M3/M4 does not need IRQ numbers
 */
#if !defined(CONFIG_CPU_CORTEX_M3_M4)
  #include <board.h>
#endif

#define FIBER_STACKSIZE    256
#define FIBER_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)
  #define TICK_IRQ CONFIG_LOAPIC_TIMER_IRQ
#elif defined(CONFIG_CPU_CORTEX_M3_M4)
  /* Cortex-M3/M4 does not need a tick IRQ number. */
#else
  /* generate an error */
  #error Timer type is not defined for this platform
#endif

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_interrupt_func)(int);
typedef void (* enable_interrupt_func)(int);

/* Cortex-M3/M4 does not implement connecting non-IRQ exception handlers */
#if !defined(CONFIG_CPU_CORTEX_M3_M4)
static volatile int    excHandlerExecuted;
#endif

static struct nano_sem        wakeFiber;
static struct nano_timer      timer;
static struct nano_sem        reply_timeout;
struct nano_fifo              timeout_order_fifo;
static void *timerData[1];

static int  fiberDetectedError = 0;
static char __stack fiberStack1[FIBER_STACKSIZE];
static char __stack fiberStack2[FIBER_STACKSIZE];
static int  fiberEvidence = 0;

static ISR_INFO  isrInfo;

/**
 *
 * @brief Handler to perform various actions from within an ISR context
 *
 * This routine is the ISR handler for _trigger_isrHandler().  It performs
 * the command requested in <isrInfo.command>.
 *
 * @return N/A
 */

void isr_handler(void *data)
{
	ARG_UNUSED(data);

	switch (isrInfo.command) {
	case THREAD_SELF_CMD:
		isrInfo.data = (void *) sys_thread_self_get();
		break;

	case EXEC_CTX_TYPE_CMD:
		isrInfo.value = sys_execution_context_type_get();
		break;

	default:
		isrInfo.error = UNKNOWN_COMMAND;
		break;
	}
}
static void _trigger_isrHandler(void)
{
	irq_offload(isr_handler, NULL);
}


/* Cortex-M3/M4 does not implement connecting non-IRQ exception handlers */
#if !defined(CONFIG_CPU_CORTEX_M3_M4)
/**
 *
 * @brief Divide by zero exception handler
 *
 * This handler is part of a test that is only interested in detecting the
 * error so that we know the exception connect code is working. It simply
 * adds 2 to the EIP to skip over the offending instruction:
 *         f7 f9         idiv %ecx
 * thereby preventing the infinite loop of divide-by-zero errors which would
 * arise if control simply returns to that instruction.
 *
 * @return N/A
 */

void exc_divide_error_handler(NANO_ESF *pEsf)
{
	pEsf->eip += 2;
	excHandlerExecuted = 1;    /* provide evidence that the handler executed */
}
#endif

/**
 *
 * @brief Initialize nanokernel objects
 *
 * This routine initializes the nanokernel objects used in this module's tests.
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int initNanoObjects(void)
{
	nano_sem_init(&wakeFiber);
	nano_timer_init(&timer, timerData);
	nano_fifo_init(&timeout_order_fifo);

/* no nanoCpuExcConnect on Cortex-M3/M4 */
#if !defined(CONFIG_CPU_CORTEX_M3_M4)
	nanoCpuExcConnect(IV_DIVIDE_ERROR, exc_divide_error_handler);
#endif

	return TC_PASS;
}

/**
 *
 * @brief Test the nano_cpu_idle() routine
 *
 * This tests the nano_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 nano_cpu_idle(), the tick count should be one higher.
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int nano_cpu_idleTest(void)
{
	int  tick;   /* current tick count */
	int  i;      /* loop variable */

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

	for (i = 0; i < 5; i++) {     /* Repeat the test five times */
		nano_cpu_idle();
		tick++;
		if (sys_tick_get_32() != tick) {
			return TC_FAIL;
		}
	}

	return TC_PASS;
}

/**
 *
 * @brief A wrapper for irq_lock()
 *
 * @return irq_lock() return value
 */

int irq_lockWrapper(int unused)
{
	ARG_UNUSED(unused);

	return irq_lock();
}

/**
 *
 * @brief A wrapper for irq_unlock()
 *
 * @return N/A
 */

void irq_unlockWrapper(int imask)
{
	irq_unlock(imask);
}

/**
 *
 * @brief A wrapper for irq_disable()
 *
 * @return <irq>
 */

int irq_disableWrapper(int irq)
{
	irq_disable(irq);
	return irq;
}

/**
 *
 * @brief A wrapper for irq_enable()
 *
 * @return N/A
 */

void irq_enableWrapper(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, TC_FAIL on failure
 */

int nanoCpuDisableInterruptsTest(disable_interrupt_func disableRtn,
								 enable_interrupt_func enableRtn, int irq)
{
	unsigned long long  count = 0;
	unsigned long long  i = 0;
	int  tick;
	int  tick2;
	int  imask;

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

	while (sys_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 = disableRtn(irq);
	tick = sys_tick_get_32();
	for (i = 0; i < count; i++) {
		sys_tick_get_32();
	}

	tick2 = sys_tick_get_32();

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

	enableRtn(imask);

	if (tick2 != tick) {
		return TC_FAIL;
	}

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

	return (tick == sys_tick_get_32()) ? TC_FAIL : TC_PASS;
}

/**
 *
 * @brief Test the various nanoCtxXXX() routines from a task
 *
 * This routines tests the sys_thread_self_get() and
 * sys_execution_context_type_get() routines from both a task and an ISR (that
 * interrupted a task).  Checking those routines with fibers are done
 * elsewhere.
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int nanoCtxTaskTest(void)
{
	nano_thread_id_t  self_thread_id;

	TC_PRINT("Testing sys_thread_self_get() from an ISR and task\n");
	self_thread_id = sys_thread_self_get();
	isrInfo.command = THREAD_SELF_CMD;
	isrInfo.error = 0;
	_trigger_isrHandler();
	if ((isrInfo.error != 0) || (isrInfo.data != (void *) self_thread_id)) {
		/*
		 * Either the ISR detected an error, or the ISR context ID does not
		 * match the interrupted task's thread ID.
		 */
		return TC_FAIL;
	}

	TC_PRINT("Testing sys_execution_context_type_get() from an ISR\n");
	isrInfo.command = EXEC_CTX_TYPE_CMD;
	isrInfo.error = 0;
	_trigger_isrHandler();
	if ((isrInfo.error != 0) || (isrInfo.value != NANO_CTX_ISR)) {
		return TC_FAIL;
	}

	TC_PRINT("Testing sys_execution_context_type_get() from a task\n");
	if (sys_execution_context_type_get() != NANO_CTX_TASK) {
		return TC_FAIL;
	}

	return TC_PASS;
}

/**
 *
 * @brief Test the various context/thread routines from a fiber
 *
 * This routines tests the sys_thread_self_get() and
 * sys_execution_context_type_get() routines from both a fiber and an ISR (that
 * interrupted a fiber).  Checking those routines with tasks are done
 * elsewhere.
 *
 * This routine may set <fiberDetectedError> to the following values:
 *   1 - if fiber ID matches that of the task
 *   2 - if thread ID taken during ISR does not match that of the fiber
 *   3 - sys_execution_context_type_get() when called from an ISR is not
 *       NANO_TYPE_ISR
 *   4 - sys_execution_context_type_get() when called from a fiber is not
 *       NANO_TYPE_FIBER
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int nanoCtxFiberTest(nano_thread_id_t task_thread_id)
{
	nano_thread_id_t  self_thread_id;

	self_thread_id = sys_thread_self_get();
	if (self_thread_id == task_thread_id) {
		fiberDetectedError = 1;
		return TC_FAIL;
	}

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

	isrInfo.command = EXEC_CTX_TYPE_CMD;
	isrInfo.error = 0;
	_trigger_isrHandler();
	if ((isrInfo.error != 0) || (isrInfo.value != NANO_CTX_ISR)) {
		fiberDetectedError = 3;
		return TC_FAIL;
	}

	if (sys_execution_context_type_get() != NANO_CTX_FIBER) {
		fiberDetectedError = 4;
		return TC_FAIL;
	}

	return TC_PASS;
}

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

static void fiberHelper(int arg1, int arg2)
{
	nano_thread_id_t  self_thread_id;

	ARG_UNUSED(arg1);
	ARG_UNUSED(arg2);

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

	fiberEvidence++;

	/* Test that helper will yield to a fiber of equal priority */
	self_thread_id = sys_thread_self_get();
	self_thread_id->prio++;  /* Lower priority to that of fiberEntry() */
	fiber_yield();        /* Yield to fiber of equal priority */

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

}

/**
 *
 * @brief Test the fiber_yield() routine
 *
 * This routine tests the fiber_yield() routine.  It starts another fiber
 * (thus also testing fiber_fiber_start()) and checks that behaviour of
 * fiber_yield() against the cases of there being a higher priority fiber,
 * a lower priority fiber, and another fiber of equal priority.
 *
 * On error, it may set <fiberDetectedError> to one of the following values:
 *   10 - helper fiber ran prematurely
 *   11 - fiber_yield() did not yield to a higher priority fiber
 *   12 - fiber_yield() did not yield to an equal prioirty fiber
 *   13 - fiber_yield() yielded to a lower priority fiber
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int fiber_yieldTest(void)
{
	nano_thread_id_t  self_thread_id;

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

	self_thread_id = sys_thread_self_get();
	fiberEvidence = 0;
	fiber_fiber_start(fiberStack2, FIBER_STACKSIZE, fiberHelper,
		0, 0, FIBER_PRIORITY - 1, 0);

	if (fiberEvidence != 0) {
		/* ERROR! Helper spawned at higher */
		fiberDetectedError = 10;    /* priority ran prematurely. */
		return TC_FAIL;
	}

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

	fiber_yield();

	if (fiberEvidence == 0) {
		/* ERROR! Did not yield to higher */
		fiberDetectedError = 11;    /* priority fiber. */
		return TC_FAIL;
	}

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

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

	self_thread_id->prio--;
	fiber_yield();

	if (fiberEvidence != 1) {
		/* ERROR! Context switched to a lower */
		fiberDetectedError = 13;    /* priority fiber! */
		return TC_FAIL;
	}

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

	nano_fiber_sem_take(&wakeFiber, TICKS_UNLIMITED);

	return TC_PASS;
}

/**
 *
 * @brief Entry point to fiber started by the task
 *
 * This routine is the entry point to the fiber started by the task.
 *
 * @param task_thread_id    thread ID of the spawning task
 * @param arg1         unused
 *
 * @return N/A
 */

static void fiberEntry(int task_thread_id, int arg1)
{
	int          rv;

	ARG_UNUSED(arg1);

	fiberEvidence++;    /* Prove to the task that the fiber has run */
	nano_fiber_sem_take(&wakeFiber, TICKS_UNLIMITED);

	rv = nanoCtxFiberTest((nano_thread_id_t) task_thread_id);
	if (rv != TC_PASS) {
		return;
	}

	/* Allow the task to print any messages before the next test runs */
	nano_fiber_sem_take(&wakeFiber, TICKS_UNLIMITED);

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

/*
 * Timeout tests
 *
 * Test the fiber_sleep() API, as well as the fiber_delayed_start() ones.
 */

#include <tc_nano_timeout_common.h>

struct timeout_order_data {
	void *link_in_fifo;
	int32_t timeout;
	int timeout_order;
	int q_order;
};

struct timeout_order_data timeout_order_data[] = {
	{0, TIMEOUT(2), 2, 0},
	{0, TIMEOUT(4), 4, 1},
	{0, TIMEOUT(0), 0, 2},
	{0, TIMEOUT(1), 1, 3},
	{0, TIMEOUT(5), 5, 4},
	{0, TIMEOUT(6), 6, 5},
	{0, TIMEOUT(3), 3, 6},
};

#define NUM_TIMEOUT_FIBERS ARRAY_SIZE(timeout_order_data)
static char __stack timeout_stacks[NUM_TIMEOUT_FIBERS][FIBER_STACKSIZE];

/* a fiber busy waits, then reports through a fifo */
static void test_fiber_busy_wait(int ticks, int unused)
{
	ARG_UNUSED(unused);

	uint32_t usecs = ticks * sys_clock_us_per_tick;

	TC_PRINT(" fiber busy waiting for %d usecs (%d ticks)\n",
			 usecs, ticks);
	sys_thread_busy_wait(usecs);
	TC_PRINT(" fiber busy waiting completed\n");

	/*
	 * Ideally the test should verify that the correct number of ticks
	 * have elapsed. However, when run 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.)
	 */

	nano_fiber_sem_give(&reply_timeout);
}

/* a fiber sleeps and times out, then reports through a fifo */
static void test_fiber_sleep(int timeout, int arg2)
{
	int64_t orig_ticks = sys_tick_get();

	TC_PRINT(" fiber sleeping for %d ticks\n", timeout);
	fiber_sleep(timeout);
	TC_PRINT(" fiber back from sleep\n");
	if (!is_timeout_in_range(orig_ticks, timeout)) {
		return;
	}

	nano_fiber_sem_give(&reply_timeout);
}

/* a fiber is started with a delay, then it reports that it ran via a fifo */
void delayed_fiber(int num, int unused)
{
	struct timeout_order_data *data = &timeout_order_data[num];

	ARG_UNUSED(unused);

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

	nano_fiber_fifo_put(&timeout_order_fifo, data);
}

static int test_timeout(void)
{
	int32_t timeout;
	int rv;
	int ii;
	struct timeout_order_data *data;

	/* test sys_thread_busy_wait() */

	TC_PRINT("Testing sys_thread_busy_wait()\n");
	timeout = 2;
	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_busy_wait, (int)timeout, 0,
						FIBER_PRIORITY, 0);

	rv = nano_task_sem_take(&reply_timeout, timeout + 2);
	if (!rv) {
		rv = TC_FAIL;
		TC_ERROR(" *** task timed out waiting for sys_thread_busy_wait()\n");
		return TC_FAIL;
	}

	/* test fiber_sleep() */

	TC_PRINT("Testing fiber_sleep()\n");
	timeout = 5;
	task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
						test_fiber_sleep, (int)timeout, 0,
						FIBER_PRIORITY, 0);

	rv = nano_task_sem_take(&reply_timeout, timeout + 5);
	if (!rv) {
		rv = TC_FAIL;
		TC_ERROR(" *** task timed out waiting for fiber on fiber_sleep().\n");
		return TC_FAIL;
	}

	/* test fiber_delayed_start() without cancellation */

	TC_PRINT("Testing fiber_delayed_start() without cancellation\n");

	for (ii = 0; ii < NUM_TIMEOUT_FIBERS; ii++) {
		(void)task_fiber_delayed_start(timeout_stacks[ii], FIBER_STACKSIZE,
										delayed_fiber, ii, 0, 5, 0,
										timeout_order_data[ii].timeout);
	}
	for (ii = 0; ii < NUM_TIMEOUT_FIBERS; ii++) {

		data = nano_task_fifo_get(&timeout_order_fifo, TIMEOUT_TWO_INTERVALS);

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

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

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

	/* ensure no more fibers fire */

	data = nano_task_fifo_get(&timeout_order_fifo, TIMEOUT_TWO_INTERVALS);

	if (data) {
		TC_ERROR(" *** got something on the fifo, but shouldn't have...\n");
		return TC_FAIL;
	}

	/* test fiber_delayed_start() with cancellation */

	TC_PRINT("Testing fiber_delayed_start() with cancellations\n");

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

	nano_thread_id_t delayed_fibers[NUM_TIMEOUT_FIBERS];

	for (ii = 0; ii < NUM_TIMEOUT_FIBERS; ii++) {
		delayed_fibers[ii] =
			task_fiber_delayed_start(timeout_stacks[ii], FIBER_STACKSIZE,
										delayed_fiber, ii, 0, 5, 0,
										timeout_order_data[ii].timeout);
	}

	for (ii = 0; ii < NUM_TIMEOUT_FIBERS; ii++) {
		int jj;

		if (ii == cancellations[next_cancellation]) {
			TC_PRINT(" cancelling [q order: %d, t/o: %d, t/o order: %d]\n",
						timeout_order_data[ii].q_order,
						timeout_order_data[ii].timeout, ii);
			for (jj = 0; jj < NUM_TIMEOUT_FIBERS; jj++) {
				if (timeout_order_data[jj].timeout_order == ii) {
					break;
				}
			}
			task_fiber_delayed_start_cancel(delayed_fibers[jj]);
			++next_cancellation;
			continue;
		}

		data = nano_task_fifo_get(&timeout_order_fifo, TIMEOUT_TEN_INTERVALS);

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

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

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

	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 fibers fire */

	data = nano_task_fifo_get(&timeout_order_fifo, TIMEOUT_TWO_INTERVALS);

	if (data) {
		TC_ERROR(" *** got something on the fifo, but shouldn't have...\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 */

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

	TC_PRINT("Initializing nanokernel objects\n");
	rv = initNanoObjects();
	if (rv != TC_PASS) {
		goto doneTests;
	}

	TC_PRINT("Testing nano_cpu_idle()\n");
	rv = nano_cpu_idleTest();
	if (rv != TC_PASS) {
		goto doneTests;
	}

	TC_PRINT("Testing interrupt locking and unlocking\n");
	rv = nanoCpuDisableInterruptsTest(irq_lockWrapper,
									  irq_unlockWrapper, -1);
	if (rv != TC_PASS) {
		goto doneTests;
	}


/*
 * The Cortex-M3/M4 use the SYSTICK exception for the system timer, which is
 * not considered an IRQ by the irq_enable/Disable APIs.
 */
#if !defined(CONFIG_CPU_CORTEX_M3_M4)
	/* Disable interrupts coming from the timer. */

	TC_PRINT("Testing irq_disable() and irq_enable()\n");
	rv = nanoCpuDisableInterruptsTest(irq_disableWrapper,
									  irq_enableWrapper, TICK_IRQ);
	if (rv != TC_PASS) {
		goto doneTests;
	}
#endif

	rv = nanoCtxTaskTest();
	if (rv != TC_PASS) {
		goto doneTests;
	}

	TC_PRINT("Spawning a fiber from a task\n");
	fiberEvidence = 0;
	task_fiber_start(fiberStack1, FIBER_STACKSIZE, fiberEntry,
					 (int) sys_thread_self_get(), 0, FIBER_PRIORITY, 0);

	if (fiberEvidence != 1) {
		rv = TC_FAIL;
		TC_ERROR("  - fiber did not execute as expected!\n");
		goto doneTests;
	}

	/*
	 * The fiber ran, now wake it so it can test sys_thread_self_get and
	 * sys_execution_context_type_get.
	 */
	TC_PRINT("Fiber to test sys_thread_self_get() and sys_execution_context_type_get\n");
	nano_task_sem_give(&wakeFiber);

	if (fiberDetectedError != 0) {
		rv = TC_FAIL;
		TC_ERROR("  - failure detected in fiber; fiberDetectedError = %d\n",
				 fiberDetectedError);
		goto doneTests;
	}

	TC_PRINT("Fiber to test fiber_yield()\n");
	nano_task_sem_give(&wakeFiber);

	if (fiberDetectedError != 0) {
		rv = TC_FAIL;
		TC_ERROR("  - failure detected in fiber; fiberDetectedError = %d\n",
				 fiberDetectedError);
		goto doneTests;
	}

	nano_task_sem_give(&wakeFiber);

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

/* Cortex-M3/M4 does not implement connecting non-IRQ exception handlers */
#if !defined(CONFIG_CPU_CORTEX_M3_M4)
	/*
	 * Test divide by zero exception handler.
	 *
	 * WARNING: This code has been very carefully crafted so that it does
	 * what it is supposed to. Both "error" and "excHandlerExecuted" must be
	 * volatile to prevent the compiler from issuing a "divide by zero"
	 * warning (since otherwise in knows "excHandlerExecuted" is zero),
	 * and to ensure the compiler issues the two byte "idiv" instruction
	 * that the exception handler is designed to deal with.
	 */

	volatile int error;    /* used to create a divide by zero error */
	TC_PRINT("Verifying exception handler installed\n");
	excHandlerExecuted = 0;
	error = error / excHandlerExecuted;
	TC_PRINT("excHandlerExecuted: %d\n", excHandlerExecuted);

	rv = (excHandlerExecuted == 1) ? TC_PASS : TC_FAIL;
#endif

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