Index: c/src/lib/libbsp/i386/shared/smp/smp-imps.c
===================================================================
--- c/src/lib/libbsp/i386/shared/smp/smp-imps.c	(revision 8cacceb7b9e789976c943339ab76317e8964b528)
+++ c/src/lib/libbsp/i386/shared/smp/smp-imps.c	(revision 2f6108f93b3ee4dcc85b236593d4c57c7652bf1b)
@@ -72,5 +72,4 @@
 #define VIRTUAL_TO_PHYS(x)    /* convert virtual address "x" to physical */
 #define UDELAY(x)             /* delay roughly at least "x" microsecs */
-#define TEST_BOOTED(x)        /* test bootaddr x to see if CPU started */
 #define READ_MSR_LO(x)        /* Read MSR low function */
 #else
@@ -125,7 +124,4 @@
 #define READ_MSR_LO(_x) \
   (unsigned int)(read_msr(_x) & 0xffffffff)
-
-#define TEST_BOOTED(_cpu) \
-  (_Per_CPU_Information[_cpu].state == RTEMS_BSP_SMP_CPU_INITIALIZED)
 
 static inline unsigned long long read_msr(unsigned int msr)
@@ -312,20 +308,4 @@
 
   /*
-   *  Check to see if other processor has started.
-   */
-  bsp_smp_wait_for(
-    (volatile unsigned int *)&_Per_CPU_Information[imps_num_cpus].state,
-    RTEMS_BSP_SMP_CPU_INITIALIZED,
-    1600
-  );
-  if ( _Per_CPU_Information[imps_num_cpus].state ==
-        RTEMS_BSP_SMP_CPU_INITIALIZED )
-    printk("#%d  Application Processor (AP)", imps_num_cpus);
-  else {
-    printk("CPU Not Responding, DISABLED");
-    success = 0;
-  }
-
-  /*
    *  Generic CPU startup sequence ends here, the rest is cleanup.
    */
@@ -836,31 +816,2 @@
   send_ipi( 0, LAPIC_ICR_DS_ALLEX | 0x30 );
 }
-
-void bsp_smp_wait_for(
-  volatile unsigned int *address,
-  unsigned int           desired,
-  int                    maximum_usecs
-)
-{
-  int iterations;
-  volatile int i;
-  volatile unsigned int *p = (volatile unsigned int *)address;
-
-  for (iterations=0 ;  iterations < maximum_usecs ; iterations++ ) {
-    if ( *p == desired )
-      break;
-    #ifdef __SSE3__
-      __builtin_ia32_monitor( (const void *)address, 0, 0 );
-      if ( *p == desired )
-        break;
-      __builtin_ia32_mwait( 0, 0 );
-    #endif
-
-    /*
-     *  Until i386 ms delay does not depend upon the clock we
-     *  will use this less sophisticated delay. 
-     */
-    for(i=5000; i>0; i--)
-      ;
-  }
-}
Index: src/lib/libbsp/shared/smp/bspsmp_wait_for.c
===================================================================
--- c/src/lib/libbsp/shared/smp/bspsmp_wait_for.c	(revision 8cacceb7b9e789976c943339ab76317e8964b528)
+++ 	(revision )
@@ -1,28 +1,0 @@
-/*
- *
- *  COPYRIGHT (c) 1989-2011.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  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.
- */
-
-void rtems_bsp_delay( int usec );
-
-void bsp_smp_wait_for(
-  volatile unsigned int *address,
-  unsigned int           desired,
-  int                    maximum_usecs
-)
-{
-  int iterations;
-  volatile unsigned int *p = address;
-
-  for (iterations=0 ;  iterations < maximum_usecs ; iterations++ ) {
-    if ( *p == desired )
-      break;
-
-    rtems_bsp_delay( 1 );
-  }
-}
Index: c/src/lib/libbsp/sparc/erc32/Makefile.am
===================================================================
--- c/src/lib/libbsp/sparc/erc32/Makefile.am	(revision 8cacceb7b9e789976c943339ab76317e8964b528)
+++ c/src/lib/libbsp/sparc/erc32/Makefile.am	(revision 2f6108f93b3ee4dcc85b236593d4c57c7652bf1b)
@@ -67,6 +67,5 @@
 
 if HAS_SMP
