summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/percpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/include/rtems/score/percpu.h')
-rw-r--r--cpukit/score/include/rtems/score/percpu.h257
1 files changed, 257 insertions, 0 deletions
diff --git a/cpukit/score/include/rtems/score/percpu.h b/cpukit/score/include/rtems/score/percpu.h
new file mode 100644
index 0000000000..0c48b50570
--- /dev/null
+++ b/cpukit/score/include/rtems/score/percpu.h
@@ -0,0 +1,257 @@
+/**
+ * @file rtems/score/percpu.h
+ *
+ * This include file defines the per CPU information required
+ * by RTEMS.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _RTEMS_PERCPU_H
+#define _RTEMS_PERCPU_H
+
+#include <rtems/score/cpu.h>
+
+#ifdef ASM
+ #include <rtems/asm.h>
+#else
+ #if defined(RTEMS_SMP)
+ #include <rtems/score/smplock.h>
+ #endif
+ #include <rtems/bspsmp.h>
+#endif
+
+/**
+ * @defgroup PerCPU RTEMS Per CPU Information
+ *
+ * This defines the per CPU state information required by RTEMS
+ * and the BSP. In an SMP configuration, there will be multiple
+ * instances of this data structure -- one per CPU -- and the
+ * current CPU number will be used as the index.
+ */
+
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ASM
+#ifndef __THREAD_CONTROL_DEFINED__
+#define __THREAD_CONTROL_DEFINED__
+typedef struct Thread_Control_struct Thread_Control;
+#endif
+
+#if (CPU_ALLOCATE_INTERRUPT_STACK == FALSE) && defined(RTEMS_SMP)
+ #error "RTEMS must allocate per CPU interrupt stack for SMP"
+#endif
+
+typedef enum {
+
+ /**
+ * This defines the constant used to indicate that the cpu code is in
+ * its initial powered up start.
+ */
+ RTEMS_BSP_SMP_CPU_INITIAL_STATE = 1,
+
+ /**
+ * This defines the constant used to indicate that the cpu code has
+ * completed basic initialization and awaits further commands.
+ */
+ RTEMS_BSP_SMP_CPU_INITIALIZED = 2,
+
+ /**
+ * This defines the constant used to indicate that the cpu code has
+ * shut itself down.
+ */
+ RTEMS_BSP_SMP_CPU_SHUTDOWN = 3
+} bsp_smp_cpu_state;
+
+/**
+ * @brief Per CPU Core Structure
+ *
+ * This structure is used to hold per core state information.
+ */
+typedef struct {
+ #if defined(RTEMS_SMP)
+ /** This element is used to lock this structure */
+ SMP_lock_Control lock;
+
+ /** This indicates that the CPU is online. */
+ uint32_t state;
+
+ /**
+ * This is the request for the interrupt.
+ *
+ * @note This may become a chain protected by atomic instructions.
+ */
+ uint32_t message;
+
+ #endif
+
+#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
+ (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
+ /**
+ * This contains a pointer to the lower range of the interrupt stack for
+ * this CPU. This is the address allocated and freed.
+ */
+ void *interrupt_stack_low;
+
+ /**
+ * This contains a pointer to the interrupt stack pointer for this CPU.
+ * It will be loaded at the beginning on an ISR.
+ */
+ void *interrupt_stack_high;
+#endif
+
+ /**
+ * This contains the current interrupt nesting level on this
+ * CPU.
+ */
+ uint32_t isr_nest_level;
+
+ /** This is the thread executing on this CPU. */
+ Thread_Control *executing;
+
+ /** This is the heir thread for this this CPU. */
+ Thread_Control *heir;
+
+ /** This is the idle thread for this CPU. */
+ Thread_Control *idle;
+
+ /** This is set to true when this CPU needs to run the dispatcher. */
+ volatile bool dispatch_necessary;
+
+} Per_CPU_Control;
+#endif
+
+#ifdef ASM
+#if defined(RTEMS_SMP)
+ #define PER_CPU_LOCK 0
+ #define PER_CPU_STATE (1 * __RTEMS_SIZEOF_VOID_P__)
+ #define PER_CPU_MESSAGE (2 * __RTEMS_SIZEOF_VOID_P__)
+ #define PER_CPU_END_SMP (3 * __RTEMS_SIZEOF_VOID_P__)
+#else
+ #define PER_CPU_END_SMP 0
+#endif
+
+#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
+ (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
+ /*
+ * If this CPU target lets RTEMS allocates the interrupt stack, then
+ * we need to have places in the per cpu table to hold them.
+ */
+ #define PER_CPU_INTERRUPT_STACK_LOW PER_CPU_END_SMP
+ #define PER_CPU_INTERRUPT_STACK_HIGH \
+ PER_CPU_INTERRUPT_STACK_LOW + (1 * __RTEMS_SIZEOF_VOID_P__)
+ #define PER_CPU_END_STACK \
+ PER_CPU_INTERRUPT_STACK_HIGH + (1 * __RTEMS_SIZEOF_VOID_P__)
+#else
+ #define PER_CPU_END_STACK PER_CPU_END_SMP
+#endif
+
+/*
+ * These are the offsets of the required elements in the per CPU table.
+ */
+#define PER_CPU_ISR_NEST_LEVEL \
+ PER_CPU_END_STACK + 0
+#define PER_CPU_EXECUTING \
+ PER_CPU_END_STACK + (1 * __RTEMS_SIZEOF_VOID_P__)
+#define PER_CPU_HEIR \
+ PER_CPU_END_STACK + (2 * __RTEMS_SIZEOF_VOID_P__)
+#define PER_CPU_IDLE \
+ PER_CPU_END_STACK + (3 * __RTEMS_SIZEOF_VOID_P__)
+#define PER_CPU_DISPATCH_NEEDED \
+ PER_CPU_END_STACK + (4 * __RTEMS_SIZEOF_VOID_P__)
+
+#define ISR_NEST_LEVEL \
+ (SYM(_Per_CPU_Information) + PER_CPU_ISR_NEST_LEVEL)
+#define DISPATCH_NEEDED \
+ (SYM(_Per_CPU_Information) + PER_CPU_DISPATCH_NEEDED)
+
+/*
+ * Do not define these offsets if they are not in the table.
+ */
+#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
+ (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
+ #define INTERRUPT_STACK_LOW \
+ (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_LOW)
+ #define INTERRUPT_STACK_HIGH \
+ (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_HIGH)
+#endif
+
+#endif
+
+#ifndef ASM
+
+/**
+ * @brief Set of Per CPU Core Information
+ *
+ * This is an array of per CPU core information.
+ */
+extern Per_CPU_Control _Per_CPU_Information[];
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief Set of Pointers to Per CPU Core Information
+ *
+ * This is an array of pointers to each CPU's per CPU data structure.
+ * It should be simpler to retrieve this pointer in assembly language
+ * that to calculate the array offset.
+ */
+extern Per_CPU_Control *_Per_CPU_Information_p[];
+
+/**
+ * @brief Initialize SMP Handler
+ *
+ * This method initialize the SMP Handler.
+ */
+void _SMP_Handler_initialize(void);
+
+/**
+ * @brief Allocate and Initialize Per CPU Structures
+ *
+ * This method allocates and initialize the per CPU structure.
+ */
+void _Per_CPU_Initialize(void);
+
+#endif
+
+/*
+ * On a non SMP system, the bsp_smp_processor_id is defined to 0.
+ * Thus when built for non-SMP, there should be no performance penalty.
+ */
+#define _Thread_Heir \
+ _Per_CPU_Information[bsp_smp_processor_id()].heir
+#define _Thread_Executing \
+ _Per_CPU_Information[bsp_smp_processor_id()].executing
+#define _Thread_Idle \
+ _Per_CPU_Information[bsp_smp_processor_id()].idle
+#define _ISR_Nest_level \
+ _Per_CPU_Information[bsp_smp_processor_id()].isr_nest_level
+#define _CPU_Interrupt_stack_low \
+ _Per_CPU_Information[bsp_smp_processor_id()].interrupt_stack_low
+#define _CPU_Interrupt_stack_high \
+ _Per_CPU_Information[bsp_smp_processor_id()].interrupt_stack_high
+#define _Thread_Dispatch_necessary \
+ _Per_CPU_Information[bsp_smp_processor_id()].dispatch_necessary
+
+#endif /* ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */