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

/**
 * @file
 * test static IDT APIs
 *  Ensures interrupt and exception stubs are installed correctly.
 */

#include <zephyr.h>
#include <tc_util.h>
#include <arch/x86/segmentation.h>

#include <kernel_structs.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 60
#define TEST_SPUR_INT 61


#define MY_STACK_SIZE 2048
#define MY_PRIORITY 5

K_THREAD_STACK_DEFINE(my_stack_area, MY_STACK_SIZE);
static struct k_thread my_thread;

/* externs */

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

extern unsigned char _idt_base_address[];

extern void *int_stub;
NANO_CPU_INT_REGISTER(int_stub, -1, -1, TEST_SOFT_INT, 0);

static volatile int exc_handler_executed;
static volatile int int_handler_executed;
/* Assume the spurious interrupt handler will execute and abort the task */
static volatile int spur_handler_aborted_thread = 1;


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

void isr_handler(void)
{
	int_handler_executed++;
}

/**
 *
 * This is the handler for the divide by zero exception.
 *
 * The source of this divide-by-zero error comes from the following line in
 * main() ...
 *         error = error / exc_handler_executed;
 * Where exc_handler_executed 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 *p_esf)
{
	p_esf->eip += 2;
	/* provide evidence that the handler executed */
	exc_handler_executed = 1;
}
_EXCEPTION_CONNECT_NOCODE(exc_divide_error_handler, IV_DIVIDE_ERROR);
extern void *_EXCEPTION_STUB_NAME(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 idt_stub_test(void)
{
	struct segment_descriptor *p_idt_entry;
	u32_t offset;

	/* Check for the interrupt stub */
	p_idt_entry = (struct segment_descriptor *)
		      (_idt_base_address + (TEST_SOFT_INT << 3));
	offset = (u32_t)(&int_stub);
	if (DTE_OFFSET(p_idt_entry) != offset) {
		TC_ERROR("Failed to find offset of int_stub (0x%x) at vector %d\n",
			 offset, TEST_SOFT_INT);
		return TC_FAIL;
	}

	/* Check for the exception stub */
	p_idt_entry = (struct segment_descriptor *)
		      (_idt_base_address + (IV_DIVIDE_ERROR << 3));
	offset = (u32_t)(&_EXCEPTION_STUB_NAME(exc_divide_error_handler, 0));
	if (DTE_OFFSET(p_idt_entry) != offset) {
		TC_ERROR("Failed to find offset of exc stub (0x%x) at vector %d\n",
			 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 to test spurious handlers
 *
 * @return 0
 */

void idt_spur_task(void *arg1, void *arg2, void *arg3)
{
	TC_PRINT("- Expect to see unhandled interrupt/exception message\n");

	_trigger_spur_handler();

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

}

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

void main(void)
{
	int rv;                 /* return value from tests */
	volatile int error;     /* used to create a divide by zero error */

	TC_START("Starting static IDT tests");

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

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

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

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

	/*
	 * Use exc_handler_executed instead of 0 to prevent the compiler issuing a
	 * 'divide by zero' warning.
	 */
	error = 32;     /* avoid static checker uninitialized warnings */
	error = error / exc_handler_executed;

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

	/*
	 * Start task to trigger the spurious interrupt handler
	 */
	TC_PRINT("Testing to see spurious handler executes properly\n");
	k_thread_create(&my_thread, my_stack_area, MY_STACK_SIZE,
			idt_spur_task, NULL, NULL, NULL,
			MY_PRIORITY, 0, K_NO_WAIT);

	/*
	 * The fiber/task should not run past where the spurious interrupt is
	 * generated. Therefore spur_handler_aborted_thread should remain at 1.
	 */
	if (spur_handler_aborted_thread == 0) {
		TC_ERROR("Spurious handler did not execute as expected\n");
		rv = TC_FAIL;
		goto done_tests;
	}

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