Zephyr Project API 3.7.1
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
irq_multilevel.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2023 Meta
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
11#ifndef ZEPHYR_INCLUDE_IRQ_MULTILEVEL_H_
12#define ZEPHYR_INCLUDE_IRQ_MULTILEVEL_H_
13
14#ifndef _ASMLANGUAGE
15#include <zephyr/sys/__assert.h>
17#include <zephyr/types.h>
18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23#if defined(CONFIG_MULTI_LEVEL_INTERRUPTS) || defined(__DOXYGEN__)
32static inline unsigned int irq_get_level(unsigned int irq)
33{
34 const uint32_t mask2 = BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS) <<
35 CONFIG_1ST_LEVEL_INTERRUPT_BITS;
36 const uint32_t mask3 = BIT_MASK(CONFIG_3RD_LEVEL_INTERRUPT_BITS) <<
37 (CONFIG_1ST_LEVEL_INTERRUPT_BITS + CONFIG_2ND_LEVEL_INTERRUPT_BITS);
38
39 if (IS_ENABLED(CONFIG_3RD_LEVEL_INTERRUPTS) && (irq & mask3) != 0) {
40 return 3;
41 }
42
43 if (IS_ENABLED(CONFIG_2ND_LEVEL_INTERRUPTS) && (irq & mask2) != 0) {
44 return 2;
45 }
46
47 return 1;
48}
49
60static inline unsigned int irq_from_level_2(unsigned int irq)
61{
62 if (IS_ENABLED(CONFIG_3RD_LEVEL_INTERRUPTS)) {
63 return ((irq >> CONFIG_1ST_LEVEL_INTERRUPT_BITS) &
64 BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS)) - 1;
65 } else {
66 return (irq >> CONFIG_1ST_LEVEL_INTERRUPT_BITS) - 1;
67 }
68}
69
77#define IRQ_TO_L2(irq) ((irq + 1) << CONFIG_1ST_LEVEL_INTERRUPT_BITS)
78
91static inline unsigned int irq_to_level_2(unsigned int irq)
92{
93 return IRQ_TO_L2(irq);
94}
95
106static inline unsigned int irq_parent_level_2(unsigned int irq)
107{
108 return irq & BIT_MASK(CONFIG_1ST_LEVEL_INTERRUPT_BITS);
109}
110
122static inline unsigned int irq_from_level_3(unsigned int irq)
123{
124 return (irq >> (CONFIG_1ST_LEVEL_INTERRUPT_BITS + CONFIG_2ND_LEVEL_INTERRUPT_BITS)) - 1;
125}
126
134#define IRQ_TO_L3(irq) \
135 ((irq + 1) << (CONFIG_1ST_LEVEL_INTERRUPT_BITS + CONFIG_2ND_LEVEL_INTERRUPT_BITS))
136
149static inline unsigned int irq_to_level_3(unsigned int irq)
150{
151 return IRQ_TO_L3(irq);
152}
153
164static inline unsigned int irq_parent_level_3(unsigned int irq)
165{
166 return ((irq >> CONFIG_1ST_LEVEL_INTERRUPT_BITS) &
167 BIT_MASK(CONFIG_2ND_LEVEL_INTERRUPT_BITS)) -
168 1;
169}
170
179static inline unsigned int irq_from_level(unsigned int irq, unsigned int level)
180{
181 if (level == 1) {
182 return irq;
183 } else if (level == 2) {
184 return irq_from_level_2(irq);
185 } else if (level == 3) {
186 return irq_from_level_3(irq);
187 }
188
189 /* level is higher than 3 */
190 __ASSERT_NO_MSG(false);
191 return irq;
192}
193
202static inline unsigned int irq_to_level(unsigned int irq, unsigned int level)
203{
204 if (level == 1) {
205 return irq;
206 } else if (level == 2) {
207 return irq_to_level_2(irq);
208 } else if (level == 3) {
209 return irq_to_level_3(irq);
210 }
211
212 /* level is higher than 3 */
213 __ASSERT_NO_MSG(false);
214 return irq;
215}
216
225static inline unsigned int irq_parent_level(unsigned int irq, unsigned int level)
226{
227 if (level == 1) {
228 /* doesn't really make sense, but return anyway */
229 return irq;
230 } else if (level == 2) {
231 return irq_parent_level_2(irq);
232 } else if (level == 3) {
233 return irq_parent_level_3(irq);
234 }
235
236 /* level is higher than 3 */
237 __ASSERT_NO_MSG(false);
238 return irq;
239}
240
248static inline unsigned int irq_get_intc_irq(unsigned int irq)
249{
250 const unsigned int level = irq_get_level(irq);
251
252 __ASSERT_NO_MSG(level > 1 && level <= 3);
253
254 return irq & BIT_MASK(CONFIG_1ST_LEVEL_INTERRUPT_BITS +
255 (level == 3 ? CONFIG_2ND_LEVEL_INTERRUPT_BITS : 0));
256}
257
258#endif /* CONFIG_MULTI_LEVEL_INTERRUPTS */
259#ifdef __cplusplus
260}
261#endif
262
263#endif /* _ASMLANGUAGE */
264#endif /* ZEPHYR_INCLUDE_IRQ_MULTILEVEL_H_ */
#define IS_ENABLED(config_macro)
Check for macro definition in compiler-visible expressions.
Definition util_macro.h:124
#define BIT_MASK(n)
Bit mask with bits 0 through n-1 (inclusive) set, or 0 if n is 0.
Definition util_macro.h:68
static unsigned int irq_from_level(unsigned int irq, unsigned int level)
Return the interrupt number for a given level.
Definition irq_multilevel.h:179
#define IRQ_TO_L3(irq)
Preprocessor macro to convert irq from level 1 to level 3 format.
Definition irq_multilevel.h:134
static unsigned int irq_to_level_3(unsigned int irq)
Converts irq from level 1 to level 3 format.
Definition irq_multilevel.h:149
static unsigned int irq_from_level_3(unsigned int irq)
Return the 3rd level interrupt number.
Definition irq_multilevel.h:122
static unsigned int irq_from_level_2(unsigned int irq)
Return the 2nd level interrupt number.
Definition irq_multilevel.h:60
static unsigned int irq_get_level(unsigned int irq)
Return IRQ level This routine returns the interrupt level number of the provided interrupt.
Definition irq_multilevel.h:32
static unsigned int irq_to_level_2(unsigned int irq)
Converts irq from level 1 to level 2 format.
Definition irq_multilevel.h:91
static unsigned int irq_parent_level(unsigned int irq, unsigned int level)
Returns the parent IRQ of the given level raw IRQ number.
Definition irq_multilevel.h:225
#define IRQ_TO_L2(irq)
Preprocessor macro to convert irq from level 1 to level 2 format.
Definition irq_multilevel.h:77
static unsigned int irq_get_intc_irq(unsigned int irq)
Returns the parent interrupt controller IRQ of the given IRQ number.
Definition irq_multilevel.h:248
static unsigned int irq_parent_level_2(unsigned int irq)
Returns the parent IRQ of the level 2 raw IRQ number.
Definition irq_multilevel.h:106
static unsigned int irq_parent_level_3(unsigned int irq)
Returns the parent IRQ of the level 3 raw IRQ number.
Definition irq_multilevel.h:164
static unsigned int irq_to_level(unsigned int irq, unsigned int level)
Converts irq from level 1 to a given level.
Definition irq_multilevel.h:202
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
Macro utilities.