Changeset d4dc7c8 in rtems


Ignore:
Timestamp:
May 26, 2011, 6:07:07 PM (8 years ago)
Author:
Jennifer Averett <Jennifer.Averett@…>
Branches:
4.11, master
Children:
f3aa15c
Parents:
27f09f17
Message:

2011-05-26 Jennifer Averett <Jennifer.Averett@…>

PR 1796/cpukit

  • sapi/src/exshutdown.c, score/include/rtems/score/percpu.h, score/include/rtems/score/smp.h, score/src/smp.c, score/src/threaddispatch.c, score/src/threadhandler.c: Added SMP interprocess communications.
Location:
cpukit
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • cpukit/ChangeLog

    r27f09f17 rd4dc7c8  
     12011-05-26      Jennifer Averett <Jennifer.Averett@OARcorp.com>
     2
     3        PR 1796/cpukit
     4        * sapi/src/exshutdown.c, score/include/rtems/score/percpu.h,
     5        score/include/rtems/score/smp.h, score/src/smp.c,
     6        score/src/threaddispatch.c, score/src/threadhandler.c: Added SMP
     7        interprocess communications.
     8
    192011-05-24      Ralf Corsépius <ralf.corsepius@rtems.org>
    210
  • cpukit/sapi/src/exshutdown.c

    r27f09f17 rd4dc7c8  
    22 *  Initialization Manager
    33 *
    4  *  COPYRIGHT (c) 1989-1999.
     4 *  COPYRIGHT (c) 1989-2011.
    55 *  On-Line Applications Research Corporation (OAR).
    66 *
     
    2121#include <rtems/score/interr.h>
    2222
     23#if defined(RTEMS_SMP)
     24  #include <rtems/score/smp.h>
     25#endif
     26
    2327/*
    2428 *  rtems_shutdown_executive
     
    3842{
    3943  if ( _System_state_Is_up( _System_state_Get() ) ) {
     44    #if defined(RTEMS_SMP)
     45      _SMP_Request_other_cores_to_shutdown();
     46    #endif
    4047    _System_state_Set( SYSTEM_STATE_SHUTDOWN );
    4148    _Thread_Stop_multitasking();
  • cpukit/score/include/rtems/score/percpu.h

    r27f09f17 rd4dc7c8  
    8080  /**
    8181   *  This defines the constant used to indicate that the cpu code has
     82   *  completed basic initialization and awaits further commands.
     83   */
     84  RTEMS_BSP_SMP_CPU_UP = 3,
     85
     86  /**
     87   *  This defines the constant used to indicate that the cpu code has
    8288   *  shut itself down.
    8389   */
    84   RTEMS_BSP_SMP_CPU_SHUTDOWN = 3
     90  RTEMS_BSP_SMP_CPU_SHUTDOWN = 4
    8591} bsp_smp_cpu_state;
    8692
  • cpukit/score/include/rtems/score/smp.h

    r27f09f17 rd4dc7c8  
    8888
    8989/**
     90 *  @brief Request Other Cores to Perform First Context Switch
     91 *
     92 *  Send message to other cores requesting them to perform
     93 *  their first context switch operation.
     94 */
     95void _SMP_Request_other_cores_to_perform_first_context_switch(void);
     96
     97/**
    9098 *  @brief Request Dispatch on Other Cores
    9199 *
  • cpukit/score/src/smp.c

    r27f09f17 rd4dc7c8  
    2020
    2121#if defined(RTEMS_SMP)
    22 #define SMP_DEBUG
    23 
    24 #if defined(SMP_DEBUG)
     22  #define RTEMS_DEBUG
     23#endif
     24
     25#if defined(RTEMS_DEBUG)
    2526  #include <rtems/bspIo.h>
    2627#endif
    2728
     29/*
     30 *  Process request to switch to the first task on a secondary core.
     31 */
    2832void rtems_smp_run_first_task(int cpu)
    2933{
     
    3135
    3236  /*
    33    *  This CPU has an heir thread so we need to dispatch it.
     37   *  The Scheduler will have selected the heir thread for each CPU core.
     38   *  Now we have been requested to perform the first context switch.  So
     39   *  force a switch to the designated heir and make it executing on
     40   *  THIS core.
    3441   */
    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  heir              = _Thread_Heir;
    4243  _Thread_Executing = heir;
     44
    4345  _CPU_Context_switch_to_first_task_smp( &heir->Registers );
    4446}
    4547
     48/*
     49 *  Process request to initialize this secondary core.
     50 */
    4651void rtems_smp_secondary_cpu_initialize(void)
    4752{
     
    5257  bsp_smp_secondary_cpu_initialize(cpu);
    5358
    54   #if defined(SMP_DEBUG)
     59  #if defined(RTEMS_DEBUG)
    5560    printk( "Made it to %d -- ", cpu );
    5661  #endif
     
    6469
    6570  /*
    66    *  HACK: Should not have to enable interrupts in real system here.
    67    *        It should happen as part of switching to the first task.
     71   *  With this secondary core out of reset, we can wait for the
     72   *  request to switch to the first task.
     73   *
     74   *  XXX When SMP ISR code is complete, do we want interrupts on
     75   *  XXX or off at this point?
    6876   */
    69 
    70   _Per_CPU_Information[cpu].isr_nest_level = 1;
    7177  _ISR_Set_level( 0 );
    72   while(1) ;
    73 }
    74 
     78  while(1) {
     79    bsp_smp_wait_for(
     80      (volatile unsigned int *)&_Per_CPU_Information[cpu].message,
     81      RTEMS_BSP_SMP_FIRST_TASK,
     82      10000
     83    );
     84  }
     85}
     86
     87/*
     88 *  Process an interrupt processor interrupt which indicates a request
     89 *  from another core.
     90 */
    7591void rtems_smp_process_interrupt(void)
    7692{
     
    8197  cpu = bsp_smp_processor_id();
    8298
    83   level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
    84     message = _Per_CPU_Information[cpu].message;
    85     _Per_CPU_Information[cpu].message &= ~message;
    86   _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
    87 
    88   #if defined(SMP_DEBUG)
     99  level = _SMP_lock_Simple_Spinlock_Obtain( &_Per_CPU_Information[cpu].lock );
     100  message = _Per_CPU_Information[cpu].message;
     101
     102  #if defined(RTEMS_DEBUG)
    89103    {
    90104      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 );
     105      if ( !(message & RTEMS_BSP_SMP_SHUTDOWN) ) {
     106        printk( "ISR on CPU %d -- (0x%02x) (0x%p)\n", cpu, message, sp );
     107        if ( message & RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY )
     108          printk( "context switch necessary\n" );
     109        if ( message & RTEMS_BSP_SMP_SIGNAL_TO_SELF )
     110          printk( "signal to self\n" );
     111        if ( message & RTEMS_BSP_SMP_SHUTDOWN )
     112          printk( "shutdown\n" );
     113        if ( message & RTEMS_BSP_SMP_FIRST_TASK )
     114          printk( "switch to first task\n" );
     115      }
     116 
     117      printk( "Dispatch level %d\n", _Thread_Dispatch_get_disable_level() );
    94118    }
    95119  #endif
    96120
    97121  if ( message & RTEMS_BSP_SMP_FIRST_TASK ) {
     122    /*
     123     * XXX Thread dispatch disable level at this point will have to be
     124     * XXX revisited when Interrupts on SMP is addressed.
     125     */
     126    _Thread_Dispatch_disable_level--; /* undo ISR code */
    98127    _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;
     128    _Per_CPU_Information[cpu].message &= ~message;
     129    _Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_UP;
     130
     131    _SMP_lock_Simple_Spinlock_Release( &_Per_CPU_Information[cpu].lock, level );
     132    _Thread_Disable_dispatch();
    101133    rtems_smp_run_first_task(cpu);
    102134    /* does not return */
     
    104136
    105137  if ( message & RTEMS_BSP_SMP_SHUTDOWN ) {
    106     ISR_Level level;
    107     _Thread_Dispatch_set_disable_level(0);
     138    /*
     139     * XXX Thread dispatch disable level at this point will have to be
     140     * XXX revisited when Interrupts on SMP is addressed.
     141     */
     142    _Per_CPU_Information[cpu].message &= ~message;
     143    _SMP_lock_Simple_Spinlock_Release( &_Per_CPU_Information[cpu].lock, level );
     144
     145    _Thread_Dispatch_disable_level--; /* undo ISR code */
    108146    _Per_CPU_Information[cpu].isr_nest_level = 0;
    109147    _Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_SHUTDOWN;
     
    115153
    116154  if ( message & RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY ) {
    117     printk( "switch needed\n" );
    118     _Per_CPU_Information[cpu].dispatch_necessary = true;
    119   }
    120 }
    121 
    122 void rtems_smp_send_message(
     155    #if defined(RTEMS_DEBUG)
     156      printk( "switch needed\n" );
     157    #endif
     158    /*
     159     * XXX Thread dispatch disable level at this point will have to be
     160     * XXX revisited when Interrupts on SMP is addressed.
     161     */
     162    _Per_CPU_Information[cpu].message &= ~message;
     163    _SMP_lock_Simple_Spinlock_Release( &_Per_CPU_Information[cpu].lock, level );
     164  }
     165}
     166
     167/*
     168 *  Send an interrupt processor request to another cpu.
     169 */
     170void _SMP_Send_message(
    123171  int       cpu,
    124172  uint32_t  message
     
    133181}
    134182
    135 void rtems_smp_broadcast_message(
     183/*
     184 *  Send interrupt processor request to all other nodes
     185 */
     186void _SMP_Broadcast_message(
    136187  uint32_t  message
    137188)
     
    152203  bsp_smp_broadcast_interrupt();
    153204}
    154 #endif
     205
     206/*
     207 *  Send interrupt processor requests to perform first context switch
     208 */
     209void _SMP_Request_other_cores_to_perform_first_context_switch(void)
     210{
     211  int    cpu;
     212
     213  for (cpu=1 ; cpu < _SMP_Processor_count ; cpu++ ) {
     214    _SMP_Send_message( cpu, RTEMS_BSP_SMP_FIRST_TASK );
     215    while (_Per_CPU_Information[cpu].state != RTEMS_BSP_SMP_CPU_UP ) {
     216      bsp_smp_wait_for(
     217        (volatile unsigned int *)&_Per_CPU_Information[cpu].state,
     218        RTEMS_BSP_SMP_CPU_UP,
     219        10000
     220      );
     221    }
     222  }
     223}
     224
     225/*
     226 *  Send message to other cores requesting them to perform
     227 *  a thread dispatch operation.
     228 */
     229void _SMP_Request_other_cores_to_dispatch(void)
     230{
     231  int i;
     232  int cpu;
     233
     234  cpu = bsp_smp_processor_id();
     235
     236  if ( !_System_state_Is_up (_System_state_Current) )
     237    return;
     238  for (i=1 ; i < _SMP_Processor_count ; i++ ) {
     239    if ( cpu == i )
     240      continue;
     241    if ( _Per_CPU_Information[i].state != RTEMS_BSP_SMP_CPU_UP )
     242      continue;
     243    if ( !_Per_CPU_Information[i].dispatch_necessary )
     244      continue;
     245    _SMP_Send_message( i, RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY );
     246    bsp_smp_wait_for(
     247      (volatile unsigned int *)&_Per_CPU_Information[i].message,
     248      0,
     249      10000
     250    );
     251  }
     252}
     253
     254/*
     255 *  Send message to other cores requesting them to shutdown.
     256 */
     257void _SMP_Request_other_cores_to_shutdown(void)
     258{
     259  bool allDown;
     260  int  ncpus;
     261  int  cpu;
     262
     263  ncpus = _SMP_Processor_count;
     264
     265  _SMP_Broadcast_message( RTEMS_BSP_SMP_SHUTDOWN );
     266
     267  allDown = true;
     268  for (cpu=1 ; cpu<ncpus ; cpu++ ) {
     269     bsp_smp_wait_for(
     270       (unsigned int *)&_Per_CPU_Information[cpu].state,
     271       RTEMS_BSP_SMP_CPU_SHUTDOWN,
     272       10000
     273    );
     274    if ( _Per_CPU_Information[cpu].state != RTEMS_BSP_SMP_CPU_SHUTDOWN )
     275      allDown = false;
     276  }
     277  if ( !allDown )
     278    printk( "All CPUs not successfully shutdown -- timed out\n" );
     279  #if (RTEMS_DEBUG)
     280    else
     281      printk( "All CPUs shutdown successfully\n" );
     282  #endif
     283}
  • cpukit/score/src/threaddispatch.c

    r27f09f17 rd4dc7c8  
    3434#endif
    3535
     36#if defined(RTEMS_SMP)
     37  #include <rtems/score/smp.h>
     38#endif
     39
    3640/**
    3741 *  _Thread_Dispatch
     
    4852 *    no dispatch thread
    4953 */
    50 
    5154void _Thread_Dispatch( void )
    5255{
     
    5558  ISR_Level         level;
    5659
     60  _Thread_Disable_dispatch();
     61  #if defined(RTEMS_SMP)
     62    /*
     63     *  If necessary, send dispatch request to other cores.
     64     */
     65    _SMP_Request_other_cores_to_dispatch();
     66  #endif
     67
     68  /*
     69   *  Now determine if we need to perform a dispatch on the current CPU.
     70   */
    5771  executing   = _Thread_Executing;
    5872  _ISR_Disable( level );
    5973  while ( _Thread_Dispatch_necessary == true ) {
     74
    6075    heir = _Thread_Heir;
    61    _Thread_Dispatch_set_disable_level( 1 );
    6276    _Thread_Dispatch_necessary = false;
    6377    _Thread_Executing = heir;
     
    97111      }
    98112    #else
    99       heir->cpu_time_used++;
     113      {
     114        TOD_Get_uptime( &_Thread_Time_of_last_context_switch );
     115        heir->cpu_time_used++;
     116      }
    100117    #endif
    101118
  • cpukit/score/src/threadhandler.c

    r27f09f17 rd4dc7c8  
    33 *
    44 *
    5  *  COPYRIGHT (c) 1989-2009.
     5 *  COPYRIGHT (c) 1989-2011.
    66 *  On-Line Applications Research Corporation (OAR).
    77 *
     
    5252#endif
    5353
     54#if defined(RTEMS_SMP)
     55  #include <rtems/score/smp.h>
     56#endif
     57
     58
    5459/*PAGE
    5560 *
     
    139144    if (!doneCons) /* && (volatile void *)_init) */ {
    140145      INIT_NAME ();
    141     }
    142   #endif
     146   
     147      #if defined(RTEMS_SMP)
     148        _Thread_Disable_dispatch();
     149          _SMP_Request_other_cores_to_perform_first_context_switch();
     150        _Thread_Enable_dispatch();
     151      #endif
     152
     153    }
     154 #endif
    143155
    144156  if ( executing->Start.prototype == THREAD_START_NUMERIC ) {
Note: See TracChangeset for help on using the changeset viewer.