Zephyr Project API 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
irq.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2013-2014 Wind River Systems, Inc.
3 * Copyright (c) 2019 Nordic Semiconductor ASA.
4 * Copyright 2026 Arm Limited and/or its affiliates <open-source-office@arm.com>
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
16
17#ifndef ZEPHYR_INCLUDE_ARCH_ARM_IRQ_H_
18#define ZEPHYR_INCLUDE_ARCH_ARM_IRQ_H_
19
20#include <zephyr/sw_isr_table.h>
21#include <stdbool.h>
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27#ifdef _ASMLANGUAGE
28#if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) || defined(CONFIG_MULTI_LEVEL_INTERRUPTS)
29#define arch_irq_enable z_soc_irq_enable
30#define arch_irq_disable z_soc_irq_disable
31#define arch_irq_is_enabled z_soc_irq_is_enabled
32#define arch_irq_clear_pending z_soc_irq_clear_pending
33#define arch_irq_set_pending z_soc_irq_set_pending
34#define arch_irq_is_pending z_soc_irq_is_pending
35#else
36#define arch_irq_enable arm_irq_enable
37#define arch_irq_disable arm_irq_disable
38#define arch_irq_is_enabled arm_irq_is_enabled
39#define arch_irq_clear_pending arm_irq_clear_pending
40#define arch_irq_set_pending arm_irq_set_pending
41#define arch_irq_is_pending arm_irq_is_pending
42#endif
43#ifndef CONFIG_USE_SWITCH
44GTEXT(z_arm_int_exit);
45#endif
46GTEXT(arch_irq_enable)
49#if defined(CONFIG_ARCH_HAS_IRQ_PENDING_OPS)
53#endif
54#if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER)
55GTEXT(z_soc_irq_get_active)
56GTEXT(z_soc_irq_eoi)
57#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */
58#else
59
60#if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER)
61extern void arm_irq_enable(unsigned int irq);
62extern void arm_irq_disable(unsigned int irq);
63extern int arm_irq_is_enabled(unsigned int irq);
64extern void arm_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags);
65#if defined(CONFIG_ARCH_HAS_IRQ_PENDING_OPS)
66extern void arm_irq_clear_pending(unsigned int irq);
67extern void arm_irq_set_pending(unsigned int irq);
68extern bool arm_irq_is_pending(unsigned int irq);
69#endif
70#if !defined(CONFIG_MULTI_LEVEL_INTERRUPTS)
71#define arch_irq_enable(irq) arm_irq_enable(irq)
72#define arch_irq_disable(irq) arm_irq_disable(irq)
73#define arch_irq_is_enabled(irq) arm_irq_is_enabled(irq)
74#define z_arm_irq_priority_set(irq, prio, flags) arm_irq_priority_set(irq, prio, flags)
75#if defined(CONFIG_ARCH_HAS_IRQ_PENDING_OPS)
76#define arch_irq_clear_pending(irq) arm_irq_clear_pending(irq)
77#define arch_irq_set_pending(irq) arm_irq_set_pending(irq)
78#define arch_irq_is_pending(irq) arm_irq_is_pending(irq)
79#endif
80#endif
81#endif
82
83#if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) || defined(CONFIG_MULTI_LEVEL_INTERRUPTS)
84/*
85 * When a custom interrupt controller or multi-level interrupts is specified,
86 * map the architecture interrupt control functions to the SoC layer interrupt
87 * control functions.
88 */
89
90void z_soc_irq_init(void);
91void z_soc_irq_enable(unsigned int irq);
92void z_soc_irq_disable(unsigned int irq);
93int z_soc_irq_is_enabled(unsigned int irq);
94
95void z_soc_irq_priority_set(
96 unsigned int irq, unsigned int prio, unsigned int flags);
97
98unsigned int z_soc_irq_get_active(void);
99void z_soc_irq_eoi(unsigned int irq);
100
101#if defined(CONFIG_ARCH_HAS_IRQ_PENDING_OPS)
102void z_soc_irq_clear_pending(unsigned int irq);
103void z_soc_irq_set_pending(unsigned int irq);
104bool z_soc_irq_is_pending(unsigned int irq);
105#endif
106
107#define arch_irq_enable(irq) z_soc_irq_enable(irq)
108#define arch_irq_disable(irq) z_soc_irq_disable(irq)
109#define arch_irq_is_enabled(irq) z_soc_irq_is_enabled(irq)
110
111#if defined(CONFIG_ARCH_HAS_IRQ_PENDING_OPS)
112#define arch_irq_clear_pending(irq) z_soc_irq_clear_pending(irq)
113#define arch_irq_set_pending(irq) z_soc_irq_set_pending(irq)
114#define arch_irq_is_pending(irq) z_soc_irq_is_pending(irq)
115#endif
116
117#define z_arm_irq_priority_set(irq, prio, flags) \
118 z_soc_irq_priority_set(irq, prio, flags)
119
120#endif
121
122#if defined(CONFIG_CPU_CORTEX_M) && defined(CONFIG_USE_SWITCH)
123/* CMSIS may include SoC headers that include <zephyr/irq.h>. Keep this after the IRQ mappings. */
125
126static inline void z_arm_int_exit(void)
127{
129}
130#else
131extern void z_arm_int_exit(void);
132#endif
133
134extern void z_arm_interrupt_init(void);
135
136/* Flags for use with IRQ_CONNECT() */
150#define IRQ_ZERO_LATENCY BIT(0)
151
152#ifdef CONFIG_CPU_CORTEX_M
153
154#if defined(CONFIG_ZERO_LATENCY_LEVELS)
155#define ZERO_LATENCY_LEVELS CONFIG_ZERO_LATENCY_LEVELS
156#else
157#define ZERO_LATENCY_LEVELS 1
158#endif
159
160#define _CHECK_PRIO(priority_p, flags_p) \
161 BUILD_ASSERT(((flags_p & IRQ_ZERO_LATENCY) && \
162 ((ZERO_LATENCY_LEVELS == 1) || \
163 (priority_p < ZERO_LATENCY_LEVELS))) || \
164 (priority_p <= IRQ_PRIO_LOWEST), \
165 "Invalid interrupt priority. Values must not exceed IRQ_PRIO_LOWEST");
166#else
167#define _CHECK_PRIO(priority_p, flags_p)
168#endif
169
170/* All arguments must be computable by the compiler at build time.
171 *
172 * Z_ISR_DECLARE will populate the .intList section with the interrupt's
173 * parameters, which will then be used by gen_irq_tables.py to create
174 * the vector table and the software ISR table. This is all done at
175 * build-time.
176 *
177 * We additionally set the priority in the interrupt controller at
178 * runtime.
179 */
180#define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
181{ \
182 BUILD_ASSERT(!(flags_p & IRQ_ZERO_LATENCY), \
183 "ZLI interrupts must be registered using IRQ_DIRECT_CONNECT()"); \
184 _CHECK_PRIO(priority_p, flags_p) \
185 Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \
186 z_arm_irq_priority_set(irq_p, priority_p, flags_p); \
187}
188
189#define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \
190{ \
191 BUILD_ASSERT(IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS) || !(flags_p & IRQ_ZERO_LATENCY), \
192 "ZLI interrupt registered but feature is disabled"); \
193 _CHECK_PRIO(priority_p, flags_p) \
194 Z_ISR_DECLARE_DIRECT(irq_p, ISR_FLAG_DIRECT, isr_p); \
195 z_arm_irq_priority_set(irq_p, priority_p, flags_p); \
196}
197
198#ifdef CONFIG_PM
199extern void _arch_isr_direct_pm(void);
200#define ARCH_ISR_DIRECT_PM() _arch_isr_direct_pm()
201#else
202#define ARCH_ISR_DIRECT_PM() do { } while (false)
203#endif
204
205#define ARCH_ISR_DIRECT_HEADER() arch_isr_direct_header()
206#define ARCH_ISR_DIRECT_FOOTER(swap) arch_isr_direct_footer(swap)
207
208#ifdef CONFIG_TRACING_ISR
209extern void sys_trace_isr_enter(void);
210extern void sys_trace_isr_exit(void);
211#endif
212
213static inline void arch_isr_direct_header(void)
214{
215#ifdef CONFIG_TRACING_ISR
217#endif
218}
219
220static inline void arch_isr_direct_footer(int maybe_swap)
221{
222#ifdef CONFIG_TRACING_ISR
224#endif
225 if (maybe_swap != 0) {
226 z_arm_int_exit();
227 }
228}
229
230#define ARCH_ISR_DIAG_OFF \
231 TOOLCHAIN_DISABLE_CLANG_WARNING(TOOLCHAIN_WARNING_EXTRA) \
232 TOOLCHAIN_DISABLE_CLANG_WARNING(TOOLCHAIN_WARNING_ARM_INTERRUPT_VFP_CLOBBER) \
233 TOOLCHAIN_DISABLE_GCC_WARNING(TOOLCHAIN_WARNING_ATTRIBUTES) \
234 TOOLCHAIN_DISABLE_IAR_WARNING(TOOLCHAIN_WARNING_ATTRIBUTES)
235#define ARCH_ISR_DIAG_ON \
236 TOOLCHAIN_ENABLE_CLANG_WARNING(TOOLCHAIN_WARNING_EXTRA) \
237 TOOLCHAIN_ENABLE_CLANG_WARNING(TOOLCHAIN_WARNING_ARM_INTERRUPT_VFP_CLOBBER) \
238 TOOLCHAIN_ENABLE_GCC_WARNING(TOOLCHAIN_WARNING_ATTRIBUTES) \
239 TOOLCHAIN_ENABLE_IAR_WARNING(TOOLCHAIN_WARNING_ATTRIBUTES)
240
241#define ARCH_ISR_DIRECT_DECLARE(name) \
242 static inline int name##_body(void); \
243 ARCH_ISR_DIAG_OFF \
244 __attribute__ ((interrupt ("IRQ"))) void name(void) \
245 { \
246 int check_reschedule; \
247 ISR_DIRECT_HEADER(); \
248 check_reschedule = name##_body(); \
249 ISR_DIRECT_FOOTER(check_reschedule); \
250 } \
251 ARCH_ISR_DIAG_ON \
252 static inline int name##_body(void)
253
254#if defined(CONFIG_DYNAMIC_DIRECT_INTERRUPTS)
255
256extern void z_arm_irq_direct_dynamic_dispatch_reschedule(void);
257extern void z_arm_irq_direct_dynamic_dispatch_no_reschedule(void);
258
311#define ARM_IRQ_DIRECT_DYNAMIC_CONNECT(irq_p, priority_p, flags_p, resch) \
312 IRQ_DIRECT_CONNECT(irq_p, priority_p, \
313 _CONCAT(z_arm_irq_direct_dynamic_dispatch_, resch), flags_p)
314
315#endif /* CONFIG_DYNAMIC_DIRECT_INTERRUPTS */
316
317#if defined(CONFIG_ARM_SECURE_FIRMWARE)
318/* Architecture-specific definition for the target security
319 * state of an NVIC IRQ line.
320 */
321typedef enum {
322 IRQ_TARGET_STATE_SECURE = 0,
323 IRQ_TARGET_STATE_NON_SECURE
324} irq_target_state_t;
325
326#endif /* CONFIG_ARM_SECURE_FIRMWARE */
327
328#endif /* _ASMLANGUAGE */
329
330#ifdef __cplusplus
331}
332#endif
333
334#endif /* ZEPHYR_INCLUDE_ARCH_ARM_IRQ_H_ */
static void arch_isr_direct_header(void)
Definition irq.h:91
static void arch_isr_direct_footer(int maybe_swap)
Definition irq.h:98
#define arch_irq_disable(irq)
Definition irq.h:72
void arm_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags)
#define arch_irq_enable(irq)
Definition irq.h:71
int arm_irq_is_enabled(unsigned int irq)
void arm_irq_enable(unsigned int irq)
void arm_irq_disable(unsigned int irq)
#define arch_irq_is_enabled(irq)
Definition irq.h:73
Cortex-M context-switch support helpers.
static void arm_m_exc_tail(void)
ISR-tail helper that patches the stacked LR for deferred switch fixup.
Definition arm-m-switch.h:157
void arch_irq_clear_pending(unsigned int irq)
Clear the pending state of the specified interrupt line.
bool arch_irq_is_pending(unsigned int irq)
Test if the specified interrupt line is pending.
void arch_irq_set_pending(unsigned int irq)
Set the pending state of the specified interrupt line.
void sys_trace_isr_enter(void)
Called when entering an ISR.
void sys_trace_isr_exit(void)
Called when exiting an ISR.
flags
Definition parser.h:97
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
Software-managed ISR table.