summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems/rtems/intr.h
blob: be216a013c53ba25d834d7608aa92a55d9429b38 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
/**
 *  @file
 *
 * @defgroup ClassicINTR Interrupts
 *
 * @ingroup ClassicRTEMS
 * @brief Header file for Interrupt Manager
 *
 * This include file contains all the constants and structures associated with
 * the Interrupt Manager.
 */

/* COPYRIGHT (c) 1989-2013.
 * On-Line Applications Research Corporation (OAR).
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rtems.org/license/LICENSE.
 */

#ifndef _RTEMS_RTEMS_INTR_H
#define _RTEMS_RTEMS_INTR_H

#include <rtems/rtems/status.h>
#include <rtems/score/isr.h>
#include <rtems/score/isrlock.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 *  @defgroup ClassicINTR Interrupts
 *
 *  @ingroup ClassicRTEMS
 *
 *  This encapsulates functionality related to the Classic API Interrupt
 *  Manager.
 */
/**@{*/

/**
 *  @brief Interrupt level type.
 */
typedef ISR_Level rtems_interrupt_level;

/**
 *  @brief Control block type used to manage the vectors.
 */
typedef ISR_Vector_number rtems_vector_number;

/**
 *  @brief Return type for interrupt handler.
 */
typedef ISR_Handler rtems_isr;

#if (CPU_SIMPLE_VECTORED_INTERRUPTS == FALSE)

typedef ISR_Handler_entry rtems_isr_entry;

#else
/**
 *  @brief Interrupt handler type.
 *
 *  @see rtems_interrupt_catch()
 */
typedef rtems_isr ( *rtems_isr_entry )(
                 rtems_vector_number
             );

/**
 * @brief RTEMS Interrupt Catch
 *
 * This directive installs @a new_isr_handler as the RTEMS interrupt service
 * routine for the interrupt vector with number @a vector. The previous RTEMS
 * interrupt service routine is returned in @a old_isr_handler.
 *  
 * @param[in] new_isr_handler is the address of interrupt service routine
 * @param[in] vector is the interrupt vector number
 * @param[in] old_isr_handler address at which to store previous ISR address
 * 
 * @retval RTEMS_SUCCESSFUL and *old_isr_handler filled with previous ISR
 * 		address
 */
rtems_status_code rtems_interrupt_catch(
  rtems_isr_entry      new_isr_handler,
  rtems_vector_number  vector,
  rtems_isr_entry     *old_isr_handler
);
#endif

#if !defined(RTEMS_SMP)

/**
 *  @brief Disable RTEMS Interrupt
 *
 *  @note The interrupt level shall be of type @ref rtems_interrupt_level.
 *
 *  This macro is only available on uni-processor configurations.  The macro
 *  rtems_interrupt_local_disable() is available on all configurations.
 */
#define rtems_interrupt_disable( _isr_cookie ) \
    _ISR_Local_disable(_isr_cookie)

/**
 *  @brief Enable RTEMS Interrupt
 *
 *  @note The interrupt level shall be of type @ref rtems_interrupt_level.
 *
 *  This macro is only available on uni-processor configurations.  The macro
 *  rtems_interrupt_local_enable() is available on all configurations.
 */
#define rtems_interrupt_enable( _isr_cookie ) \
    _ISR_Local_enable(_isr_cookie)

/**
 *  @brief Flash RTEMS Interrupt
 *
 *  @note The interrupt level shall be of type @ref rtems_interrupt_level.
 *
 *  This macro is only available on uni-processor configurations.  The macro
 *  rtems_interrupt_local_disable() and rtems_interrupt_local_enable() is
 *  available on all configurations.
 */
#define rtems_interrupt_flash( _isr_cookie ) \
    _ISR_Local_flash(_isr_cookie)

#endif /* RTEMS_SMP */

/**
 * @brief This macro disables the interrupts on the current processor.
 *
 * On SMP configurations this will not ensure system wide mutual exclusion.
 * Use interrupt locks instead.
 *
 * @param[in] _isr_cookie The previous interrupt level is returned.  The type
 *   of this variable must be rtems_interrupt_level.
 *
 * @see rtems_interrupt_local_enable().
 */
