/* static_idt.c - test static IDT APIs */

/*
 * Copyright (c) 2012-2014 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
Ensures interrupt and exception stubs are installed correctly.
 */

#include <zephyr.h>
#include <tc_util.h>

#include <nano_private.h>
#if defined(__GNUC__)
#include <test_asm_inline_gcc.h>
#else
#include <test_asm_inline_other.h>
#endif

/* These vectors are somewhat arbitrary. We try and use unused vectors */
#define TEST_SOFT_INT 62
#define TEST_SPUR_INT 63

/* externs */

 /* the _idt_base_address symbol is generated via a linker script */

extern unsigned char _idt_base_address[];

extern void *nanoIntStub;
extern void *exc_divide_error_handlerStub;

NANO_CPU_INT_REGISTER(nanoIntStub, -1, -1, TEST_SOFT_INT, 0);

static volatile int    excHandlerExecuted;
static volatile int    intHandlerExecuted;
/* Assume the spurious interrupt handler will execute and abort the task/fiber */
static volatile int    spurHandlerAbortedThread = 1;

#ifdef CONFIG_NANOKERNEL
static char __stack fiberStack[512];
#endif


/**
 *
 *  isr_handler - handler to perform various actions from within an ISR context
 *
 * This routine is the ISR handler for _trigger_isrHandler().
 *
 * @return N/A
 */

void isr_handler(void)
{
	intHandlerExecuted++;
}

/**
 *
 * exc_divide_error_handler -
 *
 * This is the handler for the divde by zero exception.  The source of this
 * divide-by-zero error comes from the following line in main() ...
 *         error = error / excHandlerExecuted;
 * Where excHandlerExecuted is zero.
 * The disassembled code for it looks something like ....
 *         f7 fb                   idiv   %ecx
 * 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.  Therefore,
 * a very quick and dirty approach is taken for dealing with the exception;
 * we skip the offending instruction by adding 2 to the EIP.  (If nothing is
 * done, then control goes back to the offending instruction and an infinite
 * loop of divide-by-zero errors would be created.)
 *
 * @return N/A
 */

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

/**
 *
 * @brief Check the IDT.
 *
 * This test examines the IDT and verifies that the static interrupt and
 * exception stubs are installed at the correct place.
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int nanoIdtStubTest(void)
{
	IDT_ENTRY *pIdtEntry;
	uint16_t offset;

	/* Check for the interrupt stub */
	pIdtEntry = (IDT_ENTRY *) (_idt_base_address + (TEST_SOFT_INT << 3));

	offset = (uint16_t)((uint32_t)(&nanoIntStub) & 0xFFFF);
	if (pIdtEntry->offset_low != offset) {
		TC_ERROR("Failed to find low offset of nanoIntStub "
				 "(0x%x) at vector %d\n", (uint32_t)offset, TEST_SOFT_INT);
		return TC_FAIL;
	}

	offset = (uint16_t)((uint32_t)(&nanoIntStub) >> 16);
	if (pIdtEntry->offset_high != offset) {
		TC_ERROR("Failed to find high offset of nanoIntStub "
				 "(0x%x) at vector %d\n", (uint32_t)offset, TEST_SOFT_INT);
		return TC_FAIL;
	}

	/* Check for the exception stub */
	pIdtEntry = (IDT_ENTRY *) (_idt_base_address + (IV_DIVIDE_ERROR << 3));

	offset = (uint16_t)((uint32_t)(&exc_divide_error_handlerStub) & 0xFFFF);
	if (pIdtEntry->offset_low != offset) {
		TC_ERROR("Failed to find low offset of exc stub "
				 "(0x%x) at vector %d\n", (uint32_t)offset, IV_DIVIDE_ERROR);
		return TC_FAIL;
	}

	offset = (uint16_t)((uint32_t)(&exc_divide_error_handlerStub) >> 16);
	if (pIdtEntry->offset_high != offset) {
		TC_ERROR("Failed to find high offset of exc stub "
				 "(0x%x) at vector %d\n", (uint32_t)offset, IV_DIVIDE_ERROR);
		return TC_FAIL;
	}

	/*
	 * If the other fields are wrong, the system will crash when the exception
	 * and software interrupt are triggered so we don't check them.
	 */
	return TC_PASS;
}

/**
 *
 * @brief Task/fiber to test spurious handlers
 *
 * @return 0
 */

#ifdef CONFIG_MICROKERNEL
void idtSpurTask(void)
#else
static void idtSpurFiber(int a1, int a2)
#endif
{
#ifndef CONFIG_MICROKERNEL
	ARG_UNUSED(a1);
	ARG_UNUSED(a2);
#endif /* !CONFIG_MICROKERNEL */

	TC_PRINT("- Expect to see unhandled interrupt/exception message\n");

	_trigger_spurHandler();

	/* Shouldn't get here */
	spurHandlerAbortedThread = 0;

}

/**
 *
 * @brief Entry point to static IDT tests
 *
 * This is the entry point to the static IDT tests.
 *
 * @return N/A
 */

#ifdef CONFIG_MICROKERNEL
void idtTestTask(void)
#else
void main(void)
#endif
{
	int           rv;       /* return value from tests */
	volatile int  error;    /* used to create a divide by zero error */

	TC_START("Test Nanokernel static IDT tests");


	TC_PRINT("Testing to see if IDT has address of test stubs()\n");
	rv = nanoIdtStubTest();
	if (rv != TC_PASS) {
		goto doneTests;
	}

	TC_PRINT("Testing to see interrupt handler executes properly\n");
	_trigger_isrHandler();

	if (intHandlerExecuted == 0) {
		TC_ERROR("Interrupt handler did not execute\n");
		rv = TC_FAIL;
		goto doneTests;
	} else if (intHandlerExecuted != 1) {
		TC_ERROR("Interrupt handler executed more than once! (%d)\n",
				 intHandlerExecuted);
		rv = TC_FAIL;
		goto doneTests;
	}

	TC_PRINT("Testing to see exception handler executes properly\n");

	/*
	 * Use excHandlerExecuted instead of 0 to prevent the compiler issuing a
	 * 'divide by zero' warning.
	 */
	error = error / excHandlerExecuted;

	if (excHandlerExecuted == 0) {
		TC_ERROR("Exception handler did not execute\n");
		rv = TC_FAIL;
		goto doneTests;
	} else if (excHandlerExecuted != 1) {
		TC_ERROR("Exception handler executed more than once! (%d)\n",
				 excHandlerExecuted);
		rv = TC_FAIL;
		goto doneTests;
	}

	/*
	 * Start fiber/task to trigger the spurious interrupt handler
	 */
	TC_PRINT("Testing to see spurious handler executes properly\n");
#ifdef CONFIG_MICROKERNEL
	task_start(tSpurTask);
#else
	task_fiber_start(fiberStack, sizeof(fiberStack), idtSpurFiber, 0, 0, 5, 0);
#endif
	/*
	 * The fiber/task should not run past where the spurious interrupt is
	 * generated. Therefore spurHandlerAbortedThread should remain at 1.
	 */
	if (spurHandlerAbortedThread == 0) {
		TC_ERROR("Spurious handler did not execute as expected\n");
		rv = TC_FAIL;
		goto doneTests;
	}

doneTests:
	TC_END(rv, "%s - %s.\n", rv == TC_PASS ? PASS : FAIL, __func__);
	TC_END_REPORT(rv);
}
