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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | /* * Copyright (c) 2013-2014 Wind River Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Cortex-M public interrupt handling * * ARM-specific kernel interrupt handling interface. Included by arm/arch.h. */ #ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_IRQ_H_ #define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_IRQ_H_ #include <irq.h> #include <sw_isr_table.h> #include <stdbool.h> #ifdef __cplusplus extern "C" { #endif #ifdef _ASMLANGUAGE GTEXT(_IntExit); GTEXT(z_arch_irq_enable) GTEXT(z_arch_irq_disable) GTEXT(z_arch_irq_is_enabled) #else extern void z_arch_irq_enable(unsigned int irq); extern void z_arch_irq_disable(unsigned int irq); extern int z_arch_irq_is_enabled(unsigned int irq); extern void _IntExit(void); #if defined(CONFIG_ARMV7_R) static ALWAYS_INLINE void z_IntLibInit(void) { } #else extern void z_IntLibInit(void); #endif /* macros convert value of it's argument to a string */ #define DO_TOSTR(s) #s #define TOSTR(s) DO_TOSTR(s) /* concatenate the values of the arguments into one */ #define DO_CONCAT(x, y) x ## y #define CONCAT(x, y) DO_CONCAT(x, y) /* internal routine documented in C file, needed by IRQ_CONNECT() macro */ extern void z_irq_priority_set(unsigned int irq, unsigned int prio, u32_t flags); /* Flags for use with IRQ_CONNECT() */ #ifdef CONFIG_ZERO_LATENCY_IRQS /** * Set this interrupt up as a zero-latency IRQ. It has a fixed hardware * priority level (discarding what was supplied in the interrupt's priority * argument), and will run even if irq_lock() is active. Be careful! */ #define IRQ_ZERO_LATENCY BIT(0) #endif /** * Configure a static interrupt. * * All arguments must be computable by the compiler at build time. * * Z_ISR_DECLARE will populate the .intList section with the interrupt's * parameters, which will then be used by gen_irq_tables.py to create * the vector table and the software ISR table. This is all done at * build-time. * * We additionally set the priority in the interrupt controller at * runtime. * * @param irq_p IRQ line number * @param priority_p Interrupt priority * @param isr_p Interrupt service routine * @param isr_param_p ISR parameter * @param flags_p IRQ options * * @return The vector assigned to this interrupt */ #define Z_ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \ ({ \ Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \ z_irq_priority_set(irq_p, priority_p, flags_p); \ irq_p; \ }) /** * Configure a 'direct' static interrupt. * * See include/irq.h for details. * All arguments must be computable at build time. */ #define Z_ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \ ({ \ Z_ISR_DECLARE(irq_p, ISR_FLAG_DIRECT, isr_p, NULL); \ z_irq_priority_set(irq_p, priority_p, flags_p); \ irq_p; \ }) /* FIXME prefer these inline, but see GH-3056 */ #ifdef CONFIG_SYS_POWER_MANAGEMENT extern void _arch_isr_direct_pm(void); #define Z_ARCH_ISR_DIRECT_PM() _arch_isr_direct_pm() #else #define Z_ARCH_ISR_DIRECT_PM() do { } while (false) #endif #define Z_ARCH_ISR_DIRECT_HEADER() z_arch_isr_direct_header() extern void z_arch_isr_direct_header(void); #define Z_ARCH_ISR_DIRECT_FOOTER(swap) z_arch_isr_direct_footer(swap) /* arch/arm/core/exc_exit.S */ extern void _IntExit(void); #ifdef CONFIG_TRACING extern void z_sys_trace_isr_exit(void); #endif static inline void z_arch_isr_direct_footer(int maybe_swap) { #ifdef CONFIG_TRACING z_sys_trace_isr_exit(); #endif if (maybe_swap) { _IntExit(); } } #define Z_ARCH_ISR_DIRECT_DECLARE(name) \ static inline int name##_body(void); \ __attribute__ ((interrupt ("IRQ"))) void name(void) \ { \ int check_reschedule; \ ISR_DIRECT_HEADER(); \ check_reschedule = name##_body(); \ ISR_DIRECT_FOOTER(check_reschedule); \ } \ static inline int name##_body(void) /* Spurious interrupt handler. Throws an error if called */ extern void z_irq_spurious(void *unused); #ifdef CONFIG_GEN_SW_ISR_TABLE /* Architecture-specific common entry point for interrupts from the vector * table. Most likely implemented in assembly. Looks up the correct handler * and parameter from the _sw_isr_table and executes it. */ extern void _isr_wrapper(void); #endif #endif /* _ASMLANGUAGE */ #ifdef __cplusplus } #endif #endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_IRQ_H_ */ |