Changeset 90d8567 in rtems


Ignore:
Timestamp:
Feb 18, 2016, 7:36:16 AM (4 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
03b900d
Parents:
5b0d2c1
git-author:
Sebastian Huber <sebastian.huber@…> (02/18/16 07:36:16)
git-committer:
Sebastian Huber <sebastian.huber@…> (03/04/16 12:36:10)
Message:

score: Distribute clock tick to all online CPUs

Update #2554.

Files:
18 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/arm/shared/arm-a9mpcore-clock-config.c

    r5b0d2c1 r90d8567  
    11/*
    2  * Copyright (c) 2013-2015 embedded brains GmbH.  All rights reserved.
     2 * Copyright (c) 2013, 2016 embedded brains GmbH.  All rights reserved.
    33 *
    44 *  embedded brains GmbH
     
    1616#include <bsp/fatal.h>
    1717#include <bsp/irq.h>
     18#include <bsp/irq-generic.h>
    1819#include <bsp/arm-a9mpcore-regs.h>
    1920#include <bsp/arm-a9mpcore-clock.h>
    2021#include <rtems/timecounter.h>
     22#include <rtems/score/smpimpl.h>
    2123
    2224#define A9MPCORE_GT ((volatile a9mpcore_gt *) BSP_ARM_A9MPCORE_GT_BASE)
     
    7880}
    7981
     82static void a9mpcore_clock_gt_init(
     83  volatile a9mpcore_gt *gt,
     84  uint64_t cmpval,
     85  uint32_t interval
     86)
     87{
     88  gt->cmpvallower = (uint32_t) cmpval;
     89  gt->cmpvalupper = (uint32_t) (cmpval >> 32);
     90  gt->autoinc = interval;
     91  gt->ctrl = A9MPCORE_GT_CTRL_AUTOINC_EN
     92    | A9MPCORE_GT_CTRL_IRQ_EN
     93    | A9MPCORE_GT_CTRL_COMP_EN
     94    | A9MPCORE_GT_CTRL_TMR_EN;
     95}
     96
     97#ifdef RTEMS_SMP
     98typedef struct {
     99  uint64_t cmpval;
     100  uint32_t interval;
     101} a9mpcore_clock_init_data;
     102
     103static void a9mpcore_clock_secondary_action(void *arg)
     104{
     105  volatile a9mpcore_gt *gt = A9MPCORE_GT;
     106  a9mpcore_clock_init_data *init_data = arg;
     107
     108  a9mpcore_clock_gt_init(gt, init_data->cmpval, init_data->interval);
     109  bsp_interrupt_vector_enable(A9MPCORE_IRQ_GT);
     110}
     111#endif
     112
     113static void a9mpcore_clock_secondary_initialization(
     114  volatile a9mpcore_gt *gt,
     115  uint64_t cmpval,
     116  uint32_t interval
     117)
     118{
     119#ifdef RTEMS_SMP
     120  a9mpcore_clock_init_data init_data = {
     121    .cmpval = cmpval,
     122    .interval = interval
     123  };
     124
     125  _SMP_Before_multitasking_action_broadcast(
     126    a9mpcore_clock_secondary_action,
     127    &init_data
     128  );
     129
     130  if (cmpval - a9mpcore_clock_get_counter(gt) >= interval) {
     131    bsp_fatal(BSP_ARM_A9MPCORE_FATAL_CLOCK_SMP_INIT);
     132  }
     133#endif
     134}
     135
    80136static void a9mpcore_clock_initialize(void)
    81137{
     
    92148  cmpval += interval;
    93149
    94   gt->cmpvallower = (uint32_t) cmpval;
    95   gt->cmpvalupper = (uint32_t) (cmpval >> 32);
    96   gt->autoinc = interval;
    97 
    98   gt->ctrl = A9MPCORE_GT_CTRL_AUTOINC_EN
    99     | A9MPCORE_GT_CTRL_IRQ_EN
    100     | A9MPCORE_GT_CTRL_COMP_EN
    101     | A9MPCORE_GT_CTRL_TMR_EN;
     150  a9mpcore_clock_gt_init(gt, cmpval, interval);
     151  a9mpcore_clock_secondary_initialization(gt, cmpval, interval);
    102152
    103153  a9mpcore_tc.tc_get_timecount = a9mpcore_clock_get_timecount;
  • c/src/lib/libbsp/arm/shared/arm-gic-irq.c

    r5b0d2c1 r90d8567  
    165165  return sc;
    166166}
     167
     168rtems_status_code arm_gic_irq_set_affinity(
     169  rtems_vector_number vector,
     170  uint8_t targets
     171)
     172{
     173  rtems_status_code sc = RTEMS_SUCCESSFUL;
     174
     175  if (bsp_interrupt_is_valid_vector(vector)) {
     176    volatile gic_dist *dist = ARM_GIC_DIST;
     177
     178    gic_id_set_targets(dist, vector, targets);
     179  } else {
     180    sc = RTEMS_INVALID_ID;
     181  }
     182
     183  return sc;
     184}
  • c/src/lib/libbsp/arm/shared/include/arm-gic-irq.h

    r5b0d2c1 r90d8567  
    5959);
    6060
     61rtems_status_code arm_gic_irq_set_affinity(
     62  rtems_vector_number vector,
     63  uint8_t targets
     64);
     65
    6166typedef enum {
    6267  ARM_GIC_IRQ_SOFTWARE_IRQ_TO_ALL_IN_LIST,
  • c/src/lib/libbsp/i386/pc386/clock/ckinit.c

    r5b0d2c1 r90d8567  
    6666
    6767
    68 /*
    69  *  Hooks which get swapped based upon which nanoseconds since last
    70  *  tick method is preferred.
    71  */
    72 #define Clock_driver_support_at_tick()
     68#ifdef RTEMS_SMP
     69#define Clock_driver_support_at_tick() \
     70  _SMP_Send_message_broadcast(SMP_MESSAGE_CLOCK_TICK)
     71#endif
    7372
    7473#define Clock_driver_support_install_isr( _new, _old ) \
     
    204203}
    205204
     205#define Clock_driver_support_set_interrupt_affinity(online_processors) \
     206  do { \
     207    /* FIXME: Is there a way to do this on x86? */ \
     208    (void) online_processors; \
     209  } while (0)
     210
    206211void Clock_driver_support_initialize_hardware(void)
    207212{
  • c/src/lib/libbsp/i386/shared/smp/smp-imps.c

    r5b0d2c1 r90d8567  
    745745}
    746746
     747/* FIXME: There should be a header file for this */
     748void Clock_isr(void *arg);
     749
    747750static void bsp_inter_processor_interrupt(void *arg)
    748751{
     752  unsigned long message;
     753
    749754  (void) arg;
    750755
    751756  smp_apic_ack();
    752757
    753   _SMP_Inter_processor_interrupt_handler();
     758  message = _SMP_Inter_processor_interrupt_handler();
     759
     760  if ((message & SMP_MESSAGE_CLOCK_TICK) != 0) {
     761    Clock_isr(NULL);
     762  }
    754763}
    755764
  • c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c

    r5b0d2c1 r90d8567  
    88
    99/*
    10  * Copyright (c) 2011-2015 embedded brains GmbH.  All rights reserved.
     10 * Copyright (c) 2011, 2016 embedded brains GmbH.  All rights reserved.
    1111 *
    1212 *  embedded brains GmbH
     
    5656  *old_isr = NULL;
    5757
     58#if defined(RTEMS_MULTIPROCESSING) && !defined(RTEMS_SMP)
    5859  sc = qoriq_pic_set_affinity(
    5960    CLOCK_INTERRUPT,
     
    6364    rtems_fatal_error_occurred(0xdeadbeef);
    6465  }
     66#endif
    6567
    6668  sc = qoriq_pic_set_priority(
     
    127129#define Clock_driver_support_initialize_hardware() \
    128130  qoriq_clock_initialize()
     131
    129132#define Clock_driver_support_install_isr(clock_isr, old_isr) \
    130133  qoriq_clock_handler_install(&old_isr)
     134
     135#define Clock_driver_support_set_interrupt_affinity(online_processors) \
     136  qoriq_pic_set_affinities(CLOCK_INTERRUPT, online_processors[0])
     137
    131138#define Clock_driver_support_shutdown_hardware() \
    132139  qoriq_clock_cleanup()
  • c/src/lib/libbsp/powerpc/qoriq/include/irq.h

    r5b0d2c1 r90d8567  
    378378);
    379379
     380rtems_status_code qoriq_pic_set_affinities(
     381  rtems_vector_number vector,
     382  uint32_t processor_affinities
     383);
     384
    380385/** @} */
    381386
  • c/src/lib/libbsp/powerpc/qoriq/irq/irq.c

    r5b0d2c1 r90d8567  
    148148}
    149149
     150rtems_status_code qoriq_pic_set_affinities(
     151        rtems_vector_number vector,
     152        uint32_t processor_affinities
     153)
     154{
     155        rtems_status_code sc = RTEMS_SUCCESSFUL;
     156
     157        if (bsp_interrupt_is_valid_vector(vector)) {
     158                volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);
     159
     160                src_cfg->dr = processor_affinities;
     161        } else {
     162                sc = RTEMS_INVALID_ID;
     163        }
     164
     165        return sc;
     166}
     167
    150168rtems_status_code qoriq_pic_set_affinity(
    151169        rtems_vector_number vector,
     
    153171)
    154172{
    155         rtems_status_code sc = RTEMS_SUCCESSFUL;
    156 
    157         if (bsp_interrupt_is_valid_vector(vector)) {
    158                 if (processor_index <= 1) {
    159                         volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);
    160 
    161                         src_cfg->dr = BSP_BIT32(processor_index);
    162                 } else {
    163                         sc = RTEMS_INVALID_NUMBER;
    164                 }
    165         } else {
    166                 sc = RTEMS_INVALID_ID;
    167         }
    168 
    169         return sc;
     173        return qoriq_pic_set_affinities(vector, BSP_BIT32(processor_index));
    170174}
    171175
  • c/src/lib/libbsp/shared/clockdrv_shell.h

    r5b0d2c1 r90d8567  
    2121#include <rtems/clockdrv.h>
    2222#include <rtems/score/percpu.h>
     23#include <rtems/score/smpimpl.h>
    2324
    2425#ifdef Clock_driver_nanoseconds_since_last_tick
     
    5051#ifndef Clock_driver_support_at_tick
    5152  #define Clock_driver_support_at_tick()
     53#endif
     54
     55/**
     56 * @brief Do nothing by default.
     57 */
     58#ifndef Clock_driver_support_set_interrupt_affinity
     59  #define Clock_driver_support_set_interrupt_affinity(online_processors)
    5260#endif
    5361
     
    200208  Clock_driver_support_install_isr( Clock_isr, Old_ticker );
    201209
     210  #ifdef RTEMS_SMP
     211    Clock_driver_support_set_interrupt_affinity( _SMP_Online_processors );
     212  #endif
     213
    202214  /*
    203215   *  Now initialize the hardware that is the source of the tick ISR.
  • c/src/lib/libbsp/shared/include/fatal.h

    r5b0d2c1 r90d8567  
    4848  BSP_ARM_PL111_FATAL_SEM_CREATE,
    4949  BSP_ARM_PL111_FATAL_SEM_RELEASE,
     50  BSP_ARM_A9MPCORE_FATAL_CLOCK_SMP_INIT,
    5051
    5152  /* LEON3 fatal codes */
  • c/src/lib/libbsp/sparc/erc32/clock/ckinit.c

    r5b0d2c1 r90d8567  
    4141    _old = set_vector( _new, CLOCK_VECTOR, 1 ); \
    4242  } while(0)
     43
     44#define Clock_driver_support_set_interrupt_affinity( _online_processors ) \
     45  do { \
     46    (void) _online_processors; \
     47  } while (0)
    4348
    4449extern int CLOCK_SPEED;
  • c/src/lib/libbsp/sparc/leon3/clock/ckinit.c

    r5b0d2c1 r90d8567  
    155155  }
    156156}
     157
     158#define Clock_driver_support_set_interrupt_affinity(online_processors) \
     159  do { \
     160    uint32_t cpu_count = _SMP_Processor_count; \
     161    uint32_t cpu_index; \
     162    LEON_Enable_interrupt_broadcast(clkirq); \
     163    for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) { \
     164      if (_Processor_mask_Is_set(online_processors, cpu_index)) { \
     165        BSP_Cpu_Unmask_interrupt(clkirq, cpu_index); \
     166      } \
     167    } \
     168  } while (0)
    157169
    158170static void leon3_clock_initialize(void)
  • c/src/lib/libbsp/sparc/leon3/include/leon.h

    r5b0d2c1 r90d8567  
    195195  } while (0)
    196196
     197#define LEON_Enable_interrupt_broadcast( _source ) \
     198  do { \
     199    rtems_interrupt_lock_context _lock_context; \
     200    uint32_t _mask = 1U << ( _source ); \
     201    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
     202    LEON3_IrqCtrl_Regs->bcast |= _mask; \
     203    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
     204  } while (0)
     205
     206#define LEON_Disable_interrupt_broadcast( _source ) \
     207  do { \
     208    rtems_interrupt_lock_context _lock_context; \
     209    uint32_t _mask = 1U << ( _source ); \
     210    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
     211    LEON3_IrqCtrl_Regs->bcast &= ~_mask; \
     212    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
     213  } while (0)
     214
    197215#define LEON_Is_interrupt_pending( _source ) \
    198216  (LEON3_IrqCtrl_Regs->ipend & (1 << (_source)))
  • cpukit/score/include/rtems/score/smpimpl.h

    r5b0d2c1 r90d8567  
    5959 */
    6060#define SMP_MESSAGE_MULTICAST_ACTION 0x4UL
     61
     62/**
     63 * @brief SMP message to request a clock tick.
     64 *
     65 * This message is provided for systems without a proper interrupt affinity
     66 * support and may be used by the clock driver.
     67 *
     68 * @see _SMP_Send_message().
     69 */
     70#define SMP_MESSAGE_CLOCK_TICK 0x8UL
    6171
    6272/**
     
    153163/**
    154164 * @brief Interrupt handler for inter-processor interrupts.
    155  */
    156 static inline void _SMP_Inter_processor_interrupt_handler( void )
     165 *
     166 * @return The received message.
     167 */
     168static inline long unsigned _SMP_Inter_processor_interrupt_handler( void )
    157169{
    158170  Per_CPU_Control *cpu_self = _Per_CPU_Get();
     171  unsigned long message = 0;
    159172
    160173  /*
     
    165178
    166179  if ( _Atomic_Load_ulong( &cpu_self->message, ATOMIC_ORDER_RELAXED ) != 0 ) {
    167     unsigned long message = _Atomic_Exchange_ulong(
     180    message = _Atomic_Exchange_ulong(
    168181      &cpu_self->message,
    169182      0UL,
     
    184197    }
    185198  }
     199
     200  return message;
    186201}
    187202
     
    198213
    199214/**
    200  *  @brief Sends a SMP message to a processor.
     215 *  @brief Sends an SMP message to a processor.
    201216 *
    202217 *  The target processor may be the sending processor.
     
    208223
    209224/**
    210  *  @brief Request of others CPUs.
    211  *
    212  *  This method is invoked by RTEMS when it needs to make a request
    213  *  of the other CPUs.  It should be implemented using some type of
    214  *  interprocessor interrupt. CPUs not including the originating
    215  *  CPU should receive the message.
    216  *
    217  *  @param [in] message is message to send
     225 *  @brief Sends an SMP message to all other online processors.
     226 *
     227 *  @param[in] message The message.
    218228 */
    219229void _SMP_Send_message_broadcast(
     
    222232
    223233/**
    224  *  @brief Sends a SMP message to a set of processors.
     234 *  @brief Sends an SMP message to a set of processors.
    225235 *
    226236 *  The sending processor may be part of the set.
     
    239249
    240250/**
    241  *  @brief Initiates a SMP multicast action to a set of processors.
     251 *  @brief Initiates an SMP multicast action to a set of processors.
    242252 *
    243253 *  The current processor may be part of the set.
  • cpukit/score/include/rtems/score/watchdogimpl.h

    r5b0d2c1 r90d8567  
    2424#include <rtems/score/chainimpl.h>
    2525#include <rtems/score/isrlock.h>
     26#include <rtems/score/percpu.h>
    2627
    2728#ifdef __cplusplus
     
    140141
    141142/**
    142  *  @brief Triggers a watchdog tick.
    143  *
    144  *  This routine executes TOD, watchdog and scheduler ticks.
    145  */
    146 void _Watchdog_Tick( void );
     143 *  @brief Performs a watchdog tick.
     144 *
     145 *  @param cpu The processor for this watchdog tick.
     146 */
     147void _Watchdog_Tick( Per_CPU_Control *cpu );
    147148
    148149/**
  • cpukit/score/src/kern_tc.c

    r5b0d2c1 r90d8567  
    19751975_Timecounter_Tick(void)
    19761976{
     1977        Per_CPU_Control *cpu_self = _Per_CPU_Get();
     1978
     1979        if (_Per_CPU_Is_boot_processor(cpu_self)) {
    19771980#endif /* __rtems__ */
    19781981        tc_windup();
    19791982#ifdef __rtems__
    1980         _Watchdog_Tick();
     1983        };
     1984
     1985        _Watchdog_Tick(cpu_self);
    19811986#endif /* __rtems__ */
    19821987}
     
    20172022        _Timecounter_Release(lock_context);
    20182023
    2019         _Watchdog_Tick();
     2024        _Watchdog_Tick(_Per_CPU_Get());
    20202025}
    20212026#endif /* __rtems__ */
  • cpukit/score/src/smp.c

    r5b0d2c1 r90d8567  
    190190
    191191  for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {
    192     if ( cpu_index != cpu_index_self ) {
     192    if (
     193      cpu_index != cpu_index_self
     194        && _Processor_mask_Is_set( _SMP_Online_processors, cpu_index )
     195    ) {
    193196      _SMP_Send_message( cpu_index, message );
    194197    }
  • cpukit/score/src/watchdogtick.c

    r5b0d2c1 r90d8567  
    2323#endif
    2424
    25 void _Watchdog_Tick( void )
     25void _Watchdog_Tick( Per_CPU_Control *cpu )
    2626{
    2727  _Assert( !_Thread_Dispatch_is_enabled() );
    2828
    29   _TOD_Tickle_ticks();
     29  if ( _Per_CPU_Is_boot_processor( cpu ) ) {
     30    _TOD_Tickle_ticks();
    3031
    31   _Watchdog_Tickle_ticks();
     32    _Watchdog_Tickle_ticks();
    3233
    33   _Scheduler_Tick();
     34    _Scheduler_Tick();
     35  }
    3436}
Note: See TracChangeset for help on using the changeset viewer.