source: rtems/bsps/or1k/generic_or1k/clock/clockdrv.c @ 0a1f5df9

5
Last change on this file since 0a1f5df9 was 0a1f5df9, checked in by Sebastian Huber <sebastian.huber@…>, on 05/03/18 at 11:03:27

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.

  • Property mode set to 100644
File size: 3.4 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup bsp_clock
5 *
6 * @brief or1k clock support.
7 */
8
9/*
10 * generic_or1k Clock driver
11 *
12 * COPYRIGHT (c) 2014-2015 Hesham ALMatary <heshamelmatary@gmail.com>
13 *
14 * The license and distribution terms for this file may be
15 * found in the file LICENSE in this distribution or at
16 * http://www.rtems.org/license/LICENSE
17 */
18
19#include <rtems.h>
20#include <bsp.h>
21#include <bsp/irq.h>
22#include <bsp/generic_or1k.h>
23#include <rtems/score/cpu.h>
24#include <rtems/score/or1k-utility.h>
25#include <rtems/timecounter.h>
26
27/* The number of clock cycles before generating a tick timer interrupt. */
28#define TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT     0x09ED9
29#define OR1K_CLOCK_CYCLE_TIME_NANOSECONDS     10
30
31static struct timecounter or1ksim_tc;
32
33/* CPU counter */
34static CPU_Counter_ticks cpu_counter_ticks;
35
36static void generic_or1k_clock_at_tick(void)
37{
38  uint32_t TTMR;
39
40 /* For TTMR register,
41  * The least significant 28 bits are the number of clock cycles
42  * before generating a tick timer interrupt. While the most
43  * significant 4 bits are used for mode configuration, tick timer
44  * interrupt enable and pending interrupts status.
45  */
46  TTMR = (CPU_OR1K_SPR_TTMR_MODE_RESTART | CPU_OR1K_SPR_TTMR_IE |
47           (TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT & CPU_OR1K_SPR_TTMR_TP_MASK)
48         ) & ~(CPU_OR1K_SPR_TTMR_IP);
49
50  _OR1K_mtspr(CPU_OR1K_SPR_TTMR, TTMR);
51  _OR1K_mtspr(CPU_OR1K_SPR_TTCR, 0);
52
53  cpu_counter_ticks += TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT;
54}
55
56static void generic_or1k_clock_handler_install(CPU_ISR_handler new_isr)
57{
58  rtems_status_code sc = RTEMS_SUCCESSFUL;
59  _CPU_ISR_install_vector(OR1K_EXCEPTION_TICK_TIMER,
60                          new_isr,
61                          NULL);
62
63  if (sc != RTEMS_SUCCESSFUL) {
64    rtems_fatal_error_occurred(0xdeadbeef);
65  }
66}
67
68static uint32_t or1ksim_get_timecount(struct timecounter *tc)
69{
70  uint32_t ticks_since_last_timer_interrupt;
71
72  ticks_since_last_timer_interrupt = _OR1K_mfspr(CPU_OR1K_SPR_TTCR);
73
74  return cpu_counter_ticks + ticks_since_last_timer_interrupt;
75}
76
77CPU_Counter_ticks _CPU_Counter_read(void)
78{
79  return or1ksim_get_timecount(NULL);
80}
81
82static void generic_or1k_clock_initialize(void)
83{
84  uint64_t frequency = (1000000000 / OR1K_CLOCK_CYCLE_TIME_NANOSECONDS);
85  uint32_t TTMR;
86
87 /* For TTMR register,
88  * The least significant 28 bits are the number of clock cycles
89  * before generating a tick timer interrupt. While the most
90  * significant 4 bits are used for mode configuration, tick timer
91  * interrupt enable and pending interrupts status.
92  */
93
94  /* FIXME: Long interval should pass since initializing the tick timer
95   * registers fires exceptions dispite interrupts has not been enabled yet.
96   */
97  TTMR = (CPU_OR1K_SPR_TTMR_MODE_RESTART | CPU_OR1K_SPR_TTMR_IE |
98           (0xFFED9 & CPU_OR1K_SPR_TTMR_TP_MASK)
99         ) & ~(CPU_OR1K_SPR_TTMR_IP);
100
101  _OR1K_mtspr(CPU_OR1K_SPR_TTMR, TTMR);
102  _OR1K_mtspr(CPU_OR1K_SPR_TTCR, 0);
103
104  /* Initialize timecounter */
105  or1ksim_tc.tc_get_timecount = or1ksim_get_timecount;
106  or1ksim_tc.tc_counter_mask = 0xffffffff;
107  or1ksim_tc.tc_frequency = frequency;
108  or1ksim_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
109  rtems_timecounter_install(&or1ksim_tc);
110}
111
112#define Clock_driver_support_at_tick() generic_or1k_clock_at_tick()
113
114#define Clock_driver_support_initialize_hardware() generic_or1k_clock_initialize()
115
116#define Clock_driver_support_install_isr(isr) \
117  generic_or1k_clock_handler_install(isr)
118
119#include "../../../shared/dev/clock/clockimpl.h"
Note: See TracBrowser for help on using the repository browser.