source: rtems/cpukit/score/include/rtems/score/percpu.h @ df00777

4.115
Last change on this file since df00777 was df00777, checked in by Jennifer Averett <Jennifer.Averett@…>, on 07/15/11 at 14:36:37

2011-07-15 Jennifer Averett <Jennifer.Averett@…>

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