[PATCH 2/4] score: SMP initialization and shutdown changes
Gedare Bloom
gedare at rtems.org
Wed Feb 19 15:11:02 UTC 2014
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.huber at 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 at .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
> + * <rtems at 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 at rtems.org
> http://www.rtems.org/mailman/listinfo/rtems-devel
More information about the devel
mailing list