/*
 * 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/kernel.h>
#include <zephyr/ztest.h>
#include <zephyr/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.
 *
 */
ZTEST(static_idt, test_idt_stub)
{
	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
 */

ZTEST(static_idt, test_static_idt)
{
	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");
}

ZTEST_SUITE(static_idt, NULL, NULL, NULL, NULL, NULL);
