source: rtems/cpukit/score/include/rtems/score/percpu.h @ 3f764a8

4.115
Last change on this file since 3f764a8 was 3f764a8, checked in by Sebastian Huber <sebastian.huber@…>, on 09/14/11 at 14:16:56

2011-09-14 Sebastian Huber <sebastian.huber@…>

PR 1898/cpukit

  • score/include/rtems/score/percpu.h: Use CPU_STRUCTURE_ALIGNMENT for _Per_CPU_Information.
  • Property mode set to 100644
File size: 7.4 KB
RevLine 
[11e8bc5]1/**
2 *  @file  rtems/score/percpu.h
3 *
4 *  This include file defines the per CPU information required
5 *  by RTEMS.
6 */
7
8/*
[06dcaf0]9 *  COPYRIGHT (c) 1989-2011.
[11e8bc5]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 *
[dacdda30]16 *  $Id$
[11e8bc5]17 */
18
19#ifndef _RTEMS_PERCPU_H
20#define _RTEMS_PERCPU_H
21
[9f9a82b]22#include <rtems/score/cpu.h>
23
[11e8bc5]24#ifdef ASM
25  #include <rtems/asm.h>
[06dcaf0]26#else
[df00777]27  #include <rtems/score/isrlevel.h>
[0a101d57]28  #include <rtems/score/timestamp.h>
[06dcaf0]29  #if defined(RTEMS_SMP)
30    #include <rtems/score/smplock.h>
31  #endif
[42bb344e]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   */
[06dcaf0]37  #include <rtems/bspsmp.h>
[11e8bc5]38#endif
39
40/**
41 *  @defgroup PerCPU RTEMS Per CPU Information
42 *
[d8cd045c]43 *  @ingroup Score
44 *
[11e8bc5]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
[0a101d57]58#include <rtems/score/timestamp.h>
59
[06dcaf0]60#ifndef __THREAD_CONTROL_DEFINED__
61#define __THREAD_CONTROL_DEFINED__
[11e8bc5]62typedef struct Thread_Control_struct Thread_Control;
[06dcaf0]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 {
[dacdda30]70
[06dcaf0]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
[d4dc7c8]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
[06dcaf0]89  /**
90   *  This defines the constant used to indicate that the cpu code has
91   *  shut itself down.
92   */
[d4dc7c8]93  RTEMS_BSP_SMP_CPU_SHUTDOWN = 4
[06dcaf0]94} bsp_smp_cpu_state;
[11e8bc5]95
96/**
97 *  @brief Per CPU Core Structure
98 *
99 *  This structure is used to hold per core state information.
100 */
101typedef struct {
[06dcaf0]102  #if defined(RTEMS_SMP)
103    /** This element is used to lock this structure */
[dacdda30]104    SMP_lock_spinlock_simple_Control  lock;
[06dcaf0]105
106    /** This indicates that the CPU is online. */
[dacdda30]107    uint32_t                          state;
[06dcaf0]108
109    /**
110     *  This is the request for the interrupt.
[dacdda30]111     *
[06dcaf0]112     *  @note This may become a chain protected by atomic instructions.
113     */
[dacdda30]114    uint32_t                          message;
[06dcaf0]115  #endif
116
[11e8bc5]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. */
[4b1d261]148  volatile bool dispatch_necessary;
[11e8bc5]149
[0a101d57]150  /** This is the time of the last context switch on this CPU. */
151  Timestamp_Control time_of_last_context_switch;
[11e8bc5]152} Per_CPU_Control;
153#endif
154
155#ifdef ASM
[06dcaf0]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
[11e8bc5]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   */
[06dcaf0]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__)
[11e8bc5]176#else
[06dcaf0]177  #define PER_CPU_END_STACK             PER_CPU_END_SMP
[11e8bc5]178#endif
179
180/*
181 *  These are the offsets of the required elements in the per CPU table.
182 */
[263ab4b]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
[11e8bc5]194#define ISR_NEST_LEVEL \
[263ab4b]195         (SYM(_Per_CPU_Information) + PER_CPU_ISR_NEST_LEVEL)
[11e8bc5]196#define DISPATCH_NEEDED \
[263ab4b]197         (SYM(_Per_CPU_Information) + PER_CPU_DISPATCH_NEEDED)
[11e8bc5]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 */
[3f764a8]219extern Per_CPU_Control _Per_CPU_Information[] CPU_STRUCTURE_ALIGNMENT;
[06dcaf0]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
[11e8bc5]246
247/*
[06dcaf0]248 * On a non SMP system, the bsp_smp_processor_id is defined to 0.
[11e8bc5]249 * Thus when built for non-SMP, there should be no performance penalty.
250 */
[06dcaf0]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
[0a101d57]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
[11e8bc5]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.