[PATCH 2/2] score: Add and use _CPU_SMP_Start_processor()
Sebastian Huber
sebastian.huber at embedded-brains.de
Thu Apr 10 14:47:04 UTC 2014
Add and use _CPU_SMP_Finalize_initialization(). Move the processor
start loop to the high-level _SMP_Handler_initialize() function. This
can simplify the CPU port. The CPU port has the ability to signal a
processor start failure. With the support for clustered/partitioned
scheduling the presence of particular processors can be configured to be
optional or mandatory. There will be a fatal error only in case
mandatory processors are not present.
---
c/src/lib/libbsp/arm/shared/arm-a9mpcore-smp.c | 18 +++++++++-
c/src/lib/libbsp/i386/shared/smp/smp-imps.c | 28 +++++++--------
c/src/lib/libbsp/powerpc/qoriq/startup/smp.c | 20 ++++++++++-
c/src/lib/libbsp/shared/smp/smp_stub.c | 11 +++++-
c/src/lib/libbsp/sparc/leon3/smp/smp_leon3.c | 22 +++++++-----
cpukit/score/cpu/arm/rtems/score/cpu.h | 6 +++-
cpukit/score/cpu/i386/rtems/score/cpu.h | 6 +++-
cpukit/score/cpu/no_cpu/rtems/score/cpu.h | 43 ++++++++++++++++++++----
cpukit/score/cpu/powerpc/rtems/score/cpu.h | 6 +++-
cpukit/score/cpu/sparc/rtems/score/cpu.h | 6 +++-
cpukit/score/include/rtems/score/smpimpl.h | 3 +-
cpukit/score/src/smp.c | 23 ++++++++++++-
12 files changed, 151 insertions(+), 41 deletions(-)
diff --git a/c/src/lib/libbsp/arm/shared/arm-a9mpcore-smp.c b/c/src/lib/libbsp/arm/shared/arm-a9mpcore-smp.c
index c9c9936..321e89e 100644
--- a/c/src/lib/libbsp/arm/shared/arm-a9mpcore-smp.c
+++ b/c/src/lib/libbsp/arm/shared/arm-a9mpcore-smp.c
@@ -25,7 +25,12 @@ static void bsp_inter_processor_interrupt(void *arg)
_SMP_Inter_processor_interrupt_handler();
}
-void _CPU_SMP_Initialize(uint32_t cpu_count)
+void _CPU_SMP_Initialize(void)
+{
+ /* Nothing to do */
+}
+
+void _CPU_SMP_Finalize_initialization(uint32_t cpu_count)
{
if (cpu_count > 0) {
rtems_status_code sc;
@@ -41,6 +46,15 @@ void _CPU_SMP_Initialize(uint32_t cpu_count)
}
}
+bool _CPU_SMP_Start_processor(uint32_t cpu_index)
+{
+ (void) cpu_index;
+
+ /* Nothing to do */
+
+ return true;
+}
+
uint32_t _CPU_SMP_Get_processor_count( void )
{
return arm_gic_irq_processor_count();
@@ -48,7 +62,7 @@ uint32_t _CPU_SMP_Get_processor_count( void )
void _CPU_SMP_Send_interrupt( uint32_t target_processor_index )
{
- rtems_status_code sc = arm_gic_irq_generate_software_irq(
+ arm_gic_irq_generate_software_irq(
ARM_GIC_IRQ_SGI_0,
ARM_GIC_IRQ_SOFTWARE_IRQ_TO_ALL_IN_LIST,
(uint8_t) (1U << target_processor_index)
diff --git a/c/src/lib/libbsp/i386/shared/smp/smp-imps.c b/c/src/lib/libbsp/i386/shared/smp/smp-imps.c
index 2882953..296f0e7 100644
--- a/c/src/lib/libbsp/i386/shared/smp/smp-imps.c
+++ b/c/src/lib/libbsp/i386/shared/smp/smp-imps.c
@@ -684,8 +684,6 @@ imps_force(int ncpus)
static int
imps_probe(void)
{
- static bool probe_done;
-
/*
* Determine possible address of the EBDA
*/
@@ -703,10 +701,6 @@ imps_probe(void)
unsigned mem_lower = ((CMOS_READ_BYTE(CMOS_BASE_MEMORY+1) << 8)
| CMOS_READ_BYTE(CMOS_BASE_MEMORY)) << 10;
- if (probe_done) {
- return imps_num_cpus;
- }
-
#ifdef IMPS_DEBUG
imps_enabled = 0;
imps_num_cpus = 1;
@@ -729,8 +723,6 @@ imps_probe(void)
if (((ebda_addr && imps_scan(ebda_addr, 1024))
|| (!ebda_addr && imps_scan(mem_lower - 1024, 1024))
|| imps_scan(0xF0000, 0x10000)) && imps_enabled) {
- probe_done = true;
-
return imps_num_cpus;
}
@@ -794,22 +786,28 @@ static void secondary_cpu_initialize(void)
_SMP_Start_multitasking_on_secondary_processor();
}
-void _CPU_SMP_Initialize( uint32_t cpu_count )
+void _CPU_SMP_Initialize( void )
{
- int cores;
/* XXX need to deal with finding too many cores */
- cores = imps_probe();
+ imps_probe();
+}
- if ( cores > 1 )
+void _CPU_SMP_Finalize_initialization( uint32_t cpu_count )
+{
+ if ( cpu_count > 1 )
ipi_install_irq();
- return cores;
}
-uint32_t _CPU_SMP_Get_processor_count( void )
+bool _CPU_SMP_Start_processor( uint32_t cpu_index )
{
- imps_probe();
+ (void) cpu_index;
+ return true;
+}
+
+uint32_t _CPU_SMP_Get_processor_count( void )
+{
return imps_num_cpus;
}
diff --git a/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c b/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c
index 205e84d..ca01663 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c
+++ b/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c
@@ -141,7 +141,12 @@ static void bsp_inter_processor_interrupt(void *arg)
_SMP_Inter_processor_interrupt_handler();
}
-void _CPU_SMP_Initialize(uint32_t cpu_count)
+void _CPU_SMP_Initialize(void)
+{
+ /* Nothing to do */
+}
+
+void _CPU_SMP_Finalize_initialization(uint32_t cpu_count)
{
if (cpu_count > 1) {
rtems_status_code sc;
@@ -154,9 +159,22 @@ void _CPU_SMP_Initialize(uint32_t cpu_count)
NULL
);
assert(sc == RTEMS_SUCCESSFUL);
+ }
+}
+bool _CPU_SMP_Start_processor(uint32_t cpu_index)
+{
+ bool ok;
+
+ if (cpu_index == 1) {
release_core_1();
+
+ ok = true;
+ } else {
+ ok = false;
}
+
+ return ok;
}
uint32_t _CPU_SMP_Get_processor_count(void)
diff --git a/c/src/lib/libbsp/shared/smp/smp_stub.c b/c/src/lib/libbsp/shared/smp/smp_stub.c
index fa46076..c398ac9 100644
--- a/c/src/lib/libbsp/shared/smp/smp_stub.c
+++ b/c/src/lib/libbsp/shared/smp/smp_stub.c
@@ -11,10 +11,19 @@
#include <rtems/score/cpu.h>
-void _CPU_SMP_Initialize( uint32_t cpu_count )
+void _CPU_SMP_Initialize( void )
{
}
+void _CPU_SMP_Finalize_initialization( uint32_t cpu_count )
+{
+}
+
+bool _CPU_SMP_Start_processor( uint32_t cpu_index )
+{
+ return cpu_index == 1;
+}
+
uint32_t _CPU_SMP_Get_processor_count( void )
{
return 1;
diff --git a/c/src/lib/libbsp/sparc/leon3/smp/smp_leon3.c b/c/src/lib/libbsp/sparc/leon3/smp/smp_leon3.c
index bfc801a..e1c1715 100644
--- a/c/src/lib/libbsp/sparc/leon3/smp/smp_leon3.c
+++ b/c/src/lib/libbsp/sparc/leon3/smp/smp_leon3.c
@@ -35,24 +35,28 @@ void leon3_secondary_cpu_initialize(uint32_t cpu_index)
_SMP_Start_multitasking_on_secondary_processor();
}
-void _CPU_SMP_Initialize( uint32_t cpu_count )
+void _CPU_SMP_Initialize( void )
{
- uint32_t cpu_index;
-
leon3_set_cache_control_register(0x80000F);
+}
+void _CPU_SMP_Finalize_initialization( uint32_t cpu_count )
+{
if ( cpu_count > 1 ) {
LEON_Unmask_interrupt(LEON3_MP_IRQ);
set_vector(bsp_inter_processor_interrupt, LEON_TRAP_TYPE(LEON3_MP_IRQ), 1);
}
+}
- for ( cpu_index = 1 ; cpu_index < cpu_count ; ++cpu_index ) {
- #if defined(RTEMS_DEBUG)
- printk( "Waking CPU %d\n", cpu_index );
- #endif
+bool _CPU_SMP_Start_processor( uint32_t cpu_index )
+{
+ #if defined(RTEMS_DEBUG)
+ printk( "Waking CPU %d\n", cpu_index );
+ #endif
- LEON3_IrqCtrl_Regs->mpstat = 1U << cpu_index;
- }
+ LEON3_IrqCtrl_Regs->mpstat = 1U << cpu_index;
+
+ return true;
}
uint32_t _CPU_SMP_Get_processor_count( void )
diff --git a/cpukit/score/cpu/arm/rtems/score/cpu.h b/cpukit/score/cpu/arm/rtems/score/cpu.h
index acf82c6..b770599 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
- void _CPU_SMP_Initialize( uint32_t cpu_count );
+ void _CPU_SMP_Initialize( void );
+
+ void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
+
+ bool _CPU_SMP_Start_processor( uint32_t cpu_index );
uint32_t _CPU_SMP_Get_processor_count( void );
diff --git a/cpukit/score/cpu/i386/rtems/score/cpu.h b/cpukit/score/cpu/i386/rtems/score/cpu.h
index 92afa59..b831038 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)
- void _CPU_SMP_Initialize( uint32_t cpu_count );
+ void _CPU_SMP_Initialize( void );
+
+ void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
+
+ bool _CPU_SMP_Start_processor( uint32_t cpu_index );
uint32_t _CPU_SMP_Get_processor_count( void );
diff --git a/cpukit/score/cpu/no_cpu/rtems/score/cpu.h b/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
index 7d43185..393d5ed 100644
--- a/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
+++ b/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
@@ -1467,24 +1467,53 @@ 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_Get_processor_count() or _CPU_SMP_Start_processor() is
+ * used.
+ */
+ void _CPU_SMP_Initialize( void );
+
+ /**
+ * @brief Performs final steps of CPU specific SMP initialization in the
+ * context of the boot processor.
*
- * The CPU port should start secondary processors now.
+ * This function is invoked on the boot processor during system
+ * initialization.
+ *
+ * This function will be called after all processors requested by the
+ * application have been started.
*
* @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.
*/
- void _CPU_SMP_Initialize( uint32_t cpu_count );
+ void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
+
+ /**
+ * @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 Returns the count of physically or virtually available processors.
*
- * This function is used during system initialization and is not performance
- * critical. Depending on the configuration the application may use less
- * processors.
+ * This function is invoked on the boot processor during system
+ * initialization. Depending on the configuration the application may use
+ * less processors.
+ *
+ * This function will be called after _CPU_SMP_Initialize().
*
* @return The count of physically or virtually available processors.
*/
diff --git a/cpukit/score/cpu/powerpc/rtems/score/cpu.h b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
index ffc5c18..35e3c36 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
- void _CPU_SMP_Initialize( uint32_t cpu_count );
+ void _CPU_SMP_Initialize( void );
+
+ void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
+
+ bool _CPU_SMP_Start_processor( uint32_t cpu_index );
uint32_t _CPU_SMP_Get_processor_count( void );
diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h
index cbc9cf9..cfb6132 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)
- void _CPU_SMP_Initialize( uint32_t cpu_count );
+ void _CPU_SMP_Initialize( void );
+
+ void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
+
+ bool _CPU_SMP_Start_processor( uint32_t cpu_index );
uint32_t _CPU_SMP_Get_processor_count( void );
diff --git a/cpukit/score/include/rtems/score/smpimpl.h b/cpukit/score/include/rtems/score/smpimpl.h
index c32d4a2..962c7f2 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_UNABLE_TO_START_PROCESSOR
} SMP_Fatal_code;
/**
diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c
index d635a19..107b121 100644
--- a/cpukit/score/src/smp.c
+++ b/cpukit/score/src/smp.c
@@ -27,6 +27,7 @@
void _SMP_Handler_initialize( void )
{
uint32_t cpu_max = rtems_configuration_get_maximum_processors();
+ uint32_t cpu_self;
uint32_t cpu_count;
uint32_t cpu_index;
@@ -39,10 +40,30 @@ void _SMP_Handler_initialize( void )
/*
* Discover and initialize the secondary cores in an SMP system.
*/
+
+ _CPU_SMP_Initialize();
+
cpu_count = _CPU_SMP_Get_processor_count();
cpu_count = cpu_count < cpu_max ? cpu_count : cpu_max;
_SMP_Processor_count = cpu_count;
- _CPU_SMP_Initialize( 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_UNABLE_TO_START_PROCESSOR
+ );
+ }
+ }
+ }
+
+ _CPU_SMP_Finalize_initialization( cpu_count );
}
void _SMP_Request_start_multitasking( void )
--
1.7.7
More information about the devel
mailing list