/* * Copyright 2023 NXP * * SPDX-License-Identifier: Apache-2.0 */ #include "test_shared_irq.h" #define GIC_IRQ1 10 #define GIC_IRQ2 11 /** * @brief Test writing to a vector using static shared interrupts. * * @ingroup kernel_interrupt_tests * * @details This tests if interrupts are statically shared successfully * (i.e: multiple ISR/arg pairs are called whenever the interrupt they * were registered for is triggered). */ ZTEST(interrupt_feature, test_static_shared_irq_write) { /* note: this test is very brittle since it requires that * the chosen interrupt lines be unused for all of the * testing platforms. Failing to meet this requirement * leads to build failures due to the number of clients * exceeding the limit. Still, it's important to test that * the static shared interrupts work properly. As such, * this test shall be restricted to a single platform, thus * decreasing the risk of build errors appearing due to the * chosen interrupts being used. */ #ifndef CONFIG_BOARD_QEMU_CORTEX_A53 ztest_test_skip(); #else int i; IRQ_CONNECT(GIC_IRQ1, IRQ_PRIORITY, test_isr_0, 0, 0); IRQ_CONNECT(GIC_IRQ1, IRQ_PRIORITY, test_isr_1, (void *)1, 0); IRQ_CONNECT(GIC_IRQ2, IRQ_PRIORITY, test_isr_2, (void *)2, 0); zassert_true(_sw_isr_table[GIC_IRQ1].isr == z_shared_isr, "wrong _sw_isr_table ISR at GIC_IRQ1"); zassert_true(_sw_isr_table[GIC_IRQ2].isr == test_isr_2, "wrong _sw_isr_table ISR at GIC_IRQ1"); zassert_true(_sw_isr_table[GIC_IRQ1].arg == &z_shared_sw_isr_table[GIC_IRQ1], "wrong _sw_isr_table arg at GIC_IRQ1"); zassert_true(_sw_isr_table[GIC_IRQ2].arg == (void *)2, "wrong _sw_isr_table arg at GIC_IRQ2"); zassert_true(z_shared_sw_isr_table[GIC_IRQ1].client_num == 2, "wrong client number for GIC_IRQ1"); zassert_true(!z_shared_sw_isr_table[GIC_IRQ2].client_num, "wrong client number for GIC_IRQ2"); zassert_true(client_exists_at_index(test_isr_0, 0, GIC_IRQ1, TEST_INVALID_IDX), "test_isr_0 not a client for GIC_IRQ1"); zassert_true(client_exists_at_index(test_isr_1, (void *)1, GIC_IRQ1, TEST_INVALID_IDX), "test_isr_1 not a client for GIC_IRQ1"); irq_enable(GIC_IRQ1); irq_enable(GIC_IRQ2); trigger_irq(GIC_IRQ1); trigger_irq(GIC_IRQ2); /* wait 5ms before checking the results */ k_busy_wait(5000); for (i = 0; i < TEST_VECTOR_SIZE; i++) { zassert_true(test_vector[i] == result_vector[i], "wrong test_vector value at %d: 0x%x vs 0x%x", i, test_vector[i], result_vector[i]); } irq_disable(GIC_IRQ1); irq_disable(GIC_IRQ2); #ifdef CONFIG_DYNAMIC_INTERRUPTS /* if dynamic interrupts are enabled this will restore the _sw_isr_table * entries for GIC_IRQ1 and GIC_IRQ2 to their default values (NULL, * z_irq_spurious). In turn, this will increase the probability of * dynamic_shared_irq.c's get_irq_slot() being able to find an available * slot. */ arch_irq_disconnect_dynamic(GIC_IRQ1, IRQ_PRIORITY, test_isr_0, 0, 0); arch_irq_disconnect_dynamic(GIC_IRQ1, IRQ_PRIORITY, test_isr_1, (void *)1, 0); arch_irq_disconnect_dynamic(GIC_IRQ2, IRQ_PRIORITY, test_isr_2, (void *)2, 0); #endif /* CONFIG_DYNAMIC_INTERRUPTS */ #endif /* CONFIG_BOARD_QEMU_CORTEX_A53 */ }