Skip to content

Commit

Permalink
tests: kernel: gen_isr_table: support ISR_TABLE_USE_INTERUPT_ID option
Browse files Browse the repository at this point in the history
When CONFIG_ISR_TABLE_USE_INTERUPT_ID is enabled, the isr table is
reordered. I modified it to reference the IRQ number and the operation
when the option is enabled to work correctly.
The table reordering only applies to ISRs defined with IRQ_CONNECT or
IRQ_DIRECT_CONNECT and does not affect interrupts enabled in code with
irq_connect_dynamic.

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
  • Loading branch information
soburi committed Jul 21, 2024
1 parent 0e0773e commit 98b6c13
Showing 1 changed file with 71 additions and 28 deletions.
99 changes: 71 additions & 28 deletions tests/kernel/gen_isr_table/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

extern uint32_t _irq_vector_table[];

typedef int (*translate_fn)(int);

#if defined(ARCH_IRQ_DIRECT_CONNECT) && defined(CONFIG_GEN_IRQ_VECTOR_TABLE)
#define HAS_DIRECT_IRQS
#endif
Expand Down Expand Up @@ -179,18 +181,18 @@ void isr6(const void *param)
*/
__no_optimization
#endif
int test_irq(int offset)
int test_irq(int offset, translate_fn translate)
{
#ifndef NO_TRIGGER_FROM_SW
TC_PRINT("triggering irq %d\n", IRQ_LINE(offset));
trigger_irq(IRQ_LINE(offset));
TC_PRINT("triggering irq %d\n", translate(IRQ_LINE(offset)));
trigger_irq(translate(IRQ_LINE(offset)));
#ifdef CONFIG_CPU_CORTEX_M
barrier_dsync_fence_full();
barrier_isync_fence_full();
#endif
if (trigger_check[offset] != 1) {
TC_PRINT("interrupt %d didn't run once, ran %d times\n",
IRQ_LINE(offset),
translate(IRQ_LINE(offset)),
trigger_check[offset]);
return -1;
}
Expand All @@ -201,10 +203,31 @@ int test_irq(int offset)
return 0;
}

static inline int passthrough(int x)
{
return x;
}

#if defined(CONFIG_ISR_TABLE_USE_INTERRUPT_ID)
static inline int intr_id_lookup(int x)
{
return __intr_id_table[x];
}

static inline int table_index(int offset, translate_fn translate)
{
return translate(IRQ_LINE(offset));
}

#elif defined(CONFIG_GEN_SW_ISR_TABLE)
static inline int table_index(int offset, translate_fn translate)
{
return TABLE_INDEX(offset);
}
#endif

#ifdef HAS_DIRECT_IRQS
static int check_vector(void *isr, int offset)
static int check_vector(void *isr, int offset, translate_fn translate)
{
/*
* The problem with an IRQ table where the entries are jump opcodes is that it
Expand All @@ -213,16 +236,21 @@ static int check_vector(void *isr, int offset)
* dependent). For the sake of simplicity just skip the checks.
*/
#ifndef CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_CODE
#ifndef CONFIG_ISR_TABLE_USE_INTERRUPT_ID
TC_PRINT("Checking _irq_vector_table entry %d for irq %d\n",
TABLE_INDEX(offset), IRQ_LINE(offset));
table_index(offset, translate), translate(IRQ_LINE(offset)));
#else
TC_PRINT("Checking _irq_vector_table entry %d for irq %d id %d\n",
table_index(offset, translate), translate(IRQ_LINE(offset)), IRQ_LINE(offset));
#endif

if (_irq_vector_table[TABLE_INDEX(offset)] != (uint32_t)isr) {
TC_PRINT("bad entry %d in vector table\n", TABLE_INDEX(offset));
if (_irq_vector_table[table_index(offset, translate)] != (uint32_t)isr) {
TC_PRINT("bad entry %d in vector table\n", table_index(offset, translate));
return -1;
}
#endif /* !CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_CODE */

if (test_irq(offset)) {
if (test_irq(offset, translate)) {
return -1;
}

Expand All @@ -231,12 +259,17 @@ static int check_vector(void *isr, int offset)
#endif

#ifdef CONFIG_GEN_SW_ISR_TABLE
static int check_sw_isr(void *isr, uintptr_t arg, int offset)
static int check_sw_isr(void *isr, uintptr_t arg, int offset, translate_fn translate)
{
struct _isr_table_entry *e = &_sw_isr_table[TABLE_INDEX(offset)];
struct _isr_table_entry *e = &_sw_isr_table[table_index(offset, translate)];

#ifndef CONFIG_ISR_TABLE_USE_INTERRUPT_ID
TC_PRINT("Checking _sw_isr_table entry %d for irq %d\n",
TABLE_INDEX(offset), IRQ_LINE(offset));
table_index(offset, translate), translate(IRQ_LINE(offset)));
#else
TC_PRINT("Checking _sw_isr_table entry %d for irq %d id %d\n",
table_index(offset, translate), translate(IRQ_LINE(offset)), IRQ_LINE(offset));
#endif

if (e->arg != (void *)arg) {
TC_PRINT("bad argument in SW isr table\n");
Expand All @@ -249,15 +282,15 @@ static int check_sw_isr(void *isr, uintptr_t arg, int offset)
return -1;
}
#if defined(CONFIG_GEN_IRQ_VECTOR_TABLE) && !defined(CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_CODE)
void *v = (void *)_irq_vector_table[TABLE_INDEX(offset)];
void *v = (void *)_irq_vector_table[table_index(offset, translate)];
if (v != _isr_wrapper) {
TC_PRINT("Vector does not point to _isr_wrapper\n");
TC_PRINT("expected %p got %p\n", _isr_wrapper, v);
return -1;
}
#endif /* CONFIG_GEN_IRQ_VECTOR_TABLE && !CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_CODE */

if (test_irq(offset)) {
if (test_irq(offset, translate)) {
return -1;
}
return 0;
Expand Down Expand Up @@ -285,21 +318,26 @@ ZTEST(gen_isr_table, test_build_time_direct_interrupt)
ztest_test_skip();
#else

#if defined(ISR1_OFFSET) || defined(ISR2_OFFSET)
translate_fn translate =
COND_CODE_1(CONFIG_ISR_TABLE_USE_INTERRUPT_ID, (intr_id_lookup), (passthrough));
#endif

#ifdef ISR1_OFFSET
IRQ_DIRECT_CONNECT(IRQ_LINE(ISR1_OFFSET), 0, isr1, IRQ_FLAGS);
irq_enable(IRQ_LINE(ISR1_OFFSET));
TC_PRINT("isr1 isr=%p irq=%d\n", isr1, IRQ_LINE(ISR1_OFFSET));
zassert_ok(check_vector(isr1, ISR1_OFFSET),
irq_enable(translate(IRQ_LINE(ISR1_OFFSET)));
TC_PRINT("isr1 isr=%p irq=%d\n", isr1, translate(IRQ_LINE(ISR1_OFFSET)));
zassert_ok(check_vector(isr1, ISR1_OFFSET, translate),
"check direct interrpt isr1 failed");
#endif

#ifdef ISR2_OFFSET
IRQ_DIRECT_CONNECT(IRQ_LINE(ISR2_OFFSET), 0, isr2, IRQ_FLAGS);
irq_enable(IRQ_LINE(ISR2_OFFSET));
TC_PRINT("isr2 isr=%p irq=%d\n", isr2, IRQ_LINE(ISR2_OFFSET));
irq_enable(translate(IRQ_LINE(ISR2_OFFSET)));
TC_PRINT("isr2 isr=%p irq=%d\n", isr2, translate(IRQ_LINE(ISR2_OFFSET)));


zassert_ok(check_vector(isr2, ISR2_OFFSET),
zassert_ok(check_vector(isr2, ISR2_OFFSET, translate),
"check direct interrpt isr2 failed");
#endif
#endif
Expand Down Expand Up @@ -328,23 +366,28 @@ ZTEST(gen_isr_table, test_build_time_interrupt)
#else
TC_PRINT("_sw_isr_table at location %p\n", _sw_isr_table);

#if defined(ISR3_OFFSET) || defined(ISR4_OFFSET)
translate_fn translate =
COND_CODE_1(CONFIG_ISR_TABLE_USE_INTERRUPT_ID, (intr_id_lookup), (passthrough));
#endif

#ifdef ISR3_OFFSET
IRQ_CONNECT(IRQ_LINE(ISR3_OFFSET), 1, isr3, ISR3_ARG, IRQ_FLAGS);
irq_enable(IRQ_LINE(ISR3_OFFSET));
TC_PRINT("isr3 isr=%p irq=%d param=%p\n", isr3, IRQ_LINE(ISR3_OFFSET),
irq_enable(translate(IRQ_LINE(ISR3_OFFSET)));
TC_PRINT("isr3 isr=%p irq=%d param=%p\n", isr3, translate(IRQ_LINE(ISR3_OFFSET)),
(void *)ISR3_ARG);

zassert_ok(check_sw_isr(isr3, ISR3_ARG, ISR3_OFFSET),
zassert_ok(check_sw_isr(isr3, ISR3_ARG, ISR3_OFFSET, translate),
"check interrupt isr3 failed");
#endif

#ifdef ISR4_OFFSET
IRQ_CONNECT(IRQ_LINE(ISR4_OFFSET), 1, isr4, ISR4_ARG, IRQ_FLAGS);
irq_enable(IRQ_LINE(ISR4_OFFSET));
TC_PRINT("isr4 isr=%p irq=%d param=%p\n", isr4, IRQ_LINE(ISR4_OFFSET),
irq_enable(translate(IRQ_LINE(ISR4_OFFSET)));
TC_PRINT("isr4 isr=%p irq=%d param=%p\n", isr4, translate(IRQ_LINE(ISR4_OFFSET)),
(void *)ISR4_ARG);

zassert_ok(check_sw_isr(isr4, ISR4_ARG, ISR4_OFFSET),
zassert_ok(check_sw_isr(isr4, ISR4_ARG, ISR4_OFFSET, translate),
"check interrupt isr4 failed");
#endif
#endif
Expand Down Expand Up @@ -379,7 +422,7 @@ ZTEST(gen_isr_table, test_run_time_interrupt)
irq_enable(IRQ_LINE(ISR5_OFFSET));
TC_PRINT("isr5 isr=%p irq=%d param=%p\n", isr5, IRQ_LINE(ISR5_OFFSET),
(void *)ISR5_ARG);
zassert_ok(check_sw_isr(isr5, ISR5_ARG, ISR5_OFFSET),
zassert_ok(check_sw_isr(isr5, ISR5_ARG, ISR5_OFFSET, passthrough),
"test dynamic interrupt isr5 failed");
#endif

Expand All @@ -390,7 +433,7 @@ ZTEST(gen_isr_table, test_run_time_interrupt)
TC_PRINT("isr6 isr=%p irq=%d param=%p\n", isr6, IRQ_LINE(ISR6_OFFSET),
(void *)ISR6_ARG);

zassert_ok(check_sw_isr(isr6, ISR6_ARG, ISR6_OFFSET),
zassert_ok(check_sw_isr(isr6, ISR6_ARG, ISR6_OFFSET, passthrough),
"check dynamic interrupt isr6 failed");
#endif
#endif
Expand Down

0 comments on commit 98b6c13

Please sign in to comment.