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

4.115
Last change on this file since 8f420927 was edde99b, checked in by Sebastian Huber <sebastian.huber@…>, on 06/14/13 at 12:26:34

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
RevLine 
[e655f7e]1/**
2 *  @file
3 *
4 *  @brief SMP Support
5 *  @ingroup Score
6 */
7
[06dcaf0]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>
[0d5a9f1]23#include <rtems/score/smp.h>
[06dcaf0]24#include <rtems/score/thread.h>
[4fc370e]25#include <rtems/score/threaddispatch.h>
[06dcaf0]26
[d4dc7c8]27#if defined(RTEMS_DEBUG)
[06dcaf0]28  #include <rtems/bspIo.h>
29#endif
30
[2f6108f9]31void rtems_smp_secondary_cpu_initialize( void )
[06dcaf0]32{
[2f6108f9]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 );
[dad36c52]44
[2f6108f9]45  _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_UP );
[06dcaf0]46
47  /*
[d4dc7c8]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
[2f6108f9]50   *  force a switch to the designated heir and make it executing on
[d4dc7c8]51   *  THIS core.
[06dcaf0]52   */
[2f6108f9]53  heir = per_cpu->heir;
54  per_cpu->executing = heir;
[06dcaf0]55
56  /*
[2f6108f9]57   * Threads begin execution in the _Thread_Handler() function.   This function
58   * will call _Thread_Enable_dispatch().
[06dcaf0]59   */
[2f6108f9]60  _Thread_Disable_dispatch();
[dad36c52]61
[2f6108f9]62  _CPU_Context_switch_to_first_task_smp( &heir->Registers );
[06dcaf0]63}
64
[2f6108f9]65void rtems_smp_process_interrupt( void )
[06dcaf0]66{
[2f6108f9]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;
[06dcaf0]71
72
[a8ef3bf0]73  _Per_CPU_Lock_acquire( per_cpu, level );
[2f6108f9]74  message = per_cpu->message;
75  per_cpu->message = 0;
[a8ef3bf0]76  _Per_CPU_Lock_release( per_cpu, level );
[06dcaf0]77
[d4dc7c8]78  #if defined(RTEMS_DEBUG)
[06dcaf0]79    {
80      void *sp = __builtin_frame_address(0);
[d4dc7c8]81      if ( !(message & RTEMS_BSP_SMP_SHUTDOWN) ) {
[2f6108f9]82        printk( "ISR on CPU %d -- (0x%02x) (0x%p)\n", self, message, sp );
[d4dc7c8]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() );
[06dcaf0]92    }
93  #endif
94
95  if ( message & RTEMS_BSP_SMP_SHUTDOWN ) {
[2f6108f9]96    _ISR_Disable_on_this_core( level );
[d4dc7c8]97
[2f6108f9]98    while ( _Thread_Dispatch_decrement_disable_level() != 0 ) {
99      /* Release completely */
100    }
[dad36c52]101
[2f6108f9]102    _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_SHUTDOWN );
[3148438]103
104    _CPU_Fatal_halt( self );
[06dcaf0]105    /* does not continue past here */
106  }
107}
108
[2f6108f9]109void _SMP_Send_message( int cpu, uint32_t message )
[06dcaf0]110{
[2f6108f9]111  Per_CPU_Control *per_cpu = &_Per_CPU_Information[ cpu ];
[06dcaf0]112  ISR_Level level;
113
[dad36c52]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
[a8ef3bf0]119  _Per_CPU_Lock_acquire( per_cpu, level );
[2f6108f9]120  per_cpu->message |= message;
[a8ef3bf0]121  _Per_CPU_Lock_release( per_cpu, level );
[2f6108f9]122
[06dcaf0]123  bsp_smp_interrupt_cpu( cpu );
124}
125
[2f6108f9]126void _SMP_Broadcast_message( uint32_t message )
[06dcaf0]127{
[2f6108f9]128  int self = bsp_smp_processor_id();
[edde99b]129  int ncpus = _SMP_Get_processor_count();
[2f6108f9]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 ];
[e358088]135      ISR_Level level;
136
[a8ef3bf0]137      _Per_CPU_Lock_acquire( per_cpu, level );
[2f6108f9]138      per_cpu->message |= message;
[a8ef3bf0]139      _Per_CPU_Lock_release( per_cpu, level );
[2f6108f9]140    }
[06dcaf0]141  }
[2f6108f9]142
[06dcaf0]143  bsp_smp_broadcast_interrupt();
144}
[d4dc7c8]145
[2f6108f9]146void _SMP_Request_other_cores_to_perform_first_context_switch( void )
[d4dc7c8]147{
[2f6108f9]148  int self = bsp_smp_processor_id();
[edde99b]149  int ncpus = _SMP_Get_processor_count();
[2f6108f9]150  int cpu;
[d4dc7c8]151
[2f6108f9]152  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
[7cf2ec6f]153    Per_CPU_Control *per_cpu = &_Per_CPU_Information[ cpu ];
154
[2f6108f9]155    if ( cpu != self ) {
[7cf2ec6f]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 );
[2f6108f9]160    }
[d4dc7c8]161  }
162}
163
[2f6108f9]164void _SMP_Request_other_cores_to_dispatch( void )
[d4dc7c8]165{
[2f6108f9]166  if ( _System_state_Is_up( _System_state_Get() ) ) {
167    int self = bsp_smp_processor_id();
[edde99b]168    int ncpus = _SMP_Get_processor_count();
[2f6108f9]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    }
[d4dc7c8]182  }
183}
184
[2f6108f9]185void _SMP_Request_other_cores_to_shutdown( void )
[d4dc7c8]186{
[2f6108f9]187  int self = bsp_smp_processor_id();
[edde99b]188  int ncpus = _SMP_Get_processor_count();
[2f6108f9]189  int cpu;
[d4dc7c8]190
191  _SMP_Broadcast_message( RTEMS_BSP_SMP_SHUTDOWN );
192
[2f6108f9]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    }
[d4dc7c8]200  }
201}
Note: See TracBrowser for help on using the repository browser.