#define rtems_interrupt_local_disable( _isr_cookie ) \
  _ISR_Local_disable( _isr_cookie )

/**
 * @brief This macro restores the previous interrupt level on the current
 * processor.
 *
 * @param[in] _isr_cookie The previous interrupt level returned by
 *   rtems_interrupt_local_disable().
 */
#define rtems_interrupt_local_enable( _isr_cookie ) \
  _ISR_Local_enable( _isr_cookie )

/**
 *  @brief RTEMS Interrupt Is in Progress
 *
 *  A return value of true indicates that the caller is an interrupt service
 *  routine and @b not a thread.  The directives available to an interrupt
 *  service routine are restricted.
 */
#define rtems_interrupt_is_in_progress() \
    _ISR_Is_in_progress()

/**
 *  @brief This routine generates an interrupt.
 *
 *  @note No implementation.
 */
#define rtems_interrupt_cause( _interrupt_to_cause )

/**
 *  @brief This routine clears the specified interrupt.
 *
 *  @note No implementation.
 */
#define rtems_interrupt_clear( _interrupt_to_clear )

/**
 * @defgroup ClassicINTRLocks Interrupt Locks
 *
 * @ingroup ClassicINTR
 *
 * @brief Low-level lock to protect critical sections accessed by threads and
 * interrupt service routines.
 *
 * On single processor configurations the interrupt locks degrade to simple
 * interrupt disable/enable sequences.  No additional storage or objects are
 * required.
 *
 * This synchronization primitive is supported on SMP configurations.  Here SMP
 * locks are used.
 * @{
 */

/**
 * @brief Interrupt lock control.
 */
typedef ISR_lock_Control rtems_interrupt_lock;

/**
 * @brief Local interrupt lock context for acquire and release pairs.
 */
typedef ISR_lock_Context rtems_interrupt_lock_context;

/**
 * @brief Defines an interrupt lock member.
 *
 * Do not add a ';' after this macro.
 *
 * @param _designator The designator for the interrupt lock.
 */
#define RTEMS_INTERRUPT_LOCK_MEMBER( _designator ) \
  ISR_LOCK_MEMBER( _designator )

/**
 * @brief Declares an interrupt lock variable.
 *
 * Do not add a ';' after this macro.
 *
 * @param _qualifier The qualifier for the interrupt lock, e.g. extern.
 * @param _designator The designator for the interrupt lock.
 */
#define RTEMS_INTERRUPT_LOCK_DECLARE( _qualifier, _designator ) \
  ISR_LOCK_DECLARE( _qualifier, _designator )

/**
 * @brief Defines an interrupt lock variable.
 *
 * Do not add a ';' after this macro.
 *
 * @param _qualifier The qualifier for the interrupt lock, e.g. static.
 * @param _designator The designator for the interrupt lock.
 * @param _name The name for the interrupt lock.  It must be a string.  The
 * name is only used if profiling is enabled.
 */
#define RTEMS_INTERRUPT_LOCK_DEFINE( _qualifier, _designator, _name ) \
  ISR_LOCK_DEFINE( _qualifier, _designator, _name )

/**
 * @brief Defines an interrupt lock variable reference.
 *
 * Do not add a ';' after this macro.
 *
 * @param _designator The designator for the interrupt lock reference.
 * @param _target The target for the interrupt lock reference.
 */
#define RTEMS_INTERRUPT_LOCK_REFERENCE( _designator, _target ) \
  ISR_LOCK_REFERENCE( _designator, _target )

/**
 * @brief Initializer for static initialization of interrupt locks.
 *
 * @param _name The name for the interrupt lock.  It must be a string.  The
 * name is only used if profiling is enabled.
 */
#define RTEMS_INTERRUPT_LOCK_INITIALIZER( _name ) ISR_LOCK_INITIALIZER( _name )

/**
 * @brief Initializes an interrupt lock.
 *
 * Concurrent initialization leads to unpredictable results.
 *
 * @param[in,out] _lock The interrupt lock.
 * @param[in] _name The name for the interrupt lock.  This name must be a
 * string persistent throughout the life time of this lock.  The name is only
 * used if profiling is enabled.
 */
