tests: improve test cases for interrupt testing
Improve dynamic interrupt test cases of interrupt for platform such as x86, x86_64, native_posix, this improve code coverage of it. Signed-off-by: Enjia Mai <enjiax.mai@intel.com>
This commit is contained in:
parent
30a1a4bb44
commit
b488b396bb
4 changed files with 155 additions and 8 deletions
|
@ -6,3 +6,8 @@ project(interrupt)
|
||||||
|
|
||||||
FILE(GLOB app_sources src/*.c)
|
FILE(GLOB app_sources src/*.c)
|
||||||
target_sources(app PRIVATE ${app_sources})
|
target_sources(app PRIVATE ${app_sources})
|
||||||
|
|
||||||
|
target_include_directories(app PRIVATE
|
||||||
|
${ZEPHYR_BASE}/kernel/include
|
||||||
|
${ZEPHYR_BASE}/arch/${ARCH}/include
|
||||||
|
)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
CONFIG_ZTEST=y
|
CONFIG_ZTEST=y
|
||||||
CONFIG_DYNAMIC_INTERRUPTS=y
|
CONFIG_DYNAMIC_INTERRUPTS=y
|
||||||
CONFIG_MP_NUM_CPUS=1
|
CONFIG_MP_NUM_CPUS=1
|
||||||
|
CONFIG_THREAD_STACK_INFO=y
|
||||||
|
|
|
@ -5,25 +5,37 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ztest.h>
|
#include <ztest.h>
|
||||||
|
#include "interrupt_util.h"
|
||||||
|
|
||||||
#if defined(CONFIG_DYNAMIC_INTERRUPTS) && defined(CONFIG_GEN_SW_ISR_TABLE)
|
#if defined(CONFIG_DYNAMIC_INTERRUPTS)
|
||||||
extern struct _isr_table_entry __sw_isr_table _sw_isr_table[];
|
|
||||||
extern void z_irq_spurious(const void *unused);
|
#define ISR_DYN_ARG 0xab249cfd
|
||||||
|
|
||||||
|
static unsigned int handler_has_run;
|
||||||
|
static uintptr_t handler_test_result;
|
||||||
|
|
||||||
static void dyn_isr(const void *arg)
|
static void dyn_isr(const void *arg)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(arg);
|
ARG_UNUSED(arg);
|
||||||
|
handler_test_result = (uintptr_t)arg;
|
||||||
|
handler_has_run = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_GEN_SW_ISR_TABLE)
|
||||||
|
extern struct _isr_table_entry __sw_isr_table _sw_isr_table[];
|
||||||
|
extern void z_irq_spurious(const void *unused);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Test dynamic ISR installation
|
* @brief Test dynamic ISR installation
|
||||||
*
|
*
|
||||||
* @ingroup kernel_interrupt_tests
|
* @ingroup kernel_interrupt_tests
|
||||||
*
|
*
|
||||||
* This routine locates an unused entry in the software ISR table, installs a
|
* @details This routine locates an unused entry in the software ISR table,
|
||||||
* dynamic ISR to the unused entry by calling the `arch_irq_connect_dynamic`
|
* installs a dynamic ISR to the unused entry by calling the dynamic
|
||||||
* function, and verifies that the ISR is successfully installed by checking
|
* configured function, and verifies that the ISR is successfully installed
|
||||||
* the software ISR table entry.
|
* by checking the software ISR table entry.
|
||||||
|
*
|
||||||
|
* @see arch_irq_connect_dynamic()
|
||||||
*/
|
*/
|
||||||
void test_isr_dynamic(void)
|
void test_isr_dynamic(void)
|
||||||
{
|
{
|
||||||
|
@ -50,10 +62,76 @@ void test_isr_dynamic(void)
|
||||||
_sw_isr_table[i].arg == argval,
|
_sw_isr_table[i].arg == argval,
|
||||||
"dynamic isr did not install successfully");
|
"dynamic isr did not install successfully");
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* For testing arch such as x86, x86_64 and posix which support dynamic
|
||||||
|
* interrupt but without SW ISR table, we test it by applying for a dynamic
|
||||||
|
* interrupt and then trigger it to check if happened correctly.
|
||||||
|
*/
|
||||||
|
static int get_dynamic_interrupt_line(void)
|
||||||
|
{
|
||||||
|
#ifdef TEST_IRQ_DYN_LINE
|
||||||
|
return TEST_IRQ_DYN_LINE;
|
||||||
|
#else
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_isr_dynamic(void)
|
||||||
|
{
|
||||||
|
int irq_dyn_line;
|
||||||
|
int vector_num;
|
||||||
|
|
||||||
|
/* Get a irq line for dynamic interrupt */
|
||||||
|
irq_dyn_line = get_dynamic_interrupt_line();
|
||||||
|
|
||||||
|
/**TESTPOINT: configuration of interrupts dynamically at runtime */
|
||||||
|
vector_num = arch_irq_connect_dynamic(irq_dyn_line, 1, dyn_isr,
|
||||||
|
(void *)ISR_DYN_ARG, 0);
|
||||||
|
|
||||||
|
#if defined(CONFIG_X86_64)
|
||||||
|
/* The isr table for x86_64 is visiable, so check it up here */
|
||||||
|
extern void (*x86_irq_funcs[])(const void *);
|
||||||
|
extern const void *x86_irq_args[];
|
||||||
|
|
||||||
|
zassert_true(x86_irq_funcs[irq_dyn_line] == dyn_isr &&
|
||||||
|
x86_irq_args[irq_dyn_line] == (void *)ISR_DYN_ARG,
|
||||||
|
"dynamic isr did not install successfully");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TC_PRINT("vector(%d)\n", vector_num);
|
||||||
|
zassert_true(vector_num > 0,
|
||||||
|
"irq connect dynamic failed");
|
||||||
|
|
||||||
|
zassert_equal(handler_has_run, 0,
|
||||||
|
"handler has run before interrupt trigger");
|
||||||
|
|
||||||
|
irq_enable(irq_dyn_line);
|
||||||
|
|
||||||
|
trigger_irq(irq_dyn_line);
|
||||||
|
|
||||||
|
zassert_equal(handler_has_run, 1,
|
||||||
|
"interrupt triggered but handler has not run(%d)",
|
||||||
|
handler_has_run);
|
||||||
|
|
||||||
|
/**TESTPOINT: pass word-sized parameter to interrupt */
|
||||||
|
zassert_equal(handler_test_result, ISR_DYN_ARG,
|
||||||
|
"parameter(0x%lx) in handler is not correct",
|
||||||
|
handler_test_result);
|
||||||
|
|
||||||
|
irq_disable(irq_dyn_line);
|
||||||
|
|
||||||
|
/**TESTPOINT: interrupt cannot be triggered when disable it */
|
||||||
|
zassert_equal(handler_has_run, 1,
|
||||||
|
"interrupt handler should not be triggered again(%d)",
|
||||||
|
handler_has_run);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_GEN_SW_ISR_TABLE */
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* Skip the dynamic interrupt test for the platforms that do not support it */
|
/* Skip the dynamic interrupt test for the platforms that do not support it */
|
||||||
void test_isr_dynamic(void)
|
void test_isr_dynamic(void)
|
||||||
{
|
{
|
||||||
ztest_test_skip();
|
ztest_test_skip();
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_DYNAMIC_INTERRUPTS && CONFIG_GEN_SW_ISR_TABLE */
|
#endif /* CONFIG_DYNAMIC_INTERRUPTS */
|
||||||
|
|
|
@ -99,6 +99,69 @@ static inline void trigger_irq(int irq)
|
||||||
printk("Triggering irq : %d\n", irq);
|
printk("Triggering irq : %d\n", irq);
|
||||||
z_arc_v2_aux_reg_write(_ARC_V2_AUX_IRQ_HINT, irq);
|
z_arc_v2_aux_reg_write(_ARC_V2_AUX_IRQ_HINT, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined(CONFIG_X86)
|
||||||
|
|
||||||
|
#define TEST_IRQ_DYN_LINE 16
|
||||||
|
#define TEST_DYNAMIC_VECTOR TEST_IRQ_DYN_LINE+32
|
||||||
|
|
||||||
|
static inline void trigger_irq(int irq)
|
||||||
|
{
|
||||||
|
int vector = irq + 32;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Trigger an interrupt of x86 under gcov code coverage report enabled,
|
||||||
|
* which means GCC optimization will be -O0, so need to hard code the
|
||||||
|
* immediate number for INT instruction. Otherwise, an build error
|
||||||
|
* happends and shows:
|
||||||
|
* "error: 'asm' operand 0 probably does not match constraints" and
|
||||||
|
* "error: impossible constraint in 'asm'"
|
||||||
|
*/
|
||||||
|
#if defined(CONFIG_COVERAGE)
|
||||||
|
if (vector == TEST_DYNAMIC_VECTOR) {
|
||||||
|
__asm__ volatile("int %0" :: "i"(TEST_DYNAMIC_VECTOR));
|
||||||
|
} else {
|
||||||
|
printk("not interrupt");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
__asm__ volatile("int %0" :: "i"(vector));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(CONFIG_ARCH_POSIX)
|
||||||
|
#include "irq_ctrl.h"
|
||||||
|
|
||||||
|
#define TEST_IRQ_DYN_LINE 5
|
||||||
|
|
||||||
|
static inline void trigger_irq(int irq)
|
||||||
|
{
|
||||||
|
hw_irq_ctrl_raise_im_from_sw(irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(CONFIG_RISCV)
|
||||||
|
static inline void trigger_irq(int irq)
|
||||||
|
{
|
||||||
|
uint32_t mip;
|
||||||
|
|
||||||
|
__asm__ volatile ("csrrs %0, mip, %1\n"
|
||||||
|
: "=r" (mip)
|
||||||
|
: "r" (1 << irq));
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(CONFIG_XTENSA)
|
||||||
|
static inline void trigger_irq(int irq)
|
||||||
|
{
|
||||||
|
z_xt_set_intset(BIT((unsigned int)irq));
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(CONFIG_SPARC)
|
||||||
|
extern void z_sparc_enter_irq(int);
|
||||||
|
|
||||||
|
static inline void trigger_irq(int irq)
|
||||||
|
{
|
||||||
|
z_sparc_enter_irq(irq);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* for not supported architecture */
|
/* for not supported architecture */
|
||||||
#define NO_TRIGGER_FROM_SW
|
#define NO_TRIGGER_FROM_SW
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue