tests: port static_idt test to unified kernel
Change-Id: Ida4333b91ad322ff676cfbaa2ccaab0bdd38cd48 Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
5bb0169d02
commit
7a90ab448b
19 changed files with 107 additions and 467 deletions
|
@ -1,4 +1,3 @@
|
|||
MDEF_FILE = prj.mdef
|
||||
BOARD ?= qemu_x86
|
||||
CONF_FILE = prj.conf
|
||||
|
34
tests/kernel/static_idt/README.txt
Normal file
34
tests/kernel/static_idt/README.txt
Normal file
|
@ -0,0 +1,34 @@
|
|||
Title: Static IDT Support
|
||||
|
||||
Description:
|
||||
|
||||
This test verifies that the static IDT feature operates as expected.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Building and Running Project:
|
||||
|
||||
This project outputs to the console. It can be built and executed
|
||||
on QEMU as follows:
|
||||
|
||||
make run
|
||||
|
||||
|
||||
Sample Output:
|
||||
|
||||
tc_start() - Starting static IDT tests
|
||||
Testing to see if IDT has address of test stubs()
|
||||
Testing to see interrupt handler executes properly
|
||||
Testing to see exception handler executes properly
|
||||
Testing to see spurious handler executes properly
|
||||
- Expect to see unhandled interrupt/exception message
|
||||
***** Unhandled interrupt vector *****
|
||||
Current thread ID = 0x001028e0
|
||||
Faulting segment:address = 0x8:0x1001c9
|
||||
eax: 0xa, ebx: 0x0, ecx: 0x1018e0, edx: 0xa
|
||||
esi: 0x0, edi: 0x0, ebp: 01030b4, esp: 0x1030b4
|
||||
eflags: 0x202
|
||||
Fatal fault in thread 0x001028e0! Aborting.
|
||||
PASS - main.
|
||||
===================================================================
|
||||
PROJECT EXECUTION SUCCESSFUL
|
|
@ -1,2 +1,3 @@
|
|||
CONFIG_EXCEPTION_DEBUG=n
|
||||
CONFIG_LEGACY_KERNEL=y
|
||||
CONFIG_MAIN_THREAD_PRIORITY=6
|
|
@ -1,4 +1,3 @@
|
|||
/* static_idt.c - test static IDT APIs */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Wind River Systems, Inc.
|
||||
|
@ -6,9 +5,10 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
Ensures interrupt and exception stubs are installed correctly.
|
||||
/**
|
||||
* @file
|
||||
* test static IDT APIs
|
||||
* Ensures interrupt and exception stubs are installed correctly.
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
|
@ -26,43 +26,48 @@ Ensures interrupt and exception stubs are installed correctly.
|
|||
#define TEST_SOFT_INT 62
|
||||
#define TEST_SPUR_INT 63
|
||||
|
||||
|
||||
#define MY_STACK_SIZE 2048
|
||||
#define MY_PRIORITY 5
|
||||
|
||||
char __noinit __stack my_stack_area[MY_STACK_SIZE];
|
||||
|
||||
/* externs */
|
||||
|
||||
/* the _idt_base_address symbol is generated via a linker script */
|
||||
/* The _idt_base_address symbol is generated via a linker script */
|
||||
|
||||
extern unsigned char _idt_base_address[];
|
||||
|
||||
extern void *nanoIntStub;
|
||||
NANO_CPU_INT_REGISTER(nanoIntStub, -1, -1, TEST_SOFT_INT, 0);
|
||||
extern void *int_stub;
|
||||
NANO_CPU_INT_REGISTER(int_stub, -1, -1, TEST_SOFT_INT, 0);
|
||||
|
||||
static volatile int excHandlerExecuted;
|
||||
static volatile int intHandlerExecuted;
|
||||
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 spurHandlerAbortedThread = 1;
|
||||
static volatile int spur_handler_aborted_thread = 1;
|
||||
|
||||
|
||||
/**
|
||||
* Handler to perform various actions from within an ISR context
|
||||
*
|
||||
* isr_handler - handler to perform various actions from within an ISR context
|
||||
*
|
||||
* This routine is the ISR handler for _trigger_isrHandler().
|
||||
* This routine is the ISR handler for _trigger_isr_handler().
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
|
||||
void isr_handler(void)
|
||||
{
|
||||
intHandlerExecuted++;
|
||||
int_handler_executed++;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* exc_divide_error_handler -
|
||||
* This is the handler for the divde by zero exception.
|
||||
*
|
||||
* 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 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
|
||||
|
@ -75,16 +80,16 @@ void isr_handler(void)
|
|||
* @return N/A
|
||||
*/
|
||||
|
||||
void exc_divide_error_handler(NANO_ESF *pEsf)
|
||||
void exc_divide_error_handler(NANO_ESF *p_esf)
|
||||
{
|
||||
pEsf->eip += 2;
|
||||
excHandlerExecuted = 1; /* provide evidence that the handler executed */
|
||||
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
|
||||
|
@ -93,26 +98,26 @@ extern void *_EXCEPTION_STUB_NAME(exc_divide_error_handler, IV_DIVIDE_ERROR);
|
|||
* @return TC_PASS on success, TC_FAIL on failure
|
||||
*/
|
||||
|
||||
int nanoIdtStubTest(void)
|
||||
int idt_stub_test(void)
|
||||
{
|
||||
struct segment_descriptor *pIdtEntry;
|
||||
struct segment_descriptor *p_idt_entry;
|
||||
uint32_t offset;
|
||||
|
||||
/* Check for the interrupt stub */
|
||||
pIdtEntry = (struct segment_descriptor *)
|
||||
(_idt_base_address + (TEST_SOFT_INT << 3));
|
||||
offset = (uint32_t)(&nanoIntStub);
|
||||
if (DTE_OFFSET(pIdtEntry) != offset) {
|
||||
TC_ERROR("Failed to find offset of nanoIntStub (0x%x) at vector %d\n",
|
||||
p_idt_entry = (struct segment_descriptor *)
|
||||
(_idt_base_address + (TEST_SOFT_INT << 3));
|
||||
offset = (uint32_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 */
|
||||
pIdtEntry = (struct segment_descriptor *)
|
||||
(_idt_base_address + (IV_DIVIDE_ERROR << 3));
|
||||
p_idt_entry = (struct segment_descriptor *)
|
||||
(_idt_base_address + (IV_DIVIDE_ERROR << 3));
|
||||
offset = (uint32_t)(&_EXCEPTION_STUB_NAME(exc_divide_error_handler, 0));
|
||||
if (DTE_OFFSET(pIdtEntry) != offset) {
|
||||
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;
|
||||
|
@ -126,25 +131,23 @@ int nanoIdtStubTest(void)
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Task to test spurious handlers
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
|
||||
void idtSpurTask(void)
|
||||
void idt_spur_task(void *arg1, void *arg2, void *arg3)
|
||||
{
|
||||
TC_PRINT("- Expect to see unhandled interrupt/exception message\n");
|
||||
|
||||
_trigger_spurHandler();
|
||||
_trigger_spur_handler();
|
||||
|
||||
/* Shouldn't get here */
|
||||
spurHandlerAbortedThread = 0;
|
||||
spur_handler_aborted_thread = 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Entry point to static IDT tests
|
||||
*
|
||||
* This is the entry point to the static IDT tests.
|
||||
|
@ -152,69 +155,72 @@ void idtSpurTask(void)
|
|||
* @return N/A
|
||||
*/
|
||||
|
||||
void idtTestTask(void)
|
||||
void main(void)
|
||||
{
|
||||
int rv; /* return value from tests */
|
||||
volatile int error; /* used to create a divide by zero error */
|
||||
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 = nanoIdtStubTest();
|
||||
rv = idt_stub_test();
|
||||
if (rv != TC_PASS) {
|
||||
goto doneTests;
|
||||
goto done_tests;
|
||||
}
|
||||
|
||||
TC_PRINT("Testing to see interrupt handler executes properly\n");
|
||||
_trigger_isrHandler();
|
||||
_trigger_isr_handler();
|
||||
|
||||
if (intHandlerExecuted == 0) {
|
||||
if (int_handler_executed == 0) {
|
||||
TC_ERROR("Interrupt handler did not execute\n");
|
||||
rv = TC_FAIL;
|
||||
goto doneTests;
|
||||
} else if (intHandlerExecuted != 1) {
|
||||
goto done_tests;
|
||||
} else if (int_handler_executed != 1) {
|
||||
TC_ERROR("Interrupt handler executed more than once! (%d)\n",
|
||||
intHandlerExecuted);
|
||||
int_handler_executed);
|
||||
rv = TC_FAIL;
|
||||
goto doneTests;
|
||||
goto done_tests;
|
||||
}
|
||||
|
||||
TC_PRINT("Testing to see exception handler executes properly\n");
|
||||
|
||||
/*
|
||||
* Use excHandlerExecuted instead of 0 to prevent the compiler issuing a
|
||||
* 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 / excHandlerExecuted;
|
||||
error = 32; /* avoid static checker uninitialized warnings */
|
||||
error = error / exc_handler_executed;
|
||||
|
||||
if (excHandlerExecuted == 0) {
|
||||
if (exc_handler_executed == 0) {
|
||||
TC_ERROR("Exception handler did not execute\n");
|
||||
rv = TC_FAIL;
|
||||
goto doneTests;
|
||||
} else if (excHandlerExecuted != 1) {
|
||||
goto done_tests;
|
||||
} else if (exc_handler_executed != 1) {
|
||||
TC_ERROR("Exception handler executed more than once! (%d)\n",
|
||||
excHandlerExecuted);
|
||||
exc_handler_executed);
|
||||
rv = TC_FAIL;
|
||||
goto doneTests;
|
||||
goto done_tests;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start task to trigger the spurious interrupt handler
|
||||
*/
|
||||
TC_PRINT("Testing to see spurious handler executes properly\n");
|
||||
task_start(tSpurTask);
|
||||
k_thread_spawn(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 spurHandlerAbortedThread should remain at 1.
|
||||
* generated. Therefore spur_handler_aborted_thread should remain at 1.
|
||||
*/
|
||||
if (spurHandlerAbortedThread == 0) {
|
||||
if (spur_handler_aborted_thread == 0) {
|
||||
TC_ERROR("Spurious handler did not execute as expected\n");
|
||||
rv = TC_FAIL;
|
||||
goto doneTests;
|
||||
goto done_tests;
|
||||
}
|
||||
|
||||
doneTests:
|
||||
done_tests:
|
||||
TC_END(rv, "%s - %s.\n", rv == TC_PASS ? PASS : FAIL, __func__);
|
||||
TC_END_REPORT(rv);
|
||||
}
|
|
@ -13,7 +13,7 @@
|
|||
#error test_asm_inline_gcc.h goes only with x86 GCC
|
||||
#endif
|
||||
|
||||
#define _trigger_isrHandler() __asm__ volatile("int %0" : : "i" (TEST_SOFT_INT) : "memory")
|
||||
#define _trigger_spurHandler() __asm__ volatile("int %0" : : "i" (TEST_SPUR_INT) : "memory")
|
||||
#define _trigger_isr_handler() __asm__ volatile("int %0" : : "i" (TEST_SOFT_INT) : "memory")
|
||||
#define _trigger_spur_handler() __asm__ volatile("int %0" : : "i" (TEST_SPUR_INT) : "memory")
|
||||
|
||||
#endif /* _TEST_ASM_INLINE_GCC_H */
|
|
@ -27,8 +27,8 @@ testing.
|
|||
|
||||
/* Static interrupt handler stubs */
|
||||
|
||||
GTEXT(nanoIntStub)
|
||||
SECTION_FUNC(TEXT, nanoIntStub)
|
||||
GTEXT(int_stub)
|
||||
SECTION_FUNC(TEXT, int_stub)
|
||||
pushl $0
|
||||
pushl $isr_handler
|
||||
jmp _interrupt_enter
|
|
@ -1,6 +0,0 @@
|
|||
#
|
||||
# This TC will force a fatal fault, as it is testing it. Don't error
|
||||
# if we find it (cancel out the default setting in root's defaults.tc
|
||||
# that will consider a testcase toast if a fatal fault is found
|
||||
#
|
||||
# ^eval console-rx %(console)s::pass [Ff]atal fault in
|
|
@ -1,45 +0,0 @@
|
|||
Title: Static IDT Support
|
||||
|
||||
Description:
|
||||
|
||||
This test verifies that the static IDT feature operates as expected.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Building and Running Project:
|
||||
|
||||
This microkernel project outputs to the console. It can be built and executed
|
||||
on QEMU as follows:
|
||||
|
||||
make qemu
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Troubleshooting:
|
||||
|
||||
Problems caused by out-dated project information can be addressed by
|
||||
issuing one of the following commands then rebuilding the project:
|
||||
|
||||
make clean # discard results of previous builds
|
||||
# but keep existing configuration info
|
||||
or
|
||||
make pristine # discard results of previous builds
|
||||
# and restore pre-defined configuration info
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Sample Output:
|
||||
|
||||
tc_start() - Test Nanokernel static IDT tests
|
||||
Testing to see if IDT has address of test stubs()
|
||||
Testing to see interrupt handler executes properly
|
||||
Testing to see exception handler executes properly
|
||||
Testing to see spurious handler executes properly
|
||||
- Expect to see unhandled interrupt/exception message
|
||||
***** Unhandled exception/interrupt occurred! *****
|
||||
Current context ID = 0x00102c44
|
||||
Faulting instruction address = 0x0010342c
|
||||
Fatal task error! Aborting task.
|
||||
PASS - idtTestTask.
|
||||
===================================================================
|
||||
PROJECT EXECUTION SUCCESSFUL
|
|
@ -1,2 +0,0 @@
|
|||
CONFIG_EXCEPTION_DEBUG=n
|
||||
CONFIG_LEGACY_KERNEL=y
|
|
@ -1,6 +0,0 @@
|
|||
% Application : test static interrutps
|
||||
|
||||
% TASK NAME PRIO ENTRY STACK GROUPS
|
||||
% ==================================================
|
||||
TASK tStartTask 6 idtTestTask 2048 [EXE]
|
||||
TASK tSpurTask 5 idtSpurTask 2048 []
|
|
@ -1,4 +0,0 @@
|
|||
BOARD ?= qemu_x86
|
||||
CONF_FILE = prj.conf
|
||||
|
||||
include $(ZEPHYR_BASE)/Makefile.test
|
|
@ -1,46 +0,0 @@
|
|||
Title: Static IDT Support
|
||||
|
||||
Description:
|
||||
|
||||
This test verifies that the static IDT feature operates as expected in a
|
||||
nanokernel environment.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Building and Running Project:
|
||||
|
||||
This nanokernel project outputs to the console. It can be built and executed
|
||||
on QEMU as follows:
|
||||
|
||||
make qemu
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Troubleshooting:
|
||||
|
||||
Problems caused by out-dated project information can be addressed by
|
||||
issuing one of the following commands then rebuilding the project:
|
||||
|
||||
make clean # discard results of previous builds
|
||||
# but keep existing configuration info
|
||||
or
|
||||
make pristine # discard results of previous builds
|
||||
# and restore pre-defined configuration info
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Sample Output:
|
||||
|
||||
tc_start() - Test Nanokernel static IDT tests
|
||||
Testing to see if IDT has address of test stubs()
|
||||
Testing to see interrupt handler executes properly
|
||||
Testing to see exception handler executes properly
|
||||
Testing to see spurious handler executes properly
|
||||
- Expect to see unhandled interrupt/exception message
|
||||
***** Unhandled exception/interrupt occurred! *****
|
||||
Current context ID = 0x00102a68
|
||||
Faulting instruction address = 0x00102c50
|
||||
Fatal fiber error! Aborting fiber.
|
||||
PASS - main.
|
||||
===================================================================
|
||||
PROJECT EXECUTION SUCCESSFUL
|
|
@ -1,3 +0,0 @@
|
|||
ccflags-y += -I${ZEPHYR_BASE}/tests/include
|
||||
|
||||
obj-y = static_idt.o test_stubs.o
|
|
@ -1,226 +0,0 @@
|
|||
/* static_idt.c - test static IDT APIs */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
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 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;
|
||||
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 fiber */
|
||||
static volatile int spurHandlerAbortedThread = 1;
|
||||
|
||||
#define STACK_SIZE 1024
|
||||
static char __stack fiberStack[STACK_SIZE];
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 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);
|
||||
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 nanoIdtStubTest(void)
|
||||
{
|
||||
struct segment_descriptor *pIdtEntry;
|
||||
uint32_t offset;
|
||||
|
||||
/* Check for the interrupt stub */
|
||||
pIdtEntry = (struct segment_descriptor *)
|
||||
(_idt_base_address + (TEST_SOFT_INT << 3));
|
||||
offset = (uint32_t)(&nanoIntStub);
|
||||
if (DTE_OFFSET(pIdtEntry) != offset) {
|
||||
TC_ERROR("Failed to find offset of nanoIntStub (0x%x) at vector %d\n",
|
||||
offset, TEST_SOFT_INT);
|
||||
return TC_FAIL;
|
||||
}
|
||||
|
||||
/* Check for the exception stub */
|
||||
pIdtEntry = (struct segment_descriptor *)
|
||||
(_idt_base_address + (IV_DIVIDE_ERROR << 3));
|
||||
offset = (uint32_t)(&_EXCEPTION_STUB_NAME(exc_divide_error_handler, 0));
|
||||
if (DTE_OFFSET(pIdtEntry) != 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 Fiber to test spurious handlers
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
|
||||
static void idtSpurFiber(int a1, int a2)
|
||||
{
|
||||
ARG_UNUSED(a1);
|
||||
ARG_UNUSED(a2);
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
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 = 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 = 32;
|
||||
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 to trigger the spurious interrupt handler
|
||||
*/
|
||||
TC_PRINT("Testing to see spurious handler executes properly\n");
|
||||
task_fiber_start(fiberStack, sizeof(fiberStack), idtSpurFiber, 0, 0, 5, 0);
|
||||
/*
|
||||
* 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);
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/* Intel x86 GCC specific test inline assembler functions and macros */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015, Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _TEST_ASM_INLINE_GCC_H
|
||||
#define _TEST_ASM_INLINE_GCC_H
|
||||
|
||||
#if !defined(__GNUC__) || !defined(CONFIG_X86)
|
||||
#error test_asm_inline_gcc.h goes only with x86 GCC
|
||||
#endif
|
||||
|
||||
#define _trigger_isrHandler() __asm__ volatile("int %0" : : "i" (TEST_SOFT_INT) : "memory")
|
||||
#define _trigger_spurHandler() __asm__ volatile("int %0" : : "i" (TEST_SPUR_INT) : "memory")
|
||||
|
||||
#endif /* _TEST_ASM_INLINE_GCC_H */
|
|
@ -1,39 +0,0 @@
|
|||
/* test_stubs.S - Exception and interrupt stubs */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This module implements assembler exception and interrupt stubs for regression
|
||||
testing.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ISA_IA32
|
||||
|
||||
/* IA-32 specific */
|
||||
|
||||
#include <arch/cpu.h>
|
||||
#include <kernel_structs.h>
|
||||
#include <arch/x86/asm.h>
|
||||
#include <asm_inline.h>
|
||||
|
||||
/* imports (internal APIs) */
|
||||
|
||||
GTEXT(_interrupt_enter)
|
||||
|
||||
/* Static interrupt handler stubs */
|
||||
|
||||
GTEXT(nanoIntStub)
|
||||
SECTION_FUNC(TEXT, nanoIntStub)
|
||||
pushl $0
|
||||
pushl $isr_handler
|
||||
jmp _interrupt_enter
|
||||
#else
|
||||
|
||||
#error Arch not supported
|
||||
|
||||
#endif /* CONFIG_ISA_IA32 */
|
|
@ -1,4 +0,0 @@
|
|||
[test]
|
||||
tags = legacy core bat_commit ignore_faults
|
||||
arch_whitelist = x86
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue