1 /*
2 * Copyright 2023 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "test_shared_irq.h"
8
9 #define GIC_IRQ1 10
10 #define GIC_IRQ2 11
11
12 /**
13 * @brief Test writing to a vector using static shared interrupts.
14 *
15 * @ingroup kernel_interrupt_tests
16 *
17 * @details This tests if interrupts are statically shared successfully
18 * (i.e: multiple ISR/arg pairs are called whenever the interrupt they
19 * were registered for is triggered).
20 */
ZTEST(interrupt_feature,test_static_shared_irq_write)21 ZTEST(interrupt_feature, test_static_shared_irq_write)
22 {
23 /* note: this test is very brittle since it requires that
24 * the chosen interrupt lines be unused for all of the
25 * testing platforms. Failing to meet this requirement
26 * leads to build failures due to the number of clients
27 * exceeding the limit. Still, it's important to test that
28 * the static shared interrupts work properly. As such,
29 * this test shall be restricted to a single platform, thus
30 * decreasing the risk of build errors appearing due to the
31 * chosen interrupts being used.
32 */
33 #ifndef CONFIG_BOARD_QEMU_CORTEX_A53
34 ztest_test_skip();
35 #else
36 int i;
37
38 IRQ_CONNECT(GIC_IRQ1, IRQ_PRIORITY, test_isr_0, 0, 0);
39 IRQ_CONNECT(GIC_IRQ1, IRQ_PRIORITY, test_isr_1, (void *)1, 0);
40 IRQ_CONNECT(GIC_IRQ2, IRQ_PRIORITY, test_isr_2, (void *)2, 0);
41
42 zassert_true(_sw_isr_table[GIC_IRQ1].isr == z_shared_isr,
43 "wrong _sw_isr_table ISR at GIC_IRQ1");
44 zassert_true(_sw_isr_table[GIC_IRQ2].isr == test_isr_2,
45 "wrong _sw_isr_table ISR at GIC_IRQ1");
46
47 zassert_true(_sw_isr_table[GIC_IRQ1].arg ==
48 &z_shared_sw_isr_table[GIC_IRQ1],
49 "wrong _sw_isr_table arg at GIC_IRQ1");
50 zassert_true(_sw_isr_table[GIC_IRQ2].arg == (void *)2,
51 "wrong _sw_isr_table arg at GIC_IRQ2");
52
53 zassert_true(z_shared_sw_isr_table[GIC_IRQ1].client_num == 2,
54 "wrong client number for GIC_IRQ1");
55 zassert_true(!z_shared_sw_isr_table[GIC_IRQ2].client_num,
56 "wrong client number for GIC_IRQ2");
57
58 zassert_true(client_exists_at_index(test_isr_0, 0, GIC_IRQ1,
59 TEST_INVALID_IDX),
60 "test_isr_0 not a client for GIC_IRQ1");
61 zassert_true(client_exists_at_index(test_isr_1, (void *)1, GIC_IRQ1,
62 TEST_INVALID_IDX),
63 "test_isr_1 not a client for GIC_IRQ1");
64
65 irq_enable(GIC_IRQ1);
66 irq_enable(GIC_IRQ2);
67
68 trigger_irq(GIC_IRQ1);
69 trigger_irq(GIC_IRQ2);
70
71 /* wait 5ms before checking the results */
72 k_busy_wait(5000);
73
74 for (i = 0; i < TEST_VECTOR_SIZE; i++) {
75 zassert_true(test_vector[i] == result_vector[i],
76 "wrong test_vector value at %d: 0x%x vs 0x%x",
77 i, test_vector[i], result_vector[i]);
78 }
79
80 irq_disable(GIC_IRQ1);
81 irq_disable(GIC_IRQ2);
82
83 #ifdef CONFIG_DYNAMIC_INTERRUPTS
84 /* if dynamic interrupts are enabled this will restore the _sw_isr_table
85 * entries for GIC_IRQ1 and GIC_IRQ2 to their default values (NULL,
86 * z_irq_spurious). In turn, this will increase the probability of
87 * dynamic_shared_irq.c's get_irq_slot() being able to find an available
88 * slot.
89 */
90 arch_irq_disconnect_dynamic(GIC_IRQ1, IRQ_PRIORITY, test_isr_0, 0, 0);
91 arch_irq_disconnect_dynamic(GIC_IRQ1, IRQ_PRIORITY, test_isr_1, (void *)1, 0);
92 arch_irq_disconnect_dynamic(GIC_IRQ2, IRQ_PRIORITY, test_isr_2, (void *)2, 0);
93 #endif /* CONFIG_DYNAMIC_INTERRUPTS */
94
95 #endif /* CONFIG_BOARD_QEMU_CORTEX_A53 */
96 }
97