Skip to content

Commit

Permalink
tests: kernel: interrupt: Add testcase for shared interrupts
Browse files Browse the repository at this point in the history
This commit introduces a new testcase for shared interrupts.

Signed-off-by: Laurentiu Mihalcea <[email protected]>
  • Loading branch information
LaurentiuM1234 committed Aug 11, 2023
1 parent fce4907 commit 01f40b9
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 0 deletions.
1 change: 1 addition & 0 deletions tests/kernel/interrupt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ target_sources(app PRIVATE

target_sources_ifdef(CONFIG_DYNAMIC_INTERRUPTS app PRIVATE src/dynamic_isr.c)
target_sources_ifdef(CONFIG_X86 app PRIVATE src/regular_isr.c)
target_sources_ifdef(CONFIG_SHARED_INTERRUPTS app PRIVATE src/shared_irq.c)
182 changes: 182 additions & 0 deletions tests/kernel/interrupt/src/shared_irq.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/*
* Copyright 2023 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/ztest.h>
#include <zephyr/interrupt_util.h>

#if defined(CONFIG_GIC)
#define TEST_IRQ_LINE_1 10
#define TEST_IRQ_LINE_2 11
#else
#define TEST_IRQ_LINE_1 (CONFIG_NUM_IRQS - 7)
#define TEST_IRQ_LINE_2 (CONFIG_NUM_IRQS - 6)
#endif

#define TEST_IRQ_PRIORITY 0
#define NUM_TEST_ISRS 4

static uint32_t test_vector[NUM_TEST_ISRS];
static uint32_t test_vector_results[NUM_TEST_ISRS] = {
0xdeadbeef,
0xcafebabe,
0xcafebeef,
0xabcd1234,
};

void test_isr_1(const void *data)
{
int index = POINTER_TO_INT(data);

test_vector[index] = test_vector_results[index];
}

void test_isr_2(const void *data)
{
int index = POINTER_TO_INT(data);

test_vector[index] = test_vector_results[index];
}

void test_isr_3(const void *data)
{
int index = POINTER_TO_INT(data);

test_vector[index] = test_vector_results[index];
}

void test_isr_4(const void *data)
{
int index = POINTER_TO_INT(data);

test_vector[index] = test_vector_results[index];
}

static void reset_test_vector(void)
{
int i;

for (i = 0; i < NUM_TEST_ISRS; i++)
test_vector[i] = 0;
}

ZTEST(interrupt_feature, test_shared_irq)
{
int i;

IRQ_CONNECT(TEST_IRQ_LINE_1, TEST_IRQ_PRIORITY, test_isr_1, 0, 0);
IRQ_CONNECT(TEST_IRQ_LINE_1, TEST_IRQ_PRIORITY, test_isr_2, (void *)1, 0);
IRQ_CONNECT(TEST_IRQ_LINE_2, TEST_IRQ_PRIORITY, test_isr_3, (void *)2, 0);

zassert_true(_shared_irq_table[TEST_IRQ_LINE_1].client_num == 2,
"_shared_irq_table should have 2 clients.");

zassert_true(_sw_isr_table[TEST_IRQ_LINE_1].isr == shared_isr,
"the ISR for TEST_IRQ_LINE_1 should be shared_isr");

zassert_true(_sw_isr_table[TEST_IRQ_LINE_1].arg ==
&_shared_irq_table[TEST_IRQ_LINE_1],
"the arg from TEST_IRQ_LINE_1's entry in _sw_isr_table should be _shared_irq_table[TEST_IRQ_LINE_1]");

zassert_true(_sw_isr_table[TEST_IRQ_LINE_2].isr == test_isr_3,
"the routine entry from _sw_isr_table[TEST_IRQ_LINE_2] should be test_isr_3");

irq_enable(TEST_IRQ_LINE_1);
irq_enable(TEST_IRQ_LINE_2);

trigger_irq(TEST_IRQ_LINE_1);
trigger_irq(TEST_IRQ_LINE_2);

/* wait a bit */
k_busy_wait(5000);

/* check results */
for (i = 0; i < NUM_TEST_ISRS - 1; i++) {
zassert_true(test_vector[i] == test_vector_results[i],
"wrong test_vector value");
}

irq_disable(TEST_IRQ_LINE_1);
irq_disable(TEST_IRQ_LINE_2);

/* wait a bit */
k_busy_wait(5000);

reset_test_vector();

#ifdef CONFIG_DYNAMIC_INTERRUPTS
arch_irq_connect_dynamic(TEST_IRQ_LINE_2, TEST_IRQ_PRIORITY, test_isr_4,
(void *)3, 0);

zassert_true(_shared_irq_table[TEST_IRQ_LINE_2].clients[0].routine ==
test_isr_3,
"first client's routine on TEST_IRQ_LINE_2 should be test_isr_3");

zassert_true(_shared_irq_table[TEST_IRQ_LINE_2].clients[1].routine ==
test_isr_4,
"second client's routine on TEST_IRQ_LINE_2 should be test_isr_4");

zassert_true(_sw_isr_table[TEST_IRQ_LINE_2].isr == shared_isr,
"the ISR for TEST_IRQ_LINE_2 should be shared_isr");

irq_enable(TEST_IRQ_LINE_2);

trigger_irq(TEST_IRQ_LINE_2);

/* wait a bit */
k_busy_wait(5000);

/* check results */
zassert_true(test_vector[3] == test_vector_results[3],
"wrong test_vector value");

irq_disable(TEST_IRQ_LINE_2);

/* wait a bit */
k_busy_wait(5000);

reset_test_vector();

/* note: this will not remove test_isr_3 from the client list since
* the argument is different from the one we used for registration.
*/
arch_irq_disconnect_dynamic(TEST_IRQ_LINE_2, TEST_IRQ_PRIORITY,
test_isr_3, (void *)0xdeadbeef, 0);

irq_enable(TEST_IRQ_LINE_2);

trigger_irq(TEST_IRQ_LINE_2);

/* wait a bit */
k_busy_wait(5000);

zassert_true(!test_vector[0] && !test_vector[1] &&
test_vector[3] == test_vector_results[3] &&
test_vector[2] == test_vector_results[2],
"wrong test_vector value");

irq_disable(TEST_IRQ_LINE_2);

/* wait a bit */
k_busy_wait(5000);

reset_test_vector();

/* this will remove test_isr_3 */
arch_irq_disconnect_dynamic(TEST_IRQ_LINE_2, TEST_IRQ_PRIORITY,
test_isr_3, (void *)2, 0);

irq_enable(TEST_IRQ_LINE_2);

trigger_irq(TEST_IRQ_LINE_2);

/* wait a bit */
k_busy_wait(5000);

zassert_true(test_vector[3] == test_vector_results[3] &&
!test_vector[2] && !test_vector[1] && !test_vector[0],
"wrong test_vector value");
#endif /* CONFIG_DYNAMIC_INTERRUPTS */
}
9 changes: 9 additions & 0 deletions tests/kernel/interrupt/testcase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,12 @@ tests:
- kernel
- interrupt
filter: not CONFIG_TRUSTED_EXECUTION_NONSECURE
arch.shared_interrupt:
arch_allow:
- arm64
- arm
tags:
- kernel
- interrupt
extra_configs:
- CONFIG_SHARED_INTERRUPTS=y

0 comments on commit 01f40b9

Please sign in to comment.