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

4.11
Last change on this file since d4dc7c8 was d4dc7c8, checked in by Jennifer Averett <Jennifer.Averett@…>, on May 26, 2011 at 6:07:07 PM

2011-05-26 Jennifer Averett <Jennifer.Averett@…>

PR 1796/cpukit

  • sapi/src/exshutdown.c, score/include/rtems/score/percpu.h, score/include/rtems/score/smp.h, score/src/smp.c, score/src/threaddispatch.c, score/src/threadhandler.c: Added SMP interprocess communications.
  • 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/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   *  completed basic initialization and awaits further commands.
83   */
84  RTEMS_BSP_SMP_CPU_UP = 3,
85
86  /**
87   *  This defines the constant used to indicate that the cpu code has
88   *  shut itself down.
89   */
90  RTEMS_BSP_SMP_CPU_SHUTDOWN = 4
91} bsp_smp_cpu_state;
92
93/**
94 *  @brief Per CPU Core Structure
95 *
96 *  This structure is used to hold per core state information.
97 */
98typedef struct {
99  #if defined(RTEMS_SMP)
100    /** This element is used to lock this structure */
101    SMP_lock_spinlock_simple_Control  lock;
102
103    /** This indicates that the CPU is online. */
104    uint32_t                          state;
105
106    /**
107     *  This is the request for the interrupt.
108     *
109     *  @note This may become a chain protected by atomic instructions.
110     */
111    uint32_t                          message;
112  #endif
113
114#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
115    (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
116  /**
117   * This contains a pointer to the lower range of the interrupt stack for
118   * this CPU.  This is the address allocated and freed.
119   */
120  void  *interrupt_stack_low;
121
122  /**
123   * This contains a pointer to the interrupt stack pointer for this CPU.
124   * It will be loaded at the beginning on an ISR.
125   */
126  void  *interrupt_stack_high;
127#endif
128
129  /**
130   *  This contains the current interrupt nesting level on this
131   *  CPU.
132   */
133  uint32_t isr_nest_level;
134
135  /** This is the thread executing on this CPU. */
136  Thread_Control *executing;
137
138  /** This is the heir thread for this this CPU. */
139  Thread_Control *heir;
140
141  /** This is the idle thread for this CPU. */
142  Thread_Control *idle;
143
144  /** This is set to true when this CPU needs to run the dispatcher. */
145  volatile bool dispatch_necessary;
146
147  /** This is the time of the last context switch on this CPU. */
148  Timestamp_Control time_of_last_context_switch;
149} Per_CPU_Control;
150#endif
151
152#ifdef ASM
153#if defined(RTEMS_SMP)
154  #define PER_CPU_LOCK     0
155  #define PER_CPU_STATE    (1 * __RTEMS_SIZEOF_VOID_P__)
156  #define PER_CPU_MESSAGE  (2 * __RTEMS_SIZEOF_VOID_P__)
157  #define PER_CPU_END_SMP  (3 * __RTEMS_SIZEOF_VOID_P__)
158#else
159  #define PER_CPU_END_SMP  0
160#endif
161
162#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
163    (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
164  /*
165   *  If this CPU target lets RTEMS allocates the interrupt stack, then
166   *  we need to have places in the per cpu table to hold them.
167   */
168  #define PER_CPU_INTERRUPT_STACK_LOW   PER_CPU_END_SMP
169  #define PER_CPU_INTERRUPT_STACK_HIGH  \
170          PER_CPU_INTERRUPT_STACK_LOW + (1 * __RTEMS_SIZEOF_VOID_P__)
171  #define PER_CPU_END_STACK             \
172          PER_CPU_INTERRUPT_STACK_HIGH + (1 * __RTEMS_SIZEOF_VOID_P__)
173#else
174  #define PER_CPU_END_STACK             PER_CPU_END_SMP
175#endif
176
177/*
178 *  These are the offsets of the required elements in the per CPU table.
179 */
180#define PER_CPU_ISR_NEST_LEVEL \
181          PER_CPU_END_STACK + 0
182#define PER_CPU_EXECUTING \
183          PER_CPU_END_STACK + (1 * __RTEMS_SIZEOF_VOID_P__)
184#define PER_CPU_HEIR \
185          PER_CPU_END_STACK + (2 * __RTEMS_SIZEOF_VOID_P__)
186#define PER_CPU_IDLE \
187          PER_CPU_END_STACK + (3 * __RTEMS_SIZEOF_VOID_P__)
188#define PER_CPU_DISPATCH_NEEDED \
189          PER_CPU_END_STACK + (4 * __RTEMS_SIZEOF_VOID_P__)
190
191#define ISR_NEST_LEVEL \
192         (SYM(_Per_CPU_Information) + PER_CPU_ISR_NEST_LEVEL)
193#define DISPATCH_NEEDED \
194         (SYM(_Per_CPU_Information) + PER_CPU_DISPATCH_NEEDED)
195
196/*
197 * Do not define these offsets if they are not in the table.
198 */
199#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
200    (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
201  #define INTERRUPT_STACK_LOW \
202      (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_LOW)
203  #define INTERRUPT_STACK_HIGH \
204      (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_HIGH)
205#endif
206
207#endif
208
209#ifndef ASM
210
211/**
212 *  @brief Set of Per CPU Core Information
213 *
214 *  This is an array of per CPU core information.
215 */
216extern Per_CPU_Control _Per_CPU_Information[];
217
218#if defined(RTEMS_SMP)
219/**
220 *  @brief Set of Pointers to Per CPU Core Information
221 *
222 *  This is an array of pointers to each CPU's per CPU data structure.
223 *  It should be simpler to retrieve this pointer in assembly language
224 *  that to calculate the array offset.
225 */
226extern Per_CPU_Control *_Per_CPU_Information_p[];
227
228/**
229 *  @brief Initialize SMP Handler
230 *
231 *  This method initialize the SMP Handler.
232 */
233void _SMP_Handler_initialize(void);
234
235/**
236 *  @brief Allocate and Initialize Per CPU Structures
237 *
238 *  This method allocates and initialize the per CPU structure.
239 */
240void _Per_CPU_Initialize(void);
241
242#endif
243
244/*
245 * On a non SMP system, the bsp_smp_processor_id is defined to 0.
246 * Thus when built for non-SMP, there should be no performance penalty.
247 */
248#define _Thread_Heir \
249  _Per_CPU_Information[bsp_smp_processor_id()].heir
250#define _Thread_Executing \
251  _Per_CPU_Information[bsp_smp_processor_id()].executing
252#define _Thread_Idle \
253  _Per_CPU_Information[bsp_smp_processor_id()].idle
254#define _ISR_Nest_level \
255  _Per_CPU_Information[bsp_smp_processor_id()].isr_nest_level
256#define _CPU_Interrupt_stack_low \
257  _Per_CPU_Information[bsp_smp_processor_id()].interrupt_stack_low
258#define _CPU_Interrupt_stack_high \
259  _Per_CPU_Information[bsp_smp_processor_id()].interrupt_stack_high
260#define _Thread_Dispatch_necessary \
261  _Per_CPU_Information[bsp_smp_processor_id()].dispatch_necessary
262#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
263  #define _Thread_Time_of_last_context_switch \
264    _Per_CPU_Information[bsp_smp_processor_id()].time_of_last_context_switch
265#endif
266
267
268#endif  /* ASM */
269
270#ifdef __cplusplus
271}
272#endif
273
274/**@}*/
275
276#endif
277/* end of include file */
Note: See TracBrowser for help on using the repository browser.