1 /*
2  * Copyright (c) 2014, Wind River Systems, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief Software-managed ISR table
10  *
11  * Data types for a software-managed ISR table, with a parameter per-ISR.
12  */
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/types.h>
19 #include <toolchain.h>
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 /*
26  * Note the order: arg first, then ISR. This allows a table entry to be
27  * loaded arg -> r0, isr -> r3 in _isr_wrapper with one ldmia instruction,
28  * on ARM Cortex-M (Thumb2).
29  */
30 struct _isr_table_entry {
31 	const void *arg;
32 	void (*isr)(const void *);
33 };
34 
35 /* The software ISR table itself, an array of these structures indexed by the
36  * irq line
37  */
38 extern struct _isr_table_entry _sw_isr_table[];
39 
40 /*
41  * Data structure created in a special binary .intlist section for each
42  * configured interrupt. gen_irq_tables.py pulls this out of the binary and
43  * uses it to create the IRQ vector table and the _sw_isr_table.
44  *
45  * More discussion in include/linker/intlist.ld
46  */
47 struct _isr_list {
48 	/** IRQ line number */
49 	int32_t irq;
50 	/** Flags for this IRQ, see ISR_FLAG_* definitions */
51 	int32_t flags;
52 	/** ISR to call */
53 	void *func;
54 	/** Parameter for non-direct IRQs */
55 	const void *param;
56 };
57 
58 /** This interrupt gets put directly in the vector table */
59 #define ISR_FLAG_DIRECT BIT(0)
60 
61 #define _MK_ISR_NAME(x, y) __MK_ISR_NAME(x, y)
62 #define __MK_ISR_NAME(x, y) __isr_ ## x ## _irq_ ## y
63 
64 /* Create an instance of struct _isr_list which gets put in the .intList
65  * section. This gets consumed by gen_isr_tables.py which creates the vector
66  * and/or SW ISR tables.
67  */
68 #define Z_ISR_DECLARE(irq, flags, func, param) \
69 	static Z_DECL_ALIGN(struct _isr_list) Z_GENERIC_SECTION(.intList) \
70 		__used _MK_ISR_NAME(func, __COUNTER__) = \
71 			{irq, flags, (void *)&func, (const void *)param}
72 
73 #define IRQ_TABLE_SIZE (CONFIG_NUM_IRQS - CONFIG_GEN_IRQ_START_VECTOR)
74 
75 #ifdef CONFIG_DYNAMIC_INTERRUPTS
76 void z_isr_install(unsigned int irq, void (*routine)(const void *),
77 		   const void *param);
78 #endif
79 
80 #ifdef __cplusplus
81 }
82 #endif
83 
84 #endif /* _ASMLANGUAGE */
85 
86 #endif /* ZEPHYR_INCLUDE_SW_ISR_TABLE_H_ */
87