-libbsp_a_SOURCES += ../../shared/smp/getcpuid.c ../../shared/smp/smp_stub.c \
-    ../../shared/smp/bspsmp_wait_for.c
+libbsp_a_SOURCES += ../../shared/smp/getcpuid.c ../../shared/smp/smp_stub.c
 endif
 
Index: c/src/lib/libbsp/sparc/leon2/Makefile.am
===================================================================
--- c/src/lib/libbsp/sparc/leon2/Makefile.am	(revision 8cacceb7b9e789976c943339ab76317e8964b528)
+++ c/src/lib/libbsp/sparc/leon2/Makefile.am	(revision 2f6108f93b3ee4dcc85b236593d4c57c7652bf1b)
@@ -120,6 +120,5 @@
 
 if HAS_SMP
-libbsp_a_SOURCES += ../../shared/smp/getcpuid.c ../../shared/smp/smp_stub.c \
-    ../../shared/smp/bspsmp_wait_for.c
+libbsp_a_SOURCES += ../../shared/smp/getcpuid.c ../../shared/smp/smp_stub.c
 endif
 
Index: c/src/lib/libbsp/sparc/leon3/smp/smp_leon3.c
===================================================================
--- c/src/lib/libbsp/sparc/leon3/smp/smp_leon3.c	(revision 8cacceb7b9e789976c943339ab76317e8964b528)
+++ c/src/lib/libbsp/sparc/leon3/smp/smp_leon3.c	(revision 2f6108f93b3ee4dcc85b236593d4c57c7652bf1b)
@@ -34,5 +34,5 @@
 }
 
-rtems_isr bsp_ap_ipi_isr(
+static rtems_isr bsp_ap_ipi_isr(
   rtems_vector_number vector
 )
@@ -100,8 +100,9 @@
     #if defined(RTEMS_DEBUG)
       printk(
-	"CPU %d is %s\n",
-	cpu,
-	((_Per_CPU_Information[cpu].state == RTEMS_BSP_SMP_CPU_INITIALIZED) ?
-	   "online" : "offline")
+        "CPU %d is %s\n",
+        cpu,
+        _Per_CPU_Information[cpu].state
+          == PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING ?
+            "online" : "offline"
       );
     #endif
@@ -161,20 +162,2 @@
    __delay( max );
 }
-
-void bsp_smp_wait_for(
-  volatile unsigned int *address,
-  unsigned int           desired,
-  int                    maximum_usecs
-)
-{
-  int iterations;
-  volatile unsigned int *p = address;
-
-  for (iterations=0 ;  iterations < maximum_usecs ; iterations++ ) {
-    if ( *p == desired )
-      break;
-    bsp_smp_delay( 5000 );
-  }
-}
-
-
Index: cpukit/score/cpu/i386/rtems/score/cpu.h
===================================================================
--- cpukit/score/cpu/i386/rtems/score/cpu.h	(revision 8cacceb7b9e789976c943339ab76317e8964b528)
+++ cpukit/score/cpu/i386/rtems/score/cpu.h	(revision 2f6108f93b3ee4dcc85b236593d4c57c7652bf1b)
@@ -464,4 +464,14 @@
         "cc"); \
     } while (0)
+
+  static inline void _CPU_Processor_event_broadcast( void )
+  {
+    __asm__ volatile ( "" : : : "memory" );
+  }
+
+  static inline void _CPU_Processor_event_receive( void )
+  {
+    __asm__ volatile ( "" : : : "memory" );
+  }
 #endif
 
Index: cpukit/score/cpu/no_cpu/rtems/score/cpu.h
===================================================================
--- cpukit/score/cpu/no_cpu/rtems/score/cpu.h	(revision 8cacceb7b9e789976c943339ab76317e8964b528)
+++ cpukit/score/cpu/no_cpu/rtems/score/cpu.h	(revision 2f6108f93b3ee4dcc85b236593d4c57c7652bf1b)
@@ -1403,4 +1403,35 @@
   (((value&0xff) << 8) | ((value >> 8)&0xff))
 
