[PATCH 1/2] score: Add and use _CPU_SMP_Get_processor_count()

Sebastian Huber sebastian.huber at embedded-brains.de
Thu Apr 10 14:47:03 UTC 2014


This makes most _CPU_SMP_Initialize() a bit simpler since we can
calulate the minimum value of the count of processors requested by the
application configuration and the count of physically or virtually
available processors in the high-level code.
---
 c/src/lib/libbsp/arm/shared/arm-a9mpcore-smp.c |   30 ++++++++++--------
 c/src/lib/libbsp/i386/shared/smp/smp-imps.c    |   17 ++++++++++-
 c/src/lib/libbsp/powerpc/qoriq/startup/smp.c   |   29 +++++++++--------
 c/src/lib/libbsp/shared/smp/smp_stub.c         |    7 +++-
 c/src/lib/libbsp/sparc/leon3/smp/smp_leon3.c   |   39 +++++++----------------
 cpukit/score/cpu/arm/rtems/score/cpu.h         |    4 ++-
 cpukit/score/cpu/i386/rtems/score/cpu.h        |    4 ++-
 cpukit/score/cpu/no_cpu/rtems/score/cpu.h      |   19 ++++++++---
 cpukit/score/cpu/powerpc/rtems/score/cpu.h     |    4 ++-
 cpukit/score/cpu/sparc/rtems/score/cpu.h       |    4 ++-
 cpukit/score/src/smp.c                         |   16 +++++----
 11 files changed, 99 insertions(+), 74 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 17d6498..c9c9936 100644
--- a/c/src/lib/libbsp/arm/shared/arm-a9mpcore-smp.c
+++ b/c/src/lib/libbsp/arm/shared/arm-a9mpcore-smp.c
@@ -25,23 +25,25 @@ static void bsp_inter_processor_interrupt(void *arg)
   _SMP_Inter_processor_interrupt_handler();
 }
 
-uint32_t _CPU_SMP_Initialize(uint32_t configured_cpu_count)
+void _CPU_SMP_Initialize(uint32_t cpu_count)
 {
-  rtems_status_code sc;
-  uint32_t max_cpu_count = arm_gic_irq_processor_count();
-  uint32_t used_cpu_count = configured_cpu_count < max_cpu_count ?
-    configured_cpu_count : max_cpu_count;
+  if (cpu_count > 0) {
+    rtems_status_code sc;
 
-  sc = rtems_interrupt_handler_install(
-    ARM_GIC_IRQ_SGI_0,
-    "IPI",
-    RTEMS_INTERRUPT_UNIQUE,
-    bsp_inter_processor_interrupt,
-    NULL
-  );
-  assert(sc == RTEMS_SUCCESSFUL);
+    sc = rtems_interrupt_handler_install(
+      ARM_GIC_IRQ_SGI_0,
+      "IPI",
+      RTEMS_INTERRUPT_UNIQUE,
+      bsp_inter_processor_interrupt,
+      NULL
+    );
+    assert(sc == RTEMS_SUCCESSFUL);
+  }
+}
 
-  return used_cpu_count;
+uint32_t _CPU_SMP_Get_processor_count( void )
+{
+  return arm_gic_irq_processor_count();
 }
 
 void _CPU_SMP_Send_interrupt( uint32_t 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 1e5faeb..2882953 100644
--- a/c/src/lib/libbsp/i386/shared/smp/smp-imps.c
+++ b/c/src/lib/libbsp/i386/shared/smp/smp-imps.c
@@ -684,6 +684,8 @@ imps_force(int ncpus)
 static int
 imps_probe(void)
 {
+  static bool probe_done;
+
   /*
    *  Determine possible address of the EBDA
    */
@@ -701,6 +703,10 @@ 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;
@@ -723,6 +729,8 @@ 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;
   }
 
@@ -786,7 +794,7 @@ static void secondary_cpu_initialize(void)
   _SMP_Start_multitasking_on_secondary_processor();
 }
 
-uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count )
+void _CPU_SMP_Initialize( uint32_t cpu_count )
 {
   int cores;
   /* XXX need to deal with finding too many cores */
@@ -798,6 +806,13 @@ uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count )
   return cores;
 }
 