#define rtems_interrupt_lock_initialize( _lock, _name ) \
  _ISR_lock_Initialize( _lock, _name )

/**
 * @brief Destroys an interrupt lock.
 *
 * Concurrent destruction leads to unpredictable results.
 *
 * @param[in,out] _lock The interrupt lock control.
 */
#define rtems_interrupt_lock_destroy( _lock ) \
  _ISR_lock_Destroy( _lock )

/**
 * @brief Disables interrupts on the current processor.
 *
 * This function can be used in thread and interrupt context.
 *
 * @param[in,out] _lock_context The local interrupt lock context for an acquire
 * and release pair.
 *
 * @see rtems_interrupt_lock_acquire_isr().
 */
#define rtems_interrupt_lock_interrupt_disable( _lock_context ) \
  _ISR_lock_ISR_disable( _lock_context )

/**
 * @brief Acquires an interrupt lock.
 *
 * Interrupts will be disabled.  On SMP configurations this function acquires
 * an SMP lock.
 *
 * This function can be used in thread and interrupt context.
 *
 * @param[in,out] _lock The interrupt lock.
 * @param[in,out] _lock_context The local interrupt lock context for an acquire
 * and release pair.
 *
 * @see rtems_interrupt_lock_release().
 */
#define rtems_interrupt_lock_acquire( _lock, _lock_context ) \
  _ISR_lock_ISR_disable_and_acquire( _lock, _lock_context )

/**
 * @brief Releases an interrupt lock.
 *
 * The interrupt status will be restored.  On SMP configurations this function
 * releases an SMP lock.
 *
 * This function can be used in thread and interrupt context.
 *
 * @param[in,out] _lock The interrupt lock.
 * @param[in,out] _lock_context The local interrupt lock context for an acquire
 * and release pair.
 *
 * @see rtems_interrupt_lock_acquire().
 */
#define rtems_interrupt_lock_release( _lock, _lock_context ) \
  _ISR_lock_Release_and_ISR_enable( _lock, _lock_context )

/**
 * @brief Acquires an interrupt lock in the corresponding interrupt service
 * routine.
 *
 * The interrupt status will remain unchanged.  On SMP configurations this
 * function acquires an SMP lock.
 *
 * In case the corresponding interrupt service routine can be interrupted by
 * higher priority interrupts and these interrupts enter the critical section
 * protected by this lock, then the result is unpredictable.
 *
 * @param[in,out] _lock The interrupt lock.
 * @param[in,out] _lock_context The local interrupt lock context for an acquire
 * and release pair.
 *
 * @see rtems_interrupt_lock_release_isr().
 */
#if defined(RTEMS_SMP)
  #define rtems_interrupt_lock_acquire_isr( _lock, _lock_context ) \
    _SMP_lock_Acquire( \
      &( _lock )->Lock, \
      &( _lock_context )->Lock_context \
    )
#else
  #define rtems_interrupt_lock_acquire_isr( _lock, _lock_context ) \
    do { (void) _lock_context; } while ( 0 )
#endif

/**
 * @brief Releases an interrupt lock in the corresponding interrupt service
 * routine.
 *
 * The interrupt status will remain unchanged.  On SMP configurations this
 * function releases an SMP lock.
 *
 * @param[in,out] _lock The interrupt lock.
 * @param[in,out] _lock_context The local interrupt lock context for an acquire
 * and release pair.
 *
 * @see rtems_interrupt_lock_acquire_isr().
 */
#if defined(RTEMS_SMP)
  #define rtems_interrupt_lock_release_isr( _lock, _lock_context ) \
    _SMP_lock_Release( \
      &( _lock )->Lock, \
      &( _lock_context )->Lock_context \
    )
#else
  #define rtems_interrupt_lock_release_isr( _lock, _lock_context ) \
    do { (void) _lock_context; } while ( 0 )
#endif

/** @} */

#ifdef __cplusplus
}
#endif

/**@}*/

#endif
/* end of include file */