source: rtems/cpukit/score/src/smp.c @ 2cb95b5f

4.115
Last change on this file since 2cb95b5f was 2cb95b5f, checked in by Sebastian Huber <sebastian.huber@…>, on 02/17/14 at 12:58:01

score: Rename RTEMS_BSP_SMP_SHUTDOWN

Rename RTEMS_BSP_SMP_SHUTDOWN in SMP_MESSAGE_SHUTDOWN since SMP messages
have nothing to do with the BSP. Use UINT32_C() instead of casts.

  • 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#include <rtems/fatal.h>
27
28#if defined(RTEMS_DEBUG)
29  #include <rtems/bspIo.h>
30#endif
31
32void rtems_smp_secondary_cpu_initialize( void )
33{
34  Per_CPU_Control *self_cpu = _Per_CPU_Get();
35
36  #if defined(RTEMS_DEBUG)
37    printk( "Made it to %d -- ", _Per_CPU_Get_index( self_cpu ) );
38  #endif
39
40  _Per_CPU_Change_state( self_cpu, PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING );
41
42  _Per_CPU_Wait_for_state( self_cpu, PER_CPU_STATE_BEGIN_MULTITASKING );
43
44  _Thread_Start_multitasking();
45}
46
47void rtems_smp_process_interrupt( void )
48{
49  Per_CPU_Control *self_cpu = _Per_CPU_Get();
50
51
52  if ( self_cpu->message != 0 ) {
53    uint32_t  message;
54    ISR_Level level;
55
56    _Per_CPU_ISR_disable_and_acquire( self_cpu, level );
57    message = self_cpu->message;
58    self_cpu->message = 0;
59    _Per_CPU_Release_and_ISR_enable( self_cpu, level );
60
61    #if defined(RTEMS_DEBUG)
62      {
63        void *sp = __builtin_frame_address(0);
64        if ( !(message & SMP_MESSAGE_SHUTDOWN) ) {
65          printk(
66            "ISR on CPU %d -- (0x%02x) (0x%p)\n",
67            _Per_CPU_Get_index( self_cpu ),
68            message,
69            sp
70          );
71          if ( message & SMP_MESSAGE_SHUTDOWN )
72            printk( "shutdown\n" );
73        }
74        printk( "Dispatch level %d\n", _Thread_Dispatch_get_disable_level() );
75      }
76    #endif
77
78    if ( ( message & SMP_MESSAGE_SHUTDOWN ) != 0 ) {
79      _Per_CPU_Change_state( self_cpu, PER_CPU_STATE_SHUTDOWN );
80
81      rtems_fatal( RTEMS_FATAL_SOURCE_SMP, SMP_FATAL_SHUTDOWN );
82      /* does not continue past here */
83    }
84  }
85}
86
87void _SMP_Send_message( uint32_t cpu, uint32_t message )
88{
89  Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
90  ISR_Level level;
91
92  _Per_CPU_ISR_disable_and_acquire( per_cpu, level );
93  per_cpu->message |= message;
94  _Per_CPU_Release_and_ISR_enable( per_cpu, level );
95
96  _CPU_SMP_Send_interrupt( cpu );
97}
98
99void _SMP_Broadcast_message( uint32_t message )
100{
101  uint32_t self = _SMP_Get_current_processor();
102  uint32_t ncpus = _SMP_Get_processor_count();
103  uint32_t cpu;
104
105  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
106    if ( cpu != self ) {
107      Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
108      ISR_Level level;
109
110      _Per_CPU_ISR_disable_and_acquire( per_cpu, level );
111      per_cpu->message |= message;
112      _Per_CPU_Release_and_ISR_enable( per_cpu, level );
113    }
114  }
115
116  bsp_smp_broadcast_interrupt();
117}
118
119void _SMP_Request_other_cores_to_perform_first_context_switch( void )
120{
121  uint32_t self = _SMP_Get_current_processor();
122  uint32_t ncpus = _SMP_Get_processor_count();
123  uint32_t cpu;
124
125  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
126    Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
127
128    if ( cpu != self ) {
129      _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_BEGIN_MULTITASKING );
130    }
131  }
132}
133
134void _SMP_Request_other_cores_to_shutdown( void )
135{
136  uint32_t self = _SMP_Get_current_processor();
137
138  /*
139   * Do not use _SMP_Get_processor_count() since this value might be not
140   * initialized yet.  For example due to a fatal error in the middle of
141   * bsp_smp_initialize().
142   */
143  uint32_t ncpus = rtems_configuration_get_maximum_processors();
144
145  uint32_t cpu;
146
147  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
148    if ( cpu != self ) {
149      const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
150
151      if ( per_cpu->state != PER_CPU_STATE_BEFORE_INITIALIZATION ) {
152        _SMP_Send_message( cpu, SMP_MESSAGE_SHUTDOWN );
153      }
154    }
155  }
156}
Note: See TracBrowser for help on using the repository browser.