+uint32_t _CPU_SMP_Get_processor_count( void )
+{
+  imps_probe();
+
+  return imps_num_cpus;
+}
+
 void _CPU_SMP_Send_interrupt( uint32_t target_processor_index )
 {
   send_ipi( target_processor_index, 0x30 );
diff --git a/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c b/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c
index 2ce0ba7..205e84d 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c
+++ b/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c
@@ -141,26 +141,27 @@ static void bsp_inter_processor_interrupt(void *arg)
   _SMP_Inter_processor_interrupt_handler();
 }
 
-uint32_t _CPU_SMP_Initialize(uint32_t configured_cpu_count)
+void _CPU_SMP_Initialize(uint32_t cpu_count)
 {
-  rtems_status_code sc;
-  uint32_t cores = configured_cpu_count < CORE_COUNT ?
-    configured_cpu_count : CORE_COUNT;
+  if (cpu_count > 1) {
+    rtems_status_code sc;
 
-  sc = rtems_interrupt_handler_install(
-    QORIQ_IRQ_IPI_0,
-    "IPI",
-    RTEMS_INTERRUPT_UNIQUE,
-    bsp_inter_processor_interrupt,
-    NULL
-  );
-  assert(sc == RTEMS_SUCCESSFUL);
+    sc = rtems_interrupt_handler_install(
+      QORIQ_IRQ_IPI_0,
+      "IPI",
+      RTEMS_INTERRUPT_UNIQUE,
+      bsp_inter_processor_interrupt,
+      NULL
+    );
+    assert(sc == RTEMS_SUCCESSFUL);
 
-  if (cores > 1) {
     release_core_1();
   }
+}
 
-  return cores;
+uint32_t _CPU_SMP_Get_processor_count(void)
+{
+  return CORE_COUNT;
 }
 
 void _CPU_SMP_Send_interrupt(uint32_t target_processor_index)
diff --git a/c/src/lib/libbsp/shared/smp/smp_stub.c b/c/src/lib/libbsp/shared/smp/smp_stub.c
index 8165363..fa46076 100644
--- a/c/src/lib/libbsp/shared/smp/smp_stub.c
+++ b/c/src/lib/libbsp/shared/smp/smp_stub.c
@@ -11,9 +11,12 @@
 
 #include <rtems/score/cpu.h>
 
-uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count )
+void _CPU_SMP_Initialize( uint32_t cpu_count )
+{
+}
+
+uint32_t _CPU_SMP_Get_processor_count( void )
 {
-  /* return the number of CPUs */
   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 2470e76..bfc801a 100644
--- a/c/src/lib/libbsp/sparc/leon3/smp/smp_leon3.c
+++ b/c/src/lib/libbsp/sparc/leon3/smp/smp_leon3.c
@@ -26,53 +26,38 @@ static rtems_isr bsp_inter_processor_interrupt(
   _SMP_Inter_processor_interrupt_handler();
 }
 
-void leon3_secondary_cpu_initialize(uint32_t cpu)
+void leon3_secondary_cpu_initialize(uint32_t cpu_index)
 {
   leon3_set_cache_control_register(0x80000F);
   /* Unmask IPI interrupts at Interrupt controller for this CPU */
-  LEON3_IrqCtrl_Regs->mask[cpu] |= 1 << LEON3_MP_IRQ;
+  LEON3_IrqCtrl_Regs->mask[cpu_index] |= 1U << LEON3_MP_IRQ;
 
   _SMP_Start_multitasking_on_secondary_processor();
 }
 
-uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count )
+void _CPU_SMP_Initialize( uint32_t cpu_count )
 {
-  uint32_t max_cpu_count;
-  uint32_t used_cpu_count;
-  uint32_t cpu;
+  uint32_t cpu_index;
 
   leon3_set_cache_control_register(0x80000F);
 
-  max_cpu_count = leon3_get_cpu_count(LEON3_IrqCtrl_Regs);
-  used_cpu_count = configured_cpu_count < max_cpu_count ?
-    configured_cpu_count : max_cpu_count;
-
-  #if defined(RTEMS_DEBUG)
-    printk( "Found %d CPUs\n", max_cpu_count );
-
-    if ( max_cpu_count > configured_cpu_count ) {
-      printk(
-        "%d CPUs IS MORE THAN CONFIGURED -- ONLY USING %d\n",
-        max_cpu_count,
-        configured_cpu_count
-      );
-    }
-  #endif
-
-  if ( used_cpu_count > 1 ) {
+  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 = 1 ; cpu < used_cpu_count ; ++cpu ) {
+  for ( cpu_index = 1 ; cpu_index < cpu_count ; ++cpu_index ) {
     #if defined(RTEMS_DEBUG)
-      printk( "Waking CPU %d\n", cpu );
+      printk( "Waking CPU %d\n", cpu_index );
     #endif
 
-    LEON3_IrqCtrl_Regs->mpstat = 1 << cpu;
+    LEON3_IrqCtrl_Regs->mpstat = 1U << cpu_index;
   }
+}
 
-  return used_cpu_count;
+uint32_t _CPU_SMP_Get_processor_count( void )
+{
+  return leon3_get_cpu_count(LEON3_IrqCtrl_Regs);
 }
 
 void _CPU_SMP_Send_interrupt(uint32_t target_processor_index)
diff --git a/cpukit/score/cpu/arm/rtems/score/cpu.h b/cpukit/score/cpu/arm/rtems/score/cpu.h
index dc2bbdd..acf82c6 100644
--- a/cpukit/score/cpu/arm/rtems/score/cpu.h
+++ b/cpukit/score/cpu/arm/rtems/score/cpu.h
@@ -467,7 +467,9 @@ 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 );
+  void _CPU_SMP_Initialize( uint32_t cpu_count );
+
+  uint32_t _CPU_SMP_Get_processor_count( void );
 
   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 296ad8b..92afa59 100644
