Changeset 0a1f5df9 in rtems


Ignore:
Timestamp:
May 3, 2018, 11:03:27 AM (14 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
7ee6437
Parents:
ef23838
git-author:
Sebastian Huber <sebastian.huber@…> (05/03/18 11:03:27)
git-committer:
Sebastian Huber <sebastian.huber@…> (12/07/18 13:22:01)
Message:

Simplify _CPU_Counter_difference()

In order to simplify the use of CPU counter values it is beneficial to
have monotonic increasing values within the range of the CPU counter
ticks data type, e.g. 32-bit unsigned integer. This eases the use of
CPU counter timestamps in external tools which do not know the details
of the CPU counter hardware. The CPU counter is the fastest way to get
a time on an RTEMS system.

Such a CPU counter may be also used as the timecounter. Use it on SPARC
for this purpose to simplify the clock drivers.

Update #3456.

Files:
2 deleted
13 edited

Legend:

Unmodified
Added
Removed
  • bsps/or1k/generic_or1k/clock/clockdrv.c

    ref23838 r0a1f5df9  
    110110}
    111111
    112 CPU_Counter_ticks _CPU_Counter_difference(
    113   CPU_Counter_ticks second,
    114   CPU_Counter_ticks first
    115 )
    116 {
    117   return second - first;
    118 }
    119 
    120112#define Clock_driver_support_at_tick() generic_or1k_clock_at_tick()
    121113
  • bsps/sparc/erc32/clock/ckinit.c

    ref23838 r0a1f5df9  
    2525#include <bsp.h>
    2626#include <bspopts.h>
    27 #include <rtems/counter.h>
     27#include <rtems/sysinit.h>
    2828#include <rtems/timecounter.h>
    2929#include <rtems/score/sparcimpl.h>
    3030
     31extern int CLOCK_SPEED;
     32
    3133#define ERC32_REAL_TIME_CLOCK_FREQUENCY 1000000
     34
     35static struct timecounter erc32_tc;
     36
     37static void erc32_clock_init( void )
     38{
     39  struct timecounter *tc;
     40
     41  tc = &erc32_tc;
     42  tc->tc_get_timecount = _SPARC_Get_timecount_clock;
     43  tc->tc_counter_mask = 0xffffffff;
     44  tc->tc_frequency = ERC32_REAL_TIME_CLOCK_FREQUENCY;
     45  tc->tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
     46  rtems_timecounter_install(tc);
     47}
     48
     49uint32_t _CPU_Counter_frequency(void)
     50{
     51  return ERC32_REAL_TIME_CLOCK_FREQUENCY;
     52}
     53
     54static void erc32_clock_at_tick( void )
     55{
     56  SPARC_Counter *counter;
     57  rtems_interrupt_level level;
     58
     59  counter = &_SPARC_Counter_mutable;
     60  rtems_interrupt_local_disable(level);
     61
     62  ERC32_Clear_interrupt( ERC32_INTERRUPT_REAL_TIME_CLOCK );
     63  counter->accumulated += counter->interval;
     64
     65  rtems_interrupt_local_enable(level);
     66}
     67
     68static void erc32_clock_initialize_early( void )
     69{
     70  SPARC_Counter *counter;
     71
     72  /* approximately 1 us per countdown */
     73  ERC32_MEC.Real_Time_Clock_Scalar = CLOCK_SPEED - 1;
     74  ERC32_MEC.Real_Time_Clock_Counter =
     75    rtems_configuration_get_microseconds_per_tick();
     76  ERC32_MEC_Set_Real_Time_Clock_Timer_Control(
     77      ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING |
     78      ERC32_MEC_TIMER_COUNTER_LOAD_SCALER |
     79      ERC32_MEC_TIMER_COUNTER_LOAD_COUNTER
     80  );
     81  ERC32_MEC_Set_Real_Time_Clock_Timer_Control(
     82    ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING |
     83    ERC32_MEC_TIMER_COUNTER_RELOAD_AT_ZERO
     84  );
     85
     86  counter = &_SPARC_Counter_mutable;
     87  counter->read_isr_disabled = _SPARC_Counter_read_clock_isr_disabled;
     88  counter->read = _SPARC_Counter_read_clock;
     89  counter->counter_register = &ERC32_MEC.Real_Time_Clock_Counter,
     90  counter->pending_register = &ERC32_MEC.Interrupt_Pending;
     91  counter->pending_mask = UINT32_C(1) << ERC32_INTERRUPT_REAL_TIME_CLOCK;
     92  counter->accumulated = rtems_configuration_get_microseconds_per_tick();
     93  counter->interval = rtems_configuration_get_microseconds_per_tick();
     94}
     95
     96RTEMS_SYSINIT_ITEM(
     97  erc32_clock_initialize_early,
     98  RTEMS_SYSINIT_CPU_COUNTER,
     99  RTEMS_SYSINIT_ORDER_FIRST
     100);
    32101
    33102/*
     
    44113  } while (0)
    45114
    46 extern int CLOCK_SPEED;
     115#define Clock_driver_support_at_tick() erc32_clock_at_tick()
    47116
    48 static rtems_timecounter_simple erc32_tc;
    49 
    50 static uint32_t erc32_tc_get( rtems_timecounter_simple *tc )
    51 {
    52   return ERC32_MEC.Real_Time_Clock_Counter;
    53 }
    54 
    55 static bool erc32_tc_is_pending( rtems_timecounter_simple *tc )
    56 {
    57   return ERC32_Is_interrupt_pending( ERC32_INTERRUPT_REAL_TIME_CLOCK );
    58 }
    59 
    60 static uint32_t erc32_tc_get_timecount( struct timecounter *tc )
    61 {
    62   return rtems_timecounter_simple_downcounter_get(
    63     tc,
    64     erc32_tc_get,
    65     erc32_tc_is_pending
    66   );
    67 }
    68 
    69 static void erc32_tc_at_tick( rtems_timecounter_simple *tc )
    70 {
    71   /* Nothing to do */
    72 }
    73 
    74 static void erc32_tc_tick( void )
    75 {
    76   rtems_timecounter_simple_downcounter_tick(
    77     &erc32_tc,
    78     erc32_tc_get,
    79     erc32_tc_at_tick
    80   );
    81 }
    82 
    83 static void erc32_counter_initialize( void )
    84 {
    85   _SPARC_Counter_initialize(
    86     _SPARC_Counter_read_address,
    87     _SPARC_Counter_difference_clock_period,
    88     &ERC32_MEC.Real_Time_Clock_Counter
    89   );
    90 }
    91 
    92 uint32_t _CPU_Counter_frequency(void)
    93 {
    94   return ERC32_REAL_TIME_CLOCK_FREQUENCY;
    95 }
    96 
    97 #define Clock_driver_support_initialize_hardware() \
    98   do { \
    99     /* approximately 1 us per countdown */ \
    100     ERC32_MEC.Real_Time_Clock_Scalar  = CLOCK_SPEED - 1; \
    101     ERC32_MEC.Real_Time_Clock_Counter = \
    102       rtems_configuration_get_microseconds_per_tick(); \
    103     \
    104     ERC32_MEC_Set_Real_Time_Clock_Timer_Control( \
    105         ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING | \
    106         ERC32_MEC_TIMER_COUNTER_LOAD_SCALER | \
    107         ERC32_MEC_TIMER_COUNTER_LOAD_COUNTER \
    108     ); \
    109     \
    110     ERC32_MEC_Set_Real_Time_Clock_Timer_Control( \
    111         ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING | \
    112         ERC32_MEC_TIMER_COUNTER_RELOAD_AT_ZERO \
    113     );  \
    114     rtems_timecounter_simple_install( \
    115         &erc32_tc, \
    116         ERC32_REAL_TIME_CLOCK_FREQUENCY, \
    117         rtems_configuration_get_microseconds_per_tick(), \
    118         erc32_tc_get_timecount \
    119     ); \
    120     erc32_counter_initialize(); \
    121   } while (0)
    122 
    123 #define Clock_driver_timecounter_tick() erc32_tc_tick()
     117#define Clock_driver_support_initialize_hardware() erc32_clock_init()
    124118
    125119#include "../../../shared/dev/clock/clockimpl.h"
  • bsps/sparc/leon2/clock/ckinit.c

    ref23838 r0a1f5df9  
    2525#include <bsp.h>
    2626#include <bspopts.h>
     27#include <rtems/sysinit.h>
    2728#include <rtems/timecounter.h>
    2829#include <rtems/score/sparcimpl.h>
    2930
    30 static rtems_timecounter_simple leon2_tc;
     31extern int CLOCK_SPEED;
    3132
    32 static uint32_t leon2_tc_get( rtems_timecounter_simple *tc )
     33#define LEON2_TIMER_1_FREQUENCY 1000000
     34
     35static struct timecounter leon2_tc;
     36
     37static void leon2_clock_init( void )
    3338{
    34   return LEON_REG.Timer_Counter_1;
     39  struct timecounter *tc;
     40
     41  tc = &leon2_tc;
     42  tc->tc_get_timecount = _SPARC_Get_timecount_clock;
     43  tc->tc_counter_mask = 0xffffffff;
     44  tc->tc_frequency = LEON2_TIMER_1_FREQUENCY;
     45  tc->tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
     46  rtems_timecounter_install(tc);
    3547}
    3648
    37 static bool leon2_tc_is_pending( rtems_timecounter_simple *tc )
     49static void leon2_clock_at_tick( void )
    3850{
    39   return LEON_Is_interrupt_pending( LEON_INTERRUPT_TIMER1 );
     51  SPARC_Counter *counter;
     52  rtems_interrupt_level level;
     53
     54  counter = &_SPARC_Counter_mutable;
     55  rtems_interrupt_local_disable(level);
     56
     57  LEON_Clear_interrupt( LEON_INTERRUPT_TIMER1 );
     58  counter->accumulated += counter->interval;
     59
     60  rtems_interrupt_local_enable(level);
    4061}
    4162
    42 static uint32_t leon2_tc_get_timecount( struct timecounter *tc )
     63static void leon2_clock_initialize_early( void )
    4364{
    44   return rtems_timecounter_simple_downcounter_get(
    45     tc,
    46     leon2_tc_get,
    47     leon2_tc_is_pending
     65  SPARC_Counter *counter;
     66
     67  LEON_REG.Timer_Reload_1 =
     68    rtems_configuration_get_microseconds_per_tick() - 1;
     69  LEON_REG.Timer_Control_1 = (
     70    LEON_REG_TIMER_COUNTER_ENABLE_COUNTING |
     71      LEON_REG_TIMER_COUNTER_RELOAD_AT_ZERO |
     72      LEON_REG_TIMER_COUNTER_LOAD_COUNTER
    4873  );
     74
     75  counter = &_SPARC_Counter_mutable;
     76  counter->read_isr_disabled = _SPARC_Counter_read_clock_isr_disabled;
     77  counter->read = _SPARC_Counter_read_clock;
     78  counter->counter_register = &LEON_REG.Timer_Counter_1;
     79  counter->pending_register = &LEON_REG.Interrupt_Pending;
     80  counter->pending_mask = UINT32_C(1) << LEON_INTERRUPT_TIMER1;
     81  counter->accumulated = rtems_configuration_get_microseconds_per_tick();
     82  counter->interval = rtems_configuration_get_microseconds_per_tick();
    4983}
    5084
    51 static void leon2_tc_at_tick( rtems_timecounter_simple *tc )
     85RTEMS_SYSINIT_ITEM(
     86  leon2_clock_initialize_early,
     87  RTEMS_SYSINIT_CPU_COUNTER,
     88  RTEMS_SYSINIT_ORDER_FIRST
     89);
     90
     91uint32_t _CPU_Counter_frequency(void)
    5292{
    53   /* Nothing to do */
    54 }
    55 
    56 static void leon2_tc_tick( void )
    57 {
    58   rtems_timecounter_simple_downcounter_tick(
    59     &leon2_tc,
    60     leon2_tc_get,
    61     leon2_tc_at_tick
    62   );
     93  return LEON2_TIMER_1_FREQUENCY;
    6394}
    6495
     
    72103  set_vector( _new, CLOCK_VECTOR, 1 )
    73104
    74 extern int CLOCK_SPEED;
     105#define Clock_driver_support_at_tick() leon2_clock_at_tick()
    75106
    76 #define Clock_driver_support_initialize_hardware() \
    77   do { \
    78     LEON_REG.Timer_Reload_1 = \
    79         rtems_configuration_get_microseconds_per_tick() - 1; \
    80     \
    81     LEON_REG.Timer_Control_1 = ( \
    82       LEON_REG_TIMER_COUNTER_ENABLE_COUNTING |  \
    83         LEON_REG_TIMER_COUNTER_RELOAD_AT_ZERO | \
    84         LEON_REG_TIMER_COUNTER_LOAD_COUNTER  \
    85     ); \
    86     rtems_timecounter_simple_install( \
    87       &leon2_tc, \
    88       1000000, \
    89       rtems_configuration_get_microseconds_per_tick(), \
    90       leon2_tc_get_timecount \
    91     ); \
    92   } while (0)
    93 
    94 #define Clock_driver_timecounter_tick() leon2_tc_tick()
     107#define Clock_driver_support_initialize_hardware() leon2_clock_init()
    95108
    96109#include "../../../shared/dev/clock/clockimpl.h"
  • bsps/sparc/leon3/clock/ckinit.c

    ref23838 r0a1f5df9  
    2828#include <ambapp.h>
    2929#include <rtems/score/profiling.h>
     30#include <rtems/score/sparcimpl.h>
    3031#include <rtems/timecounter.h>
    3132
     
    4344static void (*leon3_tc_tick)(void);
    4445
    45 static rtems_timecounter_simple leon3_tc;
    46 
    47 #ifndef RTEMS_SMP
    48 static uint32_t leon3_tc_get(rtems_timecounter_simple *tc)
    49 {
    50   return LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX].value;
    51 }
    52 
    53 static bool leon3_tc_is_pending(rtems_timecounter_simple *tc)
    54 {
    55   return LEON_Is_interrupt_pending(clkirq);
    56 }
    57 
    58 static void leon3_tc_at_tick( rtems_timecounter_simple *tc )
    59 {
    60   /* Nothing to do */
    61 }
    62 
    63 static uint32_t leon3_tc_get_timecount(struct timecounter *tc)
    64 {
    65   return rtems_timecounter_simple_downcounter_get(
    66     tc,
    67     leon3_tc_get,
    68     leon3_tc_is_pending
    69   );
    70 }
    71 
    72 static void leon3_tc_tick_simple(void)
    73 {
    74   rtems_timecounter_simple_downcounter_tick(
    75     &leon3_tc,
    76     leon3_tc_get,
    77     leon3_tc_at_tick
    78   );
    79 }
    80 #endif
    81 
    82 static uint32_t leon3_tc_get_timecount_up_counter(struct timecounter *tc)
    83 {
    84   return leon3_up_counter_low();
    85 }
    86 
    87 static uint32_t leon3_tc_get_timecount_irqmp(struct timecounter *tc)
    88 {
    89   return LEON3_IrqCtrl_Regs->timestamp[0].counter;
    90 }
    91 
    92 #ifdef RTEMS_SMP
    93 static uint32_t leon3_tc_get_timecount_second_timer(struct timecounter *tc)
    94 {
    95   return 0xffffffff - LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX + 1].value;
    96 }
    97 #endif
     46static struct timecounter leon3_tc;
    9847
    9948#ifdef RTEMS_PROFILING
     
    14796}
    14897
    149 #ifdef RTEMS_SMP
    150 static void leon3_tc_tick_second_timer(void)
    151 {
     98static void leon3_tc_tick_default(void)
     99{
     100#ifndef RTEMS_SMP
     101  SPARC_Counter *counter;
     102  rtems_interrupt_level level;
     103
     104  counter = &_SPARC_Counter_mutable;
     105  rtems_interrupt_local_disable(level);
     106
     107  LEON3_IrqCtrl_Regs->iclear = counter->pending_mask;
     108  counter->accumulated += counter->interval;
     109
     110  rtems_interrupt_local_enable(level);
     111#endif
     112
    152113  rtems_timecounter_tick();
    153114}
    154 #endif
    155115
    156116static void leon3_tc_do_tick(void)
     
    197157  volatile struct irqmp_timestamp_regs *irqmp_ts;
    198158  volatile struct gptimer_regs *gpt;
     159  struct timecounter *tc;
    199160
    200161  irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0];
    201162  gpt = LEON3_Timer_Regs;
     163  tc = &leon3_tc;
    202164
    203165  gpt->timer[LEON3_CLOCK_INDEX].reload =
     
    211173  if (leon3_up_counter_is_available()) {
    212174    /* Use the LEON4 up-counter if available */
    213     leon3_tc.tc.tc_get_timecount = leon3_tc_get_timecount_up_counter;
    214     leon3_tc.tc.tc_counter_mask = 0xffffffff;
    215     leon3_tc.tc.tc_frequency = leon3_up_counter_frequency();
    216     leon3_tc.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
     175    tc->tc_get_timecount = _SPARC_Get_timecount_asr23;
     176    tc->tc_frequency = leon3_up_counter_frequency();
    217177
    218178#ifdef RTEMS_PROFILING
     
    223183
    224184    leon3_tc_tick = leon3_tc_tick_irqmp_timestamp_init;
    225     rtems_timecounter_install(&leon3_tc.tc);
    226185  } else if (leon3_irqmp_has_timestamp(irqmp_ts)) {
    227186    /* Use the interrupt controller timestamp counter if available */
    228     leon3_tc.tc.tc_get_timecount = leon3_tc_get_timecount_irqmp;
    229     leon3_tc.tc.tc_counter_mask = 0xffffffff;
    230     leon3_tc.tc.tc_frequency = ambapp_freq_get(&ambapp_plb, LEON3_Timer_Adev);
    231     leon3_tc.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
     187    tc->tc_get_timecount = _SPARC_Get_timecount_up;
     188    tc->tc_frequency = ambapp_freq_get(&ambapp_plb, LEON3_Timer_Adev);
     189
    232190    leon3_tc_tick = leon3_tc_tick_irqmp_timestamp_init;
    233191
     
    237195     */
    238196    irqmp_ts->control = 0x1;
    239 
    240     rtems_timecounter_install(&leon3_tc.tc);
    241197  } else {
    242198#ifdef RTEMS_SMP
     
    246202     * in free running mode for the timecounter.
    247203     */
    248     gpt->timer[LEON3_CLOCK_INDEX + 1].ctrl =
     204    gpt->timer[LEON3_COUNTER_GPTIMER_INDEX].ctrl =
    249205      GPTIMER_TIMER_CTRL_EN | GPTIMER_TIMER_CTRL_IE;
    250     leon3_tc.tc.tc_get_timecount = leon3_tc_get_timecount_second_timer;
    251     leon3_tc.tc.tc_counter_mask = 0xffffffff;
    252     leon3_tc.tc.tc_frequency = LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER;
    253     leon3_tc.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
    254     leon3_tc_tick = leon3_tc_tick_second_timer;
    255     rtems_timecounter_install(&leon3_tc.tc);
     206
     207    tc->tc_get_timecount = _SPARC_Get_timecount_down;
    256208#else
    257     leon3_tc_tick = leon3_tc_tick_simple;
    258     rtems_timecounter_simple_install(
    259       &leon3_tc,
    260       LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER,
    261       rtems_configuration_get_microseconds_per_tick(),
    262       leon3_tc_get_timecount
    263     );
    264 #endif
     209    SPARC_Counter *counter;
     210
     211    counter = &_SPARC_Counter_mutable;
     212    counter->read_isr_disabled = _SPARC_Counter_read_clock_isr_disabled;
     213    counter->read = _SPARC_Counter_read_clock;
     214    counter->counter_register = &gpt->timer[LEON3_CLOCK_INDEX].value;
     215    counter->pending_register = &LEON3_IrqCtrl_Regs->ipend;
     216    counter->pending_mask = UINT32_C(1) << clkirq;
     217    counter->accumulated = rtems_configuration_get_microseconds_per_tick();
     218    counter->interval = rtems_configuration_get_microseconds_per_tick();
     219
     220    tc->tc_get_timecount = _SPARC_Get_timecount_clock;
     221#endif
     222
     223    tc->tc_frequency = LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER,
     224    leon3_tc_tick = leon3_tc_tick_default;
    265225  }
     226
     227  tc->tc_counter_mask = 0xffffffff;
     228  tc->tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
     229  rtems_timecounter_install(tc);
    266230}
    267231
  • bsps/sparc/leon3/include/leon.h

    ref23838 r0a1f5df9  
    334334#endif
    335335
     336#if defined(RTEMS_SMP)
     337#define LEON3_COUNTER_GPTIMER_INDEX (LEON3_CLOCK_INDEX + 1)
     338#else
     339#define LEON3_COUNTER_GPTIMER_INDEX LEON3_CLOCK_INDEX
     340#endif
     341
    336342/*
    337343 * We assume that a boot loader (usually GRMON) initialized the GPTIMER 0 to
  • bsps/sparc/leon3/start/cpucounter.c

    ref23838 r0a1f5df9  
    11/*
    2  * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
     2 * Copyright (c) 2014, 2018 embedded brains GmbH.  All rights reserved.
    33 *
    44 *  embedded brains GmbH
     
    3030  volatile struct irqmp_timestamp_regs *irqmp_ts;
    3131  volatile struct gptimer_regs *gpt;
     32  SPARC_Counter *counter;
    3233
    3334  irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0];
    3435  gpt = LEON3_Timer_Regs;
     36  counter = &_SPARC_Counter_mutable;
    3537
    3638  leon3_up_counter_enable();
     
    3840  if (leon3_up_counter_is_available()) {
    3941    /* Use the LEON4 up-counter if available */
    40 
    41     _SPARC_Counter_initialize(
    42       _SPARC_Counter_read_asr23,
    43       _SPARC_Counter_difference_normal,
    44       NULL
    45     );
     42    counter->read_isr_disabled = _SPARC_Counter_read_asr23;
     43    counter->read = _SPARC_Counter_read_asr23;
    4644
    4745    leon3_counter_frequency = leon3_up_counter_frequency();
    4846  } else if (leon3_irqmp_has_timestamp(irqmp_ts)) {
    4947    /* Use the interrupt controller timestamp counter if available */
     48    counter->read_isr_disabled = _SPARC_Counter_read_up;
     49    counter->read = _SPARC_Counter_read_up;
     50    counter->counter_register = &LEON3_IrqCtrl_Regs->timestamp[0].counter;
    5051
    5152    /* Enable interrupt timestamping for an arbitrary interrupt line */
    5253    irqmp_ts->control = 0x1;
    5354
    54     _SPARC_Counter_initialize(
    55       _SPARC_Counter_read_address,
    56       _SPARC_Counter_difference_normal,
    57       (volatile const uint32_t *) &irqmp_ts->counter
    58     );
    59 
    6055    leon3_counter_frequency = ambapp_freq_get(&ambapp_plb, LEON3_IrqCtrl_Adev);
    6156  } else if (gpt != NULL) {
    6257    /* Fall back to the first GPTIMER if available */
     58    counter->read_isr_disabled = _SPARC_Counter_read_down;
     59    counter->read = _SPARC_Counter_read_down;
     60    counter->counter_register = &gpt->timer[LEON3_COUNTER_GPTIMER_INDEX].value;
    6361
    6462    /* Enable timer just in case no clock driver is configured */
    65     gpt->timer[LEON3_CLOCK_INDEX].ctrl |= GPTIMER_TIMER_CTRL_EN;
    66 
    67     _SPARC_Counter_initialize(
    68       _SPARC_Counter_read_address,
    69       _SPARC_Counter_difference_clock_period,
    70       (volatile const uint32_t *) &gpt->timer[LEON3_CLOCK_INDEX].value
    71     );
     63    gpt->timer[LEON3_COUNTER_GPTIMER_INDEX].ctrl |= GPTIMER_TIMER_CTRL_EN;
    7264
    7365    leon3_counter_frequency = ambapp_freq_get(&ambapp_plb, LEON3_Timer_Adev) /
  • c/src/lib/libbsp/sparc/leon2/Makefile.am

    ref23838 r0a1f5df9  
    2727librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon2/start/bspstart.c
    2828librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/start/bspgetworkarea.c
    29 librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/cpucounter/cpucounterfrequency.c
    3029librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy-cpucounter.c
    3130librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/sbrk.c
  • cpukit/Makefile.am

    ref23838 r0a1f5df9  
    17541754librtemscpu_a_SOURCES += score/cpu/sparc/sparc-context-volatile-clobber.S
    17551755librtemscpu_a_SOURCES += score/cpu/sparc/sparc-counter-asm.S
    1756 librtemscpu_a_SOURCES += score/cpu/sparc/sparc-counter.c
    17571756librtemscpu_a_SOURCES += score/cpu/sparc/syscall.S
    17581757librtemscpu_a_SOURCES += score/cpu/sparc/window.S
  • cpukit/score/cpu/no_cpu/include/rtems/score/cpu.h

    ref23838 r0a1f5df9  
    12201220 * @return Returns second minus first modulo counter period.
    12211221 */
    1222 CPU_Counter_ticks _CPU_Counter_difference(
     1222static inline CPU_Counter_ticks _CPU_Counter_difference(
    12231223  CPU_Counter_ticks second,
    12241224  CPU_Counter_ticks first
    1225 );
     1225)
     1226{
     1227  return second - first;
     1228}
    12261229
    12271230#ifdef RTEMS_SMP
  • cpukit/score/cpu/or1k/include/rtems/score/cpu.h

    ref23838 r0a1f5df9  
    713713CPU_Counter_ticks _CPU_Counter_read( void );
    714714
    715 CPU_Counter_ticks _CPU_Counter_difference(
     715static inline CPU_Counter_ticks _CPU_Counter_difference(
    716716  CPU_Counter_ticks second,
    717717  CPU_Counter_ticks first
    718 );
     718)
     719{
     720  return second - first;
     721}
    719722
    720723/** Type that can store a 32-bit integer or a pointer. */
  • cpukit/score/cpu/sparc/include/rtems/score/cpu.h

    ref23838 r0a1f5df9  
    11041104typedef CPU_Counter_ticks ( *SPARC_Counter_read )( void );
    11051105
    1106 typedef CPU_Counter_ticks ( *SPARC_Counter_difference )(
    1107   CPU_Counter_ticks second,
    1108   CPU_Counter_ticks first
    1109 );
    1110 
    11111106/*
    11121107 * The SPARC processors supported by RTEMS have no built-in CPU counter
    11131108 * support.  We have to use some hardware counter module for this purpose, for
    11141109 * example the GPTIMER instance used by the clock driver.  The BSP must provide
    1115  * an implementation of the CPU counter read and difference functions.  This
    1116  * allows the use of dynamic hardware enumeration.
     1110 * an implementation of the CPU counter read function.  This allows the use of
     1111 * dynamic hardware enumeration.
    11171112 */
    11181113typedef struct {
    1119   SPARC_Counter_read                counter_read;
    1120   SPARC_Counter_difference          counter_difference;
    1121   volatile const CPU_Counter_ticks *counter_address;
     1114  SPARC_Counter_read                read_isr_disabled;
     1115  SPARC_Counter_read                read;
     1116  volatile const CPU_Counter_ticks *counter_register;
     1117  volatile const uint32_t          *pending_register;
     1118  uint32_t                          pending_mask;
     1119  CPU_Counter_ticks                 accumulated;
     1120  CPU_Counter_ticks                 interval;
    11221121} SPARC_Counter;
    11231122
     
    11261125static inline CPU_Counter_ticks _CPU_Counter_read( void )
    11271126{
    1128   return ( *_SPARC_Counter.counter_read )();
     1127  return ( *_SPARC_Counter.read )();
    11291128}
    11301129
     
    11341133)
    11351134{
    1136   return ( *_SPARC_Counter.counter_difference )( second, first );
     1135  return second - first;
    11371136}
    11381137
  • cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h

    ref23838 r0a1f5df9  
    11/*
    2  * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
     2 * Copyright (c) 2016, 2018 embedded brains GmbH.  All rights reserved.
    33 *
    44 *  embedded brains GmbH
     
    2222#endif /* __cplusplus */
    2323
     24struct timecounter;
     25
    2426/*
    2527 * Provides a mutable alias to _SPARC_Counter for use in
     
    2931extern SPARC_Counter _SPARC_Counter_mutable;
    3032
    31 CPU_Counter_ticks _SPARC_Counter_read_address( void );
     33void _SPARC_Counter_at_tick_clock( void );
     34
     35CPU_Counter_ticks _SPARC_Counter_read_default( void );
     36
     37CPU_Counter_ticks _SPARC_Counter_read_up( void );
     38
     39CPU_Counter_ticks _SPARC_Counter_read_down( void );
     40
     41CPU_Counter_ticks _SPARC_Counter_read_clock_isr_disabled( void );
     42
     43CPU_Counter_ticks _SPARC_Counter_read_clock( void );
    3244
    3345CPU_Counter_ticks _SPARC_Counter_read_asr23( void );
    3446
    35 CPU_Counter_ticks _SPARC_Counter_difference_normal(
    36   CPU_Counter_ticks second,
    37   CPU_Counter_ticks first
    38 );
     47uint32_t _SPARC_Get_timecount_up( struct timecounter * );
    3948
    40 CPU_Counter_ticks _SPARC_Counter_difference_clock_period(
    41   CPU_Counter_ticks second,
    42   CPU_Counter_ticks first
    43 );
     49uint32_t _SPARC_Get_timecount_down( struct timecounter * );
    4450
    45 /*
    46  * Returns always a value of one regardless of the parameters.  This prevents
    47  * an infinite loop in rtems_counter_delay_ticks().  Its only a reasonably safe
    48  * default.
    49  */
    50 CPU_Counter_ticks _SPARC_Counter_difference_one(
    51   CPU_Counter_ticks second,
    52   CPU_Counter_ticks first
    53 );
     51uint32_t _SPARC_Get_timecount_clock( struct timecounter * );
    5452
    55 static inline void _SPARC_Counter_initialize(
    56   SPARC_Counter_read                counter_read,
    57   SPARC_Counter_difference          counter_difference,
    58   volatile const CPU_Counter_ticks *counter_address
    59 )
    60 {
    61   _SPARC_Counter_mutable.counter_read = counter_read;
    62   _SPARC_Counter_mutable.counter_difference = counter_difference;
    63   _SPARC_Counter_mutable.counter_address = counter_address;
    64 }
     53uint32_t _SPARC_Get_timecount_asr23( struct timecounter * );
    6554
    6655/*
     
    7665    "\t.align\t4\n" \
    7766    "\t.type\t_SPARC_Counter, #object\n" \
    78     "\t.size\t_SPARC_Counter, 12\n" \
     67    "\t.size\t_SPARC_Counter, 28\n" \
    7968    "_SPARC_Counter:\n" \
    8069    "_SPARC_Counter_mutable:\n" \
    81     "\t.long\t_SPARC_Counter_read_address\n" \
    82     "\t.long\t_SPARC_Counter_difference_one\n" \
    83     "\t.long\t_SPARC_Counter\n" \
     70    "\t.long\t_SPARC_Counter_read_default\n" \
     71    "\t.long\t_SPARC_Counter_read_default\n" \
     72    "\t.long\t0\n" \
     73    "\t.long\t0\n" \
     74    "\t.long\t0\n" \
     75    "\t.long\t0\n" \
     76    "\t.long\t0\n" \
    8477    "\t.previous\n" \
    8578  )
  • cpukit/score/cpu/sparc/sparc-counter-asm.S

    ref23838 r0a1f5df9  
    11/*
    2  * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
     2 * Copyright (c) 2016, 2018 embedded brains GmbH.  All rights reserved.
    33 *
    44 *  embedded brains GmbH
     
    1919#include <rtems/asm.h>
    2020
     21        /*
     22         * All functions except _SPARC_Counter_read_clock() in this module are
     23         * sometimes called with traps disabled.
     24         */
     25
    2126        .section        ".text"
    2227        .align  4
    2328
    24         PUBLIC(_SPARC_Counter_read_address)
    25 SYM(_SPARC_Counter_read_address):
     29        PUBLIC(_SPARC_Counter_read_default)
     30SYM(_SPARC_Counter_read_default):
     31        sethi   %hi(_SPARC_Counter + 12), %o1
     32        ld      [%o1 + %lo(_SPARC_Counter + 12)], %o0
     33        add     %o0, 1, %o0
     34        jmp     %o7 + 8
     35         st     %o0, [%o1 + %lo(_SPARC_Counter + 12)]
     36
     37        PUBLIC(_SPARC_Counter_read_up)
     38        PUBLIC(_SPARC_Get_timecount_up)
     39SYM(_SPARC_Counter_read_up):
     40SYM(_SPARC_Get_timecount_up):
    2641        sethi   %hi(_SPARC_Counter + 8), %o0
    2742        ld      [%o0 + %lo(_SPARC_Counter + 8)], %o0
     
    2944         ld     [%o0], %o0
    3045
     46        PUBLIC(_SPARC_Counter_read_down)
     47        PUBLIC(_SPARC_Get_timecount_down)
     48SYM(_SPARC_Counter_read_down):
     49SYM(_SPARC_Get_timecount_down):
     50        sethi   %hi(_SPARC_Counter + 8), %o0
     51        ld      [%o0 + %lo(_SPARC_Counter + 8)], %o0
     52        ld      [%o0], %o0
     53        jmp     %o7 + 8
     54         xnor   %g0, %o0, %o0
     55
     56        /*
     57         * For the corresponding C code is something like this:
     58         *
     59         * CPU_Counter_ticks _SPARC_Counter_read_clock_isr_disabled( void )
     60         * {
     61         *   const SPARC_Counter *ctr;
     62         *   CPU_Counter_ticks    ticks;
     63         *   CPU_Counter_ticks    accumulated;
     64         *
     65         *   ctr = &_SPARC_Counter;
     66         *   ticks = *ctr->counter_register;
     67         *   accumulated = ctr->accumulated;
     68         *
     69         *   if ( ( *ctr->pending_register & ctr->pending_mask ) != 0 ) {
     70         *     ticks = *ctr->counter_register;
     71         *     accumulated += ctr->interval;
     72         *   }
     73         *
     74         *   return accumulated - ticks;
     75         * }
     76         */
     77        PUBLIC(_SPARC_Counter_read_clock_isr_disabled)
     78SYM(_SPARC_Counter_read_clock_isr_disabled):
     79        sethi   %hi(_SPARC_Counter), %o5
     80        or      %o5, %lo(_SPARC_Counter), %o5
     81        ld      [%o5 + 8], %o3
     82        ld      [%o5 + 12], %o4
     83        ld      [%o5 + 16], %o2
     84        ld      [%o3], %o0
     85        ld      [%o4], %o1
     86        btst    %o1, %o2
     87        bne     .Lpending_isr_disabled
     88         ld     [%o5 + 20], %o4
     89        jmp     %o7 + 8
     90         sub    %o4, %o0, %o0
     91.Lpending_isr_disabled:
     92        ld      [%o5 + 24], %o5
     93        ld      [%o3], %o0
     94        add     %o4, %o5, %o4
     95        jmp     %o7 + 8
     96         sub    %o4, %o0, %o0
     97
     98        /*
     99         * For the corresponding C code see
     100         * _SPARC_Counter_read_clock_isr_disabled() above.
     101         */
     102        PUBLIC(_SPARC_Counter_read_clock)
     103        PUBLIC(_SPARC_Get_timecount_clock)
     104SYM(_SPARC_Counter_read_clock):
     105SYM(_SPARC_Get_timecount_clock):
     106        sethi   %hi(_SPARC_Counter), %o5
     107        or      %o5, %lo(_SPARC_Counter), %o5
     108        ta      SPARC_SWTRAP_IRQDIS
     109        ld      [%o5 + 8], %o3
     110        ld      [%o5 + 12], %o4
     111        ld      [%o5 + 16], %o2
     112        ld      [%o3], %o0
     113        ld      [%o4], %o1
     114        btst    %o1, %o2
     115        bne     .Lpending
     116         ld     [%o5 + 20], %o4
     117        ta      SPARC_SWTRAP_IRQEN
     118        jmp     %o7 + 8
     119         sub    %o4, %o0, %o0
     120.Lpending:
     121        ld      [%o5 + 24], %o5
     122        ld      [%o3], %o0
     123        ta      SPARC_SWTRAP_IRQEN
     124        add     %o4, %o5, %o4
     125        jmp     %o7 + 8
     126         sub    %o4, %o0, %o0
     127
    31128        PUBLIC(_SPARC_Counter_read_asr23)
     129        PUBLIC(_SPARC_Get_timecount_asr23)
    32130SYM(_SPARC_Counter_read_asr23):
     131SYM(_SPARC_Get_timecount_asr23):
    33132        jmp     %o7 + 8
    34133         mov    %asr23, %o0
Note: See TracChangeset for help on using the changeset viewer.