-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests: kernel: interrupt: Add testcase for shared interrupts
This commit introduces a new testcase for shared interrupts. Signed-off-by: Laurentiu Mihalcea <[email protected]>
- Loading branch information
1 parent
fce4907
commit 01f40b9
Showing
3 changed files
with
192 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 */ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters