source: rtems/cpukit/score/src/smp.c @ 8a6de83

4.115
Last change on this file since 8a6de83 was 8a6de83, checked in by Sebastian Huber <sebastian.huber@…>, on 02/17/14 at 09:10:27

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.

  • Property mode set to 100644
File size: 3.9 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief SMP Support
5 *  @ingroup Score
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2011.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.com/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/bspsmp.h>
22#include <rtems/score/threaddispatch.h>
23#include <rtems/score/threadimpl.h>
24#include <rtems/score/smp.h>
25#include <rtems/config.h>
26
27#if defined(RTEMS_DEBUG)
28  #include <rtems/bspIo.h>
29#endif
30
31void rtems_smp_secondary_cpu_initialize( void )
32{
33  Per_CPU_Control *self_cpu = _Per_CPU_Get();
34
35  #if defined(RTEMS_DEBUG)
36    printk( "Made it to %d -- ", _Per_CPU_Get_index( self_cpu ) );
37  #endif
38
39  _Per_CPU_Change_state( self_cpu, PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING );
40
41  _Per_CPU_Wait_for_state( self_cpu, PER_CPU_STATE_BEGIN_MULTITASKING );
42
43  _Thread_Start_multitasking();
44}
45
46void rtems_smp_process_interrupt( void )
47{
48  Per_CPU_Control *self_cpu = _Per_CPU_Get();
49
50
51  if ( self_cpu->message != 0 ) {
52    uint32_t  message;
53    ISR_Level level;
54
55    _Per_CPU_ISR_disable_and_acquire( self_cpu, level );
56    message = self_cpu->message;
57    self_cpu->message = 0;
58    _Per_CPU_Release_and_ISR_enable( self_cpu, level );
59
60    #if defined(RTEMS_DEBUG)
61      {
62        void *sp = __builtin_frame_address(0);
63        if ( !(message & RTEMS_BSP_SMP_SHUTDOWN) ) {
64          printk(
65            "ISR on CPU %d -- (0x%02x) (0x%p)\n",
66            _Per_CPU_Get_index( self_cpu ),
67            message,
68            sp
69          );
70          if ( message & RTEMS_BSP_SMP_SHUTDOWN )
71            printk( "shutdown\n" );
72        }
73        printk( "Dispatch level %d\n", _Thread_Dispatch_get_disable_level() );
74      }
75    #endif
76
77    if ( ( message & RTEMS_BSP_SMP_SHUTDOWN ) != 0 ) {
78      _ISR_Disable_without_giant( level );
79
80      _Thread_Dispatch_set_disable_level( 0 );
81
82      _Per_CPU_Change_state( self_cpu, PER_CPU_STATE_SHUTDOWN );
83
84      _CPU_Fatal_halt( _Per_CPU_Get_index( self_cpu ) );
85      /* does not continue past here */
86    }
87  }
88}
89
90void _SMP_Send_message( uint32_t cpu, uint32_t message )
91{
92  Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
93  ISR_Level level;
94
95  _Per_CPU_ISR_disable_and_acquire( per_cpu, level );
96  per_cpu->message |= message;
97  _Per_CPU_Release_and_ISR_enable( per_cpu, level );
98
99  _CPU_SMP_Send_interrupt( cpu );
100}
101
102void _SMP_Broadcast_message( uint32_t message )
103{
104  uint32_t self = _SMP_Get_current_processor();
105  uint32_t ncpus = _SMP_Get_processor_count();
106  uint32_t cpu;
107
108  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
109    if ( cpu != self ) {
110      Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
111      ISR_Level level;
112
113      _Per_CPU_ISR_disable_and_acquire( per_cpu, level );
114      per_cpu->message |= message;
115      _Per_CPU_Release_and_ISR_enable( per_cpu, level );
116    }
117  }
118
119  bsp_smp_broadcast_interrupt();
120}
121
122void _SMP_Request_other_cores_to_perform_first_context_switch( void )
123{
124  uint32_t self = _SMP_Get_current_processor();
125  uint32_t ncpus = _SMP_Get_processor_count();
126  uint32_t cpu;
127
128  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
129    Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
130
131    if ( cpu != self ) {
132      _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_BEGIN_MULTITASKING );
133    }
134  }
135}
136
137void _SMP_Request_other_cores_to_shutdown( void )
138{
139  uint32_t self = _SMP_Get_current_processor();
140
141  /*
142   * Do not use _SMP_Get_processor_count() since this value might be not
143   * initialized yet.  For example due to a fatal error in the middle of
144   * bsp_smp_initialize().
145   */
146  uint32_t ncpus = rtems_configuration_get_maximum_processors();
147
148  uint32_t cpu;
149
150  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
151    if ( cpu != self ) {
152      const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
153
154      if ( per_cpu->state != PER_CPU_STATE_BEFORE_INITIALIZATION ) {
155        _SMP_Send_message( cpu, RTEMS_BSP_SMP_SHUTDOWN );
156      }
157    }
158  }
159}
Note: See TracBrowser for help on using the repository browser.