source: rtems/cpukit/score/src/smp.c @ 7045dc4

4.115
Last change on this file since 7045dc4 was 7045dc4, checked in by Sebastian Huber <sebastian.huber@…>, on 08/01/13 at 07:17:51

smp: Use ISR lock in per-CPU control

Rename _Per_CPU_Lock_acquire() to _Per_CPU_ISR_disable_and_acquire().
Rename _Per_CPU_Lock_release() to _Per_CPU_Release_and_ISR_enable().

Add _Per_CPU_Acquire() and _Per_CPU_Release().

  • 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/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  Per_CPU_Control *self_cpu = _Per_CPU_Get();
34  Thread_Control  *heir;
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( NULL );
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 & RTEMS_BSP_SMP_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 & RTEMS_BSP_SMP_SIGNAL_TO_SELF )
72            printk( "signal to self\n" );
73          if ( message & RTEMS_BSP_SMP_SHUTDOWN )
74            printk( "shutdown\n" );
75        }
76        printk( "Dispatch level %d\n", _Thread_Dispatch_get_disable_level() );
77      }
78    #endif
79
80    if ( ( message & RTEMS_BSP_SMP_SHUTDOWN ) != 0 ) {
81      _ISR_Disable( level );
82
83      _Thread_Dispatch_set_disable_level( 0 );
84
85      _Per_CPU_Change_state( self_cpu, PER_CPU_STATE_SHUTDOWN );
86
87      _CPU_Fatal_halt( _Per_CPU_Get_index( self_cpu ) );
88      /* does not continue past here */
89    }
90  }
91}
92
93void _SMP_Send_message( uint32_t cpu, uint32_t message )
94{
95  Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
96  ISR_Level level;
97
98  #if defined(RTEMS_DEBUG)
99    if ( message & RTEMS_BSP_SMP_SIGNAL_TO_SELF )
100      printk( "Send 0x%x to %d\n", message, cpu );
101  #endif
102
103  _Per_CPU_ISR_disable_and_acquire( per_cpu, level );
104  per_cpu->message |= message;
105  _Per_CPU_Release_and_ISR_enable( per_cpu, level );
106
107  _CPU_SMP_Send_interrupt( cpu );
108}
109
110void _SMP_Broadcast_message( uint32_t message )
111{
112  uint32_t self = _SMP_Get_current_processor();
113  uint32_t ncpus = _SMP_Get_processor_count();
114  uint32_t cpu;
115
116  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
117    if ( cpu != self ) {
118      Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
119      ISR_Level level;
120
121      _Per_CPU_ISR_disable_and_acquire( per_cpu, level );
122      per_cpu->message |= message;
123      _Per_CPU_Release_and_ISR_enable( per_cpu, level );
124    }
125  }
126
127  bsp_smp_broadcast_interrupt();
128}
129
130void _SMP_Request_other_cores_to_perform_first_context_switch( void )
131{
132  uint32_t self = _SMP_Get_current_processor();
133  uint32_t ncpus = _SMP_Get_processor_count();
134  uint32_t cpu;
135
136  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
137    Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
138
139    if ( cpu != self ) {
140      _Per_CPU_Change_state( per_cpu, PER_CPU_STATE_BEGIN_MULTITASKING );
141    }
142  }
143}
144
145void _SMP_Request_other_cores_to_shutdown( void )
146{
147  uint32_t self = _SMP_Get_current_processor();
148  uint32_t ncpus = _SMP_Get_processor_count();
149  uint32_t cpu;
150
151  _SMP_Broadcast_message( RTEMS_BSP_SMP_SHUTDOWN );
152
153  for ( cpu = 0 ; cpu < ncpus ; ++cpu ) {
154    if ( cpu != self ) {
155      _Per_CPU_Wait_for_state(
156        _Per_CPU_Get_by_index( cpu ),
157        PER_CPU_STATE_SHUTDOWN
158      );
159    }
160  }
161}
Note: See TracBrowser for help on using the repository browser.