+#ifdef RTEMS_SMP
+  /**
+   * @brief Broadcasts a processor event.
+   *
+   * Some architectures provide a low-level synchronization primitive for
+   * processors in a multi-processor environment.  Processors waiting for this
+   * event may go into a low-power state and stop generating system bus
+   * transactions.  This function must ensure that preceding store operations
+   * can be observed by other processors.
+   *
+   * @see _CPU_Processor_event_receive().
+   */
+  static inline void _CPU_Processor_event_broadcast( void )
+  {
+    __asm__ volatile ( "" : : : "memory" );
+  }
+
+  /**
+   * @brief Receives a processor event.
+   *
+   * This function will wait for the processor event and may wait forever if no
+   * such event arrives.
+   *
+   * @see _CPU_Processor_event_broadcast().
+   */
+  static inline void _CPU_Processor_event_receive( void )
+  {
+    __asm__ volatile ( "" : : : "memory" );
+  }
+#endif
+
 #ifdef __cplusplus
 }
Index: cpukit/score/cpu/sparc/rtems/score/cpu.h
===================================================================
--- cpukit/score/cpu/sparc/rtems/score/cpu.h	(revision 8cacceb7b9e789976c943339ab76317e8964b528)
+++ cpukit/score/cpu/sparc/rtems/score/cpu.h	(revision 2f6108f93b3ee4dcc85b236593d4c57c7652bf1b)
@@ -1204,4 +1204,14 @@
       _previous = _val; \
     } while (0)
+
+  static inline void _CPU_Processor_event_broadcast( void )
+  {
+    __asm__ volatile ( "" : : : "memory" );
+  }
+
+  static inline void _CPU_Processor_event_receive( void )
+  {
+    __asm__ volatile ( "" : : : "memory" );
+  }
 #endif
 
Index: cpukit/score/include/rtems/bspsmp.h
===================================================================
--- cpukit/score/include/rtems/bspsmp.h	(revision 8cacceb7b9e789976c943339ab76317e8964b528)
+++ cpukit/score/include/rtems/bspsmp.h	(revision 2f6108f93b3ee4dcc85b236593d4c57c7652bf1b)
@@ -149,10 +149,4 @@
 void rtems_smp_process_interrupt(void);
 
-void bsp_smp_wait_for(
-  volatile unsigned int *address,
-  unsigned int           desired,
-  int                    maximum_usecs
-);
-
 #endif
 
Index: cpukit/score/include/rtems/score/percpu.h
===================================================================
--- cpukit/score/include/rtems/score/percpu.h	(revision 8cacceb7b9e789976c943339ab76317e8964b528)
+++ cpukit/score/include/rtems/score/percpu.h	(revision 2f6108f93b3ee4dcc85b236593d4c57c7652bf1b)
@@ -61,30 +61,69 @@
 #endif
 
