summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Krutwig <alexander.krutwig@embedded-brains.de>2015-04-01 15:33:25 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-05-20 08:40:34 +0200
commit75acd9e69f906cbd880a17ee4ca705ad7caa92c0 (patch)
tree71529028154cb323286b02392def2e5277eed312
parenttimecounter: Use in RTEMS (diff)
downloadrtems-75acd9e69f906cbd880a17ee4ca705ad7caa92c0.tar.bz2
bsps: Convert clock drivers to use a timecounter
Update #2271.
-rw-r--r--c/src/lib/libbsp/arm/beagle/clock.c35
-rw-r--r--c/src/lib/libbsp/arm/edb7312/clock/clockdrv.c2
-rw-r--r--c/src/lib/libbsp/arm/gba/clock/clockdrv.c2
-rw-r--r--c/src/lib/libbsp/arm/lpc176x/include/lpc-clock-config.h1
-rw-r--r--c/src/lib/libbsp/arm/lpc24xx/include/lpc-clock-config.h2
-rw-r--r--c/src/lib/libbsp/arm/lpc32xx/include/lpc-clock-config.h2
-rw-r--r--c/src/lib/libbsp/arm/nds/clock/clock.c2
-rw-r--r--c/src/lib/libbsp/arm/raspberrypi/clock/clockdrv.c12
-rw-r--r--c/src/lib/libbsp/arm/shared/arm-a9mpcore-clock-config.c48
-rw-r--r--c/src/lib/libbsp/arm/shared/armv7m/clock/armv7m-clock-config.c65
-rw-r--r--c/src/lib/libbsp/arm/shared/lpc/clock/lpc-clock-config.c37
-rw-r--r--c/src/lib/libbsp/arm/tms570/clock/clock.c40
-rw-r--r--c/src/lib/libbsp/i386/pc386/clock/ckinit.c125
-rw-r--r--c/src/lib/libbsp/lm32/shared/clock/ckinit.c2
-rw-r--r--c/src/lib/libbsp/lm32/shared/milkymist_clock/ckinit.c2
-rw-r--r--c/src/lib/libbsp/m68k/av5282/clock/clock.c2
-rw-r--r--c/src/lib/libbsp/m68k/gen68360/clock/clock.c2
-rw-r--r--c/src/lib/libbsp/m68k/genmcf548x/clock/clock.c2
-rw-r--r--c/src/lib/libbsp/m68k/mcf52235/clock/clock.c50
-rw-r--r--c/src/lib/libbsp/m68k/mcf5225x/clock/clock.c44
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/clock/clock.c2
-rw-r--r--c/src/lib/libbsp/m68k/mcf5329/clock/clock.c49
-rw-r--r--c/src/lib/libbsp/m68k/sim68000/clock/clockdrv.c2
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/clock/clock.c48
-rw-r--r--c/src/lib/libbsp/mips/csb350/clock/clockdrv.c2
-rw-r--r--c/src/lib/libbsp/mips/genmongoosev/clock/clockdrv.c2
-rw-r--r--c/src/lib/libbsp/mips/jmr3904/clock/clockdrv.c2
-rw-r--r--c/src/lib/libbsp/mips/rbtx4925/clock/clockdrv.c1
-rw-r--r--c/src/lib/libbsp/mips/rbtx4938/clock/clockdrv.c2
-rw-r--r--c/src/lib/libbsp/mips/shared/clock/clockdrv.c10
-rw-r--r--c/src/lib/libbsp/nios2/nios2_iss/clock/clock.c2
-rw-r--r--c/src/lib/libbsp/or1k/generic_or1k/clock/clockdrv.c50
-rw-r--r--c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c96
-rw-r--r--c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c61
-rw-r--r--c/src/lib/libbsp/powerpc/qoriq/configure.ac4
-rw-r--r--c/src/lib/libbsp/powerpc/shared/clock/clock.c56
-rw-r--r--c/src/lib/libbsp/shared/clock_driver_simidle.c2
-rw-r--r--c/src/lib/libbsp/shared/clockdrv_shell.h52
-rw-r--r--c/src/lib/libbsp/sparc/erc32/clock/ckinit.c52
-rw-r--r--c/src/lib/libbsp/sparc/leon2/clock/ckinit.c52
-rw-r--r--c/src/lib/libbsp/sparc/leon3/clock/ckinit.c97
-rw-r--r--c/src/lib/libbsp/sparc64/shared/clock/ckinit.c2
-rw-r--r--c/src/lib/libcpu/arm/at91rm9200/clock/clock.c23
-rw-r--r--c/src/lib/libcpu/arm/lpc22xx/clock/clockdrv.c53
-rw-r--r--c/src/lib/libcpu/arm/mc9328mxl/clock/clockdrv.c3
-rw-r--r--c/src/lib/libcpu/arm/pxa255/clock/clock.c2
-rw-r--r--c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c14
-rw-r--r--c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c107
48 files changed, 685 insertions, 640 deletions
diff --git a/c/src/lib/libbsp/arm/beagle/clock.c b/c/src/lib/libbsp/arm/beagle/clock.c
index 66aba1b84b..912d904197 100644
--- a/c/src/lib/libbsp/arm/beagle/clock.c
+++ b/c/src/lib/libbsp/arm/beagle/clock.c
@@ -15,11 +15,12 @@
*/
#include <rtems.h>
+#include <rtems/timecounter.h>
#include <bsp.h>
#include <libcpu/omap_timer.h>
-#ifdef ARM_MULTILIB_ARCH_V4
+static struct timecounter beagle_clock_tc;
static omap_timer_registers_t regs_v1 = {
.TIDR = OMAP3_TIMER_TIDR,
@@ -115,8 +116,6 @@ static struct omap_timer *timer = &am335x_timer;
#endif
-static int done = 0;
-
#if IS_AM335X
#define FRCLOCK_HZ (16*1500000)
#endif
@@ -181,20 +180,14 @@ omap3_frclock_init(void)
/* Start timer, without prescaler */
mmio_set(fr_timer->base + fr_timer->regs->TCLR,
OMAP3_TCLR_OVF_TRG | OMAP3_TCLR_AR | OMAP3_TCLR_ST);
- done = 1;
}
-static inline uint32_t
-read_frc(void)
+static uint32_t
+beagle_clock_get_timecount(struct timecounter *tc)
{
- if (done == 0) {
- return 0;
- }
return mmio_read(fr_timer->base + fr_timer->regs->TCRR);
}
-static uint32_t last_tick_nanoseconds;
-
static void
beagle_clock_initialize(void)
{
@@ -262,12 +255,16 @@ beagle_clock_initialize(void)
while(mmio_read(AM335X_WDT_BASE+AM335X_WDT_WWPS) != 0) ;
#endif
+ /* Install timecounter */ \
+ beagle_clock_tc.tc_get_timecount = beagle_clock_get_timecount;
+ beagle_clock_tc.tc_counter_mask = 0xffffffff;
+ beagle_clock_tc.tc_frequency = FRCLOCK_HZ;
+ beagle_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install(&beagle_clock_tc);
}
static void beagle_clock_at_tick(void)
{
- last_tick_nanoseconds = read_frc();
-
mmio_write(timer->base + timer->regs->TISR,
OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
OMAP3_TISR_TCAR_IT_FLAG);
@@ -315,14 +312,6 @@ static void beagle_clock_cleanup(void)
mmio_clear(fr_timer->base + fr_timer->regs->TCLR, OMAP3_TCLR_ST);
}
-static inline uint32_t beagle_clock_nanoseconds_since_last_tick(void)
-{
- /* this arithmetic also works if read_frc() wraps around, as long
- * as the subtraction wraps around too
- */
- return (read_frc() - (uint64_t) last_tick_nanoseconds) * 1000000000 / FRCLOCK_HZ;
-}
-
#define Clock_driver_support_at_tick() beagle_clock_at_tick()
#define Clock_driver_support_initialize_hardware() beagle_clock_initialize()
#define Clock_driver_support_install_isr(isr, old_isr) \
@@ -332,10 +321,6 @@ static inline uint32_t beagle_clock_nanoseconds_since_last_tick(void)
} while (0)
#define Clock_driver_support_shutdown_hardware() beagle_clock_cleanup()
-#define Clock_driver_nanoseconds_since_last_tick \
- beagle_clock_nanoseconds_since_last_tick
/* Include shared source clock driver code */
#include "../../shared/clockdrv_shell.h"
-
-#endif /* ARM_MULTILIB_ARCH_V4 */
diff --git a/c/src/lib/libbsp/arm/edb7312/clock/clockdrv.c b/c/src/lib/libbsp/arm/edb7312/clock/clockdrv.c
index 499a27904c..121b2c9d32 100644
--- a/c/src/lib/libbsp/arm/edb7312/clock/clockdrv.c
+++ b/c/src/lib/libbsp/arm/edb7312/clock/clockdrv.c
@@ -68,4 +68,6 @@ void Clock_isr(void * arg);
assert(status == RTEMS_SUCCESSFUL); \
} while (0)
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/arm/gba/clock/clockdrv.c b/c/src/lib/libbsp/arm/gba/clock/clockdrv.c
index 72d0b81e32..ff171110b9 100644
--- a/c/src/lib/libbsp/arm/gba/clock/clockdrv.c
+++ b/c/src/lib/libbsp/arm/gba/clock/clockdrv.c
@@ -92,4 +92,6 @@ void Clock_driver_support_initialize_hardware(void)
GBA_REG_TM3CNT = (0x00c0|GBA_TMCNT_PS);
}
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/arm/lpc176x/include/lpc-clock-config.h b/c/src/lib/libbsp/arm/lpc176x/include/lpc-clock-config.h
index c72575f719..3eef02152e 100644
--- a/c/src/lib/libbsp/arm/lpc176x/include/lpc-clock-config.h
+++ b/c/src/lib/libbsp/arm/lpc176x/include/lpc-clock-config.h
@@ -33,6 +33,7 @@ extern "C" {
#define LPC_CLOCK_INTERRUPT LPC176X_IRQ_TIMER_0
#define LPC_CLOCK_TIMER_BASE TMR0_BASE_ADDR
+#define LPC_CLOCK_TIMECOUNTER_BASE TMR1_BASE_ADDR
#define LPC_CLOCK_REFERENCE LPC176X_PCLK
#define LPC_CLOCK_MODULE_ENABLE() \
lpc176x_module_enable( LPC176X_MODULE_TIMER_0, LPC176X_MODULE_PCLK_DEFAULT )
diff --git a/c/src/lib/libbsp/arm/lpc24xx/include/lpc-clock-config.h b/c/src/lib/libbsp/arm/lpc24xx/include/lpc-clock-config.h
index 1edab4eb02..5e6b469e0f 100644
--- a/c/src/lib/libbsp/arm/lpc24xx/include/lpc-clock-config.h
+++ b/c/src/lib/libbsp/arm/lpc24xx/include/lpc-clock-config.h
@@ -35,6 +35,8 @@ extern "C" {
#define LPC_CLOCK_TIMER_BASE TMR0_BASE_ADDR
+#define LPC_CLOCK_TIMECOUNTER_BASE TMR1_BASE_ADDR
+
#define LPC_CLOCK_REFERENCE LPC24XX_PCLK
#define LPC_CLOCK_MODULE_ENABLE() \
diff --git a/c/src/lib/libbsp/arm/lpc32xx/include/lpc-clock-config.h b/c/src/lib/libbsp/arm/lpc32xx/include/lpc-clock-config.h
index accd0d256a..2b676b433f 100644
--- a/c/src/lib/libbsp/arm/lpc32xx/include/lpc-clock-config.h
+++ b/c/src/lib/libbsp/arm/lpc32xx/include/lpc-clock-config.h
@@ -44,6 +44,8 @@ extern "C" {
#define LPC_CLOCK_TIMER_BASE LPC32XX_BASE_TIMER_0
+#define LPC_CLOCK_TIMECOUNTER_BASE LPC32XX_BASE_TIMER_1
+
#define LPC_CLOCK_REFERENCE LPC32XX_PERIPH_CLK
#define LPC_CLOCK_MODULE_ENABLE()
diff --git a/c/src/lib/libbsp/arm/nds/clock/clock.c b/c/src/lib/libbsp/arm/nds/clock/clock.c
index a24f8cc788..1e239d44d9 100644
--- a/c/src/lib/libbsp/arm/nds/clock/clock.c
+++ b/c/src/lib/libbsp/arm/nds/clock/clock.c
@@ -81,4 +81,6 @@ void Clock_driver_support_initialize_hardware (void)
TIMER_DATA (0) = TIMER_FREQ_64 ((uint16_t) freq);
}
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/arm/raspberrypi/clock/clockdrv.c b/c/src/lib/libbsp/arm/raspberrypi/clock/clockdrv.c
index 533873cf19..f765485570 100644
--- a/c/src/lib/libbsp/arm/raspberrypi/clock/clockdrv.c
+++ b/c/src/lib/libbsp/arm/raspberrypi/clock/clockdrv.c
@@ -72,14 +72,6 @@ static void raspberrypi_clock_cleanup(void)
}
}
-/*
- * Return the nanoseconds since last tick
- */
-static uint32_t raspberrypi_clock_nanoseconds_since_last_tick(void)
-{
- return 0;
-}
-
#define Clock_driver_support_at_tick() raspberrypi_clock_at_tick()
#define Clock_driver_support_initialize_hardware() raspberrypi_clock_initialize()
@@ -92,8 +84,6 @@ static uint32_t raspberrypi_clock_nanoseconds_since_last_tick(void)
#define Clock_driver_support_shutdown_hardware() raspberrypi_clock_cleanup()
-#define Clock_driver_nanoseconds_since_last_tick \
- raspberrypi_clock_nanoseconds_since_last_tick
-
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/arm/shared/arm-a9mpcore-clock-config.c b/c/src/lib/libbsp/arm/shared/arm-a9mpcore-clock-config.c
index f2ce07e3b6..8e2e153b46 100644
--- a/c/src/lib/libbsp/arm/shared/arm-a9mpcore-clock-config.c
+++ b/c/src/lib/libbsp/arm/shared/arm-a9mpcore-clock-config.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2013-2015 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -17,14 +17,11 @@
#include <bsp/irq.h>
#include <bsp/arm-a9mpcore-regs.h>
#include <bsp/arm-a9mpcore-clock.h>
+#include <rtems/timecounter.h>
#define A9MPCORE_GT ((volatile a9mpcore_gt *) BSP_ARM_A9MPCORE_GT_BASE)
-static uint64_t a9mpcore_clock_last_tick_k;
-
-static uint32_t a9mpcore_clock_last_tick_cmpvallower;
-
-static uint32_t a9mpcore_clock_autoinc;
+static struct timecounter a9mpcore_tc;
/* This is defined in clockdrv_shell.h */
void Clock_isr(rtems_irq_hdl_param arg);
@@ -39,13 +36,6 @@ static void a9mpcore_clock_at_tick(void)
{
volatile a9mpcore_gt *gt = A9MPCORE_GT;
- /*
- * FIXME: Now the _TOD_Get_with_nanoseconds() yields wrong values until
- * _TOD_Tickle_ticks() managed to update the uptime. See also PR2180.
- */
- a9mpcore_clock_last_tick_cmpvallower =
- gt->cmpvallower - a9mpcore_clock_autoinc;
-
gt->irqst = A9MPCORE_GT_IRQST_EFLG;
}
@@ -80,6 +70,13 @@ static uint64_t a9mpcore_clock_get_counter(volatile a9mpcore_gt *gt)
return ((uint64_t) cu2 << 32) | cl;
}
+static uint32_t a9mpcore_clock_get_timecount(struct timecounter *tc)
+{
+ volatile a9mpcore_gt *gt = A9MPCORE_GT;
+
+ return gt->cntrlower;
+}
+
static void a9mpcore_clock_initialize(void)
{
volatile a9mpcore_gt *gt = A9MPCORE_GT;
@@ -98,14 +95,16 @@ static void a9mpcore_clock_initialize(void)
gt->cmpvalupper = (uint32_t) (cmpval >> 32);
gt->autoinc = interval;
- a9mpcore_clock_last_tick_k = (UINT64_C(1000000000) << 32) / periphclk;
- a9mpcore_clock_last_tick_cmpvallower = (uint32_t) cmpval - interval;
- a9mpcore_clock_autoinc = interval;
-
gt->ctrl = A9MPCORE_GT_CTRL_AUTOINC_EN
| A9MPCORE_GT_CTRL_IRQ_EN
| A9MPCORE_GT_CTRL_COMP_EN
| A9MPCORE_GT_CTRL_TMR_EN;
+
+ a9mpcore_tc.tc_get_timecount = a9mpcore_clock_get_timecount;
+ a9mpcore_tc.tc_counter_mask = 0xffffffff;
+ a9mpcore_tc.tc_frequency = periphclk;
+ a9mpcore_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install(&a9mpcore_tc);
}
CPU_Counter_ticks _CPU_Counter_read(void)
@@ -147,16 +146,6 @@ static void a9mpcore_clock_cleanup(void)
}
}
-static uint32_t a9mpcore_clock_nanoseconds_since_last_tick(void)
-{
- volatile a9mpcore_gt *gt = A9MPCORE_GT;
- uint64_t k = a9mpcore_clock_last_tick_k;
- uint32_t n = a9mpcore_clock_last_tick_cmpvallower;
- uint32_t c = gt->cntrlower;
-
- return (uint32_t) (((c - n) * k) >> 32);
-}
-
#define Clock_driver_support_at_tick() \
a9mpcore_clock_at_tick()
@@ -165,15 +154,12 @@ static uint32_t a9mpcore_clock_nanoseconds_since_last_tick(void)
#define Clock_driver_support_install_isr(isr, old_isr) \
do { \
- a9mpcore_clock_handler_install(); \
+ a9mpcore_clock_handler_install(); \
old_isr = NULL; \
} while (0)
#define Clock_driver_support_shutdown_hardware() \
a9mpcore_clock_cleanup()
-#define Clock_driver_nanoseconds_since_last_tick \
- a9mpcore_clock_nanoseconds_since_last_tick
-
/* Include shared source clock driver code */
#include "../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/arm/shared/armv7m/clock/armv7m-clock-config.c b/c/src/lib/libbsp/arm/shared/armv7m/clock/armv7m-clock-config.c
index 8e4ae338f8..e78684c8d2 100644
--- a/c/src/lib/libbsp/arm/shared/armv7m/clock/armv7m-clock-config.c
+++ b/c/src/lib/libbsp/arm/shared/armv7m/clock/armv7m-clock-config.c
@@ -13,6 +13,7 @@
*/
#include <rtems.h>
+#include <rtems/timecounter.h>
#include <rtems/score/armv7m.h>
#include <bsp.h>
@@ -22,15 +23,35 @@
/* This is defined in clockdrv_shell.h */
static void Clock_isr(void *arg);
-#define _ARMV7M_Systick_get_factor(freq) \
- ((1000000000ULL << 32) / (freq))
+static rtems_timecounter_simple _ARMV7M_TC;
-#ifdef BSP_ARMV7M_SYSTICK_FREQUENCY
- #define _ARMV7M_Systick_factor \
- _ARMV7M_Systick_get_factor(BSP_ARMV7M_SYSTICK_FREQUENCY)
-#else
- static uint64_t _ARMV7M_Systick_factor;
-#endif
+static uint32_t _ARMV7M_TC_get(rtems_timecounter_simple *tc)
+{
+ volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
+
+ return systick->cvr;
+}
+
+static bool _ARMV7M_TC_is_pending(rtems_timecounter_simple *tc)
+{
+ volatile ARMV7M_SCB *scb = _ARMV7M_SCB;
+
+ return ((scb->icsr & ARMV7M_SCB_ICSR_PENDSTSET) != 0);
+}
+
+static uint32_t _ARMV7M_TC_get_timecount(struct timecounter *tc)
+{
+ return rtems_timecounter_simple_downcounter_get(
+ tc,
+ _ARMV7M_TC_get,
+ _ARMV7M_TC_is_pending
+ );
+}
+
+static void _ARMV7M_TC_tick(void)
+{
+ rtems_timecounter_simple_downcounter_tick(&_ARMV7M_TC, _ARMV7M_TC_get);
+}
static void _ARMV7M_Systick_at_tick(void)
{
@@ -67,15 +88,18 @@ static void _ARMV7M_Systick_initialize(void)
uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
uint64_t interval = (freq * us_per_tick) / 1000000ULL;
- #ifndef BSP_ARMV7M_SYSTICK_FREQUENCY
- _ARMV7M_Systick_factor = _ARMV7M_Systick_get_factor(freq);
- #endif
-
systick->rvr = (uint32_t) interval;
systick->cvr = 0;
systick->csr = ARMV7M_SYSTICK_CSR_ENABLE
| ARMV7M_SYSTICK_CSR_TICKINT
| ARMV7M_SYSTICK_CSR_CLKSOURCE;
+
+ rtems_timecounter_simple_install(
+ &_ARMV7M_TC,
+ freq,
+ interval,
+ _ARMV7M_TC_get_timecount
+ );
}
static void _ARMV7M_Systick_cleanup(void)
@@ -85,19 +109,7 @@ static void _ARMV7M_Systick_cleanup(void)
systick->csr = 0;
}
-static uint32_t _ARMV7M_Systick_nanoseconds_since_last_tick(void)
-{
- volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
- volatile ARMV7M_SCB *scb = _ARMV7M_SCB;
- uint32_t rvr = systick->rvr;
- uint32_t c = rvr - systick->cvr;
-
- if ((scb->icsr & ARMV7M_SCB_ICSR_PENDSTSET) != 0) {
- c = rvr - systick->cvr + rvr;
- }
-
- return (uint32_t) ((c * _ARMV7M_Systick_factor) >> 32);
-}
+#define Clock_driver_timecounter_tick() _ARMV7M_TC_tick()
#define Clock_driver_support_at_tick() \
_ARMV7M_Systick_at_tick()
@@ -114,9 +126,6 @@ static uint32_t _ARMV7M_Systick_nanoseconds_since_last_tick(void)
#define Clock_driver_support_shutdown_hardware() \
_ARMV7M_Systick_cleanup()
-#define Clock_driver_nanoseconds_since_last_tick \
- _ARMV7M_Systick_nanoseconds_since_last_tick
-
/* Include shared source clock driver code */
#include "../../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/arm/shared/lpc/clock/lpc-clock-config.c b/c/src/lib/libbsp/arm/shared/lpc/clock/lpc-clock-config.c
index 05c94a6b2c..a55ba0e33c 100644
--- a/c/src/lib/libbsp/arm/shared/lpc/clock/lpc-clock-config.c
+++ b/c/src/lib/libbsp/arm/shared/lpc/clock/lpc-clock-config.c
@@ -7,10 +7,10 @@
*/
/*
- * Copyright (c) 2009-2012 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2009-2015 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
- * Obere Lagerstr. 30
+ * Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
@@ -21,6 +21,7 @@
*/
#include <rtems.h>
+#include <rtems/timecounter.h>
#include <bsp/lpc-clock-config.h>
#include <bsp/lpc-timer.h>
@@ -33,6 +34,16 @@ void Clock_isr(rtems_irq_hdl_param arg);
static volatile lpc_timer *const lpc_clock =
(volatile lpc_timer *) LPC_CLOCK_TIMER_BASE;
+static volatile lpc_timer *const lpc_timecounter =
+ (volatile lpc_timer *) LPC_CLOCK_TIMECOUNTER_BASE;
+
+static struct timecounter lpc_clock_tc;
+
+static uint32_t lpc_clock_tc_get_timecount(struct timecounter *tc)
+{
+ return lpc_timecounter->tc;
+}
+
static void lpc_clock_at_tick(void)
{
lpc_clock->ir = LPC_TIMER_IR_MR0;
@@ -56,6 +67,7 @@ static void lpc_clock_handler_install(void)
static void lpc_clock_initialize(void)
{
+ uint32_t mask;
uint64_t interval = ((uint64_t) LPC_CLOCK_REFERENCE
* (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000;
@@ -85,6 +97,13 @@ static void lpc_clock_initialize(void)
/* Enable timer */
lpc_clock->tcr = LPC_TIMER_TCR_EN;
+
+ /* Install timecounter */
+ lpc_clock_tc.tc_get_timecount = lpc_clock_tc_get_timecount;
+ lpc_clock_tc.tc_counter_mask = 0xffffffff;
+ lpc_clock_tc.tc_frequency = LPC_CLOCK_REFERENCE;
+ lpc_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install(&lpc_clock_tc);
}
static void lpc_clock_cleanup(void)
@@ -105,18 +124,6 @@ static void lpc_clock_cleanup(void)
}
}
-static uint32_t lpc_clock_nanoseconds_since_last_tick(void)
-{
- uint64_t k = (1000000000ULL << 32) / LPC_CLOCK_REFERENCE;
- uint64_t c = lpc_clock->tc;
-
- if ((lpc_clock->ir & LPC_TIMER_IR_MR0) != 0) {
- c = lpc_clock->tc + lpc_clock->mr0;
- }
-
- return (uint32_t) ((c * k) >> 32);
-}
-
#define Clock_driver_support_at_tick() lpc_clock_at_tick()
#define Clock_driver_support_initialize_hardware() lpc_clock_initialize()
#define Clock_driver_support_install_isr(isr, old_isr) \
@@ -126,8 +133,6 @@ static uint32_t lpc_clock_nanoseconds_since_last_tick(void)
} while (0)
#define Clock_driver_support_shutdown_hardware() lpc_clock_cleanup()
-#define Clock_driver_nanoseconds_since_last_tick \
- lpc_clock_nanoseconds_since_last_tick
/* Include shared source clock driver code */
#include "../../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/arm/tms570/clock/clock.c b/c/src/lib/libbsp/arm/tms570/clock/clock.c
index 4dba949c86..d438a3da34 100644
--- a/c/src/lib/libbsp/arm/tms570/clock/clock.c
+++ b/c/src/lib/libbsp/arm/tms570/clock/clock.c
@@ -30,13 +30,14 @@
#include <bsp/irq.h>
#include <bsp/tms570-rti.h>
#include <rtems/counter.h>
+#include <rtems/timecounter.h>
-/**
- * holds HW counter value since last interrupt event
- * sets in tms570_clock_driver_support_at_tick
- * used in tms570_clock_driver_nanoseconds_since_last_tick
- */
-static uint32_t tms570_rti_last_tick_fcr0;
+static struct timecounter tms570_rti_tc;
+
+static uint32_t tms570_rti_get_timecount(struct timecounter tc)
+{
+ return TMS570_RTI.RTIFRC0;
+}
/**
* @brief Initialize the HW peripheral for clock driver
@@ -72,6 +73,12 @@ static void tms570_clock_driver_support_initialize_hardware( void )
TMS570_RTI.RTISETINTENA = 0x1;
/* enable timer */
TMS570_RTI.RTIGCTRL = 1;
+ /* set timecounter */
+ tms570_rti_tc.tc_get_timecount = tms570_rti_get_timecount;
+ tms570_rti_tc.tc_counter_mask = 0xffffffff;
+ tms570_rti_tc.tc_frequency = BSP_PLL_OUT_CLOCK;
+ tms570_rti_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install(&tms570_rti_tc);
}
/**
@@ -82,7 +89,6 @@ static void tms570_clock_driver_support_initialize_hardware( void )
static void tms570_clock_driver_support_at_tick( void )
{
TMS570_RTI.RTIINTFLAG = 0x00000001;
- tms570_rti_last_tick_fcr0 = TMS570_RTI.RTICOMP0 - TMS570_RTI.RTIUDCP0;
}
/**
@@ -124,24 +130,6 @@ static void tms570_clock_driver_support_shutdown_hardware( void )
TMS570_RTI.RTICLEARINTENA = 0x20000;
}
-/**
- * @brief returns the nanoseconds since last tick
- *
- * Return the nanoseconds since last tick
- *
- * @retval x nanoseconds
- *
- */
-static uint32_t tms570_clock_driver_nanoseconds_since_last_tick( void )
-{
- uint32_t actual_fcr0 = TMS570_RTI.RTIFRC0;
- uint32_t usec_since_tick;
-
- usec_since_tick = actual_fcr0 - tms570_rti_last_tick_fcr0;
-
- return usec_since_tick * 1000;
-}
-
#define Clock_driver_support_initialize_hardware \
tms570_clock_driver_support_initialize_hardware
#define Clock_driver_support_at_tick \
@@ -150,8 +138,6 @@ static uint32_t tms570_clock_driver_nanoseconds_since_last_tick( void )
tms570_clock_driver_support_initialize_hardware
#define Clock_driver_support_shutdown_hardware \
tms570_clock_driver_support_shutdown_hardware
-#define Clock_driver_nanoseconds_since_last_tick \
- tms570_clock_driver_nanoseconds_since_last_tick
#define Clock_driver_support_install_isr(Clock_isr, Old_ticker ) \
tms570_clock_driver_support_install_isr( Clock_isr )
diff --git a/c/src/lib/libbsp/i386/pc386/clock/ckinit.c b/c/src/lib/libbsp/i386/pc386/clock/ckinit.c
index 2782252680..44a35bc6c1 100644
--- a/c/src/lib/libbsp/i386/pc386/clock/ckinit.c
+++ b/c/src/lib/libbsp/i386/pc386/clock/ckinit.c
@@ -28,6 +28,7 @@
#include <bspopts.h>
#include <libcpu/cpuModel.h>
#include <assert.h>
+#include <rtems/timecounter.h>
#define CLOCK_VECTOR 0
@@ -39,29 +40,24 @@ uint32_t pc386_clock_click_count;
void Clock_isr(void *param);
static void Clock_driver_support_at_tick_empty(void);
static void clockOff(void);
-static void Clock_driver_support_at_tick_tsc(void);
-static uint32_t bsp_clock_nanoseconds_since_last_tick_tsc(void);
-static uint32_t bsp_clock_nanoseconds_since_last_tick_i8254(void);
static void Clock_isr_handler(void *param);
/*
- * Roughly the number of cycles per tick and per nanosecond. Note that these
+ * Roughly the number of cycles per second. Note that these
* will be wildly inaccurate if the chip speed changes due to power saving
* or thermal modes.
*
* NOTE: These are only used when the TSC method is used.
*/
-uint64_t pc586_tsc_per_tick;
-uint64_t pc586_nanoseconds_per_tick;
+static uint64_t pc586_tsc_frequency;
-uint64_t pc586_tsc_at_tick;
+static struct timecounter pc386_tc;
/* this driver may need to count ISRs per tick */
#define CLOCK_DRIVER_ISRS_PER_TICK 1
#define CLOCK_DRIVER_ISRS_PER_TICK_VALUE pc386_isrs_per_tick
-/* The driver uses the count in Clock_driver_support_at_tick */
-extern volatile uint32_t Clock_driver_isrs;
+extern volatile uint32_t Clock_driver_ticks;
#define READ_8254( _lsb, _msb ) \
do { outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_LATCH); \
@@ -74,60 +70,21 @@ extern volatile uint32_t Clock_driver_isrs;
* Hooks which get swapped based upon which nanoseconds since last
* tick method is preferred.
*/
-void (*Clock_driver_support_at_tick)(void) = NULL;
-uint32_t (*Clock_driver_nanoseconds_since_last_tick)(void) = NULL;
-
-/*
- * What do we do at each clock tick?
- */
-static void Clock_driver_support_at_tick_tsc(void)
-{
- pc586_tsc_at_tick = rdtsc();
-}
-
-static void Clock_driver_support_at_tick_empty(void)
-{
-}
+#define Clock_driver_support_at_tick()
#define Clock_driver_support_install_isr( _new, _old ) \
do { \
_old = NULL; \
} while(0)
-/*
- * Get nanoseconds using Pentium-compatible TSC register
- */
-static uint32_t bsp_clock_nanoseconds_since_last_tick_tsc(void)
+static uint32_t pc386_get_timecount_tsc(struct timecounter *tc)
{
- uint64_t diff_nsec;
-
- diff_nsec = rdtsc() - pc586_tsc_at_tick;
-
- /*
- * At this point, with a hypothetical 10 GHz CPU clock and 100 Hz tick
- * clock, diff_nsec <= 27 bits.
- */
- diff_nsec *= pc586_nanoseconds_per_tick; /* <= 54 bits */
- diff_nsec /= pc586_tsc_per_tick;
-
- if (diff_nsec > pc586_nanoseconds_per_tick)
- /*
- * Hmmm... Some drift or rounding. Pin the value to 1 nanosecond before
- * the next tick.
- */
- /* diff_nsec = pc586_nanoseconds_per_tick - 1; */
- diff_nsec = 12345;
-
- return (uint32_t)diff_nsec;
+ return (uint32_t)rdtsc();
}
-/*
- * Get nanoseconds using 8254 timer chip
- */
-static uint32_t bsp_clock_nanoseconds_since_last_tick_i8254(void)
+static uint32_t pc386_get_timecount_i8254(struct timecounter *tc)
{
- uint32_t usecs, clicks, isrs;
- uint32_t usecs1, usecs2;
+ uint32_t irqs;
uint8_t lsb, msb;
rtems_interrupt_level level;
@@ -136,34 +93,10 @@ static uint32_t bsp_clock_nanoseconds_since_last_tick_i8254(void)
*/
rtems_interrupt_disable(level);
READ_8254(lsb, msb);
- isrs = Clock_driver_isrs;
+ irqs = Clock_driver_ticks;
rtems_interrupt_enable(level);
- /*
- * Now do the math
- */
- /* convert values read into counter clicks */
- clicks = ((msb << 8) | lsb);
-
- /* whole ISRs we have done since the last tick */
- usecs1 = (pc386_isrs_per_tick - isrs - 1) * pc386_microseconds_per_isr;
-
- /* the partial ISR we in the middle of now */
- usecs2 = pc386_microseconds_per_isr - TICK_TO_US(clicks);
-
- /* total microseconds */
- usecs = usecs1 + usecs2;
- #if 0
- printk( "usecs1=%d usecs2=%d ", usecs1, usecs2 );
- printk( "maxclicks=%d clicks=%d ISRs=%d ISRsper=%d usersPer=%d usecs=%d\n",
- pc386_clock_click_count, clicks,
- Clock_driver_isrs, pc386_isrs_per_tick,
- pc386_microseconds_per_isr, usecs );
- #endif
-
- /* return it in nanoseconds */
- return usecs * 1000;
-
+ return (irqs + 1) * pc386_microseconds_per_isr - ((msb << 8) | lsb);
}
/*
@@ -175,9 +108,6 @@ static void calibrate_tsc(void)
uint8_t then_lsb, then_msb, now_lsb, now_msb;
uint32_t i;
- pc586_nanoseconds_per_tick =
- rtems_configuration_get_microseconds_per_tick() * 1000;
-
/*
* We just reset the timer, so we know we're at the beginning of a tick.
*/
@@ -204,16 +134,11 @@ static void calibrate_tsc(void)
} while (1);
}
- pc586_tsc_per_tick = rdtsc() - begin_time;
-
- /* Initialize "previous tick" counters */
- pc586_tsc_at_tick = rdtsc();
+ pc586_tsc_frequency = rdtsc() - begin_time;
#if 0
- printk( "CPU clock at %u MHz\n", (uint32_t)(pc586_tsc_per_tick / 1000000));
+ printk( "CPU clock at %u MHz\n", (uint32_t)(pc586_tsc_frequency / 1000000));
#endif
-
- pc586_tsc_per_tick /= rtems_clock_get_ticks_per_second();
}
static void clockOn(void)
@@ -299,24 +224,18 @@ void Clock_driver_support_initialize_hardware(void)
if ( use_8254 ) {
/* printk( "Use 8254\n" ); */
- Clock_driver_support_at_tick = Clock_driver_support_at_tick_empty;
- Clock_driver_nanoseconds_since_last_tick =
- bsp_clock_nanoseconds_since_last_tick_i8254;
+ pc386_tc.tc_get_timecount = pc386_get_timecount_i8254;
+ pc386_tc.tc_counter_mask = 0xffffffff;
+ pc386_tc.tc_frequency = TIMER_TICK;
} else {
/* printk( "Use TSC\n" ); */
- Clock_driver_support_at_tick = Clock_driver_support_at_tick_tsc;
- Clock_driver_nanoseconds_since_last_tick =
- bsp_clock_nanoseconds_since_last_tick_tsc;
+ pc386_tc.tc_get_timecount = pc386_get_timecount_tsc;
+ pc386_tc.tc_counter_mask = 0xffffffff;
+ pc386_tc.tc_frequency = pc586_tsc_frequency;
}
- /* Shell installs nanosecond handler before calling
- * Clock_driver_support_initialize_hardware() :-(
- * so we do it again now that we're ready.
- */
- rtems_clock_set_nanoseconds_extension(
- Clock_driver_nanoseconds_since_last_tick
- );
-
+ pc386_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install(&pc386_tc);
Clock_isr_enabled = true;
}
diff --git a/c/src/lib/libbsp/lm32/shared/clock/ckinit.c b/c/src/lib/libbsp/lm32/shared/clock/ckinit.c
index ae065de0d8..b1f5c8d0b9 100644
--- a/c/src/lib/libbsp/lm32/shared/clock/ckinit.c
+++ b/c/src/lib/libbsp/lm32/shared/clock/ckinit.c
@@ -75,5 +75,7 @@ static void Clock_driver_support_shutdown_hardware(void)
clockwrite(LM32_CLOCK_CR, LM32_CLOCK_CR_STOP);
}
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/lm32/shared/milkymist_clock/ckinit.c b/c/src/lib/libbsp/lm32/shared/milkymist_clock/ckinit.c
index 65651e6470..3230d83325 100644
--- a/c/src/lib/libbsp/lm32/shared/milkymist_clock/ckinit.c
+++ b/c/src/lib/libbsp/lm32/shared/milkymist_clock/ckinit.c
@@ -46,4 +46,6 @@ static void Clock_driver_support_shutdown_hardware(void)
MM_WRITE(MM_TIMER0_CONTROL, 0);
}
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/m68k/av5282/clock/clock.c b/c/src/lib/libbsp/m68k/av5282/clock/clock.c
index 3dded8adf1..182693fe03 100644
--- a/c/src/lib/libbsp/m68k/av5282/clock/clock.c
+++ b/c/src/lib/libbsp/m68k/av5282/clock/clock.c
@@ -58,4 +58,6 @@
MCF5282_PIT_PCSR_EN; \
} while (0)
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/m68k/gen68360/clock/clock.c b/c/src/lib/libbsp/m68k/gen68360/clock/clock.c
index 78deaf9cce..3b9d4ca293 100644
--- a/c/src/lib/libbsp/m68k/gen68360/clock/clock.c
+++ b/c/src/lib/libbsp/m68k/gen68360/clock/clock.c
@@ -98,4 +98,6 @@ extern int m360_clock_rate;
m360.pitr |= divisor; \
} while (0)
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/m68k/genmcf548x/clock/clock.c b/c/src/lib/libbsp/m68k/genmcf548x/clock/clock.c
index d3f6eb467c..d0f28c6b72 100644
--- a/c/src/lib/libbsp/m68k/genmcf548x/clock/clock.c
+++ b/c/src/lib/libbsp/m68k/genmcf548x/clock/clock.c
@@ -98,5 +98,7 @@
MCF548X_SLT_SCR0 |= (MCF548X_SLT_SCR_TEN | MCF548X_SLT_SCR_RUN | MCF548X_SLT_SCR_IEN); \
} while (0)
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/m68k/mcf52235/clock/clock.c b/c/src/lib/libbsp/m68k/mcf52235/clock/clock.c
index c22393d5ae..7a508a3b1c 100644
--- a/c/src/lib/libbsp/m68k/mcf52235/clock/clock.c
+++ b/c/src/lib/libbsp/m68k/mcf52235/clock/clock.c
@@ -3,6 +3,7 @@
*/
#include <rtems.h>
+#include <rtems/timecounter.h>
#include <bsp.h>
/*
@@ -10,34 +11,37 @@
*/
#define CLOCK_VECTOR (64+56)
-static uint32_t s_pcntrAtTick = 0;
-static uint32_t s_nanoScale = 0;
+static rtems_timecounter_simple mcf52235_tc;
-/*
- * Provide nanosecond extension
- * Interrupts are disabled when this is called
- */
-static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
+static uint32_t mcf52235_tc_get(rtems_timecounter_simple *tc)
{
- uint32_t i;
+ return MCF_PIT1_PCNTR;
+}
- if (MCF_PIT1_PCSR & MCF_PIT_PCSR_PIF) {
- i = s_pcntrAtTick + (MCF_PIT1_PMR - MCF_PIT1_PCNTR);
- }
- else {
- i = s_pcntrAtTick - MCF_PIT1_PCNTR;
- }
- return i * s_nanoScale;
+static bool mcf52235_tc_is_pending(rtems_timecounter_simple *tc)
+{
+ return (MCF_PIT1_PCSR & MCF_PIT_PCSR_PIF) != 0;
}
-#define Clock_driver_nanoseconds_since_last_tick bsp_clock_nanoseconds_since_last_tick
+static uint32_t mcf52235_tc_get_timecount(struct timecounter *tc)
+{
+ return rtems_timecounter_simple_downcounter_get(
+ tc,
+ mcf52235_tc_get,
+ mcf52235_tc_is_pending
+ );
+}
+
+static void mcf52235_tc_tick(void)
+{
+ rtems_timecounter_simple_downcounter_tick(&mcf52235_tc, mcf52235_tc_get);
+}
/*
* Periodic interval timer interrupt handler
*/
#define Clock_driver_support_at_tick() \
do { \
- s_pcntrAtTick = MCF_PIT1_PCNTR; \
MCF_PIT1_PCSR |= MCF_PIT_PCSR_PIF; \
} while (0) \
@@ -64,6 +68,7 @@ static void Clock_driver_support_shutdown_hardware(void)
*/
static void Clock_driver_support_initialize_hardware(void)
{
+ uint32_t mask;
int level;
uint32_t pmr;
uint32_t preScaleCode = 0;
@@ -76,7 +81,6 @@ static void Clock_driver_support_initialize_hardware(void)
break;
preScaleCode++;
}
- s_nanoScale = 1000000000 / (clk >> preScaleCode);
MCF_INTC0_ICR56 = MCF_INTC_ICR_IL(PIT3_IRQ_LEVEL) |
MCF_INTC_ICR_IP(PIT3_IRQ_PRIORITY);
@@ -90,7 +94,15 @@ static void Clock_driver_support_initialize_hardware(void)
MCF_PIT1_PMR = pmr;
MCF_PIT1_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) |
MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_EN;
- s_pcntrAtTick = MCF_PIT1_PCNTR;
+
+ rtems_timecounter_simple_install(
+ &mcf52235_tc,
+ clk >> preScaleCode,
+ pmr,
+ mcf52235_tc_get_timecount
+ );
}
+#define Clock_driver_timecounter_tick() mcf52235_tc_tick()
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/m68k/mcf5225x/clock/clock.c b/c/src/lib/libbsp/m68k/mcf5225x/clock/clock.c
index d058126798..33fd76c0ae 100644
--- a/c/src/lib/libbsp/m68k/mcf5225x/clock/clock.c
+++ b/c/src/lib/libbsp/m68k/mcf5225x/clock/clock.c
@@ -3,6 +3,7 @@
*/
#include <rtems.h>
+#include <rtems/timecounter.h>
#include <bsp.h>
/*
@@ -10,26 +11,37 @@
*/
#define CLOCK_VECTOR (64+56)
-static uint32_t s_pcntrAtTick = 0;
-static uint32_t s_nanoScale = 0;
+static rtems_timecounter_simple mcf5225x_tc;
-/*
- * Provide nanosecond extension
- * Interrupts are disabled when this is called
- */
-static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
+static uint32_t mcf5225x_tc_get(rtems_timecounter_simple *tc)
+{
+ return MCF_PIT1_PCNTR;
+}
+
+static bool mcf5225x_tc_is_pending(rtems_timecounter_simple *tc)
+{
+ return (MCF_PIT1_PCSR & MCF_PIT_PCSR_PIF) != 0;
+}
+
+static uint32_t mcf5225x_tc_get_timecount(struct timecounter *tc)
{
- return MCF_PIT1_PCSR & MCF_PIT_PCSR_PIF ? (s_pcntrAtTick + (MCF_PIT1_PMR - MCF_PIT1_PCNTR)) * s_nanoScale : (s_pcntrAtTick - MCF_PIT1_PCNTR) * s_nanoScale;
+ return rtems_timecounter_simple_downcounter_get(
+ tc,
+ mcf5225x_tc_get,
+ mcf5225x_tc_is_pending
+ );
}
-#define Clock_driver_nanoseconds_since_last_tick bsp_clock_nanoseconds_since_last_tick
+static void mcf5225x_tc_tick(void)
+{
+ rtems_timecounter_simple_downcounter_tick(&mcf5225x_tc, mcf5225x_tc_get);
+}
/*
* Periodic interval timer interrupt handler
*/
#define Clock_driver_support_at_tick() \
do { \
- s_pcntrAtTick = MCF_PIT1_PCNTR; \
MCF_PIT1_PCSR |= MCF_PIT_PCSR_PIF; \
} while (0) \
@@ -56,6 +68,7 @@ static void Clock_driver_support_shutdown_hardware(void)
*/
static void Clock_driver_support_initialize_hardware(void)
{
+ uint32_t mask;
int level;
uint32_t pmr;
uint32_t preScaleCode = 0;
@@ -68,7 +81,6 @@ static void Clock_driver_support_initialize_hardware(void)
break;
preScaleCode++;
}
- s_nanoScale = 1000000000 / (clk >> preScaleCode);
MCF_INTC0_ICR56 = MCF_INTC_ICR_IL(PIT3_IRQ_LEVEL) |
MCF_INTC_ICR_IP(PIT3_IRQ_PRIORITY);
@@ -82,7 +94,15 @@ static void Clock_driver_support_initialize_hardware(void)
MCF_PIT1_PMR = pmr;
MCF_PIT1_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) |
MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_EN;
- s_pcntrAtTick = MCF_PIT1_PCNTR;
+
+ rtems_timecounter_simple_install(
+ &mcf5225x_tc,
+ clk >> preScaleCode,
+ pmr,
+ mcf5225x_tc_get_timecount
+ );
}
+#define Clock_driver_timecounter_tick() mcf5225x_tc_tick()
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/m68k/mcf5235/clock/clock.c b/c/src/lib/libbsp/m68k/mcf5235/clock/clock.c
index c057796e59..95b7f37bac 100644
--- a/c/src/lib/libbsp/m68k/mcf5235/clock/clock.c
+++ b/c/src/lib/libbsp/m68k/mcf5235/clock/clock.c
@@ -58,4 +58,6 @@
MCF5235_PIT_PCSR_EN; \
} while (0)
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/m68k/mcf5329/clock/clock.c b/c/src/lib/libbsp/m68k/mcf5329/clock/clock.c
index ed11320bba..94c5bb0b04 100644
--- a/c/src/lib/libbsp/m68k/mcf5329/clock/clock.c
+++ b/c/src/lib/libbsp/m68k/mcf5329/clock/clock.c
@@ -3,6 +3,7 @@
*/
#include <rtems.h>
+#include <rtems/timecounter.h>
#include <bsp.h>
/*
@@ -10,36 +11,40 @@
*/
#define CLOCK_VECTOR (128+46)
-static uint32_t s_pcntrAtTick = 0;
-static uint32_t s_nanoScale = 0;
+static rtems_timecounter_simple mcf5329_tc;
-/*
- * Provide nanosecond extension
- */
-static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
+static uint32_t mcf5329_tc_get(rtems_timecounter_simple *tc)
{
- uint32_t i;
+ return MCF_PIT3_PCNTR;
+}
- if (MCF_PIT3_PCSR & MCF_PIT_PCSR_PIF) {
- i = s_pcntrAtTick + (MCF_PIT3_PMR - MCF_PIT3_PCNTR);
- } else {
- i = s_pcntrAtTick - MCF_PIT3_PCNTR;
- }
- return i * s_nanoScale;
+static bool mcf5329_tc_is_pending(rtems_timecounter_simple *tc)
+{
+ return (MCF_PIT3_PCSR & MCF_PIT_PCSR_PIF) != 0;
+}
+
+static uint32_t mcf5329_tc_get_timecount(struct timecounter *tc)
+{
+ return rtems_timecounter_simple_downcounter_get(
+ tc,
+ mcf5329_tc_get,
+ mcf5329_tc_is_pending
+ );
}
-#define Clock_driver_nanoseconds_since_last_tick bsp_clock_nanoseconds_since_last_tick
+static void mcf5329_tc_tick(void)
+{
+ rtems_timecounter_simple_downcounter_tick(&mcf5329_tc, mcf5329_tc_get);
+}
/*
* Periodic interval timer interrupt handler
*/
#define Clock_driver_support_at_tick() \
do { \
- s_pcntrAtTick = MCF_PIT3_PCNTR; \
MCF_PIT3_PCSR |= MCF_PIT_PCSR_PIF; \
} while (0) \
-
/*
* Attach clock interrupt handler
*/
@@ -75,8 +80,6 @@ static void Clock_driver_support_initialize_hardware(void)
break;
preScaleCode++;
}
- s_nanoScale = 1000000000 / (clk >> preScaleCode);
-
MCF_INTC1_ICR46 = MCF_INTC_ICR_IL(PIT3_IRQ_LEVEL);
rtems_interrupt_disable(level);
@@ -89,7 +92,15 @@ static void Clock_driver_support_initialize_hardware(void)
MCF_PIT3_PMR = pmr;
MCF_PIT3_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) |
MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_EN;
- s_pcntrAtTick = MCF_PIT3_PCNTR;
+
+ rtems_timecounter_simple_install(
+ &mcf5329_tc,
+ clk >> preScaleCode,
+ pmr,
+ mcf5329_tc_get_timecount
+ );
}
+#define Clock_driver_timecounter_tick() mcf5329_tc_tick()
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/m68k/sim68000/clock/clockdrv.c b/c/src/lib/libbsp/m68k/sim68000/clock/clockdrv.c
index 3cf981863a..0a78abc15f 100644
--- a/c/src/lib/libbsp/m68k/sim68000/clock/clockdrv.c
+++ b/c/src/lib/libbsp/m68k/sim68000/clock/clockdrv.c
@@ -48,4 +48,6 @@ static void Clock_driver_support_shutdown_hardware(void)
t->cr = 0xA0; /* initialize with timer disabled */
}
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/m68k/uC5282/clock/clock.c b/c/src/lib/libbsp/m68k/uC5282/clock/clock.c
index 8636f96fe0..46e045cae3 100644
--- a/c/src/lib/libbsp/m68k/uC5282/clock/clock.c
+++ b/c/src/lib/libbsp/m68k/uC5282/clock/clock.c
@@ -12,6 +12,7 @@
*/
#include <rtems.h>
+#include <rtems/timecounter.h>
#include <bsp.h>
#include <mcf5282/mcf5282.h>
@@ -20,6 +21,32 @@
*/
#define CLOCK_VECTOR (64+58)
+static rtems_timecounter_simple uC5282_tc;
+
+static uint32_t uC5282_tc_get(rtems_timecounter_simple *tc)
+{
+ return MCF5282_PIT3_PCNTR;
+}
+
+static bool uC5282_tc_is_pending(rtems_timecounter_simple *tc)
+{
+ return (MCF5282_PIT3_PCSR & MCF5282_PIT_PCSR_PIF) != 0;
+}
+
+static uint32_t uC5282_tc_get_timecount(struct timecounter *tc)
+{
+ return rtems_timecounter_simple_downcounter_get(
+ tc,
+ uC5282_tc_get,
+ uC5282_tc_is_pending
+ );
+}
+
+static void uC5282_tc_tick(void)
+{
+ rtems_timecounter_simple_downcounter_tick(&uC5282_tc, uC5282_tc_get);
+}
+
/*
* CPU load counters
* Place in static RAM so updates don't hit the SDRAM
@@ -31,17 +58,6 @@
#define NSEC_PER_PITC __SRAMBASE.nsec_per_pitc
#define FILTER_SHIFT 6
-static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
-{
- int i = MCF5282_PIT3_PCNTR;
- if (MCF5282_PIT3_PCSR & MCF5282_PIT_PCSR_PIF)
- i = MCF5282_PIT3_PCNTR - PITC_PER_TICK;
- return (PITC_PER_TICK - i) * NSEC_PER_PITC;
-}
-
-#define Clock_driver_nanoseconds_since_last_tick \
- bsp_clock_nanoseconds_since_last_tick
-
/*
* Periodic interval timer interrupt handler
*/
@@ -83,7 +99,7 @@ static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
*/
#define Clock_driver_support_initialize_hardware() \
do { \
- unsigned long long N; \
+ unsigned long long N; \
int level; \
int preScaleCode = 0; \
N = bsp_get_CPU_clock_speed(); \
@@ -116,6 +132,12 @@ static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
MCF5282_PIT_PCSR_PIE | \
MCF5282_PIT_PCSR_RLD | \
MCF5282_PIT_PCSR_EN; \
+ rtems_timecounter_simple_install( \
+ &uC5282_tc, \
+ bsp_get_CPU_clock_speed() >> (preScaleCode + 1), \
+ PITC_PER_TICK, \
+ uC5282_tc_get_timecount \
+ ); \
} while (0)
/*
@@ -135,4 +157,6 @@ int bsp_cpu_load_percentage(void)
0;
}
+#define Clock_driver_timecounter_tick() uC5282_tc_tick()
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/mips/csb350/clock/clockdrv.c b/c/src/lib/libbsp/mips/csb350/clock/clockdrv.c
index c733a1b19a..537bf7ee1e 100644
--- a/c/src/lib/libbsp/mips/csb350/clock/clockdrv.c
+++ b/c/src/lib/libbsp/mips/csb350/clock/clockdrv.c
@@ -88,4 +88,6 @@ void au1x00_clock_init(void)
#define Clock_driver_support_shutdown_hardware()
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/mips/genmongoosev/clock/clockdrv.c b/c/src/lib/libbsp/mips/genmongoosev/clock/clockdrv.c
index 05c1a92ac4..20f730ad6b 100644
--- a/c/src/lib/libbsp/mips/genmongoosev/clock/clockdrv.c
+++ b/c/src/lib/libbsp/mips/genmongoosev/clock/clockdrv.c
@@ -54,4 +54,6 @@
#define Clock_driver_support_shutdown_hardware() \
MONGOOSEV_WRITE_REGISTER( CLOCK_BASE, MONGOOSEV_TIMER_CONTROL_REGISTER, 0 )
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/mips/jmr3904/clock/clockdrv.c b/c/src/lib/libbsp/mips/jmr3904/clock/clockdrv.c
index 4aa1f9ebb6..f3bcbe25f1 100644
--- a/c/src/lib/libbsp/mips/jmr3904/clock/clockdrv.c
+++ b/c/src/lib/libbsp/mips/jmr3904/clock/clockdrv.c
@@ -55,4 +55,6 @@
#define Clock_driver_support_shutdown_hardware()
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/mips/rbtx4925/clock/clockdrv.c b/c/src/lib/libbsp/mips/rbtx4925/clock/clockdrv.c
index 4a45c9a955..2fb56c6eb9 100644
--- a/c/src/lib/libbsp/mips/rbtx4925/clock/clockdrv.c
+++ b/c/src/lib/libbsp/mips/rbtx4925/clock/clockdrv.c
@@ -123,5 +123,6 @@
TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TCR, 0x0 ); /* Disable timer */ \
} while(0)
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/mips/rbtx4938/clock/clockdrv.c b/c/src/lib/libbsp/mips/rbtx4938/clock/clockdrv.c
index f50c6d2fdc..59b3452d88 100644
--- a/c/src/lib/libbsp/mips/rbtx4938/clock/clockdrv.c
+++ b/c/src/lib/libbsp/mips/rbtx4938/clock/clockdrv.c
@@ -114,4 +114,6 @@ void new_brk_esr(void)
} while(0)
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/mips/shared/clock/clockdrv.c b/c/src/lib/libbsp/mips/shared/clock/clockdrv.c
index 8ee52c63ed..8b178bbd52 100644
--- a/c/src/lib/libbsp/mips/shared/clock/clockdrv.c
+++ b/c/src/lib/libbsp/mips/shared/clock/clockdrv.c
@@ -43,17 +43,11 @@ static uint32_t mips_timer_rate = 0;
mips_enable_in_interrupt_mask(CLOCK_VECTOR_MASK); \
} while(0)
-static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
-{
- return 0;
-}
-
-#define Clock_driver_nanoseconds_since_last_tick \
- bsp_clock_nanoseconds_since_last_tick
-
#define Clock_driver_support_shutdown_hardware() \
do { \
mips_disable_in_interrupt_mask(CLOCK_VECTOR_MASK); \
} while (0)
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/nios2/nios2_iss/clock/clock.c b/c/src/lib/libbsp/nios2/nios2_iss/clock/clock.c
index 939af651c5..1656e763c1 100644
--- a/c/src/lib/libbsp/nios2/nios2_iss/clock/clock.c
+++ b/c/src/lib/libbsp/nios2/nios2_iss/clock/clock.c
@@ -49,5 +49,7 @@ static void Clock_driver_support_initialize_hardware(void)
NIOS2_IENABLE(1 << CLOCK_VECTOR);
}
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/or1k/generic_or1k/clock/clockdrv.c b/c/src/lib/libbsp/or1k/generic_or1k/clock/clockdrv.c
index 57e46c1897..e01d2e506d 100644
--- a/c/src/lib/libbsp/or1k/generic_or1k/clock/clockdrv.c
+++ b/c/src/lib/libbsp/or1k/generic_or1k/clock/clockdrv.c
@@ -22,11 +22,14 @@
#include <bsp/generic_or1k.h>
#include <rtems/score/cpu.h>
#include <rtems/score/or1k-utility.h>
+#include <rtems/timecounter.h>
/* The number of clock cycles before generating a tick timer interrupt. */
#define TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT 0x09ED9
#define OR1K_CLOCK_CYCLE_TIME_NANOSECONDS 10
+static struct timecounter or1ksim_tc;
+
/* CPU counter */
static CPU_Counter_ticks cpu_counter_ticks;
@@ -69,8 +72,23 @@ static void generic_or1k_clock_handler_install(
}
}
+static uint32_t or1ksim_get_timecount(struct timecounter *tc)
+{
+ uint32_t ticks_since_last_timer_interrupt;
+
+ ticks_since_last_timer_interrupt = _OR1K_mfspr(CPU_OR1K_SPR_TTCR);
+
+ return cpu_counter_ticks + ticks_since_last_timer_interrupt;
+}
+
+CPU_Counter_ticks _CPU_Counter_read(void)
+{
+ return or1ksim_get_timecount(NULL);
+}
+
static void generic_or1k_clock_initialize(void)
{
+ uint64_t frequency = (1000000000 / OR1K_CLOCK_CYCLE_TIME_NANOSECONDS);
uint32_t TTMR;
/* For TTMR register,
@@ -90,11 +108,15 @@ static void generic_or1k_clock_initialize(void)
_OR1K_mtspr(CPU_OR1K_SPR_TTMR, TTMR);
_OR1K_mtspr(CPU_OR1K_SPR_TTCR, 0);
- /* Initialize CPU Counter */
- cpu_counter_ticks = 0;
+ /* Initialize timecounter */
+ or1ksim_tc.tc_get_timecount = or1ksim_get_timecount;
+ or1ksim_tc.tc_counter_mask = 0xffffffff;
+ or1ksim_tc.tc_frequency = frequency;
+ or1ksim_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install(&or1ksim_tc);
}
- static void generic_or1k_clock_cleanup(void)
+static void generic_or1k_clock_cleanup(void)
{
uint32_t sr;
@@ -109,24 +131,6 @@ static void generic_or1k_clock_initialize(void)
_OR1K_mtspr(CPU_OR1K_SPR_TTMR, 0);
}
-/*
- * Return the nanoseconds since last tick
- */
-static uint32_t generic_or1k_clock_nanoseconds_since_last_tick(void)
-{
- return
- TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT * OR1K_CLOCK_CYCLE_TIME_NANOSECONDS;
-}
-
-CPU_Counter_ticks _CPU_Counter_read(void)
-{
- uint32_t ticks_since_last_timer_interrupt;
-
- ticks_since_last_timer_interrupt = _OR1K_mfspr(CPU_OR1K_SPR_TTCR);
-
- return cpu_counter_ticks + ticks_since_last_timer_interrupt;
-}
-
CPU_Counter_ticks _CPU_Counter_difference(
CPU_Counter_ticks second,
CPU_Counter_ticks first
@@ -134,6 +138,7 @@ CPU_Counter_ticks _CPU_Counter_difference(
{
return second - first;
}
+
#define Clock_driver_support_at_tick() generic_or1k_clock_at_tick()
#define Clock_driver_support_initialize_hardware() generic_or1k_clock_initialize()
@@ -146,7 +151,4 @@ CPU_Counter_ticks _CPU_Counter_difference(
#define Clock_driver_support_shutdown_hardware() generic_or1k_clock_cleanup()
-#define Clock_driver_nanoseconds_since_last_tick \
- generic_or1k_clock_nanoseconds_since_last_tick
-
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c
index 5743dcff35..5724f9bf4b 100644
--- a/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c
+++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c
@@ -26,14 +26,40 @@
#include <mpc55xx/regs.h>
+#include <rtems/timecounter.h>
+
void Clock_isr(void *arg);
-static uint64_t mpc55xx_clock_factor;
+static rtems_timecounter_simple mpc55xx_tc;
#if defined(MPC55XX_CLOCK_EMIOS_CHANNEL)
#include <mpc55xx/emios.h>
+static uint32_t mpc55xx_tc_get(rtems_timecounter_simple *tc)
+{
+ return EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CCNTR.R;
+}
+
+static bool mpc55xx_tc_is_pending(rtems_timecounter_simple *tc)
+{
+ return EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CSR.B.FLAG != 0;
+}
+
+static uint32_t mpc55xx_tc_get_timecount(struct timecounter *tc)
+{
+ return rtems_timecounter_simple_upcounter_get(
+ tc,
+ mpc55xx_tc_get,
+ mpc55xx_tc_is_pending
+ );
+}
+
+static void mpc55xx_tc_tick(void)
+{
+ rtems_timecounter_simple_upcounter_tick(&mpc55xx_tc, mpc55xx_tc_get);
+}
+
static void mpc55xx_clock_at_tick(void)
{
union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS;
@@ -60,6 +86,7 @@ static void mpc55xx_clock_handler_install(rtems_isr_entry isr)
static void mpc55xx_clock_initialize(void)
{
+ uint32_t mask;
volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
union EMIOS_CCR_tag ccr = MPC55XX_ZERO_FLAGS;
union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS;
@@ -68,8 +95,6 @@ static void mpc55xx_clock_initialize(void)
uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
uint64_t interval = (reference_clock * us_per_tick) / 1000000;
- mpc55xx_clock_factor = (1000000000ULL << 32) / reference_clock;
-
/* Apply prescaler */
if (prescaler > 0) {
interval /= (uint64_t) prescaler;
@@ -110,6 +135,13 @@ static void mpc55xx_clock_initialize(void)
ccr.B.FEN = 1;
ccr.B.FREN = 1;
regs->CCR.R = ccr.R;
+
+ rtems_timecounter_simple_install(
+ &mpc55xx_tc,
+ reference_clock,
+ interval,
+ mpc55xx_tc_get_timecount
+ );
}
static void mpc55xx_clock_cleanup(void)
@@ -122,21 +154,31 @@ static void mpc55xx_clock_cleanup(void)
regs->CCR.R = ccr.R;
}
-static uint32_t mpc55xx_clock_nanoseconds_since_last_tick(void)
+#elif defined(MPC55XX_CLOCK_PIT_CHANNEL)
+
+static uint32_t mpc55xx_tc_get(rtems_timecounter_simple *tc)
{
- volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
- uint64_t c = regs->CCNTR.R;
- union EMIOS_CSR_tag csr = { .R = regs->CSR.R };
- uint64_t k = mpc55xx_clock_factor;
+ return PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL].CVAL.R;
+}
- if (csr.B.FLAG != 0) {
- c = regs->CCNTR.R + regs->CADR.R + 1;
- }
+static bool mpc55xx_tc_is_pending(rtems_timecounter_simple *tc)
+{
+ return PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL].TFLG.B.TIF != 0;
+}
- return (uint32_t) ((c * k) >> 32);
+static uint32_t mpc55xx_tc_get_timecount(struct timecounter *tc)
+{
+ return rtems_timecounter_simple_downcounter_get(
+ tc,
+ mpc55xx_tc_get,
+ mpc55xx_tc_is_pending
+ );
}
-#elif defined(MPC55XX_CLOCK_PIT_CHANNEL)
+static void mpc55xx_tc_tick(void)
+{
+ rtems_timecounter_simple_downcounter_tick(&mpc55xx_tc, mpc55xx_tc_get);
+}
static void mpc55xx_clock_at_tick(void)
{
@@ -166,6 +208,7 @@ static void mpc55xx_clock_handler_install(rtems_isr_entry isr)
static void mpc55xx_clock_initialize(void)
{
+ uint32_t mask;
volatile PIT_RTI_CHANNEL_tag *channel =
&PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
uint64_t reference_clock = bsp_clock_speed;
@@ -174,11 +217,16 @@ static void mpc55xx_clock_initialize(void)
PIT_RTI_PITMCR_32B_tag pitmcr = { .B = { .FRZ = 1 } };
PIT_RTI_TCTRL_32B_tag tctrl = { .B = { .TIE = 1, .TEN = 1 } };
- mpc55xx_clock_factor = (1000000000ULL << 32) / reference_clock;
-
PIT_RTI.PITMCR.R = pitmcr.R;
channel->LDVAL.R = interval;
channel->TCTRL.R = tctrl.R;
+
+ rtems_timecounter_simple_install(
+ &mpc55xx_tc,
+ reference_clock,
+ interval,
+ mpc55xx_tc_get_timecount
+ );
}
static void mpc55xx_clock_cleanup(void)
@@ -189,23 +237,9 @@ static void mpc55xx_clock_cleanup(void)
channel->TCTRL.R = 0;
}
-static uint32_t mpc55xx_clock_nanoseconds_since_last_tick(void)
-{
- volatile PIT_RTI_CHANNEL_tag *channel =
- &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
- uint32_t c = channel->CVAL.R;
- uint32_t i = channel->LDVAL.R;
- uint64_t k = mpc55xx_clock_factor;
-
- if (channel->TFLG.B.TIF != 0) {
- c = channel->CVAL.R - i;
- }
-
- return (uint32_t) (((i - c) * k) >> 32);
-}
-
#endif
+#define Clock_driver_timecounter_tick() mpc55xx_tc_tick()
#define Clock_driver_support_at_tick() \
mpc55xx_clock_at_tick()
#define Clock_driver_support_initialize_hardware() \
@@ -217,8 +251,6 @@ static uint32_t mpc55xx_clock_nanoseconds_since_last_tick(void)
} while (0)
#define Clock_driver_support_shutdown_hardware() \
mpc55xx_clock_cleanup()
-#define Clock_driver_nanoseconds_since_last_tick \
- mpc55xx_clock_nanoseconds_since_last_tick
/* Include shared source clock driver code */
#include "../../../../libbsp/shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c b/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c
index 039edde46e..c6300e254f 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c
+++ b/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c
@@ -7,10 +7,10 @@
*/
/*
- * Copyright (c) 2011-2012 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2011-2015 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
- * Obere Lagerstr. 30
+ * Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
@@ -20,6 +20,8 @@
* http://www.rtems.org/license/LICENSE.
*/
+#include <rtems/timecounter.h>
+
#include <libcpu/powerpc-utility.h>
#include <bsp.h>
@@ -29,10 +31,6 @@
/* This is defined in clockdrv_shell.h */
static rtems_isr Clock_isr(void *arg);
-static uint32_t qoriq_clock_last_ccr;
-
-static uint32_t qoriq_clock_nanoseconds_per_timer_tick;
-
static volatile qoriq_pic_global_timer *const qoriq_clock =
#if QORIQ_CLOCK_TIMER < 4
&qoriq.pic.gta [QORIQ_CLOCK_TIMER];
@@ -40,8 +38,17 @@ static volatile qoriq_pic_global_timer *const qoriq_clock =
&qoriq.pic.gtb [QORIQ_CLOCK_TIMER - 4];
#endif
+static volatile qoriq_pic_global_timer *const qoriq_timecounter =
+ #if QORIQ_CLOCK_TIMECOUNTER < 4
+ &qoriq.pic.gta [QORIQ_CLOCK_TIMECOUNTER];
+ #else
+ &qoriq.pic.gtb [QORIQ_CLOCK_TIMECOUNTER - 4];
+ #endif
+
#define CLOCK_INTERRUPT (QORIQ_IRQ_GT_BASE + QORIQ_CLOCK_TIMER)
+static struct timecounter qoriq_clock_tc;
+
static void qoriq_clock_handler_install(rtems_isr_entry *old_isr)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
@@ -77,18 +84,28 @@ static void qoriq_clock_handler_install(rtems_isr_entry *old_isr)
}
}
+static uint32_t qoriq_clock_get_timecount(struct timecounter *tc)
+{
+ uint32_t ccr = qoriq_timecounter->ccr;
+
+ return GTCCR_COUNT_GET(-ccr);
+}
+
static void qoriq_clock_initialize(void)
{
uint32_t timer_frequency = BSP_bus_frequency / 8;
- uint32_t nanoseconds_per_second = 1000000000;
uint32_t interval = (uint32_t) (((uint64_t) timer_frequency
* (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000);
- qoriq_clock_nanoseconds_per_timer_tick =
- nanoseconds_per_second / timer_frequency;
-
qoriq_clock->bcr = GTBCR_COUNT(interval);
- qoriq_clock_last_ccr = qoriq_clock->ccr;
+
+ qoriq_timecounter->bcr = GTBCR_COUNT(0xffffffff);
+
+ qoriq_clock_tc.tc_get_timecount = qoriq_clock_get_timecount;
+ qoriq_clock_tc.tc_counter_mask = GTCCR_COUNT_GET(0xffffffff);
+ qoriq_clock_tc.tc_frequency = timer_frequency;
+ qoriq_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install(&qoriq_clock_tc);
}
static void qoriq_clock_cleanup(void)
@@ -107,33 +124,13 @@ static void qoriq_clock_cleanup(void)
}
}
-static void qoriq_clock_at_tick(void)
-{
- qoriq_clock_last_ccr = qoriq_clock->ccr;
-}
-
-static uint32_t qoriq_clock_nanoseconds_since_last_tick(void)
-{
- uint32_t ccr = qoriq_clock->ccr;
- uint32_t bcr = qoriq_clock->bcr;
-
- if ((ccr & GTCCR_TOG) != (qoriq_clock_last_ccr & GTCCR_TOG)) {
- bcr += bcr;
- }
-
- return (bcr - GTCCR_COUNT_GET(ccr)) * qoriq_clock_nanoseconds_per_timer_tick;
-}
-
-#define Clock_driver_support_at_tick() \
- qoriq_clock_at_tick()
+#define Clock_driver_support_at_tick()
#define Clock_driver_support_initialize_hardware() \
qoriq_clock_initialize()
#define Clock_driver_support_install_isr(clock_isr, old_isr) \
qoriq_clock_handler_install(&old_isr)
#define Clock_driver_support_shutdown_hardware() \
qoriq_clock_cleanup()
-#define Clock_driver_nanoseconds_since_last_tick \
- qoriq_clock_nanoseconds_since_last_tick
/* Include shared source clock driver code */
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/powerpc/qoriq/configure.ac b/c/src/lib/libbsp/powerpc/qoriq/configure.ac
index f1ff103d7c..409ac193c4 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/configure.ac
+++ b/c/src/lib/libbsp/powerpc/qoriq/configure.ac
@@ -154,6 +154,10 @@ RTEMS_BSPOPTS_SET([QORIQ_CLOCK_TIMER],[qoriq_core_1],[4])
RTEMS_BSPOPTS_SET([QORIQ_CLOCK_TIMER],[*],[0])
RTEMS_BSPOPTS_HELP([QORIQ_CLOCK_TIMER],[global timer used for system clock, 0..3 maps to A0..A3, and 4..7 maps to B0..B3])
+RTEMS_BSPOPTS_SET([QORIQ_CLOCK_TIMECOUNTER],[qoriq_core_1],[5])
+RTEMS_BSPOPTS_SET([QORIQ_CLOCK_TIMECOUNTER],[*],[1])
+RTEMS_BSPOPTS_HELP([QORIQ_CLOCK_TIMECOUNTER],[global timer used for the timecounter, 0..3 maps to A0..A3, and 4..7 maps to B0..B3])
+
RTEMS_BSPOPTS_SET([QORIQ_CHIP_VARIANT],[qoriq_t2080*],[QORIQ_CHIP_T2080])
RTEMS_BSPOPTS_SET([QORIQ_CHIP_VARIANT],[qoriq_t4240*],[QORIQ_CHIP_T4240])
RTEMS_BSPOPTS_SET([QORIQ_CHIP_VARIANT],[*],[QORIQ_CHIP_P1020])
diff --git a/c/src/lib/libbsp/powerpc/shared/clock/clock.c b/c/src/lib/libbsp/powerpc/shared/clock/clock.c
index e9b1d4d24a..d2f2d0d1b0 100644
--- a/c/src/lib/libbsp/powerpc/shared/clock/clock.c
+++ b/c/src/lib/libbsp/powerpc/shared/clock/clock.c
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (c) 2008-2013 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2008-2015 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Obere Lagerstr. 30
@@ -22,6 +22,7 @@
#include <rtems.h>
#include <rtems/clockdrv.h>
+#include <rtems/timecounter.h>
#include <libcpu/powerpc-utility.h>
#include <bsp/vectors.h>
@@ -46,7 +47,12 @@ static uint32_t ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX;
static uint32_t ppc_clock_next_time_base;
-static uint64_t ppc_clock_factor;
+static struct timecounter ppc_tc;
+
+static uint32_t ppc_get_timecount(struct timecounter *tc)
+{
+ return ppc_time_base();
+}
static void ppc_clock_no_tick(void)
{
@@ -161,28 +167,6 @@ static int ppc_clock_exception_handler_ppc405(BSP_Exception_frame *frame, unsign
return 0;
}
-static uint32_t ppc_clock_nanoseconds_since_last_tick(void)
-{
- uint64_t k = ppc_clock_factor;
- uint32_t c = ppc_decrementer_register();
- uint32_t i = ppc_clock_decrementer_value + 1;
-
- return (uint32_t) (((i - c) * k) >> 32);
-}
-
-static uint32_t ppc_clock_nanoseconds_since_last_tick_ppc405(void)
-{
- uint64_t k = ppc_clock_factor;
- uint32_t i = ppc_clock_decrementer_value;
- uint32_t c = i - PPC_SPECIAL_PURPOSE_REGISTER(PPC405_PIT);
-
- if ((PPC_SPECIAL_PURPOSE_REGISTER(PPC405_TSR) & BOOKE_TSR_DIS) != 0) {
- c = i - PPC_SPECIAL_PURPOSE_REGISTER(PPC405_PIT) + i;
- }
-
- return (uint32_t) ((c * k) >> 32);
-}
-
void Clock_exit(void)
{
/* Set the decrementer to the maximum value */
@@ -201,18 +185,12 @@ rtems_device_driver Clock_initialize(
uint64_t frequency = bsp_time_base_frequency;
uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000);
+ uint32_t mask;
/*
* Set default ticker.
- *
- * The function rtems_clock_tick() returns a status code. This value
- * will be discarded since the RTEMS documentation claims that it is
- * always successful.
*/
- ppc_clock_tick = (void (*)(void)) rtems_clock_tick;
-
- /* Factor for nano seconds extension */
- ppc_clock_factor = (1000000000ULL << 32) / frequency;
+ ppc_clock_tick = rtems_timecounter_tick;
if (ppc_cpu_is_bookE() != PPC_BOOKE_405) {
/* Decrementer value */
@@ -223,10 +201,6 @@ rtems_device_driver Clock_initialize(
ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX;
RTEMS_SYSLOG_ERROR( "decrementer value would be zero, will be set to maximum value instead\n");
}
-
- /* Set the nanoseconds since last tick handler */
- rtems_clock_set_nanoseconds_extension( ppc_clock_nanoseconds_since_last_tick);
-
if (ppc_cpu_is_bookE()) {
/* Set decrementer auto-reload value */
PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_DECAR, ppc_clock_decrementer_value);
@@ -253,9 +227,6 @@ rtems_device_driver Clock_initialize(
/* PIT interval value */
ppc_clock_decrementer_value = interval;
- /* Set the nanoseconds since last tick handler */
- rtems_clock_set_nanoseconds_extension(ppc_clock_nanoseconds_since_last_tick_ppc405);
-
/* Install exception handler */
ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_ppc405);
@@ -266,5 +237,12 @@ rtems_device_driver Clock_initialize(
PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_PIT, interval);
}
+ /* Install timecounter */
+ ppc_tc.tc_get_timecount = ppc_get_timecount;
+ ppc_tc.tc_counter_mask = 0xffffffff;
+ ppc_tc.tc_frequency = frequency;
+ ppc_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install(&ppc_tc);
+
return RTEMS_SUCCESSFUL;
}
diff --git a/c/src/lib/libbsp/shared/clock_driver_simidle.c b/c/src/lib/libbsp/shared/clock_driver_simidle.c
index 0f94b1e56b..ee4b116b40 100644
--- a/c/src/lib/libbsp/shared/clock_driver_simidle.c
+++ b/c/src/lib/libbsp/shared/clock_driver_simidle.c
@@ -28,6 +28,8 @@ volatile bool clock_driver_enabled;
clock_driver_enabled = false; \
} while (0)
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "clockdrv_shell.h"
/*
diff --git a/c/src/lib/libbsp/shared/clockdrv_shell.h b/c/src/lib/libbsp/shared/clockdrv_shell.h
index 5dbea1335f..628ba58672 100644
--- a/c/src/lib/libbsp/shared/clockdrv_shell.h
+++ b/c/src/lib/libbsp/shared/clockdrv_shell.h
@@ -20,6 +20,10 @@
#include <bsp.h>
#include <rtems/clockdrv.h>
+#ifdef Clock_driver_nanoseconds_since_last_tick
+#error "Update driver to use the timecounter instead of nanoseconds extension"
+#endif
+
/**
* @defgroup bsp_clock Clock Support
*
@@ -39,6 +43,18 @@
#define Clock_driver_support_find_timer()
#endif
+/*
+ * A specialized clock driver may use for example rtems_timecounter_tick_simple()
+ * instead of the default.
+ */
+#ifndef Clock_driver_timecounter_tick
+ #ifdef CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+ #define Clock_driver_timecounter_tick() rtems_clock_tick()
+ #else
+ #define Clock_driver_timecounter_tick() rtems_timecounter_tick()
+ #endif
+#endif
+
/**
* @brief ISRs until next clock tick
*/
@@ -78,16 +94,24 @@ rtems_isr Clock_isr(
Clock_driver_ticks += 1;
#if CLOCK_DRIVER_USE_FAST_IDLE
- do {
- rtems_clock_tick();
- } while (
- _Thread_Heir == _Thread_Executing
- && _Thread_Executing->Start.entry_point
- == (Thread_Entry) rtems_configuration_get_idle_task()
- );
+ {
+ struct timecounter *tc = _Timecounter;
+ uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
+ uint32_t interval = (uint32_t)
+ ((tc->tc_frequency * us_per_tick) / 1000000);
+
+ Clock_driver_timecounter_tick();
+
+ while (
+ _Thread_Heir == _Thread_Executing
+ && _Thread_Executing->Start.entry_point
+ == (Thread_Entry) rtems_configuration_get_idle_task()
+ ) {
+ _Timecounter_Tick_simple(interval, (*tc->tc_get_timecount)(tc));
+ }
- Clock_driver_support_at_tick();
- return;
+ Clock_driver_support_at_tick();
+ }
#else
/*
* Do the hardware specific per-tick action.
@@ -101,7 +125,7 @@ rtems_isr Clock_isr(
* The driver is multiple ISRs per clock tick.
*/
if ( !Clock_driver_isrs ) {
- rtems_clock_tick();
+ Clock_driver_timecounter_tick();
Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK;
}
@@ -110,7 +134,7 @@ rtems_isr Clock_isr(
/*
* The driver is one ISR per clock tick.
*/
- rtems_clock_tick();
+ Clock_driver_timecounter_tick();
#endif
#endif
}
@@ -160,12 +184,6 @@ rtems_device_driver Clock_initialize(
(void) Old_ticker;
Clock_driver_support_install_isr( Clock_isr, Old_ticker );
- #if defined(Clock_driver_nanoseconds_since_last_tick)
- rtems_clock_set_nanoseconds_extension(
- Clock_driver_nanoseconds_since_last_tick
- );
- #endif
-
/*
* Now initialize the hardware that is the source of the tick ISR.
*/
diff --git a/c/src/lib/libbsp/sparc/erc32/clock/ckinit.c b/c/src/lib/libbsp/sparc/erc32/clock/ckinit.c
index 2afe770b4b..46f99a5e7d 100644
--- a/c/src/lib/libbsp/sparc/erc32/clock/ckinit.c
+++ b/c/src/lib/libbsp/sparc/erc32/clock/ckinit.c
@@ -25,6 +25,7 @@
#include <bsp.h>
#include <bspopts.h>
#include <rtems/counter.h>
+#include <rtems/timecounter.h>
#if SIMSPARC_FAST_IDLE==1
#define CLOCK_DRIVER_USE_FAST_IDLE 1
@@ -44,24 +45,34 @@
extern int CLOCK_SPEED;
-static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
+static rtems_timecounter_simple erc32_tc;
+
+static uint32_t erc32_tc_get( rtems_timecounter_simple *tc )
+{
+ return ERC32_MEC.Real_Time_Clock_Counter;
+}
+
+static bool erc32_tc_is_pending( rtems_timecounter_simple *tc )
+{
+ return ERC32_Is_interrupt_pending( ERC32_INTERRUPT_REAL_TIME_CLOCK );
+}
+
+static uint32_t erc32_tc_get_timecount( struct timecounter *tc )
{
- uint32_t clicks;
- uint32_t usecs;
-
- clicks = ERC32_MEC.Real_Time_Clock_Counter;
-
- if ( ERC32_Is_interrupt_pending( ERC32_INTERRUPT_REAL_TIME_CLOCK ) ) {
- clicks = ERC32_MEC.Real_Time_Clock_Counter;
- usecs = (2*rtems_configuration_get_microseconds_per_tick() - clicks);
- } else {
- usecs = (rtems_configuration_get_microseconds_per_tick() - clicks);
- }
- return usecs * 1000;
+ return rtems_timecounter_simple_downcounter_get(
+ tc,
+ erc32_tc_get,
+ erc32_tc_is_pending
+ );
}
-#define Clock_driver_nanoseconds_since_last_tick \
- bsp_clock_nanoseconds_since_last_tick
+static void erc32_tc_tick( void )
+{
+ rtems_timecounter_simple_downcounter_tick(
+ &erc32_tc,
+ erc32_tc_get
+ );
+}
static CPU_Counter_ticks erc32_counter_difference(
CPU_Counter_ticks second,
@@ -75,6 +86,7 @@ static CPU_Counter_ticks erc32_counter_difference(
#define Clock_driver_support_initialize_hardware() \
do { \
+ uint32_t frequency = 1000000; \
/* approximately 1 us per countdown */ \
ERC32_MEC.Real_Time_Clock_Scalar = CLOCK_SPEED - 1; \
ERC32_MEC.Real_Time_Clock_Counter = \
@@ -89,14 +101,22 @@ static CPU_Counter_ticks erc32_counter_difference(
ERC32_MEC_Set_Real_Time_Clock_Timer_Control( \
ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING | \
ERC32_MEC_TIMER_COUNTER_RELOAD_AT_ZERO \
+ ); \
+ rtems_timecounter_simple_install( \
+ &erc32_tc, \
+ frequency, \
+ rtems_configuration_get_microseconds_per_tick(), \
+ erc32_tc_get_timecount \
); \
_SPARC_Counter_initialize( \
&ERC32_MEC.Real_Time_Clock_Counter, \
erc32_counter_difference \
); \
- rtems_counter_initialize_converter(1000000); \
+ rtems_counter_initialize_converter( frequency ); \
} while (0)
+#define Clock_driver_timecounter_tick() erc32_tc_tick()
+
#define Clock_driver_support_shutdown_hardware() \
do { \
ERC32_Mask_interrupt( ERC32_INTERRUPT_REAL_TIME_CLOCK ); \
diff --git a/c/src/lib/libbsp/sparc/leon2/clock/ckinit.c b/c/src/lib/libbsp/sparc/leon2/clock/ckinit.c
index ab4efa0e8a..3dd68e080a 100644
--- a/c/src/lib/libbsp/sparc/leon2/clock/ckinit.c
+++ b/c/src/lib/libbsp/sparc/leon2/clock/ckinit.c
@@ -24,11 +24,38 @@
#include <bsp.h>
#include <bspopts.h>
+#include <rtems/timecounter.h>
#if SIMSPARC_FAST_IDLE==1
#define CLOCK_DRIVER_USE_FAST_IDLE 1
#endif
+static rtems_timecounter_simple leon2_tc;
+
+static uint32_t leon2_tc_get( rtems_timecounter_simple *tc )
+{
+ return LEON_REG.Timer_Counter_1;
+}
+
+static bool leon2_tc_is_pending( rtems_timecounter_simple *tc )
+{
+ return LEON_Is_interrupt_pending( LEON_INTERRUPT_TIMER1 );
+}
+
+static uint32_t leon2_tc_get_timecount( struct timecounter *tc )
+{
+ return rtems_timecounter_simple_downcounter_get(
+ tc,
+ leon2_tc_get,
+ leon2_tc_is_pending
+ );
+}
+
+static void leon2_tc_tick( void )
+{
+ rtems_timecounter_simple_downcounter_tick( &leon2_tc, leon2_tc_get );
+}
+
/*
* The Real Time Clock Counter Timer uses this trap type.
*/
@@ -54,6 +81,12 @@ extern int CLOCK_SPEED;
LEON_REG_TIMER_COUNTER_RELOAD_AT_ZERO | \
LEON_REG_TIMER_COUNTER_LOAD_COUNTER \
); \
+ rtems_timecounter_simple_install( \
+ &leon2_tc, \
+ 1000000, \
+ rtems_configuration_get_microseconds_per_tick(), \
+ leon2_tc_get_timecount \
+ ); \
} while (0)
#define Clock_driver_support_shutdown_hardware() \
@@ -62,23 +95,6 @@ extern int CLOCK_SPEED;
LEON_REG.Timer_Control_1 = 0; \
} while (0)
-static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
-{
- uint32_t clicks;
- uint32_t usecs;
-
- clicks = LEON_REG.Timer_Counter_1;
-
- if ( LEON_Is_interrupt_pending( LEON_INTERRUPT_TIMER1 ) ) {
- clicks = LEON_REG.Timer_Counter_1;
- usecs = (2*rtems_configuration_get_microseconds_per_tick() - clicks);
- } else {
- usecs = (rtems_configuration_get_microseconds_per_tick() - clicks);
- }
- return usecs * 1000;
-}
-
-#define Clock_driver_nanoseconds_since_last_tick \
- bsp_clock_nanoseconds_since_last_tick
+#define Clock_driver_timecounter_tick() leon2_tc_tick()
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/sparc/leon3/clock/ckinit.c b/c/src/lib/libbsp/sparc/leon3/clock/ckinit.c
index ad226161bc..b82b457866 100644
--- a/c/src/lib/libbsp/sparc/leon3/clock/ckinit.c
+++ b/c/src/lib/libbsp/sparc/leon3/clock/ckinit.c
@@ -24,6 +24,7 @@
#include <rtems/rtems/intr.h>
#include <ambapp.h>
#include <rtems/score/profiling.h>
+#include <rtems/timecounter.h>
/* The LEON3 BSP Timer driver can rely on the Driver Manager if the
* DrvMgr is initialized during startup. Otherwise the classic driver
@@ -40,6 +41,43 @@
/* LEON3 Timer system interrupt number */
static int clkirq;
+static bool leon3_tc_use_irqmp;
+
+static rtems_timecounter_simple leon3_tc;
+
+static uint32_t leon3_tc_get(rtems_timecounter_simple *tc)
+{
+ return LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX].value;
+}
+
+static bool leon3_tc_is_pending(rtems_timecounter_simple *tc)
+{
+ return LEON_Is_interrupt_pending(clkirq);
+}
+
+static uint32_t leon3_tc_get_timecount(struct timecounter *tc)
+{
+ return rtems_timecounter_simple_downcounter_get(
+ tc,
+ leon3_tc_get,
+ leon3_tc_is_pending
+ );
+}
+
+static uint32_t leon3_tc_get_timecount_irqmp(struct timecounter *tc)
+{
+ return LEON3_IrqCtrl_Regs->timestamp[0].counter;
+}
+
+static void leon3_tc_tick(void)
+{
+ if (leon3_tc_use_irqmp) {
+ rtems_timecounter_tick();
+ } else {
+ rtems_timecounter_simple_downcounter_tick(&leon3_tc, leon3_tc_get);
+ }
+}
+
static void leon3_clock_profiling_interrupt_delay(void)
{
#ifdef RTEMS_PROFILING
@@ -112,15 +150,36 @@ static void bsp_clock_handler_install(rtems_isr *new)
}
}
+static void leon3_clock_initialize(void)
+{
+ volatile struct irqmp_timestamp_regs *irqmp_ts =
+ &LEON3_IrqCtrl_Regs->timestamp[0];
+
+ LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX].reload =
+ rtems_configuration_get_microseconds_per_tick() - 1;
+ LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX].ctrl =
+ GPTIMER_TIMER_CTRL_EN | GPTIMER_TIMER_CTRL_RS |
+ GPTIMER_TIMER_CTRL_LD | GPTIMER_TIMER_CTRL_IE;
+
+ if (leon3_irqmp_has_timestamp(irqmp_ts)) {
+ leon3_tc.tc.tc_get_timecount = leon3_tc_get_timecount_irqmp;
+ leon3_tc.tc.tc_counter_mask = 0xffffffff;
+ leon3_tc.tc.tc_frequency = ambapp_freq_get(&ambapp_plb, LEON3_Timer_Adev);
+ leon3_tc.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ leon3_tc_use_irqmp = true;
+ rtems_timecounter_install(&leon3_tc.tc);
+ } else {
+ rtems_timecounter_simple_install(
+ &leon3_tc,
+ LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER,
+ rtems_configuration_get_microseconds_per_tick(),
+ leon3_tc_get_timecount
+ );
+ }
+}
+
#define Clock_driver_support_initialize_hardware() \
- do { \
- LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX].reload = \
- rtems_configuration_get_microseconds_per_tick() - 1; \
- \
- LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX].ctrl = \
- GPTIMER_TIMER_CTRL_EN | GPTIMER_TIMER_CTRL_RS | \
- GPTIMER_TIMER_CTRL_LD | GPTIMER_TIMER_CTRL_IE; \
- } while (0)
+ leon3_clock_initialize()
#define Clock_driver_support_shutdown_hardware() \
do { \
@@ -128,27 +187,7 @@ static void bsp_clock_handler_install(rtems_isr *new)
LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX].ctrl = 0; \
} while (0)
-static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
-{
- uint32_t clicks;
- uint32_t usecs;
-
- if ( !LEON3_Timer_Regs )
- return 0;
-
- clicks = LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX].value;
-
- if ( LEON_Is_interrupt_pending( clkirq ) ) {
- clicks = LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX].value;
- usecs = (2*rtems_configuration_get_microseconds_per_tick() - clicks);
- } else {
- usecs = (rtems_configuration_get_microseconds_per_tick() - clicks);
- }
- return usecs * 1000;
-}
-
-#define Clock_driver_nanoseconds_since_last_tick \
- bsp_clock_nanoseconds_since_last_tick
+#define Clock_driver_timecounter_tick() leon3_tc_tick()
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libbsp/sparc64/shared/clock/ckinit.c b/c/src/lib/libbsp/sparc64/shared/clock/ckinit.c
index a3f9450174..ff0464c8f2 100644
--- a/c/src/lib/libbsp/sparc64/shared/clock/ckinit.c
+++ b/c/src/lib/libbsp/sparc64/shared/clock/ckinit.c
@@ -114,5 +114,7 @@ static void Clock_driver_support_initialize_hardware(void)
\
} while ( 0 )
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../shared/clockdrv_shell.h"
diff --git a/c/src/lib/libcpu/arm/at91rm9200/clock/clock.c b/c/src/lib/libcpu/arm/at91rm9200/clock/clock.c
index 16cf145b37..42b85f3f98 100644
--- a/c/src/lib/libcpu/arm/at91rm9200/clock/clock.c
+++ b/c/src/lib/libcpu/arm/at91rm9200/clock/clock.c
@@ -22,8 +22,6 @@
#include <at91rm9200.h>
#include <at91rm9200_pmc.h>
-static unsigned long st_pimr_reload;
-
/**
* Enables clock interrupt.
*
@@ -77,17 +75,16 @@ rtems_irq_connect_data clock_isr_data = {
BSP_install_rtems_irq_handler(&clock_isr_data); \
} while(0)
-uint16_t st_pimr_value;
static void Clock_driver_support_initialize_hardware(void)
{
uint32_t st_str;
int slck;
+ unsigned long value;
/* the system timer is driven from SLCK */
slck = at91rm9200_get_slck();
- st_pimr_value = (((rtems_configuration_get_microseconds_per_tick() * slck) +
+ value = (((rtems_configuration_get_microseconds_per_tick() * slck) +
(1000000/2))/ 1000000);
- st_pimr_reload = st_pimr_value;
/* read the status to clear the int */
st_str = ST_REG(ST_SR);
@@ -97,21 +94,9 @@ static void Clock_driver_support_initialize_hardware(void)
AIC_SMR_REG(AIC_SMR_SYSIRQ) = AIC_SMR_PRIOR(0x7);
/* set the timer value */
- ST_REG(ST_PIMR) = st_pimr_reload;
+ ST_REG(ST_PIMR) = value;
}
-static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
-{
- uint16_t slck_counts;
-
- slck_counts = st_pimr_value - st_pimr_reload;
- return (rtems_configuration_get_microseconds_per_tick() * slck_counts * 1000)
- / st_pimr_value;
-}
-
-#define Clock_driver_nanoseconds_since_last_tick \
- bsp_clock_nanoseconds_since_last_tick
-
#define Clock_driver_support_at_tick() \
do { \
uint32_t st_str; \
@@ -126,4 +111,6 @@ static void Clock_driver_support_shutdown_hardware( void )
BSP_remove_rtems_irq_handler(&clock_isr_data);
}
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../../libbsp/shared/clockdrv_shell.h"
diff --git a/c/src/lib/libcpu/arm/lpc22xx/clock/clockdrv.c b/c/src/lib/libcpu/arm/lpc22xx/clock/clockdrv.c
index 02f5b8c5ea..e75fed8a9e 100644
--- a/c/src/lib/libcpu/arm/lpc22xx/clock/clockdrv.c
+++ b/c/src/lib/libcpu/arm/lpc22xx/clock/clockdrv.c
@@ -17,12 +17,39 @@
#include <bsp/irq.h>
#include <lpc22xx.h>
#include <rtems/bspIo.h> /* for printk */
+#include <rtems/timecounter.h>
void Clock_isr(rtems_irq_hdl_param arg);
static void clock_isr_on(const rtems_irq_connect_data *unused);
static void clock_isr_off(const rtems_irq_connect_data *unused);
static int clock_isr_is_on(const rtems_irq_connect_data *irq);
+static rtems_timecounter_simple lpc22xx_tc;
+
+static uint32_t lpc22xx_tc_get(rtems_timecounter_simple *tc)
+{
+ return T0TC;
+}
+
+static bool lpc22xx_tc_is_pending(rtems_timecounter_simple *tc)
+{
+ return (T0IR & 0x1) != 0;
+}
+
+static uint32_t lpc22xx_tc_get_timecount(struct timecounter *tc)
+{
+ return rtems_timecounter_simple_upcounter_get(
+ tc,
+ lpc22xx_tc_get,
+ lpc22xx_tc_is_pending
+ );
+}
+
+static void lpc22xx_tc_tick(void)
+{
+ rtems_timecounter_simple_upcounter_tick(&lpc22xx_tc, lpc22xx_tc_get);
+}
+
/* Replace the first value with the clock's interrupt name. */
rtems_irq_connect_data clock_isr_data = {
.name = LPC22xx_INTERRUPT_TIMER0,
@@ -74,9 +101,10 @@ rtems_irq_connect_data clock_isr_data = {
*/
#define Clock_driver_support_initialize_hardware() \
do { \
+ uint32_t mask; \
/* disable and clear timer 0, set to */ \
T0TCR &= 0; \
- /* TC is incrementet on every pclk.*/ \
+ /* TC is incremented on every pclk.*/ \
T0PC = 0; \
/* initialize the timer period and prescaler */ \
T0MR0 = ((LPC22xx_Fpclk/1000 * \
@@ -89,6 +117,13 @@ rtems_irq_connect_data clock_isr_data = {
T0TCR = 1; \
/* enable interrupt, skyeye will check this*/ \
T0IR |= 0x01; \
+ /* install timecounter */ \
+ rtems_timecounter_simple_install( \
+ &lpc22xx_tc, \
+ LPC22xx_Fpclk, \
+ T0MR0, \
+ lpc22xx_tc_get_timecount \
+ ); \
} while (0)
/**
@@ -104,20 +139,6 @@ rtems_irq_connect_data clock_isr_data = {
BSP_remove_rtems_irq_handler(&clock_isr_data); \
} while (0)
-static uint32_t bsp_clock_nanoseconds_since_last_tick(void)
-{
- uint32_t clicks;
- uint32_t microseconds;
-
- clicks = T0TC; /* T0TC is the 32bit time counter 0 */
-
- microseconds = (rtems_configuration_get_microseconds_per_tick() - clicks);
- return microseconds * 1000;
-}
-
-#define Clock_driver_nanoseconds_since_last_tick \
- bsp_clock_nanoseconds_since_last_tick
-
/**
* Enables clock interrupt.
*
@@ -149,6 +170,8 @@ static int clock_isr_is_on(const rtems_irq_connect_data *irq)
return T0IR & 0x01; /* MR0 mask */
}
+#define Clock_driver_timecounter_tick() lpc22xx_tc_tick()
+
/* Make sure to include this, and only at the end of the file */
#include "../../../../libbsp/shared/clockdrv_shell.h"
diff --git a/c/src/lib/libcpu/arm/mc9328mxl/clock/clockdrv.c b/c/src/lib/libcpu/arm/mc9328mxl/clock/clockdrv.c
index 0c3ab5dd93..d5dc69c9a0 100644
--- a/c/src/lib/libcpu/arm/mc9328mxl/clock/clockdrv.c
+++ b/c/src/lib/libcpu/arm/mc9328mxl/clock/clockdrv.c
@@ -130,5 +130,8 @@ static int clock_isr_is_on(const rtems_irq_connect_data *irq)
return MC9328MXL_TMR1_TCTL & MC9328MXL_TMR_TCTL_IRQEN;
}
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
/* Make sure to include this, and only at the end of the file */
+
#include "../../../../libbsp/shared/clockdrv_shell.h"
diff --git a/c/src/lib/libcpu/arm/pxa255/clock/clock.c b/c/src/lib/libcpu/arm/pxa255/clock/clock.c
index 92d9b21d2b..69b684926c 100644
--- a/c/src/lib/libcpu/arm/pxa255/clock/clock.c
+++ b/c/src/lib/libcpu/arm/pxa255/clock/clock.c
@@ -116,4 +116,6 @@ static void Clock_driver_support_shutdown_hardware( void )
BSP_remove_rtems_irq_handler(&clock_isr_data);
}
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
#include "../../../../libbsp/shared/clockdrv_shell.h"
diff --git a/c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c b/c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c
index 519d3f850d..a92dc607a3 100644
--- a/c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c
+++ b/c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c
@@ -28,17 +28,6 @@ rtems_irq_connect_data clock_isr_data = {
};
/**
- * Return the nanoseconds since last tick
- */
-static uint32_t clock_driver_get_nanoseconds_since_last_tick(void)
-{
- return 0;
-}
-
-#define Clock_driver_nanoseconds_since_last_tick \
- clock_driver_get_nanoseconds_since_last_tick
-
-/**
* When we get the clock interrupt
* - clear the interrupt bit?
* - restart the timer?
@@ -74,6 +63,7 @@ static uint32_t clock_driver_get_nanoseconds_since_last_tick(void)
do { \
uint32_t cr; \
uint32_t freq; \
+ uint32_t mask; \
/* set MUX for Timer4 to 1/16 */ \
cr=rTCFG1 & 0xFFF0FFFF; \
rTCFG1=(cr | (3<<16)); \
@@ -131,5 +121,7 @@ static int clock_isr_is_on(const rtems_irq_connect_data *irq)
return 1;
}
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
/* Make sure to include this, and only at the end of the file */
#include "../../../../libbsp/shared/clockdrv_shell.h"
diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c b/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c
index 218828cf4a..41b10cb30d 100644
--- a/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c
+++ b/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c
@@ -29,6 +29,7 @@
#include <libcpu/spr.h>
#include <rtems/bspIo.h> /* for printk() */
#include <libcpu/powerpc-utility.h>
+#include <rtems/timecounter.h>
#include <bspopts.h> /* for CLOCK_DRIVER_USE_FAST_IDLE */
@@ -48,11 +49,12 @@ volatile uint32_t Clock_driver_ticks;
*/
static uint32_t Clock_Decrementer_value;
-/*
- * This is the value by which elapsed count down timer ticks are multiplied to
- * give an elapsed duration in nanoseconds, left-shifted by 32 bits
- */
-static uint64_t Clock_Decrementer_reference;
+static struct timecounter Clock_TC;
+
+static uint32_t Clock_Get_timecount(struct timecounter *tc)
+{
+ return ppc_time_base();
+}
void clockOff(void* unused)
{
@@ -94,16 +96,27 @@ void clockOn(void* unused)
static void clockHandler(void)
{
#if (CLOCK_DRIVER_USE_FAST_IDLE == 1)
- do {
- rtems_clock_tick();
- } while (
+ rtems_interrupt_level level;
+ uint32_t tb;
+
+ rtems_interrupt_disable(level);
+
+ tb = ppc_time_base();
+ rtems_timecounter_tick();
+
+ while (
_Thread_Heir == _Thread_Executing
&& _Thread_Executing->Start.entry_point
== (Thread_Entry) rtems_configuration_get_idle_task()
- );
+ ) {
+ tb += Clock_Decrementer_value;
+ ppc_set_time_base( tb );
+ rtems_timecounter_tick();
+ }
+ rtems_interrupt_enable(level);
#else
- rtems_clock_tick();
+ rtems_timecounter_tick();
#endif
}
@@ -141,7 +154,6 @@ void clockIsr(void *unused)
rtems_interrupt_enable(flags);
Clock_driver_ticks += 1;
-
/*
* Real Time Clock counter/timer is set to automatically reload.
*/
@@ -187,7 +199,6 @@ int clockIsOn(void* unused)
return 0;
}
-
/*
* Clock_exit
*
@@ -199,53 +210,6 @@ void Clock_exit( void )
(void) BSP_disconnect_clock_handler ();
}
-static uint32_t Clock_driver_nanoseconds_since_last_tick(void)
-{
- uint32_t clicks, tmp;
-
- PPC_Get_decrementer( clicks );
-
- /*
- * Multiply by 1000 here separately from below so we do not overflow
- * and get a negative value.
- */
- tmp = (Clock_Decrementer_value - clicks) * 1000;
- tmp /= (BSP_bus_frequency/BSP_time_base_divisor);
-
- return tmp * 1000;
-}
-
-static uint32_t Clock_driver_nanoseconds_since_last_tick_bookE(void)
-{
- uint32_t clicks;
- uint64_t c;
-
- PPC_Get_decrementer( clicks );
- c = Clock_Decrementer_value - clicks;
-
- /*
- * Check whether a clock tick interrupt is pending and hence that the
- * decrementer's wrapped. If it has, we'll compensate by returning a time one
- * tick period longer.
- *
- * We have to check interrupt status after reading the decrementer. If we
- * don't, we may miss an interrupt and read a wrapped decrementer value
- * without compensating for it
- */
- if ( _read_BOOKE_TSR() & BOOKE_TSR_DIS )
- {
- /*
- * Re-read the decrementer: The tick interrupt may have been
- * generated and the decrementer wrapped during the time since we
- * last read it and the time we checked the interrupt status
- */
- PPC_Get_decrementer( clicks );
- c = (Clock_Decrementer_value - clicks) + Clock_Decrementer_value;
- }
-
- return (uint32_t)((c * Clock_Decrementer_reference) >> 32);
-}
-
/*
* Clock_initialize
*
@@ -262,9 +226,6 @@ rtems_device_driver Clock_initialize(
Clock_Decrementer_value = (BSP_bus_frequency/BSP_time_base_divisor)*
rtems_configuration_get_milliseconds_per_tick();
- Clock_Decrementer_reference = ((uint64_t)1000000U<<32)/
- (BSP_bus_frequency/BSP_time_base_divisor);
-
/* set the decrementer now, prior to installing the handler
* so no interrupts will happen in a while.
*/
@@ -283,24 +244,14 @@ rtems_device_driver Clock_initialize(
_write_BOOKE_TCR(tcr);
rtems_interrupt_enable(l);
-
- /*
- * Set the nanoseconds since last tick handler
- */
- rtems_clock_set_nanoseconds_extension(
- Clock_driver_nanoseconds_since_last_tick_bookE
- );
- }
- else
- {
- /*
- * Set the nanoseconds since last tick handler
- */
- rtems_clock_set_nanoseconds_extension(
- Clock_driver_nanoseconds_since_last_tick
- );
}
+ Clock_TC.tc_get_timecount = Clock_Get_timecount;
+ Clock_TC.tc_counter_mask = 0xffffffff;
+ Clock_TC.tc_frequency = (1000 * BSP_bus_frequency) / BSP_time_base_divisor;
+ Clock_TC.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install(&Clock_TC);
+
/*
* If a decrementer exception was pending, it is cleared by
* executing the default (nop) handler at this point;