diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-02-17 10:10:27 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-02-19 09:59:39 +0100 |
commit | 8a6de83fd833c4b0458ba27eb4883c53c1b1ecf4 (patch) | |
tree | ea45e29f7ca5cab0a54ad005e93f942079442814 /cpukit/score | |
parent | score: Disable ISR in _Internal_error_Occurred() (diff) | |
download | rtems-8a6de83fd833c4b0458ba27eb4883c53c1b1ecf4.tar.bz2 |
score: Move _SMP_Request_other_cores_to_shutdown()
Move _SMP_Request_other_cores_to_shutdown() invocation from
rtems_shutdown_executive() to _Internal_error_Occurred() to allow a
proper shutdown on SMP configurations even in the error case.
Diffstat (limited to 'cpukit/score')
-rw-r--r-- | cpukit/score/include/rtems/score/interr.h | 5 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/smp.h | 11 | ||||
-rw-r--r-- | cpukit/score/src/interr.c | 3 | ||||
-rw-r--r-- | cpukit/score/src/smp.c | 22 |
4 files changed, 29 insertions, 12 deletions
diff --git a/cpukit/score/include/rtems/score/interr.h b/cpukit/score/include/rtems/score/interr.h index 2f5add4b54..2ee7109cf2 100644 --- a/cpukit/score/include/rtems/score/interr.h +++ b/cpukit/score/include/rtems/score/interr.h @@ -186,7 +186,10 @@ extern Internal_errors_Information _Internal_errors_What_happened; * - valid read-only data. * * For the initial extensions the read-write data (including BSS segment) is - * not required. + * not required on single processor configurations. On SMP configurations + * however the read-write data must be initialized since this function must + * determine the state of the other processors and request them to shut-down if + * necessary. * * Non-initial extensions require in addition valid read-write data. The BSP * may install an initial extension that performs a system reset. In this case diff --git a/cpukit/score/include/rtems/score/smp.h b/cpukit/score/include/rtems/score/smp.h index 2fd915022f..b97cceda36 100644 --- a/cpukit/score/include/rtems/score/smp.h +++ b/cpukit/score/include/rtems/score/smp.h @@ -88,14 +88,19 @@ void _SMP_Broadcast_message( */ void _SMP_Request_other_cores_to_perform_first_context_switch(void); +#endif /* defined( RTEMS_SMP ) */ + /** * @brief Request other cores to shutdown. * * Send message to other cores requesting them to shutdown. */ -void _SMP_Request_other_cores_to_shutdown(void); - -#endif /* defined( RTEMS_SMP ) */ +#if defined( RTEMS_SMP ) + void _SMP_Request_other_cores_to_shutdown( void ); +#else + #define _SMP_Request_other_cores_to_shutdown() \ + do { } while ( 0 ) +#endif #endif /* !defined( ASM ) */ diff --git a/cpukit/score/src/interr.c b/cpukit/score/src/interr.c index 9f52ce70cf..bb15e0cbe4 100644 --- a/cpukit/score/src/interr.c +++ b/cpukit/score/src/interr.c @@ -20,6 +20,7 @@ #include <rtems/score/interr.h> #include <rtems/score/isrlevel.h> +#include <rtems/score/smp.h> #include <rtems/score/sysstate.h> #include <rtems/score/userextimpl.h> @@ -38,6 +39,8 @@ void _Internal_error_Occurred( _ISR_Disable_without_giant( level ); (void) level; + _SMP_Request_other_cores_to_shutdown(); + _User_extensions_Fatal( the_source, is_internal, the_error ); _Internal_errors_What_happened.the_source = the_source; diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c index df1c6d312a..50ebc132a8 100644 --- a/cpukit/score/src/smp.c +++ b/cpukit/score/src/smp.c @@ -22,7 +22,7 @@ #include <rtems/score/threaddispatch.h> #include <rtems/score/threadimpl.h> #include <rtems/score/smp.h> -#include <rtems/score/sysstate.h> +#include <rtems/config.h> #if defined(RTEMS_DEBUG) #include <rtems/bspIo.h> @@ -137,17 +137,23 @@ void _SMP_Request_other_cores_to_perform_first_context_switch( void ) void _SMP_Request_other_cores_to_shutdown( void ) { uint32_t self = _SMP_Get_current_processor(); - uint32_t ncpus = _SMP_Get_processor_count(); - uint32_t cpu; - _SMP_Broadcast_message( RTEMS_BSP_SMP_SHUTDOWN ); + /* + * Do not use _SMP_Get_processor_count() since this value might be not + * initialized yet. For example due to a fatal error in the middle of + * bsp_smp_initialize(). + */ + uint32_t ncpus = rtems_configuration_get_maximum_processors(); + + uint32_t cpu; for ( cpu = 0 ; cpu < ncpus ; ++cpu ) { if ( cpu != self ) { - _Per_CPU_Wait_for_state( - _Per_CPU_Get_by_index( cpu ), - PER_CPU_STATE_SHUTDOWN - ); + const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu ); + + if ( per_cpu->state != PER_CPU_STATE_BEFORE_INITIALIZATION ) { + _SMP_Send_message( cpu, RTEMS_BSP_SMP_SHUTDOWN ); + } } } } |