summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-02-17 10:10:27 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-02-19 09:59:39 +0100
commit8a6de83fd833c4b0458ba27eb4883c53c1b1ecf4 (patch)
treeea45e29f7ca5cab0a54ad005e93f942079442814 /cpukit
parentscore: Disable ISR in _Internal_error_Occurred() (diff)
downloadrtems-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')
-rw-r--r--cpukit/sapi/src/exshutdown.c8
-rw-r--r--cpukit/score/include/rtems/score/interr.h5
-rw-r--r--cpukit/score/include/rtems/score/smp.h11
-rw-r--r--cpukit/score/src/interr.c3
-rw-r--r--cpukit/score/src/smp.c22
5 files changed, 29 insertions, 20 deletions
diff --git a/cpukit/sapi/src/exshutdown.c b/cpukit/sapi/src/exshutdown.c
index 41ee537e44..80848f0953 100644
--- a/cpukit/sapi/src/exshutdown.c
+++ b/cpukit/sapi/src/exshutdown.c
@@ -17,10 +17,6 @@
#include <rtems/score/sysstate.h>
#include <rtems/score/interr.h>
-#if defined(RTEMS_SMP)
- #include <rtems/score/smp.h>
-#endif
-
void rtems_shutdown_executive( uint32_t result )
{
Internal_errors_Source source;
@@ -28,10 +24,6 @@ void rtems_shutdown_executive( uint32_t result )
Internal_errors_t code;
if ( _System_state_Is_up( _System_state_Get() ) ) {
- #if defined(RTEMS_SMP)
- _SMP_Request_other_cores_to_shutdown();
- #endif
-
source = RTEMS_FATAL_SOURCE_EXIT;
is_internal = false;
code = result;
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 );
+ }
}
}
}