source: rtems/cpukit/score/src/smp.c @ 5618c37a

4.115
Last change on this file since 5618c37a was 5618c37a, checked in by Sebastian Huber <sebastian.huber@…>, on 07/24/13 at 13:14:48

score: Create thread implementation header

Move implementation specific parts of thread.h and thread.inl into new
header file threadimpl.h. The thread.h contains now only the
application visible API.

Remove superfluous header file includes from various files.

  • Property mode set to 100644
File size: 5.1 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/thread.h>
23#include <rtems/score/threaddispatch.h>
24#include <rtems/score/smp.h>
25#include <rtems/score/sysstate.h>
26
27#if defined(RTEMS_DEBUG)
28  #include <rtems/bspIo.h>
29#endif
30
31void rtems_smp_secondary_cpu_initialize( void )
32{
33  uint32_t         self = _SMP_Get_current_processor();
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  heir->is_executing = true;
55  per_cpu->executing->is_executing = false;
56  per_cpu->executing = heir;
57  per_cpu->dispatch_necessary = false;
58
59  /*
60   * Threads begin execution in the _Thread_Handler() function.   This function
61   * will call _Thread_Enable_dispatch().
62   */
63  _Thread_Disable_dispatch();
64
65  _CPU_Context_switch_to_first_task_smp( &heir->Registers );
66}
67
68void rtems_smp_process_interrupt( void )
69{
70  uint32_t         self = _SMP_Get_current_processor();
71  Per_CPU_Control *per_cpu = &_Per_CPU_Information[ self ];
72
73
74  if ( per_cpu->message != 0 ) {
75    uint32_t  message;
76    ISR_Level level;
77
78    _Per_CPU_Lock_acquire( per_cpu, level );
79    message = per_cpu->message;
80    per_cpu->message = 0;
81    _Per_CPU_Lock_release( per_cpu, level );
82
83    #if defined(RTEMS_DEBUG)
84      {
85        void *sp = __builtin_frame_address(0);
86        if ( !(message & RTEMS_BSP_SMP_SHUTDOWN) ) {
87          printk( "ISR on CPU %d -- (0x%02x) (0x%p)\n", self, message, sp );
88          if ( message & RTEMS_BSP_SMP_SIGNAL_TO_SELF )
89            printk( "signal to self\n" );
90          if ( message & RTEMS_BSP_SMP_SHUTDOWN )
91            printk( "shutdown\n" );
92        }
93        printk( "Dispatch level %d\n", _Thread_Dispatch_get_disable_level() );
94      }
95    #endif
96
97    if ( ( message & RTEMS_BSP_SMP_SHUTDOWN ) != 0 ) {
98      _ISR_Disable_on_this_core( level );
99
100      _Thread_Dispatch_set_disable_level( 0 );
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}
109
110void _SMP_Send_message( uint32_t cpu, uint32_t message )
111{
112  Per_CPU_Control *per_cpu = &_Per_CPU_Information[ cpu ];
113  ISR_Level level;
114
115  #if defined(RTEMS_DEBUG)
116    if ( message & RTEMS_BSP_SMP_SIGNAL_TO_SELF )
117      printk( "Send 0x%x to %d\n", message, cpu );
118  #endif
119
120  _Per_CPU_Lock_acquire( per_cpu, level );
121  per_cpu->message |= message;
122  _Per_CPU_Lock_release( per_cpu, level );
123
124  _CPU_SMP_Send_interrupt( cpu );
125}
126
127void _SMP_Broadcast_message( uint32_t message )
128{
129  uint32_t self = _SMP_Get_current_processor();
130  uint32_t ncpus = _SMP_Get_processor_count();
131  uint32_t cpu;
132
133  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
134    if ( cpu != self ) {
135      Per_CPU_Control *per_cpu = &_Per_CPU_Information[ cpu ];
136      ISR_Level level;
137
138      _Per_CPU_Lock_acquire( per_cpu, level );
139      per_cpu->message |= message;
140      _Per_CPU_Lock_release( per_cpu, level );
141    }
142  }
143
144  bsp_smp_broadcast_interrupt();
145}
146
147void _SMP_Request_other_cores_to_perform_first_context_switch( void )
148{
149  uint32_t self = _SMP_Get_current_processor();
150  uint32_t ncpus = _SMP_Get_processor_count();
151  uint32_t cpu;
152
153  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
154    Per_CPU_Control *per_cpu = &_Per_CPU_Information[ cpu ];
155
156    if ( cpu != self ) {
157      _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_BEGIN_MULTITASKING );
158    } else {
159
160      _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_UP );
161    }
162  }
163}
164
165void _SMP_Request_other_cores_to_dispatch( void )
166{
167  if ( _System_state_Is_up( _System_state_Get() ) ) {
168    uint32_t self = _SMP_Get_current_processor();
169    uint32_t ncpus = _SMP_Get_processor_count();
170    uint32_t cpu;
171
172    for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
173      const Per_CPU_Control *per_cpu = &_Per_CPU_Information[ cpu ];
174
175      if (
176        cpu != self
177          && per_cpu->state == PER_CPU_STATE_UP
178          && per_cpu->dispatch_necessary
179      ) {
180        _SMP_Send_message( cpu, 0 );
181      }
182    }
183  }
184}
185
186void _SMP_Request_other_cores_to_shutdown( void )
187{
188  uint32_t self = _SMP_Get_current_processor();
189  uint32_t ncpus = _SMP_Get_processor_count();
190  uint32_t cpu;
191
192  _SMP_Broadcast_message( RTEMS_BSP_SMP_SHUTDOWN );
193
194  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
195    if ( cpu != self ) {
196      _Per_CPU_Wait_for_state(
197        &_Per_CPU_Information[ cpu ],
198        PER_CPU_STATE_SHUTDOWN
199      );
200    }
201  }
202}
Note: See TracBrowser for help on using the repository browser.