diff options
Diffstat (limited to '')
-rw-r--r-- | c/src/lib/libbsp/arm/shared/arm-a9mpcore-smp.c | 41 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/shared/smp/smp-imps.c | 18 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/qoriq/startup/smp.c | 42 | ||||
-rw-r--r-- | c/src/lib/libbsp/shared/smp/smp_stub.c | 11 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon3/smp/smp_leon3.c | 50 | ||||
-rw-r--r-- | cpukit/score/cpu/arm/rtems/score/cpu.h | 6 | ||||
-rw-r--r-- | cpukit/score/cpu/i386/rtems/score/cpu.h | 6 | ||||
-rw-r--r-- | cpukit/score/cpu/no_cpu/rtems/score/cpu.h | 44 | ||||
-rw-r--r-- | cpukit/score/cpu/powerpc/rtems/score/cpu.h | 6 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/rtems/score/cpu.h | 6 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/smpimpl.h | 3 | ||||
-rw-r--r-- | cpukit/score/src/smp.c | 33 |
12 files changed, 179 insertions, 87 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 17d6498804..6f4af46343 100644 --- a/c/src/lib/libbsp/arm/shared/arm-a9mpcore-smp.c +++ b/c/src/lib/libbsp/arm/shared/arm-a9mpcore-smp.c @@ -25,28 +25,39 @@ static void bsp_inter_processor_interrupt(void *arg) _SMP_Inter_processor_interrupt_handler(); } -uint32_t _CPU_SMP_Initialize(uint32_t configured_cpu_count) +uint32_t _CPU_SMP_Initialize(void) { - 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; + return arm_gic_irq_processor_count(); +} - sc = rtems_interrupt_handler_install( - ARM_GIC_IRQ_SGI_0, - "IPI", - RTEMS_INTERRUPT_UNIQUE, - bsp_inter_processor_interrupt, - NULL - ); - assert(sc == RTEMS_SUCCESSFUL); +bool _CPU_SMP_Start_processor(uint32_t cpu_index) +{ + (void) cpu_index; + + /* Nothing to do */ + + return true; +} + +void _CPU_SMP_Finalize_initialization(uint32_t cpu_count) +{ + if (cpu_count > 0) { + rtems_status_code sc; - return used_cpu_count; + sc = rtems_interrupt_handler_install( + ARM_GIC_IRQ_SGI_0, + "IPI", + RTEMS_INTERRUPT_UNIQUE, + bsp_inter_processor_interrupt, + NULL + ); + assert(sc == RTEMS_SUCCESSFUL); + } } 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 1e5faeb644..19b23e2631 100644 --- a/c/src/lib/libbsp/i386/shared/smp/smp-imps.c +++ b/c/src/lib/libbsp/i386/shared/smp/smp-imps.c @@ -786,16 +786,24 @@ static void secondary_cpu_initialize(void) _SMP_Start_multitasking_on_secondary_processor(); } -uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count ) +uint32_t _CPU_SMP_Initialize( void ) { - int cores; /* XXX need to deal with finding too many cores */ - cores = imps_probe(); + return (uint32_t) imps_probe(); +} + +bool _CPU_SMP_Start_processor( uint32_t cpu_index ) +{ + (void) cpu_index; - if ( cores > 1 ) + return true; +} + +void _CPU_SMP_Finalize_initialization( uint32_t cpu_count ) +{ + if ( cpu_count > 1 ) ipi_install_irq(); - return cores; } void _CPU_SMP_Send_interrupt( uint32_t target_processor_index ) diff --git a/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c b/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c index 2ce0ba75ad..5b4c12a2db 100644 --- a/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c +++ b/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c @@ -141,26 +141,34 @@ static void bsp_inter_processor_interrupt(void *arg) _SMP_Inter_processor_interrupt_handler(); } -uint32_t _CPU_SMP_Initialize(uint32_t configured_cpu_count) +uint32_t _CPU_SMP_Initialize(void) { - rtems_status_code sc; - uint32_t cores = configured_cpu_count < CORE_COUNT ? - configured_cpu_count : CORE_COUNT; - - sc = rtems_interrupt_handler_install( - QORIQ_IRQ_IPI_0, - "IPI", - RTEMS_INTERRUPT_UNIQUE, - bsp_inter_processor_interrupt, - NULL - ); - assert(sc == RTEMS_SUCCESSFUL); + return CORE_COUNT; +} - if (cores > 1) { - release_core_1(); - } +bool _CPU_SMP_Start_processor(uint32_t cpu_index) +{ + (void) cpu_index; + + release_core_1(); - return cores; + return true; +} + +void _CPU_SMP_Finalize_initialization(uint32_t cpu_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); + } } 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 8165363d3b..3dc44b1d3a 100644 --- a/c/src/lib/libbsp/shared/smp/smp_stub.c +++ b/c/src/lib/libbsp/shared/smp/smp_stub.c @@ -11,12 +11,21 @@ #include <rtems/score/cpu.h> -uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count ) +uint32_t _CPU_SMP_Initialize( void ) { /* return the number of CPUs */ return 1; } +bool _CPU_SMP_Start_processor( uint32_t cpu_index ) +{ + return true; +} + +void _CPU_SMP_Finalize_initialization( uint32_t cpu_count ) +{ +} + void _CPU_SMP_Send_interrupt( uint32_t target_processor_index ) { } 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 2470e76fce..6681525861 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,43 @@ 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 ) +uint32_t _CPU_SMP_Initialize( void ) { - uint32_t max_cpu_count; - uint32_t used_cpu_count; - uint32_t cpu; - 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 ( rtems_configuration_get_maximum_processors() > 1 ) { + LEON_Unmask_interrupt(LEON3_MP_IRQ); + set_vector(bsp_inter_processor_interrupt, LEON_TRAP_TYPE(LEON3_MP_IRQ), 1); + } - #if defined(RTEMS_DEBUG) - printk( "Found %d CPUs\n", max_cpu_count ); + return leon3_get_cpu_count(LEON3_IrqCtrl_Regs); +} - if ( max_cpu_count > configured_cpu_count ) { - printk( - "%d CPUs IS MORE THAN CONFIGURED -- ONLY USING %d\n", - max_cpu_count, - configured_cpu_count - ); - } +bool _CPU_SMP_Start_processor( uint32_t cpu_index ) +{ + #if defined(RTEMS_DEBUG) + printk( "Waking CPU %d\n", cpu_index ); #endif - if ( used_cpu_count > 1 ) { - LEON_Unmask_interrupt(LEON3_MP_IRQ); - set_vector(bsp_inter_processor_interrupt, LEON_TRAP_TYPE(LEON3_MP_IRQ), 1); - } + LEON3_IrqCtrl_Regs->mpstat = 1U << cpu_index; - for ( cpu = 1 ; cpu < used_cpu_count ; ++cpu ) { - #if defined(RTEMS_DEBUG) - printk( "Waking CPU %d\n", cpu ); - #endif + return true; +} - LEON3_IrqCtrl_Regs->mpstat = 1 << cpu; - } +void _CPU_SMP_Finalize_initialization( uint32_t cpu_count ) +{ + (void) cpu_count; - return used_cpu_count; + /* Nothing to do */ } 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 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 ) |