1 /*
2 * Copyright (c) 2021 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/interrupt_util.h>
9
10 /*
11 * Other arch has already been tested in testcase of gen_isr_table,
12 * so we only test x86 and arch posix here.
13 * And x86_64 is also not support this kind of interrupt, we skip it.
14 */
15 #if defined(CONFIG_X86)
16
17 #define TEST_DIRECT_IRQ_LINE_1 3
18 #define TEST_DIRECT_IRQ_LINE_2 4
19
20 #define TEST_DIRECT_IRQ_PRIO 0
21
22 #elif defined(CONFIG_ARCH_POSIX)
23 #define TEST_DIRECT_IRQ_LINE_1 5
24 #define TEST_DIRECT_IRQ_LINE_2 6
25
26 #define TEST_DIRECT_IRQ_PRIO 5
27
28 #endif
29
30 volatile uint32_t direct_int_executed[2];
31
ISR_DIRECT_DECLARE(direct_isr1)32 ISR_DIRECT_DECLARE(direct_isr1)
33 {
34 direct_int_executed[0]++;
35
36 return 0;
37 }
38
ISR_DIRECT_DECLARE(direct_isr2)39 ISR_DIRECT_DECLARE(direct_isr2)
40 {
41 direct_int_executed[1]++;
42
43 return 1;
44 }
45
46 /**
47 * @brief Test direct interrupt function
48 *
49 * @details validate direct interrupt works as expected.
50 * - Register two direct interrupt at build time.
51 * - Trigger interrupt and check if isr handler has executed or not.
52 * - Also check irq_enable and irq_disable works.
53 *
54 * @ingroup kernel_interrupt_tests
55 *
56 * @see IRQ_DIRECT_CONNECT(), ISR_DIRECT_DECLARE()
57 */
ZTEST(x86_direct_interrupt,test_direct_interrupt)58 ZTEST(x86_direct_interrupt, test_direct_interrupt)
59 {
60 int trig_vec1, trig_vec2;
61
62 IRQ_DIRECT_CONNECT(TEST_DIRECT_IRQ_LINE_1, TEST_DIRECT_IRQ_PRIO, direct_isr1, 0);
63 IRQ_DIRECT_CONNECT(TEST_DIRECT_IRQ_LINE_2, TEST_DIRECT_IRQ_PRIO, direct_isr2, 0);
64
65 #if defined(CONFIG_X86)
66 trig_vec1 = Z_IRQ_TO_INTERRUPT_VECTOR(TEST_DIRECT_IRQ_LINE_1);
67 trig_vec2 = Z_IRQ_TO_INTERRUPT_VECTOR(TEST_DIRECT_IRQ_LINE_2);
68 #elif defined(CONFIG_ARCH_POSIX)
69 trig_vec1 = TEST_DIRECT_IRQ_LINE_1;
70 trig_vec2 = TEST_DIRECT_IRQ_LINE_2;
71 #endif
72 TC_PRINT("irq(%d)=vector(%d)\n", TEST_DIRECT_IRQ_LINE_1, trig_vec1);
73 TC_PRINT("irq(%d)=vector(%d)\n", TEST_DIRECT_IRQ_LINE_2, trig_vec2);
74
75 irq_enable(TEST_DIRECT_IRQ_LINE_1);
76 irq_enable(TEST_DIRECT_IRQ_LINE_2);
77
78 zassert_true(direct_int_executed[0] == 0 &&
79 direct_int_executed[1] == 0,
80 "Both ISR should not execute");
81
82 trigger_irq(trig_vec1);
83
84 zassert_true(direct_int_executed[0] == 1 &&
85 direct_int_executed[1] == 0,
86 "ISR1 should execute");
87
88 trigger_irq(trig_vec2);
89
90 zassert_true(direct_int_executed[0] == 1 &&
91 direct_int_executed[1] == 1,
92 "Both ISR should execute");
93
94 unsigned int key = irq_lock();
95
96 /* trigger under irq locked */
97 trigger_irq(trig_vec1);
98 trigger_irq(trig_vec2);
99
100 zassert_true(direct_int_executed[0] == 1 &&
101 direct_int_executed[1] == 1,
102 "Both ISR should not execute again");
103
104 irq_unlock(key);
105
106 /* interrupt serve after irq unlocked */
107 zassert_true(direct_int_executed[0] == 2 &&
108 direct_int_executed[1] == 2,
109 "Both ISR should execute again(%d)(%d)",
110 direct_int_executed[0], direct_int_executed[1]);
111
112 /* trigger after irq unlocked */
113 trigger_irq(trig_vec1);
114 trigger_irq(trig_vec2);
115
116 zassert_true(direct_int_executed[0] == 3 &&
117 direct_int_executed[1] == 3,
118 "Both ISR should execute again(%d)(%d)",
119 direct_int_executed[0], direct_int_executed[1]);
120 }
121
122 ZTEST_SUITE(x86_direct_interrupt, NULL, NULL, NULL, NULL, NULL);
123