Changeset 9460333e in rtems


Ignore:
Timestamp:
Jun 20, 2016, 8:08:39 AM (3 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
291945f1
Parents:
4c927c79
git-author:
Sebastian Huber <sebastian.huber@…> (06/20/16 08:08:39)
git-committer:
Sebastian Huber <sebastian.huber@…> (06/21/16 13:54:18)
Message:

sparc: Rework CPU counter support

Rework CPU counter support to enable use of the GR740 up-counter via
%asr22 and %asr23.

Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/erc32/clock/ckinit.c

    r4c927c79 r9460333e  
    8484}
    8585
    86 static CPU_Counter_ticks erc32_counter_difference(
    87   CPU_Counter_ticks second,
    88   CPU_Counter_ticks first
    89 )
     86static void erc32_counter_initialize( uint32_t frequency )
    9087{
    91   CPU_Counter_ticks period = rtems_configuration_get_microseconds_per_tick();
    92 
    93   return (first + period - second) % period;
     88  _SPARC_Counter_initialize(
     89    _SPARC_Counter_read_address,
     90    _SPARC_Counter_difference_clock_period,
     91    &ERC32_MEC.Real_Time_Clock_Counter
     92  );
     93  rtems_counter_initialize_converter( frequency );
    9494}
    9595
     
    118118        erc32_tc_get_timecount \
    119119    ); \
    120     _SPARC_Counter_initialize( \
    121       &ERC32_MEC.Real_Time_Clock_Counter, \
    122       erc32_counter_difference \
    123     ); \
    124     rtems_counter_initialize_converter( frequency ); \
     120    erc32_counter_initialize( frequency ); \
    125121  } while (0)
    126122
     
    138134#include "../../../shared/clockdrv_shell.h"
    139135
     136SPARC_Counter _SPARC_Counter = {
     137  .counter_read = _SPARC_Counter_read_address,
     138  .counter_difference = _SPARC_Counter_difference_one,
     139  .counter_address = (uint32_t *) &_SPARC_Counter
     140};
  • c/src/lib/libbsp/sparc/leon2/clock/ckinit.c

    r4c927c79 r9460333e  
    106106
    107107#include "../../../shared/clockdrv_shell.h"
     108
     109SPARC_Counter _SPARC_Counter = {
     110  .counter_read = _SPARC_Counter_read_address,
     111  .counter_difference = _SPARC_Counter_difference_one,
     112  .counter_address = (uint32_t *) &_SPARC_Counter
     113};
  • c/src/lib/libbsp/sparc/leon3/include/leon.h

    r4c927c79 r9460333e  
    388388extern unsigned int leon3_timer_prescaler;
    389389
    390 void leon3_cpu_counter_initialize(void);
    391 
    392390/* GRLIB extended IRQ controller register */
    393391void leon3_ext_irq_init(void);
     
    458456}
    459457
     458static inline uint32_t leon3_up_counter_low(void)
     459{
     460  uint32_t asr23;
     461
     462  __asm__ volatile (
     463    "mov %%asr23, %0"
     464    : "=&r" (asr23)
     465  );
     466
     467  return asr23;
     468}
     469
     470static inline uint32_t leon3_up_counter_high(void)
     471{
     472  uint32_t asr22;
     473
     474  __asm__ volatile (
     475    "mov %%asr22, %0"
     476    : "=&r" (asr22)
     477  );
     478
     479  return asr22;
     480}
     481
     482static inline void leon3_up_counter_enable(void)
     483{
     484  __asm__ volatile (
     485    "mov %g0, %asr23"
     486  );
     487}
     488
     489static inline bool leon3_up_counter_is_available(void)
     490{
     491  return leon3_up_counter_low() != leon3_up_counter_low();
     492}
     493
     494static inline uint32_t leon3_up_counter_frequency(void)
     495{
     496  /*
     497   * For simplicity, assume that the interrupt controller uses the processor
     498   * clock.  This is at least true on the GR740.
     499   */
     500  return ambapp_freq_get(&ambapp_plb, LEON3_IrqCtrl_Adev);
     501}
     502
    460503#endif /* !ASM */
    461504
  • c/src/lib/libbsp/sparc/leon3/startup/bspstart.c

    r4c927c79 r9460333e  
    5959{
    6060  CPU_SPARC_HAS_SNOOPING = set_snooping();
    61 
    62   leon3_cpu_counter_initialize();
    6361}
    6462
  • c/src/lib/libbsp/sparc/leon3/startup/cpucounter.c

    r4c927c79 r9460333e  
    11/*
    2  * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
     2 * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
    33 *
    44 *  embedded brains GmbH
     
    1616
    1717#include <rtems/counter.h>
     18#include <rtems/sysinit.h>
    1819
    19 static CPU_Counter_ticks timestamp_counter_difference(
    20   CPU_Counter_ticks second,
    21   CPU_Counter_ticks first
    22 )
     20static void leon3_counter_initialize(void)
    2321{
    24   return second - first;
    25 }
    26 
    27 static CPU_Counter_ticks clock_counter_difference(
    28   CPU_Counter_ticks second,
    29   CPU_Counter_ticks first
    30 )
    31 {
    32   CPU_Counter_ticks period = rtems_configuration_get_microseconds_per_tick();
    33 
    34   return (first + period - second) % period;
    35 }
    36 
    37 static void gpt_counter_initialize(
    38   volatile struct gptimer_regs *gpt,
    39   size_t timer_index,
    40   uint32_t frequency,
    41   SPARC_Counter_difference counter_difference
    42 )
    43 {
    44   _SPARC_Counter_initialize(
    45     (volatile const uint32_t *) &gpt->timer[timer_index].value,
    46     counter_difference
    47   );
    48 
    49   rtems_counter_initialize_converter(frequency);
    50 }
    51 
    52 void leon3_cpu_counter_initialize(void)
    53 {
    54   volatile struct irqmp_timestamp_regs *irqmp_ts =
    55     &LEON3_IrqCtrl_Regs->timestamp[0];
     22  volatile struct irqmp_timestamp_regs *irqmp_ts;
     23  volatile struct gptimer_regs *gpt;
    5624  unsigned int freq;
    5725
    58   if (leon3_irqmp_has_timestamp(irqmp_ts)) {
     26  irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0];
     27  gpt = LEON3_Timer_Regs;
     28
     29  leon3_up_counter_enable();
     30
     31  if (leon3_up_counter_is_available()) {
     32    /* Use the LEON4 up-counter if available */
     33
     34    _SPARC_Counter_initialize(
     35      _SPARC_Counter_read_asr23,
     36      _SPARC_Counter_difference_normal,
     37      NULL
     38    );
     39
     40    freq = leon3_up_counter_frequency();
     41    rtems_counter_initialize_converter(freq);
     42  } else if (leon3_irqmp_has_timestamp(irqmp_ts)) {
    5943    /* Use the interrupt controller timestamp counter if available */
    6044
     
    6347
    6448    _SPARC_Counter_initialize(
    65       (volatile const uint32_t *) &irqmp_ts->counter,
    66       timestamp_counter_difference
     49      _SPARC_Counter_read_address,
     50      _SPARC_Counter_difference_normal,
     51      (volatile const uint32_t *) &irqmp_ts->counter
    6752    );
    6853
    69     /* Get and set the frequency */
    70     rtems_counter_initialize_converter(
    71       ambapp_freq_get(&ambapp_plb, LEON3_IrqCtrl_Adev));
    72   } else if (LEON3_Timer_Regs != NULL) {
    73       /* Fall back to the first GPTIMER if available */
    74       freq = ambapp_freq_get(&ambapp_plb, LEON3_Timer_Adev);
     54    freq = ambapp_freq_get(&ambapp_plb, LEON3_IrqCtrl_Adev);
     55    rtems_counter_initialize_converter(freq);
     56  } else if (gpt != NULL) {
     57    /* Fall back to the first GPTIMER if available */
    7558
    76       gpt_counter_initialize(
    77         LEON3_Timer_Regs,
    78         LEON3_CLOCK_INDEX,
    79         freq / (LEON3_Timer_Regs->scaler_reload - 1),
    80         clock_counter_difference
    81       );
     59    _SPARC_Counter_initialize(
     60      _SPARC_Counter_read_address,
     61      _SPARC_Counter_difference_clock_period,
     62      (volatile const uint32_t *) &gpt->timer[LEON3_CLOCK_INDEX].value
     63    );
     64
     65    freq = ambapp_freq_get(&ambapp_plb, LEON3_Timer_Adev);
     66    rtems_counter_initialize_converter(freq / (gpt->scaler_reload - 1));
    8267  }
    8368}
     69
     70RTEMS_SYSINIT_ITEM(
     71  leon3_counter_initialize,
     72  RTEMS_SYSINIT_BSP_START,
     73  RTEMS_SYSINIT_ORDER_THIRD
     74);
     75
     76SPARC_Counter _SPARC_Counter = {
     77  .counter_read = _SPARC_Counter_read_address,
     78  .counter_difference = _SPARC_Counter_difference_one,
     79  .counter_address = (uint32_t *) &_SPARC_Counter
     80};
  • c/src/lib/libbsp/sparc/shared/irq_asm.S

    r4c927c79 r9460333e  
    452452        bnz      dont_switch_stacks      ! No, then do not switch stacks
    453453
    454 #if defined( RTEMS_PROFILING )
    455          sethi   %hi(SYM(_SPARC_Counter)), %o5
    456         ld       [%o5 + %lo(SYM(_SPARC_Counter))], %l4
    457         ld       [%l4], %o5
     454#if defined(RTEMS_PROFILING)
     455         sethi   %hi(_SPARC_Counter), %o5
     456        ld       [%o5 + %lo(_SPARC_Counter)], %l4
     457        call     %l4, 0
     458         nop
     459        mov      %o0, %o5
    458460#else
    459461         nop
     
    537539        mov      %l3, %o0               ! o0 = 1st arg = vector number
    538540        call     %g4, 0
    539 #if defined( RTEMS_PROFILING )
     541#if defined(RTEMS_PROFILING)
    540542         mov     %o5, %l3               ! save interrupt entry instant
    541543        cmp      %l7, 0
     
    543545         nop
    544546        ta       SPARC_SWTRAP_IRQDIS    ! Call interrupt disable trap handler
    545         ld       [%l4], %o2             ! o2 = 3rd arg = interrupt exit instant
     547        call     %l4, 0                 ! Call _SPARC_Counter.counter_read
     548         nop
     549        mov      %o0, %o2               ! o2 = 3rd arg = interrupt exit instant
    546550        mov      %l3, %o1               ! o1 = 2nd arg = interrupt entry instant
    547551        call     SYM(_Profiling_Outer_most_interrupt_entry_and_exit), 0
  • cpukit/score/cpu/sparc/Makefile.am

    r4c927c79 r9460333e  
    1515libscorecpu_a_SOURCES += sparc-context-validate.S
    1616libscorecpu_a_SOURCES += sparc-counter.c
     17libscorecpu_a_SOURCES += sparc-counter-asm.S
    1718libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
    1819
  • cpukit/score/cpu/sparc/rtems/score/cpu.h

    r4c927c79 r9460333e  
    13051305typedef uint32_t CPU_Counter_ticks;
    13061306
     1307typedef CPU_Counter_ticks ( *SPARC_Counter_read )( void );
     1308
    13071309typedef CPU_Counter_ticks (*SPARC_Counter_difference)(
    13081310  CPU_Counter_ticks second,
     
    13121314/*
    13131315 * The SPARC processors supported by RTEMS have no built-in CPU counter
    1314  * support.  We have to use some hardware counter module for this purpose.  The
    1315  * BSP must provide a 32-bit register which contains the current CPU counter
    1316  * value and a function for the difference calculation.  It can use for example
    1317  * the GPTIMER instance used for the clock driver.
     1316 * support.  We have to use some hardware counter module for this purpose, for
     1317 * example the GPTIMER instance used by the clock driver.  The BSP must provide
     1318 * an implementation of the CPU counter read and difference functions.  This
     1319 * allows the use of dynamic hardware enumeration.
    13181320 */
    13191321typedef struct {
    1320   volatile const CPU_Counter_ticks *counter_register;
    1321   SPARC_Counter_difference counter_difference;
     1322  SPARC_Counter_read                counter_read;
     1323  SPARC_Counter_difference          counter_difference;
     1324  volatile const CPU_Counter_ticks *counter_address;
    13221325} SPARC_Counter;
    13231326
    13241327extern SPARC_Counter _SPARC_Counter;
     1328
     1329CPU_Counter_ticks _SPARC_Counter_read_address( void );
     1330
     1331CPU_Counter_ticks _SPARC_Counter_read_asr23( void );
     1332
     1333CPU_Counter_ticks _SPARC_Counter_difference_normal(
     1334  CPU_Counter_ticks second,
     1335  CPU_Counter_ticks first
     1336);
     1337
     1338CPU_Counter_ticks _SPARC_Counter_difference_clock_period(
     1339  CPU_Counter_ticks second,
     1340  CPU_Counter_ticks first
     1341);
    13251342
    13261343/*
     
    13291346 * default.
    13301347 */
    1331 CPU_Counter_ticks _SPARC_Counter_difference_default(
     1348CPU_Counter_ticks _SPARC_Counter_difference_one(
    13321349  CPU_Counter_ticks second,
    13331350  CPU_Counter_ticks first
    13341351);
    13351352
    1336 static inline bool _SPARC_Counter_is_default( void )
    1337 {
    1338   return _SPARC_Counter.counter_difference
    1339     == _SPARC_Counter_difference_default;
    1340 }
    1341 
    13421353static inline void _SPARC_Counter_initialize(
    1343   volatile const CPU_Counter_ticks *counter_register,
    1344   SPARC_Counter_difference counter_difference
     1354  SPARC_Counter_read                counter_read,
     1355  SPARC_Counter_difference          counter_difference,
     1356  volatile const CPU_Counter_ticks *counter_address
    13451357)
    13461358{
    1347   _SPARC_Counter.counter_register = counter_register;
     1359  _SPARC_Counter.counter_read = counter_read;
    13481360  _SPARC_Counter.counter_difference = counter_difference;
     1361  _SPARC_Counter.counter_address = counter_address;
    13491362}
    13501363
    13511364static inline CPU_Counter_ticks _CPU_Counter_read( void )
    13521365{
    1353   return *_SPARC_Counter.counter_register;
     1366  return ( *_SPARC_Counter.counter_read )();
    13541367}
    13551368
     
    13591372)
    13601373{
    1361   return (*_SPARC_Counter.counter_difference)( second, first );
     1374  return ( *_SPARC_Counter.counter_difference )( second, first );
    13621375}
    13631376
  • cpukit/score/cpu/sparc/sparc-counter.c

    r4c927c79 r9460333e  
    11/*
    2  * Copyright (c) 2014 embedded brains GmbH.  All rights reserved.
     2 * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
    33 *
    44 *  embedded brains GmbH
     
    1818
    1919#include <rtems/score/cpu.h>
     20#include <rtems/config.h>
    2021
    21 static CPU_Counter_ticks _SPARC_Counter_register_dummy;
     22CPU_Counter_ticks _SPARC_Counter_difference_normal(
     23  CPU_Counter_ticks second,
     24  CPU_Counter_ticks first
     25)
     26{
     27  return second - first;
     28}
    2229
    23 CPU_Counter_ticks _SPARC_Counter_difference_default(
     30CPU_Counter_ticks _SPARC_Counter_difference_clock_period(
     31  CPU_Counter_ticks second,
     32  CPU_Counter_ticks first
     33)
     34{
     35  CPU_Counter_ticks period;
     36
     37  period = rtems_configuration_get_microseconds_per_tick();
     38
     39  return ( first + period - second ) % period;
     40}
     41
     42CPU_Counter_ticks _SPARC_Counter_difference_one(
    2443  CPU_Counter_ticks second,
    2544  CPU_Counter_ticks first
     
    2847  return 1;
    2948}
    30 
    31 SPARC_Counter _SPARC_Counter = {
    32   .counter_register = &_SPARC_Counter_register_dummy,
    33   .counter_difference = _SPARC_Counter_difference_default
    34 };
Note: See TracChangeset for help on using the changeset viewer.