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

4.11
Last change on this file since 8f42092 was edde99b, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 14, 2013 at 12:26:34 PM

score: Rename rtems_smp_get_number_of_processors()

Rename in rtems_smp_get_processor_count(). Always provide
<rtems/score/smp.h> and <rtems/rtems/smp.h>. Add
_SMP_Get_processor_count(). This function will be a compile time
constant defined to be one on uni-processor configurations. This allows
iterations over all processors without overhead on uni-processor
configurations.

  • Property mode set to 100644
File size: 5.0 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/system.h>
22#include <rtems/bspsmp.h>
23#include <rtems/score/smp.h>
24#include <rtems/score/thread.h>
25#include <rtems/score/threaddispatch.h>
26
27#if defined(RTEMS_DEBUG)
28  #include <rtems/bspIo.h>
29#endif
30
31void rtems_smp_secondary_cpu_initialize( void )
32{
33  int              self = bsp_smp_processor_id();
34  Per_CPU_Control *per_cpu = &_Per_CPU_Information[ self ];
35  Thread_Control  *heir;
36
37  #if defined(RTEMS_DEBUG)
38    printk( "Made it to %d -- ", self );
39  #endif
40
41  _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING );
42
43  _Per_CPU_Wait_for_state( per_cpu, PER_CPU_STATE_BEGIN_MULTITASKING );
44
45  _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_UP );
46
47  /*
48   *  The Scheduler will have selected the heir thread for each CPU core.
49   *  Now we have been requested to perform the first context switch.  So
50   *  force a switch to the designated heir and make it executing on
51   *  THIS core.
52   */
53  heir = per_cpu->heir;
54  per_cpu->executing = heir;
55
56  /*
57   * Threads begin execution in the _Thread_Handler() function.   This function
58   * will call _Thread_Enable_dispatch().
59   */
60  _Thread_Disable_dispatch();
61
62  _CPU_Context_switch_to_first_task_smp( &heir->Registers );
63}
64
65void rtems_smp_process_interrupt( void )
66{
67  int              self = bsp_smp_processor_id();
68  Per_CPU_Control *per_cpu = &_Per_CPU_Information[ self ];
69  uint32_t         message;
70  ISR_Level        level;
71
72
73  _Per_CPU_Lock_acquire( per_cpu, level );
74  message = per_cpu->message;
75  per_cpu->message = 0;
76  _Per_CPU_Lock_release( per_cpu, level );
77
78  #if defined(RTEMS_DEBUG)
79    {
80      void *sp = __builtin_frame_address(0);
81      if ( !(message & RTEMS_BSP_SMP_SHUTDOWN) ) {
82        printk( "ISR on CPU %d -- (0x%02x) (0x%p)\n", self, message, sp );
83        if ( message & RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY )
84          printk( "context switch necessary\n" );
85        if ( message & RTEMS_BSP_SMP_SIGNAL_TO_SELF )
86          printk( "signal to self\n" );
87        if ( message & RTEMS_BSP_SMP_SHUTDOWN )
88          printk( "shutdown\n" );
89      }
90 
91      printk( "Dispatch level %d\n", _Thread_Dispatch_get_disable_level() );
92    }
93  #endif
94
95  if ( message & RTEMS_BSP_SMP_SHUTDOWN ) {
96    _ISR_Disable_on_this_core( level );
97
98    while ( _Thread_Dispatch_decrement_disable_level() != 0 ) {
99      /* Release completely */
100    }
101
102    _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_SHUTDOWN );
103
104    _CPU_Fatal_halt( self );
105    /* does not continue past here */
106  }
107}
108
109void _SMP_Send_message( int cpu, uint32_t message )
110{
111  Per_CPU_Control *per_cpu = &_Per_CPU_Information[ cpu ];
112  ISR_Level level;
113
114  #if defined(RTEMS_DEBUG)
115    if ( message & RTEMS_BSP_SMP_SIGNAL_TO_SELF )
116      printk( "Send 0x%x to %d\n", message, cpu );
117  #endif
118
119  _Per_CPU_Lock_acquire( per_cpu, level );
120  per_cpu->message |= message;
121  _Per_CPU_Lock_release( per_cpu, level );
122
123  bsp_smp_interrupt_cpu( cpu );
124}
125
126void _SMP_Broadcast_message( uint32_t message )
127{
128  int self = bsp_smp_processor_id();
129  int ncpus = _SMP_Get_processor_count();
130  int cpu;
131
132  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
133    if ( cpu != self ) {
134      Per_CPU_Control *per_cpu = &_Per_CPU_Information[ cpu ];
135      ISR_Level level;
136
137      _Per_CPU_Lock_acquire( per_cpu, level );
138      per_cpu->message |= message;
139      _Per_CPU_Lock_release( per_cpu, level );
140    }
141  }
142
143  bsp_smp_broadcast_interrupt();
144}
145
146void _SMP_Request_other_cores_to_perform_first_context_switch( void )
147{
148  int self = bsp_smp_processor_id();
149  int ncpus = _SMP_Get_processor_count();
150  int cpu;
151
152  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
153    Per_CPU_Control *per_cpu = &_Per_CPU_Information[ cpu ];
154
155    if ( cpu != self ) {
156      _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_BEGIN_MULTITASKING );
157    } else {
158
159      _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_UP );
160    }
161  }
162}
163
164void _SMP_Request_other_cores_to_dispatch( void )
165{
166  if ( _System_state_Is_up( _System_state_Get() ) ) {
167    int self = bsp_smp_processor_id();
168    int ncpus = _SMP_Get_processor_count();
169    int cpu;
170
171    for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
172      const Per_CPU_Control *per_cpu = &_Per_CPU_Information[ cpu ];
173
174      if (
175        cpu != self
176          && per_cpu->state == PER_CPU_STATE_UP
177          && per_cpu->dispatch_necessary
178      ) {
179        _SMP_Send_message( cpu, RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY );
180      }
181    }
182  }
183}
184
185void _SMP_Request_other_cores_to_shutdown( void )
186{
187  int self = bsp_smp_processor_id();
188  int ncpus = _SMP_Get_processor_count();
189  int cpu;
190
191  _SMP_Broadcast_message( RTEMS_BSP_SMP_SHUTDOWN );
192
193  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
194    if ( cpu != self ) {
195      _Per_CPU_Wait_for_state(
196        &_Per_CPU_Information[ cpu ],
197        PER_CPU_STATE_SHUTDOWN
198      );
199    }
200  }
201}
Note: See TracBrowser for help on using the repository browser.