Skip to content

Commit

Permalink
tests: interrupt: refine the interrupt testcases
Browse files Browse the repository at this point in the history
This PR include 2 changes to refine the testcases:
1. Now we using IPI to trigger interrupt in testing instead of INT
   instruction, this means we don't need to hardcode the vector
   number. That can avoid some problem.

Fixes: zephyrproject-rtos#40374

2. Refined the test cases. Tigger interrupt by INT instruction and
   IPI cannot be masked by irq_disabled(). Unless it's a external
   interrupt, such as a timer. Now remove those incorrect part of
   these testcases.

Signed-off-by: Enjia Mai <enjiax.mai@intel.com>
  • Loading branch information
Enjia Mai authored and nashif committed Jan 18, 2022
1 parent db3fa50 commit e61e63e
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 119 deletions.
62 changes: 26 additions & 36 deletions tests/kernel/interrupt/src/direct_isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,13 @@
#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
#define TEST_DIRECT_IRQ_PRIO 5

#endif

Expand Down Expand Up @@ -81,55 +69,57 @@ void test_direct_interrupt(void)
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;
trig_vec1 = TEST_DIRECT_IRQ_LINE_1;
trig_vec2 = TEST_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);
trigger_irq(trig_vec1);

zassert_true(direct_int_executed[0] == 1 &&
direct_int_executed[1] == 0,
"ISR1 should execute");

trigger_irq(TRIGGER_DIRECT_IRQ_LINE_2);
trigger_irq(trig_vec2);

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);
unsigned int key = irq_lock();

trigger_irq(TRIGGER_DIRECT_IRQ_LINE_1);
trigger_irq(TRIGGER_DIRECT_IRQ_LINE_2);
/* trigger under irq locked */
trigger_irq(trig_vec1);
trigger_irq(trig_vec2);

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

irq_unlock(key);

/* interrupt serve after irq unlocked */
zassert_true(direct_int_executed[0] == 2 &&
direct_int_executed[1] == 2,
"Both ISR should execute again(%d)(%d)",
direct_int_executed[0], direct_int_executed[1]);

/* trigger after irq unlocked */
trigger_irq(trig_vec1);
trigger_irq(trig_vec2);

zassert_true(direct_int_executed[0] == 3 &&
direct_int_executed[1] == 3,
"Both ISR should execute again(%d)(%d)",
direct_int_executed[0], direct_int_executed[1]);
}
#else
void test_direct_interrupt(void)
Expand Down
43 changes: 9 additions & 34 deletions tests/kernel/interrupt/src/dynamic_isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ static void dyn_isr(const void *arg)
{
ARG_UNUSED(arg);
handler_test_result = (uintptr_t)arg;
handler_has_run = 1;
handler_has_run++;
}

#if defined(CONFIG_GEN_SW_ISR_TABLE)
Expand Down Expand Up @@ -70,19 +70,10 @@ void test_isr_dynamic(void)
*/
#if defined(CONFIG_X86)
#define IV_IRQS 32 /* start of vectors available for x86 IRQs */

/* Using APIC TSC deadline timer will conflict with our testcase */
#if defined(CONFIG_APIC_TSC_DEADLINE_TIMER)
#define TEST_IRQ_DYN_LINE 17
#else
#define TEST_IRQ_DYN_LINE 16
#endif

#define TRIGGER_IRQ_DYN_LINE (TEST_IRQ_DYN_LINE + IV_IRQS)

#elif defined(CONFIG_ARCH_POSIX)
#define TEST_IRQ_DYN_LINE 5
#define TRIGGER_IRQ_DYN_LINE 5
#endif

void test_isr_dynamic(void)
Expand All @@ -98,38 +89,21 @@ void test_isr_dynamic(void)
extern void (*x86_irq_funcs[])(const void *);
extern const void *x86_irq_args[];

