Zephyr API
4.4.99
A Scalable Open Source RTOS
Toggle main menu visibility
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
>
19
#include <
zephyr/sys/iterable_sections.h
>
20
#include <
zephyr/types.h
>
21
#include <
zephyr/toolchain.h
>
22
#include <
zephyr/sys/util.h
>
23
24
#ifdef __cplusplus
25
extern
"C"
{
26
#endif
27
28
/* Default vector for the IRQ vector table */
29
void
_isr_wrapper(
void
);
30
31
/* Spurious interrupt handler. Throws an error if called */
32
void
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
*/
39
struct
_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
*/
48
extern
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)
54
extern
void
__sw_isr_table get_isr_entry(
int
irq_number,
struct
_isr_table_entry *entry);
55
#endif
/* CONFIG_GEN_SW_ISR_TABLE_ARRAY */
56
57
struct
_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
*/
147
struct
_isr_list {
149
int32_t
irq;
151
int32_t
flags
;
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
*/
167
struct
_isr_list_sname {
169
int32_t
irq;
171
int32_t
flags;
173
const
char
sname[];
174
};
175
176
#ifdef CONFIG_SHARED_INTERRUPTS
177
struct
z_shared_isr_table_entry {
178
struct
_isr_table_entry clients[CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS];
179
size_t
client_num;
180
};
181
182
void
z_shared_isr(
const
void
*data);
183
184
extern
185
#ifndef CONFIG_DYNAMIC_INTERRUPTS
186
const
187
#endif
188
struct
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
302
void
z_isr_install(
unsigned
int
irq,
void
(*routine)(
const
void
*),
303
const
void
*param);
304
305
#ifdef CONFIG_SHARED_INTERRUPTS
306
int
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_ */
device.h
types.h
flags
flags
Definition
parser.h:97
int32_t
__INT32_TYPE__ int32_t
Definition
stdint.h:74
iterable_sections.h
Iterable sections helpers.
util.h
Misc utilities.
toolchain.h
Macros to abstract toolchain specific capabilities.
zephyr
sw_isr_table.h
Generated on
for Zephyr API by
1.17.0