source: rtems/cpukit/score/src/smp.c @ 4fc370e

4.115
Last change on this file since 4fc370e was 4fc370e, checked in by Sebastian Huber <sebastian.huber@…>, on 06/05/13 at 10:08:23

score: Move thread dispatch content to new file

Move thread dispatch declarations and inline functions to new header
<rtems/score/threaddispatch.h> to make it independent of the
Thread_Control structure. This avoids a cyclic dependency in case
thread dispatch functions are used for the object implementation.

  • 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  _SMP_lock_ISR_disable_and_acquire( &per_cpu->lock, level );
74  message = per_cpu->message;
75  per_cpu->message = 0;
76  _SMP_lock_Release_and_ISR_enable( &per_cpu->lock, 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  _SMP_lock_ISR_disable_and_acquire( &per_cpu->lock, level );
120  per_cpu->message |= message;
121  _SMP_lock_Release_and_ISR_enable( &per_cpu->lock, 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_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      _SMP_lock_ISR_disable_and_acquire( &per_cpu->lock, level );
138      per_cpu->message |= message;
139      _SMP_lock_Release_and_ISR_enable( &per_cpu->lock, 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_Processor_count;
150  int cpu;
151
152  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
153    if ( cpu != self ) {
154      _Per_CPU_Change_state(
155        &_Per_CPU_Information[ cpu ],
156        PER_CPU_STATE_BEGIN_MULTITASKING
157      );
158    }
159  }
160}
161
162void _SMP_Request_other_cores_to_dispatch( void )
163{
164  if ( _System_state_Is_up( _System_state_Get() ) ) {
165    int self = bsp_smp_processor_id();
166    int ncpus = _SMP_Processor_count;
167    int cpu;
168
169    for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
170      const Per_CPU_Control *per_cpu = &_Per_CPU_Information[ cpu ];
171
172      if (
173        cpu != self
174          && per_cpu->state == PER_CPU_STATE_UP
175          && per_cpu->dispatch_necessary
176      ) {
177        _SMP_Send_message( cpu, RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY );
178      }
179    }
180  }
181}
182
183void _SMP_Request_other_cores_to_shutdown( void )
184{
185  int self = bsp_smp_processor_id();
186  int ncpus = _SMP_Processor_count;
187  int cpu;
188
189  _SMP_Broadcast_message( RTEMS_BSP_SMP_SHUTDOWN );
190
191  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
192    if ( cpu != self ) {
193      _Per_CPU_Wait_for_state(
194        &_Per_CPU_Information[ cpu ],
195        PER_CPU_STATE_SHUTDOWN
196      );
197    }
198  }
199}
Note: See TracBrowser for help on using the repository browser.