source: rtems/cpukit/score/src/smp.c @ 0d5a9f1

4.115
Last change on this file since 0d5a9f1 was 0d5a9f1, checked in by Jennifer Averett <Jennifer.Averett@…>, on 04/27/11 at 17:18:59

2011-04-27 Jennifer Averett <Jennifer.Averett@…>

PR 1784

  • sapi/src/exinit.c, score/Makefile.am, score/preinstall.am, score/include/rtems/bspsmp.h, score/src/percpu.c, score/src/smp.c, score/src/threadcreateidle.c: Split bspsmp.h into two files smp.h and bspsmp.h
  • score/include/rtems/score/smp.h: New file.
  • Property mode set to 100644
File size: 3.8 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2011.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.com/license/LICENSE.
8 *
9 *  $Id$
10 */
11
12#if HAVE_CONFIG_H
13#include "config.h"
14#endif
15
16#include <rtems/system.h>
17#include <rtems/bspsmp.h>
18#include <rtems/score/smp.h>
19#include <rtems/score/thread.h>
20
21#if defined(RTEMS_SMP)
22#define SMP_DEBUG
23
24#if defined(SMP_DEBUG)
25  #include <rtems/bspIo.h>
26#endif
27
28void rtems_smp_run_first_task(int cpu)
29{
30  Thread_Control *heir;
31
32  /*
33   *  This CPU has an heir thread so we need to dispatch it.
34   */
35  heir = _Thread_Heir;
36
37  /*
38   *  This is definitely a hack until we have SMP scheduling.  Since there
39   *  is only one executing and heir right now, we have to fake this out.
40   */
41  _Thread_Dispatch_set_disable_level(1);
42  _Thread_Executing = heir;
43  _CPU_Context_switch_to_first_task_smp( &heir->Registers );
44}
45
46void rtems_smp_secondary_cpu_initialize(void)
47{
48  int cpu;
49
50  cpu = bsp_smp_processor_id();
51
52  bsp_smp_secondary_cpu_initialize(cpu);
53
54  #if defined(SMP_DEBUG)
55    printk( "Made it to %d -- ", cpu );
56  #endif
57
58  /*
59   *  Inform the primary CPU that this secondary CPU is initialized
60   *  and ready to dispatch to the first thread it is supposed to
61   *  execute when the primary CPU is ready.
62   */
63  _Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_INITIALIZED;
64
65  /*
66   *  HACK: Should not have to enable interrupts in real system here.
67   *        It should happen as part of switching to the first task.
68   */
69   
70  _Per_CPU_Information[cpu].isr_nest_level = 1;
71  _ISR_Set_level( 0 );
72  while(1) ;
73}
74
75void rtems_smp_process_interrupt(void)
76{
77  int        cpu;
78  uint32_t   message;
79  ISR_Level  level;
80
81  cpu = bsp_smp_processor_id();
82
83  level = _SMP_lock_Spinlock_Obtain( &_Per_CPU_Information[cpu].lock );
84    message = _Per_CPU_Information[cpu].message;
85    _Per_CPU_Information[cpu].message &= ~message;
86  _SMP_lock_Spinlock_Release( &_Per_CPU_Information[cpu].lock, level );
87
88  #if defined(SMP_DEBUG)
89    {
90      void *sp = __builtin_frame_address(0);
91      if ( !(message & RTEMS_BSP_SMP_SHUTDOWN) )
92        printk( "ISR on CPU %d -- (0x%02x) (0x%p)\n", cpu, message, sp );
93      printk( "Dispatch level %d\n", _Thread_Dispatch_disable_level );
94    }
95  #endif
96
97  if ( message & RTEMS_BSP_SMP_FIRST_TASK ) {
98    _Per_CPU_Information[cpu].isr_nest_level = 0;
99    _Per_CPU_Information[cpu].message = 0;
100    _Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_INITIALIZED;
101    rtems_smp_run_first_task(cpu);
102    /* does not return */
103  }
104
105  if ( message & RTEMS_BSP_SMP_SHUTDOWN ) {
106    ISR_Level level;
107    _Thread_Dispatch_set_disable_level(0);
108    _Per_CPU_Information[cpu].isr_nest_level = 0;
109    _Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_SHUTDOWN;
110    _ISR_Disable( level );
111    while(1)
112      ;
113    /* does not continue past here */
114  }
115
116  if ( message & RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY ) {
117    printk( "switch needed\n" );
118    _Per_CPU_Information[cpu].dispatch_necessary = true;
119  }
120}
121
122void rtems_smp_send_message(
123  int       cpu,
124  uint32_t  message
125)
126{
127  ISR_Level level;
128
129  level = _SMP_lock_Spinlock_Obtain( &_Per_CPU_Information[cpu].lock );
130    _Per_CPU_Information[cpu].message |= message;
131  _SMP_lock_Spinlock_Release( &_Per_CPU_Information[cpu].lock, level );
132  bsp_smp_interrupt_cpu( cpu );
133}
134
135void rtems_smp_broadcast_message(
136  uint32_t  message
137)
138{
139  int        dest_cpu;
140  int        cpu;
141  ISR_Level  level;
142
143  cpu = bsp_smp_processor_id();
144
145  for ( dest_cpu=0 ; dest_cpu <  _SMP_Processor_count; dest_cpu++ ) {
146    if ( cpu == dest_cpu )
147      continue;
148    level = _SMP_lock_Spinlock_Obtain( &_Per_CPU_Information[cpu].lock );
149      _Per_CPU_Information[dest_cpu].message |= message;
150    _SMP_lock_Spinlock_Release( &_Per_CPU_Information[cpu].lock, level );
151  }
152  bsp_smp_broadcast_interrupt();
153}
154#endif
Note: See TracBrowser for help on using the repository browser.