source: rtems/cpukit/score/include/rtems/score/isr.h @ 826fa6b1

4.115
Last change on this file since 826fa6b1 was 826fa6b1, checked in by Joel Sherrill <joel.sherrill@…>, on 05/07/12 at 23:29:56

Score ISR - Minimize Capabilities When Not Simple Vectored

In particular CPU_INTERRUPT_NUMBER_OF_VECTORS and
CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER are only used on
Simple Vectored Architectures, so do not depend on
them being defined. This disables as much as possible
that is specific to the Simple Vectored Model and
not expected to be used on architectures which use
the Programmable Interrupt Controller model for
interrupt handler vectoring.

  • Property mode set to 100644
File size: 10.9 KB
Line 
1/**
2 *  @file  rtems/score/isr.h
3 *
4 *  This include file contains all the constants and structures associated
5 *  with the management of processor interrupt levels.  This handler
6 *  supports interrupt critical sections, vectoring of user interrupt
7 *  handlers, nesting of interrupts, and manipulating interrupt levels.
8 */
9
10/*
11 *  COPYRIGHT (c) 1989-2012.
12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.com/license/LICENSE.
17 *
18 *  $Id$
19 */
20
21#ifndef _RTEMS_SCORE_ISR_H
22#define _RTEMS_SCORE_ISR_H
23
24#include <rtems/score/percpu.h>
25
26/**
27 *  @defgroup ScoreISR ISR Handler
28 *
29 *  @ingroup Score
30 *
31 *  This handler encapsulates functionality which provides the foundation
32 *  ISR services used in all of the APIs supported by RTEMS.
33 *
34 *  The ISR Nest level counter variable is maintained as part of the
35 *  per cpu data structure.
36 */
37/**@{*/
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43/**
44 *  The following type defines the type used to manage the vectors.
45 */
46typedef uint32_t   ISR_Vector_number;
47
48/**
49 *  Return type for ISR Handler
50 */
51typedef void ISR_Handler;
52
53#if (CPU_SIMPLE_VECTORED_INTERRUPTS == FALSE)
54
55typedef void * ISR_Handler_entry;
56
57#else
58/**
59 *  Pointer to an ISR Handler
60 */
61#if (CPU_ISR_PASSES_FRAME_POINTER == 1)
62typedef ISR_Handler ( *ISR_Handler_entry )(
63                 ISR_Vector_number,
64                 CPU_Interrupt_frame *
65             );
66#else
67typedef ISR_Handler ( *ISR_Handler_entry )(
68                 ISR_Vector_number
69             );
70#endif
71
72/**
73 *  This constant promotes out the number of vectors truly supported by
74 *  the current CPU being used.  This is usually the number of distinct vectors
75 *  the cpu can vector.
76 */
77#define ISR_NUMBER_OF_VECTORS                CPU_INTERRUPT_NUMBER_OF_VECTORS
78
79/**
80 *  This constant promotes out the highest valid interrupt vector number.
81 */
82#define ISR_INTERRUPT_MAXIMUM_VECTOR_NUMBER  CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER
83
84/**
85 *  The following declares the Vector Table.  Application
86 *  interrupt service routines are vectored by the ISR Handler via this table.
87 */
88SCORE_EXTERN ISR_Handler_entry *_ISR_Vector_table;
89#endif
90
91/**
92 *  This routine performs the initialization necessary for this handler.
93 */
94void _ISR_Handler_initialization ( void );
95
96/**
97 *  @brief Disable Interrupts on This Core
98 *
99 *  This routine disables all interrupts so that a critical section
100 *  of code can be executing without being interrupted.
101 *
102 *  @return The argument @a _level will contain the previous interrupt
103 *          mask level.
104 */
105#define _ISR_Disable_on_this_core( _level ) \
106  do { \
107    _CPU_ISR_Disable( _level ); \
108    RTEMS_COMPILER_MEMORY_BARRIER(); \
109  } while (0)
110
111/**
112 *  @brief Enable Interrupts on This Core
113 *
114 *  This routine enables interrupts to the previous interrupt mask
115 *  LEVEL.  It is used at the end of a critical section of code to
116 *  enable interrupts so they can be processed again.
117 *
118 *  @param[in] level contains the interrupt level mask level
119 *             previously returned by @ref _ISR_Disable_on_this_core.
120 */
121#define _ISR_Enable_on_this_core( _level ) \
122  do { \
123    RTEMS_COMPILER_MEMORY_BARRIER(); \
124    _CPU_ISR_Enable( _level ); \
125  } while (0)
126
127/**
128 *  @brief Temporarily Enable Interrupts on This Core
129 *
130 *  This routine temporarily enables interrupts to the previous
131 *  interrupt mask level and then disables all interrupts so that
132 *  the caller can continue into the second part of a critical
133 *  section.
134 *
135 *  This routine is used to temporarily enable interrupts
136 *  during a long critical section.  It is used in long sections of
137 *  critical code when a point is reached at which interrupts can
138 *  be temporarily enabled.  Deciding where to flash interrupts
139 *  in a long critical section is often difficult and the point
140 *  must be selected with care to ensure that the critical section
141 *  properly protects itself.
142 *
143 *  @param[in] level contains the interrupt level mask level
144 *             previously returned by @ref _ISR_Disable_on_this_core.
145 */
146#define _ISR_Flash_on_this_core( _level ) \
147  do { \
148    RTEMS_COMPILER_MEMORY_BARRIER(); \
149    _CPU_ISR_Flash( _level ); \
150    RTEMS_COMPILER_MEMORY_BARRIER(); \
151  } while (0)
152
153#if defined(RTEMS_SMP)
154
155/**
156 *  @brief Initialize SMP Interrupt Critical Section Support
157 *
158 *  This method initializes the variables required by the SMP implementation
159 *  of interrupt critical section management.
160 */
161void _ISR_SMP_Initialize(void);
162
163/**
164 *  @brief Enter Interrupt Critical Section on SMP System
165 *
166 *  This method is used to enter an interrupt critical section that
167 *  is honored across all cores in an SMP system.
168 *
169 *  @return This method returns the previous interrupt mask level.
170 */
171ISR_Level _ISR_SMP_Disable(void);
172
173/**
174 *  @brief Exit Interrupt Critical Section on SMP System
175 *
176 *  This method is used to exit an interrupt critical section that
177 *  is honored across all cores in an SMP system.
178 *
179 *  @param[in] level contains the interrupt level mask level
180 *             previously returned by @ref _ISR_SMP_Disable.
181 */
182void _ISR_SMP_Enable(ISR_Level level);
183
184/**
185 *  @brief Temporarily Exit Interrupt Critical Section on SMP System
186 *
187 *  This method is used to temporarily exit an interrupt critical section
188 *  that is honored across all cores in an SMP system.
189 *
190 *  @param[in] level contains the interrupt level mask level
191 *             previously returned by @ref _ISR_SMP_Disable.
192 */
193void _ISR_SMP_Flash(ISR_Level level);
194
195/**
196 *  @brief Enter SMP interrupt code
197 *
198 *  This method is used to enter the SMP interrupt section.
199 *
200 *  @return This method returns the isr level.
201 */
202int _ISR_SMP_Enter(void);
203
204/**
205 *  @brief Exit SMP interrupt code
206 *
207 *  This method is used to exit the SMP interrupt.
208 *
209 *  @return This method returns 0 on a simple return and returns 1 on a
210 *  dispatching return.
211 */
212int _ISR_SMP_Exit(void);
213
214#endif
215
216/**
217 *  @brief Enter Interrupt Disable Critical Section
218 *
219 *  This routine enters an interrupt disable critical section.  When
220 *  in an SMP configuration, this involves obtaining a spinlock to ensure
221 *  that only one core is inside an interrupt disable critical section.
222 *  When on a single core system, this only involves disabling local
223 *  CPU interrupts.
224 *
225 *  @return The argument @a _level will contain the previous interrupt
226 *          mask level.
227 */
228#if defined(RTEMS_SMP)
229  #define _ISR_Disable( _level ) \
230    _level = _ISR_SMP_Disable();
231#else
232  #define _ISR_Disable( _level ) \
233    _ISR_Disable_on_this_core( _level );
234#endif
235 
236/**
237 *  @brief Exits Interrupt Disable Critical Section
238 *
239 *  This routine exits an interrupt disable critical section.  When
240 *  in an SMP configuration, this involves releasing a spinlock.
241 *  When on a single core system, this only involves disabling local
242 *  CPU interrupts.
243 *
244 *  @return The argument @a _level will contain the previous interrupt
245 *          mask level.
246 */
247#if defined(RTEMS_SMP)
248  #define _ISR_Enable( _level ) \
249    _ISR_SMP_Enable( _level );
250#else
251  #define _ISR_Enable( _level ) \
252    _ISR_Enable_on_this_core( _level );
253#endif
254
255/**
256 *  @brief Temporarily Exit Interrupt Disable Critical Section
257 *
258 *  This routine is used to temporarily enable interrupts
259 *  during a long critical section.  It is used in long sections of
260 *  critical code when a point is reached at which interrupts can
261 *  be temporarily enabled.  Deciding where to flash interrupts
262 *  in a long critical section is often difficult and the point
263 *  must be selected with care to ensure that the critical section
264 *  properly protects itself.
265 *
266 *  @return The argument @a _level will contain the previous interrupt
267 *          mask level.
268 */
269#if defined(RTEMS_SMP)
270  #define _ISR_Flash( _level ) \
271    _ISR_SMP_Flash( _level );
272#else
273  #define _ISR_Flash( _level ) \
274    _ISR_Flash_on_this_core( _level );
275#endif
276
277/**
278 *  @brief Install Interrupt Handler Vector
279 *
280 *  This routine installs new_handler as the interrupt service routine
281 *  for the specified vector.  The previous interrupt service routine is
282 *  returned as old_handler.
283 *
284 *  @param[in] _vector is the vector number
285 *  @param[in] _new_handler is ISR handler to install
286 *  @param[in] _old_handler is a pointer to a variable which will be set
287 *             to the old handler
288 *
289 *  @return *_old_handler will be set to the old ISR handler
290 */
291#define _ISR_Install_vector( _vector, _new_handler, _old_handler ) \
292  _CPU_ISR_install_vector( _vector, _new_handler, _old_handler )
293
294/**
295 *  @brief Return Current Interrupt Level
296 *
297 *  This routine returns the current interrupt level.
298 *
299 *  @return This method returns the current level.
300 */
301#define _ISR_Get_level() \
302        _CPU_ISR_Get_level()
303
304/**
305 *  @brief Set Current Interrupt Level
306 *
307 *  This routine sets the current interrupt level to that specified
308 *  by @a _new_level.  The new interrupt level is effective when the
309 *  routine exits.
310 *
311 *  @param[in] _new_level contains the desired interrupt level.
312 */
313#define _ISR_Set_level( _new_level ) \
314  do { \
315    RTEMS_COMPILER_MEMORY_BARRIER();  \
316    _CPU_ISR_Set_level( _new_level ); \
317    RTEMS_COMPILER_MEMORY_BARRIER();  \
318  } while (0)
319
320/**
321 *  @brief ISR Handler or Dispatcher
322 *
323 *  This routine is the interrupt dispatcher.  ALL interrupts
324 *  are vectored to this routine so that minimal context can be saved
325 *  and setup performed before the application's high-level language
326 *  interrupt service routine is invoked.   After the application's
327 *  interrupt service routine returns control to this routine, it
328 *  will determine if a thread dispatch is necessary.  If so, it will
329 *  ensure that the necessary thread scheduling operations are
330 *  performed when the outermost interrupt service routine exits.
331 *
332 *  @note  Typically implemented in assembly language.
333 */
334void _ISR_Handler( void );
335
336/**
337 *  @brief ISR Wrapper for Thread Dispatcher
338 *
339 *  This routine provides a wrapper so that the routine
340 *  @ref _Thread_Dispatch can be invoked when a reschedule is necessary
341 *  at the end of the outermost interrupt service routine.  This
342 *  wrapper is necessary to establish the processor context needed
343 *  by _Thread_Dispatch and to save the processor context which is
344 *  corrupted by _Thread_Dispatch.  This context typically consists
345 *  of registers which are not preserved across routine invocations.
346 *
347 *  @note  Typically mplemented in assembly language.
348 */
349void _ISR_Dispatch( void );
350
351/**
352 *  @brief Is an ISR in Progress
353 *
354 *  This function returns true if the processor is currently servicing
355 *  and interrupt and false otherwise.   A return value of true indicates
356 *  that the caller is an interrupt service routine, NOT a thread.
357 *
358 *  @return This methods returns true when called from an ISR.
359 */
360#if (CPU_PROVIDES_ISR_IS_IN_PROGRESS == TRUE)
361  bool _ISR_Is_in_progress( void );
362#else
363  #define _ISR_Is_in_progress() \
364          (_ISR_Nest_level != 0)
365#endif
366
367#include <rtems/score/isr.inl>
368
369#ifdef __cplusplus
370}
371#endif
372
373/**@}*/
374
375#endif
376/* end of include file */
Note: See TracBrowser for help on using the repository browser.