Index: bsps/arm/atsam/clock/systick-freq.c
===================================================================
--- bsps/arm/atsam/clock/systick-freq.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/arm/atsam/clock/systick-freq.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+
+#include <chip.h>
+
+uint32_t atsam_systick_frequency(void)
+{
+  uint32_t mdiv = (PMC->PMC_MCKR & PMC_MCKR_MDIV_Msk) >> PMC_MCKR_MDIV_Pos;
+  uint32_t fclk;
+
+  if (mdiv == 3) {
+    fclk = BOARD_MCK * mdiv;
+  } else {
+    fclk = BOARD_MCK * (1 << mdiv);
+  }
+
+  return fclk;
+}
Index: bsps/arm/csb336/clock/clockdrv.c
===================================================================
--- bsps/arm/csb336/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/arm/csb336/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,134 @@
+/*
+ *  MC9328MXL clock specific using the System Timer
+ */
+
+/*
+ *  Copyright (c) 2004 by Cogent Computer Systems
+ *  Written by Jay Monkman <jtm@lopingdog.com>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <mc9328mxl.h>
+#include <rtems/bspIo.h>  /* for printk */
+
+/* this is defined in ../../../shared/dev/clock/clockimpl.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);
+
+/* Replace the first value with the clock's interrupt name. */
+rtems_irq_connect_data clock_isr_data = {
+  .name   = BSP_INT_TIMER1,
+  .hdl    = Clock_isr,
+  .handle = (void *)BSP_INT_TIMER1,
+  .on     = clock_isr_on,
+  .off    = clock_isr_off,
+  .isOn   = clock_isr_is_on,
+};
+
+/**
+ * When we get the clock interrupt
+ *    - clear the interrupt bit?
+ *    - restart the timer?
+ */
+#define Clock_driver_support_at_tick()               \
+  do {                                               \
+    uint32_t reg;                                    \
+                                                     \
+    reg = MC9328MXL_TMR1_TSTAT;                      \
+    (void) reg; /* avoid set but not used warning */ \
+    MC9328MXL_TMR1_TSTAT = 0;                        \
+  } while(0)
+
+/**
+ * Installs the clock ISR. You shouldn't need to change this.
+ */
+#define Clock_driver_support_install_isr( _new ) \
+  BSP_install_rtems_irq_handler(&clock_isr_data)
+
+/**
+ * Initialize the hardware for the clock
+ *   - Set the frequency
+ *   - enable it
+ *   - clear any pending interrupts
+ *
+ * Since you may want the clock always running, you can
+ * enable interrupts here. If you do so, the clock_isr_on(),
+ * clock_isr_off(), and clock_isr_is_on() functions can be
+ * NOPs.
+ */
+#define Clock_driver_support_initialize_hardware() \
+  do { \
+        int freq; \
+        int cnt; \
+        freq = get_perclk1_freq(); \
+        printk("perclk1 freq is %d\n", freq); \
+        cnt = ((long long)freq * rtems_configuration_get_microseconds_per_tick() + 500000) / 1000000;\
+        printk("cnt freq is %d\n", cnt); \
+        MC9328MXL_TMR1_TCMP = cnt; \
+        /* use PERCLK1 as input, enable timer */ \
+        MC9328MXL_TMR1_TCTL = (MC9328MXL_TMR_TCTL_CLKSRC_PCLK1 | \
+                               MC9328MXL_TMR_TCTL_TEN | \
+                               MC9328MXL_TMR_TCTL_IRQEN); \
+        /* set prescaler to 1 (register value + 1) */ \
+        MC9328MXL_TMR1_TPRER = 0; \
+     } while (0)
+
+/**
+ * Do whatever you need to shut the clock down and remove the
+ * interrupt handler. Since this normally only gets called on
+ * RTEMS shutdown, you may not need to do anything other than
+ * remove the ISR.
+ */
+#define Clock_driver_support_shutdown_hardware()                        \
+  do {                                                                  \
+    /* Disable timer */ \
+    MC9328MXL_TMR1_TCTL = 0; \
+    BSP_remove_rtems_irq_handler(&clock_isr_data);                  \
+  } while (0)
+
+/**
+ * Enables clock interrupt.
+ *
+ * If the interrupt is always on, this can be a NOP.
+ */
+static void clock_isr_on(const rtems_irq_connect_data *unused)
+{
+  MC9328MXL_TMR1_TCTL |= MC9328MXL_TMR_TCTL_IRQEN;
+  MC9328MXL_AITC_INTENNUM = MC9328MXL_INT_TIMER1;
+}
+
+/**
+ * Disables clock interrupts
+ *
+ * If the interrupt is always on, this can be a NOP.
+ */
+static void clock_isr_off(const rtems_irq_connect_data *unused)
+{
+  MC9328MXL_TMR1_TCTL &= ~MC9328MXL_TMR_TCTL_IRQEN;
+  MC9328MXL_AITC_INTDISNUM = MC9328MXL_INT_TIMER1;
+}
+
+/**
+ * Tests to see if clock interrupt is enabled, and returns 1 if so.
+ * If interrupt is not enabled, returns 0.
+ *
+ * If the interrupt is always on, this always returns 1.
+ */
+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 "../../../shared/dev/clock/clockimpl.h"
Index: bsps/arm/csb337/clock/clock.c
===================================================================
--- bsps/arm/csb337/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/arm/csb337/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,113 @@
+/*
+ *  AT91RM9200 clock specific using the System Timer
+ */
+
+/*
+ *  Copyright (c) 2003 by Cogent Computer Systems
+ *  Written by Mike Kelly <mike@cogcomp.com>
+ *         and Jay Monkman <jtm@lopingdog.com>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <rtems/clockdrv.h>
+#include <rtems/libio.h>
+
+#include <stdlib.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <at91rm9200.h>
+#include <at91rm9200_pmc.h>
+
+/**
+ * Enables clock interrupt.
+ *
+ * If the interrupt is always on, this can be a NOP.
+ */
+static void clock_isr_on(const rtems_irq_connect_data *unused)
+{
+  /* enable timer interrupt */
+  ST_REG(ST_IER) = ST_SR_PITS;
+}
+
+/**
+ * Disables clock interrupts
+ *
+ * If the interrupt is always on, this can be a NOP.
+ */
+static void clock_isr_off(const rtems_irq_connect_data *unused)
+{
+  /* disable timer interrupt */
+  ST_REG(ST_IDR) = ST_SR_PITS;
+}
+
+/**
+ * Tests to see if clock interrupt is enabled, and returns 1 if so.
+ * If interrupt is not enabled, returns 0.
+ *
+ * If the interrupt is always on, this always returns 1.
+ */
+static int clock_isr_is_on(const rtems_irq_connect_data *irq)
+{
+  /* check timer interrupt */
+  return ST_REG(ST_IMR) & ST_SR_PITS;
+}
+
+void Clock_isr(rtems_irq_hdl_param arg);
+
+/* Replace the first value with the clock's interrupt name. */
+rtems_irq_connect_data clock_isr_data = {
+  .name   = AT91RM9200_INT_SYSIRQ,
+  .hdl    = Clock_isr,
+  .handle = NULL,
+  .on     = clock_isr_on,
+  .off    = clock_isr_off,
+  .isOn   = clock_isr_is_on,
+};
+
+
+#define Clock_driver_support_install_isr( _new ) \
+  BSP_install_rtems_irq_handler(&clock_isr_data)
+
+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();
+  value = (((rtems_configuration_get_microseconds_per_tick() * slck) +
+                      (1000000/2))/ 1000000);
+
+  /* read the status to clear the int */
+  st_str = ST_REG(ST_SR);
+  (void) st_str; /* avoid set but not used warning */ \
+
+  /* set priority */
+  AIC_SMR_REG(AIC_SMR_SYSIRQ) = AIC_SMR_PRIOR(0x7);
+
+  /* set the timer value */
+  ST_REG(ST_PIMR) = value;
+}
+
+#define Clock_driver_support_at_tick() \
+  do { \
+    uint32_t st_str; \
+    \
+    /* read the status to clear the int */ \
+    st_str = ST_REG(ST_SR); \
+    (void) st_str; /* avoid set but not used warning */ \
+  } while (0)
+
+#define Clock_driver_support_shutdown_hardware() \
+  do { \
+    BSP_remove_rtems_irq_handler(&clock_isr_data); \
+  } while (0)
+
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/arm/edb7312/clock/clockdrv.c
===================================================================
--- bsps/arm/edb7312/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/arm/edb7312/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,72 @@
+/*
+ * Cirrus EP7312 Clock driver
+ *
+ * Copyright (c) 2002 by Jay Monkman <jtm@smoothsmoothie.com>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <ep7312.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <assert.h>
+
+#if ON_SKYEYE==1
+  #define CLOCK_DRIVER_USE_FAST_IDLE 1
+#endif
+
+void Clock_isr(void * arg);
+
+#define Clock_driver_support_at_tick()                \
+  do {                                                \
+    *EP7312_TC1EOI = 0xffffffff;                      \
+  } while(0)
+
+#define Clock_driver_support_install_isr( _new )       \
+  do {                                                 \
+    rtems_status_code status = RTEMS_SUCCESSFUL;       \
+    status = rtems_interrupt_handler_install(          \
+        BSP_TC1OI,                                     \
+        "Clock",                                       \
+        RTEMS_INTERRUPT_UNIQUE,                        \
+        Clock_isr,                                     \
+        NULL                                           \
+    );                                                 \
+    assert(status == RTEMS_SUCCESSFUL);                \
+  } while(0)
+
+/*
+ * Set up the clock hardware
+ */
+#if ON_SKYEYE
+  #define TCD_VALUE \
+    (rtems_configuration_get_microseconds_per_tick() * 2000)/25000
+#else
+  #define TCD_VALUE \
+    (rtems_configuration_get_microseconds_per_tick() * 2000)/1000000
+#endif
+
+#define Clock_driver_support_initialize_hardware()  \
+  do {                                              \
+    *EP7312_SYSCON1 |= EP7312_SYSCON1_TC1_PRESCALE; \
+    *EP7312_TC1D = TCD_VALUE;                       \
+    *EP7312_TC1EOI = 0xFFFFFFFF;                    \
+  } while (0)
+
+#define Clock_driver_support_shutdown_hardware()    \
+  do {                                              \
+    rtems_status_code status = RTEMS_SUCCESSFUL;    \
+    status = rtems_interrupt_handler_remove(        \
+        BSP_TC1OI,                                  \
+        Clock_isr,                                  \
+        NULL                                        \
+    );                                              \
+    assert(status == RTEMS_SUCCESSFUL);             \
+  } while (0)
+
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/arm/gumstix/clock/clock.c
===================================================================
--- bsps/arm/gumstix/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/arm/gumstix/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,118 @@
+/*
+ *  PXA255 clock specific using the System Timer
+ *
+ *  RTEMS uses IRQ 26 as Clock Source
+ */
+
+/*
+ *  By Yang Xi <hiyangxi@gmail.com>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <rtems/clockdrv.h>
+#include <rtems/libio.h>
+
+#include <stdlib.h>
+#include <bsp.h>
+#include <bspopts.h>
+#include <bsp/irq.h>
+#include <pxa255.h>
+
+#if ON_SKYEYE==1
+  #define CLOCK_DRIVER_USE_FAST_IDLE 1
+#endif
+
+static unsigned long period_num;
+
+/**
+ * Enables clock interrupt.
+ *
+ * If the interrupt is always on, this can be a NOP.
+ */
+static void clock_isr_on(const rtems_irq_connect_data *unused)
+{
+  /*Clear the interrupt bit */
+  XSCALE_OS_TIMER_TSR = 0x1;
+
+  /* enable timer interrupt */
+  XSCALE_OS_TIMER_IER |= 0x1;
+
+#if ON_SKYEYE==1
+  period_num = (TIMER_RATE* rtems_configuration_get_microseconds_per_tick())/100000;
+#else
+  period_num = (TIMER_RATE* rtems_configuration_get_microseconds_per_tick())/10000;
+#endif
+
+  XSCALE_OS_TIMER_MR0 = XSCALE_OS_TIMER_TCR + period_num;
+}
+
+/**
+ * Disables clock interrupts
+ *
+ * If the interrupt is always on, this can be a NOP.
+ */
+static void clock_isr_off(const rtems_irq_connect_data *unused)
+{
+  /*Clear the interrupt bit */
+  XSCALE_OS_TIMER_TSR = 0x1;
+  /* disable timer interrupt*/
+  XSCALE_OS_TIMER_IER &= ~0x1;
+}
+
+/**
+ * Tests to see if clock interrupt is enabled, and returns 1 if so.
+ * If interrupt is not enabled, returns 0.
+ *
+ * If the interrupt is always on, this always returns 1.
+ */
+static int clock_isr_is_on(const rtems_irq_connect_data *irq)
+{
+  /* check timer interrupt */
+  return XSCALE_OS_TIMER_IER & 0x1;
+}
+
+void Clock_isr(rtems_irq_hdl_param arg);
+
+rtems_irq_connect_data clock_isr_data = {
+  .name   = XSCALE_IRQ_OS_TIMER,
+  .hdl    = Clock_isr,
+  .handle = NULL,
+  .on     = clock_isr_on,
+  .off    = clock_isr_off,
+  .isOn   = clock_isr_is_on,
+};
+
+#define Clock_driver_support_install_isr( _new ) \
+  BSP_install_rtems_irq_handler(&clock_isr_data)
+
+static void Clock_driver_support_initialize_hardware(void)
+{
+  period_num = TIMER_RATE* rtems_configuration_get_microseconds_per_tick();
+#if ON_SKYEYE==1
+  period_num /= 100000;
+#else
+  period_num /= 10000;
+#endif
+}
+
+#define Clock_driver_support_at_tick() \
+  do { \
+    /* read the status to clear the int */ \
+    XSCALE_OS_TIMER_TSR = 0x1; \
+    \
+    /*Add the match register*/ \
+    XSCALE_OS_TIMER_MR0 = XSCALE_OS_TIMER_TCR + period_num; \
+  } while (0)
+
+#define Clock_driver_support_shutdown_hardware() \
+  do { \
+    BSP_remove_rtems_irq_handler(&clock_isr_data); \
+  } while (0)
+
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/arm/raspberrypi/clock/clockdrv.c
===================================================================
--- bsps/arm/raspberrypi/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/arm/raspberrypi/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,114 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_clock
+ *
+ * @brief Raspberry Pi clock support.
+ */
+
+/*
+ * BCM2835 Clock driver
+ *
+ * Copyright (c) 2013 Alan Cudmore
+ * Copyright (c) 2016 Pavel Pisa
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *
+ *  http://www.rtems.org/license/LICENSE
+ *
+*/
+
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+#include <bsp/raspberrypi.h>
+#include <rtems/timecounter.h>
+
+/* This is defined in ../../../shared/dev/clock/clockimpl.h */
+void Clock_isr(rtems_irq_hdl_param arg);
+
+static struct timecounter raspberrypi_tc;
+
+static uint32_t raspberrypi_clock_get_timecount(struct timecounter *tc)
+{
+  return BCM2835_REG(BCM2835_GPU_TIMER_CLO);
+}
+
+static void raspberrypi_clock_at_tick(void)
+{
+  uint32_t act_val;
+  uint32_t next_cmp = BCM2835_REG(BCM2835_GPU_TIMER_C3);
+  next_cmp += rtems_configuration_get_microseconds_per_tick();
+  BCM2835_REG(BCM2835_GPU_TIMER_C3) = next_cmp;
+  act_val = BCM2835_REG(BCM2835_GPU_TIMER_CLO);
+
+  /*
+   * Clear interrupt only if there is time left to the next tick.
+   * If time of the next tick has already passed then interrupt
+   * request stays active and fires immediately after current tick
+   * processing is finished.
+   */
+  if ((int32_t)(next_cmp - act_val) > 0)
+    BCM2835_REG(BCM2835_GPU_TIMER_CS) = BCM2835_GPU_TIMER_CS_M3;
+}
+
+static void raspberrypi_clock_handler_install_isr(
+  rtems_isr_entry clock_isr
+)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  if (clock_isr != NULL) {
+    sc = rtems_interrupt_handler_install(
+      BCM2835_IRQ_ID_GPU_TIMER_M3,
+      "Clock",
+      RTEMS_INTERRUPT_UNIQUE,
+      (rtems_interrupt_handler) clock_isr,
+      NULL
+    );
+  } else {
+    /* Remove interrupt handler */
+    sc = rtems_interrupt_handler_remove(
+      BCM2835_IRQ_ID_GPU_TIMER_M3,
+      (rtems_interrupt_handler) Clock_isr,
+      NULL
+    );
+  }
+  if ( sc != RTEMS_SUCCESSFUL ) {
+    rtems_fatal_error_occurred(0xdeadbeef);
+  }
+}
+
+static void raspberrypi_clock_initialize_hardware(void)
+{
+  uint32_t next_cmp = BCM2835_REG(BCM2835_GPU_TIMER_CLO);
+  next_cmp += rtems_configuration_get_microseconds_per_tick();
+  BCM2835_REG(BCM2835_GPU_TIMER_C3) = next_cmp;
+  BCM2835_REG(BCM2835_GPU_TIMER_CS) = BCM2835_GPU_TIMER_CS_M3;
+
+  raspberrypi_tc.tc_get_timecount = raspberrypi_clock_get_timecount;
+  raspberrypi_tc.tc_counter_mask = 0xffffffff;
+  raspberrypi_tc.tc_frequency = 1000000; /* 1 MHz */
+  raspberrypi_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+  rtems_timecounter_install(&raspberrypi_tc);
+}
+
+static void raspberrypi_clock_cleanup(void)
+{
+  bsp_interrupt_vector_disable(BCM2835_IRQ_ID_GPU_TIMER_M3);
+}
+
+#define Clock_driver_support_at_tick() raspberrypi_clock_at_tick()
+
+#define Clock_driver_support_initialize_hardware() raspberrypi_clock_initialize_hardware()
+
+#define Clock_driver_support_shutdown_hardware() raspberrypi_clock_cleanup()
+
+#define Clock_driver_support_install_isr(clock_isr) \
+  raspberrypi_clock_handler_install_isr(clock_isr)
+
+#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR 1
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/arm/rtl22xx/clock/clockdrv.c
===================================================================
--- bsps/arm/rtl22xx/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/arm/rtl22xx/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,177 @@
+/*
+ *  LPC22XX/LPC21xx clock specific using the System Timer
+ *
+ *  Set the Time0 to generate click for RTEMS
+ */
+
+/*
+ *  Copyright (c) 2006 by Ray <rayx.cn@gmail.com>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#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
+  );
+}
+
+/**
+ * When we get the clock interrupt
+ *    - clear the interrupt bit?
+ *    - restart the timer?
+ */
+static void lpc22xx_tc_at_tick(rtems_timecounter_simple *tc)
+{
+  if (!(T0IR & 0x01))
+    return;
+  T0IR = 0x01;
+  VICVectAddr = 0x00;
+}
+
+static void lpc22xx_tc_tick(void)
+{
+  rtems_timecounter_simple_upcounter_tick(
+    &lpc22xx_tc,
+    lpc22xx_tc_get,
+    lpc22xx_tc_at_tick
+  );
+}
+
+/* Replace the first value with the clock's interrupt name. */
+rtems_irq_connect_data clock_isr_data = {
+  .name   = LPC22xx_INTERRUPT_TIMER0,
+  .hdl    = Clock_isr,
+  .handle = NULL,
+  .on     = clock_isr_on,
+  .off    = clock_isr_off,
+  .isOn   = clock_isr_is_on,
+};
+
+/* use the /shared/dev/clock/clockimpl.h code template */
+
+/**
+ * Installs the clock ISR. You shouldn't need to change this.
+ */
+#define Clock_driver_support_install_isr( _new ) \
+  BSP_install_rtems_irq_handler(&clock_isr_data)
+
+/**
+ * Initialize the hardware for the clock
+ *   - Set the frequency
+ *   - enable it
+ *   - clear any pending interrupts
+ *
+ * Since you may want the clock always running, you can
+ * enable interrupts here. If you do so, the clock_isr_on(),
+ * clock_isr_off(), and clock_isr_is_on() functions can be
+ * NOPs.
+ * 
+ * set timer to generate interrupt every
+ * rtems_configuration_get_microseconds_per_tick()
+ *     MR0/(LPC22xx_Fpclk/(PR0+1)) = 10/1000 = 0.01s
+ */
+#define Clock_driver_support_initialize_hardware() \
+  do { \
+    /* disable and clear timer 0, set to  */ \
+    T0TCR &= 0;                              \
+    /* TC is incremented on every pclk.*/    \
+    T0PC   = 0;                              \
+    /* initialize the timer period and prescaler */  \
+    T0MR0  = ((LPC22xx_Fpclk/1000 *          \
+             rtems_configuration_get_microseconds_per_tick()) / 1000); \
+    /* generate interrupt when T0MR0 match T0TC and Reset Timer Count*/ \
+    T0MCR |= 0x03;          \
+    /* No external match */ \
+    T0EMR = 0;              \
+    /* enable timer0 */     \
+    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)
+
+/**
+ * Do whatever you need to shut the clock down and remove the
+ * interrupt handler. Since this normally only gets called on
+ * RTEMS shutdown, you may not need to do anything other than
+ * remove the ISR.
+ */
+#define Clock_driver_support_shutdown_hardware()                        \
+  do {                                                                  \
+    /* Disable timer */ \
+    T0TCR&=~0x02; \
+    BSP_remove_rtems_irq_handler(&clock_isr_data);                  \
+  } while (0)
+
+/**
+ * Enables clock interrupt.
+ *
+ * If the interrupt is always on, this can be a NOP.
+ */
+static void clock_isr_on(const rtems_irq_connect_data *unused)
+{
+  T0IR&=0x01;
+}
+
+/**
+ * Disables clock interrupts
+ *
+ * If the interrupt is always on, this can be a NOP.
+ */
+static void clock_isr_off(const rtems_irq_connect_data *unused)
+{
+  T0IR=0x00;
+}
+
+/**
+ * Tests to see if clock interrupt is enabled, and returns 1 if so.
+ * If interrupt is not enabled, returns 0.
+ *
+ * If the interrupt is always on, this always returns 1.
+ */
+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 "../../../shared/dev/clock/clockimpl.h"
+
Index: bsps/arm/shared/clock/clock-armv7m.c
===================================================================
--- bsps/arm/shared/clock/clock-armv7m.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/arm/shared/clock/clock-armv7m.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2011-2012 Sebastian Huber.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <rtems/timecounter.h>
+#include <rtems/score/armv7m.h>
+
+#include <bsp.h>
+
+#ifdef ARM_MULTILIB_ARCH_V7M
+
+/* This is defined in dev/clock/clockimpl.h */
+static void Clock_isr(void *arg);
+
+typedef struct {
+  rtems_timecounter_simple base;
+  void (*tick)(void);
+  bool countflag;
+} ARMV7M_Timecounter;
+
+static ARMV7M_Timecounter _ARMV7M_TC;
+
+static uint32_t _ARMV7M_TC_systick_get(rtems_timecounter_simple *tc)
+{
+  volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
+
+  return systick->cvr;
+}
+
+static bool _ARMV7M_TC_systick_is_pending(rtems_timecounter_simple *base)
+{
+  ARMV7M_Timecounter *tc = (ARMV7M_Timecounter *) base;
+  rtems_interrupt_level level;
+  bool countflag;
+
+  rtems_interrupt_disable(level);
+
+  countflag = tc->countflag;
+  if (!countflag) {
+    volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
+
+    countflag = ((systick->csr & ARMV7M_SYSTICK_CSR_COUNTFLAG) != 0);
+    tc->countflag = countflag;
+  }
+
+  rtems_interrupt_enable(level);
+
+  return countflag;
+}
+
+static uint32_t _ARMV7M_TC_systick_get_timecount(struct timecounter *tc)
+{
+  return rtems_timecounter_simple_downcounter_get(
+    tc,
+    _ARMV7M_TC_systick_get,
+    _ARMV7M_TC_systick_is_pending
+  );
+}
+
+static void _ARMV7M_TC_systick_at_tick(rtems_timecounter_simple *base)
+{
+  ARMV7M_Timecounter *tc = (ARMV7M_Timecounter *) base;
+  volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
+
+  tc->countflag = false;
+
+  /* Clear COUNTFLAG */
+  systick->csr;
+}
+
+static void _ARMV7M_TC_systick_tick(void)
+{
+  rtems_timecounter_simple_downcounter_tick(
+    &_ARMV7M_TC.base,
+    _ARMV7M_TC_systick_get,
+    _ARMV7M_TC_systick_at_tick
+  );
+}
+
+static void _ARMV7M_TC_tick(void)
+{
+  (*_ARMV7M_TC.tick)();
+}
+
+static void _ARMV7M_Systick_handler(void)
+{
+  _ARMV7M_Interrupt_service_enter();
+  Clock_isr(NULL);
+  _ARMV7M_Interrupt_service_leave();
+}
+
+static void _ARMV7M_Systick_handler_install(void)
+{
+  _ARMV7M_Set_exception_priority_and_handler(
+    ARMV7M_VECTOR_SYSTICK,
+    BSP_ARMV7M_SYSTICK_PRIORITY,
+    _ARMV7M_Systick_handler
+  );
+}
+
+static void _ARMV7M_Systick_initialize(void)
+{
+  volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
+  #ifdef BSP_ARMV7M_SYSTICK_FREQUENCY
+    uint64_t freq = BSP_ARMV7M_SYSTICK_FREQUENCY;
+  #else
+    uint64_t freq = ARMV7M_SYSTICK_CALIB_TENMS_GET(systick->calib) * 100ULL;
+  #endif
+  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
+  uint64_t interval = (freq * us_per_tick) / 1000000ULL;
+
+  systick->rvr = (uint32_t) interval;
+  systick->cvr = 0;
+  systick->csr = ARMV7M_SYSTICK_CSR_ENABLE
+    | ARMV7M_SYSTICK_CSR_TICKINT
+    | ARMV7M_SYSTICK_CSR_CLKSOURCE;
+
+  _ARMV7M_TC.tick = _ARMV7M_TC_systick_tick;
+  rtems_timecounter_simple_install(
+    &_ARMV7M_TC.base,
+    freq,
+    interval,
+    _ARMV7M_TC_systick_get_timecount
+  );
+}
+
+static void _ARMV7M_Systick_cleanup(void)
+{
+  volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
+
+  systick->csr = 0;
+}
+
+#define Clock_driver_timecounter_tick() _ARMV7M_TC_tick()
+
+#define Clock_driver_support_initialize_hardware() \
+  _ARMV7M_Systick_initialize()
+
+#define Clock_driver_support_install_isr(isr) \
+  _ARMV7M_Systick_handler_install()
+
+#define Clock_driver_support_shutdown_hardware() \
+  _ARMV7M_Systick_cleanup()
+
+/* Include shared source clock driver code */
+#include "../../../shared/dev/clock/clockimpl.h"
+
+#endif /* ARM_MULTILIB_ARCH_V7M */
Index: bsps/arm/shared/clock/clock-nxp-lpc.c
===================================================================
--- bsps/arm/shared/clock/clock-nxp-lpc.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/arm/shared/clock/clock-nxp-lpc.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,136 @@
+/**
+ * @file
+ *
+ * @ingroup lpc_clock
+ *
+ * @brief Clock driver configuration.
+ */
+
+/*
+ * Copyright (c) 2009-2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <rtems/timecounter.h>
+
+#include <bsp/lpc-clock-config.h>
+#include <bsp/lpc-timer.h>
+
+#ifdef ARM_MULTILIB_ARCH_V4
+
+/* This is defined in ../../../shared/dev/clock/clockimpl.h */
+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;
+}
+
+static void lpc_clock_handler_install(void)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  sc = rtems_interrupt_handler_install(
+    LPC_CLOCK_INTERRUPT,
+    "Clock",
+    RTEMS_INTERRUPT_UNIQUE,
+    (rtems_interrupt_handler) Clock_isr,
+    NULL
+  );
+  if (sc != RTEMS_SUCCESSFUL) {
+    rtems_fatal_error_occurred(0xdeadbeef);
+  }
+}
+
+static void lpc_clock_initialize(void)
+{
+  uint64_t interval = ((uint64_t) LPC_CLOCK_REFERENCE
+    * (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000;
+
+  /* Enable module */
+  LPC_CLOCK_MODULE_ENABLE();
+
+  /* Reset timer */
+  lpc_clock->tcr = LPC_TIMER_TCR_RST;
+
+  /* Clear interrupt flags */
+  lpc_clock->ir = LPC_TIMER_IR_ALL;
+
+  /* Set timer mode */
+  lpc_clock->ccr = 0;
+
+  /* Timer is incremented every PERIPH_CLK tick */
+  lpc_clock->pr = 0;
+
+  /* Set match registers */
+  lpc_clock->mr0 = (uint32_t) interval;
+
+  /* Generate interrupt and reset counter on match with MR0 */
+  lpc_clock->mcr = LPC_TIMER_MCR_MR0_INTR | LPC_TIMER_MCR_MR0_RST;
+
+  /* No external match */
+  lpc_clock->emr = 0x0;
+
+  /* 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)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  /* Disable timer */
+  lpc_clock->tcr = 0x0;
+
+  /* Remove interrupt handler */
+  sc = rtems_interrupt_handler_remove(
+    LPC_CLOCK_INTERRUPT,
+    (rtems_interrupt_handler) Clock_isr,
+    NULL
+  );
+  if (sc != RTEMS_SUCCESSFUL) {
+    rtems_fatal_error_occurred(0xdeadbeef);
+  }
+}
+
+#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) \
+  lpc_clock_handler_install()
+
+#define Clock_driver_support_shutdown_hardware() lpc_clock_cleanup()
+
+/* Include shared source clock driver code */
+#include "../../../shared/dev/clock/clockimpl.h"
+
+#endif /* ARM_MULTILIB_ARCH_V4 */
Index: bsps/arm/smdk2410/clock/clockdrv.c
===================================================================
--- bsps/arm/smdk2410/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/arm/smdk2410/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,123 @@
+/*
+ *  S3C2400 clock specific using the System Timer
+ */
+
+/*
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+#include <s3c24xx.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);
+
+rtems_irq_connect_data clock_isr_data = {
+  .name   = BSP_INT_TIMER4,
+  .hdl    = Clock_isr,
+  .handle = NULL,
+  .on     = clock_isr_on,
+  .off    = clock_isr_off,
+  .isOn   = clock_isr_is_on,
+};
+
+/**
+ * When we get the clock interrupt
+ *    - clear the interrupt bit?
+ *    - restart the timer?
+ */
+#define Clock_driver_support_at_tick()                \
+  do {                                                \
+        ClearPending(BIT_TIMER4);                     \
+  } while(0)
+
+
+/**
+ * Installs the clock ISR. You shouldn't need to change this.
+ */
+#define Clock_driver_support_install_isr( _new ) \
+  BSP_install_rtems_irq_handler(&clock_isr_data)
+
+
+/**
+ * Initialize the hardware for the clock
+ *   - Set the frequency
+ *   - enable it
+ *   - clear any pending interrupts
+ *
+ * Since you may want the clock always running, you can
+ * enable interrupts here. If you do so, the clock_isr_on(),
+ * clock_isr_off(), and clock_isr_is_on() functions can be
+ * NOPs.
+ */
+#define Clock_driver_support_initialize_hardware() \
+  do { \
+        uint32_t cr; \
+        uint32_t freq; \
+        /* set MUX for Timer4 to 1/16 */ \
+        cr=rTCFG1 & 0xFFF0FFFF; \
+        rTCFG1=(cr | (3<<16)); \
+        freq = get_PCLK(); \
+        /* set TIMER4 counter, input freq=PLCK/16/16Mhz*/ \
+        freq = (freq /16)/16; \
+        rTCNTB4 = ((freq / 1000) * rtems_configuration_get_microseconds_per_tick()) / 1000; \
+        /*unmask TIMER4 irq*/ \
+        rINTMSK&=~BIT_TIMER4; \
+        /* start TIMER4 with autoreload */ \
+        cr=rTCON & 0xFF8FFFFF; \
+        rTCON=(cr|(0x6<<20)); \
+        rTCON=(cr|(0x5<<20)); \
+    } while (0)
+
+/**
+ * Do whatever you need to shut the clock down and remove the
+ * interrupt handler. Since this normally only gets called on
+ * RTEMS shutdown, you may not need to do anything other than
+ * remove the ISR.
+ */
+#define Clock_driver_support_shutdown_hardware()                        \
+  do {                                                                  \
+        /* Disable timer */ \
+        BSP_remove_rtems_irq_handler(&clock_isr_data);                  \
+     } while (0)
+
+/**
+ * Enables clock interrupt.
+ *
+ * If the interrupt is always on, this can be a NOP.
+ */
+static void clock_isr_on(const rtems_irq_connect_data *unused)
+{
+}
+
+/**
+ * Disables clock interrupts
+ *
+ * If the interrupt is always on, this can be a NOP.
+ */
+static void clock_isr_off(const rtems_irq_connect_data *unused)
+{
+    return;
+}
+
+/**
+ * Tests to see if clock interrupt is enabled, and returns 1 if so.
+ * If interrupt is not enabled, returns 0.
+ *
+ * If the interrupt is always on, this always returns 1.
+ */
+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 "../../../shared/dev/clock/clockimpl.h"
Index: bsps/arm/smdk2410/clock/support.c
===================================================================
--- bsps/arm/smdk2410/clock/support.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/arm/smdk2410/clock/support.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,57 @@
+#include <rtems.h>
+#include <bsp.h>
+#include <s3c24xx.h>
+
+/* ------------------------------------------------------------------------- */
+/* NOTE: This describes the proper use of this file.
+ *
+ * BSP_OSC_FREQ should be defined as the input frequency of the PLL.
+ *
+ * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of
+ * the specified bus in HZ.
+ */
+/* ------------------------------------------------------------------------- */
+
+/* return FCLK frequency */
+uint32_t get_FCLK(void)
+{
+    uint32_t r, m, p, s;
+
+    r = rMPLLCON;
+    m = ((r & 0xFF000) >> 12) + 8;
+    p = ((r & 0x003F0) >> 4) + 2;
+    s = r & 0x3;
+
+    return((BSP_OSC_FREQ * m) / (p << s));
+}
+
+/* return UCLK frequency */
+uint32_t get_UCLK(void)
+{
+    uint32_t r, m, p, s;
+
+    r = rUPLLCON;
+    m = ((r & 0xFF000) >> 12) + 8;
+    p = ((r & 0x003F0) >> 4) + 2;
+    s = r & 0x3;
+
+    return((BSP_OSC_FREQ * m) / (p << s));
+}
+
+/* return HCLK frequency */
+uint32_t get_HCLK(void)
+{
+    if (rCLKDIVN & 0x2)
+	return get_FCLK()/2;
+    else
+	return get_FCLK();
+}
+
+/* return PCLK frequency */
+uint32_t get_PCLK(void)
+{
+    if (rCLKDIVN & 0x1)
+	return get_HCLK()/2;
+    else
+	return get_HCLK();
+}
Index: bsps/arm/tms570/clock/clock.c
===================================================================
--- bsps/arm/tms570/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/arm/tms570/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,190 @@
+/**
+ * @file clock.c
+ *
+ * @ingroup tms570
+ *
+ * @brief clock functions definitions.
+ */
+
+/*
+ * Copyright (c) 2014 Premysl Houdek <kom541000@gmail.com>
+ *
+ * Google Summer of Code 2014 at
+ * Czech Technical University in Prague
+ * Zikova 1903/4
+ * 166 36 Praha 6
+ * Czech Republic
+ *
+ * Based on LPC24xx and LPC1768 BSP
+ * by embedded brains GmbH and others
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdlib.h>
+
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/tms570-rti.h>
+#include <rtems/timecounter.h>
+
+static struct timecounter tms570_rti_tc;
+
+static uint32_t tms570_rti_get_timecount(struct timecounter *tc)
+{
+  return TMS570_RTI.CNT[0].FRCx;
+}
+
+#ifndef TMS570_PREFERRED_TC_FREQUENCY
+/*
+ * Define preferred main time base counter frequency
+ * The value of 1MHz is the best matching RTEMS
+ * timing system because then there is no need
+ * to scale RTEMS configuration microseconds_per_tick
+ * parameter
+ */
+#define TMS570_PREFERRED_TC_FREQUENCY 1000000
+#endif /* TMS570_PREFERRED_TC_FREQUENCY */
+
+/**
+ *  @brief Initialize the HW peripheral for clock driver
+ *
+ *  Clock driver is implemented by RTI module
+ *
+ * @retval Void
+ */
+static void tms570_clock_driver_support_initialize_hardware( void )
+{
+
+  uint32_t microsec_per_tick;
+  uint32_t tc_frequency;
+  uint32_t tc_prescaler;
+  uint32_t tc_increments_per_tick;
+
+  microsec_per_tick = rtems_configuration_get_microseconds_per_tick();
+  tc_frequency = TMS570_PREFERRED_TC_FREQUENCY;
+
+  tc_prescaler = (BSP_PLL_OUT_CLOCK + tc_frequency) / (tc_frequency * 2);
+
+  /* Recompute actual most close frequency which can be realized */
+  tc_frequency = (BSP_PLL_OUT_CLOCK + tc_prescaler) / (tc_prescaler * 2);
+
+  /*
+   * Recompute tick period to adjust for configurable or exact
+   * preferred time base 1 usec resolution.
+   */
+  tc_increments_per_tick = ((uint64_t)microsec_per_tick * tc_frequency +
+                           500000) / 1000000;
+
+  /* Hardware specific initialize */
+  TMS570_RTI.GCTRL = 0;
+  TMS570_RTI.CNT[0].CPUCx = tc_prescaler - 1;
+  TMS570_RTI.TBCTRL = TMS570_RTI_TBCTRL_INC;
+  TMS570_RTI.CAPCTRL = 0;
+  TMS570_RTI.COMPCTRL = 0;
+  /* set counter to zero */
+  TMS570_RTI.CNT[0].UCx = 0;
+  TMS570_RTI.CNT[0].FRCx = 0;
+  /* clear interrupts*/
+  TMS570_RTI.CLEARINTENA = TMS570_RTI_CLEARINTENA_CLEAROVL1INT |
+                           TMS570_RTI_CLEARINTENA_CLEAROVL0INT |
+                           TMS570_RTI_CLEARINTENA_CLEARTBINT |
+                           TMS570_RTI_CLEARINTENA_CLEARDMA3 |
+                           TMS570_RTI_CLEARINTENA_CLEARDMA2 |
+                           TMS570_RTI_CLEARINTENA_CLEARDMA1 |
+                           TMS570_RTI_CLEARINTENA_CLEARDMA0 |
+                           TMS570_RTI_CLEARINTENA_CLEARINT3 |
+                           TMS570_RTI_CLEARINTENA_CLEARINT2 |
+                           TMS570_RTI_CLEARINTENA_CLEARINT1 |
+                           TMS570_RTI_CLEARINTENA_CLEARINT0;
+  TMS570_RTI.INTFLAG = TMS570_RTI_INTFLAG_OVL1INT |
+                       TMS570_RTI_INTFLAG_OVL0INT |
+                       TMS570_RTI_INTFLAG_TBINT |
+                       TMS570_RTI_INTFLAG_INT3 |
+                       TMS570_RTI_INTFLAG_INT2 |
+                       TMS570_RTI_INTFLAG_INT1 |
+                       TMS570_RTI_INTFLAG_INT0;
+  /* set timer */
+  TMS570_RTI.CMP[0].COMPx = TMS570_RTI.CNT[0].FRCx + tc_increments_per_tick;
+  TMS570_RTI.COMP0CLR = TMS570_RTI.CMP[0].COMPx + tc_increments_per_tick / 2;
+  TMS570_RTI.CMP[0].UDCPx = tc_increments_per_tick;
+  /* enable interupt */
+  TMS570_RTI.SETINTENA = TMS570_RTI_SETINTENA_SETINT0;
+  /* enable timer */
+  TMS570_RTI.GCTRL = TMS570_RTI_GCTRL_CNT0EN;
+  /* set timecounter */
+  tms570_rti_tc.tc_get_timecount = tms570_rti_get_timecount;
+  tms570_rti_tc.tc_counter_mask = 0xffffffff;
+  tms570_rti_tc.tc_frequency = tc_frequency;
+  tms570_rti_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+  rtems_timecounter_install(&tms570_rti_tc);
+}
+
+/**
+ * @brief Clears interrupt source
+ *
+ * @retval Void
+ */
+static void tms570_clock_driver_support_at_tick( void )
+{
+  TMS570_RTI.INTFLAG = TMS570_RTI_INTFLAG_INT0;
+}
+
+/**
+ * @brief registers RTI interrupt handler
+ *
+ * @param[in] Clock_isr new ISR handler
+ * @param[in] Old_ticker old ISR handler (unused and type broken)
+ *
+ * @retval Void
+ */
+static void tms570_clock_driver_support_install_isr(
+  rtems_isr_entry Clock_isr
+)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  sc = rtems_interrupt_handler_install(
+    TMS570_IRQ_TIMER_0,
+    "Clock",
+    RTEMS_INTERRUPT_UNIQUE,
+    (rtems_interrupt_handler) Clock_isr,
+    NULL
+  );
+  if ( sc != RTEMS_SUCCESSFUL ) {
+    rtems_fatal_error_occurred(0xdeadbeef);
+  }
+}
+
+/**
+ * @brief disables RTI interrupt
+ *
+ * Called when closing clock driver
+ *
+ * @retval Void
+ */
+static void tms570_clock_driver_support_shutdown_hardware( void )
+{
+  /* turn off the timer interrupts */
+  TMS570_RTI.CLEARINTENA = TMS570_RTI_CLEARINTENA_CLEAROVL0INT |
+                           TMS570_RTI_CLEARINTENA_CLEARINT0;  
+}
+
+#define Clock_driver_support_initialize_hardware \
+                        tms570_clock_driver_support_initialize_hardware
+#define Clock_driver_support_at_tick \
+                        tms570_clock_driver_support_at_tick
+#define Clock_driver_support_initialize_hardware \
+                        tms570_clock_driver_support_initialize_hardware
+#define Clock_driver_support_shutdown_hardware \
+                        tms570_clock_driver_support_shutdown_hardware
+
+#define Clock_driver_support_install_isr(Clock_isr) \
+              tms570_clock_driver_support_install_isr( Clock_isr )
+
+void Clock_isr(void *arg); /* to supress warning */
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/i386/pc386/clock/ckinit.c
===================================================================
--- bsps/i386/pc386/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/i386/pc386/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,262 @@
+/**
+ *  @file
+ *
+ *  Clock Tick Device Driver
+ *
+ *  History:
+ *    + Original driver was go32 clock by Joel Sherrill
+ *    + go32 clock driver hardware code was inserted into new
+ *      boilerplate when the pc386 BSP by:
+ *        Pedro Miguel Da Cruz Neto Romano <pmcnr@camoes.rnl.ist.utl.pt>
+ *        Jose Rufino <ruf@asterix.ist.utl.pt>
+ *    + Reworked by Joel Sherrill to use clock driver template.
+ *      This removes all boilerplate and leave original hardware
+ *      code I developed for the go32 BSP.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/irq-generic.h>
+#include <bspopts.h>
+#include <libcpu/cpuModel.h>
+#include <assert.h>
+#include <rtems/timecounter.h>
+
+#define CLOCK_VECTOR 0
+
+volatile uint32_t pc386_microseconds_per_isr;
+volatile uint32_t pc386_isrs_per_tick;
+uint32_t pc386_clock_click_count;
+
+/* forward declaration */
+void Clock_isr(void *param);
+static void clockOff(void);
+static void Clock_isr_handler(void *param);
+
+/*
+ * 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.
+ */
+static uint64_t pc586_tsc_frequency;
+
+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
+
+extern volatile uint32_t Clock_driver_ticks;
+
+#define READ_8254( _lsb, _msb )                               \
+  do { outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_LATCH);      \
+     inport_byte(TIMER_CNTR0, _lsb);                          \
+     inport_byte(TIMER_CNTR0, _msb);                          \
+  } while (0)
+
+
+#ifdef RTEMS_SMP
+#define Clock_driver_support_at_tick() \
+  _SMP_Send_message_broadcast(SMP_MESSAGE_CLOCK_TICK)
+#endif
+
+static uint32_t pc386_get_timecount_tsc(struct timecounter *tc)
+{
+  return (uint32_t)rdtsc();
+}
+
+static uint32_t pc386_get_timecount_i8254(struct timecounter *tc)
+{
+  uint32_t                 irqs;
+  uint8_t                  lsb, msb;
+  rtems_interrupt_lock_context lock_context;
+
+  /*
+   * Fetch all the data in an interrupt critical section.
+   */
+
+  rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context);
+
+    READ_8254(lsb, msb);
+    irqs = Clock_driver_ticks;
+
+  rtems_interrupt_lock_release(&rtems_i386_i8254_access_lock, &lock_context);
+
+  return (irqs + 1) * pc386_microseconds_per_isr - ((msb << 8) | lsb);
+}
+
+/*
+ * Calibrate CPU cycles per tick. Interrupts should be disabled.
+ */
+static void calibrate_tsc(void)
+{
+  uint64_t              begin_time;
+  uint8_t               then_lsb, then_msb, now_lsb, now_msb;
+  uint32_t              i;
+
+  /*
+   * We just reset the timer, so we know we're at the beginning of a tick.
+   */
+
+  /*
+   * Count cycles. Watching the timer introduces a several microsecond
+   * uncertaintity, so let it cook for a while and divide by the number of
+   * ticks actually executed.
+   */
+
+  begin_time = rdtsc();
+
+  for (i = rtems_clock_get_ticks_per_second() * pc386_isrs_per_tick;
+       i != 0; --i ) {
+    /* We know we've just completed a tick when timer goes from low to high */
+    then_lsb = then_msb = 0xff;
+    do {
+      READ_8254(now_lsb, now_msb);
+      if ((then_msb < now_msb) ||
+          ((then_msb == now_msb) && (then_lsb < now_lsb)))
+        break;
+      then_lsb = now_lsb;
+      then_msb = now_msb;
+    } while (1);
+  }
+
+  pc586_tsc_frequency = rdtsc() - begin_time;
+
+#if 0
+  printk( "CPU clock at %u MHz\n", (uint32_t)(pc586_tsc_frequency / 1000000));
+#endif
+}
+
+static void clockOn(void)
+{
+  rtems_interrupt_lock_context lock_context;
+  pc386_isrs_per_tick        = 1;
+  pc386_microseconds_per_isr = rtems_configuration_get_microseconds_per_tick();
+
+  while (US_TO_TICK(pc386_microseconds_per_isr) > 65535) {
+    pc386_isrs_per_tick  *= 10;
+    pc386_microseconds_per_isr /= 10;
+  }
+  pc386_clock_click_count = US_TO_TICK(pc386_microseconds_per_isr);
+
+  #if 0
+    printk( "configured usecs per tick=%d \n",
+      rtems_configuration_get_microseconds_per_tick() );
+    printk( "Microseconds per ISR =%d\n", pc386_microseconds_per_isr );
+    printk( "final ISRs per=%d\n", pc386_isrs_per_tick );
+    printk( "final timer counts=%d\n", pc386_clock_click_count );
+  #endif
+
+  rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context);
+  outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);
+  outport_byte(TIMER_CNTR0, pc386_clock_click_count >> 0 & 0xff);
+  outport_byte(TIMER_CNTR0, pc386_clock_click_count >> 8 & 0xff);
+  rtems_interrupt_lock_release(&rtems_i386_i8254_access_lock, &lock_context);
+
+  bsp_interrupt_vector_enable( BSP_PERIODIC_TIMER - BSP_IRQ_VECTOR_BASE );
+
+  /*
+   * Now calibrate cycles per tick. Do this every time we
+   * turn the clock on in case the CPU clock speed has changed.
+   */
+  if ( x86_has_tsc() )
+    calibrate_tsc();
+}
+
+static void clockOff(void)
+{
+  rtems_interrupt_lock_context lock_context;
+  rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context);
+  /* reset timer mode to standard (BIOS) value */
+  outport_byte(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN);
+  outport_byte(TIMER_CNTR0, 0);
+  outport_byte(TIMER_CNTR0, 0);
+  rtems_interrupt_lock_release(&rtems_i386_i8254_access_lock, &lock_context);
+} /* Clock_exit */
+
+bool Clock_isr_enabled = false;
+static void Clock_isr_handler(void *param)
+{
+  if ( Clock_isr_enabled )
+    Clock_isr( param );
+}
+
+void Clock_driver_install_handler(void)
+{
+  rtems_status_code status;
+
+  status = rtems_interrupt_handler_install(
+    BSP_PERIODIC_TIMER,
+    "ckinit",
+    RTEMS_INTERRUPT_UNIQUE,
+    Clock_isr_handler,
+    NULL
+  );
+  assert(status == RTEMS_SUCCESSFUL);
+  clockOn();
+}
+
+#define Clock_driver_support_set_interrupt_affinity(online_processors) \
+  do { \
+    /* FIXME: Is there a way to do this on x86? */ \
+    (void) online_processors; \
+  } while (0)
+
+void Clock_driver_support_initialize_hardware(void)
+{
+  bool use_tsc = false;
+  bool use_8254 = false;
+
+  #if (CLOCK_DRIVER_USE_TSC == 1)
+    use_tsc = true;
+  #endif
+
+  #if (CLOCK_DRIVER_USE_8254 == 1)
+    use_8254 = true;
+  #endif
+
+  if ( !use_tsc && !use_8254 ) {
+    if ( x86_has_tsc() ) use_tsc  = true;
+    else                 use_8254 = true;
+  }
+
+  if ( use_8254 ) {
+    /* printk( "Use 8254\n" ); */
+    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" ); */
+    pc386_tc.tc_get_timecount = pc386_get_timecount_tsc;
+    pc386_tc.tc_counter_mask = 0xffffffff;
+    pc386_tc.tc_frequency = pc586_tsc_frequency;
+  }
+
+  pc386_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+  rtems_timecounter_install(&pc386_tc);
+  Clock_isr_enabled = true;
+}
+
+#define Clock_driver_support_shutdown_hardware() \
+  do { \
+    rtems_status_code status; \
+    clockOff(); \
+    status = rtems_interrupt_handler_remove(  \
+      BSP_PERIODIC_TIMER, \
+      Clock_isr_handler,  \
+      NULL  \
+    );  \
+    assert(status == RTEMS_SUCCESSFUL); \
+  } while (0)
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/i386/pc386/clock/rtc.c
===================================================================
--- bsps/i386/pc386/clock/rtc.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/i386/pc386/clock/rtc.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,216 @@
+/*-------------------------------------------------------------------------+
+| rtc.c v1.1 - PC386 BSP - 1997/08/07
++--------------------------------------------------------------------------+
+| This file contains the real time clock manipulation package for the
+| PC386 board.
++--------------------------------------------------------------------------+
+| (C) Copyright 1997 -
+| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
+|
+| http://pandora.ist.utl.pt
+|
+| Instituto Superior Tecnico * Lisboa * PORTUGAL
++--------------------------------------------------------------------------+
+| Disclaimer:
+|
+| This file is provided "AS IS" without warranty of any kind, either
+| expressed or implied.
++--------------------------------------------------------------------------+
+| This code is based on:
+|   rtc.c,v 1.4 1995/12/19 20:07:15 joel Exp - go32 BSP
+| With the following copyright notice:
+| **************************************************************************
+| *  COPYRIGHT (c) 1989-1999.
+| *  On-Line Applications Research Corporation (OAR).
+| *
+| *  The license and distribution terms for this file may be
+| *  found in the file LICENSE in this distribution or at
+| *  http://www.rtems.org/license/LICENSE.
+| **************************************************************************
++--------------------------------------------------------------------------*/
+
+#include <string.h>
+
+#include <bsp.h>
+
+/*-------------------------------------------------------------------------+
+| Constants
++--------------------------------------------------------------------------*/
+#define IO_RTC         0x70  /* RTC                                    */
+
+#define RTC_SEC        0x00  /* seconds                                */
+#define RTC_SECALRM    0x01  /* seconds alarm                          */
+#define RTC_MIN        0x02  /* minutes                                */
+#define RTC_MINALRM    0x03  /* minutes alarm                          */
+#define RTC_HRS        0x04  /* hours                                  */
+#define RTC_HRSALRM    0x05  /* hours alarm                            */
+#define RTC_WDAY       0x06  /* week day                               */
+#define RTC_DAY        0x07  /* day of month                           */
+#define RTC_MONTH      0x08  /* month of year                          */
+#define RTC_YEAR       0x09  /* month of year                          */
+#define RTC_STATUSA    0x0a  /* status register A                      */
+#define  RTCSA_TUP     0x80  /* time update, don't look now            */
+
+#define RTC_STATUSB    0x0b  /* status register B                      */
+
+#define RTC_INTR       0x0c  /* status register C (R) interrupt source */
+#define  RTCIR_UPDATE  0x10  /* update intr                            */
+#define  RTCIR_ALARM   0x20  /* alarm intr                             */
+#define  RTCIR_PERIOD  0x40  /* periodic intr                          */
+#define  RTCIR_INT     0x80  /* interrupt output signal                */
+
+#define RTC_STATUSD    0x0d  /* status register D (R) Lost Power       */
+#define  RTCSD_PWR     0x80  /* clock lost power                       */
+
+#define RTC_DIAG       0x0e  /* status register E - bios diagnostic    */
+#define RTCDG_BITS     "\020\010clock_battery\007ROM_cksum\006config_unit\005memory_size\004fixed_disk\003invalid_time"
+
+#define RTC_CENTURY    0x32  /* current century - increment in Dec99   */
+
+/*-------------------------------------------------------------------------+
+| Auxiliary Functions
++--------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------+
+|         Function: bcd
+|      Description: Convert 2 digit number to its BCD representation.
+| Global Variables: None.
+|        Arguments: i - Number to convert.
+|          Returns: BCD representation of number.
++--------------------------------------------------------------------------*/
+static inline uint8_t
+bcd(uint8_t         i)
+{
+  return ((i / 16) * 10 + (i % 16));
+} /* bcd */
+
+#define QUICK_READ  /* Quick read of the RTC: don't return number of seconds. */
+
+#ifndef QUICK_READ
+
+#define SECS_PER_DAY      (24 * 60 * 60)
+#define SECS_PER_REG_YEAR (365 * SECS_PER_DAY)
+
+/*-------------------------------------------------------------------------+
+|         Function: ytos
+|      Description: Convert years to seconds (since 1970).
+| Global Variables: None.
+|        Arguments: y - year to convert (1970 <= y <= 2100).
+|          Returns: number of seconds since 1970.
++--------------------------------------------------------------------------*/
+static inline uint32_t
+ytos(uint16_t         y)
+{                                       /* v NUM LEAP YEARS v */
+  return ((y - 1970) * SECS_PER_REG_YEAR + (y - 1970 + 1) / 4 * SECS_PER_DAY);
+} /* ytos */
+
+/*-------------------------------------------------------------------------+
+|         Function: mtos
+|      Description: Convert months to seconds since January.
+| Global Variables: None.
+|        Arguments: m - month to convert, leap - is this a month of a leap year.
+|          Returns: number of seconds since January.
++--------------------------------------------------------------------------*/
+static inline uint32_t
+mtos(uint8_t         m, bool leap)
+{
+  static uint16_t         daysMonth[] = { 0, 0, 31,  59,  90, 120, 151, 181,
+				               212, 243, 273, 304, 334, 365 };
+    /* Days since beginning of year until beginning of month. */
+
+  return ((daysMonth[m] + (leap ? 1 : 0)) * SECS_PER_DAY);
+} /* mtos */
+
+#endif /* QUICK_READ */
+
+/*-------------------------------------------------------------------------+
+|         Function: rtcin
+|      Description: Perform action on RTC and return its result.
+| Global Variables: None.
+|        Arguments: what - what to write to RTC port (what to do).
+|          Returns: result received from RTC port after action performed.
++--------------------------------------------------------------------------*/
+static inline uint8_t
+rtcin(uint8_t         what)
+{
+    uint8_t         r;
+
+    outport_byte(IO_RTC,   what);
+    inport_byte (IO_RTC+1, r);
+    return r;
+} /* rtcin */
+
+/*-------------------------------------------------------------------------+
+| Functions
++--------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------+
+|         Function: init_rtc
+|      Description: Initialize real-time clock (RTC).
+| Global Variables: None.
+|        Arguments: None.
+|          Returns: Nothing.
++--------------------------------------------------------------------------*/
+void
+init_rtc(void)
+{
+  uint8_t         s;
+
+  /* initialize brain-dead battery powered clock */
+  outport_byte(IO_RTC,   RTC_STATUSA);
+  outport_byte(IO_RTC+1, 0x26);
+  outport_byte(IO_RTC,   RTC_STATUSB);
+  outport_byte(IO_RTC+1, 2);
+
+  outport_byte(IO_RTC,   RTC_DIAG);
+  inport_byte (IO_RTC+1, s);
+  if (s)
+    printk("RTC BIOS diagnostic error %b\n", s);
+
+  /* FIXME: This was last line's original version. How was it supposed to work?
+       printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS); */
+} /* init_rtc */
+
+/*-------------------------------------------------------------------------+
+|         Function: rtc_read
+|      Description: Read present time from RTC and return it.
+| Global Variables: None.
+|        Arguments: tod - to return present time in 'rtems_time_of_day' format.
+|          Returns: number of seconds from 1970/01/01 corresponding to 'tod'.
++--------------------------------------------------------------------------*/
+long int
+rtc_read(rtems_time_of_day *tod)
+{
+  uint8_t          sa;
+  uint32_t         sec = 0;
+
+  memset(tod, 0, sizeof *tod); /* zero tod structure */
+
+  /* do we have a realtime clock present? (otherwise we loop below) */
+  sa = rtcin(RTC_STATUSA);
+  if (sa == 0xff || sa == 0)
+    return -1;
+
+  /* ready for a read? */
+  while ((sa&RTCSA_TUP) == RTCSA_TUP)
+    sa = rtcin(RTC_STATUSA);
+
+  tod->year	= bcd(rtcin(RTC_YEAR)) + 1900;  /* year    */
+  if (tod->year < 1970)	tod->year += 100;
+  tod->month	= bcd(rtcin(RTC_MONTH));        /* month   */
+  tod->day	= bcd(rtcin(RTC_DAY));          /* day     */
+  (void)          bcd(rtcin(RTC_WDAY));         /* weekday */
+  tod->hour	= bcd(rtcin(RTC_HRS));          /* hour    */
+  tod->minute	= bcd(rtcin(RTC_MIN));          /* minutes */
+  tod->second	= bcd(rtcin(RTC_SEC));          /* seconds */
+  tod->ticks	= 0;
+
+#ifndef QUICK_READ  /* Quick read of the RTC: don't return number of seconds. */
+  sec =  ytos(tod->year);
+  sec += mtos(tod->month, (tod->year % 4) == 0);
+  sec += tod->day * SECS_PER_DAY;
+  sec += tod->hour * 60 * 60;                     /* hour    */
+  sec += tod->minute * 60;                        /* minutes */
+  sec += tod->second;                             /* seconds */
+#endif /* QUICK_READ */
+
+  return (long int)sec;
+} /* rtc_read */
Index: bsps/i386/pc386/clock/todcfg.c
===================================================================
--- bsps/i386/pc386/clock/todcfg.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/i386/pc386/clock/todcfg.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,32 @@
+/*
+ * This file contains the RTC driver table for Motorola shared BSPs.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <libchip/rtc.h>
+#include <libchip/mc146818a.h>
+
+/* The following table configures the RTC drivers used in this BSP */
+rtc_tbl RTC_Table[] = {
+    {
+        "/dev/rtc",                /* sDeviceName */
+        RTC_MC146818A,             /* deviceType */
+        &mc146818a_fns,            /* pDeviceFns */
+        mc146818a_probe,           /* deviceProbe */
+        NULL,                      /* pDeviceParams */
+        0x70,                      /* ulCtrlPort1 */
+        0x00,                      /* ulDataPort */
+        mc146818a_get_register,    /* getRegister */
+        mc146818a_set_register     /* setRegister */
+    }
+};
+
+/* Some information used by the RTC driver */
+
+#define NUM_RTCS (sizeof(RTC_Table)/sizeof(rtc_tbl))
+
+size_t RTC_Count = NUM_RTCS;
Index: bsps/lm32/shared/clock/ckinit.c
===================================================================
--- bsps/lm32/shared/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/lm32/shared/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,78 @@
+/*
+ *  Clock device driver for Lattice Mico32 (lm32).
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2009.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ *  Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
+ *  Micro-Research Finland Oy
+ */
+
+#include <bsp.h>
+#include "../include/system_conf.h"
+#include "clock.h"
+#include "bspopts.h"
+
+#if LM32_ON_SIMULATOR
+#define CLOCK_DRIVER_USE_FAST_IDLE 1
+#endif
+
+static inline int clockread(unsigned int reg)
+{
+  return *((int*)(TIMER0_BASE_ADDRESS + reg));
+}
+
+static inline void clockwrite(unsigned int reg, int value)
+{
+  *((int*)(TIMER0_BASE_ADDRESS + reg)) = value;
+}
+
+/*
+ *  The interrupt vector number associated with the clock tick device
+ *  driver.
+ */
+#define CLOCK_VECTOR    ( TIMER0_IRQ )
+#define CLOCK_IRQMASK   ( 1 << CLOCK_VECTOR )
+
+#define Clock_driver_support_at_tick() \
+  do { \
+    /* Clear overflow flag */ \
+    clockwrite(LM32_CLOCK_SR, 0); \
+    lm32_interrupt_ack(CLOCK_IRQMASK); \
+  } while (0)
+
+#define Clock_driver_support_install_isr(_new ) \
+  set_vector( _new, CLOCK_VECTOR, 1 )
+
+static void Clock_driver_support_initialize_hardware(void)
+{
+  /* Set clock period */
+  clockwrite(LM32_CLOCK_PERIOD,
+	     (CPU_FREQUENCY /
+	      (1000000 / rtems_configuration_get_microseconds_per_tick())));
+
+  /* Enable clock interrupts and start in continuous mode */
+  clockwrite(LM32_CLOCK_CR, LM32_CLOCK_CR_ITO |
+	     LM32_CLOCK_CR_CONT |
+	     LM32_CLOCK_CR_START);
+
+  lm32_interrupt_unmask(CLOCK_IRQMASK);
+}
+
+#define Clock_driver_support_shutdown_hardware() \
+  do { \
+    /* Disable clock interrupts and stop */ \
+    lm32_interrupt_unmask(CLOCK_IRQMASK); \
+    clockwrite(LM32_CLOCK_CR, LM32_CLOCK_CR_STOP); \
+  } while (0)
+
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
+#include "../../../shared/dev/clock/clockimpl.h"
+
Index: bsps/lm32/shared/clock/clock.h
===================================================================
--- bsps/lm32/shared/clock/clock.h	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/lm32/shared/clock/clock.h	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,55 @@
+/**
+ * @file
+ * @ingroup lm32_clock
+ * @brief LatticeMico32 Timer (Clock) definitions
+ */
+
+/*
+ *  This file contains definitions for LatticeMico32 Timer (Clock)
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ *  Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008,
+ *  Micro-Research Finland Oy
+ */
+
+/**
+ * @defgroup lm32_clock LM32 Clock
+ * @ingroup lm32_shared
+ * @brief LatticeMico32 Timer (Clock) definitions.
+ * @{
+ */
+
+#ifndef _BSPCLOCK_H
+#define _BSPCLOCK_H
+
+/** @brief Status Register */
+
+#define LM32_CLOCK_SR       (0x0000)
+#define LM32_CLOCK_SR_TO    (0x0001)
+#define LM32_CLOCK_SR_RUN   (0x0002)
+
+/** @brief Control Register */
+
+#define LM32_CLOCK_CR       (0x0004)
+#define LM32_CLOCK_CR_ITO   (0x0001)
+#define LM32_CLOCK_CR_CONT  (0x0002)
+#define LM32_CLOCK_CR_START (0x0004)
+#define LM32_CLOCK_CR_STOP  (0x0008)
+
+/** @brief Period Register */
+
+#define LM32_CLOCK_PERIOD   (0x0008)
+
+/** @brief Snapshot Register */
+
+#define LM32_CLOCK_SNAPSHOT (0x000C)
+
+#endif /* _BSPCLOCK_H */
+
+/** @} */
Index: bsps/m68k/av5282/clock/clock.c
===================================================================
--- bsps/m68k/av5282/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/m68k/av5282/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,61 @@
+/*
+ * Use the last periodic interval timer (PIT3) as the system clock.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <mcf5282/mcf5282.h>
+
+/*
+ * Use INTC0 base
+ */
+#define CLOCK_VECTOR (64+58)
+
+/*
+ * Periodic interval timer interrupt handler
+ */
+#define Clock_driver_support_at_tick()             \
+    do {                                           \
+        MCF5282_PIT3_PCSR |= MCF5282_PIT_PCSR_PIF; \
+    } while (0)                                    \
+
+/*
+ * Attach clock interrupt handler
+ */
+#define Clock_driver_support_install_isr( _new ) \
+    set_vector(_new, CLOCK_VECTOR, 1)
+
+/*
+ * Turn off the clock
+ */
+#define Clock_driver_support_shutdown_hardware()   \
+    do {                                           \
+        MCF5282_PIT3_PCSR &= ~MCF5282_PIT_PCSR_EN; \
+    } while(0)
+
+/*
+ * Set up the clock hardware
+ *
+ * We need to have 1 interrupt every 10,000 microseconds
+ * so we need to set prescaler to 64 and the PMR register to 0x23FE
+ */
+#define Clock_driver_support_initialize_hardware()                       \
+    do {                                                                 \
+        int level;                                                       \
+        int preScaleCode = 5;                                             \
+        MCF5282_INTC0_ICR58 = MCF5282_INTC_ICR_IL(PIT3_IRQ_LEVEL) |      \
+                              MCF5282_INTC_ICR_IP(PIT3_IRQ_PRIORITY);    \
+        rtems_interrupt_disable( level );                                \
+        MCF5282_INTC0_IMRH &= ~MCF5282_INTC_IMRH_INT58;                  \
+		MCF5282_PIT3_PCSR &= ~MCF5282_PIT_PCSR_EN;                       \
+        rtems_interrupt_enable( level );                                 \
+		MCF5282_PIT3_PMR = 0x23FE;  \
+		MCF5282_PIT3_PCSR = MCF5282_PIT_PCSR_PRE(preScaleCode) |         \
+                            MCF5282_PIT_PCSR_PIE |                       \
+                            MCF5282_PIT_PCSR_RLD |                       \
+                            MCF5282_PIT_PCSR_EN;                         \
+    } while (0)
+
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/m68k/gen68340/clock/ckinit.c
===================================================================
--- bsps/m68k/gen68340/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/m68k/gen68340/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,104 @@
+/*
+ * This routine initializes the MC68340/349 Periodic Interval Timer
+ */
+
+/*
+ * Based on the `gen68360' board support package, and covered by the
+ * original distribution terms.
+ *
+ * Geoffroy Montel
+ * France Telecom - CNET/DSM/TAM/CAT
+ * 4, rue du Clos Courtel
+ * 35512 CESSON-SEVIGNE
+ * FRANCE
+ *
+ * e-mail: g_montel@yahoo.com
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdlib.h>       /* for atexit() */
+#include <bsp.h>
+#include <m68340.h>
+#include <rtems/clockdrv.h>
+
+#define CLOCK_VECTOR     120 /* clock isr routine vector in the vbr */
+#define CLOCK_IRQ_LEVEL  6   /* clock isr level */
+
+/*
+ * Clock_driver_ticks is a monotonically increasing counter of the
+ * number of clock ticks since the driver was initialized.
+ */
+volatile uint32_t         Clock_driver_ticks;
+
+/*
+ * Periodic interval timer interrupt handler
+ */
+static rtems_isr
+Clock_isr (rtems_vector_number vector)
+{
+  /*
+   * Announce the clock tick
+   */
+  Clock_driver_ticks++;
+  rtems_clock_tick();
+}
+
+void
+Clock_exit (void)
+{
+  /*
+   * Turn off periodic interval timer
+   */
+  SIMPITR = 0;
+}
+
+static void
+Install_clock (rtems_isr_entry clock_isr)
+{
+  uint32_t   pitr_tmp;
+  uint32_t   usecs_per_tick;
+
+  Clock_driver_ticks = 0;
+
+  set_vector (clock_isr, CLOCK_VECTOR, 1);
+
+  /* sets the Periodic Interrupt Control Register PICR */
+  SIMPICR = ( CLOCK_IRQ_LEVEL << 8 ) | ( CLOCK_VECTOR );
+
+  /* sets the PITR count value */
+  /* this assumes a 32.765 kHz crystal */
+
+  usecs_per_tick = rtems_configuration_get_microseconds_per_tick();
+  /* find out whether prescaler should be enabled or not */
+  if ( usecs_per_tick <= 31128 ) {
+     pitr_tmp = ( usecs_per_tick * 8192 ) / 1000000 ;
+  } else {
+     pitr_tmp = ( usecs_per_tick / 1000000 ) * 16;
+     /* enable it */
+     pitr_tmp |= 0x100;
+  }
+
+  SIMPITR = (unsigned char) pitr_tmp;
+
+  atexit (Clock_exit);
+}
+
+rtems_device_driver
+Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  Install_clock (Clock_isr);
+
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/m68k/gen68360/clock/clock.c
===================================================================
--- bsps/m68k/gen68360/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/m68k/gen68360/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,101 @@
+/*
+ * This routine initializes the MC68360 Periodic Interval Timer
+ *
+ * The PIT has rather poor resolution, but it is easy to set up
+ * and requires no housekeeping once it is going.
+ *
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <rtems/m68k/m68360.h>
+
+#define CLOCK_VECTOR     120
+#define CLOCK_IRQ_LEVEL    4
+
+char M360DefaultWatchdogFeeder = 1;
+
+/*
+ * RTEMS and hardware have different notions of clock rate.
+ */
+static unsigned long rtems_nsec_per_tick;
+static unsigned long pit_nsec_per_tick;
+static unsigned long nsec;
+
+/*
+ * Periodic interval timer interrupt handler
+ *    See if it's really time for a `tick'
+ *    Perform a dummy read of DPRAM (work around bug in Rev. B of the 68360).
+ *    Feed the watchdog
+ *        Application code can override this by
+ *        setting M360DefaultWatchdogFeeder to zero.
+ */
+#define Clock_driver_support_at_tick()  \
+    do {                                   \
+        nsec += pit_nsec_per_tick;         \
+        if (nsec >= rtems_nsec_per_tick)   \
+            return;                        \
+        nsec -= rtems_nsec_per_tick;       \
+        m360.dpram0[0];                    \
+        if (M360DefaultWatchdogFeeder) {   \
+            m360.swsr = 0x55;              \
+            m360.swsr = 0xAA;              \
+        }                                  \
+    } while (0)                            \
+
+/*
+ * Attach clock interrupt handler
+ */
+#define Clock_driver_support_install_isr( _new ) \
+    set_vector(_new, CLOCK_VECTOR, 1)
+
+/*
+ * Turn off the clock
+ */
+#define Clock_driver_support_shutdown_hardware() \
+    do {                       \
+        m360.pitr &= ~0xFF;    \
+    } while(0)
+
+/*
+ * Set up the clock hardware
+ *     The rate at which the periodic interval timer
+ *     can generate interrupts is almost certainly not
+ *     the same as desired by the BSP configuration.
+ *     Handle the difference by choosing the largest PIT
+ *     interval which is less than or equal to the RTEMS
+ *     interval and skipping some hardware interrupts.
+ *     To reduce the jitter in the calls to RTEMS the
+ *     hardware interrupt interval is never greater than
+ *     the maximum non-prescaled value from the PIT.
+ *
+ *     For a 25 MHz external clock the basic clock rate is
+ *        40 nsec * 128 * 4 = 20.48 usec/tick
+ */
+extern int m360_clock_rate;
+
+#define Clock_driver_support_initialize_hardware() \
+    do {                                                                      \
+        unsigned int divisor;                                                 \
+        unsigned long nsec_per_chip_tick = 1000000000 / m360_clock_rate;      \
+        unsigned long nsec_per_pit_tick = 512 * nsec_per_chip_tick;           \
+        rtems_nsec_per_tick = rtems_configuration_get_microseconds_per_tick() * 1000; \
+        divisor = rtems_nsec_per_tick / nsec_per_pit_tick;                    \
+        if (divisor > 255)                                                    \
+            divisor = 255;                                                    \
+        else if (divisor == 0)                                                \
+            divisor = 1;                                                      \
+        pit_nsec_per_tick = nsec_per_pit_tick * divisor;                      \
+        m360.pitr &= ~0x1FF;                                                  \
+        m360.picr = (CLOCK_IRQ_LEVEL << 8) | CLOCK_VECTOR;                    \
+        m360.pitr |= divisor;                                                 \
+    } while (0)
+
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/m68k/genmcf548x/clock/clock.c
===================================================================
--- bsps/m68k/genmcf548x/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/m68k/genmcf548x/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,102 @@
+/*===============================================================*\
+| Project: RTEMS generic mcf548x BSP                              |
++-----------------------------------------------------------------+
+| File: clock.c                                                   |
++-----------------------------------------------------------------+
+| The file contains the clock driver code of generic MCF548x BSP. |
++-----------------------------------------------------------------+
+|                    Copyright (c) 2007                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
++-----------------------------------------------------------------+
+|                                                                 |
+| Parts of the code has been derived from the "dBUG source code"  |
+| package Freescale is providing for M548X EVBs. The usage of     |
+| the modified or unmodified code and it's integration into the   |
+| generic mcf548x BSP has been done according to the Freescale    |
+| license terms.                                                  |
+|                                                                 |
+| The Freescale license terms can be reviewed in the file         |
+|                                                                 |
+|    Freescale_license.txt                                        |
+|                                                                 |
++-----------------------------------------------------------------+
+|                                                                 |
+| The generic mcf548x BSP has been developed on the basic         |
+| structures and modules of the av5282 BSP.                       |
+|                                                                 |
++-----------------------------------------------------------------+
+|                                                                 |
+| The license and distribution terms for this file may be         |
+| found in the file LICENSE in this distribution or at            |
+|                                                                 |
+| http://www.rtems.org/license/LICENSE.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+|                                                                 |
+|   date                      history                        ID   |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 12.11.07                    1.0                            ras  |
+|                                                                 |
+\*===============================================================*/
+
+/*
+ * Use first slice timer (SLT0) as the system clock.
+ *
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq-generic.h>
+#include <mcf548x/mcf548x.h>
+
+/*
+ * Use SLT 0
+ */
+#define CLOCK_IRQ MCF548X_IRQ_SLT0
+
+/*
+ * Periodic interval timer interrupt handler
+ */
+#define Clock_driver_support_at_tick()             \
+    do {                                           \
+        MCF548X_SLT_SSR0 = MCF548X_SLT_SSR_ST;     \
+    } while (0)                                    \
+
+/*
+ * Attach clock interrupt handler
+ */
+#define Clock_driver_support_install_isr( _new ) \
+    set_vector(_new, CLOCK_IRQ + 64, 1)
+
+/*
+ * Turn off the clock
+ */
+#define Clock_driver_support_shutdown_hardware()                         \
+    do {                                                                 \
+        MCF548X_SLT_SCR0 &= ~(MCF548X_SLT_SCR_TEN | MCF548X_SLT_SCR_RUN | MCF548X_SLT_SCR_IEN); \
+    } while(0)
+
+/*
+ * Set up the clock hardware
+ *
+ * We need to have 1 interrupt every 10,000 microseconds
+ * XLB clock 100 MHz / MCF548X_SLT_SLTCNT0 = XLB clock/100
+ */
+#define Clock_driver_support_initialize_hardware()			\
+  do {									\
+    bsp_interrupt_vector_enable(CLOCK_IRQ);				\
+    MCF548X_SLT_SLTCNT0 = get_CPU_clock_speed()				\
+      / 1000								\
+      * rtems_configuration_get_microseconds_per_tick()			\
+      / 1000;								\
+    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/dev/clock/clockimpl.h"
+
Index: bsps/m68k/mcf52235/clock/clock.c
===================================================================
--- bsps/m68k/mcf52235/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/m68k/mcf52235/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,106 @@
+/*
+ * Use the last periodic interval timer (PIT2) as the system clock.
+ */
+
+#include <rtems.h>
+#include <rtems/timecounter.h>
+#include <bsp.h>
+
+/*
+ * Use INTC0 base
+ */
+#define CLOCK_VECTOR (64+56)
+
+static rtems_timecounter_simple mcf52235_tc;
+
+static uint32_t mcf52235_tc_get(rtems_timecounter_simple *tc)
+{
+  return MCF_PIT1_PCNTR;
+}
+
+static bool mcf52235_tc_is_pending(rtems_timecounter_simple *tc)
+{
+  return (MCF_PIT1_PCSR & MCF_PIT_PCSR_PIF) != 0;
+}
+
+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_at_tick(rtems_timecounter_simple *tc)
+{
+  MCF_PIT1_PCSR |= MCF_PIT_PCSR_PIF;
+}
+
+static void mcf52235_tc_tick(void)
+{
+  rtems_timecounter_simple_downcounter_tick(
+    &mcf52235_tc,
+    mcf52235_tc_get,
+    mcf52235_tc_at_tick
+  );
+}
+
+/*
+ * Attach clock interrupt handler
+ */
+#define Clock_driver_support_install_isr( _new ) \
+  set_vector(_new, CLOCK_VECTOR, 1)
+
+/*
+ * Turn off the clock
+ */
+#define Clock_driver_support_shutdown_hardware() \
+  do { \
+    MCF_PIT1_PCSR &= ~MCF_PIT_PCSR_EN; \
+  } while (0)
+
+/*
+ * Set up the clock hardware
+ *
+ * We need to have 1 interrupt every rtems_configuration_get_microseconds_per_tick()
+ */
+static void Clock_driver_support_initialize_hardware(void)
+{
+  int level;
+  uint32_t pmr;
+  uint32_t preScaleCode = 0;
+  uint32_t clk = bsp_get_CPU_clock_speed() >> 1;
+  uint32_t tps = 1000000 / rtems_configuration_get_microseconds_per_tick();
+
+  while (preScaleCode < 15) {
+    pmr = (clk >> preScaleCode) / tps;
+    if (pmr < (1 << 15))
+      break;
+    preScaleCode++;
+  }
+
+  MCF_INTC0_ICR56 = MCF_INTC_ICR_IL(PIT3_IRQ_LEVEL) |
+    MCF_INTC_ICR_IP(PIT3_IRQ_PRIORITY);
+  rtems_interrupt_disable(level);
+  MCF_INTC0_IMRH &= ~MCF_INTC_IMRH_MASK56;
+  MCF_PIT1_PCSR &= ~MCF_PIT_PCSR_EN;
+  rtems_interrupt_enable(level);
+
+  MCF_PIT1_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) |
+    MCF_PIT_PCSR_OVW | MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD;
+  MCF_PIT1_PMR = pmr;
+  MCF_PIT1_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) |
+    MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_EN;
+
+  rtems_timecounter_simple_install(
+    &mcf52235_tc,
+    clk >> preScaleCode,
+    pmr,
+    mcf52235_tc_get_timecount
+  );
+}
+
+#define Clock_driver_timecounter_tick() mcf52235_tc_tick()
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/m68k/mcf5225x/clock/clock.c
===================================================================
--- bsps/m68k/mcf5225x/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/m68k/mcf5225x/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,106 @@
+/*
+ * Use the last periodic interval timer (PIT2) as the system clock.
+ */
+
+#include <rtems.h>
+#include <rtems/timecounter.h>
+#include <bsp.h>
+
+/*
+ * Use INTC0 base
+ */
+#define CLOCK_VECTOR (64+56)
+
+static rtems_timecounter_simple mcf5225x_tc;
+
+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 rtems_timecounter_simple_downcounter_get(
+    tc,
+    mcf5225x_tc_get,
+    mcf5225x_tc_is_pending
+  );
+}
+
+static void mcf5225x_tc_at_tick(rtems_timecounter_simple *tc)
+{
+  MCF_PIT1_PCSR |= MCF_PIT_PCSR_PIF;
+}
+
+static void mcf5225x_tc_tick(void)
+{
+  rtems_timecounter_simple_downcounter_tick(
+    &mcf5225x_tc,
+    mcf5225x_tc_get,
+    mcf5225x_tc_at_tick
+  );
+}
+
+/*
+ * Attach clock interrupt handler
+ */
+#define Clock_driver_support_install_isr( _new ) \
+  set_vector(_new, CLOCK_VECTOR, 1)
+
+/*
+ * Turn off the clock
+ */
+#define Clock_driver_support_shutdown_hardware() \
+  do { \
+    MCF_PIT1_PCSR &= ~MCF_PIT_PCSR_EN; \
+  } while (0)
+
+/*
+ * Set up the clock hardware
+ *
+ * We need to have 1 interrupt every BSP_rtems_configuration_get_microseconds_per_tick()
+ */
+static void Clock_driver_support_initialize_hardware(void)
+{
+  int level;
+  uint32_t pmr;
+  uint32_t preScaleCode = 0;
+  uint32_t clk = bsp_get_CPU_clock_speed() >> 1;
+  uint32_t tps = 1000000 / rtems_configuration_get_microseconds_per_tick();
+
+  while (preScaleCode < 15) {
+    pmr = (clk >> preScaleCode) / tps;
+    if (pmr < (1 << 15))
+      break;
+    preScaleCode++;
+  }
+
+  MCF_INTC0_ICR56 = MCF_INTC_ICR_IL(PIT3_IRQ_LEVEL) |
+    MCF_INTC_ICR_IP(PIT3_IRQ_PRIORITY);
+  rtems_interrupt_disable(level);
+  MCF_INTC0_IMRH &= ~MCF_INTC_IMRH_MASK56;
+  MCF_PIT1_PCSR &= ~MCF_PIT_PCSR_EN;
+  rtems_interrupt_enable(level);
+
+  MCF_PIT1_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) |
+    MCF_PIT_PCSR_OVW | MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD;
+  MCF_PIT1_PMR = pmr;
+  MCF_PIT1_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) |
+    MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_EN;
+
+  rtems_timecounter_simple_install(
+    &mcf5225x_tc,
+    clk >> preScaleCode,
+    pmr,
+    mcf5225x_tc_get_timecount
+  );
+}
+
+#define Clock_driver_timecounter_tick() mcf5225x_tc_tick()
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/m68k/mcf5235/clock/clock.c
===================================================================
--- bsps/m68k/mcf5235/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/m68k/mcf5235/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,61 @@
+/*
+ * Use the last periodic interval timer (PIT3) as the system clock.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <mcf5235/mcf5235.h>
+
+/*
+ * Use INTC0 base
+ */
+#define CLOCK_VECTOR (64+39)
+
+/*
+ * Periodic interval timer interrupt handler
+ */
+#define Clock_driver_support_at_tick()             \
+    do {                                           \
+        MCF5235_PIT_PCSR3 |= MCF5235_PIT_PCSR_PIF; \
+    } while (0)                                    \
+
+/*
+ * Attach clock interrupt handler
+ */
+#define Clock_driver_support_install_isr( _new ) \
+    set_vector(_new, CLOCK_VECTOR, 1)
+
+/*
+ * Turn off the clock
+ */
+#define Clock_driver_support_shutdown_hardware()   \
+    do {                                           \
+        MCF5235_PIT_PCSR3 &= ~MCF5235_PIT_PCSR_EN; \
+    } while(0)
+
+/*
+ * Set up the clock hardware
+ *
+ * We need to have 1 interrupt every 10,000 microseconds
+ * so we need to set prescaler to 64 and the PMR register to 0x2DC6
+ */
+#define Clock_driver_support_initialize_hardware()                       \
+    do {                                                                 \
+        int level;                                                       \
+        int preScaleCode = 6;                                            \
+        MCF5235_INTC0_ICR39 = MCF5235_INTC_ICR_IL(PIT3_IRQ_LEVEL) |      \
+                              MCF5235_INTC_ICR_IP(PIT3_IRQ_PRIORITY);    \
+        rtems_interrupt_disable( level );                                \
+        MCF5235_INTC0_IMRH &= ~MCF5235_INTC0_IMRH_INT39;                  \
+	MCF5235_PIT_PCSR3 &= ~MCF5235_PIT_PCSR_EN;               \
+        rtems_interrupt_enable( level );                                 \
+		MCF5235_PIT_PMR3 = 0x2DC6;                               \
+		MCF5235_PIT_PCSR3 = MCF5235_PIT_PCSR_PRE(preScaleCode) | \
+                            MCF5235_PIT_PCSR_PIE |                       \
+                            MCF5235_PIT_PCSR_RLD |                       \
+                            MCF5235_PIT_PCSR_EN;                         \
+    } while (0)
+
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/m68k/mcf5329/clock/clock.c
===================================================================
--- bsps/m68k/mcf5329/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/m68k/mcf5329/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,105 @@
+/*
+ * Use the last periodic interval timer (PIT2) as the system clock.
+ */
+
+#include <rtems.h>
+#include <rtems/timecounter.h>
+#include <bsp.h>
+
+/*
+ * Use INTC1 base
+ */
+#define CLOCK_VECTOR (128+46)
+
+static rtems_timecounter_simple mcf5329_tc;
+
+static uint32_t mcf5329_tc_get(rtems_timecounter_simple *tc)
+{
+  return MCF_PIT3_PCNTR;
+}
+
+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
+  );
+}
+
+static void mcf5329_tc_at_tick(rtems_timecounter_simple *tc)
+{
+  MCF_PIT3_PCSR |= MCF_PIT_PCSR_PIF;
+}
+
+static void mcf5329_tc_tick(void)
+{
+  rtems_timecounter_simple_downcounter_tick(
+    &mcf5329_tc,
+    mcf5329_tc_get,
+    mcf5329_tc_at_tick
+  );
+}
+
+/*
+ * Attach clock interrupt handler
+ */
+#define Clock_driver_support_install_isr( _new ) \
+  set_vector(_new, CLOCK_VECTOR, 1)
+
+/*
+ * Turn off the clock
+ */
+#define Clock_driver_support_shutdown_hardware() \
+  do { \
+    MCF_PIT3_PCSR &= ~MCF_PIT_PCSR_EN; \
+  } while (0)
+
+/*
+ * Set up the clock hardware
+ *
+ * We need to have 1 interrupt every rtems_configuration_get_microseconds_per_tick()
+ */
+static void Clock_driver_support_initialize_hardware(void)
+{
+  int level;
+  uint32_t pmr;
+  uint32_t preScaleCode = 0;
+  uint32_t clk = bsp_get_BUS_clock_speed();
+  uint32_t tps = 1000000 / rtems_configuration_get_microseconds_per_tick();
+
+  while (preScaleCode < 15) {
+    pmr = (clk >> preScaleCode) / tps;
+    if (pmr < (1 << 15))
+      break;
+    preScaleCode++;
+  }
+  MCF_INTC1_ICR46 = MCF_INTC_ICR_IL(PIT3_IRQ_LEVEL);
+
+  rtems_interrupt_disable(level);
+  MCF_INTC1_IMRH &= ~MCF_INTC_IMRH_INT_MASK46;
+  MCF_PIT3_PCSR &= ~MCF_PIT_PCSR_EN;
+  rtems_interrupt_enable(level);
+
+  MCF_PIT3_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) |
+    MCF_PIT_PCSR_OVW | MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD;
+  MCF_PIT3_PMR = pmr;
+  MCF_PIT3_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) |
+    MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_EN;
+
+  rtems_timecounter_simple_install(
+    &mcf5329_tc,
+    clk >> preScaleCode,
+    pmr,
+    mcf5329_tc_get_timecount
+  );
+}
+
+#define Clock_driver_timecounter_tick() mcf5329_tc_tick()
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/m68k/mrm332/clock/ckinit.c
===================================================================
--- bsps/m68k/mrm332/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/m68k/mrm332/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,75 @@
+/*
+ *  This routine initailizes the periodic interrupt timer on
+ *  the Motorola 68332.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2014.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdlib.h>
+#include <bsp.h>
+#include <mrm332.h>
+#include <rtems/clockdrv.h>
+#include <rtems/m68k/sim.h>
+
+#define CLOCK_VECTOR   MRM_PIV
+
+uint32_t                Clock_isrs;         /* ISRs until next tick */
+volatile uint32_t       Clock_driver_ticks; /* ticks since initialization */
+static rtems_isr_entry  Old_ticker;
+
+void Clock_exit( void );
+
+static rtems_isr Clock_isr(rtems_vector_number vector)
+{
+  Clock_driver_ticks += 1;
+
+  if ( Clock_isrs == 1 ) {
+    rtems_clock_tick();
+    Clock_isrs = rtems_configuration_get_microseconds_per_tick() / 1000;
+  }
+  else
+    Clock_isrs -= 1;
+}
+
+static void Install_clock(rtems_isr_entry clock_isr)
+{
+  Clock_driver_ticks = 0;
+  Clock_isrs = rtems_configuration_get_microseconds_per_tick() / 1000;
+
+  Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 );
+
+  /* enable 1mS interrupts */
+  *PITR = (unsigned short int)( SAM(0x09,0,PITM) );/* load counter */
+  *PICR = (unsigned short int)                     /* enable interrupt */
+    ( SAM(ISRL_PIT,8,PIRQL) | SAM(CLOCK_VECTOR,0,PIV) );
+
+  atexit( Clock_exit );
+}
+
+void Clock_exit( void )
+{
+  /* shutdown the periodic interrupt */
+  *PICR = (unsigned short int)
+    ( SAM(0,8,PIRQL) | SAM(CLOCK_VECTOR,0,PIV) );
+  /*     ^^ zero disables interrupt */
+
+  /* do not restore old vector */
+}
+
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  Install_clock( Clock_isr );
+
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/m68k/mvme147/clock/ckinit.c
===================================================================
--- bsps/m68k/mvme147/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/m68k/mvme147/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,82 @@
+/*
+ *  This routine initializes the Tick Timer 2 on the MVME147 board.
+ *  The tick frequency is 1 millisecond.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ *  MVME147 port for TNI - Telecom Bretagne
+ *  by Dominique LE CAMPION (Dominique.LECAMPION@enst-bretagne.fr)
+ *  May 1996
+ */
+
+#include <stdlib.h>
+
+#include <bsp.h>
+#include <rtems/clockdrv.h>
+
+#define MS_COUNT          65376    /* 1ms */
+/* MS_COUNT = 0x10000 - 1e-3/6.25e-6 */
+#define CLOCK_INT_LEVEL   6               /* T2's interrupt level */
+
+uint32_t         Clock_isrs;                  /* ISRs until next tick */
+volatile uint32_t         Clock_driver_ticks; /* ticks since initialization */
+rtems_isr_entry  Old_ticker;
+
+void Clock_exit( void );
+
+/*
+ *  ISR Handler
+ */
+static rtems_isr Clock_isr(rtems_vector_number vector)
+{
+  Clock_driver_ticks += 1;
+  pcc->timer2_int_control |= 0x80; /* Acknowledge interr. */
+
+  if (Clock_isrs == 1) {
+    rtems_clock_tick();
+    Clock_isrs = rtems_configuration_get_microseconds_per_tick() / 1000;
+  }
+  else
+    Clock_isrs -= 1;
+}
+
+static void Install_clock(rtems_isr_entry clock_isr )
+{
+
+  Clock_driver_ticks = 0;
+  Clock_isrs = rtems_configuration_get_microseconds_per_tick() / 1000;
+
+  Old_ticker = (rtems_isr_entry) set_vector( clock_isr, TIMER_2_VECTOR, 1 );
+
+  pcc->timer2_int_control = 0x00; /* Disable T2 Interr. */
+  pcc->timer2_preload = MS_COUNT;
+  /* write preload value */
+  pcc->timer2_control = 0x07; /* clear T2 overflow counter, enable counter */
+  pcc->timer2_int_control = CLOCK_INT_LEVEL|0x08;
+  /* Enable Timer 2 and set its int. level */
+
+  atexit( Clock_exit );
+}
+
+void Clock_exit( void )
+{
+  pcc->timer2_int_control = 0x00; /* Disable T2 Interr. */
+}
+
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  Install_clock( Clock_isr );
+
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/m68k/mvme162/clock/ckinit.c
===================================================================
--- bsps/m68k/mvme162/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/m68k/mvme162/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,89 @@
+/*
+ *  This routine initializes the Tick Timer 2 on the MVME162 board.
+ *  The tick frequency is 1 millisecond.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ *  Modifications of respective RTEMS file: COPYRIGHT (c) 1994.
+ *  EISCAT Scientific Association. M.Savitski
+ *
+ *  This material is a part of the MVME162 Board Support Package
+ *  for the RTEMS executive. Its licensing policies are those of the
+ *  RTEMS above.
+ */
+
+#include <stdlib.h>
+
+#include <bsp.h>
+#include <rtems/clockdrv.h>
+
+#define MS_COUNT          1000            /* T2's countdown constant (1 ms) */
+#define CLOCK_INT_LEVEL   6               /* T2's interrupt level */
+
+uint32_t         Clock_isrs;                  /* ISRs until next tick */
+volatile uint32_t         Clock_driver_ticks; /* ticks since initialization */
+rtems_isr_entry  Old_ticker;
+
+void Clock_exit( void );
+
+#define CLOCK_VECTOR (VBR0 * 0x10 + 0x9)
+
+/*
+ *  ISR Handler
+ */
+static rtems_isr Clock_isr(rtems_vector_number vector)
+{
+  Clock_driver_ticks += 1;
+  lcsr->timer_cnt_2 = 0;            /* clear counter */
+  lcsr->intr_clear |= 0x02000000;
+
+  if ( Clock_isrs == 1 ) {
+    rtems_clock_tick();
+    Clock_isrs = rtems_configuration_get_microseconds_per_tick() / 1000;
+  }
+  else
+    Clock_isrs -= 1;
+}
+
+static void Install_clock(rtems_isr_entry clock_isr )
+{
+
+  Clock_driver_ticks = 0;
+  Clock_isrs = rtems_configuration_get_microseconds_per_tick() / 1000;
+
+  Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 );
+  lcsr->vector_base |= MASK_INT;   /* unmask VMEchip2 interrupts */
+  lcsr->to_ctl = 0xE7;             /* prescaler to 1 MHz (see Appendix A1) */
+  lcsr->timer_cmp_2 = MS_COUNT;
+  lcsr->timer_cnt_2 = 0;           /* clear counter */
+  lcsr->board_ctl |= 0x700;        /* increment, reset-on-compare, and */
+                                   /*   clear-overflow-cnt */
+
+  lcsr->intr_level[0] |= CLOCK_INT_LEVEL * 0x10;      /* set int level */
+  lcsr->intr_ena |= 0x02000000;       /* enable tick timer 2 interrupt */
+
+  atexit( Clock_exit );
+}
+
+void Clock_exit( void )
+{
+/* Dummy for now. See other m68k BSP's for code examples */
+}
+
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  Install_clock( Clock_isr );
+
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/m68k/mvme167/clock/ckinit.c
===================================================================
--- bsps/m68k/mvme167/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/m68k/mvme167/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,159 @@
+/*
+ *  Implementation of the Clock_initialize() functions
+ *  prototyped in rtems/c/src/lib/include/clockdrv.h.
+ *
+ *  This port does not allow the application to select which timer on the
+ *  MVME167 to use for the clock, nor does it allow the application to
+ *  configure the clock. The clock uses the VMEchip2 Tick Timer #2. This
+ *  timer is set up to raise a MC680x0 level-6 interrupt every 1 ms. The
+ *  interrupt vector is 0x69.
+ *
+ *  All page references are to the MVME166/MVME167/MVME187 Single Board
+ *  Computer Programmer's Reference Guide (MVME187PG/D2) with the April
+ *  1993 supplements/addenda (MVME187PG/D2A1).
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ *  Modifications of respective RTEMS files:
+ *  Copyright (c) 1998, National Research Council of Canada
+ */
+
+#include <stdlib.h>
+#include <bsp.h>
+#include <rtems/clockdrv.h>
+
+#define MS_COUNT          1000              /* T2's countdown constant (1 ms) */
+#define CLOCK_INT_LEVEL   6                 /* T2's interrupt level */
+#define CLOCK_VECTOR (VBR0 * 0x10 + 0x9)    /* T2 is vector $X9 (p. 2-71)*/
+
+/*
+ *  Clock_driver_ticks is a monotonically increasing counter of the number of
+ *  VMEchip2 timer #2 ticks since the driver was initialized.
+ */
+volatile uint32_t Clock_driver_ticks;
+
+/*
+ *  Clock_isrs is the number of clock ISRs until the next invocation of the
+ *  RTEMS clock tick routine. This clock tick device driver gets an interrupt
+ *  once a millisecond and counts down until the length of time between the
+ *  user configured microseconds per tick has passed. This allows the clock
+ *  device to "tick" faster than the kernel clock. Of course, the kernel clock
+ *  cannot tick faster than the hardware clock. Therefore, the kernel clock
+ *  ticks cannot occur more frequently than every 1 millisecond.
+ */
+uint32_t         Clock_isrs;
+
+/*
+ *  Records the previous clock ISR (should be NULL)
+ */
+rtems_isr_entry  Old_ticker;
+
+/*
+ *  Called when the kernel exits.
+ */
+void clock_exit( void );
+
+/*
+ *  VMEchip2_T2_isr
+ *
+ *  C ISR Handler. Increment the number of internal ticks. If it is time for a
+ *  kernel clock tick (if Clock_isrs == 1), call rtems_clock_tick() to signal
+ *  the event and reset the Clock_isrs counter; else, just decrement it.
+ */
+static rtems_isr VMEchip2_T2_isr(
+  rtems_vector_number vector
+)
+{
+  char overflow;                /* Content of overflow counter */
+  long i;
+  long ct;                      /* Number of T2 ticks per RTEMS ticks */
+
+  ct = rtems_configuration_get_microseconds_per_tick() / 1000;
+
+  /*
+   *  May have missed interrupts, so should look at the overflow counter.
+   */
+  lcsr->intr_clear |= 0x02000000;   /* Clear the interrupt */
+  overflow = (lcsr->board_ctl >> 12) & 0xF;
+  lcsr->board_ctl |= 0x400;         /* Reset overflow counter */
+
+  /* Attempt to protect against one more period */
+  if ( overflow == 0 )
+    overflow = 16;
+
+  Clock_driver_ticks += overflow;   /* One or more internal ticks */
+
+  if ( Clock_isrs <= overflow ) {
+    /* If its time for kernel clock ticks, signal the events to RTEMS */
+    for( i = overflow - Clock_isrs; i >= 0; i -= ct ) {
+      rtems_clock_tick();
+    }
+    /* Reset the counter */
+    Clock_isrs = (uint32_t)-i;
+  }
+  else
+    Clock_isrs -= overflow;
+}
+
+/*
+ *  VMEchip2_T2_initialize
+ *
+ *  Initialize the VMEchip2 Tick Timer #2.
+ *
+ *  THE VMECHIP2 PRESCALER REGISTER IS ASSUMED TO BE SET!
+ *  The prescaler is used by all VMEchip2 timers, including the VMEbus grant
+ *  timeout counter, the DMAC time off timer, the DMAC timer on timer, and the
+ *  VMEbus global timeout timer. The prescaler value is normally set by the
+ *  boot ROM to provide a 1 MHz clock to the timers. For a 25 MHz MVME167, the
+ *  prescaler value should be 0xE7 (page 2-63).
+ */
+static void VMEchip2_T2_initialize( void )
+{
+  Clock_driver_ticks = 0;
+  Clock_isrs = rtems_configuration_get_microseconds_per_tick() / 1000;
+
+  lcsr->intr_ena &= 0xFDFFFFFF;   /* Disable tick timer 2 interrupt */
+  lcsr->intr_clear = 0x02000000;  /* Clear tick timer 2 interrupt */
+  lcsr->intr_level[0] =           /* Set tick timer 2 interrupt level */
+      (lcsr->intr_level[0] & 0xFFFFFF0F ) | (CLOCK_INT_LEVEL << 4);
+  lcsr->timer_cmp_2 = MS_COUNT;   /* Period in compare register */
+  lcsr->timer_cnt_2 = 0;          /* Clear tick timer 2 counter */
+  Old_ticker =                    /* Install C ISR */
+      (rtems_isr_entry) set_vector( VMEchip2_T2_isr, CLOCK_VECTOR, 1 );
+  lcsr->board_ctl |= 0x700;       /* Start tick timer 2, reset-on-compare, */
+                                  /*  and clear tick timer 2 overflow counter */
+  lcsr->intr_ena |= 0x02000000;   /* Enable tick timer 2 interrupt */
+  lcsr->vector_base |= 0x00800000;/* Unmask VMEchip2 interrupts */
+  atexit( clock_exit );           /* Turn off T2 interrupts when we exit */
+}
+
+/*
+ *  This routine stops the VMEchip2 T2 timer, disables its interrupt, and
+ *  re-install the old interrupt vectors.
+ */
+void clock_exit( void )
+{
+  lcsr->board_ctl &= 0xFFFFFEFF;  /* Stop tick timer 2 */
+  lcsr->intr_ena &= 0xFDFFFFFF;   /* Disable tick timer 2 interrupt */
+  lcsr->intr_clear = 0x02000000;  /* Clear tick timer 2 interrupt */
+
+  set_vector( Old_ticker, CLOCK_VECTOR, 1 );
+}
+
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  VMEchip2_T2_initialize();
+
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/m68k/uC5282/clock/clock.c
===================================================================
--- bsps/m68k/uC5282/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/m68k/uC5282/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,161 @@
+/*
+ * Use the last periodic interval timer (PIT3) as the system clock.
+ *
+ *  Author: W. Eric Norum <norume@aps.anl.gov>
+ *
+ *  COPYRIGHT (c) 2005.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <rtems/timecounter.h>
+#include <bsp.h>
+#include <mcf5282/mcf5282.h>
+
+/*
+ * CPU load counters
+ * Place in static RAM so updates don't hit the SDRAM
+ */
+#define IDLE_COUNTER    __SRAMBASE.idle_counter
+#define FILTERED_IDLE   __SRAMBASE.filtered_idle
+#define MAX_IDLE_COUNT  __SRAMBASE.max_idle_count
+#define PITC_PER_TICK   __SRAMBASE.pitc_per_tick
+#define NSEC_PER_PITC   __SRAMBASE.nsec_per_pitc
+#define FILTER_SHIFT    6
+
+/*
+ * Use INTC0 base
+ */
+#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_at_tick(rtems_timecounter_simple *tc)
+{
+  unsigned idle = IDLE_COUNTER;
+  IDLE_COUNTER = 0;
+  if (idle > MAX_IDLE_COUNT)
+    MAX_IDLE_COUNT = idle;
+  FILTERED_IDLE = idle + FILTERED_IDLE - (FILTERED_IDLE>>FILTER_SHIFT);
+  MCF5282_PIT3_PCSR |= MCF5282_PIT_PCSR_PIF;
+}
+
+static void uC5282_tc_tick(void)
+{
+  rtems_timecounter_simple_downcounter_tick(
+    &uC5282_tc,
+    uC5282_tc_get,
+    uC5282_tc_at_tick
+  );
+}
+
+/*
+ * Attach clock interrupt handler
+ */
+#define Clock_driver_support_install_isr( _new ) \
+    set_vector(_new, CLOCK_VECTOR, 1)
+
+/*
+ * Turn off the clock
+ */
+#define Clock_driver_support_shutdown_hardware()   \
+    do {                                           \
+        MCF5282_PIT3_PCSR &= ~MCF5282_PIT_PCSR_EN; \
+    } while(0)
+
+/*
+ * Set up the clock hardware
+ *
+ * f_pit = f_clk / 2^(preScaleCode+1) / N  = 1/(us_per_tick/us_per_s)
+ *
+ * N = f_clk / 2^(preScaleCode+1) * us_per_tick / us_per_s
+ *
+ * ns_per_pit_clk = ns_per_s / (f_clk / 2^(preScaleCode+1))
+ *                = ns_per_s * 2^(preScaleCode+1) / f_clk;
+ */
+#define Clock_driver_support_initialize_hardware()                       \
+    do {                                                                 \
+        unsigned long long N;                                            \
+        int level;                                                       \
+        int preScaleCode = 0;                                            \
+		N  = bsp_get_CPU_clock_speed();                                  \
+		N *= rtems_configuration_get_microseconds_per_tick();            \
+		N /= 2*1000000; /* min_prescale * us_per_s */                    \
+		while ( N > 0x10000 ) {                                          \
+			preScaleCode++;                                              \
+			N >>= 1;                                                     \
+		}                                                                \
+		PITC_PER_TICK  = N;                                              \
+		N  = 2000000000ULL << preScaleCode;                              \
+		N /= bsp_get_CPU_clock_speed();                                  \
+		NSEC_PER_PITC  = N;                                              \
+        IDLE_COUNTER   = 0;                                              \
+        FILTERED_IDLE  = 0;                                              \
+        MAX_IDLE_COUNT = 0;                                              \
+        bsp_allocate_interrupt(PIT3_IRQ_LEVEL, PIT3_IRQ_PRIORITY);       \
+        MCF5282_INTC0_ICR58 = MCF5282_INTC_ICR_IL(PIT3_IRQ_LEVEL) |      \
+                              MCF5282_INTC_ICR_IP(PIT3_IRQ_PRIORITY);    \
+        rtems_interrupt_disable( level );                                \
+        MCF5282_INTC0_IMRH &= ~MCF5282_INTC_IMRH_INT58;                  \
+        MCF5282_PIT3_PCSR &= ~MCF5282_PIT_PCSR_EN;                       \
+        rtems_interrupt_enable( level );                                 \
+        MCF5282_PIT3_PCSR = MCF5282_PIT_PCSR_PRE(preScaleCode) |         \
+                            MCF5282_PIT_PCSR_OVW |                       \
+                            MCF5282_PIT_PCSR_PIE |                       \
+                            MCF5282_PIT_PCSR_RLD;                        \
+        MCF5282_PIT3_PMR = PITC_PER_TICK - 1;                            \
+        MCF5282_PIT3_PCSR = MCF5282_PIT_PCSR_PRE(preScaleCode) |         \
+                            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)
+
+/*
+ * Provide our own version of the idle task
+ */
+void * bsp_idle_thread(uint32_t ignored)
+{
+  /* Atomic increment */
+  for(;;)
+    __asm__ volatile ("addq.l #1,%0"::"m"(IDLE_COUNTER));
+}
+
+int bsp_cpu_load_percentage(void)
+{
+    return MAX_IDLE_COUNT ?
+           (100 - ((100 * (FILTERED_IDLE >> FILTER_SHIFT)) / MAX_IDLE_COUNT)) :
+           0;
+}
+
+#define Clock_driver_timecounter_tick() uC5282_tc_tick()
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/mips/csb350/clock/clockdrv.c
===================================================================
--- bsps/mips/csb350/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/mips/csb350/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,90 @@
+/**
+ *  @file
+ *  
+ *  Instantiate the clock driver shell.
+ *
+ *  This uses the TOY (Time of Year) timer to implement the clock.
+ */
+
+/*
+ *  Copyright (c) 2005 by Cogent Computer Systems
+ *  Written by Jay Monkman <jtm@lopingdog.com>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <rtems/bspIo.h>
+
+uint32_t tick_interval;
+uint32_t last_match;
+
+void au1x00_clock_init(void);
+
+#define CLOCK_VECTOR AU1X00_IRQ_TOY_MATCH2
+
+#define Clock_driver_support_at_tick()                        \
+  do {                                                        \
+    while (AU1X00_SYS_CNTCTRL(AU1X00_SYS_ADDR) & AU1X00_SYS_CNTCTRL_TM0); \
+    last_match = AU1X00_SYS_TOYREAD(AU1X00_SYS_ADDR); \
+    AU1X00_SYS_TOYMATCH2(AU1X00_SYS_ADDR) = last_match + tick_interval; \
+    au_sync(); \
+  } while(0)
+
+/* Set for rising edge interrupt */
+#define Clock_driver_support_install_isr( _new ) \
+  do { \
+    rtems_interrupt_handler_install( \
+      CLOCK_VECTOR, \
+      "clock", \
+      0, \
+      _new, \
+      NULL \
+    ); \
+    AU1X00_IC_MASKCLR(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \
+    AU1X00_IC_SRCSET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \
+    AU1X00_IC_CFG0SET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \
+    AU1X00_IC_CFG1CLR(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \
+    AU1X00_IC_CFG2CLR(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \
+    AU1X00_IC_ASSIGNSET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2; \
+  } while(0)
+
+void au1x00_clock_init(void)
+{
+    uint32_t wakemask;
+    /* Clear the trim register */
+    AU1X00_SYS_TOYTRIM(AU1X00_SYS_ADDR) = 0;
+
+    /* Clear the TOY counter */
+    while (AU1X00_SYS_CNTCTRL(AU1X00_SYS_ADDR) & AU1X00_SYS_CNTCTRL_TS);
+    AU1X00_SYS_TOYWRITE(AU1X00_SYS_ADDR) = 0;
+    while (AU1X00_SYS_CNTCTRL(AU1X00_SYS_ADDR) & AU1X00_SYS_CNTCTRL_TS);
+
+    wakemask = AU1X00_SYS_WAKEMSK(AU1X00_SYS_ADDR);
+    wakemask |= AU1X00_SYS_WAKEMSK_M20;
+    AU1X00_SYS_WAKEMSK(AU1X00_SYS_ADDR) = wakemask;
+    AU1X00_IC_WAKESET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2;
+
+    tick_interval = 32768 * rtems_configuration_get_microseconds_per_tick();
+    tick_interval = tick_interval / 1000000;
+
+    last_match = AU1X00_SYS_TOYREAD(AU1X00_SYS_ADDR);
+    AU1X00_SYS_TOYMATCH2(AU1X00_SYS_ADDR) = last_match + (50*tick_interval);
+    AU1X00_IC_MASKSET(AU1X00_IC0_ADDR) = AU1X00_IC_IRQ_TOY_MATCH2;
+    while (AU1X00_SYS_CNTCTRL(AU1X00_SYS_ADDR) & AU1X00_SYS_CNTCTRL_TM0);
+}
+
+#define Clock_driver_support_initialize_hardware() \
+  do {                                                  \
+     au1x00_clock_init(); \
+  } while(0)
+
+#define Clock_driver_support_shutdown_hardware()
+
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/mips/hurricane/clock/ckinit.c
===================================================================
--- bsps/mips/hurricane/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/mips/hurricane/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,219 @@
+/**
+ *  @file
+ *  
+ *  This file contains the clock driver initialization for the Hurricane BSP.
+ */
+
+/*
+ *  Author:     Craig Lebakken <craigl@transition.com>
+ *
+ *  COPYRIGHT (c) 1996 by Transition Networks Inc.
+ *
+ *  To anyone who acknowledges that this file is provided "AS IS"
+ *  without any express or implied warranty:
+ *      permission to use, copy, modify, and distribute this file
+ *      for any purpose is hereby granted without fee, provided that
+ *      the above copyright notice and this notice appears in all
+ *      copies, and that the name of Transition Networks not be used in
+ *      advertising or publicity pertaining to distribution of the
+ *      software without specific, written prior permission.
+ *      Transition Networks makes no representations about the suitability
+ *      of this software for any purpose.
+ *
+ *  Derived from c/src/lib/libbsp/no_cpu/no_bsp/clock/ckinit.c
+ *
+ *  COPYRIGHT (c) 1989-2012.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+/*
+ *  Rather than deleting this, it is commented out to (hopefully) help
+ *  the submitter send updates.
+ *
+ *  static char _sccsid[] = "@(#)ckinit.c 08/20/96     1.3\n";
+ */
+
+
+#include <stdlib.h>
+
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <rtems/clockdrv.h>
+
+extern uint32_t bsp_clicks_per_microsecond;
+
+#define EXT_INT1    0x800  /* external interrupt 5 */
+
+#include "clock.h"
+
+rtems_isr USC_isr(void *unused);
+
+void reset_wdt(void);
+void enable_wdi(void);
+void init_hbt(void);
+void enable_hbi(void);
+void disable_hbi(void);
+
+void Clock_exit(void);
+rtems_isr Clock_isr(rtems_vector_number vector);
+rtems_isr User_Clock_isr(rtems_vector_number vector);
+void Install_clock(rtems_isr_entry clock_isr);
+
+
+/*
+ *  The interrupt vector number associated with the clock tick device
+ *  driver.
+ */
+
+#define CLOCK_VECTOR_MASK    EXT_INT1
+#define CLOCK_VECTOR         MIPS_INTERRUPT_BASE + 0x3
+
+/*
+ *  Clock_driver_ticks is a monotonically increasing counter of the
+ *  number of clock ticks since the driver was initialized.
+ */
+
+volatile uint32_t Clock_driver_ticks;
+
+/*
+ *  Clock_isrs is the number of clock ISRs until the next invocation of
+ *  the RTEMS clock tick routine.  The clock tick device driver
+ *  gets an interrupt once a millisecond and counts down until the
+ *  length of time between the user configured microseconds per tick
+ *  has passed.
+ */
+
+uint32_t Clock_isrs;              /* ISRs until next tick */
+
+/*
+ *  The previous ISR on this clock tick interrupt vector.
+ */
+
+rtems_isr_entry  Old_ticker;
+
+void Clock_exit( void );
+
+static uint32_t mips_timer_rate = 0;
+
+/*
+ *  Isr Handler
+ */
+
+rtems_isr Clock_isr(
+  rtems_vector_number vector
+)
+{
+/*
+ * bump the number of clock driver ticks since initialization
+ *
+ * determine if it is time to announce the passing of tick as configured
+ * to RTEMS through the rtems_clock_tick directive
+ *
+ * perform any timer dependent tasks
+ */
+
+  reset_wdt();    /* Reset hardware watchdog timer */
+
+  Clock_driver_ticks += 1;
+
+  rtems_clock_tick();
+}
+
+/* User callback shell (set from Clock_Control) */
+static void (*user_callback)(void);
+
+rtems_isr User_Clock_isr(
+  rtems_vector_number vector
+)
+{
+   if (user_callback)
+      user_callback();
+}
+
+/*
+ *  Install_clock
+ *
+ *  Install a clock tick handleR and reprograms the chip.  This
+ *  is used to initially establish the clock tick.
+ */
+
+void Install_clock(
+  rtems_isr_entry clock_isr
+)
+{
+  /*
+  *  Initialize the clock tick device driver variables
+  */
+
+  Clock_driver_ticks = 0;
+  Clock_isrs = rtems_configuration_get_milliseconds_per_tick();
+
+  mips_timer_rate = rtems_configuration_get_microseconds_per_tick() *
+           bsp_clicks_per_microsecond;
+
+  /*
+  *  Hardware specific initialize goes here
+  */
+
+  /* Set up USC heartbeat timer to generate interrupts */
+  disable_hbi();      /* Disable heartbeat interrupt in USC */
+
+  /* Install interrupt handler */
+  rtems_interrupt_handler_install( 
+    CLOCK_VECTOR,
+    "clock",
+    0,
+    USC_isr,
+    NULL
+  );
+
+  init_hbt();        /* Initialize heartbeat timer */
+
+  reset_wdt();      /* Reset watchdog timer */
+
+  enable_wdi();      /* Enable watchdog interrupt in USC */
+
+  enable_hbi();      /* Enable heartbeat interrupt in USC */
+
+              /* Enable USC interrupt in MIPS processor */
+  mips_enable_in_interrupt_mask(CLOCK_VECTOR_MASK);
+
+  /*
+  *  Schedule the clock cleanup routine to execute if the application exits.
+  */
+
+  atexit( Clock_exit );
+}
+
+/*
+ *  Clean up before the application exits
+ */
+
+void Clock_exit( void )
+{
+  /* mips: turn off the timer interrupts */
+  mips_disable_in_interrupt_mask(~CLOCK_VECTOR_MASK);
+}
+
+/*
+ *  Clock_initialize
+ *
+ *  Device driver entry point for clock tick driver initialization.
+ */
+
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  Install_clock( Clock_isr );
+
+  return RTEMS_SUCCESSFUL;
+}
+
Index: bsps/mips/hurricane/clock/clock.S
===================================================================
--- bsps/mips/hurricane/clock/clock.S	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/mips/hurricane/clock/clock.S	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,42 @@
+/*  clock.s
+ *
+ *  This file contains the assembly code for the Hurricane BSP clock driver.
+ *
+ *  Author:     Craig Lebakken <craigl@transition.com>
+ *
+ *  COPYRIGHT (c) 1996 by Transition Networks Inc.
+ *
+ *  To anyone who acknowledges that this file is provided "AS IS"
+ *  without any express or implied warranty:
+ *      permission to use, copy, modify, and distribute this file
+ *      for any purpose is hereby granted without fee, provided that
+ *      the above copyright notice and this notice appears in all
+ *      copies, and that the name of Transition Networks not be used in
+ *      advertising or publicity pertaining to distribution of the
+ *      software without specific, written prior permission.
+ *      Transition Networks makes no representations about the suitability
+ *      of this software for any purpose.
+ */
+
+#include <iregdef.h>
+#include <idtcpu.h>
+#include <asm.h>
+
+FRAME(mips_set_timer,sp,0,ra)
+	.set noreorder
+        mfc0 t0,C0_COUNT
+        nop
+        addu t0,a0,t0
+        mtc0 t0,C0_COMPARE
+        j ra
+	nop
+	.set reorder
+ENDFRAME(mips_set_timer)
+
+FRAME(mips_get_timer,sp,0,ra)
+	.set noreorder
+        mfc0 v0,C0_COUNT
+        j ra
+	nop
+	.set reorder
+ENDFRAME(mips_get_timer)
Index: bsps/mips/hurricane/clock/clock.h
===================================================================
--- bsps/mips/hurricane/clock/clock.h	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/mips/hurricane/clock/clock.h	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,21 @@
+/*  clock.s
+ *
+ *  This file contains the assembly code for the Hurricane BSP clock driver.
+ *
+ *  Author:     Craig Lebakken <craigl@transition.com>
+ *
+ *  COPYRIGHT (c) 1996 by Transition Networks Inc.
+ *
+ *  To anyone who acknowledges that this file is provided "AS IS"
+ *  without any express or implied warranty:
+ *      permission to use, copy, modify, and distribute this file
+ *      for any purpose is hereby granted without fee, provided that
+ *      the above copyright notice and this notice appears in all
+ *      copies, and that the name of Transition Networks not be used in
+ *      advertising or publicity pertaining to distribution of the
+ *      software without specific, written prior permission.
+ *      Transition Networks makes no representations about the suitability
+ *      of this software for any purpose.
+ */
+
+extern void mips_set_timer( uint32_t timer_clock_interval );
Index: bsps/mips/jmr3904/clock/clockdrv.c
===================================================================
--- bsps/mips/jmr3904/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/mips/jmr3904/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,50 @@
+/**
+ *  @file
+ *  
+ *  Instantiate the clock driver shell.
+ *
+ *  The TX3904 simulator in gdb counts instructions.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+
+#define CLOCK_DRIVER_USE_FAST_IDLE 1
+
+#define CLOCK_VECTOR TX3904_IRQ_TMR0
+
+/*
+ *  5000 clicks per tick ISR is HIGHLY arbitrary
+ */
+
+#define CLICKS 5000
+
+#define Clock_driver_support_install_isr( _new ) \
+  rtems_interrupt_handler_install( CLOCK_VECTOR, "clock", 0, _new, NULL )
+
+#define Clock_driver_support_initialize_hardware() \
+  do { \
+    uint32_t   _clicks = CLICKS; \
+    TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_CCDR, 0x3 ); \
+    TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_CPRA, _clicks ); \
+    TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_TISR, 0x00 ); \
+    TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_ITMR, 0x8001 ); \
+    TX3904_TIMER_WRITE( TX3904_TIMER0_BASE, TX3904_TIMER_TCR,   0xC0 ); \
+    *((volatile uint32_t*) 0xFFFFC01C) = 0x00000700; \
+  } while(0)
+
+#define Clock_driver_support_shutdown_hardware()
+
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/mips/rbtx4925/clock/clockdrv.c
===================================================================
--- bsps/mips/rbtx4925/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/mips/rbtx4925/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,120 @@
+/**
+ *  @file
+ *  
+ *  Instantiate the clock driver shell.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+
+/* #define CLOCK_DRIVER_USE_FAST_IDLE 1 */
+
+#define CLOCK_VECTOR TX4925_IRQ_TMR0
+
+#define TX4925_TIMER_INTERVAL_MODE 1
+#define TX4925_TIMER_PULSE_MODE 2
+#define TX4925_TIMER_MODE TX4925_TIMER_INTERVAL_MODE
+
+#if (TX4925_TIMER_MODE == TX4925_TIMER_INTERVAL_MODE)
+#define TX4925_TIMER_INTERRUPT_FLAG TIIS
+#define Clock_driver_support_initialize_hardware() \
+          Initialize_timer0_in_interval_mode()
+#elif (TX4925_TIMER_MODE == TX4925_TIMER_PULSE_MODE)
+#define TX4925_TIMER_INTERRUPT_FLAG TPIBS
+#define Clock_driver_support_initialize_hardware() \
+          Initialize_timer0_in_pulse_mode()
+#else
+#error "Build Error: need to select timer mode"
+#endif
+
+
+#define Clock_driver_support_install_isr( _new ) \
+  rtems_interrupt_handler_install( CLOCK_VECTOR, "clock", 0, _new, NULL )
+
+
+#define Clock_driver_support_at_tick() \
+  do { \
+	uint32_t interrupt_flag; \
+  	do { \
+  		int loop_count; \
+  		TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TISR, 0x0 ); /* Clear timer 0 interrupt */ \
+    		loop_count = 0; \
+    		do { /* Wait until interrupt flag is cleared (this prevents re-entering interrupt) */ \
+    		 	/* Read back interrupt status register and isolate interval timer flag */ \
+    			interrupt_flag = TX4925_REG_READ( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TISR ) & TX4925_TIMER_INTERRUPT_FLAG; \
+    		} while (interrupt_flag && (++loop_count < 10)); /* Loop while timer interrupt bit is set, or loop count is lees than 10 */ \
+  	} while(interrupt_flag); \
+  } while(0)
+
+
+/* Setup timer in interval mode to generate peiodic interrupts */
+#define Initialize_timer0_in_interval_mode() \
+  do { \
+  	uint32_t temp; \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TCR, 0x0 ); /* Disable timer */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CCDR, 0x0 ); /* Set register for divide by 2 clock */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_ITMR, TIMER_CLEAR_ENABLE_MASK ); /* Set interval timer mode register */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CPRA, 0x30d40 ); /* Set tmier period ,10.0 msec (20 MHz timer clock) */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TCR, 0xC0 ); /* Enable timer in interval mode */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_DM0, 0x0 ); /* Set interrupt controller detection mode */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_LVL2, 0x1000000 ); /* Set interrupt controller level */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_MSK, 0x0 ); /* Set interrupt controller mask */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_DEN, 0x1 ); /* Enable interrupts from controller */ \
+    temp = TX4925_REG_READ( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_ITMR ); /* Enable interval timer interrupts */ \
+    temp |= TIMER_INT_ENABLE_MASK; \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_ITMR, temp ); \
+  } while(0)
+
+
+/* This mode is used to generate periodic interrupts and also output a pulse on PIO20 pin */
+#define Initialize_timer0_in_pulse_mode() \
+  do { \
+  	uint32_t temp; \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TCR, 0x0 ); /* Disable timer */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CCDR, 0x0 ); /* Set register for divide by 2 clock */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_PGMR, FFI ); /* Set pulse generator mode register */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CPRA, 0x3e8 ); /* Set pulse high duration ,0.05 msec (20 MHz timer clock) */ \
+/*    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CPRB, 0x1388 ); */ /* Set pulse total period, 0.25 msec (20 MHz timer clock) */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CPRB, 0x30d40 ); /* Set pulse total period, 10 msec (20 MHz timer clock) */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TCR, 0xC1 ); /* Enable timer in pulse generator mode */ \
+ \
+ 	/* Enable timer 0 output pulses on PIO20 */ \
+    temp = TX4925_REG_READ( TX4925_REG_BASE, TX4925_CFG_PCFG ); \
+    temp = (temp & ~ SELCHI) | SELTMR0;	/* Enable timer 0 pulses on PIO20 */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_CFG_PCFG, temp ); \
+ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_DM0, 0x0 ); /* Set interrupt controller detection mode */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_LVL2, 0x1000000 ); /* Set interrupt controller level */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_MSK, 0x0 ); /* Set interrupt controller mask */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_DEN, 0x1 ); /* Enable interrupts from controller */ \
+    temp = TX4925_REG_READ( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_PGMR ); /* Enable pulse generator interrupt */ \
+    temp |= TPIBE;	/* Only want interrupts on B compare (where clock count is cleared) */ \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_PGMR, temp ); \
+  } while(0)
+
+
+#define Clock_driver_support_shutdown_hardware() \
+  do { \
+  	uint32_t temp; \
+    temp = TX4925_REG_READ( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_ITMR ); /* Disable interval timer interrupt */ \
+    temp &= ~TIMER_INT_ENABLE_MASK; \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_ITMR, temp ); \
+    temp = TX4925_REG_READ( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_PGMR ); /* Disable pulse generator interrupt */ \
+    temp &= ~(TPIAE | TPIBE); \
+    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_PGMR, temp ); \
+    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/dev/clock/clockimpl.h"
Index: bsps/mips/rbtx4938/clock/clockdrv.c
===================================================================
--- bsps/mips/rbtx4938/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/mips/rbtx4938/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,119 @@
+/**
+ *  @file
+ *  
+ *  Instantiate the clock driver shell.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "yamon_api.h"
+
+
+/* #define CLOCK_DRIVER_USE_FAST_IDLE 1 */
+
+#define CLOCK_VECTOR TX4938_IRQ_TMR0
+
+#define TX4938_TIMER_INTERVAL_MODE 1
+
+#define TX4938_TIMER_MODE TX4938_TIMER_INTERVAL_MODE
+
+#if (TX4938_TIMER_MODE == TX4938_TIMER_INTERVAL_MODE)
+#define TX4938_TIMER_INTERRUPT_FLAG TIIS
+#define Clock_driver_support_initialize_hardware() \
+          Initialize_timer0_in_interval_mode()
+#else
+#error "Build Error: unsupported timer mode"
+#endif
+
+void new_brk_esr(void);
+
+t_yamon_retfunc esr_retfunc = 0;
+t_yamon_ref original_brk_esr = 0;
+t_yamon_ref original_tmr0_isr = 0;
+
+void new_brk_esr(void)
+{
+	if (original_tmr0_isr)
+	{
+		YAMON_FUNC_DEREGISTER_IC_ISR( original_tmr0_isr );
+		original_tmr0_isr = 0;
+	}
+	if (esr_retfunc)
+		esr_retfunc();
+}
+
+
+#define Clock_driver_support_install_isr( _new ) \
+  do { \
+    rtems_interrupt_handler_install( \
+      CLOCK_VECTOR, \
+      "clock", \
+      0, \
+      _new, \
+      NULL \
+    ); \
+    YAMON_FUNC_REGISTER_IC_ISR(17,(t_yamon_isr)_new,0,&original_tmr0_isr); /* Call Yamon to enable interrupt */ \
+  } while(0)
+
+
+#define Clock_driver_support_at_tick() \
+  do { \
+	uint32_t interrupt_flag; \
+  	do { \
+  		int loop_count; \
+  		TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_TISR, 0x0 ); /* Clear timer 0 interrupt */ \
+    		loop_count = 0; \
+    		do { /* Wait until interrupt flag is cleared (this prevents re-entering interrupt) */ \
+    		 	/* Read back interrupt status register and isolate interval timer flag */ \
+    			interrupt_flag = TX4938_REG_READ( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_TISR ) & TX4938_TIMER_INTERRUPT_FLAG; \
+    		} while (interrupt_flag && (++loop_count < 10)); /* Loop while timer interrupt bit is set, or loop count is lees than 10 */ \
+  	} while(interrupt_flag); \
+  } while(0)
+
+
+/* Setup timer in interval mode to generate peiodic interrupts */
+#define Initialize_timer0_in_interval_mode() \
+  do { \
+  	uint32_t temp; \
+    TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_TCR, 0x0 ); /* Disable timer */ \
+    TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_CCDR, 0x0 ); /* Set register for divide by 2 clock */ \
+    TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_ITMR, TIMER_CLEAR_ENABLE_MASK ); /* Set interval timer mode register */ \
+    TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_CPRA, 0x3d090 ); /* Set tmier period ,10.0 msec (25 MHz timer clock) */ \
+    TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_TCR, 0xC0 ); /* Enable timer in interval mode */ \
+    temp = TX4938_REG_READ( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_ITMR ); /* Enable interval timer interrupts */ \
+    temp |= TIMER_INT_ENABLE_MASK; \
+    TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_ITMR, temp ); \
+  } while(0)
+
+
+
+#define Clock_driver_support_shutdown_hardware() \
+  do { \
+  	uint32_t temp; \
+    temp = TX4938_REG_READ( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_ITMR ); /* Disable interval timer interrupt */ \
+    temp &= ~TIMER_INT_ENABLE_MASK; \
+    TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_ITMR, temp ); \
+    temp = TX4938_REG_READ( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_PGMR ); /* Disable pulse generator interrupt */ \
+    temp &= ~(TPIAE | TPIBE); \
+    TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_PGMR, temp ); \
+    TX4938_REG_WRITE( TX4938_REG_BASE, TX4938_TIMER0_BASE + TX4938_TIMER_TCR, 0x0 ); /* Disable timer */ \
+  } while(0)
+
+
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/mips/rbtx4938/clock/yamon_api.h
===================================================================
--- bsps/mips/rbtx4938/clock/yamon_api.h	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/mips/rbtx4938/clock/yamon_api.h	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,631 @@
+/************************************************************************
+ *
+ *  yamon_api.h
+ *
+ *  YAMON interface definitions
+ *
+ * ######################################################################
+ *
+ * mips_start_of_legal_notice
+ *
+ * Copyright (c) 2003 MIPS Technologies, Inc. All rights reserved.
+ *
+ *
+ * Unpublished rights (if any) reserved under the copyright laws of the
+ * United States of America and other countries.
+ *
+ * This code is proprietary to MIPS Technologies, Inc. ("MIPS
+ * Technologies"). Any copying, reproducing, modifying or use of this code
+ * (in whole or in part) that is not expressly permitted in writing by MIPS
+ * Technologies or an authorized third party is strictly prohibited. At a
+ * minimum, this code is protected under unfair competition and copyright
+ * laws. Violations thereof may result in criminal penalties and fines.
+ *
+ * MIPS Technologies reserves the right to change this code to improve
+ * function, design or otherwise. MIPS Technologies does not assume any
+ * liability arising out of the application or use of this code, or of any
+ * error or omission in such code. Any warranties, whether express,
+ * statutory, implied or otherwise, including but not limited to the implied
+ * warranties of merchantability or fitness for a particular purpose, are
+ * excluded. Except as expressly provided in any written license agreement
+ * from MIPS Technologies or an authorized third party, the furnishing of
+ * this code does not give recipient any license to any intellectual
+ * property rights, including any patent rights, that cover this code.
+ *
+ * This code shall not be exported or transferred for the purpose of
+ * reexporting in violation of any U.S. or non-U.S. regulation, treaty,
+ * Executive Order, law, statute, amendment or supplement thereto.
+ *
+ * This code constitutes one or more of the following: commercial computer
+ * software, commercial computer software documentation or other commercial
+ * items. If the user of this code, or any related documentation of any
+ * kind, including related technical data or manuals, is an agency,
+ * department, or other entity of the United States government
+ * ("Government"), the use, duplication, reproduction, release,
+ * modification, disclosure, or transfer of this code, or any related
+ * documentation of any kind, is restricted in accordance with Federal
+ * Acquisition Regulation 12.212 for civilian agencies and Defense Federal
+ * Acquisition Regulation Supplement 227.7202 for military agencies. The use
+ * of this code by the Government is further restricted in accordance with
+ * the terms of the license agreement(s) and/or applicable contract terms
+ * and conditions covering this code from MIPS Technologies or an authorized
+ * third party.
+ *
+ *
+ * mips_end_of_legal_notice
+ *
+ *
+ ************************************************************************/
+
+#ifndef YAMON_API_H
+#define YAMON_API_H
+
+/************************************************************************
+ *  Include files
+ ************************************************************************/
+
+
+/************************************************************************
+ *  Definitions
+*************************************************************************/
+
+/* Basic types */
+
+typedef unsigned int        t_yamon_uint32;
+typedef unsigned short      t_yamon_uint16;
+typedef unsigned char       t_yamon_uint8;
+typedef signed int	    t_yamon_int32;
+typedef signed short	    t_yamon_int16;
+typedef signed char	    t_yamon_int8;
+
+typedef unsigned char       t_yamon_bool;
+
+#define YAMON_FALSE	    0
+#define YAMON_TRUE	    (!YAMON_FALSE)
+
+/* YAMON Environment variable */
+typedef struct
+{
+    char *name;
+    char *val;
+}
+t_yamon_env_var;
+
+/* Format of application function */
+typedef t_yamon_uint32
+(*t_yamon_appl_main)(
+    t_yamon_uint32  argc,      /* Number of tokens in argv array	*/
+    char	    **argv,    /* Array of tokens (first is "go")	*/
+    t_yamon_env_var *env,      /* Array of env. variables		*/
+    t_yamon_uint32  memsize ); /* Size of memory (byte count)		*/
+
+
+/* ID of YAMON configuration object */
+typedef t_yamon_uint32 t_yamon_syscon_id;
+
+
+/*  Number used by the exception registration functions in order to register
+ *  a default ISR/ESR.
+ */
+#define YAMON_DEFAULT_HANDLER		    0xfffffff0
+
+/*  Number used by the exception registration functions in order to register
+ *  an EJTAG debug exception ESR.
+ */
+#define YAMON_DEFAULT_EJTAG_ESR		    0xfffffff1
+
+/* Registered Interrupt Service Routine (ISR) */
+typedef void (*t_yamon_isr)(void *data);
+
+/* Registered Exception Service Routine (ESR) */
+typedef void (*t_yamon_esr)(void);
+
+/* Entry point called by ESRs wishing to pass control back to YAMON */
+typedef void (*t_yamon_retfunc)(void);
+
+/* Handle used for deregistration of ISR/ESR */
+typedef void *t_yamon_ref;
+
+
+/* YAMONE Vector table address */
+#define YAMON_FUNCTION_BASE		    0x9fc00500
+
+/* YAMON Vector table offsets */
+#define YAMON_FUNC_PRINT_COUNT_OFS	    0x04
+#define YAMON_FUNC_EXIT_OFS		    0x20
+#define YAMON_FUNC_FLUSH_CACHE_OFS	    0x2C
+#define YAMON_FUNC_PRINT_OFS		    0x34
+#define YAMON_FUNC_REGISTER_CPU_ISR_OFS	    0x38
+#define YAMON_FUNC_DEREGISTER_CPU_ISR_OFS   0x3c
+#define YAMON_FUNC_REGISTER_IC_ISR_OFS	    0x40
+#define YAMON_FUNC_DEREGISTER_IC_ISR_OFS    0x44
+#define YAMON_FUNC_REGISTER_ESR_OFS	    0x48
+#define YAMON_FUNC_DEREGISTER_ESR_OFS       0x4c
+#define YAMON_FUNC_GETCHAR_OFS		    0x50
+#define YAMON_FUNC_SYSCON_READ_OFS	    0x54
+
+/* Macro for accessing YAMON function */
+#define YAMON_FUNC(ofs)\
+    (*(t_yamon_uint32 *)(YAMON_FUNCTION_BASE + (ofs)))
+
+
+/************************************************************************
+ *  Public variables
+ ************************************************************************/
+
+/************************************************************************
+ *  Public functions
+ ************************************************************************/
+
+
+/************************************************************************
+ *
+ *                          t_yamon_exit
+ *  Description :
+ *  -------------
+ *
+ *  Exit application and return to YAMON.
+ *
+ *  Parameters :
+ *  ------------
+ *
+ *  'rc' (OUT) : Return code
+ *
+ *  Return values :
+ *  ---------------
+ *
+ *  None (never returns)
+ *
+ ************************************************************************/
+typedef void
+(*t_yamon_exit)(
+    t_yamon_uint32 rc );	/* Return code				*/
+
+#define YAMON_FUNC_EXIT( rc )\
+    ((t_yamon_exit)( YAMON_FUNC(YAMON_FUNC_EXIT_OFS) ))\
+        ( rc )
+
+
+/************************************************************************
+ *
+ *                          t_yamon_print
+ *  Description :
+ *  -------------
+ *
+ *  Print null-terminated string to tty0.
+ *
+ *  Parameters :
+ *  ------------
+ *
+ *  'port' (OUT) : Ignored, always prints to tty0. Not included in macro.
+ *  's'    (OUT) : String to print.
+ *
+ *  Return values :
+ *  ---------------
+ *
+ *  None
+ *
+ ************************************************************************/
+typedef void
+(*t_yamon_print)(
+    t_yamon_uint32 port, /* Output port (not used, always tty0)		*/
+    const char           *s ); /* String to output				*/
+
+#define YAMON_FUNC_PRINT( s )\
+    ((t_yamon_print)( YAMON_FUNC(YAMON_FUNC_PRINT_OFS) ))\
+        ( 0, s )
+
+
+/************************************************************************
+ *
+ *                          t_yamon_print_count
+ *  Description :
+ *  -------------
+ *
+ *  Print specified number of characters to tty0.
+ *
+ *  Parameters :
+ *  ------------
+ *
+ *  'port'  (OUT) : Ignored, always prints to tty0. Not included in macro.
+ *  's'     (OUT) : Array of characters to print.
+ *  'count' (OUT) : Number of characters to print.
+ *
+ *  Return values :
+ *  ---------------
+ *
+ *  None
+ *
+ ************************************************************************/
+typedef void
+(*t_yamon_print_count)(
+    t_yamon_uint32 port,	/* Output port (not used, always tty0	*/
+    char	   *s,		/* String to output			*/
+    t_yamon_uint32 count );	/* Number of characters to output	*/
+
+#define YAMON_FUNC_PRINT_COUNT( s, count )\
+    ((t_yamon_print_count)( YAMON_FUNC(YAMON_FUNC_PRINT_COUNT_OFS) ))\
+        ( 0, s, count )
+
+
+/************************************************************************
+ *
+ *                          t_yamon_getchar
+ *  Description :
+ *  -------------
+ *
+ *  Get character from tty0 if character is available. Function
+ *  returns immediately if no character is available.
+ *
+ *  Parameters :
+ *  ------------
+ *
+ *  'port'  (OUT) : Ignored, always uses tty0. Not included in macro.
+ *  'ch'    (OUT) : Character read (if available).
+ *
+ *  Return values :
+ *  ---------------
+ *
+ *  YAMON_TRUE if character was available, else YAMON_FALSE.
+ *
+ ************************************************************************/
+typedef t_yamon_bool
+(*t_yamon_getchar)(
+    t_yamon_uint32 port,	/* Output port (not used, always tty0	*/
+    char	   *ch );	/* Character to output			*/
+
+#define YAMON_FUNC_GETCHAR( ch )\
+    ((t_yamon_getchar)( YAMON_FUNC(YAMON_FUNC_GETCHAR_OFS) ))\
+        ( 0, ch )
+
+
+/************************************************************************
+ *
+ *                          t_yamon_syscon_read
+ *  Description :
+ *  -------------
+ *
+ *  Read the value of system configuration object given by 'id'.
+ *
+ *  See syscon_api.h in YAMON source distribution for further details
+ *  on object IDs and error codes.
+ *
+ *  Parameters :
+ *  ------------
+ *
+ *  'id'    (IN)    : Object id.
+ *  'param' (INOUT) : Buffer for object value.
+ *  'size'  (IN)    : Size of buffer (must match size of object).
+ *
+ *  Return values :
+ *  ---------------
+ *
+ *  0 : Returned parameter is valid.
+ *  Other values indicate error.
+ *
+ ************************************************************************/
+typedef t_yamon_int32
+(*t_yamon_syscon_read)(
+    t_yamon_syscon_id   id,	      /* Object ID			*/
+    void                *param,       /* Buffer for object value	*/
+    t_yamon_uint32      size);        /* Buffer size (bytes)		*/
+
+#define YAMON_FUNC_SYSCON_READ( id, param, size )\
+    ((t_yamon_syscon_read)( YAMON_FUNC(YAMON_FUNC_SYSCON_READ_OFS) ))\
+        ( id, param, size )
+
+
+/************************************************************************
+ *
+ *                          t_yamon_flush_cache
+ *  Description :
+ *  -------------
+ *
+ *  Flush I-or D-cache
+ *
+ *  Function performs "writeback and invalidate" operations on D-cache
+ *  lines and "invalidate" operations on I-cache lines.
+ *
+ *  Parameters :
+ *  ------------
+ *
+ *  'type' (IN) : Cache to be flushed.
+ *
+ *  Return values :
+ *  ---------------
+ *
+ *  None
+ *
+ ************************************************************************/
+typedef void
+(*t_yamon_flush_cache)(
+#define YAMON_FLUSH_ICACHE	0
+#define YAMON_FLUSH_DCACHE 	1
+    t_yamon_uint32 type );	/* I- or D-cache indication		*/
+
+#define YAMON_FUNC_FLUSH_CACHE( type )\
+    ((t_yamon_flush_cache)( YAMON_FUNC(YAMON_FUNC_FLUSH_CACHE_OFS) ))\
+        ( type )
+
+
+/************************************************************************
+ *
+ *                          t_yamon_register_esr
+ *  Description :
+ *  -------------
+ *
+ *  Registers an exception handler, also known as an "Exception Service
+ *  Routine" (ESR) for the specified exception.
+ *
+ *  Two special exception IDs are defined :
+ *      YAMON_DEFAULT_HANDLER used for a default ESR.
+ *      YAMON_DEFAULT_EJTAG_ESR used for EJTAG exceptions.
+ *
+ *  The default ESR is called if no other ESR is registered
+ *  for an exception. If no default ESR is registered, a static
+ *  (i.e. not registered) "super default" function is invoked.
+ *  This function prints out the registers and halts.
+ *
+ *  Deregistration of an ESR may be be done by calling this function
+ *  with 'esr' set to NULL.
+ *  An ESR can also be deregistered using the 'yamon_deregister_esr'
+ *  function.
+ *
+ *  An ESR may be registered even if a previously registered
+ *  ESR has not been deregistered. In this case the previously
+ *  registered ESR is lost.
+ *
+ *  The ESR will get called with registers in the state they were
+ *  when the exception occurred. This includes all CP0 registers and
+ *  CPU registers $0..$31, except for k0,k1 ($26,$27).
+ *
+ *  In case an ESR does not want to handle the exception, it may
+ *  call the return function passed in the 'retfunc' parameter.
+ *
+ *  Case 1 : 'retfunc' called by ESR registered for the
+ *           INTERRUPT exception.
+ *
+ *  We assume an application has registered this ESR and wants
+ *  YAMON to process the (remaining) interrupts.
+ *
+ *  Case 2 :  'retfunc' called by an ESR registered for a specific
+ *	      exception (not INTERRUPT).
+ *
+ *  Default handling will be done.
+ *
+ *  Case 3 : 'retfunc' is called by the ESR registered as default ESR.
+ *
+ *  The exception will be handled as though no ESR is registered
+ *  (i.e. the "super default" function is called).
+ *
+ *  Parameters :
+ *  ------------
+ *
+ *  'exception' (IN)  : Exception code
+ *		        or YAMON_DEFAULT_HANDLER for a default ESR
+ *		        or YAMON_DEFAULT_EJTAG_ESR for ejtag exceptions.
+ *  'esr'       (IN)  : Function pointer for ESR.
+ *  'ref'	(OUT) : Handle used for deregistration of ESR.
+ *  'retfunc'	(OUT) : Pointer to function pointer for the return
+ *			function described above.
+ *
+ *  Return values :
+ *  ---------------
+ *
+ *  0 : Registration went well.
+ *  Other values indicate error.
+ *
+ ************************************************************************/
+typedef t_yamon_int32
+(*t_yamon_register_esr)(
+    t_yamon_uint32  exception,	     /* Exception identification	*/
+    t_yamon_esr     esr,	     /* ESR to be registered		*/
+    t_yamon_ref     *ref,	     /* Handle for deregistration	*/
+    t_yamon_retfunc *retfunc );      /* Return function			*/
+
+#define YAMON_FUNC_REGISTER_ESR( exc, esr, ref, retfunc )\
+    ((t_yamon_register_esr)( YAMON_FUNC(YAMON_FUNC_REGISTER_ESR_OFS) ))\
+        ( exc, esr, ref, retfunc )
+
+
+/************************************************************************
+ *
+ *                          t_yamon_deregister_esr
+ *  Description :
+ *  -------------
+ *
+ *  Deregisters ESR..
+ *
+ *  Parameters :
+ *  ------------
+ *
+ *  'ref' (IN) : Handle obtained when calling 'yamon_register_esr'.
+ *
+ *  Return values :
+ *  ---------------
+ *
+ *  0 : Deregistration went well.
+ *  Other values indicate error.
+ *
+ ************************************************************************/
+typedef t_yamon_int32
+(*t_yamon_deregister_esr)(
+    t_yamon_ref ref );             /* Handle for deregistration		*/
+
+#define YAMON_FUNC_DEREGISTER_ESR( ref )\
+    ((t_yamon_deregister_esr)( YAMON_FUNC(YAMON_FUNC_DEREGISTER_ESR_OFS) ))\
+        ( ref )
+
+
+/************************************************************************
+ *
+ *                          t_yamon_register_cpu_isr
+ *  Description :
+ *  -------------
+ *
+ *  Registers an Interrupt Service Routine (ISR) for the specified
+ *  CPU interrupt.
+ *  The highest service priority is attached to HW-INT5, which is
+ *  connected to the CPU-built-in CP0-timer. SW_INT0 gets the lowest
+ *  service priority. During registration, the interrupt mask field
+ *  in the CPU CP0-status register is updated to enable interrupts
+ *  from the specified interrupt source.
+ *
+ *  A special ID is defined :
+ *      YAMON_DEFAULT_HANDLER used for a default ISR.
+ *
+ *  The default ISR is called if no other ISR is registered
+ *  for a CPU interrupt.
+ *
+ *  Deregistration of the default ISR may be done by calling
+ *  this function with 'isr' set to NULL.
+ *  Also, a new default ISR may be registered even if a
+ *  previously registered ISR has not been deregistered.
+ *  ISRs for specific CPU interrupts must be deregistered using
+ *  'yamon_deregister_cpu_isr'.
+ *
+ *  Parameters :
+ *  ------------
+ *
+ *  'cpu_int' (IN)  : CPU interrupt (0..7)
+ *		      or YAMON_DEFAULT_HANDLER for a default ISR.
+ *  'isr'     (IN)  : Function pointer for ISR.
+ *  'data'    (IN)  : Data pointer (may be NULL). Will be passed to
+ *		      ISR when called.
+ *  'ref'     (OUT) : Handle used for deregistration of ISR.
+ *
+ *  Return values :
+ *  ---------------
+ *
+ *  0 : Registration went well.
+ *  Other values indicate error.
+ *
+ ************************************************************************/
+typedef t_yamon_int32
+(*t_yamon_register_cpu_isr)(
+    t_yamon_uint32 cpu_int,	/* CPU interrupt (0..7)			*/
+    t_yamon_isr	   isr,		/* ISR to be registered			*/
+    void	   *data,   	/* Data reference to be registered	*/
+    t_yamon_ref	   *ref );      /* Handle for deregistration		*/
+
+#define YAMON_FUNC_REGISTER_CPU_ISR( cpu_int, isr, data, ref )\
+    ((t_yamon_register_cpu_isr)( YAMON_FUNC(YAMON_FUNC_REGISTER_CPU_ISR_OFS) ))\
+        ( cpu_int, isr, data, ref )
+
+
+/************************************************************************
+ *
+ *                          t_yamon_deregister_cpu_isr
+ *  Description :
+ *  -------------
+ *
+ *  Deregisters ISR for CPU interrupt.
+ *
+ *  Parameters :
+ *  ------------
+ *
+ *  'ref' (IN) : Handle obtained when calling 'yamon_register_cpu_isr'.
+ *
+ *  Return values :
+ *  ---------------
+ *
+ *  0 : Deregistration went well.
+ *  Other values indicate error
+ *
+ ************************************************************************/
+typedef t_yamon_int32
+(*t_yamon_deregister_cpu_isr)(
+    t_yamon_ref ref );	             /* Handle for deregistration	*/
+
+#define YAMON_FUNC_DEREGISTER_CPU_ISR( ref )\
+    ((t_yamon_deregister_cpu_isr)( YAMON_FUNC(YAMON_FUNC_DEREGISTER_CPU_ISR_OFS) ))\
+        ( ref )
+
+
+/************************************************************************
+ *
+ *                          t_yamon_register_ic_isr
+ *  Description :
+ *  -------------
+ *
+ *  Registers an Interrupt Service Routine (ISR) for the specified
+ *  source in the interrupt controller.
+ *
+ *  A special ID is defined :
+ *      YAMON_DEFAULT_HANDLER used for a default ISR.
+ *
+ *  The default ISR is called if no other ISR is registered
+ *  for an interrupt.
+ *
+ *  Deregistration of the default ISR may be done by calling
+ *  this function with 'isr' set to NULL.
+ *  Also, a new default ISR may be registered even if a
+ *  previously registered ISR has not been deregistered.
+ *  ISRs for specific interrupts must be deregistered using
+ *  'yamon_deregister_ic_isr'.
+ *
+ *  Parameters :
+ *  ------------
+ *
+ *  'ic_line' (IN)  : Interrupt source line in Int. Controller
+ *		      or YAMON_DEFAULT_HANDLER for a default ISR.
+ *  'isr',    (IN)  : Function pointer for user defined ISR.
+ *  'data'    (IN)  : Data pointer (may be NULL). Will be passed to
+ *		      ISR when called.
+ *  'ref',    (OUT) : Handle used for deregistration of ISR.
+ *
+ *  Return values :
+ *  ---------------
+ *
+ *  0 : Registration went well.
+ *  Other values indicate error.
+ *
+ ************************************************************************/
+typedef t_yamon_int32
+(*t_yamon_register_ic_isr)(
+    t_yamon_uint32 ic_line,	    /* Interrupt controller line	*/
+    t_yamon_isr	   isr,		    /* ISR to be registered		*/
+    void	   *data,	    /* Data reference to be registered  */
+    t_yamon_ref	   *ref );	    /* Handle for deregistration	*/
+
+#define YAMON_FUNC_REGISTER_IC_ISR( ic_line, isr, data, ref )\
+    ((t_yamon_register_ic_isr)( YAMON_FUNC(YAMON_FUNC_REGISTER_IC_ISR_OFS) ))\
+        ( ic_line, isr, data, ref )
+
+
+/************************************************************************
+ *
+ *                          t_yamon_deregister_ic_isr
+ *  Description :
+ *  -------------
+ *
+ *  Deregisters ISR for source in interrupt controller.
+ *
+ *  Parameters :
+ *  ------------
+ *
+ *  'ref' (IN) : Handle obtained when calling 'yamon_register_ic_isr'.
+ *
+ *  Return values :
+ *  ---------------
+ *
+ *  0 : Deregistration went well.
+ *  Other values indicate error
+ *
+ ************************************************************************/
+typedef t_yamon_int32
+(*t_yamon_deregister_ic_isr)(
+    t_yamon_ref ref );	             /* Handle for deregistration	*/
+
+#define YAMON_FUNC_DEREGISTER_IC_ISR( ref )\
+    ((t_yamon_deregister_ic_isr)( YAMON_FUNC(YAMON_FUNC_DEREGISTER_IC_ISR_OFS) ))\
+        ( ref )
+
+
+#endif /* #ifndef YAMON_API_H */
+
+
+
+
+
+
Index: bsps/mips/shared/clock/clockdrv.c
===================================================================
--- bsps/mips/shared/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/mips/shared/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,49 @@
+/*
+ *  COPYRIGHT (c) 1989-2013.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bspopts.h>
+
+/* XXX convert to macros? Move to score/cpu? */
+void mips_set_timer(uint32_t timer_clock_interval);
+uint32_t mips_get_timer(void);
+
+/* XXX move to BSP.h or irq.h?? */
+#define EXT_INT5             0x8000  /* external interrupt 5 */
+#define CLOCK_VECTOR_MASK    EXT_INT5
+#define CLOCK_VECTOR         (MIPS_INTERRUPT_BASE+0x7)
+
+extern uint32_t bsp_clicks_per_microsecond;
+
+static uint32_t mips_timer_rate = 0;
+
+/* refresh the internal CPU timer */
+#define Clock_driver_support_at_tick() \
+  mips_set_timer( mips_timer_rate );
+
+#define Clock_driver_support_install_isr( _new ) \
+  rtems_interrupt_handler_install(CLOCK_VECTOR, "PIT clock",0, _new, NULL)
+
+#define Clock_driver_support_initialize_hardware() \
+  do { \
+    mips_timer_rate = rtems_configuration_get_microseconds_per_tick() * \
+      bsp_clicks_per_microsecond; \
+    mips_set_timer( mips_timer_rate ); \
+    mips_enable_in_interrupt_mask(CLOCK_VECTOR_MASK); \
+  } while(0)
+
+#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/dev/clock/clockimpl.h"
Index: bsps/mips/shared/clock/mips_timer.S
===================================================================
--- bsps/mips/shared/clock/mips_timer.S	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/mips/shared/clock/mips_timer.S	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,43 @@
+/*  clock.s
+ *
+ *  This file contains the assembly code for the IDT 4650 clock driver.
+ *
+ *  Author:     Craig Lebakken <craigl@transition.com>
+ *
+ *  COPYRIGHT (c) 1996 by Transition Networks Inc.
+ *
+ *  To anyone who acknowledges that this file is provided "AS IS"
+ *  without any express or implied warranty:
+ *      permission to use, copy, modify, and distribute this file
+ *      for any purpose is hereby granted without fee, provided that
+ *      the above copyright notice and this notice appears in all
+ *      copies, and that the name of Transition Networks not be used in
+ *      advertising or publicity pertaining to distribution of the
+ *      software without specific, written prior permission.
+ *      Transition Networks makes no representations about the suitability
+ *      of this software for any purpose.
+ */
+/* @(#)clock.S       08/20/96     1.2 */
+
+#include <rtems/mips/iregdef.h>
+#include <rtems/mips/idtcpu.h>
+#include <rtems/asm.h>
+
+FRAME(mips_set_timer,sp,0,ra)
+	.set noreorder
+        mfc0 t0,C0_COUNT
+        nop
+        addu t0,a0,t0
+        mtc0 t0,C0_COMPARE
+        j ra
+	nop
+	.set reorder
+ENDFRAME(mips_set_timer)
+
+FRAME(mips_get_timer,sp,0,ra)
+	.set noreorder
+        mfc0 v0,C0_COUNT
+        j ra
+	nop
+	.set reorder
+ENDFRAME(mips_get_timer)
Index: bsps/nios2/nios2_iss/clock/clock.c
===================================================================
--- bsps/nios2/nios2_iss/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/nios2/nios2_iss/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,55 @@
+/*
+ * Use SYS_CLK as system clock
+ *
+ * Copyright (c) 2005-2006 Kolja Waschk, rtemsdev/ixo.de
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+
+#define CLOCK_REGS ((altera_avalon_timer_regs*)NIOS2_IO_BASE(CLOCK_BASE))
+
+/*
+ * Periodic interval timer interrupt handler
+ */
+#define Clock_driver_support_at_tick() \
+  do { CLOCK_REGS->status = 0; } while(0)
+
+/*
+ * Attach clock interrupt handler
+ */
+#define Clock_driver_support_install_isr(_new) \
+  set_vector(_new, CLOCK_VECTOR, 1)
+
+/*
+ * Turn off the clock
+ */
+#define Clock_driver_support_shutdown_hardware() \
+  do { \
+    CLOCK_REGS->control = ALTERA_AVALON_TIMER_CONTROL_STOP_MSK; \
+  } while (0)
+
+/*
+ * Set up the clock hardware
+ */
+static void Clock_driver_support_initialize_hardware(void)
+{
+  uint32_t period;
+
+  CLOCK_REGS->control = ALTERA_AVALON_TIMER_CONTROL_STOP_MSK;
+
+  period = (CLOCK_FREQ/1000000L)*rtems_configuration_get_microseconds_per_tick() - 1;
+  CLOCK_REGS->period_hi = period >> 16;
+  CLOCK_REGS->period_lo = period & 0xFFFF;
+
+  CLOCK_REGS->control = ALTERA_AVALON_TIMER_CONTROL_ITO_MSK  |
+                        ALTERA_AVALON_TIMER_CONTROL_CONT_MSK |
+                        ALTERA_AVALON_TIMER_CONTROL_START_MSK;
+
+  NIOS2_IENABLE(1 << CLOCK_VECTOR);
+}
+
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
+#include "../../../shared/dev/clock/clockimpl.h"
+
Index: bsps/no_cpu/no_bsp/clock/ckinit.c
===================================================================
--- bsps/no_cpu/no_bsp/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/no_cpu/no_bsp/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,127 @@
+/*
+ *  This file provides a template for the clock device driver initialization.
+ *
+ *  If possible, please use the dev/clock/clockimpl.h method for instantiating
+ *  a clock driver.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2014.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdlib.h>
+
+#include <rtems.h>
+#include <bsp.h>
+
+void Clock_exit( void );
+rtems_isr Clock_isr( rtems_vector_number vector );
+
+/*
+ *  The interrupt vector number associated with the clock tick device
+ *  driver.
+ */
+#define CLOCK_VECTOR    4
+
+/*
+ *  Clock_driver_ticks is a monotonically increasing counter of the
+ *  number of clock ticks since the driver was initialized.
+ */
+volatile uint32_t         Clock_driver_ticks;
+
+/*
+ *  Clock_isrs is the number of clock ISRs until the next invocation of
+ *  the RTEMS clock tick routine.  The clock tick device driver
+ *  gets an interrupt once a millisecond and counts down until the
+ *  length of time between the user configured microseconds per tick
+ *  has passed.
+ */
+uint32_t         Clock_isrs;              /* ISRs until next tick */
+
+/*
+ *  The previous ISR on this clock tick interrupt vector.
+ */
+rtems_isr_entry  Old_ticker;
+
+void Clock_exit( void );
+
+/*
+ *  Isr Handler
+ */
+static rtems_isr Clock_isr(
+  rtems_vector_number vector
+)
+{
+  /*
+   * bump the number of clock driver ticks since initialization
+   *
+   * determine if it is time to announce the passing of tick as configured
+   * to RTEMS through the rtems_clock_tick directive
+   *
+   * perform any timer dependent tasks
+   */
+}
+
+/*
+ *  Install_clock
+ *
+ *  Install a clock tick handler and reprograms the chip.  This
+ *  is used to initially establish the clock tick.
+ */
+void Install_clock(
+  rtems_isr_entry clock_isr
+)
+{
+  /*
+   *  Initialize the clock tick device driver variables
+   */
+
+  Clock_driver_ticks = 0;
+  Clock_isrs = rtems_configuration_get_microseconds_per_tick() / 1000;
+
+  Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 );
+  /*
+   *  Hardware specific initialize goes here
+   */
+
+  /* XXX */
+
+  /*
+   *  Schedule the clock cleanup routine to execute if the application exits.
+   */
+
+  atexit( Clock_exit );
+}
+
+/*
+ *  Clean up before the application exits
+ */
+
+void Clock_exit( void )
+{
+  /* XXX: turn off the timer interrupts */
+
+  /* XXX: If necessary, restore the old vector */
+}
+
+/*
+ *  Clock_initialize
+ *
+ *  Device driver entry point for clock tick driver initialization.
+ */
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  Install_clock( Clock_isr );
+
+  return RTEMS_SUCCESSFUL;
+}
+
Index: bsps/or1k/generic_or1k/clock/clockdrv.c
===================================================================
--- bsps/or1k/generic_or1k/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/or1k/generic_or1k/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,147 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_clock
+ *
+ * @brief or1k clock support.
+ */
+
+/*
+ * generic_or1k Clock driver
+ *
+ * COPYRIGHT (c) 2014-2015 Hesham ALMatary <heshamelmatary@gmail.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#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;
+
+/* This prototype is added here to Avoid warnings */
+void Clock_isr(void *arg);
+
+static void generic_or1k_clock_at_tick(void)
+{
+  uint32_t TTMR;
+
+ /* For TTMR register,
+  * The least significant 28 bits are the number of clock cycles
+  * before generating a tick timer interrupt. While the most
+  * significant 4 bits are used for mode configuration, tick timer
+  * interrupt enable and pending interrupts status.
+  */
+  TTMR = (CPU_OR1K_SPR_TTMR_MODE_RESTART | CPU_OR1K_SPR_TTMR_IE |
+           (TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT & CPU_OR1K_SPR_TTMR_TP_MASK)
+         ) & ~(CPU_OR1K_SPR_TTMR_IP);
+
+  _OR1K_mtspr(CPU_OR1K_SPR_TTMR, TTMR);
+  _OR1K_mtspr(CPU_OR1K_SPR_TTCR, 0);
+
+  cpu_counter_ticks += TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT;
+}
+
+static void generic_or1k_clock_handler_install(proc_ptr new_isr)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+  _CPU_ISR_install_vector(OR1K_EXCEPTION_TICK_TIMER,
+                          new_isr,
+                          NULL);
+
+  if (sc != RTEMS_SUCCESSFUL) {
+    rtems_fatal_error_occurred(0xdeadbeef);
+  }
+}
+
+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,
+  * The least significant 28 bits are the number of clock cycles
+  * before generating a tick timer interrupt. While the most
+  * significant 4 bits are used for mode configuration, tick timer
+  * interrupt enable and pending interrupts status.
+  */
+
+  /* FIXME: Long interval should pass since initializing the tick timer
+   * registers fires exceptions dispite interrupts has not been enabled yet.
+   */
+  TTMR = (CPU_OR1K_SPR_TTMR_MODE_RESTART | CPU_OR1K_SPR_TTMR_IE |
+           (0xFFED9 & CPU_OR1K_SPR_TTMR_TP_MASK)
+         ) & ~(CPU_OR1K_SPR_TTMR_IP);
+
+  _OR1K_mtspr(CPU_OR1K_SPR_TTMR, TTMR);
+  _OR1K_mtspr(CPU_OR1K_SPR_TTCR, 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)
+{
+ uint32_t sr;
+
+  sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
+
+  /* Disable tick timer exceptions */
+  _OR1K_mtspr(CPU_OR1K_SPR_SR, (sr & ~CPU_OR1K_SPR_SR_IEE)
+  & ~CPU_OR1K_SPR_SR_TEE);
+
+  /* Invalidate tick timer config registers */
+  _OR1K_mtspr(CPU_OR1K_SPR_TTCR, 0);
+  _OR1K_mtspr(CPU_OR1K_SPR_TTMR, 0);
+}
+
+CPU_Counter_ticks _CPU_Counter_difference(
+  CPU_Counter_ticks second,
+  CPU_Counter_ticks first
+)
+{
+  return second - first;
+}
+
+#define Clock_driver_support_at_tick() generic_or1k_clock_at_tick()
+
+#define Clock_driver_support_initialize_hardware() generic_or1k_clock_initialize()
+
+#define Clock_driver_support_install_isr(isr) \
+  generic_or1k_clock_handler_install(isr)
+
+#define Clock_driver_support_shutdown_hardware() generic_or1k_clock_cleanup()
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/powerpc/mpc55xxevb/clock/clock-config.c
===================================================================
--- bsps/powerpc/mpc55xxevb/clock/clock-config.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/powerpc/mpc55xxevb/clock/clock-config.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,257 @@
+/**
+ * @file
+ *
+ * @ingroup mpc55xx
+ *
+ * @brief Clock driver configuration.
+ */
+
+/*
+ * Copyright (c) 2009-2013 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/fatal.h>
+#include <bsp/irq.h>
+
+#include <mpc55xx/regs.h>
+
+#include <rtems/timecounter.h>
+
+void Clock_isr(void *arg);
+
+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_at_tick(rtems_timecounter_simple *tc)
+{
+  union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS;
+  csr.B.FLAG = 1;
+  EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CSR.R = csr.R;
+}
+
+static void mpc55xx_tc_tick(void)
+{
+  rtems_timecounter_simple_upcounter_tick(
+    &mpc55xx_tc,
+    mpc55xx_tc_get,
+    mpc55xx_tc_at_tick
+  );
+}
+
+static void mpc55xx_clock_handler_install(rtems_isr_entry isr)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  sc = mpc55xx_interrupt_handler_install(
+    MPC55XX_IRQ_EMIOS(MPC55XX_CLOCK_EMIOS_CHANNEL),
+    "clock",
+    RTEMS_INTERRUPT_UNIQUE,
+    MPC55XX_INTC_MIN_PRIORITY,
+    (rtems_interrupt_handler) isr,
+    NULL
+  );
+  if (sc != RTEMS_SUCCESSFUL) {
+    bsp_fatal(MPC55XX_FATAL_CLOCK_EMIOS_IRQ_INSTALL);
+  }
+}
+
+static void mpc55xx_clock_initialize(void)
+{
+  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;
+  unsigned prescaler = mpc55xx_emios_global_prescaler();
+  uint64_t reference_clock = bsp_clock_speed;
+  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
+  uint64_t interval = (reference_clock * us_per_tick) / 1000000;
+
+  /* Apply prescaler */
+  if (prescaler > 0) {
+    interval /= (uint64_t) prescaler;
+  } else {
+    bsp_fatal(MPC55XX_FATAL_CLOCK_EMIOS_PRESCALER);
+  }
+
+  /* Check interval */
+  if (interval == 0 || interval > MPC55XX_EMIOS_VALUE_MAX) {
+    bsp_fatal(MPC55XX_FATAL_CLOCK_EMIOS_INTERVAL);
+  }
+
+  /* Configure eMIOS channel */
+
+  /* Set channel in GPIO mode */
+  ccr.B.MODE = MPC55XX_EMIOS_MODE_GPIO_INPUT;
+  regs->CCR.R = ccr.R;
+
+  /* Clear status flags */
+  csr.B.OVR = 1;
+  csr.B.OVFL = 1;
+  csr.B.FLAG = 1;
+  regs->CSR.R = csr.R;
+
+  /* Set internal counter start value */
+  regs->CCNTR.R = 1;
+
+  /* Set timer period */
+  regs->CADR.R = (uint32_t) interval - 1;
+
+  /* Set control register */
+  #if MPC55XX_CHIP_FAMILY == 551
+    ccr.B.MODE = MPC55XX_EMIOS_MODE_MCB_UP_INT_CLK;
+  #else
+    ccr.B.MODE = MPC55XX_EMIOS_MODE_MC_UP_INT_CLK;
+  #endif
+  ccr.B.UCPREN = 1;
+  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)
+{
+  volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
+  union EMIOS_CCR_tag ccr = MPC55XX_ZERO_FLAGS;
+
+  /* Set channel in GPIO mode */
+  ccr.B.MODE = MPC55XX_EMIOS_MODE_GPIO_INPUT;
+  regs->CCR.R = ccr.R;
+}
+
+#elif defined(MPC55XX_CLOCK_PIT_CHANNEL)
+
+static uint32_t mpc55xx_tc_get(rtems_timecounter_simple *tc)
+{
+  return PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL].CVAL.R;
+}
+
+static bool mpc55xx_tc_is_pending(rtems_timecounter_simple *tc)
+{
+  return PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL].TFLG.B.TIF != 0;
+}
+
+static uint32_t mpc55xx_tc_get_timecount(struct timecounter *tc)
+{
+  return rtems_timecounter_simple_downcounter_get(
+    tc,
+    mpc55xx_tc_get,
+    mpc55xx_tc_is_pending
+  );
+}
+
+static void mpc55xx_tc_at_tick(rtems_timecounter_simple *tc)
+{
+  volatile PIT_RTI_CHANNEL_tag *channel =
+    &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
+  PIT_RTI_TFLG_32B_tag tflg = { .B = { .TIF = 1 } };
+
+  channel->TFLG.R = tflg.R;
+}
+
+static void mpc55xx_tc_tick(void)
+{
+  rtems_timecounter_simple_downcounter_tick(
+    &mpc55xx_tc,
+    mpc55xx_tc_get,
+    mpc55xx_tc_at_tick
+  );
+}
+
+static void mpc55xx_clock_handler_install(rtems_isr_entry isr)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  sc = mpc55xx_interrupt_handler_install(
+    MPC55XX_IRQ_PIT_CHANNEL(MPC55XX_CLOCK_PIT_CHANNEL),
+    "clock",
+    RTEMS_INTERRUPT_UNIQUE,
+    MPC55XX_INTC_MIN_PRIORITY,
+    (rtems_interrupt_handler) isr,
+    NULL
+  );
+  if (sc != RTEMS_SUCCESSFUL) {
+    bsp_fatal(MPC55XX_FATAL_CLOCK_PIT_IRQ_INSTALL);
+  }
+}
+
+static void mpc55xx_clock_initialize(void)
+{
+  volatile PIT_RTI_CHANNEL_tag *channel =
+    &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
+  uint64_t reference_clock = bsp_clock_speed;
+  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
+  uint64_t interval = (reference_clock * us_per_tick) / 1000000;
+  PIT_RTI_PITMCR_32B_tag pitmcr = { .B = { .FRZ = 1 } };
+  PIT_RTI_TCTRL_32B_tag tctrl = { .B = { .TIE = 1, .TEN = 1 } };
+
+  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)
+{
+  volatile PIT_RTI_CHANNEL_tag *channel =
+    &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
+
+  channel->TCTRL.R = 0;
+}
+
+#endif
+
+#define Clock_driver_timecounter_tick() mpc55xx_tc_tick()
+#define Clock_driver_support_initialize_hardware() \
+  mpc55xx_clock_initialize()
+#define Clock_driver_support_install_isr(isr) \
+  mpc55xx_clock_handler_install(isr)
+#define Clock_driver_support_shutdown_hardware() \
+  mpc55xx_clock_cleanup()
+
+/* Include shared source clock driver code */
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/powerpc/mpc8260ads/clock/p_clock.c
===================================================================
--- bsps/powerpc/mpc8260ads/clock/p_clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/powerpc/mpc8260ads/clock/p_clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,69 @@
+/*
+ *  Clock Tick interrupt conexion code.
+ *
+ *  COPYRIGHT (c) 1989-1997.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may in
+ *  the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ *  Modified to support the MPC750.
+ *  Modifications Copyright (c) 1999 Eric Valette valette@crf.canon.fr
+ */
+
+#include <bsp.h>
+#include <rtems/bspIo.h>
+#include <bsp/irq.h>
+
+extern void clockOn(void*);
+extern void clockOff (void*);
+extern int clockIsOn(void*);
+extern void Clock_isr(void);
+
+static rtems_irq_connect_data clockIrqData = {BSP_PERIODIC_TIMER,
+					      (rtems_irq_hdl)Clock_isr,
+					      NULL,
+					      (rtems_irq_enable)clockOn,
+					      (rtems_irq_disable)clockOff,
+					      (rtems_irq_is_enabled)clockIsOn};
+
+int BSP_get_clock_irq_level(void)
+{
+  /*
+   * Caution : if you change this, you must change the
+   * definition of BSP_PERIODIC_TIMER accordingly
+   */
+  return BSP_PERIODIC_TIMER;
+}
+
+int BSP_disconnect_clock_handler (void)
+{
+  if (!BSP_get_current_rtems_irq_handler(&clockIrqData)) {
+     printk("Unable to stop system clock\n");
+    rtems_fatal_error_occurred(1);
+  }
+  return BSP_remove_rtems_irq_handler (&clockIrqData);
+}
+
+int BSP_connect_clock_handler (rtems_irq_hdl hdl)
+{
+  if (!BSP_get_current_rtems_irq_handler(&clockIrqData)) {
+     printk("Unable to get system clock handler\n");
+    rtems_fatal_error_occurred(1);
+  }
+  if (!BSP_remove_rtems_irq_handler (&clockIrqData)) {
+   printk("Unable to remove current system clock handler\n");
+    rtems_fatal_error_occurred(1);
+  }
+  /*
+   * Reinit structure
+   */
+  clockIrqData.name = BSP_PERIODIC_TIMER;
+  clockIrqData.hdl = (rtems_irq_hdl) hdl;
+  clockIrqData.on = (rtems_irq_enable)clockOn;
+  clockIrqData.off = (rtems_irq_enable)clockOff;
+  clockIrqData.isOn = (rtems_irq_is_enabled)clockIsOn;
+
+  return BSP_install_rtems_irq_handler (&clockIrqData);
+}
Index: bsps/powerpc/qoriq/clock/clock-config.c
===================================================================
--- bsps/powerpc/qoriq/clock/clock-config.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/powerpc/qoriq/clock/clock-config.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,178 @@
+/**
+ * @file
+ *
+ * @ingroup QorIQ
+ *
+ * @brief QorIQ clock configuration.
+ */
+
+/*
+ * Copyright (c) 2011, 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems/timecounter.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <bsp.h>
+#include <bsp/qoriq.h>
+#include <bsp/irq.h>
+
+/* This is defined in dev/clock/clockimpl.h */
+static rtems_isr Clock_isr(void *arg);
+
+static struct timecounter qoriq_clock_tc;
+
+#ifdef QORIQ_IS_HYPERVISOR_GUEST
+
+#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR
+
+void qoriq_decrementer_dispatch(void)
+{
+  PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_TSR, BOOKE_TSR_DIS);
+  Clock_isr(NULL);
+}
+
+static uint32_t qoriq_clock_get_timecount(struct timecounter *tc)
+{
+  return ppc_alternate_time_base();
+}
+
+static void qoriq_clock_initialize(void)
+{
+  uint64_t frequency = bsp_time_base_frequency;
+  uint32_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
+  uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000);
+
+  PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_DECAR, interval - 1);
+  PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(
+    BOOKE_TCR,
+    BOOKE_TCR_DIE | BOOKE_TCR_ARE
+  );
+  ppc_set_decrementer_register(interval - 1);
+
+  qoriq_clock_tc.tc_get_timecount = qoriq_clock_get_timecount;
+  qoriq_clock_tc.tc_counter_mask = 0xffffffff;
+  qoriq_clock_tc.tc_frequency = qoriq_clock_frequency;
+  qoriq_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+  rtems_timecounter_install(&qoriq_clock_tc);
+}
+
+#else /* !QORIQ_IS_HYPERVISOR_GUEST */
+
+static volatile qoriq_pic_global_timer *const qoriq_clock =
+  #if QORIQ_CLOCK_TIMER < 4
+    &qoriq.pic.gta [QORIQ_CLOCK_TIMER];
+  #else
+    &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 void qoriq_clock_handler_install(void)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+#if defined(RTEMS_MULTIPROCESSING) && !defined(RTEMS_SMP)
+  {
+    Processor_mask affinity;
+
+    _Processor_mask_From_index(&affinity, ppc_processor_id());
+    bsp_interrupt_set_affinity(CLOCK_INTERRUPT, &affinity);
+  }
+#endif
+
+  sc = qoriq_pic_set_priority(
+    CLOCK_INTERRUPT,
+    QORIQ_PIC_PRIORITY_LOWEST,
+    NULL
+  );
+  if (sc != RTEMS_SUCCESSFUL) {
+    rtems_fatal_error_occurred(0xdeadbeef);
+  }
+
+  sc = rtems_interrupt_handler_install(
+    CLOCK_INTERRUPT,
+    "Clock",
+    RTEMS_INTERRUPT_UNIQUE,
+    Clock_isr,
+    NULL
+  );
+  if (sc != RTEMS_SUCCESSFUL) {
+    rtems_fatal_error_occurred(0xdeadbeef);
+  }
+}
+
+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 interval = (uint32_t) (((uint64_t) timer_frequency
+    * (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000);
+
+  qoriq_clock->bcr = GTBCR_COUNT(interval);
+
+  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)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  qoriq_clock->bcr = GTBCR_CI;
+
+  sc = rtems_interrupt_handler_remove(
+    CLOCK_INTERRUPT,
+    Clock_isr,
+    NULL
+  );
+  if (sc != RTEMS_SUCCESSFUL) {
+    rtems_fatal_error_occurred(0xdeadbeef);
+  }
+}
+
+#define Clock_driver_support_install_isr(clock_isr) \
+  qoriq_clock_handler_install()
+
+#define Clock_driver_support_set_interrupt_affinity(online_processors) \
+  bsp_interrupt_set_affinity(CLOCK_INTERRUPT, online_processors)
+
+#define Clock_driver_support_shutdown_hardware() \
+  qoriq_clock_cleanup()
+
+#endif /* QORIQ_IS_HYPERVISOR_GUEST */
+
+#define Clock_driver_support_initialize_hardware() \
+  qoriq_clock_initialize()
+
+/* Include shared source clock driver code */
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/powerpc/shared/clock/clock-ppc-dec.c
===================================================================
--- bsps/powerpc/shared/clock/clock-ppc-dec.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/powerpc/shared/clock/clock-ppc-dec.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,266 @@
+/**
+ *  @brief Clock Tick Device Driver
+ *
+ *  This routine utilizes the Decrementer Register common to the PPC family.
+ *
+ *  The tick frequency is directly programmed to the configured number of
+ *  microseconds per tick.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2014.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may in
+ *  the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ *  Modified to support the MPC750.
+ *  Modifications Copyright (c) 1999 Eric Valette valette@crf.canon.fr
+ */
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/clockdrv.h>
+#include <stdlib.h>                     /* for atexit() */
+#include <assert.h>
+#include <libcpu/c_clock.h>
+#include <libcpu/cpuIdent.h>
+#include <libcpu/spr.h>
+#include <rtems/bspIo.h>                /* for printk() */
+#include <libcpu/powerpc-utility.h>
+#include <rtems/timecounter.h>
+#include <rtems/score/percpu.h>
+
+#include <bspopts.h>   /* for CLOCK_DRIVER_USE_FAST_IDLE */
+
+SPR_RW(BOOKE_TCR)
+SPR_RW(BOOKE_TSR)
+SPR_RW(BOOKE_DECAR)
+
+extern int BSP_connect_clock_handler (void);
+
+/*
+ *  Clock ticks since initialization
+ */
+volatile uint32_t   Clock_driver_ticks;
+
+/*
+ *  This is the value programmed into the count down timer.
+ */
+static uint32_t   Clock_Decrementer_value;
+
+static struct timecounter Clock_TC;
+
+static uint32_t Clock_Get_timecount(struct timecounter *tc)
+{
+  return ppc_time_base();
+}
+
+void clockOff(void* unused)
+{
+  rtems_interrupt_level l;
+
+  if ( ppc_cpu_is_bookE() ) {
+    rtems_interrupt_disable(l);
+    _write_BOOKE_TCR(_read_BOOKE_TCR() & ~BOOKE_TCR_DIE);
+    rtems_interrupt_enable(l);
+  } else {
+    /*
+     * Nothing to do as we cannot disable all interrupts and
+     * the decrementer interrupt enable is MSR_EE
+     */
+  }
+}
+
+void clockOn(void* unused)
+{
+  rtems_interrupt_level l;
+
+  PPC_Set_decrementer( Clock_Decrementer_value );
+
+  if ( ppc_cpu_is_bookE() ) {
+    _write_BOOKE_DECAR( Clock_Decrementer_value );
+
+    rtems_interrupt_disable(l);
+
+    /* clear pending/stale irq */
+    _write_BOOKE_TSR( BOOKE_TSR_DIS );
+    /* enable */
+    _write_BOOKE_TCR( _read_BOOKE_TCR() | BOOKE_TCR_DIE );
+
+    rtems_interrupt_enable(l);
+
+  }
+}
+
+static void clockHandler(void)
+{
+  #if (CLOCK_DRIVER_USE_FAST_IDLE == 1)
+    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->is_idle ) {
+      tb += Clock_Decrementer_value;
+      ppc_set_time_base( tb );
+      rtems_timecounter_tick();
+    }
+
+    rtems_interrupt_enable(level);
+  #else
+    rtems_timecounter_tick();
+  #endif
+}
+
+static void (*clock_handler)(void);
+
+/*
+ *  Clock_isr
+ *
+ *  This is the clock tick interrupt handler.
+ *
+ *  Input parameters:
+ *    vector - vector number
+ *
+ *  Output parameters:  NONE
+ *
+ *  Return values:      NONE
+ *
+ */
+void clockIsr(void *unused)
+{
+  int decr;
+
+  /*
+   *  The driver has seen another tick.
+   */
+  do {
+    register uint32_t flags;
+
+    rtems_interrupt_disable(flags);
+      __asm__ volatile (
+	"mfdec %0; add %0, %0, %1; mtdec %0"
+	: "=&r"(decr)
+	: "r"(Clock_Decrementer_value)
+      );
+    rtems_interrupt_enable(flags);
+
+    Clock_driver_ticks += 1;
+    /*
+     *  Real Time Clock counter/timer is set to automatically reload.
+     */
+    clock_handler();
+  } while ( decr < 0 );
+}
+
+/*
+ *  Clock_isr_bookE
+ *
+ *  This is the clock tick interrupt handler
+ *  for bookE CPUs. For efficiency reasons we
+ *  provide a separate handler rather than
+ *  checking the CPU type each time.
+ */
+void clockIsrBookE(void *unused)
+{
+  /* Note: TSR bit has already been cleared in the exception handler */
+
+  /*
+   *  The driver has seen another tick.
+   */
+
+  Clock_driver_ticks += 1;
+
+  /*
+   *  Real Time Clock counter/timer is set to automatically reload.
+   */
+  clock_handler();
+}
+
+int clockIsOn(void* unused)
+{
+  uint32_t   msr_value;
+
+  _CPU_MSR_GET( msr_value );
+
+  if ( ppc_cpu_is_bookE() && ! (_read_BOOKE_TCR() & BOOKE_TCR_DIE) )
+    msr_value = 0;
+
+  if (msr_value & MSR_EE) return 1;
+
+  return 0;
+}
+
+/*
+ *  Clock_exit
+ *
+ *  This routine allows the clock driver to exit by masking the interrupt and
+ *  disabling the clock's counter.
+ */
+void Clock_exit( void )
+{
+  (void) BSP_disconnect_clock_handler ();
+}
+
+/*
+ *  Clock_initialize
+ *
+ *  This routine initializes the clock driver.
+ */
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  rtems_interrupt_level l,tcr;
+
+  Clock_Decrementer_value = (BSP_bus_frequency/BSP_time_base_divisor)*
+            rtems_configuration_get_milliseconds_per_tick();
+
+  /* set the decrementer now, prior to installing the handler
+   * so no interrupts will happen in a while.
+   */
+  PPC_Set_decrementer( (unsigned)-1 );
+
+  /* On a bookE CPU the decrementer works differently. It doesn't
+   * count past zero but we can enable auto-reload :-)
+   */
+  if ( ppc_cpu_is_bookE() ) {
+
+    rtems_interrupt_disable(l);
+
+      tcr  = _read_BOOKE_TCR();
+      tcr |= BOOKE_TCR_ARE;
+      tcr &= ~BOOKE_TCR_DIE;
+      _write_BOOKE_TCR(tcr);
+
+    rtems_interrupt_enable(l);
+  }
+
+  Clock_TC.tc_get_timecount = Clock_Get_timecount;
+  Clock_TC.tc_counter_mask = 0xffffffff;
+  Clock_TC.tc_frequency = (UINT64_C(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;
+   * The next exception will then be taken by our clock handler.
+   * Clock handler installation initializes the decrementer to
+   * the correct value.
+   */
+  clock_handler = clockHandler;
+  if (!BSP_connect_clock_handler ()) {
+    printk("Unable to initialize system clock\n");
+    rtems_fatal_error_occurred(1);
+  }
+
+  return RTEMS_SUCCESSFUL;
+} /* Clock_initialize */
Index: bsps/powerpc/shared/clock/clock-ppc403.c
===================================================================
--- bsps/powerpc/shared/clock/clock-ppc403.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/powerpc/shared/clock/clock-ppc403.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,275 @@
+/**
+ *  @file
+ *
+ *  This routine initializes the interval timer on the
+ *  PowerPC 403 CPU.  The tick frequency is specified by the BSP.
+ */
+
+/*
+ *  Original PPC403 Code from:
+ *  Author: Andrew Bray <andy@i-cubed.co.uk>
+ *  COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ *  Modifications for PPC405GP by Dennis Ehlin
+ *
+ *  To anyone who acknowledges that this file is provided "AS IS"
+ *  without any express or implied warranty:
+ *      permission to use, copy, modify, and distribute this file
+ *      for any purpose is hereby granted without fee, provided that
+ *      the above copyright notice and this notice appears in all
+ *      copies, and that the name of i-cubed limited not be used in
+ *      advertising or publicity pertaining to distribution of the
+ *      software without specific, written prior permission.
+ *      i-cubed limited makes no representations about the suitability
+ *      of this software for any purpose.
+ *
+ *  Modifications for deriving timer clock from cpu system clock by
+ *              Thomas Doerfler <td@imd.m.isar.de>
+ *  for these modifications:
+ *  COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
+ *
+ *  COPYRIGHT (c) 1989-2012.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <rtems/clockdrv.h>
+#include <rtems/libio.h>
+#include <stdlib.h>                     /* for atexit() */
+#include <rtems/bspIo.h>
+#include <rtems/powerpc/powerpc.h>
+
+/*
+ * check, which exception handling code is present
+ */
+
+#include <bsp.h>
+
+#include <bsp/vectors.h>
+#include <bsp/irq.h>
+
+extern uint32_t   bsp_clicks_per_usec;
+
+volatile uint32_t Clock_driver_ticks;
+static uint32_t   pit_value, tick_time;
+static bool       auto_restart;
+
+void Clock_exit( void );
+
+static inline uint32_t get_itimer(void)
+{
+  register uint32_t rc;
+
+#ifndef ppc405 /* this is a ppc403 */
+  __asm__ volatile ("mfspr %0, 0x3dd" : "=r" ((rc))); /* TBLO */
+#else /* ppc405 */
+  __asm__ volatile ("mfspr %0, 0x10c" : "=r" ((rc))); /* 405GP TBL */
+#endif /* ppc405 */
+
+  return rc;
+}
+
+/*
+ *  ISR Handler
+ */
+static void Clock_isr(void* handle)
+{
+  uint32_t clicks_til_next_interrupt;
+#if defined(BSP_PPC403_CLOCK_ISR_IRQ_LEVEL)
+  uint32_t l_orig = _ISR_Get_level();
+#endif
+
+  if (!auto_restart) {
+    uint32_t itimer_value;
+    /*
+     * setup for next interrupt; making sure the new value is reasonably
+     * in the future.... in case we lost out on an interrupt somehow
+     */
+    itimer_value = get_itimer();
+    tick_time += pit_value;
+
+    /*
+     * how far away is next interrupt *really*
+     * It may be a long time; this subtraction works even if
+     * Clock_clicks_interrupt < Clock_clicks_low_order via
+     * the miracle of unsigned math.
+     */
+    clicks_til_next_interrupt = tick_time - itimer_value;
+
+    /*
+     * If it is too soon then bump it up.
+     * This should only happen if CPU_HPPA_CLICKS_PER_TICK is too small.
+     * But setting it low is useful for debug, so...
+     */
+    if (clicks_til_next_interrupt < 400) {
+      tick_time = itimer_value + 1000;
+      clicks_til_next_interrupt = 1000;
+      /* XXX: count these! this should be rare */
+    }
+
+    /*
+     * If it is too late, that means we missed the interrupt somehow.
+     * Rather than wait 35-50s for a wrap, we just fudge it here.
+     */
+    if (clicks_til_next_interrupt > pit_value) {
+      tick_time = itimer_value + 1000;
+      clicks_til_next_interrupt = 1000;
+      /* XXX: count these! this should never happen :-) */
+    }
+
+    __asm__ volatile ("mtspr 0x3db, %0" :: "r"
+                      (clicks_til_next_interrupt));                  /* PIT */
+  }
+
+  __asm__ volatile ("mtspr 0x3d8, %0" :: "r" (0x08000000));          /* TSR */
+
+  Clock_driver_ticks++;
+
+  /* Give BSP a chance to say if they want to re-enable interrupts */
+#if defined(BSP_PPC403_CLOCK_ISR_IRQ_LEVEL)
+  _ISR_Set_level(BSP_PPC403_CLOCK_ISR_IRQ_LEVEL);
+#endif
+  rtems_clock_tick();
+
+#if defined(BSP_PPC403_CLOCK_ISR_IRQ_LEVEL)
+  _ISR_Set_level(l_orig)
+#endif
+}
+
+static int ClockIsOn(const rtems_irq_connect_data* unused)
+{
+  register uint32_t tcr;
+
+  __asm__ volatile ("mfspr %0, 0x3da" : "=r" ((tcr)));               /* TCR */
+
+  return (tcr & 0x04000000) != 0;
+}
+
+static void ClockOff(const rtems_irq_connect_data* unused)
+{
+  register uint32_t tcr;
+
+  __asm__ volatile ("mfspr %0, 0x3da" : "=r" ((tcr)));               /* TCR */
+  tcr &= ~ 0x04400000;
+  __asm__ volatile ("mtspr 0x3da, %0" : "=r" ((tcr)) : "0" ((tcr))); /* TCR */
+}
+
+static void ClockOn(const rtems_irq_connect_data* unused)
+{
+  uint32_t          iocr;
+  register uint32_t tcr;
+#ifndef ppc405
+  uint32_t          pvr;
+#endif /* ppc403 */
+
+  Clock_driver_ticks = 0;
+
+#ifndef ppc405 /* this is a ppc403 */
+  __asm__ volatile ("mfdcr %0, 0xa0" : "=r" (iocr));              /* IOCR */
+  iocr &= ~4;                         /* timer clocked from system clock */
+  __asm__ volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); /* IOCR */
+
+  __asm__ volatile ("mfspr %0, 0x11f" : "=r" ((pvr))); /* PVR */
+  if (((pvr & 0xffff0000) >> 16) != 0x0020)
+    return;                             /* Not a ppc403 */
+
+  if ((pvr & 0xff00) == 0x0000)         /* 403GA */
+#if 0 /* FIXME: in which processor versions will "autoload" work properly? */
+    auto_restart = (pvr & 0x00f0) > 0x0000 ? true : false;
+#else
+    /* no known chip version supports auto restart of timer... */
+    auto_restart = false;
+#endif
+  else if ((pvr & 0xff00) == 0x0100)    /* 403GB */
+    auto_restart = true;
+
+#else /* ppc405 */
+  __asm__ volatile ("mfdcr %0, 0x0b2" : "=r" (iocr));              /*405GP CPC0_CR1 */
+  iocr &=~0x800000;               /* timer clocked from system clock CETE*/
+  __asm__ volatile ("mtdcr 0x0b2, %0" : "=r" (iocr) : "0" (iocr)); /* 405GP CPC0_CR1 */
+
+  /*
+   * Enable auto restart
+   */
+  auto_restart = true;
+#endif /* ppc405 */
+
+  pit_value = rtems_configuration_get_microseconds_per_tick() *
+                bsp_clicks_per_usec;
+
+  /*
+   * Set PIT value
+   */
+  __asm__ volatile ("mtspr 0x3db, %0" : : "r" (pit_value)); /* PIT */
+
+  /*
+   * Set timer to autoreload, bit TCR->ARE = 1  0x0400000
+   * Enable PIT interrupt,    bit TCR->PIE = 1  0x4000000
+   */
+  tick_time = get_itimer() + pit_value;
+
+  __asm__ volatile ("mfspr %0, 0x3da" : "=r" ((tcr)));               /* TCR */
+  tcr = (tcr & ~0x04400000) | (auto_restart ? 0x04400000 : 0x04000000);
+#if 1
+  __asm__ volatile ("mtspr 0x3da, %0" : "=r" ((tcr)) : "0" ((tcr))); /* TCR */
+#endif
+}
+
+static void Install_clock(void (*clock_isr)(void *))
+{
+  rtems_irq_connect_data clockIrqConnData;
+
+  Clock_driver_ticks = 0;
+
+  /*
+   * initialize the interval here
+   * First tick is set to right amount of time in the future
+   * Future ticks will be incremented over last value set
+   * in order to provide consistent clicks in the face of
+   * interrupt overhead
+   */
+  clockIrqConnData.on   = ClockOn;
+  clockIrqConnData.off  = ClockOff;
+  clockIrqConnData.isOn = ClockIsOn;
+  clockIrqConnData.name = BSP_PIT;
+  clockIrqConnData.hdl  = clock_isr;
+  if (!BSP_install_rtems_irq_handler (&clockIrqConnData)) {
+    printk("Unable to connect Clock Irq handler\n");
+    rtems_fatal_error_occurred(1);
+  }
+
+  atexit(Clock_exit);
+}
+
+/*
+ * Called via atexit()
+ * Remove the clock interrupt handler by setting handler to NULL
+ *
+ * This will not work on the 405GP because
+ * when bit's are set in TCR they can only be unset by a reset
+ */
+void Clock_exit(void)
+{
+  rtems_irq_connect_data clockIrqConnData;
+
+  clockIrqConnData.name = BSP_PIT;
+  if (!BSP_get_current_rtems_irq_handler(&clockIrqConnData)) {
+    printk("Unable to stop system clock\n");
+    rtems_fatal_error_occurred(1);
+  }
+
+  BSP_remove_rtems_irq_handler (&clockIrqConnData);
+}
+
+rtems_device_driver Clock_initialize(rtems_device_major_number major,
+                                     rtems_device_minor_number minor,
+                                     void *pargp)
+{
+  Install_clock( Clock_isr );
+
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/powerpc/shared/clock/clock.c
===================================================================
--- bsps/powerpc/shared/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/powerpc/shared/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,247 @@
+/**
+ * @file
+ *
+ * @ingroup powerpc_shared
+ *
+ * @brief Source file for a clock driver.
+ */
+
+/*
+ * Copyright (c) 2008-2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <rtems/clockdrv.h>
+#include <rtems/timecounter.h>
+
+#include <libcpu/powerpc-utility.h>
+#include <bsp/vectors.h>
+
+#define RTEMS_STATUS_CHECKS_USE_PRINTK
+
+#include <rtems/status-checks.h>
+
+/*
+ * This variable must be defined in the BSP and valid before clock driver
+ * initialization.
+ */
+extern uint32_t bsp_time_base_frequency;
+
+#define PPC405_PIT 0x3db
+
+#define PPC_CLOCK_DECREMENTER_MAX UINT32_MAX
+
+volatile uint32_t Clock_driver_ticks = 0;
+
+static uint32_t ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX;
+
+static uint32_t ppc_clock_next_time_base;
+
+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)
+{
+  /* Do nothing */
+}
+
+static void (*ppc_clock_tick)(void) = ppc_clock_no_tick;
+
+static int ppc_clock_exception_handler(
+  BSP_Exception_frame *frame,
+  unsigned number
+)
+{
+  uint32_t delta = ppc_clock_decrementer_value;
+  uint32_t next = ppc_clock_next_time_base;
+  uint32_t dec = 0;
+  uint32_t now = 0;
+  uint32_t msr = 0;
+
+  do {
+    /* Increment clock ticks */
+    Clock_driver_ticks += 1;
+
+    /* Enable external exceptions */
+    msr = ppc_external_exceptions_enable();
+
+    /* Call clock ticker  */
+    ppc_clock_tick();
+
+    /* Restore machine state */
+    ppc_external_exceptions_disable( msr);
+
+    /* Next time base */
+    next += delta;
+
+    /* Current time */
+    now = ppc_time_base();
+
+    /* New decrementer value */
+    dec = next - now;
+  } while (dec > delta);
+
+  /* Set decrementer */
+  ppc_set_decrementer_register( dec);
+
+  /* Expected next time base */
+  ppc_clock_next_time_base = next;
+
+  return 0;
+}
+
+static int ppc_clock_exception_handler_first(
+  BSP_Exception_frame *frame,
+  unsigned number
+)
+{
+  /* We have to clear the first pending decrementer exception this way */
+
+  if (ppc_decrementer_register() >= 0x80000000) {
+    ppc_clock_exception_handler( frame, number);
+  }
+
+  ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler);
+
+  return 0;
+}
+
+static int ppc_clock_exception_handler_booke(
+  BSP_Exception_frame *frame,
+  unsigned number
+)
+{
+  uint32_t msr;
+
+  /* Acknowledge decrementer request */
+  PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_TSR, BOOKE_TSR_DIS);
+
+  /* Increment clock ticks */
+  Clock_driver_ticks += 1;
+
+  /* Enable external exceptions */
+  msr = ppc_external_exceptions_enable();
+
+  /* Call clock ticker  */
+  ppc_clock_tick();
+
+  /* Restore machine state */
+  ppc_external_exceptions_disable( msr);
+
+  return 0;
+}
+
+static int ppc_clock_exception_handler_ppc405(BSP_Exception_frame *frame, unsigned number)
+{
+  uint32_t msr;
+
+  /* Acknowledge PIT request */
+  PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_TSR, BOOKE_TSR_DIS);
+
+  /* Increment clock ticks */
+  Clock_driver_ticks += 1;
+
+  /* Enable external exceptions */
+  msr = ppc_external_exceptions_enable();
+
+  /* Call clock ticker  */
+  ppc_clock_tick();
+
+  /* Restore machine state */
+  ppc_external_exceptions_disable(msr);
+
+  return 0;
+}
+
+void Clock_exit(void)
+{
+  /* Set the decrementer to the maximum value */
+  ppc_set_decrementer_register( PPC_CLOCK_DECREMENTER_MAX);
+
+  /* Use default clock handler */
+  ppc_clock_tick = ppc_clock_no_tick;
+}
+
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *arg
+)
+{
+  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);
+
+  /*
+   * Set default ticker.
+   */
+  ppc_clock_tick = rtems_timecounter_tick;
+
+  if (ppc_cpu_is_bookE() != PPC_BOOKE_405) {
+    /* Decrementer value */
+    ppc_clock_decrementer_value = interval - 1;
+
+    /* Check decrementer value */
+    if (ppc_clock_decrementer_value == 0) {
+      ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX;
+      RTEMS_SYSLOG_ERROR( "decrementer value would be zero, will be set to maximum value instead\n");
+    }
+    if (ppc_cpu_is_bookE()) {
+      /* Set decrementer auto-reload value */
+      PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_DECAR, ppc_clock_decrementer_value);
+
+      /* Install exception handler */
+      ppc_exc_set_handler( ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_booke);
+
+      /* Enable decrementer and auto-reload */
+      PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( BOOKE_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE);
+    } else {
+      /* Here the decrementer value is actually the interval */
+      ++ppc_clock_decrementer_value;
+
+      /* Initialize next time base */
+      ppc_clock_next_time_base = ppc_time_base() + ppc_clock_decrementer_value;
+
+      /* Install exception handler */
+      ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler_first);
+    }
+
+    /* Set the decrementer value */
+    ppc_set_decrementer_register( ppc_clock_decrementer_value);
+  } else {
+    /* PIT interval value */
+    ppc_clock_decrementer_value = interval;
+
+    /* Install exception handler */
+    ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_ppc405);
+
+    /* Enable PIT and auto-reload */
+    PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(PPC405_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE);
+
+    /* Set PIT auto-reload and initial value */
+    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;
+}
Index: bsps/powerpc/shared/clock/p_clock.c
===================================================================
--- bsps/powerpc/shared/clock/p_clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/powerpc/shared/clock/p_clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,43 @@
+/*
+ *  Clock Tick interrupt conexion code.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-1997.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may in
+ *  the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ *  Modified to support the MPC750.
+ *  Modifications Copyright (c) 1999 Eric Valette valette@crf.canon.fr
+ */
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <libcpu/c_clock.h>
+#include <libcpu/cpuIdent.h>
+
+static rtems_irq_connect_data clockIrqData;
+static rtems_irq_connect_data clockIrqData = {
+  BSP_DECREMENTER,
+  clockIsr,
+  NULL,
+  (rtems_irq_enable)clockOn,
+  (rtems_irq_disable)clockOff,
+  (rtems_irq_is_enabled) clockIsOn
+};
+
+int BSP_disconnect_clock_handler(void)
+{
+  return BSP_remove_rtems_irq_handler(&clockIrqData);
+}
+
+int BSP_connect_clock_handler(void)
+{
+  if ( ppc_cpu_is_bookE() )
+    clockIrqData.hdl = clockIsrBookE;
+
+  return BSP_install_rtems_irq_handler(&clockIrqData);
+}
Index: bsps/powerpc/shared/dev/clock-ppc-dec.c
===================================================================
--- bsps/powerpc/shared/dev/clock-ppc-dec.c	(revision 5c5b021f518cb90289daa3ca0032aa57f0569e41)
+++ 	(revision )
@@ -1,266 +1,0 @@
-/**
- *  @brief Clock Tick Device Driver
- *
- *  This routine utilizes the Decrementer Register common to the PPC family.
- *
- *  The tick frequency is directly programmed to the configured number of
- *  microseconds per tick.
- */
-
-/*
- *  COPYRIGHT (c) 1989-2014.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may in
- *  the file LICENSE in this distribution or at
- *  http://www.rtems.org/license/LICENSE.
- *
- *  Modified to support the MPC750.
- *  Modifications Copyright (c) 1999 Eric Valette valette@crf.canon.fr
- */
-
-#include <rtems.h>
-#include <rtems/libio.h>
-#include <rtems/clockdrv.h>
-#include <stdlib.h>                     /* for atexit() */
-#include <assert.h>
-#include <libcpu/c_clock.h>
-#include <libcpu/cpuIdent.h>
-#include <libcpu/spr.h>
-#include <rtems/bspIo.h>                /* for printk() */
-#include <libcpu/powerpc-utility.h>
-#include <rtems/timecounter.h>
-#include <rtems/score/percpu.h>
-
-#include <bspopts.h>   /* for CLOCK_DRIVER_USE_FAST_IDLE */
-
-SPR_RW(BOOKE_TCR)
-SPR_RW(BOOKE_TSR)
-SPR_RW(BOOKE_DECAR)
-
-extern int BSP_connect_clock_handler (void);
-
-/*
- *  Clock ticks since initialization
- */
-volatile uint32_t   Clock_driver_ticks;
-
-/*
- *  This is the value programmed into the count down timer.
- */
-static uint32_t   Clock_Decrementer_value;
-
-static struct timecounter Clock_TC;
-
-static uint32_t Clock_Get_timecount(struct timecounter *tc)
-{
-  return ppc_time_base();
-}
-
-void clockOff(void* unused)
-{
-  rtems_interrupt_level l;
-
-  if ( ppc_cpu_is_bookE() ) {
-    rtems_interrupt_disable(l);
-    _write_BOOKE_TCR(_read_BOOKE_TCR() & ~BOOKE_TCR_DIE);
-    rtems_interrupt_enable(l);
-  } else {
-    /*
-     * Nothing to do as we cannot disable all interrupts and
-     * the decrementer interrupt enable is MSR_EE
-     */
-  }
-}
-
-void clockOn(void* unused)
-{
-  rtems_interrupt_level l;
-
-  PPC_Set_decrementer( Clock_Decrementer_value );
-
-  if ( ppc_cpu_is_bookE() ) {
-    _write_BOOKE_DECAR( Clock_Decrementer_value );
-
-    rtems_interrupt_disable(l);
-
-    /* clear pending/stale irq */
-    _write_BOOKE_TSR( BOOKE_TSR_DIS );
-    /* enable */
-    _write_BOOKE_TCR( _read_BOOKE_TCR() | BOOKE_TCR_DIE );
-
-    rtems_interrupt_enable(l);
-
-  }
-}
-
-static void clockHandler(void)
-{
-  #if (CLOCK_DRIVER_USE_FAST_IDLE == 1)
-    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->is_idle ) {
-      tb += Clock_Decrementer_value;
-      ppc_set_time_base( tb );
-      rtems_timecounter_tick();
-    }
-
-    rtems_interrupt_enable(level);
-  #else
-    rtems_timecounter_tick();
-  #endif
-}
-
-static void (*clock_handler)(void);
-
-/*
- *  Clock_isr
- *
- *  This is the clock tick interrupt handler.
- *
- *  Input parameters:
- *    vector - vector number
- *
- *  Output parameters:  NONE
- *
- *  Return values:      NONE
- *
- */
-void clockIsr(void *unused)
-{
-  int decr;
-
-  /*
-   *  The driver has seen another tick.
-   */
-  do {
-    register uint32_t flags;
-
-    rtems_interrupt_disable(flags);
-      __asm__ volatile (
-	"mfdec %0; add %0, %0, %1; mtdec %0"
-	: "=&r"(decr)
-	: "r"(Clock_Decrementer_value)
-      );
-    rtems_interrupt_enable(flags);
-
-    Clock_driver_ticks += 1;
-    /*
-     *  Real Time Clock counter/timer is set to automatically reload.
-     */
-    clock_handler();
-  } while ( decr < 0 );
-}
-
-/*
- *  Clock_isr_bookE
- *
- *  This is the clock tick interrupt handler
- *  for bookE CPUs. For efficiency reasons we
- *  provide a separate handler rather than
- *  checking the CPU type each time.
- */
-void clockIsrBookE(void *unused)
-{
-  /* Note: TSR bit has already been cleared in the exception handler */
-
-  /*
-   *  The driver has seen another tick.
-   */
-
-  Clock_driver_ticks += 1;
-
-  /*
-   *  Real Time Clock counter/timer is set to automatically reload.
-   */
-  clock_handler();
-}
-
-int clockIsOn(void* unused)
-{
-  uint32_t   msr_value;
-
-  _CPU_MSR_GET( msr_value );
-
-  if ( ppc_cpu_is_bookE() && ! (_read_BOOKE_TCR() & BOOKE_TCR_DIE) )
-    msr_value = 0;
-
-  if (msr_value & MSR_EE) return 1;
-
-  return 0;
-}
-
-/*
- *  Clock_exit
- *
- *  This routine allows the clock driver to exit by masking the interrupt and
- *  disabling the clock's counter.
- */
-void Clock_exit( void )
-{
-  (void) BSP_disconnect_clock_handler ();
-}
-
-/*
- *  Clock_initialize
- *
- *  This routine initializes the clock driver.
- */
-rtems_device_driver Clock_initialize(
-  rtems_device_major_number major,
-  rtems_device_minor_number minor,
-  void *pargp
-)
-{
-  rtems_interrupt_level l,tcr;
-
-  Clock_Decrementer_value = (BSP_bus_frequency/BSP_time_base_divisor)*
-            rtems_configuration_get_milliseconds_per_tick();
-
-  /* set the decrementer now, prior to installing the handler
-   * so no interrupts will happen in a while.
-   */
-  PPC_Set_decrementer( (unsigned)-1 );
-
-  /* On a bookE CPU the decrementer works differently. It doesn't
-   * count past zero but we can enable auto-reload :-)
-   */
-  if ( ppc_cpu_is_bookE() ) {
-
-    rtems_interrupt_disable(l);
-
-      tcr  = _read_BOOKE_TCR();
-      tcr |= BOOKE_TCR_ARE;
-      tcr &= ~BOOKE_TCR_DIE;
-      _write_BOOKE_TCR(tcr);
-
-    rtems_interrupt_enable(l);
-  }
-
-  Clock_TC.tc_get_timecount = Clock_Get_timecount;
-  Clock_TC.tc_counter_mask = 0xffffffff;
-  Clock_TC.tc_frequency = (UINT64_C(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;
-   * The next exception will then be taken by our clock handler.
-   * Clock handler installation initializes the decrementer to
-   * the correct value.
-   */
-  clock_handler = clockHandler;
-  if (!BSP_connect_clock_handler ()) {
-    printk("Unable to initialize system clock\n");
-    rtems_fatal_error_occurred(1);
-  }
-
-  return RTEMS_SUCCESSFUL;
-} /* Clock_initialize */
Index: bsps/powerpc/shared/dev/clock-ppc403.c
===================================================================
--- bsps/powerpc/shared/dev/clock-ppc403.c	(revision 5c5b021f518cb90289daa3ca0032aa57f0569e41)
+++ 	(revision )
@@ -1,275 +1,0 @@
-/**
- *  @file
- *
- *  This routine initializes the interval timer on the
- *  PowerPC 403 CPU.  The tick frequency is specified by the BSP.
- */
-
-/*
- *  Original PPC403 Code from:
- *  Author: Andrew Bray <andy@i-cubed.co.uk>
- *  COPYRIGHT (c) 1995 by i-cubed ltd.
- *
- *  Modifications for PPC405GP by Dennis Ehlin
- *
- *  To anyone who acknowledges that this file is provided "AS IS"
- *  without any express or implied warranty:
- *      permission to use, copy, modify, and distribute this file
- *      for any purpose is hereby granted without fee, provided that
- *      the above copyright notice and this notice appears in all
- *      copies, and that the name of i-cubed limited not be used in
- *      advertising or publicity pertaining to distribution of the
- *      software without specific, written prior permission.
- *      i-cubed limited makes no representations about the suitability
- *      of this software for any purpose.
- *
- *  Modifications for deriving timer clock from cpu system clock by
- *              Thomas Doerfler <td@imd.m.isar.de>
- *  for these modifications:
- *  COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
- *
- *  COPYRIGHT (c) 1989-2012.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.org/license/LICENSE.
- */
-
-#include <rtems.h>
-#include <rtems/clockdrv.h>
-#include <rtems/libio.h>
-#include <stdlib.h>                     /* for atexit() */
-#include <rtems/bspIo.h>
-#include <rtems/powerpc/powerpc.h>
-
-/*
- * check, which exception handling code is present
- */
-
-#include <bsp.h>
-
-#include <bsp/vectors.h>
-#include <bsp/irq.h>
-
-extern uint32_t   bsp_clicks_per_usec;
-
-volatile uint32_t Clock_driver_ticks;
-static uint32_t   pit_value, tick_time;
-static bool       auto_restart;
-
-void Clock_exit( void );
-
-static inline uint32_t get_itimer(void)
-{
-  register uint32_t rc;
-
-#ifndef ppc405 /* this is a ppc403 */
-  __asm__ volatile ("mfspr %0, 0x3dd" : "=r" ((rc))); /* TBLO */
-#else /* ppc405 */
-  __asm__ volatile ("mfspr %0, 0x10c" : "=r" ((rc))); /* 405GP TBL */
-#endif /* ppc405 */
-
-  return rc;
-}
-
-/*
- *  ISR Handler
- */
-static void Clock_isr(void* handle)
-{
-  uint32_t clicks_til_next_interrupt;
-#if defined(BSP_PPC403_CLOCK_ISR_IRQ_LEVEL)
-  uint32_t l_orig = _ISR_Get_level();
-#endif
-
-  if (!auto_restart) {
-    uint32_t itimer_value;
-    /*
-     * setup for next interrupt; making sure the new value is reasonably
-     * in the future.... in case we lost out on an interrupt somehow
-     */
-    itimer_value = get_itimer();
-    tick_time += pit_value;
-
-    /*
-     * how far away is next interrupt *really*
-     * It may be a long time; this subtraction works even if
-     * Clock_clicks_interrupt < Clock_clicks_low_order via
-     * the miracle of unsigned math.
-     */
-    clicks_til_next_interrupt = tick_time - itimer_value;
-
-    /*
-     * If it is too soon then bump it up.
-     * This should only happen if CPU_HPPA_CLICKS_PER_TICK is too small.
-     * But setting it low is useful for debug, so...
-     */
-    if (clicks_til_next_interrupt < 400) {
-      tick_time = itimer_value + 1000;
-      clicks_til_next_interrupt = 1000;
-      /* XXX: count these! this should be rare */
-    }
-
-    /*
-     * If it is too late, that means we missed the interrupt somehow.
-     * Rather than wait 35-50s for a wrap, we just fudge it here.
-     */
-    if (clicks_til_next_interrupt > pit_value) {
-      tick_time = itimer_value + 1000;
-      clicks_til_next_interrupt = 1000;
-      /* XXX: count these! this should never happen :-) */
-    }
-
-    __asm__ volatile ("mtspr 0x3db, %0" :: "r"
-                      (clicks_til_next_interrupt));                  /* PIT */
-  }
-
-  __asm__ volatile ("mtspr 0x3d8, %0" :: "r" (0x08000000));          /* TSR */
-
-  Clock_driver_ticks++;
-
-  /* Give BSP a chance to say if they want to re-enable interrupts */
-#if defined(BSP_PPC403_CLOCK_ISR_IRQ_LEVEL)
-  _ISR_Set_level(BSP_PPC403_CLOCK_ISR_IRQ_LEVEL);
-#endif
-  rtems_clock_tick();
-
-#if defined(BSP_PPC403_CLOCK_ISR_IRQ_LEVEL)
-  _ISR_Set_level(l_orig)
-#endif
-}
-
-static int ClockIsOn(const rtems_irq_connect_data* unused)
-{
-  register uint32_t tcr;
-
-  __asm__ volatile ("mfspr %0, 0x3da" : "=r" ((tcr)));               /* TCR */
-
-  return (tcr & 0x04000000) != 0;
-}
-
-static void ClockOff(const rtems_irq_connect_data* unused)
-{
-  register uint32_t tcr;
-
-  __asm__ volatile ("mfspr %0, 0x3da" : "=r" ((tcr)));               /* TCR */
-  tcr &= ~ 0x04400000;
-  __asm__ volatile ("mtspr 0x3da, %0" : "=r" ((tcr)) : "0" ((tcr))); /* TCR */
-}
-
-static void ClockOn(const rtems_irq_connect_data* unused)
-{
-  uint32_t          iocr;
-  register uint32_t tcr;
-#ifndef ppc405
-  uint32_t          pvr;
-#endif /* ppc403 */
-
-  Clock_driver_ticks = 0;
-
-#ifndef ppc405 /* this is a ppc403 */
-  __asm__ volatile ("mfdcr %0, 0xa0" : "=r" (iocr));              /* IOCR */
-  iocr &= ~4;                         /* timer clocked from system clock */
-  __asm__ volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); /* IOCR */
-
-  __asm__ volatile ("mfspr %0, 0x11f" : "=r" ((pvr))); /* PVR */
-  if (((pvr & 0xffff0000) >> 16) != 0x0020)
-    return;                             /* Not a ppc403 */
-
-  if ((pvr & 0xff00) == 0x0000)         /* 403GA */
-#if 0 /* FIXME: in which processor versions will "autoload" work properly? */
-    auto_restart = (pvr & 0x00f0) > 0x0000 ? true : false;
-#else
-    /* no known chip version supports auto restart of timer... */
-    auto_restart = false;
-#endif
-  else if ((pvr & 0xff00) == 0x0100)    /* 403GB */
-    auto_restart = true;
-
-#else /* ppc405 */
-  __asm__ volatile ("mfdcr %0, 0x0b2" : "=r" (iocr));              /*405GP CPC0_CR1 */
-  iocr &=~0x800000;               /* timer clocked from system clock CETE*/
-  __asm__ volatile ("mtdcr 0x0b2, %0" : "=r" (iocr) : "0" (iocr)); /* 405GP CPC0_CR1 */
-
-  /*
-   * Enable auto restart
-   */
-  auto_restart = true;
-#endif /* ppc405 */
-
-  pit_value = rtems_configuration_get_microseconds_per_tick() *
-                bsp_clicks_per_usec;
-
-  /*
-   * Set PIT value
-   */
-  __asm__ volatile ("mtspr 0x3db, %0" : : "r" (pit_value)); /* PIT */
-
-  /*
-   * Set timer to autoreload, bit TCR->ARE = 1  0x0400000
-   * Enable PIT interrupt,    bit TCR->PIE = 1  0x4000000
-   */
-  tick_time = get_itimer() + pit_value;
-
-  __asm__ volatile ("mfspr %0, 0x3da" : "=r" ((tcr)));               /* TCR */
-  tcr = (tcr & ~0x04400000) | (auto_restart ? 0x04400000 : 0x04000000);
-#if 1
-  __asm__ volatile ("mtspr 0x3da, %0" : "=r" ((tcr)) : "0" ((tcr))); /* TCR */
-#endif
-}
-
-static void Install_clock(void (*clock_isr)(void *))
-{
-  rtems_irq_connect_data clockIrqConnData;
-
-  Clock_driver_ticks = 0;
-
-  /*
-   * initialize the interval here
-   * First tick is set to right amount of time in the future
-   * Future ticks will be incremented over last value set
-   * in order to provide consistent clicks in the face of
-   * interrupt overhead
-   */
-  clockIrqConnData.on   = ClockOn;
-  clockIrqConnData.off  = ClockOff;
-  clockIrqConnData.isOn = ClockIsOn;
-  clockIrqConnData.name = BSP_PIT;
-  clockIrqConnData.hdl  = clock_isr;
-  if (!BSP_install_rtems_irq_handler (&clockIrqConnData)) {
-    printk("Unable to connect Clock Irq handler\n");
-    rtems_fatal_error_occurred(1);
-  }
-
-  atexit(Clock_exit);
-}
-
-/*
- * Called via atexit()
- * Remove the clock interrupt handler by setting handler to NULL
- *
- * This will not work on the 405GP because
- * when bit's are set in TCR they can only be unset by a reset
- */
-void Clock_exit(void)
-{
-  rtems_irq_connect_data clockIrqConnData;
-
-  clockIrqConnData.name = BSP_PIT;
-  if (!BSP_get_current_rtems_irq_handler(&clockIrqConnData)) {
-    printk("Unable to stop system clock\n");
-    rtems_fatal_error_occurred(1);
-  }
-
-  BSP_remove_rtems_irq_handler (&clockIrqConnData);
-}
-
-rtems_device_driver Clock_initialize(rtems_device_major_number major,
-                                     rtems_device_minor_number minor,
-                                     void *pargp)
-{
-  Install_clock( Clock_isr );
-
-  return RTEMS_SUCCESSFUL;
-}
Index: bsps/powerpc/ss555/clock/clock.c
===================================================================
--- bsps/powerpc/ss555/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/powerpc/ss555/clock/clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,144 @@
+/*
+ *  This routine initializes the PIT on the MPC5xx.
+ *  The tick frequency is specified by the BSP.
+ */
+
+/*
+ *  MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ *  Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ *  Derived from c/src/lib/libcpu/powerpc/mpc8xx/clock/clock.c:
+ *
+ *  Author: Jay Monkman (jmonkman@frasca.com)
+ *  Copyright (C) 1998 by Frasca International, Inc.
+ *
+ *  Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c:
+ *
+ *  Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ *  COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ *  To anyone who acknowledges that this file is provided "AS IS"
+ *  without any express or implied warranty:
+ *      permission to use, copy, modify, and distribute this file
+ *      for any purpose is hereby granted without fee, provided that
+ *      the above copyright notice and this notice appears in all
+ *      copies, and that the name of i-cubed limited not be used in
+ *      advertising or publicity pertaining to distribution of the
+ *      software without specific, written prior permission.
+ *      i-cubed limited makes no representations about the suitability
+ *      of this software for any purpose.
+ *
+ *  Derived from c/src/lib/libcpu/hppa1_1/clock/clock.c:
+ *
+ *  COPYRIGHT (c) 1989-2007.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <rtems/clockdrv.h>
+#include <rtems/libio.h>
+#include <libcpu/irq.h>
+
+#include <stdlib.h>                     /* for atexit() */
+#include <mpc5xx.h>
+
+volatile uint32_t Clock_driver_ticks;
+extern int BSP_connect_clock_handler(rtems_isr_entry);
+extern int BSP_disconnect_clock_handler(void);
+extern uint32_t bsp_clicks_per_usec;
+
+void Clock_exit( void );
+
+/*
+ *  ISR Handler
+ */
+rtems_isr Clock_isr(rtems_vector_number vector)
+{
+  usiu.piscrk = USIU_UNLOCK_KEY;
+  usiu.piscr |= USIU_PISCR_PS;			/* acknowledge interrupt */
+  usiu.piscrk = 0;
+
+  Clock_driver_ticks++;
+  rtems_clock_tick();
+}
+
+void clockOn(void* unused)
+{
+  unsigned desiredLevel;
+  uint32_t pit_value;
+
+  /* calculate and set modulus */
+  pit_value = (rtems_configuration_get_microseconds_per_tick() *
+               bsp_clicks_per_usec) - 1 ;
+
+  if (pit_value > 0xffff) {           /* pit is only 16 bits long */
+    rtems_fatal_error_occurred(-1);
+  }
+  usiu.sccrk = USIU_UNLOCK_KEY;
+  usiu.sccr &= ~USIU_SCCR_RTDIV;	/* RTC and PIT clock is divided by 4 */
+  usiu.sccrk = 0;
+
+  usiu.pitck = USIU_UNLOCK_KEY;
+  usiu.pitc = pit_value;
+  usiu.pitck = 0;
+
+  /* set PIT irq level, enable PIT, PIT interrupts */
+  /*  and clear int. status */
+  desiredLevel = CPU_irq_level_from_symbolic_name(CPU_PERIODIC_TIMER);
+
+  usiu.piscrk = USIU_UNLOCK_KEY;
+  usiu.piscr = USIU_PISCR_PIRQ(desiredLevel) 	/* set interrupt priority */
+             | USIU_PISCR_PS			/* acknowledge interrupt */
+             | USIU_PISCR_PIE			/* enable interrupt */
+             | USIU_PISCR_PITF			/* freeze during debug */
+             | USIU_PISCR_PTE;			/* enable timer */
+  usiu.piscrk = 0;
+}
+
+void clockOff(void* unused)
+{
+  /* disable PIT and PIT interrupts */
+  usiu.piscrk = USIU_UNLOCK_KEY;
+  usiu.piscr &= ~(USIU_PISCR_PTE | USIU_PISCR_PIE);
+  usiu.piscrk = 0;
+}
+
+int clockIsOn(void* unused)
+{
+  if (usiu.piscr & USIU_PISCR_PIE)
+    return 1;
+  return 0;
+}
+
+/*
+ * Called via atexit()
+ * Remove the clock interrupt handler by setting handler to NULL
+ */
+void Clock_exit(void)
+{
+  (void) BSP_disconnect_clock_handler ();
+}
+
+static void Install_clock(rtems_isr_entry clock_isr)
+{
+  Clock_driver_ticks = 0;
+
+  BSP_connect_clock_handler (clock_isr);
+  atexit(Clock_exit);
+}
+
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  Install_clock( Clock_isr );
+
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/powerpc/ss555/clock/p_clock.c
===================================================================
--- bsps/powerpc/ss555/clock/p_clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/powerpc/ss555/clock/p_clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,63 @@
+/*
+ *  Clock Tick interrupt conexion code.
+ *
+ *  COPYRIGHT (c) 1989-1997.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may in
+ *  the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ *  SS555 port sponsored by Defence Research and Development Canada - Suffield
+ *  Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ *  Derived from c/src/lib/libbsp/powerpc/mbx8xx/clock/p_clock.c:
+ *
+ *  Modified to support the MPC750.
+ *  Modifications Copyright (c) 1999 Eric Valette valette@crf.canon.fr
+ */
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <rtems/bspIo.h>
+#include <mpc5xx.h>
+
+static rtems_irq_connect_data clockIrqData = {
+  CPU_PERIODIC_TIMER,
+  (rtems_irq_hdl)Clock_isr,
+  NULL,
+  (rtems_irq_enable)clockOn,
+  (rtems_irq_disable)clockOff,
+  (rtems_irq_is_enabled)clockIsOn
+};
+
+int BSP_disconnect_clock_handler (void)
+{
+  if (!BSP_get_current_rtems_irq_handler(&clockIrqData)) {
+     printk("Unable to stop system clock\n");
+    rtems_fatal_error_occurred(1);
+  }
+  return BSP_remove_rtems_irq_handler (&clockIrqData);
+}
+
+int BSP_connect_clock_handler (rtems_irq_hdl hdl)
+{
+  if (!BSP_get_current_rtems_irq_handler(&clockIrqData)) {
+     printk("Unable to get system clock handler\n");
+    rtems_fatal_error_occurred(1);
+  }
+  if (!BSP_remove_rtems_irq_handler (&clockIrqData)) {
+   printk("Unable to remove current system clock handler\n");
+    rtems_fatal_error_occurred(1);
+  }
+  /*
+   * Reinit structure
+   */
+  clockIrqData.name = CPU_PERIODIC_TIMER;
+  clockIrqData.hdl = (rtems_irq_hdl) hdl;
+  clockIrqData.on = (rtems_irq_enable)clockOn;
+  clockIrqData.off = (rtems_irq_enable)clockOff;
+  clockIrqData.isOn = (rtems_irq_is_enabled)clockIsOn;
+
+  return BSP_install_rtems_irq_handler (&clockIrqData);
+}
Index: bsps/powerpc/ss555/dev/clock.c
===================================================================
--- bsps/powerpc/ss555/dev/clock.c	(revision 5c5b021f518cb90289daa3ca0032aa57f0569e41)
+++ 	(revision )
@@ -1,144 +1,0 @@
-/*
- *  This routine initializes the PIT on the MPC5xx.
- *  The tick frequency is specified by the BSP.
- */
-
-/*
- *  MPC5xx port sponsored by Defence Research and Development Canada - Suffield
- *  Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
- *
- *  Derived from c/src/lib/libcpu/powerpc/mpc8xx/clock/clock.c:
- *
- *  Author: Jay Monkman (jmonkman@frasca.com)
- *  Copyright (C) 1998 by Frasca International, Inc.
- *
- *  Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c:
- *
- *  Author: Andrew Bray <andy@i-cubed.co.uk>
- *
- *  COPYRIGHT (c) 1995 by i-cubed ltd.
- *
- *  To anyone who acknowledges that this file is provided "AS IS"
- *  without any express or implied warranty:
- *      permission to use, copy, modify, and distribute this file
- *      for any purpose is hereby granted without fee, provided that
- *      the above copyright notice and this notice appears in all
- *      copies, and that the name of i-cubed limited not be used in
- *      advertising or publicity pertaining to distribution of the
- *      software without specific, written prior permission.
- *      i-cubed limited makes no representations about the suitability
- *      of this software for any purpose.
- *
- *  Derived from c/src/lib/libcpu/hppa1_1/clock/clock.c:
- *
- *  COPYRIGHT (c) 1989-2007.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.org/license/LICENSE.
- */
-
-#include <rtems.h>
-#include <rtems/clockdrv.h>
-#include <rtems/libio.h>
-#include <libcpu/irq.h>
-
-#include <stdlib.h>                     /* for atexit() */
-#include <mpc5xx.h>
-
-volatile uint32_t Clock_driver_ticks;
-extern int BSP_connect_clock_handler(rtems_isr_entry);
-extern int BSP_disconnect_clock_handler(void);
-extern uint32_t bsp_clicks_per_usec;
-
-void Clock_exit( void );
-
-/*
- *  ISR Handler
- */
-rtems_isr Clock_isr(rtems_vector_number vector)
-{
-  usiu.piscrk = USIU_UNLOCK_KEY;
-  usiu.piscr |= USIU_PISCR_PS;			/* acknowledge interrupt */
-  usiu.piscrk = 0;
-
-  Clock_driver_ticks++;
-  rtems_clock_tick();
-}
-
-void clockOn(void* unused)
-{
-  unsigned desiredLevel;
-  uint32_t pit_value;
-
-  /* calculate and set modulus */
-  pit_value = (rtems_configuration_get_microseconds_per_tick() *
-               bsp_clicks_per_usec) - 1 ;
-
-  if (pit_value > 0xffff) {           /* pit is only 16 bits long */
-    rtems_fatal_error_occurred(-1);
-  }
-  usiu.sccrk = USIU_UNLOCK_KEY;
-  usiu.sccr &= ~USIU_SCCR_RTDIV;	/* RTC and PIT clock is divided by 4 */
-  usiu.sccrk = 0;
-
-  usiu.pitck = USIU_UNLOCK_KEY;
-  usiu.pitc = pit_value;
-  usiu.pitck = 0;
-
-  /* set PIT irq level, enable PIT, PIT interrupts */
-  /*  and clear int. status */
-  desiredLevel = CPU_irq_level_from_symbolic_name(CPU_PERIODIC_TIMER);
-
-  usiu.piscrk = USIU_UNLOCK_KEY;
-  usiu.piscr = USIU_PISCR_PIRQ(desiredLevel) 	/* set interrupt priority */
-             | USIU_PISCR_PS			/* acknowledge interrupt */
-             | USIU_PISCR_PIE			/* enable interrupt */
-             | USIU_PISCR_PITF			/* freeze during debug */
-             | USIU_PISCR_PTE;			/* enable timer */
-  usiu.piscrk = 0;
-}
-
-void clockOff(void* unused)
-{
-  /* disable PIT and PIT interrupts */
-  usiu.piscrk = USIU_UNLOCK_KEY;
-  usiu.piscr &= ~(USIU_PISCR_PTE | USIU_PISCR_PIE);
-  usiu.piscrk = 0;
-}
-
-int clockIsOn(void* unused)
-{
-  if (usiu.piscr & USIU_PISCR_PIE)
-    return 1;
-  return 0;
-}
-
-/*
- * Called via atexit()
- * Remove the clock interrupt handler by setting handler to NULL
- */
-void Clock_exit(void)
-{
-  (void) BSP_disconnect_clock_handler ();
-}
-
-static void Install_clock(rtems_isr_entry clock_isr)
-{
-  Clock_driver_ticks = 0;
-
-  BSP_connect_clock_handler (clock_isr);
-  atexit(Clock_exit);
-}
-
-rtems_device_driver Clock_initialize(
-  rtems_device_major_number major,
-  rtems_device_minor_number minor,
-  void *pargp
-)
-{
-  Install_clock( Clock_isr );
-
-  return RTEMS_SUCCESSFUL;
-}
Index: bsps/powerpc/t32mppc/clock/clock-config.c
===================================================================
--- bsps/powerpc/t32mppc/clock/clock-config.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/powerpc/t32mppc/clock/clock-config.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011, 2017 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems/timecounter.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+
+/* This is defined in dev/clock/clockimpl.h */
+static rtems_isr Clock_isr(void *arg);
+
+static struct timecounter t32mppc_clock_tc;
+
+#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR
+
+void t32mppc_decrementer_dispatch(void)
+{
+  PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_TSR, BOOKE_TSR_DIS);
+  Clock_isr(NULL);
+}
+
+static uint32_t t32mppc_clock_get_timecount(struct timecounter *tc)
+{
+  return ppc_time_base();
+}
+
+static void t32mppc_clock_initialize(void)
+{
+  uint64_t frequency = bsp_time_base_frequency / 10;
+  uint32_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
+  uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000);
+
+  PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_DECAR, interval - 1);
+  PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(
+    BOOKE_TCR,
+    BOOKE_TCR_DIE | BOOKE_TCR_ARE
+  );
+  ppc_set_decrementer_register(interval - 1);
+
+  t32mppc_clock_tc.tc_get_timecount = t32mppc_clock_get_timecount;
+  t32mppc_clock_tc.tc_counter_mask = 0xffffffff;
+  t32mppc_clock_tc.tc_frequency = bsp_time_base_frequency;
+  t32mppc_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+  rtems_timecounter_install(&t32mppc_clock_tc);
+}
+
+#define Clock_driver_support_initialize_hardware() \
+  t32mppc_clock_initialize()
+
+/* Include shared source clock driver code */
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/powerpc/tqm8xx/clock/p_clock.c
===================================================================
--- bsps/powerpc/tqm8xx/clock/p_clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/powerpc/tqm8xx/clock/p_clock.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,58 @@
+/*
+ *  Clock Tick interrupt conexion code.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-1997.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may in
+ *  the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ *  Modified to support the MPC750.
+ *  Modifications Copyright (c) 1999 Eric Valette valette@crf.canon.fr
+ */
+
+#include <bsp.h>
+#include <bsp/irq-generic.h>
+#include <rtems/bspIo.h>
+
+extern void clockOn(void*);
+extern void clockOff (void*);
+extern int clockIsOn(void*);
+extern void Clock_isr(void*);
+
+static void BSP_clock_hdl(void * arg)
+{
+  Clock_isr(arg);
+}
+
+int BSP_disconnect_clock_handler (void)
+{
+  rtems_status_code sc;
+
+  clockOff(NULL);
+  /*
+   * remove interrupt handler
+   */
+  sc = rtems_interrupt_handler_remove(BSP_PERIODIC_TIMER,
+				      BSP_clock_hdl,NULL);
+
+  return sc == RTEMS_SUCCESSFUL;
+}
+
+int BSP_connect_clock_handler (rtems_irq_hdl hdl)
+{
+  rtems_status_code sc;
+  /*
+   * install interrupt handler
+   */
+  sc = rtems_interrupt_handler_install(BSP_PERIODIC_TIMER,
+				       "PIT clock",0,
+				       BSP_clock_hdl,NULL);
+  if (sc == RTEMS_SUCCESSFUL) {
+    clockOn(NULL);
+  }
+  return sc == RTEMS_SUCCESSFUL;
+}
Index: bsps/riscv/riscv_generic/clock/clockdrv.c
===================================================================
--- bsps/riscv/riscv_generic/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/riscv/riscv_generic/clock/clockdrv.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,131 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_clock
+ *
+ * @brief riscv clock support.
+ */
+
+/*
+ * riscv_generic Clock driver
+ *
+ * COPYRIGHT (c) 2015 Hesham Alatary <hesham@alumni.york.ac.uk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <rtems/score/riscv-utility.h>
+#include <rtems/score/cpu.h>
+#include <rtems/timecounter.h>
+
+/* The number of clock cycles before generating a tick timer interrupt. */
+#define TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT     1000
+#define RISCV_CLOCK_CYCLE_TIME_NANOSECONDS    1
+
+static struct timecounter riscv_generic_tc;
+
+/* CPU counter */
+static CPU_Counter_ticks cpu_counter_ticks;
+
+/* This prototype is added here to Avoid warnings */
+void Clock_isr(void *arg);
+
+static void riscv_generic_clock_at_tick(void)
+{
+  REG(MTIME_MM) = 0;
+  REG(MTIMECMP_MM) = TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT;
+
+  cpu_counter_ticks += TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT * 10000;
+}
+
+static void riscv_generic_clock_handler_install(proc_ptr new_isr)
+{
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+  _CPU_ISR_install_vector(RISCV_MACHINE_TIMER_INTERRUPT,
+                          new_isr,
+                          NULL);
+
+  if (sc != RTEMS_SUCCESSFUL) {
+    rtems_fatal_error_occurred(0xdeadbeef);
+  }
+}
+
+static uint32_t riscv_generic_get_timecount(struct timecounter *tc)
+{
+  uint32_t ticks_since_last_timer_interrupt = REG(MTIME_MM);
+
+  return cpu_counter_ticks + ticks_since_last_timer_interrupt;
+}
+
+CPU_Counter_ticks _CPU_Counter_read(void)
+{
+  return riscv_generic_get_timecount(NULL);
+}
+
+static void riscv_generic_clock_initialize(void)
+{
+  uint32_t mtimecmp = TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT;
+  uint64_t frequency = (1000000000 / RISCV_CLOCK_CYCLE_TIME_NANOSECONDS);
+
+  REG(MTIME_MM) = 0;
+  REG(MTIMECMP_MM) = TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT;
+
+  /* Enable mtimer interrupts */
+  set_csr(mie, MIP_MTIP);
+  set_csr(mip, MIP_MTIP);
+
+  /* Initialize timecounter */
+  riscv_generic_tc.tc_get_timecount = riscv_generic_get_timecount;
+  riscv_generic_tc.tc_counter_mask = 0xffffffff;
+  riscv_generic_tc.tc_frequency = frequency;
+  riscv_generic_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+  rtems_timecounter_install(&riscv_generic_tc);
+}
+
+static void riscv_generic_clock_cleanup(void)
+{
+  /* Disable mtimer interrupts */
+  clear_csr(mie, MIP_MTIP);
+  clear_csr(mip, MIP_MTIP);
+}
+
+CPU_Counter_ticks _CPU_Counter_difference(
+  CPU_Counter_ticks second,
+  CPU_Counter_ticks first
+)
+{
+  return second - first;
+}
+
+#define Clock_driver_support_at_tick() riscv_generic_clock_at_tick()
+
+#define Clock_driver_support_initialize_hardware() riscv_generic_clock_initialize()
+
+#define Clock_driver_support_install_isr(isr) \
+  riscv_generic_clock_handler_install(isr)
+
+#define Clock_driver_support_shutdown_hardware() riscv_generic_clock_cleanup()
+
+#include "../../../shared/dev/clock/clockimpl.h"
Index: bsps/sh/gensh1/clock/ckinit.c
===================================================================
--- bsps/sh/gensh1/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/sh/gensh1/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,306 @@
+/*
+ *  This file contains the clock driver the Hitachi SH 703X
+ */
+
+/*
+ *  Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
+ *           Bernd Becker (becker@faw.uni-ulm.de)
+ *
+ *  COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *  COPYRIGHT (c) 1998.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+
+#include <stdlib.h>
+
+#include <rtems/clockdrv.h>
+#include <rtems/score/sh_io.h>
+#include <rtems/score/sh.h>
+#include <rtems/score/ispsh7032.h>
+#include <rtems/score/iosh7032.h>
+
+extern uint32_t bsp_clicks_per_second;
+
+#ifndef CLOCKPRIO
+#define CLOCKPRIO 10
+#endif
+
+#define I_CLK_PHI_1	0
+#define I_CLK_PHI_2	1
+#define I_CLK_PHI_4	2
+#define I_CLK_PHI_8	3
+
+/*
+ * Set I_CLK_PHI to one of the I_CLK_PHI_X values from above to choose
+ * a PHI/X clock rate.
+ */
+
+#define I_CLK_PHI 	I_CLK_PHI_4
+#define CLOCK_SCALE	(1<<I_CLK_PHI)
+
+#define ITU0_STARTMASK 	0xfe
+#define ITU0_SYNCMASK 	0xfe
+#define ITU0_MODEMASK 	0xfe
+#define ITU0_TCRMASK 	(0x20 | I_CLK_PHI)
+#define ITU_STAT_MASK 	0xf8
+#define ITU0_IRQMASK 	0xfe
+#define ITU0_TIERMASK 	0x01
+#define IPRC_ITU0_MASK 	0xff0f
+#define ITU0_TIORVAL 	0x08
+
+/*
+ * clicks_per_tick := clicks_per_sec * usec_per_tick
+ *
+ * This is a very expensive function ;-)
+ *
+ * Below are two variants:
+ * 1. A variant applying integer arithmetics, only.
+ * 2. A variant applying floating point arithmetics
+ *
+ * The floating point variant pulls in the fmath routines when linking,
+ * resulting in slightly larger executables for applications that do not
+ * apply fmath otherwise. However, the imath variant is significantly slower
+ * than the fmath variant and more complex.
+ *
+ * Assuming that most applications will not use fmath, but are critical
+ * in memory size constraints, we apply the integer variant.
+ *
+ * To the sake of simplicity, we might abandon one of both variants in
+ * future.
+ */
+static unsigned int sh_clicks_per_tick(
+  unsigned int clicks_per_sec,
+  unsigned int usec_per_tick
+)
+{
+#if 1
+  unsigned int clicks_per_tick = 0 ;
+
+  unsigned int b = clicks_per_sec ;
+  unsigned int c = 1000000 ;
+  unsigned int d = 1 ;
+  unsigned int a = ( ( b / c ) * usec_per_tick ) / d;
+
+  clicks_per_tick += a ;
+
+  while ( ( b %= c ) > 0 )
+  {
+    c /= 10 ;
+    d *= 10 ;
+    a = ( ( b / c ) * usec_per_tick ) / d ;
+    clicks_per_tick += a ;
+  }
+  return clicks_per_tick ;
+#else
+  double fclicks_per_tick =
+    ((double) clicks_per_sec * (double) usec_per_tick) / 1000000.0 ;
+  return (uint32_t) fclicks_per_tick ;
+#endif
+}
+
+/*
+ *  The interrupt vector number associated with the clock tick device
+ *  driver.
+ */
+
+#define CLOCK_VECTOR IMIA0_ISP_V
+
+/*
+ *  Clock_driver_ticks is a monotonically increasing counter of the
+ *  number of clock ticks since the driver was initialized.
+ */
+
+volatile uint32_t   Clock_driver_ticks;
+
+void Clock_exit( void );
+static rtems_isr Clock_isr( rtems_vector_number vector );
+
+/*
+ *  Clock_isrs is the number of clock ISRs until the next invocation of
+ *  the RTEMS clock tick routine.  The clock tick device driver
+ *  gets an interrupt once a millisecond and counts down until the
+ *  length of time between the user configured microseconds per tick
+ *  has passed.
+ */
+
+uint32_t   Clock_isrs;              /* ISRs until next tick */
+static uint32_t   Clock_isrs_const;        /* only calculated once */
+
+/*
+ *  The previous ISR on this clock tick interrupt vector.
+ */
+rtems_isr_entry  Old_ticker;
+
+/*
+ *  Isr Handler
+ */
+static rtems_isr Clock_isr(
+  rtems_vector_number vector
+)
+{
+  /*
+   * bump the number of clock driver ticks since initialization
+   *
+   * determine if it is time to announce the passing of tick as configured
+   * to RTEMS through the rtems_clock_tick directive
+   *
+   * perform any timer dependent tasks
+   */
+  uint8_t   temp;
+
+  /* reset the flags of the status register */
+  temp = read8( ITU_TSR0) & ITU_STAT_MASK;
+  write8( temp, ITU_TSR0);
+
+  Clock_driver_ticks++ ;
+
+  if( Clock_isrs == 1)
+    {
+      rtems_clock_tick();
+      Clock_isrs = Clock_isrs_const;
+    }
+  else
+    {
+      Clock_isrs-- ;
+    }
+}
+
+/*
+ *  Install_clock
+ *
+ *  Install a clock tick handler and reprograms the chip.  This
+ *  is used to initially establish the clock tick.
+ */
+static void Install_clock(
+  rtems_isr_entry clock_isr
+)
+{
+  uint8_t   temp8 = 0;
+  uint32_t   microseconds_per_tick;
+  uint32_t   cclicks_per_tick;
+  uint16_t   Clock_limit;
+
+  /*
+   *  Initialize the clock tick device driver variables
+   */
+
+  Clock_driver_ticks = 0;
+
+  if ( rtems_configuration_get_microseconds_per_tick() != 0 )
+    microseconds_per_tick = rtems_configuration_get_microseconds_per_tick() ;
+  else
+    microseconds_per_tick = 10000 ; /* 10000 us */
+
+  /* clock clicks per tick */
+  cclicks_per_tick = sh_clicks_per_tick(
+     bsp_clicks_per_second / CLOCK_SCALE, microseconds_per_tick );
+
+  Clock_isrs_const = cclicks_per_tick >> 16 ;
+  if ( ( cclicks_per_tick | 0xffff ) > 0 )
+    Clock_isrs_const++ ;
+  Clock_limit = cclicks_per_tick / Clock_isrs_const ;
+  Clock_isrs = Clock_isrs_const;
+
+  rtems_interrupt_catch( Clock_isr, CLOCK_VECTOR, &Old_ticker );
+  /*
+   *  Hardware specific initialize goes here
+   */
+
+  /* stop Timer 0 */
+  temp8 = read8( ITU_TSTR) & ITU0_STARTMASK;
+  write8( temp8, ITU_TSTR);
+
+  /* set initial counter value to 0 */
+  write16( 0, ITU_TCNT0);
+
+  /* Timer 0 runs independent */
+  temp8 = read8( ITU_TSNC) & ITU0_SYNCMASK;
+  write8( temp8, ITU_TSNC);
+
+  /* Timer 0 normal mode */
+  temp8 = read8( ITU_TMDR) & ITU0_MODEMASK;
+  write8( temp8, ITU_TMDR);
+
+  /* TCNT is cleared by GRA ; internal clock /4 */
+  write8( ITU0_TCRMASK , ITU_TCR0);
+
+  /* use GRA without I/O - pins  */
+  write8( ITU0_TIORVAL, ITU_TIOR0);
+
+  /* reset flags of the status register */
+  temp8 = read8( ITU_TSR0) & ITU_STAT_MASK;
+  write8( temp8, ITU_TSR0);
+
+  /* Irq if is equal GRA */
+  temp8 = read8( ITU_TIER0) | ITU0_TIERMASK;
+  write8( temp8, ITU_TIER0);
+
+  /* set interrupt priority */
+  if( sh_set_irq_priority( CLOCK_VECTOR, CLOCKPRIO ) != RTEMS_SUCCESSFUL)
+    rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);
+
+  /* set counter limits */
+  write16( Clock_limit, ITU_GRA0);
+
+  /* start counter */
+  temp8 = read8( ITU_TSTR) |~ITU0_STARTMASK;
+  write8( temp8, ITU_TSTR);
+
+  /*
+   *  Schedule the clock cleanup routine to execute if the application exits.
+   */
+
+  atexit( Clock_exit );
+}
+
+/*
+ *  Clean up before the application exits
+ */
+void Clock_exit( void )
+{
+  uint8_t   temp8 = 0;
+
+  /* turn off the timer interrupts */
+  /* set interrupt priority to 0 */
+  if( sh_set_irq_priority( CLOCK_VECTOR, 0 ) != RTEMS_SUCCESSFUL)
+    rtems_fatal_error_occurred( RTEMS_UNSATISFIED);
+
+/*
+ *   temp16 = read16( ITU_TIER0) & IPRC_ITU0_IRQMASK;
+ *   write16( temp16, ITU_TIER0);
+ */
+
+  /* stop counter */
+  temp8 = read8( ITU_TSTR) & ITU0_STARTMASK;
+  write8( temp8, ITU_TSTR);
+
+  /* old vector shall not be installed */
+}
+
+/*
+ *  Clock_initialize
+ *
+ *  Device driver entry point for clock tick driver initialization.
+ */
+
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  Install_clock( Clock_isr );
+
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/sh/gensh1/clock/delay.c
===================================================================
--- bsps/sh/gensh1/clock/delay.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/sh/gensh1/clock/delay.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,51 @@
+/*
+ *  This routine is a simple spin delay
+ *
+ *  Author: Ralf Corsepius (corsepiu@faw.uni-ulm.de)
+ *
+ *  COPYRIGHT (c) 1999, Ralf Corsepius, Ulm, Germany
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+
+#include <rtems.h>
+
+extern uint32_t bsp_clicks_per_second;
+
+/*
+ *  Simple spin delay in microsecond units for device drivers.
+ *  This is very dependent on the clock speed of the target.
+ *
+ *  Since we don't have a real time clock, this is a very rough
+ *  approximation, assuming that each cycle of the delay loop takes
+ *  approx. 4 machine cycles.
+ *
+ *  e.g.: clicks_per_second = 20MHz
+ *        => 5e-8 secs per instruction
+ *        => 4 * 5e-8 secs per delay loop
+ */
+
+void CPU_delay( uint32_t   microseconds )
+{
+  register uint32_t   clicks_per_usec = bsp_clicks_per_second / 1000000;
+  register uint32_t   _delay = (microseconds) * (clicks_per_usec);
+
+  __asm__ volatile (
+"0:	add  #-4,%0\n\
+	nop\n\
+	cmp/pl %0\n\
+	bt 0b\n\
+	nop"
+     :: "r" (_delay) );
+}
Index: bsps/sh/gensh2/clock/ckinit.c
===================================================================
--- bsps/sh/gensh2/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/sh/gensh2/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,243 @@
+/*
+ *  This file contains the clock driver the Hitachi SH 704X
+ */
+
+/*
+ *  Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
+ *           Bernd Becker (becker@faw.uni-ulm.de)
+ *
+ *  COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *  COPYRIGHT (c) 1998.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *      Modified to reflect registers of sh7045 processor:
+ *      John M. Mills (jmills@tga.com)
+ *      TGA Technologies, Inc.
+ *      100 Pinnacle Way, Suite 140
+ *      Norcross, GA 30071 U.S.A.
+ *      August, 1999
+ *
+ *	This modified file may be copied and distributed in accordance
+ *	the above-referenced license. It is provided for critique and
+ *	developmental purposes without any warranty nor representation
+ *	by the authors or by TGA Technologies.
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+
+#include <stdlib.h>
+
+#include <rtems/clockdrv.h>
+#include <rtems/score/sh_io.h>
+#include <rtems/score/sh.h>
+#include <rtems/score/ispsh7045.h>
+#include <rtems/score/iosh7045.h>
+
+extern uint32_t bsp_clicks_per_second;
+
+#define _MTU_COUNTER0_MICROSECOND (Clock_MHZ/16)
+
+#ifndef CLOCKPRIO
+#define CLOCKPRIO 10
+#endif
+
+#define MTU0_STARTMASK 	0xfe
+#define MTU0_SYNCMASK 	0xfe
+#define MTU0_MODEMASK 	0xc0
+#define MTU0_TCRMASK 	0x22 /* bit 7 also used, vs 703x */
+#define MTU0_STAT_MASK 	0xc0
+#define MTU0_IRQMASK 	0xfe
+#define MTU0_TIERMASK 	0x01
+#define IPRC_MTU0_MASK 	0xff0f
+#define MTU0_TIORVAL 	0x08
+
+/*
+ *  The interrupt vector number associated with the clock tick device
+ *  driver.
+ */
+
+#define CLOCK_VECTOR MTUA0_ISP_V
+
+/*
+ *  Clock_driver_ticks is a monotonically increasing counter of the
+ *  number of clock ticks since the driver was initialized.
+ */
+volatile uint32_t   Clock_driver_ticks;
+
+static rtems_isr Clock_isr( rtems_vector_number vector );
+static uint32_t   Clock_MHZ ;
+
+/*
+ *  Clock_isrs is the number of clock ISRs until the next invocation of
+ *  the RTEMS clock tick routine.  The clock tick device driver
+ *  gets an interrupt once a millisecond and counts down until the
+ *  length of time between the user configured microseconds per tick
+ *  has passed.
+ */
+uint32_t   Clock_isrs;              /* ISRs until next tick */
+static uint32_t   Clock_isrs_const;        /* only calculated once */
+
+/*
+ *  The previous ISR on this clock tick interrupt vector.
+ */
+rtems_isr_entry  Old_ticker;
+
+/*
+ *  Isr Handler
+ */
+static rtems_isr Clock_isr(
+  rtems_vector_number vector
+)
+{
+  /*
+   * bump the number of clock driver ticks since initialization
+   *
+
+   * determine if it is time to announce the passing of tick as configured
+   * to RTEMS through the rtems_clock_tick directive
+   *
+   * perform any timer dependent tasks
+   */
+  uint8_t   temp;
+
+  /* reset the flags of the status register */
+  temp = read8( MTU_TSR0) & MTU0_STAT_MASK;
+  write8( temp, MTU_TSR0);
+
+  Clock_driver_ticks++ ;
+
+  if( Clock_isrs == 1)
+    {
+      rtems_clock_tick();
+      Clock_isrs = Clock_isrs_const;
+    }
+  else
+    {
+      Clock_isrs-- ;
+    }
+}
+
+/*
+ *  Install_clock
+ *
+ *  Install a clock tick handler and reprograms the chip.  This
+ *  is used to initially establish the clock tick.
+ */
+static void Install_clock(
+  rtems_isr_entry clock_isr
+)
+{
+  uint8_t   temp8 = 0;
+  uint32_t   factor = 1000000;
+
+  /*
+   *  Initialize the clock tick device driver variables
+   */
+
+  Clock_driver_ticks = 0;
+  Clock_isrs_const = rtems_configuration_get_microseconds_per_tick() / 10000;
+  Clock_isrs = Clock_isrs_const;
+
+  factor /= rtems_configuration_get_microseconds_per_tick(); /* minimalization of integer division error */
+  Clock_MHZ = bsp_clicks_per_second / factor ;
+
+  rtems_interrupt_catch( Clock_isr, CLOCK_VECTOR, &Old_ticker );
+
+  /*
+   *  Hardware specific initialize goes here
+   */
+
+  /* stop Timer 0 */
+  temp8 = read8( MTU_TSTR) & MTU0_STARTMASK;
+  write8( temp8, MTU_TSTR);
+
+  /* set initial counter value to 0 */
+  write16( 0, MTU_TCNT0);
+
+  /* Timer 0 runs independent */
+  temp8 = read8( MTU_TSYR) & MTU0_SYNCMASK;
+  write8( temp8, MTU_TSYR);
+
+  /* Timer 0 normal mode */
+  temp8 = read8( MTU_TMDR0) & MTU0_MODEMASK;
+  write8( temp8, MTU_TMDR0);
+
+  /* TCNT is cleared by GRA ; internal clock /16 */
+  write8( MTU0_TCRMASK , MTU_TCR0);
+
+  /* use GRA without I/O - pins  */
+  write8( MTU0_TIORVAL, MTU_TIORL0);
+
+  /* reset flags of the status register */
+  temp8 = read8( MTU_TSR0) & MTU0_STAT_MASK;
+  write8( temp8, MTU_TSR0);
+
+  /* Irq if is equal GRA */
+  temp8 = read8( MTU_TIER0) | MTU0_TIERMASK;
+  write8( temp8, MTU_TIER0);
+
+  /* set interrupt priority */
+  if( sh_set_irq_priority( CLOCK_VECTOR, CLOCKPRIO ) != RTEMS_SUCCESSFUL)
+    rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);
+
+  /* set counter limits */
+  write16( _MTU_COUNTER0_MICROSECOND, MTU_GR0A);
+
+  /* start counter */
+  temp8 = read8( MTU_TSTR) |~MTU0_STARTMASK;
+  write8( temp8, MTU_TSTR);
+
+  /*
+   *  Schedule the clock cleanup routine to execute if the application exits.
+   */
+  atexit( Clock_exit );
+}
+
+/*
+ *  Clean up before the application exits
+ */
+void Clock_exit( void )
+{
+  uint8_t   temp8 = 0;
+
+  /* turn off the timer interrupts */
+  /* set interrupt priority to 0 */
+  if( sh_set_irq_priority( CLOCK_VECTOR, 0 ) != RTEMS_SUCCESSFUL)
+    rtems_fatal_error_occurred( RTEMS_UNSATISFIED);
+
+/*
+ *   temp16 = read16( MTU_TIER0) & IPRC_MTU0_IRQMASK;
+ *   write16( temp16, MTU_TIER0);
+ */
+
+  /* stop counter */
+  temp8 = read8( MTU_TSTR) & MTU0_STARTMASK;
+  write8( temp8, MTU_TSTR);
+
+  /* old vector shall not be installed */
+}
+
+/*
+ *  Clock_initialize
+ *
+ *  Device driver entry point for clock tick driver initialization.
+ */
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  Install_clock( Clock_isr );
+
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/sh/gensh4/clock/ckinit.c
===================================================================
--- bsps/sh/gensh4/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/sh/gensh4/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,244 @@
+/*
+ * This file contains the generic RTEMS clock driver the Hitachi SH 7750
+ */
+
+/*
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ *  COPYRIGHT (c) 2001
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+
+#include <stdlib.h>
+
+#include <rtems/clockdrv.h>
+#include <rtems/score/sh_io.h>
+#include <rtems/score/sh.h>
+#include <rtems/score/ispsh7750.h>
+#include <rtems/score/iosh7750.h>
+
+extern uint32_t bsp_clicks_per_second;
+
+#ifndef CLOCKPRIO
+#define CLOCKPRIO 10
+#endif
+
+/* Clock timer prescaler division ratio */
+#define CLOCK_PRESCALER 4
+#define TCR0_TPSC       SH7750_TCR_TPSC_DIV4
+
+/*
+ *  The interrupt vector number associated with the clock tick device
+ *  driver.
+ */
+#define CLOCK_VECTOR SH7750_EVT_TO_NUM(SH7750_EVT_TUNI0)
+
+/*
+ *  Clock_driver_ticks is a monotonically increasing counter of the
+ *  number of clock ticks since the driver was initialized.
+ */
+volatile uint32_t   Clock_driver_ticks;
+
+static rtems_isr Clock_isr( rtems_vector_number vector );
+
+/*
+ *  The previous ISR on this clock tick interrupt vector.
+ */
+rtems_isr_entry  Old_ticker;
+
+/*
+ *  Isr Handler
+ */
+
+/*
+ * Clock_isr
+ *
+ * Clock interrupt handling routine.
+ */
+static rtems_isr Clock_isr(rtems_vector_number vector)
+{
+  uint16_t   tcr;
+
+  /* reset the timer underflow flag */
+  tcr = read16(SH7750_TCR0);
+  write16(tcr & ~SH7750_TCR_UNF, SH7750_TCR0);
+
+  /* Increment the clock interrupt counter */
+  Clock_driver_ticks++ ;
+
+  /* Invoke rtems clock service routine */
+    rtems_clock_tick();
+}
+
+/*
+ * Install_clock
+ *
+ * Install a clock tick handler and reprograms the chip.  This
+ * is used to initially establish the clock tick.
+ *
+ * SIDE EFFECTS:
+ *     Establish clock interrupt handler, configure Timer 0 hardware
+ */
+static void Install_clock(rtems_isr_entry clock_isr)
+{
+  int cpudiv = 1; /* CPU frequency divider */
+  int tidiv = 1;  /* Timer input frequency divider */
+  uint32_t   timer_divider; /* Calculated Timer Divider value */
+  uint8_t   temp8;
+  uint16_t   temp16;
+
+  /*
+   *  Initialize the clock tick device driver variables
+   */
+
+  Clock_driver_ticks = 0;
+
+  /* Get CPU frequency divider from clock unit */
+  switch (read16(SH7750_FRQCR) & SH7750_FRQCR_IFC) {
+    case SH7750_FRQCR_IFCDIV1:
+      cpudiv = 1;
+      break;
+
+    case SH7750_FRQCR_IFCDIV2:
+      cpudiv = 2;
+      break;
+
+    case SH7750_FRQCR_IFCDIV3:
+      cpudiv = 3;
+      break;
+
+    case SH7750_FRQCR_IFCDIV4:
+      cpudiv = 4;
+      break;
+
+    case SH7750_FRQCR_IFCDIV6:
+      cpudiv = 6;
+      break;
+
+    case SH7750_FRQCR_IFCDIV8:
+      cpudiv = 8;
+      break;
+
+      default:
+        rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);
+  }
+
+  /* Get peripheral module frequency divider from clock unit */
+  switch (read16(SH7750_FRQCR) & SH7750_FRQCR_PFC) {
+    case SH7750_FRQCR_PFCDIV2:
+      tidiv = 2 * CLOCK_PRESCALER;
+      break;
+
+    case SH7750_FRQCR_PFCDIV3:
+      tidiv = 3 * CLOCK_PRESCALER;
+      break;
+
+    case SH7750_FRQCR_PFCDIV4:
+      tidiv = 4 * CLOCK_PRESCALER;
+      break;
+
+    case SH7750_FRQCR_PFCDIV6:
+      tidiv = 6 * CLOCK_PRESCALER;
+      break;
+
+    case SH7750_FRQCR_PFCDIV8:
+      tidiv = 8 * CLOCK_PRESCALER;
+      break;
+
+    default:
+      rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);
+  }
+  timer_divider =
+      (bsp_clicks_per_second * cpudiv / (tidiv*1000000)) *
+      rtems_configuration_get_microseconds_per_tick();
+
+  /*
+   *  Hardware specific initialization
+   */
+
+  /* Stop the Timer 0 */
+  temp8 = read8(SH7750_TSTR);
+  temp8 &= ~SH7750_TSTR_STR0;
+  write8(temp8, SH7750_TSTR);
+
+  /* Establish interrupt handler */
+  rtems_interrupt_catch( Clock_isr, CLOCK_VECTOR, &Old_ticker );
+
+  /* Reset counter */
+  write32(timer_divider, SH7750_TCNT0);
+
+  /* Load divider */
+  write32(timer_divider, SH7750_TCOR0);
+
+  write16(
+      SH7750_TCR_UNIE |        /* Enable Underflow Interrupt */
+      SH7750_TCR_CKEG_RAISE |  /* Count on rising edge */
+      TCR0_TPSC,               /* Timer prescaler ratio */
+      SH7750_TCR0);
+
+  /* Set clock interrupt priority */
+  temp16 = read16(SH7750_IPRA);
+  temp16 = (temp16 & ~SH7750_IPRA_TMU0) | (CLOCKPRIO << SH7750_IPRA_TMU0_S);
+  write16(temp16, SH7750_IPRA);
+
+  /* Start the Timer 0 */
+  temp8 = read8(SH7750_TSTR);
+  temp8 |= SH7750_TSTR_STR0;
+  write8(temp8, SH7750_TSTR);
+
+  /*
+   *  Schedule the clock cleanup routine to execute if the application exits.
+   */
+  atexit( Clock_exit );
+}
+
+/*
+ * Clock_exit
+ *
+ * Clean up before the application exits
+ *
+ * SIDE EFFECTS:
+ *     Stop Timer 0 counting, set timer 0 interrupt priority level to 0.
+ */
+void
+Clock_exit(void)
+{
+  uint8_t   temp8 = 0;
+  uint16_t   temp16 = 0;
+
+  /* turn off the timer interrupts */
+  /* Stop the Timer 0 */
+  temp8 = read8(SH7750_TSTR);
+  temp8 &= ~SH7750_TSTR_STR0;
+  write8(temp8, SH7750_TSTR);
+
+  /* Lower timer interrupt priority to 0 */
+  temp16 = read16(SH7750_IPRA);
+  temp16 = (temp16 & ~SH7750_IPRA_TMU0) | (0 << SH7750_IPRA_TMU0_S);
+  write16(temp16, SH7750_IPRA);
+
+  /* old vector shall not be installed */
+}
+
+/*
+ * Clock_initialize
+ *
+ * Device driver entry point for clock tick driver initialization.
+ */
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+    Install_clock( Clock_isr );
+
+    return RTEMS_SUCCESSFUL;
+}
Index: bsps/shared/dev/clock/clock-simidle.c
===================================================================
--- bsps/shared/dev/clock/clock-simidle.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/shared/dev/clock/clock-simidle.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,59 @@
+/*
+ *  Instantiate the clock driver shell.
+ *
+ *  Since there is no clock source on the simulator, we fake
+ *  it with a special IDLE task.
+ */
+
+#include <rtems.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/threaddispatch.h>
+
+#define CLOCK_VECTOR 0
+
+volatile bool clock_driver_enabled;
+
+#define Clock_driver_support_initialize_hardware() \
+  do { \
+    clock_driver_enabled = true; \
+  } while (0)
+
+#define Clock_driver_support_shutdown_hardware() \
+  do { \
+    clock_driver_enabled = false; \
+  } while (0)
+
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
+#include "clockimpl.h"
+
+/*
+ * If this is defined, then the BSP has defined a delay of some sort so
+ * time passage appears somewhat correctly. Otherwise, it runs extremely
+ * fast with no delays.
+ */
+#ifndef BSP_CLOCK_DRIVER_DELAY
+#define BSP_CLOCK_DRIVER_DELAY()
+#endif
+
+/*
+ *  Since there is no interrupt on this simulator, let's just
+ *  fake time passing.  This will not let preemption from an
+ *  interrupt work but is enough for many tests.
+ */
+void *clock_driver_sim_idle_body(
+  uintptr_t   ignored
+)
+{
+  for( ; ; ) {
+    if ( clock_driver_enabled ) {
+      Per_CPU_Control *cpu = _Thread_Dispatch_disable();
+      _ISR_Nest_level++;
+      rtems_clock_tick();
+      _ISR_Nest_level--;
+      _Thread_Dispatch_enable( cpu );
+      BSP_CLOCK_DRIVER_DELAY();
+    }
+  }
+  return 0;   /* to avoid warning */
+}
Index: bsps/shared/dev/clock/clockimpl.h
===================================================================
--- bsps/shared/dev/clock/clockimpl.h	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/shared/dev/clock/clockimpl.h	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,260 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_clock
+ *
+ * @brief Clock Tick Device Driver Shell
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2014.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdlib.h>
+
+#include <bsp.h>
+#include <rtems/clockdrv.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/smpimpl.h>
+#include <rtems/score/watchdogimpl.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
+ *
+ * @ingroup bsp_shared
+ *
+ * @brief Clock support 
+ *
+ */
+#if CLOCK_DRIVER_USE_FAST_IDLE && CLOCK_DRIVER_ISRS_PER_TICK
+#error "Fast Idle PLUS n ISRs per tick is not supported"
+#endif
+
+/**
+ * @brief Do nothing by default.
+ */
+#ifndef Clock_driver_support_install_isr
+  #define Clock_driver_support_install_isr(isr)
+#endif
+
+/**
+ * @brief This method is rarely used so default it.
+ */
+#ifndef Clock_driver_support_find_timer
+  #define Clock_driver_support_find_timer()
+#endif
+
+/**
+ * @brief Do nothing by default.
+ */
+#ifndef Clock_driver_support_at_tick
+  #define Clock_driver_support_at_tick()
+#endif
+
+/**
+ * @brief Do nothing by default.
+ */
+#ifndef Clock_driver_support_set_interrupt_affinity
+  #define Clock_driver_support_set_interrupt_affinity(online_processors)
+#endif
+
+/*
+ * A specialized clock driver may use for example rtems_timecounter_tick_simple()
+ * instead of the default.
+ */
+#ifndef Clock_driver_timecounter_tick
+static void Clock_driver_timecounter_tick( void )
+{
+#if defined(CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER)
+  rtems_clock_tick();
+#elif defined(RTEMS_SMP) && defined(CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR)
+  uint32_t cpu_count = _SMP_Get_processor_count();
+  uint32_t cpu_index;
+
+  for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {
+    Per_CPU_Control *cpu;
+
+    cpu = _Per_CPU_Get_by_index( cpu_index );
+
+    if ( _Per_CPU_Is_boot_processor( cpu ) ) {
+      rtems_timecounter_tick();
+    } else if ( _Processor_mask_Is_set( _SMP_Get_online_processors(), cpu_index ) ) {
+      _Watchdog_Tick( cpu );
+    }
+  }
+#else
+  rtems_timecounter_tick();
+#endif
+}
+#endif
+
+/**
+ * @brief ISRs until next clock tick
+ */
+#if CLOCK_DRIVER_ISRS_PER_TICK
+  volatile uint32_t  Clock_driver_isrs;
+#endif
+
+/**
+ * @brief Clock ticks since initialization
+ */
+volatile uint32_t    Clock_driver_ticks;
+
+#ifdef Clock_driver_support_shutdown_hardware
+void Clock_exit( void );
+#endif
+
+/**
+ *  @brief Clock_isr
+ *
+ *  This is the clock tick interrupt handler.
+ *
+ *  @param vector Vector number.
+ */
+#if defined(BSP_FEATURE_IRQ_EXTENSION) || \
+    (CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE)
+void Clock_isr(void *arg);
+void Clock_isr(void *arg)
+{
+#else
+rtems_isr Clock_isr(rtems_vector_number vector);
+rtems_isr Clock_isr(
+  rtems_vector_number vector
+)
+{
+#endif
+  /*
+   *  Accurate count of ISRs
+   */
+  Clock_driver_ticks += 1;
+
+  #if CLOCK_DRIVER_USE_FAST_IDLE
+    {
+      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();
+
+      if (!rtems_configuration_is_smp_enabled()) {
+        while (
+          _Thread_Heir == _Thread_Executing && _Thread_Executing->is_idle
+        ) {
+          ISR_lock_Context lock_context;
+
+          _Timecounter_Acquire(&lock_context);
+          _Timecounter_Tick_simple(
+            interval,
+            (*tc->tc_get_timecount)(tc),
+            &lock_context
+          );
+        }
+      }
+
+      Clock_driver_support_at_tick();
+    }
+  #else
+    /*
+     *  Do the hardware specific per-tick action.
+     *
+     *  The counter/timer may or may not be set to automatically reload.
+     */
+    Clock_driver_support_at_tick();
+
+    #if CLOCK_DRIVER_ISRS_PER_TICK
+      /*
+       *  The driver is multiple ISRs per clock tick.
+       */
+      if ( !Clock_driver_isrs ) {
+        Clock_driver_timecounter_tick();
+
+        Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK;
+      }
+      Clock_driver_isrs--;
+    #else
+      /*
+       *  The driver is one ISR per clock tick.
+       */
+      Clock_driver_timecounter_tick();
+    #endif
+  #endif
+}
+
+#ifdef Clock_driver_support_shutdown_hardware
+/**
+ *  @brief Clock_exit
+ *
+ *  This routine allows the clock driver to exit by masking the interrupt and
+ *  disabling the clock's counter.
+ */
+void Clock_exit( void )
+{
+  Clock_driver_support_shutdown_hardware();
+
+  /* do not restore old vector */
+}
+#endif
+
+/**
+ * @brief Clock_initialize
+ *
+ * This routine initializes the clock driver.
+ *
+ * @param[in] major Clock device major number.
+ * @param[in] minor Clock device minor number.
+ * @param[in] parg  Pointer to optional device driver arguments
+ *
+ * @retval rtems_device_driver status code
+ */
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  Clock_driver_ticks = 0;
+
+  /*
+   *  Find timer -- some BSPs search buses for hardware timer
+   */
+  Clock_driver_support_find_timer();
+
+  /*
+   *  Install vector
+   */
+  Clock_driver_support_install_isr( Clock_isr );
+
+  #ifdef RTEMS_SMP
+    Clock_driver_support_set_interrupt_affinity(
+      _SMP_Get_online_processors()
+    );
+  #endif
+
+  /*
+   *  Now initialize the hardware that is the source of the tick ISR.
+   */
+  Clock_driver_support_initialize_hardware();
+
+#ifdef Clock_driver_support_shutdown_hardware
+  atexit( Clock_exit );
+#endif
+
+  /*
+   *  If we are counting ISRs per tick, then initialize the counter.
+   */
+  #if CLOCK_DRIVER_ISRS_PER_TICK
+    Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK_VALUE;
+  #endif
+
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/sparc/erc32/clock/ckinit.c
===================================================================
--- bsps/sparc/erc32/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/sparc/erc32/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,131 @@
+/*
+ *  This routine initializes the Real Time Clock Counter Timer which is
+ *  part of the MEC on the ERC32 CPU.
+ *
+ *  The tick frequency is directly programmed to the configured number of
+ *  microseconds per tick.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2008.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ *  Ported to ERC32 implementation of the SPARC by On-Line Applications
+ *  Research Corporation (OAR) under contract to the European Space
+ *  Agency (ESA).
+ *
+ *  ERC32 modifications of respective RTEMS file: COPYRIGHT (c) 1995.
+ *  European Space Agency.
+ */
+
+#include <bsp.h>
+#include <bspopts.h>
+#include <rtems/counter.h>
+#include <rtems/timecounter.h>
+#include <rtems/score/sparcimpl.h>
+
+/*
+ *  The Real Time Clock Counter Timer uses this trap type.
+ */
+#define CLOCK_VECTOR ERC32_TRAP_TYPE( ERC32_INTERRUPT_REAL_TIME_CLOCK )
+
+#define Clock_driver_support_install_isr( _new ) \
+  set_vector( _new, CLOCK_VECTOR, 1 )
+
+#define Clock_driver_support_set_interrupt_affinity( _online_processors ) \
+  do { \
+    (void) _online_processors; \
+  } while (0)
+
+extern int CLOCK_SPEED;
+
+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 )
+{
+  return rtems_timecounter_simple_downcounter_get(
+    tc,
+    erc32_tc_get,
+    erc32_tc_is_pending
+  );
+}
+
+static void erc32_tc_at_tick( rtems_timecounter_simple *tc )
+{
+  /* Nothing to do */
+}
+
+static void erc32_tc_tick( void )
+{
+  rtems_timecounter_simple_downcounter_tick(
+    &erc32_tc,
+    erc32_tc_get,
+    erc32_tc_at_tick
+  );
+}
+
+static void erc32_counter_initialize( uint32_t frequency )
+{
+  _SPARC_Counter_initialize(
+    _SPARC_Counter_read_address,
+    _SPARC_Counter_difference_clock_period,
+    &ERC32_MEC.Real_Time_Clock_Counter
+  );
+  rtems_counter_initialize_converter( frequency );
+}
+
+#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 = \
+      rtems_configuration_get_microseconds_per_tick(); \
+    \
+    ERC32_MEC_Set_Real_Time_Clock_Timer_Control( \
+        ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING | \
+        ERC32_MEC_TIMER_COUNTER_LOAD_SCALER | \
+        ERC32_MEC_TIMER_COUNTER_LOAD_COUNTER \
+    ); \
+    \
+    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 \
+    ); \
+    erc32_counter_initialize( 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 ); \
+     \
+    ERC32_MEC_Set_Real_Time_Clock_Timer_Control( \
+      ERC32_MEC_TIMER_COUNTER_DISABLE_COUNTING \
+    ); \
+  } while (0)
+
+#include "../../../shared/dev/clock/clockimpl.h"
+
+SPARC_COUNTER_DEFINITION;
Index: bsps/sparc/leon2/clock/ckinit.c
===================================================================
--- bsps/sparc/leon2/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/sparc/leon2/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,104 @@
+/**
+ * @file
+ * @ingroup sparc_leon2
+ * @brief Clock Tick Device Driver
+ *
+ *  This routine initializes LEON timer 1 which used for the clock tick.
+ *
+ *  The tick frequency is directly programmed to the configured number of
+ *  microseconds per tick.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2008.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  Modified for LEON BSP
+ *  COPYRIGHT (c) 2004.
+ *  Gaisler Research.
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bspopts.h>
+#include <rtems/timecounter.h>
+#include <rtems/score/sparcimpl.h>
+
+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_at_tick( rtems_timecounter_simple *tc )
+{
+  /* Nothing to do */
+}
+
+static void leon2_tc_tick( void )
+{
+  rtems_timecounter_simple_downcounter_tick(
+    &leon2_tc,
+    leon2_tc_get,
+    leon2_tc_at_tick
+  );
+}
+
+/*
+ *  The Real Time Clock Counter Timer uses this trap type.
+ */
+
+#define CLOCK_VECTOR LEON_TRAP_TYPE( LEON_INTERRUPT_TIMER1 )
+
+#define Clock_driver_support_install_isr( _new ) \
+  set_vector( _new, CLOCK_VECTOR, 1 )
+
+extern int CLOCK_SPEED;
+
+#define Clock_driver_support_initialize_hardware() \
+  do { \
+    LEON_REG.Timer_Reload_1 = \
+        rtems_configuration_get_microseconds_per_tick() - 1; \
+    \
+    LEON_REG.Timer_Control_1 = ( \
+      LEON_REG_TIMER_COUNTER_ENABLE_COUNTING |  \
+        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() \
+  do { \
+    LEON_Mask_interrupt( LEON_INTERRUPT_TIMER1 ); \
+    LEON_REG.Timer_Control_1 = 0; \
+  } while (0)
+
+#define Clock_driver_timecounter_tick() leon2_tc_tick()
+
+#include "../../../shared/dev/clock/clockimpl.h"
+
+SPARC_COUNTER_DEFINITION;
Index: bsps/sparc/leon3/clock/ckinit.c
===================================================================
--- bsps/sparc/leon3/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/sparc/leon3/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,280 @@
+/*
+ *  Clock Tick Device Driver
+ *
+ *  This routine initializes LEON timer 1 which used for the clock tick.
+ *
+ *  The tick frequency is directly programmed to the configured number of
+ *  microseconds per tick.
+ *
+ *  COPYRIGHT (c) 1989-2006.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  Modified for LEON3 BSP.
+ *  COPYRIGHT (c) 2004.
+ *  Gaisler Research.
+ *
+ *  Copyright (c) 2014, 2018 embedded brains GmbH
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bspopts.h>
+#include <bsp/fatal.h>
+#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
+ * must be used.
+ *
+ * The DrvMgr Clock driver is located in the shared/timer directory
+ */
+#ifndef RTEMS_DRVMGR_STARTUP
+
+/* LEON3 Timer system interrupt number */
+static int clkirq;
+
+static void (*leon3_tc_tick)(void);
+
+static rtems_timecounter_simple leon3_tc;
+
+#ifndef RTEMS_SMP
+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 void leon3_tc_at_tick( rtems_timecounter_simple *tc )
+{
+  /* Nothing to do */
+}
+
+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 void leon3_tc_tick_simple(void)
+{
+  rtems_timecounter_simple_downcounter_tick(
+    &leon3_tc,
+    leon3_tc_get,
+    leon3_tc_at_tick
+  );
+}
+#endif
+
+static uint32_t leon3_tc_get_timecount_up_counter(struct timecounter *tc)
+{
+  return leon3_up_counter_low();
+}
+
+static uint32_t leon3_tc_get_timecount_irqmp(struct timecounter *tc)
+{
+  return LEON3_IrqCtrl_Regs->timestamp[0].counter;
+}
+
+#ifdef RTEMS_SMP
+static uint32_t leon3_tc_get_timecount_second_timer(struct timecounter *tc)
+{
+  return 0xffffffff - LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX + 1].value;
+}
+#endif
+
+#ifdef RTEMS_PROFILING
+#define IRQMP_TIMESTAMP_S1_S2 ((1U << 25) | (1U << 26))
+
+static void leon3_tc_tick_irqmp_timestamp(void)
+{
+  volatile struct irqmp_timestamp_regs *irqmp_ts =
+    &LEON3_IrqCtrl_Regs->timestamp[0];
+  unsigned int first = irqmp_ts->assertion;
+  unsigned int second = irqmp_ts->counter;
+
+  irqmp_ts->control |= IRQMP_TIMESTAMP_S1_S2;
+
+  _Profiling_Update_max_interrupt_delay(_Per_CPU_Get(), second - first);
+
+  rtems_timecounter_tick();
+}
+#endif
+
+static void leon3_tc_tick_irqmp_timestamp_init(void)
+{
+#ifdef RTEMS_PROFILING
+  /*
+   * Ignore the first clock interrupt, since it contains the sequential system
+   * initialization time.  Do the timestamp initialization on the fly.
+   */
+
+#ifdef RTEMS_SMP
+  static Atomic_Uint counter = ATOMIC_INITIALIZER_UINT(0);
+
+  bool done =
+    _Atomic_Fetch_add_uint(&counter, 1, ATOMIC_ORDER_RELAXED)
+      == rtems_get_processor_count() - 1;
+#else
+  bool done = true;
+#endif
+
+  volatile struct irqmp_timestamp_regs *irqmp_ts =
+    &LEON3_IrqCtrl_Regs->timestamp[0];
+  unsigned int ks = 1U << 5;
+
+  irqmp_ts->control = ks | IRQMP_TIMESTAMP_S1_S2 | (unsigned int) clkirq;
+
+  if (done) {
+    leon3_tc_tick = leon3_tc_tick_irqmp_timestamp;
+  }
+#endif
+
+  rtems_timecounter_tick();
+}
+
+#ifdef RTEMS_SMP
+static void leon3_tc_tick_second_timer(void)
+{
+  rtems_timecounter_tick();
+}
+#endif
+
+static void leon3_tc_do_tick(void)
+{
+  (*leon3_tc_tick)();
+}
+
+#define Adjust_clkirq_for_node() do { clkirq += LEON3_CLOCK_INDEX; } while(0)
+
+#define Clock_driver_support_find_timer() \
+  do { \
+    /* Assume timer found during BSP initialization */ \
+    if (LEON3_Timer_Regs) { \
+      clkirq = (LEON3_Timer_Regs->cfg & 0xf8) >> 3; \
+      \
+      Adjust_clkirq_for_node(); \
+    } \
+  } while (0)
+
+#define Clock_driver_support_install_isr( _new ) \
+  bsp_clock_handler_install(_new)
+
+static void bsp_clock_handler_install(rtems_isr *new)
+{
+  rtems_status_code sc;
+
+  sc = rtems_interrupt_handler_install(
+    clkirq,
+    "Clock",
+    RTEMS_INTERRUPT_UNIQUE,
+    new,
+    NULL
+  );
+  if (sc != RTEMS_SUCCESSFUL) {
+    rtems_fatal(RTEMS_FATAL_SOURCE_BSP, LEON3_FATAL_CLOCK_INITIALIZATION);
+  }
+}
+
+#define Clock_driver_support_set_interrupt_affinity(online_processors) \
+  bsp_interrupt_set_affinity(clkirq, online_processors)
+
+static void leon3_clock_initialize(void)
+{
+  volatile struct irqmp_timestamp_regs *irqmp_ts;
+  volatile struct gptimer_regs *gpt;
+
+  irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0];
+  gpt = LEON3_Timer_Regs;
+
+  gpt->timer[LEON3_CLOCK_INDEX].reload =
+    rtems_configuration_get_microseconds_per_tick() - 1;
+  gpt->timer[LEON3_CLOCK_INDEX].ctrl =
+    GPTIMER_TIMER_CTRL_EN | GPTIMER_TIMER_CTRL_RS |
+      GPTIMER_TIMER_CTRL_LD | GPTIMER_TIMER_CTRL_IE;
+
+  leon3_up_counter_enable();
+
+  if (leon3_up_counter_is_available()) {
+    /* Use the LEON4 up-counter if available */
+    leon3_tc.tc.tc_get_timecount = leon3_tc_get_timecount_up_counter;
+    leon3_tc.tc.tc_counter_mask = 0xffffffff;
+    leon3_tc.tc.tc_frequency = leon3_up_counter_frequency();
+    leon3_tc.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+
+#ifdef RTEMS_PROFILING
+    if (!leon3_irqmp_has_timestamp(irqmp_ts)) {
+      bsp_fatal(LEON3_FATAL_CLOCK_NO_IRQMP_TIMESTAMP_SUPPORT);
+    }
+#endif
+
+    leon3_tc_tick = leon3_tc_tick_irqmp_timestamp_init;
+    rtems_timecounter_install(&leon3_tc.tc);
+  } else if (leon3_irqmp_has_timestamp(irqmp_ts)) {
+    /* Use the interrupt controller timestamp counter if available */
+    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_tick = leon3_tc_tick_irqmp_timestamp_init;
+
+    /*
+     * At least one TSISEL field must be non-zero to enable the timestamp
+     * counter.  Use an arbitrary interrupt source.
+     */
+    irqmp_ts->control = 0x1;
+
+    rtems_timecounter_install(&leon3_tc.tc);
+  } else {
+#ifdef RTEMS_SMP
+    /*
+     * The GR712RC for example has no timestamp unit in the interrupt
+     * controller.  At least on SMP configurations we must use a second timer
+     * in free running mode for the timecounter.
+     */
+    gpt->timer[LEON3_CLOCK_INDEX + 1].ctrl =
+      GPTIMER_TIMER_CTRL_EN | GPTIMER_TIMER_CTRL_IE;
+    leon3_tc.tc.tc_get_timecount = leon3_tc_get_timecount_second_timer;
+    leon3_tc.tc.tc_counter_mask = 0xffffffff;
+    leon3_tc.tc.tc_frequency = LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER;
+    leon3_tc.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+    leon3_tc_tick = leon3_tc_tick_second_timer;
+    rtems_timecounter_install(&leon3_tc.tc);
+#else
+    leon3_tc_tick = leon3_tc_tick_simple;
+    rtems_timecounter_simple_install(
+      &leon3_tc,
+      LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER,
+      rtems_configuration_get_microseconds_per_tick(),
+      leon3_tc_get_timecount
+    );
+#endif
+  }
+}
+
+#define Clock_driver_support_initialize_hardware() \
+  leon3_clock_initialize()
+
+#define Clock_driver_support_shutdown_hardware() \
+  do { \
+    LEON_Mask_interrupt(LEON_TRAP_TYPE(clkirq)); \
+    LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX].ctrl = 0; \
+  } while (0)
+
+#define Clock_driver_timecounter_tick() leon3_tc_do_tick()
+
+#include "../../../shared/dev/clock/clockimpl.h"
+
+#endif
Index: bsps/sparc64/shared/clock/ckinit.c
===================================================================
--- bsps/sparc64/shared/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
+++ bsps/sparc64/shared/clock/ckinit.c	(revision 7632906fc290b652416ab59eb5fb49356c064ed6)
@@ -0,0 +1,122 @@
+/*  ckinit.c
+ *
+ *  This file provides a template for the clock device driver initialization.
+ *
+ *  Modified for sun4v - niagara
+ */
+
+/*
+ *  Copyright (c) 2010 Gedare Bloom.
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdlib.h>
+
+#include <rtems.h>
+#include <bsp.h>
+#include <bspopts.h>
+#include <boot/ofw.h>
+#include <rtems/bspIo.h>
+
+/* This is default frequency for simics simulator of niagara. Use the
+ * get_Frequency function to determine the CPU clock frequency at runtime.
+ */
+#define CPU_FREQ (5000000)
+
+uint64_t sparc64_cycles_per_tick;
+
+/* TICK_CMPR and STICK_CMPR trigger soft interrupt 14 */
+#define CLOCK_VECTOR SPARC_SYNCHRONOUS_TRAP(0x4E)
+
+static unsigned int get_Frequency(void)
+{
+  phandle root = ofw_find_device("/");
+  unsigned int freq;
+
+  if (ofw_get_property(root, "clock-frequency", &freq, sizeof(freq)) <= 0) {
+    printk("Unable to determine frequency, default: 0x%x\n",CPU_FREQ);
+    return CPU_FREQ;
+  }
+
+  return freq;
+}
+
+#define Clock_driver_support_at_tick() \
+  Clock_driver_support_at_tick_helper()
+
+static void Clock_driver_support_at_tick_helper(void)
+{
+  uint64_t tick_reg;
+  int bit_mask;
+  uint64_t pil_reg;
+
+  bit_mask = SPARC_SOFTINT_TM_MASK | SPARC_SOFTINT_SM_MASK | (1<<14);
+  sparc64_clear_interrupt_bits(bit_mask);
+
+  sparc64_get_pil(pil_reg);
+  if(pil_reg == 0xe) { /* 0xe is the tick compare interrupt (softint(14)) */
+    pil_reg--;
+    sparc64_set_pil(pil_reg); /* enable the next timer interrupt */
+  }
+  /* Note: sun4v uses stick_cmpr for clock driver for M5 simulator, which 
+   * does not currently have tick_cmpr implemented */
+  /* TODO: this could be more efficiently implemented as a single assembly 
+   * inline */
+#if defined (SUN4U)
+  sparc64_read_tick(tick_reg);
+#elif defined (SUN4V)
+  sparc64_read_stick(tick_reg);
+#endif
+  tick_reg &= ~(1UL<<63); /* mask out NPT bit, prevents int_dis from being set */
+
+  tick_reg += sparc64_cycles_per_tick;
+
+#if defined (SUN4U)
+  sparc64_write_tick_cmpr(tick_reg);
+#elif defined (SUN4V)
+  sparc64_write_stick_cmpr(tick_reg);
+#endif
+}
+
+#define Clock_driver_support_install_isr(_new) \
+  set_vector( _new, CLOCK_VECTOR, 1 )
+
+static void Clock_driver_support_initialize_hardware(void)
+{
+  uint64_t tick_reg;
+  int bit_mask;
+
+  bit_mask = SPARC_SOFTINT_TM_MASK | SPARC_SOFTINT_SM_MASK | (1<<14);
+  sparc64_clear_interrupt_bits(bit_mask);
+
+  sparc64_cycles_per_tick =
+    rtems_configuration_get_microseconds_per_tick()*(get_Frequency()/1000000);
+
+#if defined (SUN4U)
+  sparc64_read_tick(tick_reg);
+#elif defined (SUN4V)
+  sparc64_read_stick(tick_reg);
+#endif
+
+  tick_reg &= ~(1UL<<63); /* mask out NPT bit, prevents int_dis from being set */
+  tick_reg += sparc64_cycles_per_tick;
+
+#if defined (SUN4U)
+  sparc64_write_tick_cmpr(tick_reg);
+#elif defined (SUN4V)
+  sparc64_write_stick_cmpr(tick_reg);
+#endif
+}
+
+#define Clock_driver_support_shutdown_hardware( ) \
+  do { \
+    \
+  } while ( 0 )
+
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
+#include "../../../shared/dev/clock/clockimpl.h"
+