+#ifdef RTEMS_SMP
+
 typedef enum {
-
-  /**
-   *  This defines the constant used to indicate that the cpu code is in
-   *  its initial powered up start.
-   */
-   RTEMS_BSP_SMP_CPU_INITIAL_STATE = 1,
-
-  /**
-   *  This defines the constant used to indicate that the cpu code has
-   *  completed basic initialization and awaits further commands.
-   */
-   RTEMS_BSP_SMP_CPU_INITIALIZED = 2,
-
-  /**
-   *  This defines the constant used to indicate that the cpu code has
-   *  completed basic initialization and awaits further commands.
-   */
-  RTEMS_BSP_SMP_CPU_UP = 3,
-
-  /**
-   *  This defines the constant used to indicate that the cpu code has
-   *  shut itself down.
-   */
-  RTEMS_BSP_SMP_CPU_SHUTDOWN = 4
-} bsp_smp_cpu_state;
+  /**
+   * @brief The per CPU controls are initialized to zero.
+   *
+   * 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.
+   *
+   * The owner of the per CPU state field is the secondary processor in this
+   * state.
+   */
+  PER_CPU_STATE_BEFORE_INITIALIZATION,
+
+  /**
+   * @brief Secondary processor is ready to begin multitasking.
+   *
+   * The secondary processor performed its basic initialization and is ready to
+   * receive inter-processor interrupts.  Interrupt delivery must be disabled
+   * in this state, but requested inter-processor interrupts must be recorded
+   * and must be delivered once the secondary processor enables interrupts for
+   * 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
+   * main processor once all secondary processors reached the
+   * PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING state.
+   *
+   * The owner of the per CPU state field is the main processor in this state.
+   */
+  PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING,
+
+  /**
+   * @brief Multitasking begin 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
+   * issue a context switch to the heir thread.  This normally enables
+   * interrupts on the processor for the first time.
+   *
+   * The owner of the per CPU state field is the secondary processor in this
+   * state.
+   */
+  PER_CPU_STATE_BEGIN_MULTITASKING,
+
+  /**
+   * @brief Normal multitasking state.
+   *
+   * The owner of the per CPU state field is the secondary processor in this
+   * state.
+   */
+  PER_CPU_STATE_UP,
+
+  /**
+   * @brief This is the terminal state.
+   *
+   * The owner of the per CPU state field is the secondary processor in this
+   * state.
+   */
+  PER_CPU_STATE_SHUTDOWN
+} Per_CPU_State;
+
+#endif /* RTEMS_SMP */
 
 /**
@@ -134,7 +173,4 @@
     SMP_lock_spinlock_simple_Control  lock;
 
-    /** This indicates that the CPU is online. */
-    uint32_t                          state;
-
     /**
      *  This is the request for the interrupt.
@@ -142,5 +178,14 @@
      *  @note This may become a chain protected by atomic instructions.
      */
-    uint32_t                          message;
+    uint32_t message;
+
+    /**
+     * @brief Indicates the current state of the CPU.
+     *
+     * This field is not protected by a lock.
+     *
+     * @see _Per_CPU_Change_state() and _Per_CPU_Wait_for_state().
+     */
+    Per_CPU_State state;
   #endif
 } Per_CPU_Control;
@@ -218,4 +263,14 @@
  */
 void _Per_CPU_Initialize(void);
+
+void _Per_CPU_Change_state(
+  Per_CPU_Control *per_cpu,
+  Per_CPU_State new_state
+);
+
+void _Per_CPU_Wait_for_state(
+  const Per_CPU_Control *per_cpu,
+  Per_CPU_State desired_state
+);
 
 #endif
Index: cpukit/score/include/rtems/score/smp.h
===================================================================
--- cpukit/score/include/rtems/score/smp.h	(revision 8cacceb7b9e789976c943339ab76317e8964b528)
+++ cpukit/score/include/rtems/score/smp.h	(revision 2f6108f93b3ee4dcc85b236593d4c57c7652bf1b)
@@ -59,11 +59,4 @@
 #define RTEMS_BSP_SMP_SHUTDOWN                  0x04
 
-/**
- *  This defines the bit which indicates the interprocessor interrupt
- *  has been requested that the receiving CPU needs to perform a context
- *  switch to the first task.
- */
-#define RTEMS_BSP_SMP_FIRST_TASK                0x08
-
 #ifndef ASM
 /**
@@ -74,4 +67,14 @@
  */
 SCORE_EXTERN uint32_t _SMP_Processor_count;
