summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/score/cpu/arm/rtems/score/cpu.h6
-rw-r--r--cpukit/score/cpu/i386/rtems/score/cpu.h6
-rw-r--r--cpukit/score/cpu/no_cpu/rtems/score/cpu.h44
-rw-r--r--cpukit/score/cpu/powerpc/rtems/score/cpu.h6
-rw-r--r--cpukit/score/cpu/sparc/rtems/score/cpu.h6
-rw-r--r--cpukit/score/include/rtems/score/smpimpl.h3
-rw-r--r--cpukit/score/src/smp.c33
7 files changed, 85 insertions, 19 deletions
diff --git a/cpukit/score/cpu/arm/rtems/score/cpu.h b/cpukit/score/cpu/arm/rtems/score/cpu.h
index dc2bbddcaf..ccf8c9a834 100644
--- a/cpukit/score/cpu/arm/rtems/score/cpu.h
+++ b/cpukit/score/cpu/arm/rtems/score/cpu.h
@@ -467,7 +467,11 @@ void _CPU_Context_volatile_clobber( uintptr_t pattern );
void _CPU_Context_validate( uintptr_t pattern );
#ifdef RTEMS_SMP
- uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count );
+ uint32_t _CPU_SMP_Initialize( void );
+
+ bool _CPU_SMP_Start_processor( uint32_t cpu_index );
+
+ void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
static inline uint32_t _CPU_SMP_Get_current_processor( void )
{
diff --git a/cpukit/score/cpu/i386/rtems/score/cpu.h b/cpukit/score/cpu/i386/rtems/score/cpu.h
index 296ad8ba47..be22d9e217 100644
--- a/cpukit/score/cpu/i386/rtems/score/cpu.h
+++ b/cpukit/score/cpu/i386/rtems/score/cpu.h
@@ -462,7 +462,11 @@ uint32_t _CPU_ISR_Get_level( void );
_CPU_Context_restore( (_the_context) );
#if defined(RTEMS_SMP)
- uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count );
+ uint32_t _CPU_SMP_Initialize( void );
+
+ bool _CPU_SMP_Start_processor( uint32_t cpu_index );
+
+ void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
uint32_t _CPU_SMP_Get_current_processor( void );
diff --git a/cpukit/score/cpu/no_cpu/rtems/score/cpu.h b/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
index c864164667..5241b5ba5d 100644
--- a/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
+++ b/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
@@ -1467,19 +1467,47 @@ CPU_Counter_ticks _CPU_Counter_difference(
* @brief Performs CPU specific SMP initialization in the context of the boot
* processor.
*
- * This function is invoked on the boot processor by RTEMS during
+ * This function is invoked on the boot processor during system
* initialization. All interrupt stacks are allocated at this point in case
- * the CPU port allocates the interrupt stacks.
+ * the CPU port allocates the interrupt stacks. This function is called
+ * before _CPU_SMP_Start_processor() or _CPU_SMP_Finalize_initialization() is
+ * used.
*
- * The CPU port should start secondary processors now.
+ * @return The count of physically or virtually available processors.
+ * Depending on the configuration the application may use not all processors.
+ */
+ uint32_t _CPU_SMP_Initialize( void );
+
+ /**
+ * @brief Starts a processor specified by its index.
+ *
+ * This function is invoked on the boot processor during system
+ * initialization.
+ *
+ * This function will be called after _CPU_SMP_Initialize().
+ *
+ * @param[in] cpu_index The processor index.
+ *
+ * @retval true Successful operation.
+ * @retval false Unable to start this processor.
+ */
+ bool _CPU_SMP_Start_processor( uint32_t cpu_index );
+
+ /**
+ * @brief Performs final steps of CPU specific SMP initialization in the
+ * context of the boot processor.
+ *
+ * This function is invoked on the boot processor during system
+ * initialization.
*
- * @param[in] configured_cpu_count The count of processors requested by the
- * application configuration.
+ * This function will be called after all processors requested by the
+ * application have been started.
*
- * @return The count of processors available for the application in the system.
- * This value is less than or equal to the configured count of processors.
+ * @param[in] cpu_count The minimum value of the count of processors
+ * requested by the application configuration and the count of physically or
+ * virtually available processors.
*/
- uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count );
+ void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
/**
* @brief Returns the index of the current processor.
diff --git a/cpukit/score/cpu/powerpc/rtems/score/cpu.h b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
index a7cad2e402..3130b3535e 100644
--- a/cpukit/score/cpu/powerpc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
@@ -1034,7 +1034,11 @@ void _CPU_Context_volatile_clobber( uintptr_t pattern );
void _CPU_Context_validate( uintptr_t pattern );
#ifdef RTEMS_SMP
- uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count );
+ uint32_t _CPU_SMP_Initialize( void );
+
+ bool _CPU_SMP_Start_processor( uint32_t cpu_index );
+
+ void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
static inline uint32_t _CPU_SMP_Get_current_processor( void )
{
diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h
index e43b3bee5e..1b5dbcae73 100644
--- a/cpukit/score/cpu/sparc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h
@@ -1161,7 +1161,11 @@ void _CPU_Context_restore(
) RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
#if defined(RTEMS_SMP)
- uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count );
+ uint32_t _CPU_SMP_Initialize( void );
+
+ bool _CPU_SMP_Start_processor( uint32_t cpu_index );
+
+ void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
#if defined(__leon__)
static inline uint32_t _CPU_SMP_Get_current_processor( void )
diff --git a/cpukit/score/include/rtems/score/smpimpl.h b/cpukit/score/include/rtems/score/smpimpl.h
index c32d4a2001..3e808600d3 100644
--- a/cpukit/score/include/rtems/score/smpimpl.h
+++ b/cpukit/score/include/rtems/score/smpimpl.h
@@ -48,7 +48,8 @@ extern "C" {
*/
typedef enum {
SMP_FATAL_SHUTDOWN,
- SMP_FATAL_SHUTDOWN_EARLY
+ SMP_FATAL_SHUTDOWN_EARLY,
+ SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED
} SMP_Fatal_code;
/**
diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c
index bfb09dd783..08677d83c7 100644
--- a/cpukit/score/src/smp.c
+++ b/cpukit/score/src/smp.c
@@ -26,11 +26,13 @@
void _SMP_Handler_initialize( void )
{
- uint32_t max_cpus = rtems_configuration_get_maximum_processors();
- uint32_t cpu;
+ uint32_t cpu_max = rtems_configuration_get_maximum_processors();
+ uint32_t cpu_self;
+ uint32_t cpu_count;
+ uint32_t cpu_index;
- for ( cpu = 0 ; cpu < max_cpus; ++cpu ) {
- Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
+ for ( cpu_index = 0 ; cpu_index < cpu_max; ++cpu_index ) {
+ Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu_index );
_SMP_ticket_lock_Initialize( &per_cpu->Lock, "per-CPU" );
}
@@ -38,9 +40,28 @@ void _SMP_Handler_initialize( void )
/*
* Discover and initialize the secondary cores in an SMP system.
*/
- max_cpus = _CPU_SMP_Initialize( max_cpus );
- _SMP_Processor_count = max_cpus;
+ cpu_count = _CPU_SMP_Initialize();
+ cpu_count = cpu_count < cpu_max ? cpu_count : cpu_max;
+ _SMP_Processor_count = cpu_count;
+
+ cpu_self = _SMP_Get_current_processor();
+
+ for ( cpu_index = 0 ; cpu_index < cpu_count; ++cpu_index ) {
+ if ( cpu_index != cpu_self ) {
+ bool ok = _CPU_SMP_Start_processor( cpu_index );
+
+ if ( !ok ) {
+ _Terminate(
+ RTEMS_FATAL_SOURCE_SMP,
+ false,
+ SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED
+ );
+ }
+ }
+ }
+
+ _CPU_SMP_Finalize_initialization( cpu_count );
}
void _SMP_Request_start_multitasking( void )