Changeset 5b0d2c1 in rtems


Ignore:
Timestamp:
Mar 3, 2016, 12:37:14 PM (4 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
90d8567
Parents:
3c103ba
git-author:
Sebastian Huber <sebastian.huber@…> (03/03/16 12:37:14)
git-committer:
Sebastian Huber <sebastian.huber@…> (03/04/16 12:36:09)
Message:

score: Add _SMP_Before_multitasking_action()

The use case for this is the Cortex-A9 MPCore which has per-processor
registers (only accessible by a particular processor) for the global
timer used by the clock driver. This might be useful for other drivers
as well.

Update #2554.

Location:
cpukit/score
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • cpukit/score/include/rtems/score/percpu.h

    r3c103ba r5b0d2c1  
    362362
    363363    /**
     364     * @brief Action to be executed by this processor in the
     365     * SYSTEM_STATE_BEFORE_MULTITASKING state on behalf of the boot processor.
     366     *
     367     * @see _SMP_Before_multitasking_action().
     368     */
     369    Atomic_Uintptr before_multitasking_action;
     370
     371    /**
    364372     * @brief Indicates if the processor has been successfully started via
    365373     * _CPU_SMP_Start_processor().
  • cpukit/score/include/rtems/score/smpimpl.h

    r3c103ba r5b0d2c1  
    236236);
    237237
    238 typedef void ( *SMP_Multicast_action_handler )( void *arg );
     238typedef void ( *SMP_Action_handler )( void *arg );
    239239
    240240/**
     
    251251  const size_t setsize,
    252252  const cpu_set_t *cpus,
    253   SMP_Multicast_action_handler handler,
     253  SMP_Action_handler handler,
    254254  void *arg
     255);
     256
     257/**
     258 * @brief Executes a handler with argument on the specified processor on behalf
     259 * of the boot processor.
     260 *
     261 * The calling processor must be the boot processor.  In case the specified
     262 * processor is not online or not in the
     263 * PER_CPU_STATE_READY_TO_START_MULTITASKING state, then no action is
     264 * performed.
     265 *
     266 * @param cpu The processor to execute the action.
     267 * @param handler The handler of the action.
     268 * @param arg The argument of the action.
     269 *
     270 * @retval true The handler executed on the specified processor.
     271 * @retval false Otherwise.
     272 *
     273 * @see _SMP_Before_multitasking_action_broadcast().
     274 */
     275bool _SMP_Before_multitasking_action(
     276  Per_CPU_Control    *cpu,
     277  SMP_Action_handler  handler,
     278  void               *arg
     279);
     280
     281/**
     282 * @brief Executes a handler with argument on all online processors except the
     283 * boot processor on behalf of the boot processor.
     284 *
     285 * The calling processor must be the boot processor.
     286 *
     287 * @param handler The handler of the action.
     288 * @param arg The argument of the action.
     289 *
     290 * @retval true The handler executed on all online processors except the boot
     291 * processor.
     292 * @retval false Otherwise.
     293 *
     294 * @see _SMP_Before_multitasking_action().
     295 */
     296bool _SMP_Before_multitasking_action_broadcast(
     297  SMP_Action_handler  handler,
     298  void               *arg
    255299);
    256300
  • cpukit/score/src/percpu.c

    r3c103ba r5b0d2c1  
    2121#include <rtems/score/percpu.h>
    2222#include <rtems/score/assert.h>
     23#include <rtems/score/isrlock.h>
    2324#include <rtems/score/smpimpl.h>
    2425#include <rtems/config.h>
     
    3637#if defined(RTEMS_SMP)
    3738
    38 static SMP_lock_Control _Per_CPU_State_lock =
    39   SMP_LOCK_INITIALIZER("per-CPU state");
     39typedef struct {
     40  SMP_Action_handler handler;
     41  void *arg;
     42} SMP_Before_multicast_action;
     43
     44ISR_LOCK_DEFINE( static, _Per_CPU_State_lock, "Per-CPU State" )
     45
     46static void _Per_CPU_State_acquire( ISR_lock_Context *lock_context )
     47{
     48  _ISR_lock_ISR_disable_and_acquire( &_Per_CPU_State_lock, lock_context );
     49}
     50
     51static void _Per_CPU_State_release( ISR_lock_Context *lock_context )
     52{
     53  _ISR_lock_Release_and_ISR_enable( &_Per_CPU_State_lock, lock_context );
     54}
     55
     56static void _Per_CPU_State_before_multitasking_action( Per_CPU_Control *cpu )
     57{
     58  uintptr_t action_value;
     59
     60  action_value = _Atomic_Load_uintptr(
     61    &cpu->before_multitasking_action,
     62    ATOMIC_ORDER_ACQUIRE
     63  );
     64
     65  if ( action_value != 0 ) {
     66    SMP_Before_multicast_action *action =
     67      (SMP_Before_multicast_action *) action_value;
     68
     69    ( *action->handler )( action->arg );
     70
     71    _Atomic_Store_uintptr(
     72      &cpu->before_multitasking_action,
     73      0,
     74      ATOMIC_ORDER_RELEASE
     75    );
     76  }
     77}
    4078
    4179static void _Per_CPU_State_busy_wait(
    42   const Per_CPU_Control *cpu,
     80  Per_CPU_Control *cpu,
    4381  Per_CPU_State new_state
    4482)
     
    6199          && state != PER_CPU_STATE_SHUTDOWN
    62100      ) {
     101        _Per_CPU_State_before_multitasking_action( cpu );
    63102        _CPU_SMP_Processor_event_receive();
    64103        state = cpu->state;
     
    123162)
    124163{
    125   SMP_lock_Control *lock = &_Per_CPU_State_lock;
    126   SMP_lock_Context lock_context;
     164  ISR_lock_Context lock_context;
    127165  Per_CPU_State next_state;
    128166
    129167  _Per_CPU_State_busy_wait( cpu, new_state );
    130168
    131   _SMP_lock_ISR_disable_and_acquire( lock, &lock_context );
     169  _Per_CPU_State_acquire( &lock_context );
    132170
    133171  next_state = _Per_CPU_State_get_next( cpu->state, new_state );
     
    158196  _CPU_SMP_Processor_event_broadcast();
    159197
    160   _SMP_lock_Release_and_ISR_enable( lock, &lock_context );
     198  _Per_CPU_State_release( &lock_context );
    161199
    162200  if (
     
    166204    _SMP_Fatal( SMP_FATAL_SHUTDOWN );
    167205  }
     206}
     207
     208bool _SMP_Before_multitasking_action(
     209  Per_CPU_Control    *cpu,
     210  SMP_Action_handler  handler,
     211  void               *arg
     212)
     213{
     214  bool done;
     215
     216  _Assert( _Per_CPU_Is_boot_processor( _Per_CPU_Get() ) );
     217
     218  if ( _Per_CPU_Is_processor_online( cpu ) ) {
     219    SMP_Before_multicast_action action = {
     220      .handler = handler,
     221      .arg = arg
     222    };
     223    Per_CPU_State expected_state = PER_CPU_STATE_READY_TO_START_MULTITASKING;
     224
     225    _Atomic_Store_uintptr(
     226      &cpu->before_multitasking_action,
     227      (uintptr_t) &action,
     228      ATOMIC_ORDER_RELEASE
     229    );
     230
     231    _CPU_SMP_Processor_event_broadcast();
     232
     233    _Per_CPU_State_busy_wait( cpu, expected_state );
     234
     235    do {
     236      done = _Atomic_Load_uintptr(
     237        &cpu->before_multitasking_action,
     238        ATOMIC_ORDER_ACQUIRE
     239      ) == 0;
     240    } while ( !done && cpu->state == expected_state );
     241  } else {
     242    done = false;
     243  }
     244
     245  return done;
    168246}
    169247
  • cpukit/score/src/smp.c

    r3c103ba r5b0d2c1  
    212212}
    213213
     214bool _SMP_Before_multitasking_action_broadcast(
     215  SMP_Action_handler  handler,
     216  void               *arg
     217)
     218{
     219  bool done = true;
     220  uint32_t cpu_count = _SMP_Get_processor_count();
     221  uint32_t cpu_index;
     222
     223  for ( cpu_index = 0 ; done && cpu_index < cpu_count ; ++cpu_index ) {
     224    Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index );
     225
     226    if (
     227      !_Per_CPU_Is_boot_processor( cpu )
     228        && _Per_CPU_Is_processor_online( cpu )
     229    ) {
     230      done = _SMP_Before_multitasking_action( cpu, handler, arg );
     231    }
     232  }
     233
     234  return done;
     235}
     236
    214237SMP_Test_message_handler _SMP_Test_message_handler;
  • cpukit/score/src/smpmulticastaction.c

    r3c103ba r5b0d2c1  
    1818typedef struct {
    1919  Chain_Node Node;
    20   SMP_Multicast_action_handler handler;
     20  SMP_Action_handler handler;
    2121  void *arg;
    2222  cpu_set_t *recipients;
     
    9595  const size_t setsize,
    9696  const cpu_set_t *cpus,
    97   SMP_Multicast_action_handler handler,
     97  SMP_Action_handler handler,
    9898  void *arg
    9999)
Note: See TracChangeset for help on using the changeset viewer.