+
+/**
+ *  @brief Sends a SMP message to a processor.
+ *
+ *  The target processor may be the sending processor.
+ *
+ *  @param[in] cpu The target processor of the message.
+ *  @param[in] message The message.
+ */
+void _SMP_Send_message( int cpu, uint32_t message );
 
 /**
Index: cpukit/score/src/percpu.c
===================================================================
--- cpukit/score/src/percpu.c	(revision 8cacceb7b9e789976c943339ab76317e8964b528)
+++ cpukit/score/src/percpu.c	(revision 2f6108f93b3ee4dcc85b236593d4c57c7652bf1b)
@@ -57,7 +57,4 @@
       }
 #endif
-
-      p->state = RTEMS_BSP_SMP_CPU_INITIAL_STATE;
-      RTEMS_COMPILER_MEMORY_BARRIER();
     }
 
@@ -68,4 +65,30 @@
 
     _SMP_Processor_count = max_cpus;
+
+    for ( cpu = 1 ; cpu < max_cpus; ++cpu ) {
+      _Per_CPU_Wait_for_state(
+        &_Per_CPU_Information[ cpu ],
+        PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING
+      );
+    }
+  }
+
+  void _Per_CPU_Change_state(
+    Per_CPU_Control *per_cpu,
+    Per_CPU_State new_state
+  )
+  {
+    per_cpu->state = new_state;
+    _CPU_Processor_event_broadcast();
+  }
+
+  void _Per_CPU_Wait_for_state(
+    const Per_CPU_Control *per_cpu,
+    Per_CPU_State desired_state
+  )
+  {
+    while ( per_cpu->state != desired_state ) {
+      _CPU_Processor_event_receive();
+    }
   }
 #else
Index: cpukit/score/src/smp.c
===================================================================
--- cpukit/score/src/smp.c	(revision 8cacceb7b9e789976c943339ab76317e8964b528)
+++ cpukit/score/src/smp.c	(revision 2f6108f93b3ee4dcc85b236593d4c57c7652bf1b)
@@ -28,78 +28,50 @@
 #endif
 
-/*
- *  Process request to switch to the first task on a secondary core.
- */
-void rtems_smp_run_first_task(int cpu)
+void rtems_smp_secondary_cpu_initialize( void )
 {
-  Thread_Control *heir;
-  ISR_Level       level;
+  int              self = bsp_smp_processor_id();
+  Per_CPU_Control *per_cpu = &_Per_CPU_Information[ self ];
+  Thread_Control  *heir;
 
-  _ISR_Disable_on_this_core( level );
+  #if defined(RTEMS_DEBUG)
+    printk( "Made it to %d -- ", self );
+  #endif
+
+  _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING );
+
+  _Per_CPU_Wait_for_state( per_cpu, PER_CPU_STATE_BEGIN_MULTITASKING );
+
+  _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_UP );
 
   /*
    *  The Scheduler will have selected the heir thread for each CPU core.
    *  Now we have been requested to perform the first context switch.  So
-   *  force a switch to the designated heir and make it executing on 
+   *  force a switch to the designated heir and make it executing on
    *  THIS core.
    */
-  heir              = _Thread_Heir;
-  _Thread_Executing = heir;
+  heir = per_cpu->heir;
+  per_cpu->executing = heir;
+
+  /*
+   * Threads begin execution in the _Thread_Handler() function.   This function
+   * will call _Thread_Enable_dispatch().
+   */
+  _Thread_Disable_dispatch();
 
   _CPU_Context_switch_to_first_task_smp( &heir->Registers );
 }
 
