source: rtems/bsps/include/bsp/irq-generic.h @ 3ee19b7a

Last change on this file since 3ee19b7a was 3ee19b7a, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 17, 2021 at 2:01:48 PM

bsps/irq: Change license to BSD-2-Clause

Change license to BSD-2-Clause according to file history and
re-licensing agreement.

Update #3053.

  • Property mode set to 100644
File size: 11.0 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup bsp_interrupt
7 *
8 * @brief This header file provides interfaces of the generic interrupt
9 *   controller support.
10 */
11
12/*
13 * Copyright (C) 2016 Chris Johns <chrisj@rtems.org>
14 *
15 * Copyright (C) 2008, 2017 embedded brains GmbH (http://www.embedded-brains.de)
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 *    notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 *    notice, this list of conditions and the following disclaimer in the
24 *    documentation and/or other materials provided with the distribution.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39/*
40 * The API is based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
41 */
42
43#ifndef LIBBSP_SHARED_IRQ_GENERIC_H
44#define LIBBSP_SHARED_IRQ_GENERIC_H
45
46#include <stdbool.h>
47
48#include <rtems/irq-extension.h>
49#include <rtems/score/assert.h>
50
51#ifdef RTEMS_SMP
52  #include <rtems/score/atomic.h>
53#endif
54
55#include <bsp/irq.h>
56
57#ifdef __cplusplus
58extern "C" {
59#endif /* __cplusplus */
60
61#if !defined(BSP_INTERRUPT_VECTOR_MIN) || !defined(BSP_INTERRUPT_VECTOR_MAX) || (BSP_INTERRUPT_VECTOR_MAX + 1) < BSP_INTERRUPT_VECTOR_MIN
62  #error "invalid BSP_INTERRUPT_VECTOR_MIN or BSP_INTERRUPT_VECTOR_MAX"
63#endif
64
65#if defined(BSP_INTERRUPT_USE_INDEX_TABLE) && !defined(BSP_INTERRUPT_HANDLER_TABLE_SIZE)
66  #error "if you define BSP_INTERRUPT_USE_INDEX_TABLE, you have to define BSP_INTERRUPT_HANDLER_TABLE_SIZE etc. as well"
67#endif
68
69#if defined(BSP_INTERRUPT_NO_HEAP_USAGE) && !defined(BSP_INTERRUPT_USE_INDEX_TABLE)
70  #error "if you define BSP_INTERRUPT_NO_HEAP_USAGE, you have to define BSP_INTERRUPT_USE_INDEX_TABLE etc. as well"
71#endif
72
73#define BSP_INTERRUPT_VECTOR_NUMBER \
74  (BSP_INTERRUPT_VECTOR_MAX - BSP_INTERRUPT_VECTOR_MIN + 1)
75
76#ifndef BSP_INTERRUPT_HANDLER_TABLE_SIZE
77  #define BSP_INTERRUPT_HANDLER_TABLE_SIZE BSP_INTERRUPT_VECTOR_NUMBER
78#endif
79
80/* Internal macros for SMP support, do not use externally */
81#ifdef RTEMS_SMP
82  #define bsp_interrupt_disable(level) do { (void) level; } while (0)
83  #define bsp_interrupt_enable(level) do { } while (0)
84  #define bsp_interrupt_fence(order) _Atomic_Fence(order)
85#else
86  #define bsp_interrupt_disable(level) rtems_interrupt_disable(level)
87  #define bsp_interrupt_enable(level) rtems_interrupt_enable(level)
88  #define bsp_interrupt_fence(order) do { } while (0)
89#endif
90
91#define bsp_interrupt_assert(e) _Assert(e)
92
93struct bsp_interrupt_handler_entry {
94  rtems_interrupt_handler handler;
95  void *arg;
96  const char *info;
97  struct bsp_interrupt_handler_entry *next;
98};
99
100typedef struct bsp_interrupt_handler_entry bsp_interrupt_handler_entry;
101
102extern bsp_interrupt_handler_entry bsp_interrupt_handler_table [];
103
104#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
105  #if BSP_INTERRUPT_HANDLER_TABLE_SIZE < 0x100
106    typedef uint8_t bsp_interrupt_handler_index_type;
107  #elif BSP_INTERRUPT_HANDLER_TABLE_SIZE < 0x10000
108    typedef uint16_t bsp_interrupt_handler_index_type;
109  #else
110    typedef uint32_t bsp_interrupt_handler_index_type;
111  #endif
112  extern bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table [];
113#endif
114
115static inline rtems_vector_number bsp_interrupt_handler_index(
116  rtems_vector_number vector
117)
118{
119  #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
120    return bsp_interrupt_handler_index_table [vector - BSP_INTERRUPT_VECTOR_MIN];
121  #else
122    return vector - BSP_INTERRUPT_VECTOR_MIN;
123  #endif
124}
125
126/**
127 * @defgroup bsp_interrupt BSP Interrupt Support
128 *
129 * @ingroup RTEMSBSPsShared
130 *
131 * @brief Generic BSP Interrupt Support
132 *
133 * The BSP interrupt support manages a sequence of interrupt vector numbers
134 * ranging from @ref BSP_INTERRUPT_VECTOR_MIN to @ref BSP_INTERRUPT_VECTOR_MAX
135 * including the end points.  It provides methods to
136 * @ref bsp_interrupt_handler_install() "install",
137 * @ref bsp_interrupt_handler_remove() "remove" and
138 * @ref bsp_interrupt_handler_dispatch() "dispatch" interrupt handlers for each
139 * vector number.  It implements parts of the RTEMS interrupt manager.
140 *
141 * The entry points to a list of interrupt handlers are stored in a table
142 * (= handler table).
143 *
144 * You have to configure the BSP interrupt support in the <bsp/irq.h> file
145 * for each BSP.  For a minimum configuration you have to provide
146 * @ref BSP_INTERRUPT_VECTOR_MIN and @ref BSP_INTERRUPT_VECTOR_MAX.
147 *
148 * For boards with small memory requirements you can define
149 * @ref BSP_INTERRUPT_USE_INDEX_TABLE.  With an enabled index table the handler
150 * table will be accessed via a small index table.  You can define the size of
151 * the handler table with @ref BSP_INTERRUPT_HANDLER_TABLE_SIZE.
152 *
153 * Normally new list entries are allocated from the heap.  You may define
154 * @ref BSP_INTERRUPT_NO_HEAP_USAGE, if you do not want to use the heap.  For
155 * this option you have to define @ref BSP_INTERRUPT_USE_INDEX_TABLE as well.
156 *
157 * You have to provide some special routines in your BSP (follow the links for
158 * the details):
159 * - bsp_interrupt_facility_initialize()
160 * - bsp_interrupt_vector_enable()
161 * - bsp_interrupt_vector_disable()
162 * - bsp_interrupt_handler_default()
163 *
164 * The following now deprecated functions are provided for backward
165 * compatibility:
166 * - BSP_get_current_rtems_irq_handler()
167 * - BSP_install_rtems_irq_handler()
168 * - BSP_install_rtems_shared_irq_handler()
169 * - BSP_remove_rtems_irq_handler()
170 * - BSP_rtems_irq_mngt_set()
171 * - BSP_rtems_irq_mngt_get()
172 *
173 * @{
174 */
175
176#ifdef BSP_INTERRUPT_CUSTOM_VALID_VECTOR
177  bool bsp_interrupt_is_valid_vector(rtems_vector_number vector);
178#else
179  /**
180   * @brief Returns true if the interrupt vector with number @a vector is
181   * valid.
182   */
183  static inline bool bsp_interrupt_is_valid_vector(rtems_vector_number vector)
184  {
185    return (rtems_vector_number) BSP_INTERRUPT_VECTOR_MIN <= vector
186      && vector <= (rtems_vector_number) BSP_INTERRUPT_VECTOR_MAX;
187  }
188#endif
189
190/**
191 * @brief Default interrupt handler.
192 *
193 * This routine will be called from bsp_interrupt_handler_dispatch() with the
194 * current vector number @a vector when the handler list for this vector is
195 * empty or the vector number is out of range.
196 *
197 * @note This function must cope with arbitrary vector numbers @a vector.
198 */
199void bsp_interrupt_handler_default(rtems_vector_number vector);
200
201/**
202 * @brief Initialize BSP interrupt support.
203 *
204 * You must call this function before you can install, remove and dispatch
205 * interrupt handlers.  There is no protection against concurrent
206 * initialization.  This function must be called at most once.  The BSP
207 * specific bsp_interrupt_facility_initialize() function will be called after
208 * all internals are initialized.  If the BSP specific initialization fails,
209 * then this is a fatal error.  The fatal error source is
210 * RTEMS_FATAL_SOURCE_BSP and the fatal error code is
211 * BSP_FATAL_INTERRUPT_INITIALIZATION.
212 */
213void bsp_interrupt_initialize(void);
214
215/**
216 * @brief BSP specific initialization.
217 *
218 * This routine will be called form bsp_interrupt_initialize() and shall do the
219 * following:
220 * - Initialize the facilities that call bsp_interrupt_handler_dispatch().  For
221 * example on PowerPC the external exception handler.
222 * - Initialize the interrupt controller.  You shall set the interrupt
223 * controller in a state such that interrupts are disabled for all vectors.
224 * The vectors will be enabled with your bsp_interrupt_vector_enable() function
225 * and disabled via your bsp_interrupt_vector_disable() function.  These
226 * functions have to work afterwards.
227 *
228 * @return On success RTEMS_SUCCESSFUL shall be returned.
229 */
230rtems_status_code bsp_interrupt_facility_initialize(void);
231
232/**
233 * @brief Enables the interrupt vector with number @a vector.
234 *
235 * This function shall enable the vector at the corresponding facility (in most
236 * cases the interrupt controller).  It will be called then the first handler
237 * is installed for the vector in bsp_interrupt_handler_install() for example.
238 *
239 * @note The implementation should use
240 * bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)) to valdiate the
241 * vector number.
242 *
243 * @note You must not install or remove an interrupt handler in this function.
244 * This may result in a deadlock.
245 */
246void bsp_interrupt_vector_enable(rtems_vector_number vector);
247
248/**
249 * @brief Disables the interrupt vector with number @a vector.
250 *
251 * This function shall disable the vector at the corresponding facility (in
252 * most cases the interrupt controller).  It will be called then the last
253 * handler is removed for the vector in bsp_interrupt_handler_remove() for
254 * example.
255 *
256 * @note The implementation should use
257 * bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)) to valdiate the
258 * vector number.
259 *
260 * @note You must not install or remove an interrupt handler in this function.
261 * This may result in a deadlock.
262 */
263void bsp_interrupt_vector_disable(rtems_vector_number vector);
264
265/**
266 * @brief Sequencially calls all interrupt handlers for the vector number @a
267 * vector.
268 *
269 * If the vector number is out of range or the handler list is empty
270 * bsp_interrupt_handler_default() will be called with argument @a vector.
271 *
272 * You can call this function within every context which can be disabled via
273 * rtems_interrupt_disable().
274 */
275static inline void bsp_interrupt_handler_dispatch(rtems_vector_number vector)
276{
277  if (bsp_interrupt_is_valid_vector(vector)) {
278    const bsp_interrupt_handler_entry *e =
279      &bsp_interrupt_handler_table [bsp_interrupt_handler_index(vector)];
280
281    do {
282      rtems_interrupt_handler handler;
283      void *arg;
284
285      arg = e->arg;
286      bsp_interrupt_fence(ATOMIC_ORDER_ACQUIRE);
287      handler = e->handler;
288      (*handler)(arg);
289
290      e = e->next;
291    } while (e != NULL);
292  } else {
293    bsp_interrupt_handler_default(vector);
294  }
295}
296
297/**
298 * @brief Is interrupt handler empty.
299 *
300 * This routine returns true if the handler is empty and has not been
301 * initialised else false is returned. The interrupt lock is not used
302 * so this call can be used from within interrupts.
303 *
304 * @return If empty true shall be returned else false is returned.
305 */
306bool bsp_interrupt_handler_is_empty(rtems_vector_number vector);
307
308/** @} */
309
310/* For internal use only */
311void bsp_interrupt_lock(void);
312
313/* For internal use only */
314void bsp_interrupt_unlock(void);
315
316#ifdef __cplusplus
317}
318#endif /* __cplusplus */
319
320#endif /* LIBBSP_SHARED_IRQ_GENERIC_H */
Note: See TracBrowser for help on using the repository browser.