zassert_true(x86_irq_funcs[TEST_IRQ_DYN_LINE] == dyn_isr &&
x86_irq_args[TEST_IRQ_DYN_LINE] == (void *)ISR_DYN_ARG,
zassert_true(x86_irq_funcs[vector_num - IV_IRQS] == dyn_isr &&
x86_irq_args[vector_num - IV_IRQS] == (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");

/*
* The reason we need to hard code the trigger vector here
* is that the x86 only support immediate number for INT
* instruction. So trigger an interrupt of x86 under gcov code
* coverage report enabled, which means GCC optimization will
* be -O0. In this case, an build error happens and shows:
* "error: 'asm' operand 0 probably does not match constraints"
* and "error: impossible constraint in 'asm'"
*
* Although we hard code the trigger vecotr it here, we still
* do a check if the vector match getting from
* arch_irq_connect_dynamic().
*/
zassert_equal(vector_num, TRIGGER_IRQ_DYN_LINE,
"vector %d mismatch we specified to trigger %d",
vector_num, TRIGGER_IRQ_DYN_LINE);

zassert_equal(handler_has_run, 0,
"handler has run before interrupt trigger");

irq_enable(TEST_IRQ_DYN_LINE);

trigger_irq(TRIGGER_IRQ_DYN_LINE);
trigger_irq(vector_num);

zassert_equal(handler_has_run, 1,
"interrupt triggered but handler has not run(%d)",
Expand All @@ -140,12 +114,13 @@ extern const void *x86_irq_args[];
"parameter(0x%lx) in handler is not correct",
handler_test_result);

irq_disable(TRIGGER_IRQ_DYN_LINE);
trigger_irq(vector_num);

/**TESTPOINT: interrupt cannot be triggered when disable it */
zassert_equal(handler_has_run, 1,
"interrupt handler should not be triggered again(%d)",
/**TESTPOINT: interrupt triggered again */
zassert_equal(handler_has_run, 2,
"interrupt triggered but handler has not run(%d)",
handler_has_run);

}
#endif /* CONFIG_GEN_SW_ISR_TABLE */

Expand Down
8 changes: 2 additions & 6 deletions tests/kernel/interrupt/src/interrupt_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,13 @@ void isr_handler(const void *param)
* Other arch will be add later.
*/
#if defined(CONFIG_X86)
#define IV_IRQS 32
#define TEST_IRQ_DYN_LINE 17
#define TRIGGER_IRQ_DYN_LINE (TEST_IRQ_DYN_LINE + IV_IRQS)

#elif defined(CONFIG_ARCH_POSIX)
#define TEST_IRQ_DYN_LINE 5
#define TRIGGER_IRQ_DYN_LINE 5

#else
#define TEST_IRQ_DYN_LINE 0
#define TRIGGER_IRQ_DYN_LINE 0
#endif

#endif
Expand All @@ -114,7 +110,7 @@ static void init_dyn_interrupt(void)
isr_handler, (void *)&irq_param, 0);
}

TC_PRINT("irq(%d)\n", vector_num);
TC_PRINT("vector(%d)\n", vector_num);
zassert_true(vector_num > 0, "no vector can be used");
irq_enable(TEST_IRQ_DYN_LINE);
}
Expand All @@ -124,7 +120,7 @@ static void trigger_offload_interrupt(const bool real_irq, void *work)
irq_param.work = work;

if (real_irq) {
trigger_irq(TRIGGER_IRQ_DYN_LINE);
trigger_irq(vector_num);
} else {
irq_offload((irq_offload_routine_t)&isr_handler, &irq_param);
}
Expand Down
60 changes: 17 additions & 43 deletions tests/kernel/interrupt/src/regular_isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@
#define TEST_IRQ_LINE_1 27
#define TEST_IRQ_LINE_2 28

#define TRIGGER_IRQ_LINE_1 64
#define TRIGGER_IRQ_LINE_2 65

#define TEST_IRQ_PRIO 2


