source: rtems/cpukit/score/include/rtems/score/percpu.h @ 9e735966

4.115
Last change on this file since 9e735966 was 9e735966, checked in by Joel Sherrill <joel.sherrill@…>, on 10/02/12 at 18:24:20

score/percpu.h: _Thread_Time_of_last_context_switch always available

This field is used whether ticks are used for statistics or not.

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