/*
 * 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/zephyr.h>
#include <ztest.h>
#include <tc_util.h>
#include <zephyr/arch/x86/ia32/segmentation.h>

#include <kernel_internal.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;

void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf)
{
	if (reason != K_ERR_SPURIOUS_IRQ) {
		printk("wrong error reason\n");
		k_fatal_halt(reason);
	}
	if (k_current_get() != &my_thread) {
		printk("wrong thread crashed\n");
		k_fatal_halt(reason);
	}
}

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

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.)
 *
 */

void exc_divide_error_handler(z_arch_esf_t *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, 0);
extern void *_EXCEPTION_STUB_NAME(exc_divide_error_handler, IV_DIVIDE_ERROR);

/**
 * @ingroup kernel_interrupt_tests
 * @brief Test the position of interrupt stubs in IDT
 *
 * @details This test examines the IDT and verifies that the static interrupt
 * and exception stubs are installed at the correct place.
 *
 */
void test_idt_stub(void)
{
	struct segment_descriptor *p_idt_entry;
	uint32_t offset;

	TC_PRINT("Testing to see if IDT has address of test stubs()\n");
	/* Check for the interrupt stub */
	p_idt_entry = (struct segment_descriptor *)
		      (_idt_base_address + (TEST_SOFT_INT << 3));
	offset = (uint32_t)(&int_stub);
	zassert_equal(DTE_OFFSET(p_idt_entry), offset,
		      "Failed to find offset of int_stub (0x%x)"
		      " at vector %d\n", offset, TEST_SOFT_INT);

	/* Check for the exception stub */
	p_idt_entry = (struct segment_descriptor *)
		      (_idt_base_address + (IV_DIVIDE_ERROR << 3));
	offset = (uint32_t)(&_EXCEPTION_STUB_NAME(exc_divide_error_handler, 0));
	zassert_equal(DTE_OFFSET(p_idt_entry), offset,
		      "Failed to find offset of exc stub (0x%x)"
		      " at vector %d\n", offset, IV_DIVIDE_ERROR);

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

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;

}

/**
 * @ingroup kernel_interrupt_tests
 * @brief Test entry point to static IDT
 * @details this test is to generate the interrupt, exception,
 * and spurious interrupt using various method, the registered handler
 * should get called
 */
void test_static_idt(void)
{
	volatile int error;     /* used to create a divide by zero error */


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

	zassert_not_equal(int_handler_executed, 0,
			  "Interrupt handler did not execute");
	zassert_equal(int_handler_executed, 1,
		      "Interrupt handler executed more than once! (%d)\n",
		      int_handler_executed);

	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;

	zassert_not_equal(exc_handler_executed, 0,
			  "Exception handler did not execute");
	zassert_equal(exc_handler_executed, 1,
		      "Exception handler executed more than once! (%d)\n",
		      exc_handler_executed);
	/*
	 * 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 thread should not run past where the spurious interrupt is
	 * generated. Therefore spur_handler_aborted_thread should remain at 1.
	 */
	zassert_not_equal(spur_handler_aborted_thread, 0,
			  "Spurious handler did not execute as expected");
}

void test_main(void)
{
	ztest_test_suite(static_idt,
			 ztest_unit_test(test_idt_stub),
			 ztest_unit_test(test_static_idt)
			 );
	ztest_run_test_suite(static_idt);
}
