tests: interrupt: add test cases of direct interrupt for arch x86 and posix

Add test cases of direct interrupt for arch x86 and posix.

We register two direct interrupt at build time, then triggering
interrupt and check if ISR handler has executed or not. We also
check irq_enable and irq_disable works.

Why we add an extra compiler option "-mgeneral-regs-only" to make
it works in arch x86. because there might be some existing x87
instructions executing inside interrupt context.

Signed-off-by: Enjia Mai <enjiax.mai@intel.com>
This commit is contained in:
Enjia Mai 2021-03-29 22:27:13 +08:00 committed by Anas Nashif
commit c9c8cec3b6
3 changed files with 155 additions and 2 deletions

View file

@ -0,0 +1,139 @@
/*
* Copyright (c) 2021 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <ztest.h>
#include "interrupt_util.h"
/*
* Other arch has already been tested in testcase of gen_isr_table,
* so we only test x86 and arch posix here.
* And x86_64 is also not support this kind of interrupt, we skip it.
*/
#if (defined(CONFIG_X86) && !defined(CONFIG_X86_64)) ||\
defined(CONFIG_ARCH_POSIX)
#if defined(CONFIG_X86)
#define TEST_DIRECT_IRQ_LINE_1 3
#define TEST_DIRECT_IRQ_LINE_2 4
/* the vector got would be different when enable code coverage */
#if defined(CONFIG_COVERAGE)
#define TRIGGER_DIRECT_IRQ_LINE_1 34
#define TRIGGER_DIRECT_IRQ_LINE_2 35
#else
#define TRIGGER_DIRECT_IRQ_LINE_1 35
#define TRIGGER_DIRECT_IRQ_LINE_2 34
#endif
#define TEST_DIRECT_IRQ_PRIO 0
#elif defined(CONFIG_ARCH_POSIX)
#define TEST_DIRECT_IRQ_LINE_1 5
#define TEST_DIRECT_IRQ_LINE_2 6
#define TRIGGER_DIRECT_IRQ_LINE_1 TEST_DIRECT_IRQ_LINE_1
#define TRIGGER_DIRECT_IRQ_LINE_2 TEST_DIRECT_IRQ_LINE_2
#define TEST_DIRECT_IRQ_PRIO 1
#endif
volatile uint32_t direct_int_executed[2];
ISR_DIRECT_DECLARE(direct_isr1)
{
direct_int_executed[0]++;
return 0;
}
ISR_DIRECT_DECLARE(direct_isr2)
{
direct_int_executed[1]++;
return 1;
}
/**
* @brief Test direct interrupt function
*
* @details validate direct interrupt works as expected.
* - Register two direct interrupt at build time.
* - Trigger interrupt and check if isr handler has executed or not.
* - Also check irq_enable and irq_disable works.
*
* @ingroup kernel_interrupt_tests
*
* @see IRQ_DIRECT_CONNECT(), ISR_DIRECT_DECLARE()
*/
void test_direct_interrupt(void)
{
int trig_vec1, trig_vec2;
IRQ_DIRECT_CONNECT(TEST_DIRECT_IRQ_LINE_1, TEST_DIRECT_IRQ_PRIO, direct_isr1, 0);
IRQ_DIRECT_CONNECT(TEST_DIRECT_IRQ_LINE_2, TEST_DIRECT_IRQ_PRIO, direct_isr2, 0);
#if defined(CONFIG_X86)
trig_vec1 = Z_IRQ_TO_INTERRUPT_VECTOR(TEST_DIRECT_IRQ_LINE_1);
trig_vec2 = Z_IRQ_TO_INTERRUPT_VECTOR(TEST_DIRECT_IRQ_LINE_2);
#elif defined(CONFIG_ARCH_POSIX)
trig_vec1 = TRIGGER_DIRECT_IRQ_LINE_1;
trig_vec2 = TRIGGER_DIRECT_IRQ_LINE_2;
#endif
TC_PRINT("irq(%d)=vector(%d)\n", TEST_DIRECT_IRQ_LINE_1, trig_vec1);
TC_PRINT("irq(%d)=vector(%d)\n", TEST_DIRECT_IRQ_LINE_2, trig_vec2);
/* verify the target triggering vector is correct */
zassert_equal(trig_vec1, TRIGGER_DIRECT_IRQ_LINE_1,
"vector %d mismatch we specified to trigger %d",
trig_vec1, TRIGGER_DIRECT_IRQ_LINE_1);
zassert_equal(trig_vec2, TRIGGER_DIRECT_IRQ_LINE_2,
"vector %d mismatch we specified to trigger %d",
trig_vec2, TRIGGER_DIRECT_IRQ_LINE_2);
irq_enable(TEST_DIRECT_IRQ_LINE_1);
irq_enable(TEST_DIRECT_IRQ_LINE_2);
zassert_true(direct_int_executed[0] == 0 &&
direct_int_executed[1] == 0,
"Both ISR should not execute");
trigger_irq(TRIGGER_DIRECT_IRQ_LINE_1);
zassert_true(direct_int_executed[0] == 1 &&
direct_int_executed[1] == 0,
"ISR1 should execute");
trigger_irq(TRIGGER_DIRECT_IRQ_LINE_2);
zassert_true(direct_int_executed[0] == 1 &&
direct_int_executed[1] == 1,
"Both ISR should execute");
irq_disable(TEST_DIRECT_IRQ_LINE_1);
irq_disable(TEST_DIRECT_IRQ_LINE_2);
trigger_irq(TRIGGER_DIRECT_IRQ_LINE_1);
trigger_irq(TRIGGER_DIRECT_IRQ_LINE_2);
/*
* irq_enable()/irq_disable() does not work here,
* see #33901.
*/
#if !defined(CONFIG_X86)
zassert_true(direct_int_executed[0] == 1 &&
direct_int_executed[1] == 1,
"Both ISR should not execute again");
#endif
}
#else
void test_direct_interrupt(void)
{
ztest_test_skip();
}
#endif /* end defined(CONFIG_X86) || defined(CONFIG_ARCH_POSIX) */

View file

@ -13,6 +13,7 @@ extern void test_isr_regular(void);
extern void test_isr_offload_job_multiple(void);
extern void test_isr_offload_job_identi(void);
extern void test_isr_offload_job(void);
extern void test_direct_interrupt(void);
void test_main(void)
{
@ -23,7 +24,8 @@ void test_main(void)
ztest_unit_test(test_isr_regular),
ztest_unit_test(test_isr_offload_job_multiple),
ztest_unit_test(test_isr_offload_job_identi),
ztest_unit_test(test_isr_offload_job)
ztest_unit_test(test_isr_offload_job),
ztest_unit_test(test_direct_interrupt)
);
ztest_run_test_suite(interrupt_feature);
}

View file

@ -1,6 +1,18 @@
tests:
arch.interrupt:
# nios2 excluded, see #22956
arch_exclude: nios2
arch_exclude: nios2 x86
tags: kernel interrupt
filter: not CONFIG_TRUSTED_EXECUTION_NONSECURE
arch.interrupt.x86_64:
arch_allow: x86
tags: kernel interrupt
filter: CONFIG_X86_64
arch.interrupt.x86:
arch_allow: x86
tags: kernel interrupt
filter: not CONFIG_X86_64
extra_configs:
- CONFIG_COMPILER_OPT="-mgeneral-regs-only"