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