-void rtems_smp_secondary_cpu_initialize(void)
+void rtems_smp_process_interrupt( void )
 {
-  int       cpu;
-  ISR_Level level;
+  int              self = bsp_smp_processor_id();
+  Per_CPU_Control *per_cpu = &_Per_CPU_Information[ self ];
+  uint32_t         message;
+  ISR_Level        level;
 
-  cpu = bsp_smp_processor_id();
 
-  /*
-   *  Inform the primary CPU that this secondary CPU is initialized
-   *  and ready to dispatch to the first thread it is supposed to
-   *  execute when the primary CPU is ready.
-   */
-  _Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_INITIALIZED;
-
-  #if defined(RTEMS_DEBUG)
-    printk( "Made it to %d -- ", cpu );
-  #endif
-
-  /*
-   *  With this secondary core out of reset, we can wait for the
-   *  request to switch to the first task.
-   */
-  while(1) {
-    uint32_t   message;
-
-    bsp_smp_wait_for(
-      (volatile unsigned int *)&_Per_CPU_Information[cpu].message,
-      RTEMS_BSP_SMP_FIRST_TASK,
-      10000
-    );
-
-    level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
-      message = _Per_CPU_Information[cpu].message;
-      if ( message & RTEMS_BSP_SMP_FIRST_TASK ) {
-	_SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
-        _ISR_Set_level( 0 );
-      }
-     
-    _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
-  }
-}
-
-void rtems_smp_process_interrupt(void)
-{
-  int        cpu;
-  uint32_t   message;
-  ISR_Level  level;
-
-  cpu = bsp_smp_processor_id();
-
-  level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
-  message = _Per_CPU_Information[cpu].message;
+  level = _SMP_lock_spinlock_simple_Obtain( &per_cpu->lock );
+  message = per_cpu->message;
+  per_cpu->message = 0;
+  _SMP_lock_spinlock_simple_Release( &per_cpu->lock, level );
 
   #if defined(RTEMS_DEBUG)
@@ -107,5 +79,5 @@
       void *sp = __builtin_frame_address(0);
       if ( !(message & RTEMS_BSP_SMP_SHUTDOWN) ) {
-        printk( "ISR on CPU %d -- (0x%02x) (0x%p)\n", cpu, message, sp );
+        printk( "ISR on CPU %d -- (0x%02x) (0x%p)\n", self, message, sp );
 	if ( message & RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY )
 	  printk( "context switch necessary\n" );
@@ -114,6 +86,4 @@
 	if ( message & RTEMS_BSP_SMP_SHUTDOWN )
 	  printk( "shutdown\n" );
-	if ( message & RTEMS_BSP_SMP_FIRST_TASK )
-	  printk( "switch to first task\n" );
       }
  
@@ -122,46 +92,21 @@
   #endif
 
-  if ( message & RTEMS_BSP_SMP_FIRST_TASK ) {
-    _Per_CPU_Information[cpu].isr_nest_level = 0;
-    _Per_CPU_Information[cpu].message &= ~message;
-    _Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_UP;
+  if ( message & RTEMS_BSP_SMP_SHUTDOWN ) {
+    _ISR_Disable_on_this_core( level );
 
-    _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
+    while ( _Thread_Dispatch_decrement_disable_level() != 0 ) {
+      /* Release completely */
+    }
 
-    rtems_smp_run_first_task(cpu);
-    /* does not return */
-  }
-
-  if ( message & RTEMS_BSP_SMP_SHUTDOWN ) {
-    _Per_CPU_Information[cpu].message &= ~message;
-
-    _Per_CPU_Information[cpu].isr_nest_level = 0;
-    _Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_SHUTDOWN;
-    _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
-
-    _Thread_Enable_dispatch();       /* undo ISR code */
-    _ISR_Disable_on_this_core( level );
+    _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_SHUTDOWN );
     while(1)
       ;
     /* does not continue past here */
   }
-
-  if ( message & RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY ) {
-    #if defined(RTEMS_DEBUG)
-      printk( "switch needed\n" );
-    #endif
-    _Per_CPU_Information[cpu].message &= ~message;
-    _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
-  }
 }
 
-/*
- *  Send an interrupt processor request to another cpu.
- */
-void _SMP_Send_message(
-  int       cpu,
-  uint32_t  message
-)
+void _SMP_Send_message( int cpu, uint32_t message )
 {
+  Per_CPU_Control *per_cpu = &_Per_CPU_Information[ cpu ];
   ISR_Level level;
 
@@ -171,89 +116,81 @@
   #endif
 
-  level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
-    _Per_CPU_Information[cpu].message |= message;
-  _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
+  level = _SMP_lock_spinlock_simple_Obtain( &per_cpu->lock );
+  per_cpu->message |= message;
+  _SMP_lock_spinlock_simple_Release( &per_cpu->lock, level );
+
   bsp_smp_interrupt_cpu( cpu );
 }
 
-void _SMP_Broadcast_message(
-  uint32_t  message
-)
+void _SMP_Broadcast_message( uint32_t message )
 {
-  int        dest_cpu;
-  int        cpu;
-  ISR_Level  level;
+  int self = bsp_smp_processor_id();
+  int ncpus = _SMP_Processor_count;
+  int cpu;
 
-  cpu = bsp_smp_processor_id();
+  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
+    if ( cpu != self ) {
+      Per_CPU_Control *per_cpu = &_Per_CPU_Information[ cpu ];
+      ISR_Level level = _SMP_lock_spinlock_simple_Obtain( &per_cpu->lock );
+      per_cpu->message |= message;
+      _SMP_lock_spinlock_simple_Release( &per_cpu->lock, level );
+    }
+  }
 
