Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | /* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <ztest.h> #include <interrupt_util.h> #if defined(CONFIG_DYNAMIC_INTERRUPTS) #define ISR_DYN_ARG 0xab249cfd static unsigned int handler_has_run; static uintptr_t handler_test_result; static void dyn_isr(const void *arg) { ARG_UNUSED(arg); handler_test_result = (uintptr_t)arg; handler_has_run++; } #if defined(CONFIG_GEN_SW_ISR_TABLE) extern struct _isr_table_entry __sw_isr_table _sw_isr_table[]; extern void z_irq_spurious(const void *unused); /** * @brief Test dynamic ISR installation * * @ingroup kernel_interrupt_tests * * @details This routine locates an unused entry in the software ISR table, * installs a dynamic ISR to the unused entry by calling the dynamic * configured function, and verifies that the ISR is successfully installed * by checking the software ISR table entry. * * @see arch_irq_connect_dynamic() */ void test_isr_dynamic(void) { int i; const void *argval; for (i = 0; i < (CONFIG_NUM_IRQS - CONFIG_GEN_IRQ_START_VECTOR); i++) { if (_sw_isr_table[i].isr == z_irq_spurious) { break; } } zassert_true(_sw_isr_table[i].isr == z_irq_spurious, "could not find slot for dynamic isr"); printk("installing dynamic ISR for IRQ %d\n", CONFIG_GEN_IRQ_START_VECTOR + i); argval = (const void *)&i; arch_irq_connect_dynamic(i + CONFIG_GEN_IRQ_START_VECTOR, 0, dyn_isr, argval, 0); zassert_true(_sw_isr_table[i].isr == dyn_isr && _sw_isr_table[i].arg == argval, "dynamic isr did not install successfully"); } #else /* * For testing arch such as x86, x86_64 and posix which support dynamic * interrupt but without SW ISR table, we test it by applying for a * dynamic interrupt and then trigger it to check if happened correctly. */ #if defined(CONFIG_X86) #define IV_IRQS 32 /* start of vectors available for x86 IRQs */ #define TEST_IRQ_DYN_LINE 16 #elif defined(CONFIG_ARCH_POSIX) #define TEST_IRQ_DYN_LINE 5 #endif void test_isr_dynamic(void) { int vector_num; /**TESTPOINT: configuration of interrupts dynamically at runtime */ vector_num = arch_irq_connect_dynamic(TEST_IRQ_DYN_LINE, 1, dyn_isr, (void *)ISR_DYN_ARG, 0); #if defined(CONFIG_X86_64) /* The isr table for x86_64 is visiable, so check it up here */ extern void (*x86_irq_funcs[])(const void *); extern const void *x86_irq_args[]; zassert_true(x86_irq_funcs[vector_num - IV_IRQS] == dyn_isr && x86_irq_args[vector_num - IV_IRQS] == (void *)ISR_DYN_ARG, "dynamic isr did not install successfully"); #endif TC_PRINT("vector(%d)\n", vector_num); zassert_true(vector_num > 0, "irq connect dynamic failed"); zassert_equal(handler_has_run, 0, "handler has run before interrupt trigger"); irq_enable(TEST_IRQ_DYN_LINE); trigger_irq(vector_num); zassert_equal(handler_has_run, 1, "interrupt triggered but handler has not run(%d)", handler_has_run); /**TESTPOINT: pass word-sized parameter to interrupt */ zassert_equal(handler_test_result, ISR_DYN_ARG, "parameter(0x%lx) in handler is not correct", handler_test_result); trigger_irq(vector_num); /**TESTPOINT: interrupt triggered again */ zassert_equal(handler_has_run, 2, "interrupt triggered but handler has not run(%d)", handler_has_run); } #endif /* CONFIG_GEN_SW_ISR_TABLE */ #else /* Skip the dynamic interrupt test for the platforms that do not support it */ void test_isr_dynamic(void) { ztest_test_skip(); } #endif /* CONFIG_DYNAMIC_INTERRUPTS */ |