Hi, There is dissimilarity between the SMP handler function names * _SMP_Request_processors_to_shutdown * _SMP_Request_start_multitasking_on_secondary_processors()
Note the order switch between the verb and object. If you like the similar with _Thread_Start_multitasking, I recommend using _SMP_Request_shutdown_on_secondary_processors(). I also do not think it is necessary to include "on_secondary_processors()" however. You could just use * _SMP_Request_shutdown() * _SMP_Request_start_multitasking() -Gedare On Wed, Feb 19, 2014 at 8:42 AM, Sebastian Huber <sebastian.hu...@embedded-brains.de> wrote: > Rename _SMP_Request_other_cores_to_perform_first_context_switch() into > _SMP_Request_start_multitasking_on_secondary_processors() to match the > corresponding _SMP_Start_multitasking_on_secondary_processor() action of > secondary processors. Highlights also similarity to > _Thread_Start_multitasking(). Move in source file to right place. > > Rename PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING into > PER_CPU_STATE_READY_TO_START_MULTITASKING. > > Rename PER_CPU_STATE_BEGIN_MULTITASKING into > PER_CPU_STATE_START_MULTITASKING. > > Rename _SMP_Request_other_cores_to_shutdown() into > _SMP_Request_processors_to_shutdown(). > > Add new state PER_CPU_STATE_DO_SHUTDOWN to initiate a shutdown of other > processors during system initialization. Add documentation for > Per_CPU_State. > > Delete debug output. > > New test smptests/smpfatal01. > --- > cpukit/sapi/src/exinit.c | 2 +- > cpukit/score/include/rtems/score/percpu.h | 66 ++++++++++-- > cpukit/score/include/rtems/score/smpimpl.h | 11 +- > cpukit/score/src/interr.c | 2 +- > cpukit/score/src/percpu.c | 13 ++- > cpukit/score/src/smp.c | 117 +++++++++++--------- > testsuites/smptests/Makefile.am | 1 + > testsuites/smptests/configure.ac | 1 + > testsuites/smptests/smpfatal01/Makefile.am | 19 ++++ > testsuites/smptests/smpfatal01/init.c | 140 > +++++++++++++++++++++++++ > testsuites/smptests/smpfatal01/smpfatal01.doc | 12 ++ > testsuites/smptests/smpfatal01/smpfatal01.scn | 2 + > 12 files changed, 312 insertions(+), 74 deletions(-) > create mode 100644 testsuites/smptests/smpfatal01/Makefile.am > create mode 100644 testsuites/smptests/smpfatal01/init.c > create mode 100644 testsuites/smptests/smpfatal01/smpfatal01.doc > create mode 100644 testsuites/smptests/smpfatal01/smpfatal01.scn > > diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c > index d265455..3784401 100644 > --- a/cpukit/sapi/src/exinit.c > +++ b/cpukit/sapi/src/exinit.c > @@ -210,7 +210,7 @@ void rtems_initialize_start_multitasking(void) > { > _System_state_Set( SYSTEM_STATE_UP ); > > - _SMP_Request_other_cores_to_perform_first_context_switch(); > + _SMP_Request_start_multitasking_on_secondary_processors(); > > _Thread_Start_multitasking(); > > diff --git a/cpukit/score/include/rtems/score/percpu.h > b/cpukit/score/include/rtems/score/percpu.h > index 4c46b50..27b97f6 100644 > --- a/cpukit/score/include/rtems/score/percpu.h > +++ b/cpukit/score/include/rtems/score/percpu.h > @@ -70,6 +70,32 @@ typedef struct Thread_Control_struct Thread_Control; > #error "deferred FP switch not implemented for SMP" > #endif > > +/** > + * @brief State of a processor. > + * > + * @dot > + * digraph states { > + * bi [label="PER_CPU_STATE_BEFORE_INITIALIZATION"]; > + * rsm [label="PER_CPU_STATE_READY_TO_START_MULTITASKING"]; > + * sm [label="PER_CPU_STATE_START_MULTITASKING"]; > + * ds [label="PER_CPU_STATE_DO_SHUTDOWN"]; > + * u [label="PER_CPU_STATE_UP"]; > + * s [label="PER_CPU_STATE_SHUTDOWN"]; > + * bi -> rsm [label="secondary processor\ncompleted initialization"]; > + * bi -> u [label="main processor\nstarts multitasking"]; > + * rsm -> sm [label="main processor\ncompleted initialization"]; > + * rsm -> ds [label="a fatal error occurred"]; > + * ds -> s [label="do shutdown\nstate observed"]; > + * sm -> u [label="secondary processor\nstarts multitasking"]; > + * u -> s [label="shutdown initiated"]; > + * } > + * @enddot > + * > + * The values are chosen to stop the wait for change in case an alternative > + * state change occurs during _Per_CPU_Wait_for_state(). > + * > + * @see _Per_CPU_Change_state(), _Per_CPU_Wait_for_state() and > _Per_CPU_Get_state(). > + */ > typedef enum { > /** > * @brief The per CPU controls are initialized to zero. > @@ -77,15 +103,15 @@ typedef enum { > * In this state the only valid field of the per CPU controls for secondary > * processors is the per CPU state. The secondary processors should > perform > * their basic initialization now and change into the > - * PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING state once this is complete. > + * PER_CPU_STATE_READY_TO_START_MULTITASKING state once this is complete. > * > * The owner of the per CPU state field is the secondary processor in this > * state. > */ > - PER_CPU_STATE_BEFORE_INITIALIZATION, > + PER_CPU_STATE_BEFORE_INITIALIZATION = 0x0, > > /** > - * @brief Secondary processor is ready to begin multitasking. > + * @brief Secondary processor is ready to start multitasking. > * > * The secondary processor performed its basic initialization and is ready > to > * receive inter-processor interrupts. Interrupt delivery must be disabled > @@ -94,16 +120,16 @@ typedef enum { > * the first time. The main processor will wait for all secondary > processors > * to change into this state. In case a secondary processor does not reach > * this state the system will not start. The secondary processors wait now > - * for a change into the PER_CPU_STATE_BEGIN_MULTITASKING state set by the > + * for a change into the PER_CPU_STATE_START_MULTITASKING state set by the > * main processor once all secondary processors reached the > - * PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING state. > + * PER_CPU_STATE_READY_TO_START_MULTITASKING state. > * > * The owner of the per CPU state field is the main processor in this > state. > */ > - PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING, > + PER_CPU_STATE_READY_TO_START_MULTITASKING = 0x1, > > /** > - * @brief Multitasking begin of secondary processor is requested. > + * @brief Multitasking start of secondary processor is requested. > * > * The main processor completed system initialization and is about to > perform > * a context switch to its heir thread. Secondary processors should now > @@ -113,7 +139,18 @@ typedef enum { > * The owner of the per CPU state field is the secondary processor in this > * state. > */ > - PER_CPU_STATE_BEGIN_MULTITASKING, > + PER_CPU_STATE_START_MULTITASKING = 0x2 | 0x4, > + > + /** > + * @brief Shutdown of secondary processor is requested. > + * > + * A fatal error occurred during system initialization. A secondary > + * processor will shutdown once observes this state. > + * > + * The owner of the per CPU state field is the secondary processor in this > + * state. > + */ > + PER_CPU_STATE_DO_SHUTDOWN = 0x2 | 0x8, > > /** > * @brief Normal multitasking state. > @@ -121,7 +158,7 @@ typedef enum { > * The owner of the per CPU state field is the secondary processor in this > * state. > */ > - PER_CPU_STATE_UP, > + PER_CPU_STATE_UP = 0x10, > > /** > * @brief This is the terminal state. > @@ -129,7 +166,7 @@ typedef enum { > * The owner of the per CPU state field is the secondary processor in this > * state. > */ > - PER_CPU_STATE_SHUTDOWN > + PER_CPU_STATE_SHUTDOWN = 0x20 > } Per_CPU_State; > > #endif /* defined( RTEMS_SMP ) */ > @@ -318,11 +355,18 @@ void _Per_CPU_Change_state( > Per_CPU_State new_state > ); > > -void _Per_CPU_Wait_for_state( > +Per_CPU_State _Per_CPU_Wait_for_state( > const Per_CPU_Control *per_cpu, > Per_CPU_State desired_state > ); > > +static inline Per_CPU_State _Per_CPU_Get_state( > + const Per_CPU_Control *per_cpu > +) > +{ > + return per_cpu->state; > +} > + > #endif /* defined( RTEMS_SMP ) */ > > /* > diff --git a/cpukit/score/include/rtems/score/smpimpl.h > b/cpukit/score/include/rtems/score/smpimpl.h > index d68af43..1c44c29 100644 > --- a/cpukit/score/include/rtems/score/smpimpl.h > +++ b/cpukit/score/include/rtems/score/smpimpl.h > @@ -47,6 +47,7 @@ extern "C" { > * @brief SMP fatal codes. > */ > typedef enum { > + SMP_FATAL_EARLY_SHUTDOWN, > SMP_FATAL_SHUTDOWN > } SMP_Fatal_code; > > @@ -108,8 +109,6 @@ static inline void > _SMP_Inter_processor_interrupt_handler( void ) > _Per_CPU_Release_and_ISR_enable( self_cpu, level ); > > if ( ( message & SMP_MESSAGE_SHUTDOWN ) != 0 ) { > - _Per_CPU_Change_state( self_cpu, PER_CPU_STATE_SHUTDOWN ); > - > rtems_fatal( RTEMS_FATAL_SOURCE_SMP, SMP_FATAL_SHUTDOWN ); > /* does not continue past here */ > } > @@ -149,9 +148,9 @@ void _SMP_Broadcast_message( > * their first context switch operation. > */ > #if defined( RTEMS_SMP ) > - void _SMP_Request_other_cores_to_perform_first_context_switch( void ); > + void _SMP_Request_start_multitasking_on_secondary_processors( void ); > #else > - #define _SMP_Request_other_cores_to_perform_first_context_switch() \ > + #define _SMP_Request_start_multitasking_on_secondary_processors() \ > do { } while ( 0 ) > #endif > > @@ -161,9 +160,9 @@ void _SMP_Broadcast_message( > * Send message to other cores requesting them to shutdown. > */ > #if defined( RTEMS_SMP ) > - void _SMP_Request_other_cores_to_shutdown( void ); > + void _SMP_Request_processors_to_shutdown( void ); > #else > - #define _SMP_Request_other_cores_to_shutdown() \ > + #define _SMP_Request_processors_to_shutdown() \ > do { } while ( 0 ) > #endif > > diff --git a/cpukit/score/src/interr.c b/cpukit/score/src/interr.c > index c2a9fbe..d57f116 100644 > --- a/cpukit/score/src/interr.c > +++ b/cpukit/score/src/interr.c > @@ -39,7 +39,7 @@ void _Terminate( > _ISR_Disable_without_giant( level ); > (void) level; > > - _SMP_Request_other_cores_to_shutdown(); > + _SMP_Request_processors_to_shutdown(); > > _User_extensions_Fatal( the_source, is_internal, the_error ); > > diff --git a/cpukit/score/src/percpu.c b/cpukit/score/src/percpu.c > index c68f378..9ce8b17 100644 > --- a/cpukit/score/src/percpu.c > +++ b/cpukit/score/src/percpu.c > @@ -19,6 +19,7 @@ > #endif > > #include <rtems/score/percpu.h> > +#include <rtems/score/assert.h> > > #if defined(RTEMS_SMP) > void _Per_CPU_Change_state( > @@ -30,14 +31,22 @@ > _CPU_SMP_Processor_event_broadcast(); > } > > - void _Per_CPU_Wait_for_state( > + Per_CPU_State _Per_CPU_Wait_for_state( > const Per_CPU_Control *per_cpu, > Per_CPU_State desired_state > ) > { > - while ( per_cpu->state != desired_state ) { > + Per_CPU_State state = per_cpu->state; > + > + _Assert( desired_state != 0 ); > + > + while ( (state & desired_state) == 0 ) { > _CPU_SMP_Processor_event_receive(); > + > + state = per_cpu->state; > } > + > + return state; > } > #else > /* > diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c > index 59036eb..445a56a 100644 > --- a/cpukit/score/src/smp.c > +++ b/cpukit/score/src/smp.c > @@ -24,10 +24,6 @@ > #include <rtems/score/threadimpl.h> > #include <rtems/config.h> > > -#if defined(RTEMS_DEBUG) > - #include <rtems/bspIo.h> > -#endif > - > void _SMP_Handler_initialize( void ) > { > uint32_t max_cpus = rtems_configuration_get_maximum_processors(); > @@ -47,69 +43,44 @@ void _SMP_Handler_initialize( void ) > _SMP_Processor_count = max_cpus; > } > > -void _SMP_Start_multitasking_on_secondary_processor( void ) > -{ > - Per_CPU_Control *self_cpu = _Per_CPU_Get(); > - > - #if defined(RTEMS_DEBUG) > - printk( "Made it to %d -- ", _Per_CPU_Get_index( self_cpu ) ); > - #endif > - > - _Per_CPU_Change_state( self_cpu, PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING > ); > - > - _Per_CPU_Wait_for_state( self_cpu, PER_CPU_STATE_BEGIN_MULTITASKING ); > - > - _Thread_Start_multitasking(); > -} > - > -void _SMP_Send_message( uint32_t cpu, uint32_t message ) > -{ > - Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu ); > - ISR_Level level; > - > - _Per_CPU_ISR_disable_and_acquire( per_cpu, level ); > - per_cpu->message |= message; > - _Per_CPU_Release_and_ISR_enable( per_cpu, level ); > - > - _CPU_SMP_Send_interrupt( cpu ); > -} > - > -void _SMP_Broadcast_message( uint32_t message ) > +void _SMP_Request_start_multitasking_on_secondary_processors( void ) > { > uint32_t self = _SMP_Get_current_processor(); > uint32_t ncpus = _SMP_Get_processor_count(); > uint32_t cpu; > > - _Assert_Thread_dispatching_repressed(); > - > for ( cpu = 0 ; cpu < ncpus ; ++cpu ) { > + Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu ); > + > if ( cpu != self ) { > - _SMP_Send_message( cpu, message ); > + _Per_CPU_Wait_for_state( > + per_cpu, > + PER_CPU_STATE_READY_TO_START_MULTITASKING > + ); > + > + _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_START_MULTITASKING ); > } > } > } > > -void _SMP_Request_other_cores_to_perform_first_context_switch( void ) > +void _SMP_Start_multitasking_on_secondary_processor( void ) > { > - uint32_t self = _SMP_Get_current_processor(); > - uint32_t ncpus = _SMP_Get_processor_count(); > - uint32_t cpu; > + Per_CPU_Control *self_cpu = _Per_CPU_Get(); > + Per_CPU_State state; > > - for ( cpu = 0 ; cpu < ncpus ; ++cpu ) { > - Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu ); > + _Per_CPU_Change_state( self_cpu, PER_CPU_STATE_READY_TO_START_MULTITASKING > ); > > - if ( cpu != self ) { > - _Per_CPU_Wait_for_state( > - per_cpu, > - PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING > - ); > + state = > + _Per_CPU_Wait_for_state( self_cpu, PER_CPU_STATE_START_MULTITASKING ); > > - _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_BEGIN_MULTITASKING ); > - } > + if ( state == PER_CPU_STATE_START_MULTITASKING ) { > + _Thread_Start_multitasking(); > + } else { > + rtems_fatal( RTEMS_FATAL_SOURCE_SMP, SMP_FATAL_EARLY_SHUTDOWN ); > } > } > > -void _SMP_Request_other_cores_to_shutdown( void ) > +void _SMP_Request_processors_to_shutdown( void ) > { > uint32_t self = _SMP_Get_current_processor(); > > @@ -123,12 +94,52 @@ void _SMP_Request_other_cores_to_shutdown( void ) > uint32_t cpu; > > for ( cpu = 0 ; cpu < ncpus ; ++cpu ) { > - if ( cpu != self ) { > - const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu ); > + Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu ); > > - if ( per_cpu->state != PER_CPU_STATE_BEFORE_INITIALIZATION ) { > - _SMP_Send_message( cpu, SMP_MESSAGE_SHUTDOWN ); > + if ( cpu != self ) { > + switch ( _Per_CPU_Get_state( per_cpu ) ) { > + case PER_CPU_STATE_READY_TO_START_MULTITASKING: > + _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_DO_SHUTDOWN ); > + break; > + case PER_CPU_STATE_START_MULTITASKING: > + case PER_CPU_STATE_UP: > + _SMP_Send_message( cpu, SMP_MESSAGE_SHUTDOWN ); > + break; > + case PER_CPU_STATE_DO_SHUTDOWN: > + case PER_CPU_STATE_SHUTDOWN: > + case PER_CPU_STATE_BEFORE_INITIALIZATION: > + /* Nothing to do */ > + break; > } > + } else { > + _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_SHUTDOWN ); > + } > + } > +} > + > +void _SMP_Send_message( uint32_t cpu, uint32_t message ) > +{ > + Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu ); > + ISR_Level level; > + > + _Per_CPU_ISR_disable_and_acquire( per_cpu, level ); > + per_cpu->message |= message; > + _Per_CPU_Release_and_ISR_enable( per_cpu, level ); > + > + _CPU_SMP_Send_interrupt( cpu ); > +} > + > +void _SMP_Broadcast_message( uint32_t message ) > +{ > + uint32_t self = _SMP_Get_current_processor(); > + uint32_t ncpus = _SMP_Get_processor_count(); > + uint32_t cpu; > + > + _Assert_Thread_dispatching_repressed(); > + > + for ( cpu = 0 ; cpu < ncpus ; ++cpu ) { > + if ( cpu != self ) { > + _SMP_Send_message( cpu, message ); > } > } > } > diff --git a/testsuites/smptests/Makefile.am b/testsuites/smptests/Makefile.am > index 023b7e9..7b610b5 100644 > --- a/testsuites/smptests/Makefile.am > +++ b/testsuites/smptests/Makefile.am > @@ -11,6 +11,7 @@ SUBDIRS += smp07 > SUBDIRS += smp08 > SUBDIRS += smp09 > SUBDIRS += smpatomic01 > +SUBDIRS += smpfatal01 > SUBDIRS += smplock01 > SUBDIRS += smpmigration01 > SUBDIRS += smpschedule01 > diff --git a/testsuites/smptests/configure.ac > b/testsuites/smptests/configure.ac > index 5c68772..475ee9c 100644 > --- a/testsuites/smptests/configure.ac > +++ b/testsuites/smptests/configure.ac > @@ -65,6 +65,7 @@ smp07/Makefile > smp08/Makefile > smp09/Makefile > smpatomic01/Makefile > +smpfatal01/Makefile > smplock01/Makefile > smpmigration01/Makefile > smppsxsignal01/Makefile > diff --git a/testsuites/smptests/smpfatal01/Makefile.am > b/testsuites/smptests/smpfatal01/Makefile.am > new file mode 100644 > index 0000000..2aaee2b > --- /dev/null > +++ b/testsuites/smptests/smpfatal01/Makefile.am > @@ -0,0 +1,19 @@ > +rtems_tests_PROGRAMS = smpfatal01 > +smpfatal01_SOURCES = init.c > + > +dist_rtems_tests_DATA = smpfatal01.scn smpfatal01.doc > + > +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg > +include $(top_srcdir)/../automake/compile.am > +include $(top_srcdir)/../automake/leaf.am > + > +AM_CPPFLAGS += -I$(top_srcdir)/../support/include > + > +LINK_OBJS = $(smpfatal01_OBJECTS) > +LINK_LIBS = $(smpfatal01_LDLIBS) > + > +smpfatal01$(EXEEXT): $(smpfatal01_OBJECTS) $(smpfatal01_DEPENDENCIES) > + @rm -f smpfatal01$(EXEEXT) > + $(make-exe) > + > +include $(top_srcdir)/../automake/local.am > diff --git a/testsuites/smptests/smpfatal01/init.c > b/testsuites/smptests/smpfatal01/init.c > new file mode 100644 > index 0000000..e6b2eee > --- /dev/null > +++ b/testsuites/smptests/smpfatal01/init.c > @@ -0,0 +1,140 @@ > +/* > + * Copyright (c) 2014 embedded brains GmbH. All rights reserved. > + * > + * embedded brains GmbH > + * Dornierstr. 4 > + * 82178 Puchheim > + * Germany > + * <rt...@embedded-brains.de> > + * > + * The license and distribution terms for this file may be > + * found in the file LICENSE in this distribution or at > + * http://www.rtems.com/license/LICENSE. > + */ > + > +#ifdef HAVE_CONFIG_H > + #include "config.h" > +#endif > + > +#include <rtems.h> > +#include <rtems/score/percpu.h> > +#include <rtems/score/smpimpl.h> > + > +#include "tmacros.h" > + > +#define MAX_CPUS 32 > + > +static uint32_t main_cpu; > + > +static void Init(rtems_task_argument arg) > +{ > + rtems_test_assert(0); > +} > + > +static void fatal_extension( > + rtems_fatal_source source, > + bool is_internal, > + rtems_fatal_code code > +) > +{ > + if (source != RTEMS_FATAL_SOURCE_ASSERT) { > + uint32_t self_cpu = rtems_smp_get_current_processor(); > + > + rtems_test_assert(!is_internal); > + > + if (self_cpu == main_cpu) { > + uint32_t cpu_count = rtems_smp_get_processor_count(); > + uint32_t cpu; > + > + rtems_test_assert(source == RTEMS_FATAL_SOURCE_APPLICATION); > + rtems_test_assert(code == 0xdeadbeef); > + > + for (cpu = 0; cpu < MAX_CPUS; ++cpu) { > + const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu ); > + Per_CPU_State state = _Per_CPU_Get_state( per_cpu ); > + > + if (cpu == self_cpu) { > + rtems_test_assert(state == PER_CPU_STATE_SHUTDOWN); > + } else if (cpu < cpu_count) { > + rtems_test_assert( > + state == PER_CPU_STATE_READY_TO_START_MULTITASKING > + || state == PER_CPU_STATE_DO_SHUTDOWN > + || state == PER_CPU_STATE_SHUTDOWN > + ); > + state = _Per_CPU_Wait_for_state( > + per_cpu, > + PER_CPU_STATE_SHUTDOWN > + ); > + rtems_test_assert(state == PER_CPU_STATE_SHUTDOWN); > + } else { > + rtems_test_assert(state == PER_CPU_STATE_BEFORE_INITIALIZATION); > + } > + } > + > + printk( "*** END OF TEST SMPFATAL 1 ***\n" ); > + } else { > + rtems_test_assert(source == RTEMS_FATAL_SOURCE_SMP); > + rtems_test_assert(code == SMP_FATAL_EARLY_SHUTDOWN); > + } > + } > +} > + > +static rtems_status_code test_driver_init( > + rtems_device_major_number major, > + rtems_device_minor_number minor, > + void *arg > +) > +{ > + uint32_t self_cpu = rtems_smp_get_current_processor(); > + uint32_t cpu_count = rtems_smp_get_processor_count(); > + uint32_t cpu; > + > + printk("\n\n*** TEST SMPFATAL 1 ***\n"); > + > + rtems_test_assert(rtems_configuration_get_maximum_processors() == > MAX_CPUS); > + > + main_cpu = self_cpu; > + > + for (cpu = 0; cpu < MAX_CPUS; ++cpu) { > + const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu ); > + Per_CPU_State state = _Per_CPU_Get_state( per_cpu ); > + > + if (cpu == self_cpu) { > + rtems_test_assert(state == PER_CPU_STATE_BEFORE_INITIALIZATION); > + } else if (cpu < cpu_count) { > + rtems_test_assert( > + state == PER_CPU_STATE_BEFORE_INITIALIZATION > + || state == PER_CPU_STATE_READY_TO_START_MULTITASKING > + ); > + state = _Per_CPU_Wait_for_state( > + per_cpu, > + PER_CPU_STATE_READY_TO_START_MULTITASKING > + ); > + rtems_test_assert(state == PER_CPU_STATE_READY_TO_START_MULTITASKING); > + } else { > + rtems_test_assert(state == PER_CPU_STATE_BEFORE_INITIALIZATION); > + } > + } > + > + rtems_fatal(RTEMS_FATAL_SOURCE_APPLICATION, 0xdeadbeef); > +} > + > +#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER > +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER > + > +#define CONFIGURE_APPLICATION_EXTRA_DRIVERS \ > + { .initialization_entry = test_driver_init } > + > +#define CONFIGURE_INITIAL_EXTENSIONS { .fatal = fatal_extension } > + > +#define CONFIGURE_SMP_APPLICATION > + > +#define CONFIGURE_SMP_MAXIMUM_PROCESSORS MAX_CPUS > + > +#define CONFIGURE_MAXIMUM_TASKS 1 > + > +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE > + > +#define CONFIGURE_INIT > + > +#include <rtems/confdefs.h> > diff --git a/testsuites/smptests/smpfatal01/smpfatal01.doc > b/testsuites/smptests/smpfatal01/smpfatal01.doc > new file mode 100644 > index 0000000..831fabc > --- /dev/null > +++ b/testsuites/smptests/smpfatal01/smpfatal01.doc > @@ -0,0 +1,12 @@ > +This file describes the directives and concepts tested by this test set. > + > +test set name: smpfatal01 > + > +directives: > + > + - _SMP_Request_processors_to_shutdown() > + > +concepts: > + > + - Ensure that the system termination in case of fatal errors during driver > + initialization works. > diff --git a/testsuites/smptests/smpfatal01/smpfatal01.scn > b/testsuites/smptests/smpfatal01/smpfatal01.scn > new file mode 100644 > index 0000000..0b67121 > --- /dev/null > +++ b/testsuites/smptests/smpfatal01/smpfatal01.scn > @@ -0,0 +1,2 @@ > +*** TEST SMPFATAL 1 *** > +*** END OF TEST SMPFATAL 1 *** > -- > 1.7.7 > > _______________________________________________ > rtems-devel mailing list > rtems-devel@rtems.org > http://www.rtems.org/mailman/listinfo/rtems-devel _______________________________________________ rtems-devel mailing list rtems-devel@rtems.org http://www.rtems.org/mailman/listinfo/rtems-devel