-  for ( dest_cpu=0 ; dest_cpu <  _SMP_Processor_count; dest_cpu++ ) {
-    if ( cpu == dest_cpu )
-      continue;
-    level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
-      _Per_CPU_Information[dest_cpu].message |= message;
-    _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
-  }
   bsp_smp_broadcast_interrupt();
 }
 
-void _SMP_Request_other_cores_to_perform_first_context_switch(void)
+void _SMP_Request_other_cores_to_perform_first_context_switch( void )
 {
-  int    cpu;
+  int self = bsp_smp_processor_id();
+  int ncpus = _SMP_Processor_count;
+  int cpu;
 
-  _Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_UP; 
-  for (cpu=1 ; cpu < _SMP_Processor_count ; cpu++ ) {
-    _SMP_Send_message( cpu, RTEMS_BSP_SMP_FIRST_TASK );
+  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
+    if ( cpu != self ) {
+      _Per_CPU_Change_state(
+        &_Per_CPU_Information[ cpu ],
+        PER_CPU_STATE_BEGIN_MULTITASKING
+      );
+    }
   }
 }
 
-void _SMP_Request_other_cores_to_dispatch(void)
+void _SMP_Request_other_cores_to_dispatch( void )
 {
-  int i;
-  int cpu;
+  if ( _System_state_Is_up( _System_state_Get() ) ) {
+    int self = bsp_smp_processor_id();
+    int ncpus = _SMP_Processor_count;
+    int cpu;
 
-  cpu = bsp_smp_processor_id();
+    for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
+      const Per_CPU_Control *per_cpu = &_Per_CPU_Information[ cpu ];
 
-  if ( !_System_state_Is_up (_System_state_Current) )
-    return;
-  for (i=1 ; i < _SMP_Processor_count ; i++ ) {
-    if ( cpu == i )
-      continue;
-    if ( _Per_CPU_Information[i].state != RTEMS_BSP_SMP_CPU_UP )
-      continue;
-    if ( !_Per_CPU_Information[i].dispatch_necessary )
-      continue;
-    _SMP_Send_message( i, RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY );
+      if (
+        cpu != self
+          && per_cpu->state == PER_CPU_STATE_UP
+          && per_cpu->dispatch_necessary
+      ) {
+        _SMP_Send_message( cpu, RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY );
+      }
+    }
   }
 }
 
-void _SMP_Request_other_cores_to_shutdown(void)
+void _SMP_Request_other_cores_to_shutdown( void )
 {
-  bool   allDown;
-  int    ncpus;
-  int    n;
-  int    cpu;
-
-  cpu   = bsp_smp_processor_id();
-  ncpus = _SMP_Processor_count;
+  int self = bsp_smp_processor_id();
+  int ncpus = _SMP_Processor_count;
+  int cpu;
 
   _SMP_Broadcast_message( RTEMS_BSP_SMP_SHUTDOWN );
 
-  allDown = true;
-  for (n=0 ; n<ncpus ; n++ ) {
-     if ( n == cpu ) 
-       continue;
-     bsp_smp_wait_for(
-       (unsigned int *)&_Per_CPU_Information[n].state,
-       RTEMS_BSP_SMP_CPU_SHUTDOWN,
-       10000
-    );
-    if ( _Per_CPU_Information[n].state != RTEMS_BSP_SMP_CPU_SHUTDOWN )
-      allDown = false;
+  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
+    if ( cpu != self ) {
+      _Per_CPU_Wait_for_state(
+        &_Per_CPU_Information[ cpu ],
+        PER_CPU_STATE_SHUTDOWN
+      );
+    }
   }
-  if ( !allDown )
-    printk( "not all down -- timed out\n" );
-  #if defined(RTEMS_DEBUG)
-    else
-      printk( "All CPUs shutdown successfully\n" );
-  #endif
 }
