Zephyr API Documentation 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
sw_isr_table.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014, Wind River Systems, Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
13
14#ifndef ZEPHYR_INCLUDE_SW_ISR_TABLE_H_
15#define ZEPHYR_INCLUDE_SW_ISR_TABLE_H_
16
17#if !defined(_ASMLANGUAGE)
18#include <zephyr/device.h>
20#include <zephyr/types.h>
21#include <zephyr/toolchain.h>
22#include <zephyr/sys/util.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28/* Default vector for the IRQ vector table */
29void _isr_wrapper(void);
30
31/* Spurious interrupt handler. Throws an error if called */
32void z_irq_spurious(const void *unused);
33
34/*
35 * Note the order: arg first, then ISR. This allows a table entry to be
36 * loaded arg -> r0, isr -> r3 in _isr_wrapper with one ldmia instruction,
37 * on ARM Cortex-M (Thumb2).
38 */
39struct _isr_table_entry {
40 const void *arg;
41 void (*isr)(const void *);
42};
43
44#if defined(CONFIG_GEN_SW_ISR_TABLE_ARRAY)
45/* The software ISR table itself, an array of these structures indexed by the
46 * irq line
47 */
48extern
49#ifndef CONFIG_DYNAMIC_INTERRUPTS
50 const
51#endif /* CONFIG_DYNAMIC_INTERRUPTS */
52 struct _isr_table_entry _sw_isr_table[];
53#elif defined(CONFIG_GEN_SW_ISR_TABLE_SWITCH)
54extern void __sw_isr_table get_isr_entry(int irq_number, struct _isr_table_entry *entry);
55#endif /* CONFIG_GEN_SW_ISR_TABLE_ARRAY */
56
57struct _irq_parent_entry {
58 const struct device *dev;
59 unsigned int level;
60 unsigned int irq;
61 unsigned int offset;
62};
63
67
68/* Mapping between aggregator level to order */
69#define Z_STR_L2 2ND
70#define Z_STR_L3 3RD
79#define Z_SW_ISR_TBL_KCONFIG_BY_ALVL(l) CONCAT(CONFIG_, CONCAT(Z_STR_L, l), _LVL_ISR_TBL_OFFSET)
80
84
93#define INTC_BASE_ISR_TBL_OFFSET(node_id) \
94 Z_SW_ISR_TBL_KCONFIG_BY_ALVL(DT_INTC_GET_AGGREGATOR_LEVEL(node_id))
95
103#define INTC_INST_ISR_TBL_OFFSET(inst) \
104 (INTC_BASE_ISR_TBL_OFFSET(DT_DRV_INST(inst)) + (inst * CONFIG_MAX_IRQ_PER_AGGREGATOR))
105
116#define INTC_CHILD_ISR_TBL_OFFSET(node_id) \
117 (INTC_BASE_ISR_TBL_OFFSET(node_id) + \
118 (DT_NODE_CHILD_IDX(node_id) * CONFIG_MAX_IRQ_PER_AGGREGATOR))
119
129#define IRQ_PARENT_ENTRY_DEFINE(_name, _dev, _irq, _offset, _level) \
130 static const STRUCT_SECTION_ITERABLE_ALTERNATE(intc_table, _irq_parent_entry, _name) = { \
131 .dev = _dev, \
132 .level = _level, \
133 .irq = _irq, \
134 .offset = _offset, \
135 }
136
137/*
138 * Data structure created in a special binary .intlist section for each
139 * configured interrupt. gen_irq_tables.py pulls this out of the binary and
140 * uses it to create the IRQ vector table and the _sw_isr_table.
141 *
142 * More discussion in include/linker/intlist.ld
143 *
144 * This is a version used when CONFIG_ISR_TABLES_LOCAL_DECLARATION is disabled.
145 * See _isr_list_sname used otherwise.
146 */
147struct _isr_list {
149 int32_t irq;
153 void *func;
155 const void *param;
156};
157
158/*
159 * Data structure created in a special binary .intlist section for each
160 * configured interrupt. gen_isr_tables.py pulls this out of the binary and
161 * uses it to create linker script chunks that would place interrupt table entries
162 * in the right place in the memory.
163 *
164 * This is a version used when CONFIG_ISR_TABLES_LOCAL_DECLARATION is enabled.
165 * See _isr_list used otherwise.
166 */
167struct _isr_list_sname {
169 int32_t irq;
171 int32_t flags;
173 const char sname[];
174};
175
176#ifdef CONFIG_SHARED_INTERRUPTS
177struct z_shared_isr_table_entry {
178 struct _isr_table_entry clients[CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS];
179 size_t client_num;
180};
181
182void z_shared_isr(const void *data);
183
184extern
185#ifndef CONFIG_DYNAMIC_INTERRUPTS
186const
187#endif
188struct z_shared_isr_table_entry z_shared_sw_isr_table[];
189#endif /* CONFIG_SHARED_INTERRUPTS */
190
192#define ISR_FLAG_DIRECT BIT(0)
193
194#define _MK_ISR_NAME(x, y) __MK_ISR_NAME(x, y)
195#define __MK_ISR_NAME(x, y) __isr_ ## x ## _irq_ ## y
196
197
198#if defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION)
199
200#define _MK_ISR_ELEMENT_NAME(func, id) __MK_ISR_ELEMENT_NAME(func, id)
201#define __MK_ISR_ELEMENT_NAME(func, id) __isr_table_entry_ ## func ## _irq_ ## id
202
203#define _MK_IRQ_ELEMENT_NAME(func, id) __MK_ISR_ELEMENT_NAME(func, id)
204#define __MK_IRQ_ELEMENT_NAME(func, id) __irq_table_entry_ ## func ## _irq_ ## id
205
206#define _MK_ISR_SECTION_NAME(prefix, file, counter) \
207 "." Z_STRINGIFY(prefix) "." file "." Z_STRINGIFY(counter)
208
209#define _MK_ISR_ELEMENT_SECTION(counter) _MK_ISR_SECTION_NAME(irq, __FILE__, counter)
210#define _MK_IRQ_ELEMENT_SECTION(counter) _MK_ISR_SECTION_NAME(isr, __FILE__, counter)
211
212/* Separated macro to create ISR table entry only.
213 * Used by Z_ISR_DECLARE and ISR tables generation script.
214 */
215#define _Z_ISR_TABLE_ENTRY(func, param, sect) \
216 static Z_DECL_ALIGN(struct _isr_table_entry) \
217 __attribute__((section(sect))) \
218 __used _MK_ISR_ELEMENT_NAME(func, __COUNTER__) = { \
219 .arg = (const void *)(param), \
220 .isr = (void (*)(const void *))(void *)(func) \
221 }
222
223#define Z_ISR_DECLARE_C(irq, flags, func, param, counter) \
224 _Z_ISR_DECLARE_C(irq, flags, func, param, counter)
225
226#define _Z_ISR_DECLARE_C(irq, flags, func, param, counter) \
227 _Z_ISR_TABLE_ENTRY(func, param, _MK_ISR_ELEMENT_SECTION(counter)); \
228 static Z_DECL_ALIGN(struct _isr_list_sname) Z_GENERIC_SECTION(.intList) __used \
229 _MK_ISR_NAME(func, counter) = {irq, flags, {_MK_ISR_ELEMENT_SECTION(counter)}}
230
231/* Create an entry for _isr_table to be then placed by the linker.
232 * An instance of struct _isr_list which gets put in the .intList
233 * section is created with the name of the section where _isr_table entry is placed to be then
234 * used by isr generation script to create linker script chunk.
235 */
236#define Z_ISR_DECLARE(irq, flags, func, param) \
237 BUILD_ASSERT(((flags) & ISR_FLAG_DIRECT) == 0, "Use Z_ISR_DECLARE_DIRECT macro"); \
238 Z_ISR_DECLARE_C(irq, flags, func, param, __COUNTER__)
239
240
241/* Separated macro to create ISR Direct table entry only.
242 * Used by Z_ISR_DECLARE_DIRECT and ISR tables generation script.
243 */
244#define _Z_ISR_DIRECT_TABLE_ENTRY(func, sect) \
245 COND_CODE_1(CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_ADDRESS, ( \
246 static Z_DECL_ALIGN(uintptr_t) \
247 __attribute__((section(sect))) \
248 __used _MK_IRQ_ELEMENT_NAME(func, __COUNTER__) = ((uintptr_t)(func)); \
249 ), ( \
250 void __attribute__((section(sect))) __attribute__((naked)) \
251 /* clang-format off */ \
252 __used _MK_IRQ_ELEMENT_NAME(func, __COUNTER__) (void) { \
253 __asm(ARCH_IRQ_VECTOR_JUMP_CODE(func)); \
254 } \
255 /* clang-format on */ \
256 ))
257
258#define Z_ISR_DECLARE_DIRECT_C(irq, flags, func, counter) \
259 _Z_ISR_DECLARE_DIRECT_C(irq, flags, func, counter)
260
261#define _Z_ISR_DECLARE_DIRECT_C(irq, flags, func, counter) \
262 _Z_ISR_DIRECT_TABLE_ENTRY(func, _MK_IRQ_ELEMENT_SECTION(counter)); \
263 static Z_DECL_ALIGN(struct _isr_list_sname) Z_GENERIC_SECTION(.intList) \
264 __used _MK_ISR_NAME(func, counter) = { \
265 irq, \
266 ISR_FLAG_DIRECT | (flags), \
267 _MK_IRQ_ELEMENT_SECTION(counter)}
268
269/* Create an entry to irq table and place it in specific section which name is then placed
270 * in an instance of struct _isr_list to be then used by the isr generation script to create
271 * the linker script chunks.
272 */
273#define Z_ISR_DECLARE_DIRECT(irq, flags, func) \
274 BUILD_ASSERT(IS_ENABLED(CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_ADDRESS) || \
275 IS_ENABLED(CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_CODE), \
276 "CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_{ADDRESS,CODE} not set"); \
277 Z_ISR_DECLARE_DIRECT_C(irq, flags, func, __COUNTER__)
278
279
280#else /* defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION) */
281
282/* Create an instance of struct _isr_list which gets put in the .intList
283 * section. This gets consumed by gen_isr_tables.py which creates the vector
284 * and/or SW ISR tables.
285 */
286#define Z_ISR_DECLARE(irq, flags, func, param) \
287 static Z_DECL_ALIGN(struct _isr_list) Z_GENERIC_SECTION(.intList) \
288 __used _MK_ISR_NAME(func, __COUNTER__) = \
289 {irq, flags, (void *)&func, (const void *)param}
290
291/* The version of the Z_ISR_DECLARE that should be used for direct ISR declaration.
292 * It is here for the API match the version with CONFIG_ISR_TABLES_LOCAL_DECLARATION enabled.
293 */
294#define Z_ISR_DECLARE_DIRECT(irq, flags, func) \
295 Z_ISR_DECLARE(irq, ISR_FLAG_DIRECT | (flags), func, NULL)
296
297#endif
298
299#define IRQ_TABLE_SIZE (CONFIG_NUM_IRQS - CONFIG_GEN_IRQ_START_VECTOR)
300
301#ifdef CONFIG_DYNAMIC_INTERRUPTS
302void z_isr_install(unsigned int irq, void (*routine)(const void *),
303 const void *param);
304
305#ifdef CONFIG_SHARED_INTERRUPTS
306int z_isr_uninstall(unsigned int irq, void (*routine)(const void *),
307 const void *param);
308#endif /* CONFIG_SHARED_INTERRUPTS */
309#endif
310
311#ifdef __cplusplus
312}
313#endif
314
315#endif /* _ASMLANGUAGE */
316
317#endif /* ZEPHYR_INCLUDE_SW_ISR_TABLE_H_ */
flags
Definition parser.h:97
__INT32_TYPE__ int32_t
Definition stdint.h:74
Misc utilities.
Macros to abstract toolchain specific capabilities.