Expand Down Expand Up @@ -61,58 +58,32 @@ void test_isr_regular(void)
IRQ_CONNECT(TEST_IRQ_LINE_1, TEST_IRQ_PRIO, isr_comm, (void *)TEST_IRQ_LINE_1, 0);
IRQ_CONNECT(TEST_IRQ_LINE_2, TEST_IRQ_PRIO, isr_comm, (void *)TEST_IRQ_LINE_2, 0);

#if defined(CONFIG_X86)
trig_vec1 = Z_IRQ_TO_INTERRUPT_VECTOR(TEST_IRQ_LINE_1);
trig_vec2 = Z_IRQ_TO_INTERRUPT_VECTOR(TEST_IRQ_LINE_2);
#elif defined(CONFIG_ARCH_POSIX)
trig_vec1 = TRIGGER_IRQ_LINE_1;
trig_vec2 = TRIGGER_IRQ_LINE_2;
#endif

/* verify the target triggering vector is correct */
zassert_equal(trig_vec1, TRIGGER_IRQ_LINE_1,
"vector %d mismatch we specified to trigger %d",
trig_vec1, TRIGGER_IRQ_LINE_1);

zassert_equal(trig_vec2, TRIGGER_IRQ_LINE_2,
"vector %d mismatch we specified to trigger %d",
trig_vec2, TRIGGER_IRQ_LINE_2);

TC_PRINT("irq(%d)=vector(%d)\n", TEST_IRQ_LINE_1, trig_vec1);
TC_PRINT("irq(%d)=vector(%d)\n", TEST_IRQ_LINE_2, trig_vec2);

irq_enable(TEST_IRQ_LINE_1);
irq_enable(TEST_IRQ_LINE_2);

trigger_irq(TRIGGER_IRQ_LINE_1);
trigger_irq(trig_vec1);

zassert_true(reg_int_executed[0] == 1 &&
reg_int_executed[1] == 0,
"ISR1 should execute");

trigger_irq(TRIGGER_IRQ_LINE_2);
trigger_irq(trig_vec2);

zassert_true(reg_int_executed[0] == 1 &&
reg_int_executed[1] == 1,
"Both ISR should execute");

/* Skip checking here, see #33901 */
#if !defined(CONFIG_X86)

irq_disable(TEST_IRQ_LINE_1);
irq_disable(TEST_IRQ_LINE_2);

/* trigger under irq disabled */
trigger_irq(TRIGGER_IRQ_LINE_1);
trigger_irq(TRIGGER_IRQ_LINE_2);

zassert_true(reg_int_executed[0] == 1 &&
reg_int_executed[1] == 1,
"Both ISR should not execute again");

int key = irq_lock();
unsigned int key = irq_lock();

/* trigger under irq locked */
trigger_irq(TRIGGER_IRQ_LINE_1);
trigger_irq(TRIGGER_IRQ_LINE_2);
trigger_irq(trig_vec1);
trigger_irq(trig_vec2);

zassert_true(reg_int_executed[0] == 1 &&
reg_int_executed[1] == 1,
Expand All @@ -121,17 +92,20 @@ void test_isr_regular(void)

irq_unlock(key);

/* trigger under irq unlocked */
trigger_irq(TRIGGER_IRQ_LINE_1);
trigger_irq(TRIGGER_IRQ_LINE_2);

/* interrupt serve after irq unlocked */
zassert_true(reg_int_executed[0] == 2 &&
reg_int_executed[1] == 2,
"Both ISR should execute again(%d)(%d)",
reg_int_executed[0], reg_int_executed[1]);
#else
TC_PRINT("not testing irq enable/disable\n");
#endif

/* trigger after irq unlocked */
trigger_irq(trig_vec1);
trigger_irq(trig_vec2);

zassert_true(reg_int_executed[0] == 3 &&
reg_int_executed[1] == 3,
"Both ISR should execute again(%d)(%d)",
reg_int_executed[0], reg_int_executed[1]);
}
#else
void test_isr_regular(void)
Expand Down

0 comments on commit e61e63e

Please sign in to comment.