source: rtems/cpukit/score/include/rtems/score/percpu.h @ 27f09f17

4.11
Last change on this file since 27f09f17 was dacdda30, checked in by Ralf Corsepius <ralf.corsepius@…>, on May 24, 2011 at 2:44:58 AM

Remove white-spaces.

  • Property mode set to 100644
File size: 7.1 KB
Line 
1/**
2 *  @file  rtems/score/percpu.h
3 *
4 *  This include file defines the per CPU information required
5 *  by RTEMS.
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2011.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.com/license/LICENSE.
15 *
16 *  $Id$
17 */
18
19#ifndef _RTEMS_PERCPU_H
20#define _RTEMS_PERCPU_H
21
22#include <rtems/score/cpu.h>
23
24#ifdef ASM
25  #include <rtems/asm.h>
26#else
27  #include <rtems/score/timestamp.h>
28  #if defined(RTEMS_SMP)
29    #include <rtems/score/smplock.h>
30  #endif
31
32  /*
33   * NOTE: This file MUST be included on non-smp systems as well
34   *       in order to define bsp_smp_processor_id.
35   */
36  #include <rtems/bspsmp.h>
37#endif
38
39/**
40 *  @defgroup PerCPU RTEMS Per CPU Information
41 *
42 *  This defines the per CPU state information required by RTEMS
43 *  and the BSP.  In an SMP configuration, there will be multiple
44 *  instances of this data structure -- one per CPU -- and the
45 *  current CPU number will be used as the index.
46 */
47
48/**@{*/
49
50#ifdef __cplusplus
51extern "C" {
52#endif
53
54#ifndef ASM
55#include <rtems/score/timestamp.h>
56
57#ifndef __THREAD_CONTROL_DEFINED__
58#define __THREAD_CONTROL_DEFINED__
59typedef struct Thread_Control_struct Thread_Control;
60#endif
61
62#if (CPU_ALLOCATE_INTERRUPT_STACK == FALSE) && defined(RTEMS_SMP)
63  #error "RTEMS must allocate per CPU interrupt stack for SMP"
64#endif
65
66typedef enum {
67
68  /**
69   *  This defines the constant used to indicate that the cpu code is in
70   *  its initial powered up start.
71   */
72   RTEMS_BSP_SMP_CPU_INITIAL_STATE = 1,
73
74  /**
75   *  This defines the constant used to indicate that the cpu code has
76   *  completed basic initialization and awaits further commands.
77   */
78   RTEMS_BSP_SMP_CPU_INITIALIZED = 2,
79
80  /**
81   *  This defines the constant used to indicate that the cpu code has
82   *  shut itself down.
83   */
84  RTEMS_BSP_SMP_CPU_SHUTDOWN = 3
85} bsp_smp_cpu_state;
86
87/**
88 *  @brief Per CPU Core Structure
89 *
90 *  This structure is used to hold per core state information.
91 */
92typedef struct {
93  #if defined(RTEMS_SMP)
94    /** This element is used to lock this structure */
95    SMP_lock_spinlock_simple_Control  lock;
96
97    /** This indicates that the CPU is online. */
98    uint32_t                          state;
99
100    /**
101     *  This is the request for the interrupt.
102     *
103     *  @note This may become a chain protected by atomic instructions.
104     */
105    uint32_t                          message;
106  #endif
107
108#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
109    (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
110  /**
111   * This contains a pointer to the lower range of the interrupt stack for
112   * this CPU.  This is the address allocated and freed.
113   */
114  void  *interrupt_stack_low;
115
116  /**
117   * This contains a pointer to the interrupt stack pointer for this CPU.
118   * It will be loaded at the beginning on an ISR.
119   */
120  void  *interrupt_stack_high;
121#endif
122
123  /**
124   *  This contains the current interrupt nesting level on this
125   *  CPU.
126   */
127  uint32_t isr_nest_level;
128
129  /** This is the thread executing on this CPU. */
130  Thread_Control *executing;
131
132  /** This is the heir thread for this this CPU. */
133  Thread_Control *heir;
134
135  /** This is the idle thread for this CPU. */
136  Thread_Control *idle;
137
138  /** This is set to true when this CPU needs to run the dispatcher. */
139  volatile bool dispatch_necessary;
140
141  /** This is the time of the last context switch on this CPU. */
142  Timestamp_Control time_of_last_context_switch;
143} Per_CPU_Control;
144#endif
145
146#ifdef ASM
147#if defined(RTEMS_SMP)
148  #define PER_CPU_LOCK     0
149  #define PER_CPU_STATE    (1 * __RTEMS_SIZEOF_VOID_P__)
150  #define PER_CPU_MESSAGE  (2 * __RTEMS_SIZEOF_VOID_P__)
151  #define PER_CPU_END_SMP  (3 * __RTEMS_SIZEOF_VOID_P__)
152#else
153  #define PER_CPU_END_SMP  0
154#endif
155
156#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
157    (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
158  /*
159   *  If this CPU target lets RTEMS allocates the interrupt stack, then
160   *  we need to have places in the per cpu table to hold them.
161   */
162  #define PER_CPU_INTERRUPT_STACK_LOW   PER_CPU_END_SMP
163  #define PER_CPU_INTERRUPT_STACK_HIGH  \
164          PER_CPU_INTERRUPT_STACK_LOW + (1 * __RTEMS_SIZEOF_VOID_P__)
165  #define PER_CPU_END_STACK             \
166          PER_CPU_INTERRUPT_STACK_HIGH + (1 * __RTEMS_SIZEOF_VOID_P__)
167#else
168  #define PER_CPU_END_STACK             PER_CPU_END_SMP
169#endif
170
171/*
172 *  These are the offsets of the required elements in the per CPU table.
173 */
174#define PER_CPU_ISR_NEST_LEVEL \
175          PER_CPU_END_STACK + 0
176#define PER_CPU_EXECUTING \
177          PER_CPU_END_STACK + (1 * __RTEMS_SIZEOF_VOID_P__)
178#define PER_CPU_HEIR \
179          PER_CPU_END_STACK + (2 * __RTEMS_SIZEOF_VOID_P__)
180#define PER_CPU_IDLE \
181          PER_CPU_END_STACK + (3 * __RTEMS_SIZEOF_VOID_P__)
182#define PER_CPU_DISPATCH_NEEDED \
183          PER_CPU_END_STACK + (4 * __RTEMS_SIZEOF_VOID_P__)
184
185#define ISR_NEST_LEVEL \
186         (SYM(_Per_CPU_Information) + PER_CPU_ISR_NEST_LEVEL)
187#define DISPATCH_NEEDED \
188         (SYM(_Per_CPU_Information) + PER_CPU_DISPATCH_NEEDED)
189
190/*
191 * Do not define these offsets if they are not in the table.
192 */
193#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
194    (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
195  #define INTERRUPT_STACK_LOW \
196      (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_LOW)
197  #define INTERRUPT_STACK_HIGH \
198      (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_HIGH)
199#endif
200
201#endif
202
203#ifndef ASM
204
205/**
206 *  @brief Set of Per CPU Core Information
207 *
208 *  This is an array of per CPU core information.
209 */
210extern Per_CPU_Control _Per_CPU_Information[];
211
212#if defined(RTEMS_SMP)
213/**
214 *  @brief Set of Pointers to Per CPU Core Information
215 *
216 *  This is an array of pointers to each CPU's per CPU data structure.
217 *  It should be simpler to retrieve this pointer in assembly language
218 *  that to calculate the array offset.
219 */
220extern Per_CPU_Control *_Per_CPU_Information_p[];
221
222/**
223 *  @brief Initialize SMP Handler
224 *
225 *  This method initialize the SMP Handler.
226 */
227void _SMP_Handler_initialize(void);
228
229/**
230 *  @brief Allocate and Initialize Per CPU Structures
231 *
232 *  This method allocates and initialize the per CPU structure.
233 */
234void _Per_CPU_Initialize(void);
235
236#endif
237
238/*
239 * On a non SMP system, the bsp_smp_processor_id is defined to 0.
240 * Thus when built for non-SMP, there should be no performance penalty.
241 */
242#define _Thread_Heir \
243  _Per_CPU_Information[bsp_smp_processor_id()].heir
244#define _Thread_Executing \
245  _Per_CPU_Information[bsp_smp_processor_id()].executing
246#define _Thread_Idle \
247  _Per_CPU_Information[bsp_smp_processor_id()].idle
248#define _ISR_Nest_level \
249  _Per_CPU_Information[bsp_smp_processor_id()].isr_nest_level
250#define _CPU_Interrupt_stack_low \
251  _Per_CPU_Information[bsp_smp_processor_id()].interrupt_stack_low
252#define _CPU_Interrupt_stack_high \
253  _Per_CPU_Information[bsp_smp_processor_id()].interrupt_stack_high
254#define _Thread_Dispatch_necessary \
255  _Per_CPU_Information[bsp_smp_processor_id()].dispatch_necessary
256#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
257  #define _Thread_Time_of_last_context_switch \
258    _Per_CPU_Information[bsp_smp_processor_id()].time_of_last_context_switch
259#endif
260
261
262#endif  /* ASM */
263
264#ifdef __cplusplus
265}
266#endif
267
268/**@}*/
269
270#endif
271/* end of include file */
Note: See TracBrowser for help on using the repository browser.