source: rtems/cpukit/score/include/rtems/score/isr.h @ f70526a7

4.115
Last change on this file since f70526a7 was f70526a7, checked in by Sebastian Huber <sebastian.huber@…>, on 06/11/13 at 07:26:30

score: Avoid cyclic include dependency

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