--- a/cpukit/score/cpu/i386/rtems/score/cpu.h
+++ b/cpukit/score/cpu/i386/rtems/score/cpu.h
@@ -462,7 +462,9 @@ 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 );
+  void _CPU_SMP_Initialize( uint32_t cpu_count );
+
+  uint32_t _CPU_SMP_Get_processor_count( void );
 
   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 c864164..7d43185 100644
--- a/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
+++ b/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
@@ -1473,13 +1473,22 @@ CPU_Counter_ticks _CPU_Counter_difference(
    *
    * The CPU port should start secondary processors now.
    *
-   * @param[in] configured_cpu_count The count of processors requested by the
-   * application configuration.
+   * @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 );
+
+  /**
+   * @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.
    *
-   * @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.
+   * @return The count of physically or virtually available processors.
    */
-  uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count );
+  uint32_t _CPU_SMP_Get_processor_count( void );
 
   /**
    * @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 a7cad2e..ffc5c18 100644
--- a/cpukit/score/cpu/powerpc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
@@ -1034,7 +1034,9 @@ 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 );
+  void _CPU_SMP_Initialize( uint32_t cpu_count );
+
+  uint32_t _CPU_SMP_Get_processor_count( void );
 
   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 ea092af..cbc9cf9 100644
--- a/cpukit/score/cpu/sparc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h
@@ -1161,7 +1161,9 @@ void _CPU_Context_restore(
 ) RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
 
 #if defined(RTEMS_SMP)
-  uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count );
+  void _CPU_SMP_Initialize( uint32_t cpu_count );
+
+  uint32_t _CPU_SMP_Get_processor_count( void );
 
   #if defined(__leon__)
     static inline uint32_t _CPU_SMP_Get_current_processor( void )
diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c
index bfb09dd..d635a19 100644
--- a/cpukit/score/src/smp.c
+++ b/cpukit/score/src/smp.c
@@ -26,11 +26,12 @@
 
 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_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 +39,10 @@ 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_Get_processor_count();
+  cpu_count = cpu_count < cpu_max ? cpu_count : cpu_max;
+  _SMP_Processor_count = cpu_count;
+  _CPU_SMP_Initialize( cpu_count );
 }
 
 void _SMP_Request_start_multitasking( void )
-- 
1.7.7




More information about the devel mailing list