Index: bsps/arm/csb336/btimer/btimer.c
===================================================================
--- bsps/arm/csb336/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/arm/csb336/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,93 @@
+/**
+ *  @file
+ *  @brief Cogent CSB336 Timer driver
+ *
+ * This uses timer 2 for timing measurments.
+ */
+
+/*
+ * Copyright (c) 2004 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 <rtems/btimer.h>
+#include <mc9328mxl.h>
+
+uint32_t g_start;
+uint32_t g_freq;
+
+bool benchmark_timer_find_average_overhead;
+
+
+/*
+ * Set up Timer 1
+ */
+void benchmark_timer_initialize( void )
+{
+    MC9328MXL_TMR2_TCTL = (MC9328MXL_TMR_TCTL_CLKSRC_PCLK1 |
+                            MC9328MXL_TMR_TCTL_FRR |
+                            MC9328MXL_TMR_TCTL_TEN);
+    /* set prescaler to 1 (register value + 1) */ \
+    MC9328MXL_TMR2_TPRER = 0;
+
+    /* get freq of counter in KHz */
+    g_freq = get_perclk1_freq() / 1000;
+
+    g_start =  MC9328MXL_TMR2_TCN;
+}
+
+/*
+ *  The following controls the behavior of benchmark_timer_read().
+ *
+ *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      0  /* It typically takes X.X microseconds */
+                             /* (Y countdowns) to start/stop the timer. */
+                             /* This value is in microseconds. */
+#define LEAST_VALID       1  /* Don't trust a clicks value lower than this */
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+  uint32_t t;
+  unsigned long long total;
+
+  t =  MC9328MXL_TMR2_TCN;
+  /*
+   *  Total is calculated by taking into account the number of timer overflow
+   *  interrupts since the timer was initialized and clicks since the last
+   *  interrupts.
+   */
+
+  total = (t - g_start);
+
+  /* convert to nanoseconds */
+  total = (total * 1000)/ g_freq;
+
+  if ( benchmark_timer_find_average_overhead == 1 ) {
+    return (int) total;
+  } else if ( total < LEAST_VALID ) {
+      return 0;
+  }
+  /*
+   *  Somehow convert total into microseconds
+   */
+
+  return (total - AVG_OVERHEAD);
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
+
Index: bsps/arm/csb337/btimer/btimer.c
===================================================================
--- bsps/arm/csb337/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/arm/csb337/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,91 @@
+/**
+ * @file
+ * @brief Cogent CSB337 Timer driver
+ *
+ * This uses timer 0 for timing measurments.
+ */
+
+/*
+ *  Copyright (c) 2004 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 <bsp.h>
+#include <rtems.h>
+#include <rtems/btimer.h>
+#include <at91rm9200.h>
+#include <at91rm9200_pmc.h>
+
+uint16_t tstart;
+bool benchmark_timer_find_average_overhead;
+uint32_t tick_time;
+/*
+ * Set up TC0 -
+ *   timer_clock2 (MCK/8)
+ *   capture mode - this shouldn't matter
+ */
+void benchmark_timer_initialize( void )
+{
+    uint32_t tmr_freq;
+
+    /* since we are using timer_clock2, divide mck by 8 */
+    tmr_freq = at91rm9200_get_mck() / 8;
+
+    TC_TC0_REG(TC_CMR) = TC_CMR_TCCLKS(1);   /* timer_clock2 */
+    TC_TC0_REG(TC_CCR) = (TC_CCR_CLKEN       /* enable the counter */
+                          | TC_CCR_SWTRG);   /* start it up */
+
+    /* tick time in nanoseconds */
+    tick_time = 1000000000/tmr_freq;
+
+}
+
+/*
+ *  The following controls the behavior of benchmark_timer_read().
+ *
+ *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      0  /* It typically takes X.X microseconds */
+                             /* (Y countdowns) to start/stop the timer. */
+                             /* This value is in microseconds. */
+#define LEAST_VALID       1  /* Don't trust a clicks value lower than this */
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+  uint16_t t;
+  uint32_t total;
+  t = TC_TC0_REG(TC_CV);
+
+  /*
+   *  Total is calculated by taking into account the number of timer overflow
+   *  interrupts since the timer was initialized and clicks since the last
+   *  interrupts.
+   */
+
+  total = t * tick_time;
+
+  if ( benchmark_timer_find_average_overhead == 1 )
+    return total;          /* in nanosecond units */
+  else {
+    if ( total < LEAST_VALID )
+      return 0;            /* below timer resolution */
+  /*
+   *  Somehow convert total into microseconds
+   */
+      return (total - AVG_OVERHEAD);
+    }
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
+
Index: bsps/arm/edb7312/btimer/btimer.c
===================================================================
--- bsps/arm/edb7312/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/arm/edb7312/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,80 @@
+/*
+ * Cirrus EP7312 Timer 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.
+ *
+ * Notes:
+ *  This file manages the benchmark timer used by the RTEMS Timing Test
+ *  Suite.  Each measured time period is demarcated by calls to
+ *  benchmark_timer_initialize() and benchmark_timer_read().  benchmark_timer_read() usually returns
+ *  the number of microseconds since benchmark_timer_initialize() exitted.
+ *
+ *  It is important that the timer start/stop overhead be determined
+ *  when porting or modifying this code.
+*/
+
+#include <rtems.h>
+#include <bsp.h>
+#include <rtems/btimer.h>
+#include <ep7312.h>
+
+uint16_t         tstart;
+bool benchmark_timer_find_average_overhead;
+
+void benchmark_timer_initialize( void )
+{
+    *EP7312_SYSCON1 |= EP7312_SYSCON1_TC2_512KHZ;
+    *EP7312_TC2D = 0xffff;
+}
+
+/*
+ *  The following controls the behavior of benchmark_timer_read().
+ *
+ *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      0  /* It typically takes X.X microseconds */
+                             /* (Y countdowns) to start/stop the timer. */
+                             /* This value is in microseconds. */
+#define LEAST_VALID       1  /* Don't trust a clicks value lower than this */
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+  uint16_t         t;
+  uint32_t         total;
+  t = *EP7312_TC2D;
+
+  /*
+   *  Total is calculated by taking into account the number of timer overflow
+   *  interrupts since the timer was initialized and clicks since the last
+   *  interrupts.
+   */
+
+  total = (uint32_t)0x0000ffff - t;  /* result is 1/512000 = ~2 uS */
+  total = (total * 1953) / 1000;   /* convert to uS */
+  if ( benchmark_timer_find_average_overhead == true )
+    return total;          /* in XXX microsecond units */
+  else {
+    if ( total < LEAST_VALID )
+      return 0;            /* below timer resolution */
+  /*
+   *  Somehow convert total into microseconds
+   */
+      return (total - AVG_OVERHEAD);
+    }
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/arm/gumstix/btimer/btimer.c
===================================================================
--- bsps/arm/gumstix/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/arm/gumstix/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,75 @@
+/**
+ * @file
+ * @brief PXA255 timer
+ */
+
+/*
+ * PXA255 timer by Yang Xi <hiyangxi@gmail.com>
+ * Copyright (c) 2004 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 <bsp.h>
+#include <rtems.h>
+#include <rtems/btimer.h>
+#include <pxa255.h>
+
+uint32_t tstart;
+static uint32_t tick_time;
+bool benchmark_timer_find_average_overhead;
+
+bool benchmark_timer_is_initialized = false;
+
+/*
+ * Use the timer count register to measure.
+ * The frequency of it is 3.4864MHZ
+ * The longest period we are able to capture is 4G/3.4864MHZ
+ */
+void benchmark_timer_initialize(void)
+{
+  tick_time = XSCALE_OS_TIMER_TCR;
+}
+
+/*
+ *  The following controls the behavior of Read_timer().
+ *
+ *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      0  /* It typically takes X.X microseconds */
+                             /* (Y countdowns) to start/stop the timer. */
+                             /* This value is in microseconds. */
+#define LEAST_VALID       1  /* Don't trust a clicks value lower than this */
+
+benchmark_timer_t benchmark_timer_read(void)
+{
+
+  uint32_t total;
+  total = XSCALE_OS_TIMER_TCR;
+  if(total>=tick_time)
+    total -= tick_time;
+  else
+    total += 0xffffffff - tick_time; /*Round up but not overflow*/
+
+  if ( benchmark_timer_find_average_overhead == true )
+    return total;          /*Counter cycles*/
+
+  if ( total < LEAST_VALID )
+    return 0;            /* below timer resolution */
+
+  return total;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/arm/lpc176x/btimer/btimer.c
===================================================================
--- bsps/arm/lpc176x/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/arm/lpc176x/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,407 @@
+/**
+ * @file timer.c
+ *
+ * @ingroup lpc176x
+ *
+ * @brief Timer controller for the mbed lpc1768 board.
+ */
+
+/*
+ * Copyright (c) 2014 Taller Technologies.
+ *
+ * @author  Boretto Martin    (martin.boretto@tallertechnologies.com)
+ * @author  Diaz Marcos (marcos.diaz@tallertechnologies.com)
+ * @author  Lenarduzzi Federico  (federico.lenarduzzi@tallertechnologies.com)
+ * @author  Daniel Chicco  (daniel.chicco@tallertechnologies.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 <stdio.h>
+#include <rtems/status-checks.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/io.h>
+#include <bsp/timer.h>
+
+/**
+ * @brief Represents all the timers.
+ */
+const lpc176x_timer timers[ LPC176X_TIMER_COUNT ] =
+{
+  {
+    .device = (lpc176x_timer_device *) LPC176X_TMR0_BASE_ADDR,
+    .module = LPC176X_MODULE_TIMER_0,
+    .pinselcap = LPC176X_TIMER0_CAPTURE_PORTS,
+    .pinselemat = LPC176X_TIMER0_EMATCH_PORTS,
+  },
+  {
+    .device = (lpc176x_timer_device *) LPC176X_TMR1_BASE_ADDR,
+    .module = LPC176X_MODULE_TIMER_1,
+    .pinselcap = LPC176X_TIMER1_CAPTURE_PORTS,
+    .pinselemat = LPC176X_TIMER1_EMATCH_PORTS,
+  },
+  {
+    .device = (lpc176x_timer_device *) LPC176X_TMR2_BASE_ADDR,
+    .module = LPC176X_MODULE_TIMER_2,
+    .pinselcap = LPC176X_TIMER2_CAPTURE_PORTS,
+    .pinselemat = LPC176X_TIMER2_EMATCH_PORTS,
+  },
+  {
+    .device = (lpc176x_timer_device *) LPC176X_TMR3_BASE_ADDR,
+    .module = LPC176X_MODULE_TIMER_3,
+    .pinselcap = LPC176X_TIMER3_CAPTURE_PORTS,
+    .pinselemat = LPC176X_TIMER3_EMATCH_PORTS,
+  }
+};
+
+/**
+ * @brief Represents all the functions according to the timers.
+ */
+lpc176x_timer_functions functions_vector[ LPC176X_TIMER_COUNT ] =
+{
+  {
+    .funct_vector = NULL
+  },
+  {
+    .funct_vector = NULL
+  },
+  {
+    .funct_vector = NULL
+  },
+  {
+    .funct_vector = NULL
+  }
+};
+
+/**
+ * @brief Calls the corresponding interrupt function and pass the timer
+ *        as parameter.
+ *
+ * @param  timer The specific device.
+ * @param  interruptnumber Interrupt number.
+ */
+static inline void lpc176x_call_desired_isr(
+  const lpc176x_timer_number number,
+  const lpc176x_isr_function interruptfunction
+)
+{
+  if ( ( *functions_vector[ number ].funct_vector )[ interruptfunction ] !=
+       NULL ) {
+    ( *functions_vector[ number ].funct_vector )[ interruptfunction ]( number );
+  }
+
+  /* else implies that the function vector points NULL. Also,
+     there is nothing to do. */
+}
+
+/**
+ * @brief Gets true if the selected interrupt is pending
+ *
+ * @param number: the number of the timer.
+ * @param interrupt: the interrupt we are checking for.
+ * @return TRUE if the interrupt is pending.
+ */
+static inline bool lpc176x_timer_interrupt_is_pending(
+  const lpc176x_timer_number tnumber,
+  const lpc176x_isr_function function
+)
+{
+  assert( ( tnumber < LPC176X_TIMER_COUNT )
+    && ( function < LPC176X_ISR_FUNCTIONS_COUNT ) );
+
+  return ( timers[ tnumber ].device->IR &
+           LPC176X_TIMER_INTERRUPT_SOURCE_BIT( function ) );
+}
+
+/**
+ * @brief Resets interrupt status for the selected interrupt
+ *
+ * @param tnumber: the number of the timer
+ * @param interrupt: the interrupt we are resetting
+ */
+static inline void lpc176x_timer_reset_interrupt(
+  const lpc176x_timer_number tnumber,
+  const lpc176x_isr_function function
+)
+{
+  assert( ( tnumber < LPC176X_TIMER_COUNT )
+    && ( function < LPC176X_ISR_FUNCTIONS_COUNT ) );
+  timers[ tnumber ].device->IR =
+    LPC176X_TIMER_INTERRUPT_SOURCE_BIT( function );
+}
+
+inline rtems_status_code lpc176x_timer_reset(
+  const lpc176x_timer_number tnumber )
+{
+  rtems_status_code status_code = RTEMS_INVALID_NUMBER;
+
+  if ( tnumber < LPC176X_TIMER_COUNT ) {
+    timers[ tnumber ].device->TCR = LPC176X_TIMER_RESET;
+    status_code = RTEMS_SUCCESSFUL;
+  }
+
+  /* else implies that the timer number is invalid. Also,
+     an invalid number is returned. */
+
+  return status_code;
+}
+
+inline rtems_status_code lpc176x_timer_set_mode(
+  const lpc176x_timer_number tnumber,
+  const lpc176x_timer_mode   mode
+)
+{
+  rtems_status_code status_code = RTEMS_INVALID_NUMBER;
+
+  if ( tnumber < LPC176X_TIMER_COUNT ) {
+    timers[ tnumber ].device->CTCR = mode;
+    status_code = RTEMS_SUCCESSFUL;
+  }
+
+  /* else implies that the timer number is invalid. Also,
+     an invalid number is returned. */
+
+  return status_code;
+}
+
+inline rtems_status_code lpc176x_timer_start(
+  const lpc176x_timer_number tnumber )
+{
+  rtems_status_code status_code = RTEMS_INVALID_NUMBER;
+
+  if ( tnumber < LPC176X_TIMER_COUNT ) {
+    timers[ tnumber ].device->TCR = LPC176X_TIMER_START;
+    status_code = RTEMS_SUCCESSFUL;
+  }
+
+  /* else implies that the timer number is invalid. Also,
+     an invalid number is returned. */
+
+  return status_code;
+}
+
+inline rtems_status_code lpc176x_timer_is_started(
+  const lpc176x_timer_number tnumber,
+  bool                      *is_started
+)
+{
+  rtems_status_code status_code = RTEMS_INVALID_NUMBER;
+
+  if ( tnumber < LPC176X_TIMER_COUNT ) {
+    *is_started = ( timers[ tnumber ].device->TCR & LPC176X_TIMER_START ) ==
+                  LPC176X_TIMER_START;
+    status_code = RTEMS_SUCCESSFUL;
+  }
+
+  /* else implies that the timer number is invalid. Also,
+     an invalid number is returned. */
+
+  return status_code;
+}
+
+inline rtems_status_code lpc176x_timer_set_resolution(
+  const lpc176x_timer_number tnumber,
+  const lpc176x_microseconds resolution
+)
+{
+  rtems_status_code status_code = RTEMS_INVALID_NUMBER;
+
+  if ( tnumber < LPC176X_TIMER_COUNT ) {
+    timers[ tnumber ].device->PR = ( LPC176X_CCLK /
+                                     LPC176X_TIMER_PRESCALER_DIVISOR ) *
+                                   resolution;
+    status_code = RTEMS_SUCCESSFUL;
+  }
+
+  /* else implies that the timer number is invalid. Also,
+     an invalid number is returned. */
+
+  return status_code;
+}
+
+rtems_status_code lpc176x_timer_match_config(
+  const lpc176x_timer_number   tnumber,
+  const lpc176x_match_port     match_port,
+  const lpc176x_match_function function,
+  const uint32_t               match_value
+)
+{
+  rtems_status_code status_code = RTEMS_INVALID_NUMBER;
+
+  if ( ( tnumber < LPC176X_TIMER_COUNT )
+       && ( match_port < LPC176X_EMATCH_PORTS_COUNT )
+       && ( function < LPC176X_TIMER_MATCH_FUNCTION_COUNT ) ) {
+    timers[ tnumber ].device->MCR =
+      LPC176X_SET_MCR( timers[ tnumber ].device->MCR,
+        match_port, function );
+    timers[ tnumber ].device->MR[ match_port ] = match_value;
+    status_code = RTEMS_SUCCESSFUL;
+  }
+
+  /* else implies that the timer number, or a match port or a function
+      is invalid. Also, an invalid number is returned. */
+
+  return status_code;
+}
+
+inline rtems_status_code lpc176x_timer_capture_config(
+  const lpc176x_timer_number     tnumber,
+  const lpc176x_capture_port     capture_port,
+  const lpc176x_capture_function function
+)
+{
+  rtems_status_code status_code = RTEMS_INVALID_NUMBER;
+
+  if ( ( tnumber < LPC176X_TIMER_COUNT )
+       && ( capture_port < LPC176X_CAPTURE_PORTS_COUNT )
+       && ( function < LPC176X_TIMER_CAPTURE_FUNCTION_COUNT ) ) {
+    timers[ tnumber ].device->CCR =
+      LPC176X_SET_CCR( timers[ tnumber ].device->CCR,
+        capture_port, function );
+    lpc176x_pin_select( timers[ tnumber ].pinselcap[ capture_port ],
+      LPC176X_PIN_FUNCTION_11 );
+  }
+
+  /* else implies that the timer number or the capture port is invalid. Also,
+     an invalid number is returned. */
+
+  return status_code;
+}
+
+inline rtems_status_code lpc176x_timer_external_match_config(
+  const lpc176x_timer_number       number,
+  const lpc176x_match_port         match_port,
+  const lpc176x_ext_match_function function
+)
+{
+  rtems_status_code status_code = RTEMS_INVALID_NUMBER;
+
+  if ( ( number < LPC176X_TIMER_COUNT )
+       && ( match_port < LPC176X_EMATCH_PORTS_COUNT ) ) {
+    timers[ number ].device->EMR =
+      LPC176X_SET_EMR( timers[ number ].device->EMR,
+        match_port, function );
+    lpc176x_pin_select( timers[ number ].pinselemat[ match_port ],
+      LPC176X_PIN_FUNCTION_11 );
+    status_code = RTEMS_SUCCESSFUL;
+  }
+
+  /* else implies that the timer number or the match port is invalid. Also,
+     an invalid number is returned. */
+
+  return status_code;
+}
+
+inline uint32_t lpc176x_timer_get_capvalue(
+  const lpc176x_timer_number number,
+  const lpc176x_capture_port capture_port
+)
+{
+  assert( ( number < LPC176X_TIMER_COUNT )
+    && ( capture_port < LPC176X_CAPTURE_PORTS_COUNT ) );
+
+  return timers[ number ].device->CR[ capture_port ];
+}
+
+inline uint32_t lpc176x_timer_get_timer_value(
+  const lpc176x_timer_number tnumber )
+{
+  assert( tnumber < LPC176X_TIMER_COUNT );
+
+  return timers[ tnumber ].device->TC;
+}
+
+inline rtems_status_code lpc176x_timer_set_timer_value(
+  const lpc176x_timer_number tnumber,
+  const uint32_t             timer_value
+)
+{
+  rtems_status_code status_code = RTEMS_INVALID_NUMBER;
+
+  if ( tnumber < LPC176X_TIMER_COUNT ) {
+    timers[ tnumber ].device->TC = timer_value;
+    status_code = RTEMS_SUCCESSFUL;
+  }
+
+  /* else implies that the timer number is invalid. Also,
+     an invalid number is returned. */
+
+  return status_code;
+}
+
+void lpc176x_timer_isr( void *arg )
+{
+  const lpc176x_timer_number tnumber = (lpc176x_timer_number) arg;
+
+  if ( tnumber < LPC176X_TIMER_COUNT ) {
+    lpc176x_isr_function i;
+
+    for ( i = 0; i < LPC176X_ISR_FUNCTIONS_COUNT; ++i ) {
+      if ( lpc176x_timer_interrupt_is_pending( tnumber, i ) ) {
+        lpc176x_call_desired_isr( tnumber, i );
+        lpc176x_timer_reset_interrupt( tnumber, i );
+      }
+
+      /* else implies that the current timer is not pending. Also,
+         there is nothing to do. */
+    }
+  }
+
+  /* else implies that the timer number is not valid. Also,
+     there is nothing to do. */
+}
+
+rtems_status_code lpc176x_timer_init( const lpc176x_timer_number tnumber )
+{
+  rtems_status_code status_code = RTEMS_INVALID_NUMBER;
+
+  if ( tnumber < LPC176X_TIMER_COUNT ) {
+    status_code = lpc176x_module_enable( timers[ tnumber ].module,
+      LPC176X_MODULE_PCLK_DEFAULT );
+    RTEMS_CHECK_SC( status_code, "Enabling the timer module." );
+
+    status_code = lpc176x_timer_reset( tnumber );
+    status_code = lpc176x_timer_set_mode( tnumber,
+      LPC176X_TIMER_MODE_TIMER );
+    status_code = lpc176x_timer_set_resolution( tnumber,
+      LPC176X_TIMER_DEFAULT_RESOLUTION );
+
+    timers[ tnumber ].device->MCR = LPC176X_TIMER_CLEAR_FUNCTION;
+    timers[ tnumber ].device->CCR = LPC176X_TIMER_CLEAR_FUNCTION;
+    timers[ tnumber ].device->EMR = LPC176X_TIMER_CLEAR_FUNCTION;
+  }
+
+  /* else implies that the timer number is not valid. Also,
+     an invalid number is returned. */
+
+  return status_code;
+}
+
+rtems_status_code lpc176x_timer_init_with_interrupt(
+  const lpc176x_timer_number            tnumber,
+  const lpc176x_isr_funct_vector *const vector
+)
+{
+  rtems_status_code status_code = RTEMS_INVALID_NUMBER;
+
+  char isrname[ LPC176X_ISR_NAME_STRING_SIZE ];
+
+  snprintf( isrname, LPC176X_ISR_NAME_STRING_SIZE, "TimerIsr%d", tnumber );
+
+  if ( tnumber < LPC176X_TIMER_COUNT && vector != NULL ) {
+    functions_vector[ tnumber ].funct_vector = vector;
+
+    status_code = lpc176x_timer_init( tnumber );
+    status_code = rtems_interrupt_handler_install(
+      LPC176X_TIMER_VECTOR_NUMBER( tnumber ),
+      isrname,
+      RTEMS_INTERRUPT_UNIQUE,
+      lpc176x_timer_isr,
+      (void *) tnumber );
+  }
+
+  return status_code;
+}
Index: bsps/arm/rtl22xx/btimer/btimer.c
===================================================================
--- bsps/arm/rtl22xx/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/arm/rtl22xx/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,65 @@
+/**
+ * @file
+ * @brief RTL22xx board Timer driver
+ *
+ * This uses Timer1 for timing measurments.
+ */
+
+/*
+ * By Ray Xu <rayx.cn@gmail.com>, modify form Mc9328mxl RTEMS DSP
+ *
+ * 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 <rtems.h>
+#include <rtems/btimer.h>
+#include <lpc22xx.h>
+#include "lpc_timer.h"
+
+uint32_t g_start;
+uint32_t g_freq;
+
+bool benchmark_timer_find_average_overhead;
+
+
+/*
+ * Set up Timer 1
+ */
+void benchmark_timer_initialize( void )
+{
+       g_freq = LPC22xx_Fpclk / 1000;
+}
+
+/*
+ *  The following controls the behavior of benchmark_timer_read().
+ *
+ *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      0  /* It typically takes X.X microseconds */
+                             /* (Y countdowns) to start/stop the timer. */
+                             /* This value is in microseconds. */
+#define LEAST_VALID       1  /* Don't trust a clicks value lower than this */
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+  return (T0TC/(LPC22xx_Fpclk/1000000));
+  /*
+   *  Total is calculated by taking into account the number of timer overflow
+   *  interrupts since the timer was initialized and clicks since the last
+   *  interrupts.
+   */
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
+
Index: bsps/arm/rtl22xx/btimer/lpc_timer.h
===================================================================
--- bsps/arm/rtl22xx/btimer/lpc_timer.h	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/arm/rtl22xx/btimer/lpc_timer.h	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,48 @@
+#ifndef __LPC_TIMER_H
+#define __LPC_TIMER_H
+
+/*************************************************************************
+ *
+ *    File name   : Timer.h
+ *
+ **************************************************************************/
+
+/* Timer Control register bit descriptions */
+#define TCR_ENABLE_BIT  0
+#define TCR_RESET_BIT   1
+
+// The channel name which is used in matching, in fact they represent
+// corresponding Match Register
+#define CH_MAXNUM       4
+#define CH0             0
+#define CH1             1
+#define CH2             2
+#define CH3             3
+
+// The channel name which is used in capturing, in fact they represent
+// corresponding Capture Register
+#define CPCH_MAXNUM     4
+#define CPCH0           0
+#define CPCH1           1
+#define CPCH2           2
+#define CPCH3           3
+
+//The actions when matching
+#define TimerAction_Interrupt   0x1
+#define TimerAction_ResetTimer  0x2
+#define TimerAction_StopTimer   0x4
+
+//Interrupt source type
+#define TIMERMR0Int     0x01
+#define TIMERMR1Int     0x02
+#define TIMERMR2Int     0x04
+#define TIMERMR3Int     0x08
+#define TIMERCR0Int     0x10
+#define TIMERCR1Int     0x20
+#define TIMERCR2Int     0x40
+#define TIMERCR3Int     0x80
+
+#define TIMERALLInt     0xFF
+
+#endif //__LPC_Timer_H
+
Index: bsps/arm/smdk2410/btimer/btimer.c
===================================================================
--- bsps/arm/smdk2410/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/arm/smdk2410/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,100 @@
+/**
+ * @file
+ * @brief S3C2400 Timer driver
+ *
+ * This uses timer 1 for timing measurments.
+ */
+
+/*
+ * 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 <rtems.h>
+#include <rtems/btimer.h>
+#include <s3c24xx.h>
+
+uint32_t g_start;
+uint32_t g_freq;
+
+bool benchmark_timer_find_average_overhead;
+
+
+/*
+ * Set up Timer 1
+ */
+void benchmark_timer_initialize( void )
+{
+    uint32_t cr;
+
+    /* stop TIMER1*/
+    cr=rTCON & 0xFFFFF0FF;
+    rTCON=(cr | (0x0 << 8));
+
+    /* set MUX for Timer1 to 1/2 */
+    cr=rTCFG1 & 0xFFFFFF0F;
+    rTCFG1=(cr | (0<<4));
+
+    /* input freq=PLCK/2 Mhz*/
+    g_freq = get_PCLK() / 2000;
+    rTCNTB1 = 0xFFFF;
+
+    /* start TIMER1 with manual reload */
+    cr=rTCON & 0xFFFFF0FF;
+    rTCON=(cr | (0x1 << 9));
+    rTCON=(cr | (0x1 << 8));
+
+    g_start =  rTCNTO1;
+}
+
+/*
+ *  The following controls the behavior of benchmark_timer_read().
+ *
+ *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      0  /* It typically takes X.X microseconds */
+                             /* (Y countdowns) to start/stop the timer. */
+                             /* This value is in microseconds. */
+#define LEAST_VALID       1  /* Don't trust a clicks value lower than this */
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+    uint32_t t;
+    unsigned long long total;
+
+    t =  rTCNTO1;
+    /*
+     *  Total is calculated by taking into account the number of timer overflow
+     *  interrupts since the timer was initialized and clicks since the last
+     *  interrupts.
+     */
+
+    total = (g_start - t);
+
+    /* convert to microseconds */
+    total = (total*1000) / g_freq;
+
+    if ( benchmark_timer_find_average_overhead == 1 ) {
+        return (int) total;
+    } else if ( total < LEAST_VALID ) {
+        return 0;
+    }
+
+    /*
+     *  Somehow convert total into microseconds
+     */
+    return (total - AVG_OVERHEAD);
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+    benchmark_timer_find_average_overhead = find_flag;
+}
+
Index: bsps/epiphany/epiphany_sim/btimer/btimer.c
===================================================================
--- bsps/epiphany/epiphany_sim/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/epiphany/epiphany_sim/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2015 University of York.
+ * Hesham ALMatary <hmka501@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 <rtems/btimer.h>
+#include <rtems/score/epiphany-utility.h>
+
+extern char bsp_start_vector_table_begin[];
+
+bool benchmark_timer_find_average_overhead;
+
+static void benchmark_timer1_interrupt_handler(void)
+{
+  unsigned int val = 0xFFFFFFFF;
+  unsigned int event_type = 0x1;
+
+  /* Embed assembly code for setting timer1 */
+  __asm__ __volatile__ ("movts ctimer1, %[val] \t \n" :: [val] "r" (val));
+
+  __asm__ __volatile__ ("movfs r16, config; \t \n"
+                "mov   r17, %%low(0xfffff0ff);\t \n"
+                "movt  r17, %%high(0xffff0ff);\t \n"
+                "lsl   r18, %[event_type], 0x8; \t \n"
+                "and   r16, r16, r17; \t \n"
+                "orr   r16, r16, r18; \t \n"
+                "movts config, r16; \t \n"
+                :: [event_type] "r" (event_type));
+}
+
+/* Start eCore tiemr 1 usef for profiling and timing analysis */
+void benchmark_timer_initialize( void )
+{
+  /* Install interrupt handler for timer 1 */
+
+  proc_ptr *table =
+    (proc_ptr *) bsp_start_vector_table_begin;
+
+  table[TIMER1] = benchmark_timer1_interrupt_handler;
+
+  benchmark_timer1_interrupt_handler();
+}
+
+/*
+ *  The following controls the behavior of benchmark_timer_read().
+ *
+ *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      0  /* It typically takes X.X microseconds */
+                             /* (Y countdowns) to start/stop the timer. */
+                             /* This value is in microseconds. */
+#define LEAST_VALID       1  /* Don't trust a clicks value lower than this */
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+  uint32_t timer_val = 0;
+  uint32_t total;
+
+  __asm__ __volatile__ ("movfs %[timer_val], ctimer1 \t \n"
+    :[timer_val] "=r" (timer_val):);
+
+  total = (0xFFFFFFFF - timer_val);
+
+  if ( benchmark_timer_find_average_overhead == true )
+    return total;
+  else {
+    if ( total < LEAST_VALID )
+      return 0;            /* below timer resolution */
+  /*
+   *  Somehow convert total into microseconds
+   */
+      return (total - AVG_OVERHEAD);
+    }
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/i386/pc386/btimer/btimer.c
===================================================================
--- bsps/i386/pc386/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/i386/pc386/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,552 @@
+/*
+ * This file contains the PC386 timer package.
+ *
+ * Rosimildo daSilva -ConnectTel, Inc - Fixed infinite loop in the Calibration
+ * routine. I've seen this problems with faster machines ( pentiums ). Sometimes
+ * RTEMS just hangs at startup.
+ *
+ * Joel 9 May 2010: This is now seen sometimes on qemu.
+ *
+ *  Modifications by:
+ *  (C) Copyright 1997 -
+ *    NavIST Group - Real-Time Distributed Systems and Industrial Automation
+ *    http://pandora.ist.utl.pt
+ *    Instituto Superior Tecnico * Lisboa * PORTUGAL
+ *
+ *  This file is provided "AS IS" without warranty of any kind, either
+ *  expressed or implied.
+ *
+ *  Based upon code by
+ *  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 <stdlib.h>
+#include <bsp.h>
+#include <rtems/btimer.h>
+#include <bsp/irq-generic.h>
+#include <libcpu/cpuModel.h>
+
+/*
+ * Constants
+ */
+#define AVG_OVERHEAD  0         /* 0.1 microseconds to start/stop timer. */
+#define LEAST_VALID   1         /* Don't trust a value lower than this.  */
+#define SLOW_DOWN_IO  0x80      /* io which does nothing */
+
+#define TWO_MS (uint32_t)(2000) /* TWO_MS = 2000us (sic!) */
+
+#define MSK_NULL_COUNT 0x40     /* bit counter available for reading */
+
+#define CMD_READ_BACK_STATUS 0xE2   /* command read back status */
+
+RTEMS_INTERRUPT_LOCK_DEFINE( /* visible global variable */ ,
+   rtems_i386_i8254_access_lock, "rtems_i386_i8254_access_lock" );
+
+/*
+ * Global Variables
+ */
+volatile uint32_t         Ttimer_val;
+bool                      benchmark_timer_find_average_overhead = true;
+volatile unsigned int     fastLoop1ms, slowLoop1ms;
+
+void              (*benchmark_timer_initialize_function)(void) = 0;
+benchmark_timer_t (*benchmark_timer_read_function)(void) = 0;
+void              (*Timer_exit_function)(void) = 0;
+
+/* timer (int 08h) Interrupt Service Routine (defined in 'timerisr.s') */
+extern void timerisr(void);
+
+void Timer_exit(void);
+
+/*
+ * Pentium optimized timer handling.
+ */
+
+/*
+ *  Timer cleanup routine at RTEMS exit.
+ *
+ *  NOTE: This routine is not really necessary, since there will be
+ *        a reset at exit.
+ */
+static void tsc_timer_exit(void)
+{
+}
+
+static void tsc_timer_initialize(void)
+{
+  static bool First = true;
+
+  if (First) {
+    First = false;
+
+    atexit(Timer_exit); /* Try not to hose the system at exit. */
+  }
+  Ttimer_val = rdtsc(); /* read starting time */
+}
+
+/*
+ * Read TSC timer value.
+ */
+static uint32_t tsc_read_timer(void)
+{
+  register uint32_t  total;
+
+  total =  (uint32_t)(rdtsc() - Ttimer_val);
+
+  if (benchmark_timer_find_average_overhead)
+    return total;
+
+  if (total < LEAST_VALID)
+    return 0;                 /* below timer resolution */
+
+  return (total - AVG_OVERHEAD);
+}
+
+/*
+ * Non-Pentium timer handling.
+ */
+#define US_PER_ISR   250  /* Number of micro-seconds per timer interruption */
+
+/*
+ * Timer cleanup routine at RTEMS exit. NOTE: This routine is
+ * not really necessary, since there will be a reset at exit.
+ */
+static void timerOff(const rtems_raw_irq_connect_data* used)
+{
+  rtems_interrupt_lock_context lock_context;
+  /*
+   * disable interrrupt at i8259 level
+   */
+  bsp_interrupt_vector_disable(used->idtIndex - BSP_IRQ_VECTOR_BASE);
+
+  rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context);
+
+   /* reset timer mode to standard (DOS) 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);
+}
+
+static void timerOn(const rtems_raw_irq_connect_data* used)
+{
+  rtems_interrupt_lock_context lock_context;
+
+  rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context);
+
+  /* load timer for US_PER_ISR microsecond period */
+  outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);
+  outport_byte(TIMER_CNTR0, US_TO_TICK(US_PER_ISR) >> 0 & 0xff);
+  outport_byte(TIMER_CNTR0, US_TO_TICK(US_PER_ISR) >> 8 & 0xff);
+
+  rtems_interrupt_lock_release(&rtems_i386_i8254_access_lock, &lock_context);
+
+  /*
+   * enable interrrupt at i8259 level
+   */
+  bsp_interrupt_vector_enable(used->idtIndex - BSP_IRQ_VECTOR_BASE);
+}
+
+static rtems_raw_irq_connect_data timer_raw_irq_data = {
+  BSP_PERIODIC_TIMER + BSP_IRQ_VECTOR_BASE,
+  timerisr,
+  timerOn,
+  timerOff,
+  NULL
+};
+
+/*
+ * Timer cleanup routine at RTEMS exit.
+ *
+ * NOTE: This routine is not really necessary, since there will be
+ *       a reset at exit.
+ */
+static void i386_timer_exit(void)
+{
+  i386_delete_idt_entry (&timer_raw_irq_data);
+}
+
+extern void rtems_irq_prologue_0(void);
+static void i386_timer_initialize(void)
+{
+  static bool First = true;
+
+  if (First) {
+    rtems_raw_irq_connect_data raw_irq_data = {
+      BSP_PERIODIC_TIMER + BSP_IRQ_VECTOR_BASE,
+      rtems_irq_prologue_0,
+      NULL,
+      NULL,
+      NULL
+    };
+
+    First = false;
+    i386_delete_idt_entry (&raw_irq_data);
+
+    atexit(Timer_exit);            /* Try not to hose the system at exit. */
+    if (!i386_set_idt_entry (&timer_raw_irq_data)) {
+      printk("raw handler connection failed\n");
+      rtems_fatal_error_occurred(1);
+    }
+  }
+  /* wait for ISR to be called at least once */
+  Ttimer_val = 0;
+  while (Ttimer_val == 0)
+    continue;
+  Ttimer_val = 0;
+}
+
+/*
+ * Read hardware timer value.
+ */
+static uint32_t i386_read_timer(void)
+{
+  register uint32_t         total, clicks;
+  register uint8_t          lsb, msb;
+  rtems_interrupt_lock_context lock_context;
+
+  rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context);
+  outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_LATCH);
+  inport_byte(TIMER_CNTR0, lsb);
+  inport_byte(TIMER_CNTR0, msb);
+  rtems_interrupt_lock_release(&rtems_i386_i8254_access_lock, &lock_context);
+
+  clicks = (msb << 8) | lsb;
+  total  = (Ttimer_val * US_PER_ISR) + (US_PER_ISR - TICK_TO_US(clicks));
+
+  if (benchmark_timer_find_average_overhead)
+    return total;
+
+  if (total < LEAST_VALID)
+    return 0;                            /* below timer resolution */
+
+  return (total - AVG_OVERHEAD);
+}
+
+/*
+ * General timer functions using either TSC-based implementation
+ * or interrupt-based implementation
+ */
+
+void benchmark_timer_initialize(void)
+{
+  static bool First = true;
+
+  if (First) {
+    if (x86_has_tsc()) {
+#if defined(DEBUG)
+      printk("TSC: timer initialization\n");
+#endif /* DEBUG */
+      benchmark_timer_initialize_function = &tsc_timer_initialize;
+      benchmark_timer_read_function = &tsc_read_timer;
+      Timer_exit_function = &tsc_timer_exit;
+    } else {
+#if defined(DEBUG)
+      printk("ISR: timer initialization\n");
+#endif /* DEBUG */
+      benchmark_timer_initialize_function = &i386_timer_initialize;
+      benchmark_timer_read_function = &i386_read_timer;
+      Timer_exit_function = &i386_timer_exit;
+    }
+    First = false;
+  }
+  (*benchmark_timer_initialize_function)();
+}
+
+uint32_t benchmark_timer_read(void)
+{
+  return (*benchmark_timer_read_function)();
+}
+
+void Timer_exit(void)
+{
+  if ( Timer_exit_function )
+    return (*Timer_exit_function)();
+}
+
+/*
+ * Set internal benchmark_timer_find_average_overhead flag value.
+ */
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
+
+static unsigned short lastLoadedValue;
+
+/*
+ *  Loads timer 0 with value passed as arguemnt.
+ *
+ *  Returns: Nothing. Loaded value must be a number of clock bits...
+ */
+static void loadTimerValue( unsigned short loadedValue )
+{
+  rtems_interrupt_lock_context lock_context;
+  rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context);
+  lastLoadedValue = loadedValue;
+  outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_SQWAVE);
+  outport_byte(TIMER_CNTR0, loadedValue & 0xff);
+  outport_byte(TIMER_CNTR0, (loadedValue >> 8) & 0xff);
+  rtems_interrupt_lock_release(&rtems_i386_i8254_access_lock, &lock_context);
+}
+
+/*
+ * Reads the current value of the timer, and converts the
+ *  number of ticks to micro-seconds.
+ *
+ * Returns: number of clock bits elapsed since last load.
+ */
+static unsigned int readTimer0(void)
+{
+  unsigned short lsb, msb;
+  unsigned char  status;
+  unsigned int  count;
+  rtems_interrupt_lock_context lock_context;
+  rtems_interrupt_lock_acquire(&rtems_i386_i8254_access_lock, &lock_context);
+
+  outport_byte(
+    TIMER_MODE,
+    (TIMER_RD_BACK | (RB_COUNT_0 & ~(RB_NOT_STATUS | RB_NOT_COUNT)))
+  );
+  inport_byte(TIMER_CNTR0, status);
+  inport_byte(TIMER_CNTR0, lsb);
+  inport_byte(TIMER_CNTR0, msb);
+
+  rtems_interrupt_lock_release(&rtems_i386_i8254_access_lock, &lock_context);
+
+  count = ( msb << 8 ) | lsb ;
+  if (status & RB_OUTPUT )
+    count += lastLoadedValue;
+
+  return (2*lastLoadedValue - count);
+}
+
+static void Timer0Reset(void)
+{
+  loadTimerValue(0xffff);
+  readTimer0();
+}
+
+static void fastLoop (unsigned int loopCount)
+{
+  unsigned int i;
+  for( i=0; i < loopCount; i++ )outport_byte( SLOW_DOWN_IO, 0 );
+}
+
+static void slowLoop (unsigned int loopCount)
+{
+  unsigned int j;
+  for (j=0; j <100 ;  j++) {
+    fastLoop (loopCount);
+  }
+}
+
+/*
+ * #define DEBUG_CALIBRATE
+ */
+void
+Calibrate_loop_1ms(void)
+{
+  unsigned int offset, offsetTmp, emptyCall, emptyCallTmp, res, i, j;
+  unsigned int targetClockBits, currentClockBits;
+  unsigned int slowLoopGranularity, fastLoopGranularity;
+  rtems_interrupt_level  level;
+  int retries = 0;
+
+  /*
+   * This code is designed to run before interrupt management
+   * is enabled and running it on multiple CPUs and or after
+   * secondary CPUs are bring up seems really broken.
+   * Disabling of local interrupts is enough.
+   */
+  rtems_interrupt_local_disable(level);
+
+retry:
+  if ( ++retries >= 5 ) {
+    printk( "Calibrate_loop_1ms: too many attempts. giving up!!\n" );
+    while (1);
+  }
+#ifdef DEBUG_CALIBRATE
+  printk("Calibrate_loop_1ms is starting,  please wait (but not too long.)\n");
+#endif
+  targetClockBits = US_TO_TICK(1000);
+  /*
+   * Fill up the cache to get a correct offset
+   */
+  Timer0Reset();
+  readTimer0();
+  /*
+   * Compute the minimal offset to apply due to read counter register.
+   */
+  offset = 0xffffffff;
+  for (i=0; i <1000; i++) {
+    Timer0Reset();
+    offsetTmp = readTimer0();
+    offset += offsetTmp;
+  }
+  offset = offset / 1000; /* compute average */
+  /*
+   * calibrate empty call
+   */
+  fastLoop (0);
+  emptyCall = 0;
+  j = 0;
+  for (i=0; i <10; i++) {
+    Timer0Reset();
+    fastLoop (0);
+    res =  readTimer0();
+    /* res may be inferior to offset on fast
+     * machine because we took an average for offset
+     */
+    if (res >  offset) {
+      ++j;
+      emptyCallTmp = res - offset;
+      emptyCall += emptyCallTmp;
+    }
+  }
+  if (j == 0) emptyCall = 0;
+  else emptyCall = emptyCall / j; /* compute average */
+  /*
+   * calibrate fast loop
+   */
+  Timer0Reset();
+  fastLoop (10000);
+  res = readTimer0() - offset;
+  if (res < emptyCall) {
+    printk(
+      "Problem #1 in offset computation in Calibrate_loop_1ms "
+        " in file libbsp/i386/pc386/timer/timer.c\n"
+    );
+    goto retry;
+  }
+  fastLoopGranularity = (res - emptyCall) / 10000;
+  /*
+   * calibrate slow loop
+   */
+  Timer0Reset();
+  slowLoop(10);
+  res = readTimer0();
+  if (res < offset + emptyCall) {
+    printk(
+      "Problem #2 in offset computation in Calibrate_loop_1ms "
+        " in file libbsp/i386/pc386/timer/timer.c\n"
+    );
+    goto retry;
+  }
+  slowLoopGranularity = (res - offset - emptyCall)/ 10;
+
+  if (slowLoopGranularity == 0) {
+    printk(
+      "Problem #3 in offset computation in Calibrate_loop_1ms "
+        " in file libbsp/i386/pc386/timer/timer.c\n"
+    );
+    goto retry;
+  }
+
+  targetClockBits += offset;
+#ifdef DEBUG_CALIBRATE
+  printk("offset = %u, emptyCall = %u, targetClockBits = %u\n",
+  offset, emptyCall, targetClockBits);
+  printk("slowLoopGranularity = %u fastLoopGranularity =  %u\n",
+  slowLoopGranularity, fastLoopGranularity);
+#endif
+  slowLoop1ms = (targetClockBits - emptyCall) / slowLoopGranularity;
+  if (slowLoop1ms != 0) {
+    fastLoop1ms = targetClockBits % slowLoopGranularity;
+    if (fastLoop1ms > emptyCall) fastLoop1ms -= emptyCall;
+  }
+  else
+    fastLoop1ms = targetClockBits - emptyCall / fastLoopGranularity;
+
+  if (slowLoop1ms != 0) {
+    /*
+     * calibrate slow loop
+     */
+
+    while(1)
+      {
+ int previousSign = 0; /* 0 = unset, 1 = incrementing,  2 = decrementing */
+ Timer0Reset();
+ slowLoop(slowLoop1ms);
+ currentClockBits = readTimer0();
+ if (currentClockBits > targetClockBits) {
+   if ((currentClockBits - targetClockBits) < slowLoopGranularity) {
+     /* decrement loop counter anyway to be sure slowLoop(slowLoop1ms) < targetClockBits */
+     --slowLoop1ms;
+     break;
+   }
+   else {
+     --slowLoop1ms;
+     if (slowLoop1ms == 0) break;
+     if (previousSign == 0) previousSign = 2;
+     if (previousSign == 1) break;
+   }
+ }
+ else {
+   if ((targetClockBits - currentClockBits) < slowLoopGranularity) {
+      break;
+    }
+    else {
+      ++slowLoop1ms;
+      if (previousSign == 0) previousSign = 1;
+      if (previousSign == 2) break;
+    }
+  }
+      }
+  }
+  /*
+   * calibrate fast loop
+   */
+
+  if (fastLoopGranularity != 0 ) {
+    while(1) {
+      int previousSign = 0; /* 0 = unset, 1 = incrementing,  2 = decrementing */
+      Timer0Reset();
+      if (slowLoop1ms != 0) slowLoop(slowLoop1ms);
+      fastLoop(fastLoop1ms);
+      currentClockBits = readTimer0();
+      if (currentClockBits > targetClockBits) {
+  if ((currentClockBits - targetClockBits) < fastLoopGranularity)
+    break;
+  else {
+    --fastLoop1ms;
+    if (previousSign == 0) previousSign = 2;
+    if (previousSign == 1) break;
+  }
+      }
+      else {
+  if ((targetClockBits - currentClockBits) < fastLoopGranularity)
+    break;
+  else {
+    ++fastLoop1ms;
+    if (previousSign == 0) previousSign = 1;
+    if (previousSign == 2) break;
+  }
+      }
+    }
+  }
+#ifdef DEBUG_CALIBRATE
+  printk("slowLoop1ms = %u, fastLoop1ms = %u\n", slowLoop1ms, fastLoop1ms);
+#endif
+  rtems_interrupt_local_enable(level);
+
+}
+
+/*
+ *  loop which waits at least timeToWait ms
+ */
+void Wait_X_ms( unsigned int timeToWait)
+{
+  unsigned int j;
+
+  for (j=0; j<timeToWait ; j++) {
+    if (slowLoop1ms != 0) slowLoop(slowLoop1ms);
+    fastLoop(fastLoop1ms);
+  }
+}
Index: bsps/i386/pc386/btimer/timerisr.S
===================================================================
--- bsps/i386/pc386/btimer/timerisr.S	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/i386/pc386/btimer/timerisr.S	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,56 @@
+/*-------------------------------------------------------------------------+
+| timerisr.s v1.1 - PC386 BSP - 1997/08/07
++--------------------------------------------------------------------------+
+| This file contains the PC386 timer interrupt handler.
++--------------------------------------------------------------------------+
+| (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 base on:
+|   timerisr.s,v 1.5 1995/12/19 20:07:45 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 <rtems/asm.h>
+
+BEGIN_CODE
+
+	EXTERN(Ttimer_val)
+
+/*-------------------------------------------------------------------------+
+|         Function: rtems_isr timerisr(rtems_vector_number);
+|      Description: ISR for the timer. The timer is set up to generate an
+|                   interrupt at maximum intervals.
+| Global Variables: None.
+|        Arguments: standard - see RTEMS documentation.
+|          Returns: standard return value - see RTEMS documentation.
++--------------------------------------------------------------------------*/
+	PUBLIC(timerisr)
+SYM (timerisr):
+	incl	Ttimer_val	# another tick
+	pushl	eax
+	movb	$0x20, al
+	outb	al, $0x20	# signal generic End Of Interrupt (EOI) to PIC
+	popl	eax
+	iret
+
+END_CODE
+
+END
Index: bsps/lm32/shared/btimer/btimer.c
===================================================================
--- bsps/lm32/shared/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/lm32/shared/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,111 @@
+/*  timer.c
+ *
+ *  This file manages the benchmark timer used by the RTEMS Timing
+ *  Test Suite.  Each measured time period is demarcated by calls to
+ *  benchmark_timer_initialize() and benchmark_timer_read().
+ *  benchmark_timer_read() usually returns the number of microseconds
+ *  since benchmark_timer_initialize() exitted.
+ *
+ *  NOTE: It is important that the timer start/stop overhead be
+ *        determined when porting or modifying this code.
+ *
+ *  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
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <rtems/btimer.h>
+#include <rtems/bspIo.h>
+#include "../include/system_conf.h"
+#include "../../shared/clock/clock.h"
+
+static inline int timerread(unsigned int reg)
+{
+#if ON_SIMULATOR && defined(TIMER0_BASE_ADDRESS)
+  return *((int*)(TIMER0_BASE_ADDRESS + reg));
+#elif defined(TIMER1_BASE_ADDRESS)
+  return *((int*)(TIMER1_BASE_ADDRESS + reg));
+#else
+#warning "Benchmarking timer not available!"
+  return 0;
+#endif
+}
+
+static inline void timerwrite(unsigned int reg, int value)
+{
+#if ON_SIMULATOR && defined(TIMER0_BASE_ADDRESS)
+  *((int*)(TIMER0_BASE_ADDRESS + reg)) = value;
+#elif defined(TIMER1_BASE_ADDRESS)
+  *((int*)(TIMER1_BASE_ADDRESS + reg)) = value;
+#endif
+}
+
+bool benchmark_timer_find_average_overhead;
+
+void benchmark_timer_initialize( void )
+{
+  /* Set timer period */
+  timerwrite(LM32_CLOCK_PERIOD, 0xffffffff);
+  /* Stop timer */
+  timerwrite(LM32_CLOCK_CR, LM32_CLOCK_CR_STOP);
+  /* Clear status register */
+  timerwrite(LM32_CLOCK_SR, 0);
+  /* Start timer */
+  timerwrite(LM32_CLOCK_CR, LM32_CLOCK_CR_START);
+}
+
+/*
+ *  The following controls the behavior of benchmark_timer_read().
+ *
+ *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      4  /* It typically takes X.X microseconds */
+                             /* (Y countdowns) to start/stop the timer. */
+                             /* This value is in microseconds. */
+#define LEAST_VALID       4  /* Don't trust a clicks value lower than this */
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+  uint32_t ticks;
+  uint32_t total;
+  uint32_t status;
+
+  ticks = 0xffffffff - timerread(LM32_CLOCK_SNAPSHOT);
+  status = timerread(LM32_CLOCK_SR);
+  if (status & LM32_CLOCK_SR_TO)
+    printk("Timer overflow!\n");
+
+  total = ticks / (CPU_FREQUENCY / 1000000);
+
+  if ( benchmark_timer_find_average_overhead == true )
+    return total;          /* in XXX microsecond units */
+  else
+    {
+      if ( total < LEAST_VALID )
+	return 0;            /* below timer resolution */
+      /*
+       *  Somehow convert total into microseconds
+       */
+      return (total - AVG_OVERHEAD);
+    }
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/m32c/m32cbsp/btimer/btimer.c
===================================================================
--- bsps/m32c/m32cbsp/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m32c/m32cbsp/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,69 @@
+/*
+ *  This file implements a stub benchmark timer that is sufficient to
+ *  satisfy linking the RTEMS Benchmarks.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2001.
+ *  On-Line Applications Research Corporation (OAR).
+ */
+
+#include <bsp.h>
+#include <rtems/btimer.h>
+
+#include <varvects.h>
+
+bool benchmark_timer_find_average_overhead;
+uint32_t benchmark_timer_overhead = 10;
+
+#define TABSR *((uint8_t *)0x340)
+#define TA0MR *((uint8_t *)0x356)
+#define TA0   *((uint16_t *)0x346)
+#define TA0IC *((uint8_t *)0x6c)
+
+static int benchmark_timer_interrupts;
+
+static void __attribute__((interrupt)) timer_ra_interrupt(void);
+
+#define ivec_timer_a0 12
+
+void __attribute__((interrupt))
+timer_ra_interrupt(void)
+{
+  benchmark_timer_interrupts++;
+  TA0IC = 0x05;
+
+}
+
+void benchmark_timer_initialize(void)
+{
+  benchmark_timer_interrupts = 0;
+  _set_var_vect (timer_ra_interrupt, ivec_timer_a0);
+  TA0MR = 0x00;
+  TA0   = 0xffff;
+  TA0IC = 0x05;
+  TABSR = 0x55;
+}
+
+benchmark_timer_t benchmark_timer_read(void)
+{
+  uint32_t count;
+
+  count = 0xFFFF - TA0;
+  count += benchmark_timer_interrupts * 0xFFFFL;
+
+  if (!benchmark_timer_find_average_overhead) {
+    if ( count > benchmark_timer_overhead )
+      count -= benchmark_timer_overhead;
+    else
+      count = 0;
+  }
+  return count;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/m68k/av5282/btimer/btimer.c
===================================================================
--- bsps/m68k/av5282/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/av5282/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,34 @@
+/*
+ *  Timer Init
+ *
+ *  Use the last DMA timer (DTIM3) as the diagnostic timer.
+ */
+
+#include <rtems.h>
+#include <rtems/btimer.h>
+#include <bsp.h>
+
+void
+benchmark_timer_initialize(void)
+{
+    int preScaleDivisor = 58;
+    int div = MCF5282_TIMER_DTMR_CLK_DIV1;
+    MCF5282_TIMER3_DTRR = 0x2710;
+    MCF5282_TIMER3_DTMR = 0;
+    MCF5282_TIMER3_DTMR = MCF5282_TIMER_DTMR_PS(preScaleDivisor - 1) | div |
+                          MCF5282_TIMER_DTMR_RST;
+}
+
+/*
+ * Return timer value in microsecond units
+ */
+uint32_t
+benchmark_timer_read(void)
+{
+    return MCF5282_TIMER3_DTCN;
+}
+
+void
+benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+}
Index: bsps/m68k/gen68340/btimer/btimer.c
===================================================================
--- bsps/m68k/gen68340/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/gen68340/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,256 @@
+/*
+ * ATTENTION: As MC68349 has no built-in Timer, the following code doesn't work
+ *            in a MC68349. You can't use FIFO full mode for the moment, but
+ *            it should be easy to fix this by using an external timer.
+ *
+ * Use TIMER 1 for TIMEOUT when using FIFO FULL mode in UART driver
+ * Use TIMER 2 for timing test suites
+ *
+ *  NOTE: It is important that the timer start/stop overhead be
+ *        determined when porting or modifying this code.
+ */
+
+/*
+ * 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-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>
+#include <bsp.h>
+#include <rtems/btimer.h>
+#include <m340uart.h>
+#include <m340timer.h>
+#include <m68340.h>
+
+#define TIMER1_VECTOR 122
+#define TIMER1_IRQ_LEVEL 5
+#define TIMER1_INTERRUPT_ARBITRATION 5
+
+#define TIMER2_VECTOR 123
+#define TIMER2_IRQ_LEVEL 4
+#define TIMER2_INTERRUPT_ARBITRATION 4
+
+#define CLOCK_SPEED 25    /* in Mhz */
+
+#define max(a,b) (((a)>(b)) ? (a) : (b))
+
+void (*Restart_Fifo_Full_A_Timer)(void);
+void (*Restart_Check_A_Timer)(void);
+void (*Restart_Fifo_Full_B_Timer)(void);
+void (*Restart_Check_B_Timer)(void);
+
+int preload = 0;
+
+/*
+ * __Restart_Fifo_Full_Timer
+ *
+ * When a character is received, sets the TIMER to raise an interrupt at
+ * TIMEOUT.  It's necessary to prevent from not getting n-1 characters
+ * (with n the Uart Fifo size).
+ */
+static void __Restart_Fifo_Full_Timer (void)
+{
+  TSR1 |= m340_TO;
+  TCR1 &= ~m340_CPE;
+  WPREL11 = preload;
+  TCR1 |= m340_CPE;
+}
+
+/*
+ * __Restart_Check_Timer
+ *
+ * When no character has been received recently, check now and then if whether
+ * a there's a character in the FIFO
+ */
+static void __Restart_Check_Timer (void)
+{
+ TSR1 |= m340_TO;
+ TCR1 &= ~m340_CPE;
+ WPREL11 = 0xFFFF;
+ TCR1 |= m340_CPE;
+}
+
+/*
+ * __do_nothing
+ *
+ * We always restart the fifo full timer with a call to Restart_*_Timer
+ * if we do not use FIFO full, Restart_X_Timer are set to do __do_nothing
+ */
+static void __do_nothing (void)
+{
+}
+
+#define Fifo_Full_on_A \
+   (m340_uart_config[UART_CHANNEL_A].rx_mode==UART_FIFO_FULL && \
+    m340_uart_config[UART_CHANNEL_A].enable && \
+    m340_uart_config[UART_CHANNEL_A].mode==UART_INTERRUPTS)
+#define Fifo_Full_on_B \
+    (m340_uart_config[UART_CHANNEL_B].rx_mode==UART_FIFO_FULL && \
+    m340_uart_config[UART_CHANNEL_B].enable && \
+    m340_uart_config[UART_CHANNEL_B].mode==UART_INTERRUPTS)
+
+/*
+ * Fifo_Full_benchmark_timer_initialize
+ *
+ * initialize Timer 1 for FIFO full mode
+ */
+void Fifo_Full_benchmark_timer_initialize (void)
+{
+  float max_baud_rate;
+  int prescaler_output_tap = -1;
+  int nb_of_clock_ticks = 0;
+  rtems_isr_entry old_handler;
+
+  /*
+   *  USE TIMER 1 for UART FIFO FULL mode
+   */
+  if ( Fifo_Full_on_A || Fifo_Full_on_B ) {
+    /* Disable the timer */
+    TCR1 &= ~m340_SWR;
+
+    /* Reset the interrupts */
+    TSR1 &= ~(m340_TO | m340_TG | m340_TC);
+
+    /* Init the stop bit for normal operation, ignore FREEZE, user privileges,
+     * set interrupt arbitration.
+     */
+    TMCR1 = TIMER1_INTERRUPT_ARBITRATION;
+
+    /* interrupt priority level and interrupt vector */
+    TIR1 = TIMER1_VECTOR | (TIMER1_IRQ_LEVEL << 8);
+
+    /* compute prescaler */
+    if ( Fifo_Full_on_A && Fifo_Full_on_B) {
+      max_baud_rate = max(
+        m340_uart_config[UART_CHANNEL_A].rx_baudrate,
+        m340_uart_config[UART_CHANNEL_B].rx_baudrate
+      );
+    } else if ( Fifo_Full_on_A ) {
+      max_baud_rate = m340_uart_config[UART_CHANNEL_A].rx_baudrate;
+    } else
+      max_baud_rate = m340_uart_config[UART_CHANNEL_B].rx_baudrate;
+
+    /* find out config */
+    nb_of_clock_ticks = (10/max_baud_rate)*(CLOCK_SPEED*1000000)*1.2;
+    if (nb_of_clock_ticks < 0xFFFF) {
+      preload = nb_of_clock_ticks;
+      prescaler_output_tap = -1;
+    } else if (nb_of_clock_ticks/2 < 0xFFFF) {
+      preload = nb_of_clock_ticks/2;
+      prescaler_output_tap = m340_Divide_by_2;
+    } else if (nb_of_clock_ticks/4 < 0xFFFF) {
+      preload = nb_of_clock_ticks/4;
+      prescaler_output_tap = m340_Divide_by_4;
+    } else if (nb_of_clock_ticks/8 < 0xFFFF) {
+      preload = nb_of_clock_ticks/8;
+      prescaler_output_tap = m340_Divide_by_16;
+    } else if (nb_of_clock_ticks/16 < 0xFFFF) {
+      preload = nb_of_clock_ticks/16;
+      prescaler_output_tap = m340_Divide_by_16;
+    } else if (nb_of_clock_ticks/32 < 0xFFFF) {
+      preload = nb_of_clock_ticks/32;
+      prescaler_output_tap = m340_Divide_by_32;
+    } else if (nb_of_clock_ticks/64 < 0xFFFF) {
+      preload = nb_of_clock_ticks/64;
+      prescaler_output_tap = m340_Divide_by_64;
+    } else if (nb_of_clock_ticks/128 < 0xFFFF) {
+      preload = nb_of_clock_ticks/128;
+      prescaler_output_tap = m340_Divide_by_128;
+    } else if (nb_of_clock_ticks/256 < 0xFFFF) {
+      preload = nb_of_clock_ticks/256;
+      prescaler_output_tap = m340_Divide_by_256;
+    }
+
+    /* Input Capture/Output Compare (ICOC) */
+    TCR1 = m340_SWR | m340_TO_Enabled | m340_ICOC;
+    if (prescaler_output_tap!=-1) TCR1 |= prescaler_output_tap | m340_PSE;
+
+    /* install interrupt vector */
+    rtems_interrupt_catch(InterruptHandler, TIMER1_VECTOR, &old_handler);
+
+  } /* fifo full mode on a uart */
+
+  /* install routines */
+  if ( Fifo_Full_on_A ) {
+    Restart_Check_A_Timer     = __Restart_Check_Timer;
+    Restart_Fifo_Full_A_Timer = __Restart_Fifo_Full_Timer;
+  } else {
+    Restart_Check_A_Timer     = __do_nothing;
+    Restart_Fifo_Full_A_Timer = __do_nothing;
+  }
+
+  if ( Fifo_Full_on_B ) {
+    Restart_Check_B_Timer     = __Restart_Check_Timer;
+    Restart_Fifo_Full_B_Timer = __Restart_Fifo_Full_Timer;
+  } else {
+    Restart_Check_B_Timer     = __do_nothing;
+    Restart_Fifo_Full_B_Timer = __do_nothing;
+  }
+
+  /* start checking timer */
+  Restart_Check_A_Timer();
+  Restart_Check_B_Timer();
+}
+
+/*
+ * benchmark_timer_initialize
+ *
+ * init Timer for timing test suites
+ */
+void benchmark_timer_initialize (void)
+{
+  /* Disable the timer */
+  TCR2 &= ~m340_SWR;
+
+  /* Reset the interrupts */
+  TSR2 &= ~(m340_TO | m340_TG | m340_TC);
+
+  /* Init the stop bit for normal operation, ignore FREEZE, user privileges,
+     set interrupt arbitration */
+  TMCR1 = TIMER2_INTERRUPT_ARBITRATION;
+
+  /* interrupt priority level and interrupt vector */
+  TIR1 = TIMER2_VECTOR | (TIMER2_IRQ_LEVEL << 8);
+
+  /* Init the stop bit for normal operation, ignore FREEZE, user privileges,
+     set interrupt arbitration */
+  TMCR2 = TIMER2_INTERRUPT_ARBITRATION;
+
+  /* Preload register 1 */
+  WPREL21 = 0xFFFF;
+
+  /* Input Capture/Output Compare (ICOC) */
+  TCR2 = m340_SWR | m340_ICOC | m340_PSE | m340_Divide_by_16 | m340_CPE;
+}
+
+/*
+ * benchmark_timer_read
+ *
+ * Return timer value in microsecond units
+ */
+uint32_t benchmark_timer_read (void)
+{
+ /* there's CLOCK_SPEED / 16 micro seconds between two timer
+  * register decrements.
+  */
+ return (((0xFFFF - TCNTR2) * CLOCK_SPEED) / 16);
+}
+
+/*
+ * benchmark_timer_disable_subtracting_average_overhead
+ */
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+}
Index: bsps/m68k/gen68360/btimer/btimer.c
===================================================================
--- bsps/m68k/gen68360/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/gen68360/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,83 @@
+/*
+ * Use TIMER 1 and TIMER 2 for Timing Test Suite
+ * The hardware on the MC68360 makes these routines very simple.
+ *
+ * Based on the `gen68302' board support package, and covered by the
+ * original distribution terms.
+ *
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ */
+
+/*
+ *
+ *  Input parameters:  NONE
+ *
+ *  Output parameters:  NONE
+ *
+ *  NOTE: It is important that the timer start/stop overhead be
+ *        determined when porting or modifying this code.
+ *
+ *  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>
+#include <rtems/btimer.h>
+#include <bsp.h>
+#include <rtems/m68k/m68360.h>
+
+void
+benchmark_timer_initialize (void)
+{
+	/*
+	 * Reset timers 1 and 2
+	 */
+	m360.tgcr &= ~0x00FF;
+	m360.tcn1 = 0;
+	m360.tcn2 = 0;
+	m360.ter1 = 0xFFFF;
+	m360.ter2 = 0xFFFF;
+
+	/*
+	 * Cascade timers 1 and 2
+	 */
+	m360.tgcr |= 0x0080;
+
+	/*
+	 * Configure timers 1 and 2 to a single 32-bit, 1 MHz timer.
+	 * HARDWARE:
+	 *	Change the `25' to match your processor clock
+	 */
+	m360.tmr2 = ((25-1) << 8) | 0x2;
+	m360.tmr1 = 0;
+
+	/*
+	 * Start the timers
+	 */
+	m360.tgcr |=  0x0011;
+}
+
+/*
+ * Return timer value in microsecond units
+ */
+uint32_t
+benchmark_timer_read (void)
+{
+	unsigned short val;
+
+	val = m360.tcn1;
+	return val;
+}
+
+void
+benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+}
Index: bsps/m68k/genmcf548x/btimer/btimer.c
===================================================================
--- bsps/m68k/genmcf548x/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/genmcf548x/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,83 @@
+/*===============================================================*\
+| Project: RTEMS generic mcf548x BSP                              |
++-----------------------------------------------------------------+
+| File: timer.c                                                   |
++-----------------------------------------------------------------+
+| The file contains the diagnostic timer 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  |
+|                                                                 |
+\*===============================================================*/
+
+/*
+ *  Timer Init
+ *
+ *  Use the second slice timer (SLT1) as the diagnostic timer.
+ */
+
+#include <rtems.h>
+#include <rtems/btimer.h>
+#include <bsp.h>
+#include <mcf548x/mcf548x.h>
+
+bool benchmark_timer_find_average_overhead;
+static uint32_t microsecond_timer_value = 0;
+
+void benchmark_timer_initialize(void)
+{
+    MCF548X_SLT_SLTCNT1 = 0xFFFFFFFF;
+    MCF548X_SLT_SCR1 |= (MCF548X_SLT_SCR_TEN | MCF548X_SLT_SCR_RUN);
+}
+
+/*
+ * Return timer value in microsecond units
+ * XLB clock 100 MHz / 1us is equal to 100 counts
+ */
+uint32_t
+benchmark_timer_read(void)
+{
+    microsecond_timer_value = (0xFFFFFFFF - MCF548X_SLT_SCNT1)/100;
+
+    return microsecond_timer_value;
+}
+
+void
+benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+    benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/m68k/mcf52235/btimer/btimer.c
===================================================================
--- bsps/m68k/mcf52235/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/mcf52235/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,39 @@
+/*
+ *  Timer Init
+ *
+ *  Use the last DMA timer (DTIM3) as the diagnostic timer.
+ *
+ *  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/btimer.h>
+#include <bsp.h>
+
+void benchmark_timer_initialize(void)
+{
+  uint32_t preScaleDivisor = bsp_get_CPU_clock_speed() / 1000000;
+
+  MCF_DTIM3_DTMR = 0;
+  MCF_DTIM3_DTMR = MCF_DTIM_DTMR_PS(preScaleDivisor - 1) |
+    MCF_DTIM_DTMR_CLK_DIV1 | MCF_DTIM_DTMR_RST;
+}
+
+/*
+ * Return timer value in microsecond units
+ */
+benchmark_timer_t benchmark_timer_read(void)
+{
+  return MCF_DTIM3_DTCN;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+}
Index: bsps/m68k/mcf5225x/btimer/btimer.c
===================================================================
--- bsps/m68k/mcf5225x/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/mcf5225x/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,39 @@
+/*
+ *  Timer Init
+ *
+ *  Use the last DMA timer (DTIM3) as the diagnostic timer.
+ *
+ *  Author: W. Eric Norum <norume@aps.anl.gov>
+ *
+ *  COPYRIGHT (c) 2005-2010.
+ *  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/btimer.h>
+#include <bsp.h>
+
+void benchmark_timer_initialize(void)
+{
+  uint32_t preScaleDivisor = bsp_get_CPU_clock_speed() / 1000000;
+
+  MCF_DTIM3_DTMR = 0;
+  MCF_DTIM3_DTMR = MCF_DTIM_DTMR_PS(preScaleDivisor - 1) |
+    MCF_DTIM_DTMR_CLK_DIV1 | MCF_DTIM_DTMR_RST;
+}
+
+/*
+ * Return timer value in microsecond units
+ */
+benchmark_timer_t benchmark_timer_read(void)
+{
+  return MCF_DTIM3_DTCN;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+}
Index: bsps/m68k/mcf5235/btimer/btimer.c
===================================================================
--- bsps/m68k/mcf5235/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/mcf5235/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,34 @@
+/*
+ *  Timer Init
+ *
+ *  Use the last DMA timer (DTIM3) as the diagnostic timer.
+ */
+
+#include <rtems.h>
+#include <rtems/btimer.h>
+#include <bsp.h>
+
+void
+benchmark_timer_initialize(void)
+{
+    int preScaleDivisor = 0x4A;
+    int div = MCF5235_TIMER_DTMR_CLK_DIV1;
+    MCF5235_TIMER_DTRR3 = 0x2710;
+    MCF5235_TIMER3_DTMR = 0;
+    MCF5235_TIMER3_DTMR = MCF5235_TIMER_DTMR_PS(preScaleDivisor) | div |
+                          MCF5235_TIMER_DTMR_RST;
+}
+
+/*
+ * Return timer value in microsecond units
+ */
+uint32_t
+benchmark_timer_read(void)
+{
+    return MCF5235_TIMER3_DTCN;
+}
+
+void
+benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+}
Index: bsps/m68k/mcf5329/btimer/btimer.c
===================================================================
--- bsps/m68k/mcf5329/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/mcf5329/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,39 @@
+/*
+ *  Timer Init
+ *
+ *  Use the last DMA timer (DTIM3) as the diagnostic timer.
+ *
+ *  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/btimer.h>
+#include <bsp.h>
+
+void benchmark_timer_initialize(void)
+{
+  uint32_t preScaleDivisor = bsp_get_BUS_clock_speed() / 1000000;
+
+  MCF_DTIM3_DTMR = 0;
+  MCF_DTIM3_DTMR = MCF_DTIM_DTMR_PS(preScaleDivisor - 1) |
+    MCF_DTIM_DTMR_CLK_DIV1 | MCF_DTIM_DTMR_RST;
+}
+
+/*
+ * Return timer value in microsecond units
+ */
+benchmark_timer_t benchmark_timer_read(void)
+{
+  return MCF_DTIM3_DTCN;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+}
Index: bsps/m68k/mrm332/btimer/btimer.c
===================================================================
--- bsps/m68k/mrm332/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/mrm332/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,60 @@
+/*
+ *  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 <bsp.h>
+#include <rtems/btimer.h>
+
+bool benchmark_timer_find_average_overhead;
+
+extern rtems_isr Clock_isr(void);
+
+void benchmark_timer_initialize( void )
+{
+}
+
+/*
+ *  The following controls the behavior of benchmark_timer_read().
+ *
+ *  FIND_AVG_OVERHEAD *  instructs the routine to return the "raw" count.
+ *
+ *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      0  /* It typically takes X.X microseconds */
+                             /* (Y countdowns) to start/stop the timer. */
+                             /* This value is in microseconds. */
+#define LEAST_VALID       1  /* Don't trust a clicks value lower than this */
+
+/*
+ * Return timer value in 1/2-microsecond units
+ */
+benchmark_timer_t benchmark_timer_read( void )
+{
+  uint32_t         total;
+  total = 0;
+
+  if ( benchmark_timer_find_average_overhead == true )
+    return total;          /* in XXX microsecond units */
+
+  if ( total < LEAST_VALID )
+    return 0;            /* below timer resolution */
+
+  return (total - AVG_OVERHEAD);
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/m68k/mvme147/btimer/btimer.c
===================================================================
--- bsps/m68k/mvme147/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/mvme147/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,67 @@
+/*
+ *  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 <rtems/btimer.h>
+#include <bsp.h>
+
+#define TIMER_INT_LEVEL 6
+
+#define COUNTDOWN_VALUE 0
+/* Allows 0.4096 second delay betwin ints */
+/* Each tick is 6.25 us */
+
+int Ttimer_val;
+bool benchmark_timer_find_average_overhead;
+
+rtems_isr timerisr(rtems_vector_number);
+
+void benchmark_timer_initialize(void)
+{
+  (void) set_vector(timerisr, TIMER_1_VECTOR, 0); /* install ISR */
+
+  Ttimer_val = 0;                 /* clear timer ISR count */
+  pcc->timer1_int_control = 0x00; /* Disable T1 Interr. */
+  pcc->timer1_preload = COUNTDOWN_VALUE;
+  /* write countdown preload value */
+  pcc->timer1_control = 0x00; /* load preload value */
+  pcc->timer1_control = 0x07; /* clear T1 overflow counter, enable counter */
+  pcc->timer1_int_control = TIMER_INT_LEVEL|0x08;
+  /* Enable Timer 1 and set its int. level */
+
+}
+
+#define AVG_OVERHEAD      0  /* No need to start/stop the timer to read
+				its value on the MVME147 PCC: reads are not
+				synchronized whith the counter updates*/
+#define LEAST_VALID       10 /* Don't trust a value lower than this */
+
+benchmark_timer_t benchmark_timer_read(void)
+{
+  uint32_t         total;
+  uint16_t         counter_value;
+
+  counter_value = pcc->timer1_count; /* read the counter value */
+
+  total = ((Ttimer_val * 0x10000) + counter_value); /* in 6.25 us units */
+  /* DC note : just look at the assembly generated
+     to see gcc's impressive optimization ! */
+  return total;
+
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/m68k/mvme147/btimer/timerisr.S
===================================================================
--- bsps/m68k/mvme147/btimer/timerisr.S	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/mvme147/btimer/timerisr.S	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,26 @@
+/*  timer_isr()
+ *
+ *  This routine provides the ISR for the PCC timer on the MVME147
+ *  board.   The timer is set up to generate an interrupt at maximum
+ *  intervals.
+ *
+ *  MVME147 port for TNI - Telecom Bretagne
+ *  by Dominique LE CAMPION (Dominique.LECAMPION@enst-bretagne.fr)
+ *  May 1996
+ */
+
+#include <rtems/asm.h>
+
+BEGIN_CODE
+
+.set T1_CONTROL_REGISTER,  0xfffe1018    | timer 1 control register
+
+        PUBLIC (timerisr)
+SYM (timerisr):
+	orb	#0x80, T1_CONTROL_REGISTER | clear T1 int status bit
+        addql   #1, SYM (Ttimer_val)     | increment timer value
+end_timerisr:
+	rte
+
+END_CODE
+END
Index: bsps/m68k/mvme162/btimer/btimer.c
===================================================================
--- bsps/m68k/mvme162/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/mvme162/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,73 @@
+/*
+ *  This routine initializes the Tick Timer 1 on the MVME162 board.
+ *
+ *  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 <rtems.h>
+#include <rtems/btimer.h>
+#include <bsp.h>
+
+/* Periodic tick interval */
+#define TICK_INTERVAL         0x10000U
+#define TIMER_INT_LEVEL       6
+
+uint32_t            Ttimer_val;
+bool                benchmark_timer_find_average_overhead;
+
+rtems_isr timerisr(rtems_vector_number vector);
+
+void benchmark_timer_initialize(void)
+{
+  (void) set_vector( timerisr, VBR0 * 0x10 + 0x8, 0 );
+
+  Ttimer_val = 0;                     /* clear timer ISR count */
+  lcsr->vector_base |= MASK_INT;      /* unmask VMEchip2 interrupts */
+  lcsr->intr_clear |= 0x01000000;     /* clear pending interrupt */
+  lcsr->to_ctl = 0xE7;                /* prescaler to 1 MHz (see Appendix A1) */
+  lcsr->timer_cmp_1 = TICK_INTERVAL;
+  lcsr->timer_cnt_1 = 0;              /* clear counter */
+  lcsr->board_ctl |= 7;               /* increment, reset-on-compare, */
+                                      /*   and clear-overflow-cnt */
+
+  lcsr->intr_level[0] |= TIMER_INT_LEVEL; /* set int level */
+  lcsr->intr_ena |= 0x01000000;           /* enable tick timer 1 interrupt */
+}
+
+#define AVG_OVERHEAD      3U    /* It typically takes 3.0 microseconds */
+                                /* (3 countdowns) to start/stop the timer. */
+#define LEAST_VALID       10U   /* Don't trust a value lower than this */
+
+benchmark_timer_t benchmark_timer_read(void)
+{
+  uint32_t            total;
+
+  total = (Ttimer_val * TICK_INTERVAL) + lcsr->timer_cnt_1;
+
+  if ( benchmark_timer_find_average_overhead == true )
+    return total;          /* in one-half microsecond units */
+
+  if ( total < LEAST_VALID )
+    return 0;            /* below timer resolution */
+
+  return (total-AVG_OVERHEAD) >> 1;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/m68k/mvme162/btimer/timerisr.S
===================================================================
--- bsps/m68k/mvme162/btimer/timerisr.S	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/mvme162/btimer/timerisr.S	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,44 @@
+/*  timer_isr()
+ *
+ *  This routine provides the ISR for the Z8036 timer on the MVME136
+ *  board.   The timer is set up to generate an interrupt at maximum
+ *  intervals.
+ *
+ *  Input parameters:  NONE
+ *
+ *  Output parameters:  NONE
+ *
+ *  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 <rtems/asm.h>
+
+BEGIN_CODE
+
+.set INTR_CLEAR_REG,      0xfff40074      | interrupt clear register
+.set RELOAD,              0x01000000      | clear tick 1 interrupt
+
+        PUBLIC (Ttimer_val)
+        PUBLIC (timerisr)
+SYM (timerisr):
+        move.l  a0, -(a7)                 | save a0
+        movea.l #INTR_CLEAR_REG, a0       | a0 = addr of cmd status reg
+        ori.l   #RELOAD, (a0)             | reload countdown
+        addq.l  #1, SYM (Ttimer_val)      | increment timer value
+        move.l  (a7)+, a0                 | restore a0
+        rte
+
+END_CODE
+END
Index: bsps/m68k/mvme167/btimer/btimer.c
===================================================================
--- bsps/m68k/mvme167/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/mvme167/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,139 @@
+/**
+ * @file
+ *
+ * This file manages the benchmark timer used by the RTEMS Timing Test Suite.
+ * Each measured time period is demarcated by calls to
+ * benchmark_timer_initialize() and benchmark_timer_read().
+ * benchmark_timer_read() usually returns the number of microseconds
+ * since benchmark_timer_initialize() exitted.
+ *
+ * These functions are prototyped in rtems/btimer.h and
+ * must be implemented as part of the BSP.
+ *
+ * This port does not allow the application to select which timer on the
+ * MVME167 to use for the timer, nor does it allow the application to
+ * configure the timer. The timer uses the VMEchip2 Tick Timer #1. This timer
+ * is distinct from the clock, which uses Tick Timer #2 in the VMEchip2.
+ *
+ * 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 file:
+ *  Copyright (c) 1998, National Research Council of Canada
+ */
+
+#include <rtems.h>
+#include <rtems/btimer.h>
+#include <bsp.h>
+
+/* Periodic tick interval */
+#define TICK_INTERVAL         10000UL     /* T1's countdown constant (10 ms) */
+#define TIMER_INT_LEVEL       6           /* T1's interrupt level */
+#define TIMER_VECTOR (VBR0 * 0x10 + 0x8)  /* T1 is vector $X8 (p. 2-71)*/
+
+/* Number of interrupts since timer was re-initialized */
+uint32_t            Ttimer_val;
+
+/*
+ *  Set to true to return raw value. Normally zero. Depends on being allocated
+ *  in the .bss section and on that section being explicitly zeroed at boot
+ *  time.
+ */
+bool benchmark_timer_find_average_overhead;
+
+rtems_isr timerisr(rtems_vector_number);
+
+/*
+ *  This routine initializes the Tick Timer 1 on the MVME167 board.
+ *
+ *  Input parameters:  NONE
+ *
+ *  Output parameters:  NONE
+ *
+ *  NOTE: This routine may not work if the optimizer is enabled for some
+ *        compilers. The multiple writes may be optimized away.
+ *
+ *        It is important that the timer start/stop overhead be
+ *        determined when porting or modifying this code.
+ *
+ *  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).
+ */
+void benchmark_timer_initialize(void)
+{
+  (void) set_vector( timerisr, TIMER_VECTOR, 0 );
+
+  Ttimer_val = 0;                       /* clear timer ISR count */
+  lcsr->intr_ena &= 0xFEFFFFFF;         /* disable tick timer 1 interrupt */
+  lcsr->intr_clear |= 0x01000000;       /* clear tick timer 1 interrupt */
+  lcsr->intr_level[0] =                 /* set int level */
+        (lcsr->intr_level[0] & 0xFFFFFFF0) | TIMER_INT_LEVEL;
+  lcsr->timer_cmp_1 = TICK_INTERVAL;    /* period in compare register */
+  lcsr->timer_cnt_1 = 0;                /* clear tick timer 1 counter */
+  lcsr->board_ctl |= 7;                 /* start tick timer 1, reset-on-compare, */
+                                        /*   and clear overflow counter */
+
+  lcsr->intr_ena |= 0x01000000;         /* enable tick timer 1 interrupt */
+  lcsr->vector_base |= MASK_INT;        /* unmask VMEchip2 interrupts */
+}
+
+#define AVG_OVERHEAD      3UL   /* It typically takes 3.0 microseconds */
+                                /* (3 countdowns) to start/stop the timer. */
+#define LEAST_VALID       3UL   /* Don't trust a value lower than this */
+
+/*
+ *  This routine reads the Tick Timer 1 on the MVME167 board.
+ *
+ *  Input parameters:  NONE
+ *
+ *  Output parameters:  time in microseconds
+ *
+ *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+benchmark_timer_t benchmark_timer_read(void)
+{
+  uint32_t            total;
+
+  total = (Ttimer_val * TICK_INTERVAL) + lcsr->timer_cnt_1;
+
+  if ( benchmark_timer_find_average_overhead )
+    return total;          /* in one microsecond units */
+
+  if ( total < LEAST_VALID )
+    return 0;            /* below timer resolution */
+
+  return total - AVG_OVERHEAD;
+}
+
+/*
+ *  This routine sets the benchmark_timer_find_average_overhead flag in this
+ *  module.
+ *
+ *  Input parameters:  NONE
+ *
+ *  Output parameters:  time in microseconds
+ */
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/m68k/mvme167/btimer/timerisr.S
===================================================================
--- bsps/m68k/mvme167/btimer/timerisr.S	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/mvme167/btimer/timerisr.S	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,50 @@
+/**
+ *  @file
+ *
+ *  This ISR is used to bump a count of interval "overflow" interrupts which
+ *  have occurred since the timer was started. The number of overflows is taken
+ *  into account in the benchmark_timer_read() routine.
+ */
+
+/*
+ *  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.
+ *
+ *  Modifications of respective RTEMS file: COPYRIGHT (c) 1994.
+ *  Copyright (c) 1998, National Research Council of Canada
+ */
+
+#include <rtems/asm.h>
+
+BEGIN_CODE
+
+.set INTR_CLEAR_REG,    0xfff40074      | interrupt clear register
+.set T1_CNTRL_REG,      0xfff40060      | tick timer 1 control register
+.set CLEAR_INT,         0x01000000      | clear tick 1 interrupt
+.set CLEAR_OVF,         0x00000004      | clear tick 1 overflow counter
+
+        PUBLIC (Ttimer_val)
+        PUBLIC (timerisr)
+SYM (timerisr):
+        move.l  a0, -(a7)               | save a0
+        move.l  d0, -(a7)               | save d0
+        move.w  sr, -(a7)               | save ccr
+        movea.l #INTR_CLEAR_REG, a0     | a0 = addr of intr clr reg
+        ori.l   #CLEAR_INT, (a0)        | clear tick timer 1 intr
+        movea.l #T1_CNTRL_REG, a0       | a0 = addr of t1 cntrl reg
+        move.l  (a0), d0                | read overflow counter
+        lsr.l   #4, d0                  | put overflow in low order bits
+        andi.l  #0xF, d0                | keep only overflow
+        add.l   d0, SYM (Ttimer_val)    | increment timer value
+        ori.l   #CLEAR_OVF, (a0)        | clear overflow counter
+        move.w  (a7)+, sr               | restore ccr
+        move.l  (a7)+, d0               | restore d0
+        move.l  (a7)+, a0               | restore a0
+        rte
+
+END_CODE
+END
Index: bsps/m68k/uC5282/btimer/btimer.c
===================================================================
--- bsps/m68k/uC5282/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/m68k/uC5282/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,47 @@
+/*
+ *  Timer Init
+ *
+ *  Use the last DMA timer (DTIM3) as the diagnostic timer.
+ *
+ *  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 <bsp.h>
+#include <rtems/btimer.h>
+
+void
+benchmark_timer_initialize(void)
+{
+    int preScaleDivisor = bsp_get_CPU_clock_speed() / 1000000;
+    int div = MCF5282_TIMER_DTMR_CLK_DIV1;
+
+    if (preScaleDivisor > 256) {
+        preScaleDivisor /= 16;
+        div = MCF5282_TIMER_DTMR_CLK_DIV16;
+    }
+    MCF5282_TIMER3_DTMR = 0;
+    MCF5282_TIMER3_DTMR = MCF5282_TIMER_DTMR_PS(preScaleDivisor - 1) | div |
+                          MCF5282_TIMER_DTMR_RST;
+}
+
+/*
+ * Return timer value in microsecond units
+ */
+uint32_t
+benchmark_timer_read(void)
+{
+    return MCF5282_TIMER3_DTCN;
+}
+
+void
+benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+}
Index: bsps/mips/csb350/btimer/btimer.c
===================================================================
--- bsps/mips/csb350/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/mips/csb350/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,57 @@
+/*
+ *  This file implements a benchmark timer using the count/compare
+ *  CP0 registers.
+ *
+ *  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 <assert.h>
+
+#include <bsp.h>
+#include <rtems/btimer.h>
+
+bool benchmark_timer_find_average_overhead;
+uint32_t tstart;
+
+void benchmark_timer_initialize(void)
+{
+    __asm__ volatile ("mfc0 %0, $9\n" : "=r" (tstart));
+    /* tick time in picooseconds */
+}
+
+#define AVG_OVERHEAD      0  /* It typically takes N instructions */
+                             /*     to start/stop the timer. */
+#define LEAST_VALID       1  /* Don't trust a value lower than this */
+                             /* tx39 simulator can count instructions. :) */
+
+benchmark_timer_t benchmark_timer_read(void)
+{
+  uint32_t  total;
+  uint32_t  cnt;
+
+  __asm__ volatile ("mfc0 %0, $9\n" : "=r" (cnt));
+
+  total = cnt - tstart;
+  total = (total * 1000) / 396; /* convert to nanoseconds */
+
+
+  if ( benchmark_timer_find_average_overhead == true )
+    return total;          /* in one microsecond units */
+
+  if ( total < LEAST_VALID )
+    return 0;            /* below timer resolution */
+
+  return total - AVG_OVERHEAD;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/mips/jmr3904/btimer/btimer.c
===================================================================
--- bsps/mips/jmr3904/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/mips/jmr3904/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,67 @@
+/*
+ *  This file implements a benchmark timer using a TX39 timer.
+ *
+ *  NOTE: On the simulator, the count directly reflects instructions.
+ *
+ *  COPYRIGHT (c) 1989-2000.
+ *  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 <assert.h>
+
+#include <bsp.h>
+#include <rtems/btimer.h>
+
+bool benchmark_timer_find_average_overhead;
+
+void benchmark_timer_initialize(void)
+{
+  /*
+   *  Programming the compare register as the maximum value should let
+   *  it run long enough and accurate enough not to require an interrupt.
+   *  but if it ever does generate an interrupt, we will simply fault.
+   *
+   *  NOTE:  This is similar to the clock driver initialization
+   *         with the exception that the divider is disabled and
+   *         the compare register is set to the maximum value.
+   */
+
+  TX3904_TIMER_WRITE( TX3904_TIMER1_BASE, TX3904_TIMER_TCR,   0x20 );
+  TX3904_TIMER_WRITE( TX3904_TIMER1_BASE, TX3904_TIMER_CCDR, 0x3 );
+  TX3904_TIMER_WRITE( TX3904_TIMER1_BASE, TX3904_TIMER_TRR, 0x0 );
+  TX3904_TIMER_WRITE( TX3904_TIMER1_BASE, TX3904_TIMER_CPRA, 0xFFFFFFFF );
+  TX3904_TIMER_WRITE( TX3904_TIMER1_BASE, TX3904_TIMER_TISR, 0x00 );
+  TX3904_TIMER_WRITE( TX3904_TIMER1_BASE, TX3904_TIMER_ITMR, 0x0001 );
+  TX3904_TIMER_WRITE( TX3904_TIMER1_BASE, TX3904_TIMER_TCR,   0xe0 );
+}
+
+#define AVG_OVERHEAD      0  /* It typically takes N instructions */
+                             /*     to start/stop the timer. */
+#define LEAST_VALID       1  /* Don't trust a value lower than this */
+                             /* tx39 simulator can count instructions. :) */
+
+benchmark_timer_t benchmark_timer_read(void)
+{
+  uint32_t          total;
+
+  total = TX3904_TIMER_READ( TX3904_TIMER1_BASE, TX3904_TIMER_TRR );
+
+  if ( benchmark_timer_find_average_overhead == true )
+    return total;          /* in one microsecond units */
+
+  if ( total < LEAST_VALID )
+    return 0;            /* below timer resolution */
+
+  return total - AVG_OVERHEAD;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/nios2/nios2_iss/btimer/btimer.c
===================================================================
--- bsps/nios2/nios2_iss/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/nios2/nios2_iss/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,137 @@
+/*
+ * This file manages the benchmark timer used by the RTEMS Timing Test
+ * Suite.  Each measured time period is demarcated by calls to
+ * benchmark_timer_initialize() and benchmark_timer_read(). 
+ * benchmark_timer_read() usually returns the number of microseconds
+ * since benchmark_timer_initialize() exitted.
+ *
+ *  NOTE: It is important that the timer start/stop overhead be
+ *        determined when porting or modifying this code.
+ */
+
+/*
+ *  COPYRIGHT (c) 2005-2006 Kolja Waschk rtemsdev/ixo.de
+ *  Derived from no_cpu/no_bsp/timer/timer.c 1.9,
+ *  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.
+ */
+
+#define TIMER_WRAPS_AFTER_1MS 0
+
+#include <rtems.h>
+#include <rtems/btimer.h>
+#include <rtems/score/cpu.h>
+#include <bsp.h>
+
+volatile uint32_t Timer_interrupts;
+bool benchmark_timer_find_average_overhead;
+
+#define TIMER_REGS ((altera_avalon_timer_regs*)NIOS2_IO_BASE(TIMER_BASE))
+
+static rtems_isr timerisr(rtems_vector_number vector)
+{
+  TIMER_REGS->status = 0;
+  Timer_interrupts++;
+}
+
+void benchmark_timer_initialize( void )
+{
+  /* Disable timer interrupt, stop timer */
+
+  TIMER_REGS->control = ALTERA_AVALON_TIMER_CONTROL_STOP_MSK;
+
+  set_vector(timerisr, TIMER_VECTOR, 1);
+
+  /* Enable interrupt processing */
+
+  NIOS2_IENABLE(1 << TIMER_VECTOR);
+
+#if TIMER_WRAPS_AFTER_1MS
+  /* Writing to periodl/h resets the counter and eventually
+     stops it. If the timer hasn't been configured with fixed
+     period, set it to 1 ms now */
+
+  TIMER_REGS->period_hi = (TIMER_FREQ/1000)>>16;
+  TIMER_REGS->period_lo = (TIMER_FREQ/1000)&0xFFFF;
+#else
+  /* Writing to periodl/h resets the counter and eventually
+     stops it. Set max period */
+
+  TIMER_REGS->period_hi = 0xFFFF;
+  TIMER_REGS->period_lo = 0xFFFF;
+#endif
+
+  /* For timers that can be stopped, writing to periodl/h
+     also stopped the timer and we have to manually start it. */
+
+  TIMER_REGS->control = ALTERA_AVALON_TIMER_CONTROL_ITO_MSK |
+                        ALTERA_AVALON_TIMER_CONTROL_CONT_MSK |
+                        ALTERA_AVALON_TIMER_CONTROL_START_MSK;
+
+  /* This is the most safe place for resetting the overflow
+     counter - just _after_ we reset the timer. Depending
+     on the SOPC configuration, the counter may not be
+     stoppable and it doesn't make sense to assume that
+     there is any "safe" period before resetting. */
+
+  Timer_interrupts = 0;
+}
+
+/*
+ *  The following controls the behavior of benchmark_timer_read().
+ *
+ *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      2      /* It typically takes 2 microseconds */
+                                 /* to start/stop the timer. */
+
+#define LEAST_VALID AVG_OVERHEAD /* Don't trust a value lower than this */
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+  uint32_t timer_wraps;
+  uint32_t timer_snap;
+  uint32_t timer_ticks;
+  uint32_t total;
+
+  /* Hold timer */
+  TIMER_REGS->control = ALTERA_AVALON_TIMER_CONTROL_STOP_MSK;
+
+  /* Write to request snapshot of timer value */
+  TIMER_REGS->snap_lo = 0;
+  /* Get snapshot */
+  timer_snap = ((TIMER_REGS->snap_hi)<<16) | TIMER_REGS->snap_lo;
+  timer_wraps = Timer_interrupts;
+
+  /* Restart timer */
+  TIMER_REGS->control = ALTERA_AVALON_TIMER_CONTROL_START_MSK;
+
+#if TIMER_WRAPS_AFTER_1MS
+  timer_ticks = (TIMER_FREQ / 1000) - 1 - timer_snap;
+  total = timer_wraps * 1000;
+#else
+  timer_ticks = 0xFFFFFFFF - timer_snap;
+  total = timer_wraps * 0x80000000 / (TIMER_FREQ / 2000000L);
+#endif
+  total += timer_ticks / (TIMER_FREQ / 1000000L);
+
+  if(total < LEAST_VALID) return 0;
+
+  if(benchmark_timer_find_average_overhead != TRUE) total-= AVG_OVERHEAD;
+
+  return total;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/no_cpu/no_bsp/btimer/btimer.c
===================================================================
--- bsps/no_cpu/no_bsp/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/no_cpu/no_bsp/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,92 @@
+/*  timer.c
+ *
+ *  This file manages the benchmark timer used by the RTEMS Timing Test
+ *  Suite.  Each measured time period is demarcated by calls to
+ *  benchmark_timer_initialize() and benchmark_timer_read().  benchmark_timer_read() usually returns
+ *  the number of microseconds since benchmark_timer_initialize() exitted.
+ *
+ *  NOTE: It is important that the timer start/stop overhead be
+ *        determined when porting or modifying this code.
+ *
+ *  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>
+#include <rtems/btimer.h>
+#include <bsp.h>
+
+uint32_t         Timer_interrupts;
+bool benchmark_timer_find_average_overhead;
+
+void benchmark_timer_initialize( void )
+{
+
+  /*
+   *  Timer has never overflowed.  This may not be necessary on some
+   *  implemenations of timer but ....
+   */
+
+  Timer_interrupts = 0;
+
+  /*
+   *  Somehow start the timer
+   */
+}
+
+/*
+ *  The following controls the behavior of benchmark_timer_read().
+ *
+ *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      0  /* It typically takes X.X microseconds */
+                             /* (Y countdowns) to start/stop the timer. */
+                             /* This value is in microseconds. */
+#define LEAST_VALID       1  /* Don't trust a clicks value lower than this */
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+  uint32_t         clicks;
+  uint32_t         total;
+
+  /*
+   *  Read the timer and see how many clicks it has been since we started.
+   */
+
+  clicks = 0;   /* XXX: read some HW here */
+
+  /*
+   *  Total is calculated by taking into account the number of timer overflow
+   *  interrupts since the timer was initialized and clicks since the last
+   *  interrupts.
+   */
+
+  total = clicks * 0;
+
+  if ( benchmark_timer_find_average_overhead == true )
+    return total;          /* in XXX microsecond units */
+  else {
+    if ( total < LEAST_VALID )
+      return 0;            /* below timer resolution */
+  /*
+   *  Somehow convert total into microseconds
+   */
+      return (total - AVG_OVERHEAD);
+    }
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/no_cpu/no_bsp/btimer/timerisr.c
===================================================================
--- bsps/no_cpu/no_bsp/btimer/timerisr.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/no_cpu/no_bsp/btimer/timerisr.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,38 @@
+/**
+ *  @file
+ *
+ *  If required this ISR is used to bump a count of interval "overflow"
+ *  interrupts which have occurred since the timer was started.  The
+ *  number of overflows is taken into account in the benchmark_timer_read()
+ *  routine if necessary.
+ *
+ *  To reduce overhead this is best to be the "rawest" hardware interupt
+ *  handler you can write.  This should be the only interrupt which can
+ *  occur during the measured time period.
+ *
+ *  @note This file is USUALLY in assembly and is LEAN AND MEAN.
+ *        Any code in this isr is pure overhead which can perturb
+ *        the accuracy of the Timing Test Suite.
+ */
+
+/*
+ *  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>
+#include <rtems/btimer.h>
+
+extern uint32_t         _Timer_interrupts;
+
+void timerisr( void )
+{
+  /*
+   *  _Timer_interrupts += TIMER_BETWEEN_OVERFLOWS  (usually in microseconds)
+   *  return from interrupt
+   */
+}
Index: bsps/or1k/generic_or1k/btimer/btimer.c
===================================================================
--- bsps/or1k/generic_or1k/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/or1k/generic_or1k/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,64 @@
+/**
+ * @file
+ *
+ * @ingroup generic_or1k
+ *
+ * @brief Benchmark timer support.
+ */
+
+/*
+ * Copyright (c) 2014-2015 by Hesham ALMatary
+ *
+ *  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/btimer.h>
+#include <bsp/generic_or1k.h>
+#include <rtems/score/or1k-utility.h>
+
+#define OR1K_NANOSECONDS_PER_CLK_CYCLE 10
+
+static bool benchmark_timer_find_average_overhead = false;
+static uint64_t benchmark_timer_base;
+
+void benchmark_timer_initialize(void)
+{
+  benchmark_timer_base = _OR1K_mfspr(CPU_OR1K_SPR_TTCR);
+}
+
+#define AVG_OVERHEAD  0
+#define LEAST_VALID   1
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+  uint64_t         clicks;
+  uint64_t         total;
+  uint64_t         delta;
+  /*
+   *  Read the timer and see how many clicks (clock cycles)
+   *  has passed since timer initialization.
+   */
+  clicks = _OR1K_mfspr(CPU_OR1K_SPR_TTCR);
+
+  delta = clicks - benchmark_timer_base;
+
+  /* total in nanoseconds */
+  total = OR1K_NANOSECONDS_PER_CLK_CYCLE * (delta);
+
+  if ( benchmark_timer_find_average_overhead == true )
+    return total;          /* in nanoseconds microsecond units */
+  else {
+    if ( total < LEAST_VALID )
+      return 0;            /* below timer resolution */
+
+      return (total - AVG_OVERHEAD);
+  }
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/powerpc/qoriq/btimer/btimer.c
===================================================================
--- bsps/powerpc/qoriq/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/powerpc/qoriq/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,42 @@
+/**
+ * @file
+ *
+ * @ingroup QorIQ
+ *
+ * @brief QorIQ benchmark timer.
+ */
+
+/*
+ * Copyright (c) 2011 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/btimer.h>
+
+#include <libcpu/powerpc-utility.h>
+
+static benchmark_timer_t benchmark_timer_base;
+
+void benchmark_timer_initialize(void)
+{
+  benchmark_timer_base = ppc_alternate_time_base();
+}
+
+benchmark_timer_t benchmark_timer_read(void)
+{
+  return ppc_alternate_time_base() - benchmark_timer_base;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_average_overhead)
+{
+  /* VOID */
+}
Index: bsps/powerpc/tqm8xx/btimer/btimer.c
===================================================================
--- bsps/powerpc/tqm8xx/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/powerpc/tqm8xx/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,101 @@
+/*===============================================================*\
+| Project: RTEMS TQM8xx BSP                                       |
++-----------------------------------------------------------------+
+| This file has been adapted to MPC8xx by                         |
+|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
+|                    Copyright (c) 2008                           |
+|                    Embedded Brains GmbH                         |
+|                    Obere Lagerstr. 30                           |
+|                    D-82178 Puchheim                             |
+|                    Germany                                      |
+|                    rtems@embedded-brains.de                     |
+|                                                                 |
+| See the other copyright notice below for the original parts.    |
++-----------------------------------------------------------------+
+| 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.                           |
+|                                                                 |
++-----------------------------------------------------------------+
+| this file contains the console driver                           |
+\*===============================================================*/
+/*
+ * benchmark_timer_initialize()
+ *
+ * Use TIMER 1 and TIMER 2 for Timing Test Suite
+ *
+ * this is derived from "timer.c" available in the m68k/gen68360 BSP
+ * adapted by Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>
+ */
+
+/*
+ *
+ *  Input parameters:  NONE
+ *
+ *  Output parameters:  NONE
+ *
+ *  NOTE: It is important that the timer start/stop overhead be
+ *        determined when porting or modifying this code.
+ *
+ *  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>
+#include <bsp.h>
+#include <rtems/btimer.h>
+#include <mpc8xx.h>
+
+bool benchmark_timer_find_average_overhead;
+
+void
+benchmark_timer_initialize (void)
+{
+	/*
+	 * Reset timers 1 and 2
+	 */
+	m8xx.tgcr &= ~0x00FF;
+	m8xx.tcn1 = 0;
+	m8xx.tcn2 = 0;
+	m8xx.ter1 = 0xFFFF;
+	m8xx.ter2 = 0xFFFF;
+
+	/*
+	 * Cascade timers 1 and 2
+	 */
+	m8xx.tgcr |= M8xx_TGCR_CAS2;
+
+	/*
+	 * Configure timers 1 and 2 to a single 32-bit, BUS_clock timer.
+	 */
+	m8xx.tmr2 = (0 << 8) | 0x2;
+	m8xx.tmr1 = 0;
+
+	/*
+	 * Start the timers
+	 */
+	m8xx.tgcr |=  0x0011;
+}
+
+/*
+ * Return timer value in microsecond units
+ */
+benchmark_timer_t benchmark_timer_read(void)
+{
+  uint32_t retval;
+  retval = *(uint32_t*)&m8xx.tcn1;
+  retval = retval * 1000000LL / BSP_bus_frequency;
+  return retval;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/riscv/riscv_generic/btimer/btimer.c
===================================================================
--- bsps/riscv/riscv_generic/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/riscv/riscv_generic/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2015 University of York.
+ * Hesham Almatary <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 <rtems/btimer.h>
+#include <rtems/score/riscv-utility.h>
+
+extern char bsp_start_vector_table_begin[];
+
+bool benchmark_timer_find_average_overhead;
+
+static void benchmark_timer1_interrupt_handler(void)
+{
+}
+
+/* Start eCore tiemr 1 usef for profiling and timing analysis */
+void benchmark_timer_initialize( void )
+{
+  /* Install interrupt handler for timer 1 */
+}
+
+/*
+ *  The following controls the behavior of benchmark_timer_read().
+ *
+ *  AVG_OVEREHAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      0  /* It typically takes X.X microseconds */
+/* (Y countdowns) to start/stop the timer. */
+/* This value is in microseconds. */
+#define LEAST_VALID       1  /* Don't trust a clicks value lower than this */
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/sh/gensh1/btimer/btimer.c
===================================================================
--- bsps/sh/gensh1/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/sh/gensh1/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,195 @@
+/**
+ * @file
+ * @brief Timer for 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 <rtems/btimer.h>
+
+#include <rtems/score/sh_io.h>
+#include <rtems/score/ispsh7032.h>
+#include <rtems/score/iosh7032.h>
+
+extern uint32_t bsp_clicks_per_second;
+
+#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 ITU1_STARTMASK 	0xfd
+#define ITU1_SYNCMASK 	0xfd
+#define ITU1_MODEMASK 	0xfd
+#define ITU1_TCRMASK 	(0x00 | I_CLK_PHI)
+#define ITU1_TIORMASK 	0x88
+#define ITU1_STAT_MASK 	0xf8
+#define ITU1_TIERMASK 	0xfc
+#define IPRC_ITU1_MASK	0xfff0
+
+#ifndef ITU1_PRIO
+#define ITU1_PRIO 15
+#endif
+
+#define ITU1_VECTOR OVI1_ISP_V
+
+extern rtems_isr timerisr(void);
+
+static uint32_t   Timer_interrupts;
+
+bool benchmark_timer_find_average_overhead;
+
+static uint32_t   Timer_HZ ;
+
+void benchmark_timer_initialize( void )
+{
+  uint8_t                temp8;
+  uint16_t               temp16;
+  rtems_interrupt_level  level;
+  rtems_isr             *ignored;
+
+  Timer_HZ = bsp_clicks_per_second / CLOCK_SCALE ;
+
+  /*
+   *  Timer has never overflowed.  This may not be necessary on some
+   *  implemenations of timer but ....
+   */
+
+  Timer_interrupts /* .i */ = 0;
+  rtems_interrupt_disable( level );
+
+  /*
+   *  Somehow start the timer
+   */
+  /* stop Timer 1  */
+  temp8 = read8(ITU_TSTR) & ITU1_STARTMASK;
+  write8( temp8, ITU_TSTR );
+
+  /* initialize counter 1 */
+  write16( 0, ITU_TCNT1 );
+
+  /* Timer 1 is independent of other timers */
+  temp8 = read8(ITU_TSNC) & ITU1_SYNCMASK;
+  write8( temp8, ITU_TSNC );
+
+  /* Timer 1, normal mode */
+  temp8 = read8(ITU_TMDR) & ITU1_MODEMASK;
+  write8( temp8, ITU_TMDR );
+
+  /* Use a Phi/X counter */
+  write8( ITU1_TCRMASK, ITU_TCR1 );
+
+  /* gra and grb are not used */
+  write8( ITU1_TIORMASK, ITU_TIOR1 );
+
+  /* reset all status flags */
+  temp8 = read8(ITU_TSR1) & ITU1_STAT_MASK;
+  write8( temp8, ITU_TSR1 );
+
+  /* enable overflow interrupt */
+  write8( ITU1_TIERMASK, ITU_TIER1 );
+
+  /* set interrupt priority */
+  temp16 = read16(INTC_IPRC) & IPRC_ITU1_MASK;
+  temp16 |= ITU1_PRIO;
+  write16( temp16, INTC_IPRC );
+
+  /* initialize ISR */
+  _CPU_ISR_install_raw_handler( ITU1_VECTOR, timerisr, &ignored );
+  rtems_interrupt_enable( level );
+
+  /* start timer 1 */
+  temp8 = read8(ITU_TSTR) | ~ITU1_STARTMASK;
+  write8( temp8, ITU_TSTR );
+}
+
+/*
+ *  The following controls the behavior of benchmark_timer_read().
+ *
+ *  AVG_OVERHEAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      1  /* It typically takes X.X microseconds */
+                             /* (Y countdowns) to start/stop the timer. */
+                             /* This value is in microseconds. */
+#define LEAST_VALID       0 /* 20 */ /* Don't trust a clicks value lower than this */
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+  uint32_t   cclicks;
+  uint32_t   total ;
+  /*
+   *  Read the timer and see how many clicks it has been since we started.
+   */
+
+
+  cclicks = read16( ITU_TCNT1 );    /* XXX: read some HW here */
+
+  /*
+   *  Total is calculated by taking into account the number of timer overflow
+   *  interrupts since the timer was initialized and clicks since the last
+   *  interrupts.
+   */
+
+  total = cclicks + Timer_interrupts * 65536;
+
+  if ( benchmark_timer_find_average_overhead )
+    return total / CLOCK_SCALE;          /* in XXX microsecond units */
+  else
+  {
+    if ( total < LEAST_VALID )
+      return 0;            /* below timer resolution */
+  /*
+   *  Somehow convert total into microseconds
+   */
+    return (total / CLOCK_SCALE - AVG_OVERHEAD);
+  }
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
+
+/* Timer 1 is used */
+
+#pragma interrupt
+void timerisr( void )
+{
+  uint8_t   temp8;
+
+  /* reset the flags of the status register */
+  temp8 = read8(ITU_TSR1) & ITU1_STAT_MASK;
+  write8( temp8, ITU_TSR1 );
+
+  Timer_interrupts += 1;
+}
Index: bsps/sh/gensh2/btimer/btimer.c
===================================================================
--- bsps/sh/gensh2/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/sh/gensh2/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,191 @@
+/**
+ *  @file
+ *  @brief Timer for 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).
+ *
+ *  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/btimer.h>
+
+#include <rtems/score/sh_io.h>
+#include <rtems/score/iosh7045.h>
+
+extern uint32_t bsp_clicks_per_second;
+
+/*
+ *  We use a Phi/4 timer
+ */
+#define SCALE (Timer_MHZ/4)
+
+#define MTU1_STARTMASK 	0xfd
+#define MTU1_SYNCMASK 	0xfd
+#define MTU1_MODEMASK 	0xc0
+#define MTU1_TCRMASK 	0x01
+#define MTU1_TIORMASK 	0x88
+#define MTU1_STAT_MASK 	0xf8
+#define MTU1_TIERMASK 	0xfc
+#define IPRC_MTU1_MASK	0xfff0
+
+#ifndef MTU1_PRIO
+#define MTU1_PRIO 15
+#endif
+
+#define MTU1_VECTOR 86
+
+extern rtems_isr timerisr(void);
+
+static uint32_t   Timer_interrupts;
+
+bool benchmark_timer_find_average_overhead;
+
+static uint32_t   Timer_MHZ ;
+
+void benchmark_timer_initialize( void )
+{
+  uint8_t                temp8;
+  uint16_t               temp16;
+  rtems_interrupt_level  level;
+  rtems_isr	        *ignored;
+
+  Timer_MHZ = bsp_clicks_per_second / 1000000 ;
+
+  /*
+   *  Timer has never overflowed.  This may not be necessary on some
+   *  implemenations of timer but ....
+   */
+
+  Timer_interrupts /* .i */ = 0;
+  rtems_interrupt_disable( level );
+
+  /*
+   *  Somehow start the timer
+   */
+  /* stop Timer 1  */
+  temp8 = read8(MTU_TSTR) & MTU1_STARTMASK;
+  write8( temp8, MTU_TSTR );
+
+  /* initialize counter 1 */
+  write16( 0, MTU_TCNT1);
+
+  /* Timer 1 is independent of other timers */
+  temp8 = read8(MTU_TSYR) & MTU1_SYNCMASK;
+  write8( temp8, MTU_TSYR );
+
+  /* Timer 1, normal mode */
+  temp8 = read8(MTU_TMDR1) & MTU1_MODEMASK;
+  write8( temp8, MTU_TMDR1 );
+
+  /* x0000000
+   * |||||+++--- Internal Clock
+   * |||++------ Count on rising edge
+   * |++-------- disable TCNT clear
+   * +---------- don`t care
+   */
+  write8( MTU1_TCRMASK, MTU_TCR1 );
+
+  /* gra and grb are not used */
+  write8( MTU1_TIORMASK, MTU_TIOR1 );
+
+  /* reset all status flags */
+  temp8 = read8(MTU_TSR1) & MTU1_STAT_MASK;
+  write8( temp8, MTU_TSR1 );
+
+  /* enable overflow interrupt */
+  write8( MTU1_TIERMASK, MTU_TIER1 );
+
+  /* set interrupt priority */
+  temp16 = read16(INTC_IPRC) & IPRC_MTU1_MASK;
+  temp16 |= MTU1_PRIO;
+  write16( temp16, INTC_IPRC);
+
+  /* initialize ISR */
+  _CPU_ISR_install_raw_handler( MTU1_VECTOR, timerisr, &ignored );
+  rtems_interrupt_enable( level );
+
+  /* start timer 1 */
+  temp8 = read8(MTU_TSTR) | ~MTU1_STARTMASK;
+  write8( temp8, MTU_TSTR );
+}
+
+/*
+ *  The following controls the behavior of benchmark_timer_read().
+ *
+ *  AVG_OVERHEAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      1  /* It typically takes X.X microseconds */
+                             /* (Y countdowns) to start/stop the timer. */
+                             /* This value is in microseconds. */
+#define LEAST_VALID       0 /* 20 */ /* Don't trust a clicks value lower than this */
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+  uint32_t   clicks;
+  uint32_t   total ;
+  /*
+   *  Read the timer and see how many clicks it has been since we started.
+   */
+
+
+  clicks = read16( MTU_TCNT1 );   /* XXX: read some HW here */
+
+  /*
+   *  Total is calculated by taking into account the number of timer overflow
+   *  interrupts since the timer was initialized and clicks since the last
+   *  interrupts.
+   */
+
+  total = clicks + Timer_interrupts * 65536;
+
+  if ( benchmark_timer_find_average_overhead )
+    return total / SCALE;          /* in XXX microsecond units */
+  else
+  {
+    if ( total < LEAST_VALID )
+      return 0;            /* below timer resolution */
+  /*
+   *  Somehow convert total into microseconds
+   */
+    return (total / SCALE - AVG_OVERHEAD) ;
+  }
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
+
+/* Timer 1 is used */
+
+#pragma interrupt
+void timerisr( void )
+{
+  uint8_t   temp8;
+
+  /* reset the flags of the status register */
+  temp8 = read8(MTU_TSR1) & MTU1_STAT_MASK;
+  write8( temp8, MTU_TSR1 );
+
+  Timer_interrupts += 1;
+}
Index: bsps/sh/gensh4/btimer/btimer.c
===================================================================
--- bsps/sh/gensh4/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/sh/gensh4/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,269 @@
+/**
+ *  @file
+ *  @brief Timer driver for the Hitachi SH 7750
+ */
+
+/*
+ *  Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ *  Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ *  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 <rtems/btimer.h>
+
+#include <rtems/score/sh_io.h>
+#include <rtems/score/iosh7750.h>
+
+extern uint32_t bsp_clicks_per_second;
+
+#ifndef TIMER_PRIO
+#define TIMER_PRIO 15
+#endif
+
+/* Timer prescaler division ratio */
+#define TIMER_PRESCALER 4
+#define TCR1_TPSC       SH7750_TCR_TPSC_DIV4
+
+#define TIMER_VECTOR SH7750_EVT_TO_NUM(SH7750_EVT_TUNI1)
+
+extern rtems_isr timerisr(void);
+
+static uint32_t   Timer_interrupts;
+
+/* Counter should be divided to this value to obtain time in microseconds */
+static uint32_t   microseconds_divider;
+
+/* Interrupt period in microseconds */
+static uint32_t   microseconds_per_int;
+
+bool benchmark_timer_find_average_overhead;
+
+/* benchmark_timer_initialize --
+ *     Initialize Timer 1 to operate as a RTEMS benchmark timer:
+ *        - determine timer clock frequency
+ *        - install timer interrupt handler
+ *        - configure the Timer 1 hardware
+ *        - start the timer
+ *
+ * PARAMETERS:
+ *     none
+ *
+ * RETURNS:
+ *     none
+ */
+void
+benchmark_timer_initialize(void)
+{
+    uint8_t               temp8;
+    uint16_t              temp16;
+    rtems_interrupt_level level;
+    rtems_isr            *ignored;
+    int                   cpudiv = 1;
+    int                   tidiv = 1;
+
+    Timer_interrupts  = 0;
+    rtems_interrupt_disable(level);
+
+    /* 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 * TIMER_PRESCALER;
+            break;
+
+        case SH7750_FRQCR_PFCDIV3:
+            tidiv = 3 * TIMER_PRESCALER;
+            break;
+
+        case SH7750_FRQCR_PFCDIV4:
+            tidiv = 4 * TIMER_PRESCALER;
+            break;
+
+        case SH7750_FRQCR_PFCDIV6:
+            tidiv = 6 * TIMER_PRESCALER;
+            break;
+
+        case SH7750_FRQCR_PFCDIV8:
+            tidiv = 8 * TIMER_PRESCALER;
+            break;
+
+        default:
+            rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);
+    }
+
+    microseconds_divider = bsp_clicks_per_second * cpudiv / (tidiv * 1000000);
+    microseconds_per_int = 0xFFFFFFFF / microseconds_divider;
+
+    /*
+     *  Hardware specific initialization
+     */
+
+    /* Stop the Timer 0 */
+    temp8 = read8(SH7750_TSTR);
+    temp8 &= ~SH7750_TSTR_STR1;
+    write8(temp8, SH7750_TSTR);
+
+    /* Establish interrupt handler */
+    _CPU_ISR_install_raw_handler( TIMER_VECTOR, timerisr, &ignored );
+
+    /* Reset timer constant and counter */
+    write32(0xFFFFFFFF, SH7750_TCOR1);
+    write32(0xFFFFFFFF, SH7750_TCNT1);
+
+    /* Select timer mode */
+    write16(
+        SH7750_TCR_UNIE |        /* Enable Underflow Interrupt */
+        SH7750_TCR_CKEG_RAISE |  /* Count on rising edge */
+        TCR1_TPSC,               /* Timer prescaler ratio */
+        SH7750_TCR1);
+
+    /* Set timer interrupt priority */
+    temp16 = read16(SH7750_IPRA);
+    temp16 = (temp16 & ~SH7750_IPRA_TMU1) | (TIMER_PRIO << SH7750_IPRA_TMU1_S);
+    write16(temp16, SH7750_IPRA);
+
+
+    rtems_interrupt_enable(level);
+
+    /* Start the Timer 1 */
+    temp8 = read8(SH7750_TSTR);
+    temp8 |= SH7750_TSTR_STR1;
+    write8(temp8, SH7750_TSTR);
+
+}
+
+/*
+ *  The following controls the behavior of benchmark_timer_read().
+ *
+ *  AVG_OVERHEAD is the overhead for starting and stopping the timer.  It
+ *  is usually deducted from the number returned.
+ *
+ *  LEAST_VALID is the lowest number this routine should trust.  Numbers
+ *  below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD      0  /* It typically takes X.X microseconds */
+                             /* (Y countdowns) to start/stop the timer. */
+                             /* This value is in microseconds. */
+#define LEAST_VALID       0 /* 20 */ /* Don't trust a clicks value lower than this */
+
+/* benchmark_timer_read --
+ *     Read timer value in microsecond units since timer start.
+ *
+ * PARAMETERS:
+ *     none
+ *
+ * RETURNS:
+ *     number of microseconds since timer has been started
+ */
+benchmark_timer_t
+benchmark_timer_read(void)
+{
+    uint32_t              clicks;
+    uint32_t              ints;
+    uint32_t              total;
+    rtems_interrupt_level level;
+    uint32_t              tcr;
+
+
+    rtems_interrupt_disable(level);
+
+    clicks = 0xFFFFFFFF - read32(SH7750_TCNT1);
+    tcr = read32(SH7750_TCR1);
+    ints = Timer_interrupts;
+
+    rtems_interrupt_enable(level);
+
+    /* Handle the case when timer overflowed but interrupt was not processed */
+    if ((clicks > 0xFF000000) && ((tcr & SH7750_TCR_UNF) != 0))
+    {
+        ints++;
+    }
+
+    total = microseconds_per_int * ints + (clicks / microseconds_divider);
+
+    if ( benchmark_timer_find_average_overhead )
+        return total;          /* in microsecond units */
+    else
+    {
+        if ( total < LEAST_VALID )
+            return 0;            /* below timer resolution */
+        /*
+         *  Somehow convert total into microseconds
+         */
+        return (total - AVG_OVERHEAD) ;
+    }
+}
+
+/* benchmark_timer_disable_subtracting_average_overhead --
+ *     This routine is invoked by the "Check Timer" (tmck) test in the
+ *     RTEMS Timing Test Suite. It makes the benchmark_timer_read routine not
+ *     subtract the overhead required to initialize and read the benchmark
+ *     timer.
+ *
+ * PARAMETERS:
+ *     find_flag - boolean flag, true if overhead must not be subtracted.
+ *
+ * RETURNS:
+ *     none
+ */
+void
+benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+    benchmark_timer_find_average_overhead = find_flag;
+}
+
+/* timerisr --
+ *     Timer interrupt handler routine. This function invoked on timer
+ *     underflow event; once per 2^32 clocks. It should reset the timer
+ *     event and increment timer interrupts counter.
+ */
+void
+timerisr(void)
+{
+  uint8_t   temp8;
+
+  /* reset the flags of the status register */
+  temp8 = read8(SH7750_TCR1) & ~SH7750_TCR_UNF;
+  write8(temp8, SH7750_TCR1);
+
+  Timer_interrupts += 1;
+}
Index: bsps/sparc/erc32/btimer/btimer.c
===================================================================
--- bsps/sparc/erc32/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/sparc/erc32/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,81 @@
+/*  timer.c
+ *
+ *  This file implements a benchmark timer using the General Purpose Timer on
+ *  the MEC.
+ *
+ *  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.
+ *
+ *  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 <rtems/btimer.h>
+
+bool benchmark_timer_find_average_overhead;
+
+bool benchmark_timer_is_initialized = false;
+
+void benchmark_timer_initialize(void)
+{
+  /*
+   *  Timer runs long and accurate enough not to require an interrupt.
+   */
+
+  if ( benchmark_timer_is_initialized == false ) {
+
+    /* approximately 1 us per countdown */
+    ERC32_MEC.General_Purpose_Timer_Scalar  = CLOCK_SPEED - 1;
+    ERC32_MEC.General_Purpose_Timer_Counter = 0xffffffff;
+
+  } else {
+    benchmark_timer_is_initialized = true;
+  }
+
+  ERC32_MEC_Set_General_Purpose_Timer_Control(
+    ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING |
+      ERC32_MEC_TIMER_COUNTER_LOAD_COUNTER
+  );
+
+  ERC32_MEC_Set_General_Purpose_Timer_Control(
+    ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING
+  );
+
+}
+
+#define AVG_OVERHEAD     12  /* It typically takes 3.0 microseconds */
+                             /*     to start/stop the timer. */
+#define LEAST_VALID      13  /* Don't trust a value lower than this */
+
+benchmark_timer_t benchmark_timer_read(void)
+{
+  uint32_t          total;
+
+  total = ERC32_MEC.General_Purpose_Timer_Counter;
+
+  total = 0xffffffff - total;
+
+  if ( benchmark_timer_find_average_overhead == true )
+    return total;          /* in one microsecond units */
+
+  if ( total < LEAST_VALID )
+    return 0;            /* below timer resolution */
+
+  return total - AVG_OVERHEAD;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/sparc/leon2/btimer/btimer.c
===================================================================
--- bsps/sparc/leon2/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/sparc/leon2/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,83 @@
+/**
+ * @file
+ * @ingroup sparc_leon2
+ * @brief Implement a benchmark timer using timer 2
+ */
+
+/*  timer.c
+ *
+ *  This file implements a benchmark timer using timer 2.
+ *
+ *  COPYRIGHT (c) 1989-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.
+ *
+ *  Ported to LEON implementation of the SPARC by On-Line Applications
+ *  Research Corporation (OAR) under contract to the European Space
+ *  Agency (ESA).
+ *
+ *  LEON modifications of respective RTEMS file: COPYRIGHT (c) 1995.
+ *  European Space Agency.
+ */
+
+
+#include <bsp.h>
+#include <rtems/btimer.h>
+
+bool benchmark_timer_find_average_overhead;
+
+bool benchmark_timer_is_initialized = false;
+
+void benchmark_timer_initialize(void)
+{
+  /*
+   *  Timer runs long and accurate enough not to require an interrupt.
+   */
+
+  if ( benchmark_timer_is_initialized == false ) {
+
+    /* approximately 1 us per countdown */
+    LEON_REG.Timer_Counter_2 = 0xffffff;
+    LEON_REG.Timer_Reload_2 = 0xffffff;
+
+  } else {
+    benchmark_timer_is_initialized = true;
+  }
+
+  LEON_REG.Timer_Control_2 = (
+    LEON_REG_TIMER_COUNTER_ENABLE_COUNTING |
+      LEON_REG_TIMER_COUNTER_LOAD_COUNTER
+  );
+
+}
+
+#define AVG_OVERHEAD      3  /* It typically takes 3.0 microseconds */
+                             /*     to start/stop the timer. */
+#define LEAST_VALID       2  /* Don't trust a value lower than this */
+
+benchmark_timer_t benchmark_timer_read(void)
+{
+  uint32_t total;
+
+  total = LEON_REG.Timer_Counter_2;
+
+  total = 0xffffff - total;
+
+  if ( benchmark_timer_find_average_overhead == true )
+    return total;          /* in one microsecond units */
+
+  if ( total < LEAST_VALID )
+    return 0;            /* below timer resolution */
+
+  return total - AVG_OVERHEAD;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/sparc/leon3/btimer/btimer.c
===================================================================
--- bsps/sparc/leon3/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/sparc/leon3/btimer/btimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,85 @@
+/*  timer.c
+ *
+ *  This file implements a benchmark timer using timer 2.
+ *
+ *  COPYRIGHT (c) 1989-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.
+ *
+ *  Ported to LEON implementation of the SPARC by On-Line Applications
+ *  Research Corporation (OAR) under contract to the European Space
+ *  Agency (ESA).
+ *
+ *  LEON modifications of respective RTEMS file: COPYRIGHT (c) 1995.
+ *  European Space Agency.
+ */
+
+
+#include <bsp.h>
+#include <rtems/btimer.h>
+
+#if defined(RTEMS_MULTIPROCESSING)
+  #define LEON3_TIMER_INDEX \
+      ((rtems_configuration_get_user_multiprocessing_table()) ? \
+        (rtems_configuration_get_user_multiprocessing_table()->node) - 1 : 1)
+#else
+  #define LEON3_TIMER_INDEX 0
+#endif
+
+bool benchmark_timer_find_average_overhead;
+
+bool benchmark_timer_is_initialized = false;
+
+extern volatile struct gptimer_regs *LEON3_Timer_Regs;
+
+void benchmark_timer_initialize(void)
+{
+  /*
+   *  Timer runs long and accurate enough not to require an interrupt.
+   */
+  if (LEON3_Timer_Regs) {
+    if ( benchmark_timer_is_initialized == false ) {
+      /* approximately 1 us per countdown */
+      LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].reload = 0xffffff;
+      LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].value = 0xffffff;
+    } else {
+      benchmark_timer_is_initialized = true;
+    }
+    LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].ctrl =
+      GPTIMER_TIMER_CTRL_EN | GPTIMER_TIMER_CTRL_LD;
+  }
+}
+
+#define AVG_OVERHEAD      3  /* It typically takes 3.0 microseconds */
+                             /*     to start/stop the timer. */
+#define LEAST_VALID       2  /* Don't trust a value lower than this */
+
+benchmark_timer_t benchmark_timer_read(void)
+{
+  uint32_t total;
+
+  if (LEON3_Timer_Regs) {
+    total = LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].value;
+
+    total = 0xffffff - total;
+
+    if ( benchmark_timer_find_average_overhead == true )
+      return total;          /* in one microsecond units */
+
+    if ( total < LEAST_VALID )
+      return 0;            /* below timer resolution */
+
+    return total - AVG_OVERHEAD;
+  }
+  return 0;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+  bool find_flag
+)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/sparc/leon3/btimer/watchdog.c
===================================================================
--- bsps/sparc/leon3/btimer/watchdog.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/sparc/leon3/btimer/watchdog.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,90 @@
+/*  GPTIMER Watchdog timer routines. On some systems the first GPTIMER
+ *  core's last Timer instance underflow signal is connected to system
+ *  reset.
+ *
+ *  COPYRIGHT (c) 2012.
+ *  Cobham Gaisler AB.
+ *
+ *  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/watchdog.h>
+#include <grlib.h>
+
+extern volatile struct gptimer_regs *LEON3_Timer_Regs;
+
+struct gptimer_watchdog_priv {
+  struct gptimer_regs *regs;
+  struct gptimer_timer_regs *timer;
+  int timerno;
+};
+
+struct gptimer_watchdog_priv bsp_watchdogs[1];
+int bsp_watchdog_count = 0;
+
+int bsp_watchdog_init(void)
+{
+  int timercnt;
+
+  if (!LEON3_Timer_Regs)
+    return 0;
+
+  /* Get Watchdogs in system, this is implemented for one GPTIMER core
+   * only.
+   *
+   * First watchdog is a special case, we can get the first timer core by
+   * looking at LEON3_Timer_Regs, the watchdog within a timer core is
+   * always the last timer. Unfortunately we can not know it the watchdog
+   * functionality is available or not, we assume that it is if we
+   * reached this function.
+   */
+  bsp_watchdogs[0].regs = (struct gptimer_regs *)LEON3_Timer_Regs;
+
+  /* Find Timer that has watchdog functionality */
+  timercnt = bsp_watchdogs[0].regs->cfg & 0x7;
+  if (timercnt < 2) /* First timer system clock timer */
+    return 0;
+
+  bsp_watchdogs[0].timerno = timercnt - 1;
+  bsp_watchdogs[0].timer = &bsp_watchdogs[0].regs->timer[bsp_watchdogs[0].timerno];
+
+  bsp_watchdog_count = 1;
+  return bsp_watchdog_count;
+}
+
+void bsp_watchdog_reload(int watchdog, unsigned int reload_value)
+{
+  if (bsp_watchdog_count == 0)
+    bsp_watchdog_init();
+
+  if (bsp_watchdog_count <= watchdog)
+    return;
+
+  /* Kick watchdog, and clear interrupt pending bit */
+  bsp_watchdogs[watchdog].timer->reload = reload_value;
+  bsp_watchdogs[watchdog].timer->ctrl =
+    (GPTIMER_TIMER_CTRL_LD | GPTIMER_TIMER_CTRL_EN) |
+    (bsp_watchdogs[watchdog].timer->ctrl & ~(1<<4));
+}
+
+void bsp_watchdog_stop(int watchdog)
+{
+  if (bsp_watchdog_count == 0)
+    bsp_watchdog_init();
+
+  if (bsp_watchdog_count <= watchdog)
+    return;
+
+  /* Stop watchdog timer */
+  bsp_watchdogs[watchdog].timer->ctrl = 0;
+}
+
+/* Use watchdog timer to reset system */
+void bsp_watchdog_system_reset(void)
+{
+  sparc_disable_interrupts();
+  bsp_watchdog_reload(0, 1);
+}
Index: bsps/sparc/shared/btimer/gptimer.c
===================================================================
--- bsps/sparc/shared/btimer/gptimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/sparc/shared/btimer/gptimer.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,544 @@
+/*  This file contains the driver for the GRLIB GPTIMER timers port. The driver
+ *  is implemented by using the tlib.c simple timer layer and the Driver
+ *  Manager.
+ *
+ *  The Driver can be configured using driver resources:
+ *
+ *  - timerStart  Timer Index if first Timer, this parameters is typically used
+ *                in AMP systems for resource allocation. The Timers before
+ *                timerStart will not be accessed.
+ *  - timerCnt    Number of timers that the driver will use, this parameters is
+ *                typically used in AMP systems for resource allocation between
+ *                OS instances.
+ *  - prescaler   Base prescaler, normally set by bootloader but can be
+ *                overridden. The default scaler reload value set by bootloader
+ *                is so that Timers operate in 1MHz. Setting the prescaler to a
+ *                lower value increase the accuracy of the timers but shortens
+ *                the time until underflow happens.
+ *  - clockTimer  Used to select a particular timer to be the system clock
+ *                timer. This is useful when multiple GPTIMERs cores are
+ *                available, or in AMP systems. By default the TLIB selects the
+ *                first timer registered as system clock timer.
+ *
+ *  The BSP define APBUART_INFO_AVAIL in order to add the info routine
+ *  used for debugging.
+ *
+ *  COPYRIGHT (c) 2010.
+ *  Cobham Gaisler AB.
+ *
+ *  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 <stdlib.h>
+#include <string.h>
+#include <drvmgr/drvmgr.h>
+#include <drvmgr/ambapp_bus.h>
+#include <grlib.h>
+#include <bsp/gptimer.h>
+#include <bsp/tlib.h>
+
+#if defined(LEON3)
+#include <leon.h>
+#endif
+
+#ifdef GPTIMER_INFO_AVAIL
+#include <stdio.h>
+#endif
+
+#ifdef RTEMS_SMP
+#include <rtems/score/processormask.h>
+#include <rtems/score/smpimpl.h>
+#endif
+
+/* GPTIMER Core Configuration Register (READ-ONLY) */
+#define GPTIMER_CFG_TIMERS_BIT	0
+#define GPTIMER_CFG_IRQ_BIT	3
+#define GPTIMER_CFG_SI_BIT	8
+#define GPTIMER_CFG_DF_BIT	9
+
+#define GPTIMER_CFG_TIMERS	(0x7<<GPTIMER_CFG_TIMERS_BIT)
+#define GPTIMER_CFG_IRQ		(0x1f<<GPTIMER_CFG_IRQ_BIT)
+#define GPTIMER_CFG_SI		(1<<GPTIMER_CFG_SI_BIT)
+#define GPTIMER_CFG_DF		(1<<GPTIMER_CFG_DF_BIT)
+
+/* GPTIMER Timer Control Register */
+#define GPTIMER_CTRL_EN_BIT	0
+#define GPTIMER_CTRL_RS_BIT	1
+#define GPTIMER_CTRL_LD_BIT	2
+#define GPTIMER_CTRL_IE_BIT	3
+#define GPTIMER_CTRL_IP_BIT	4
+#define GPTIMER_CTRL_CH_BIT	5
+#define GPTIMER_CTRL_DH_BIT	6
+
+#define GPTIMER_CTRL_EN	(1<<GPTIMER_CTRL_EN_BIT)
+#define GPTIMER_CTRL_RS	(1<<GPTIMER_CTRL_RS_BIT)
+#define GPTIMER_CTRL_LD	(1<<GPTIMER_CTRL_LD_BIT)
+#define GPTIMER_CTRL_IE	(1<<GPTIMER_CTRL_IE_BIT)
+#define GPTIMER_CTRL_IP	(1<<GPTIMER_CTRL_IP_BIT)
+#define GPTIMER_CTRL_CH	(1<<GPTIMER_CTRL_CH_BIT)
+#define GPTIMER_CTRL_DH	(1<<GPTIMER_CTRL_DH_BIT)
+
+#define DBG(x...)
+
+/* GPTIMER timer private */
+struct gptimer_timer {
+	struct tlib_dev tdev;	/* Must be first in struct */
+	struct gptimer_timer_regs *tregs;
+	char index; /* Timer Index in this driver */
+	char tindex; /* Timer Index In Hardware */
+	unsigned char irq_ack_mask;
+};
+
+/* GPTIMER Core private */
+struct gptimer_priv {
+	struct drvmgr_dev *dev;
+	struct gptimer_regs *regs;
+	unsigned int base_clk;
+	unsigned int base_freq;
+	unsigned int widthmask;
+	char separate_interrupt;
+	char isr_installed;
+
+	/* Structure per Timer unit, the core supports up to 8 timers */
+	int timer_cnt;
+	struct gptimer_timer timers[0];
+};
+
+void gptimer_isr(void *data);
+
+#if 0
+void gptimer_tlib_irq_register(struct tlib_drv *tdrv, tlib_isr_t func, void *data)
+{
+	struct gptimer_priv *priv = (struct gptimer_priv *)tdrv;
+
+	if ( SHARED ...)
+	
+	
+	drvmgr_interrupt_register();
+}
+#endif
+
+/******************* Driver manager interface ***********************/
+
+/* Driver prototypes */
+static struct tlib_drv gptimer_tlib_drv;
+int gptimer_device_init(struct gptimer_priv *priv);
+
+int gptimer_init1(struct drvmgr_dev *dev);
+#ifdef GPTIMER_INFO_AVAIL
+static int gptimer_info(
+	struct drvmgr_dev *dev,
+	void (*print_line)(void *p, char *str),
+	void *p, int, char *argv[]);
+#define GTIMER_INFO_FUNC gptimer_info
+#else
+#define GTIMER_INFO_FUNC NULL
+#endif
+
+struct drvmgr_drv_ops gptimer_ops =
+{
+	.init = {gptimer_init1, NULL, NULL, NULL},
+	.remove = NULL,
+	.info = GTIMER_INFO_FUNC,
+};
+
+struct amba_dev_id gptimer_ids[] =
+{
+	{VENDOR_GAISLER, GAISLER_GPTIMER},
+	{VENDOR_GAISLER, GAISLER_GRTIMER},
+	{0, 0}		/* Mark end of table */
+};
+
+struct amba_drv_info gptimer_drv_info =
+{
+	{
+		DRVMGR_OBJ_DRV,			/* Driver */
+		NULL,				/* Next driver */
+		NULL,				/* Device list */
+		DRIVER_AMBAPP_GAISLER_GPTIMER_ID,/* Driver ID */
+		"GPTIMER_DRV",			/* Driver Name */
+		DRVMGR_BUS_TYPE_AMBAPP,		/* Bus Type */
+		&gptimer_ops,
+		NULL,				/* Funcs */
+		0,				/* No devices yet */
+		0,
+	},
+	&gptimer_ids[0]
+};
+
+void gptimer_register_drv (void)
+{
+	DBG("Registering GPTIMER driver\n");
+	drvmgr_drv_register(&gptimer_drv_info.general);
+}
+
+int gptimer_init1(struct drvmgr_dev *dev)
+{
+	struct gptimer_priv *priv;
+	struct gptimer_regs *regs;
+	struct amba_dev_info *ambadev;
+	struct ambapp_core *pnpinfo;
+	int timer_hw_cnt, timer_cnt, timer_start;
+	int i, size;
+	struct gptimer_timer *timer;
+	union drvmgr_key_value *value;
+	unsigned char irq_ack_mask;
+
+	/* Get device information from AMBA PnP information */
+	ambadev = (struct amba_dev_info *)dev->businfo;
+	if ( ambadev == NULL ) {
+		return -1;
+	}
+	pnpinfo = &ambadev->info;
+	regs = (struct gptimer_regs *)pnpinfo->apb_slv->start;
+
+	DBG("GPTIMER[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
+
+	/* Get number of Timers */
+	timer_hw_cnt = regs->cfg & GPTIMER_CFG_TIMERS;
+
+	/* Let user spelect a range of timers to be used. In AMP systems
+	 * it is sometimes neccessary to leave timers for other CPU instances.
+	 *
+	 * The default operation in AMP is to shared the timers within the
+	 * first GPTIMER core as below. This can of course be overrided by
+	 * driver resources.
+	 */
+	timer_cnt = timer_hw_cnt;
+	timer_start = 0;
+#if defined(RTEMS_MULTIPROCESSING) && defined(LEON3)
+	if ((dev->minor_drv == 0) && drvmgr_on_rootbus(dev)) {
+		timer_cnt = 1;
+		timer_start = LEON3_Cpu_Index;
+	}
+#endif
+	value = drvmgr_dev_key_get(dev, "timerStart", DRVMGR_KT_INT);
+	if ( value) {
+		timer_start = value->i;
+		timer_cnt = timer_hw_cnt - timer_start;
+	}
+	value = drvmgr_dev_key_get(dev, "timerCnt", DRVMGR_KT_INT);
+	if ( value && (value->i < timer_cnt) ) {
+		timer_cnt = value->i;
+	}
+
+	/* Allocate Common Timer Description, size depends on how many timers
+	 * are present.
+	 */
+	size = sizeof(struct gptimer_priv) +
+		timer_cnt*sizeof(struct gptimer_timer);
+	priv = dev->priv = (struct gptimer_priv *)malloc(size);
+	if ( !priv )
+		return DRVMGR_NOMEM;
+	memset(priv, 0, size);
+	priv->dev = dev;
+	priv->regs = regs;
+
+	/* The Base Frequency of the GPTIMER core is the same as the
+	 * frequency of the AMBA bus it is situated on.
+	 */
+	drvmgr_freq_get(dev, DEV_APB_SLV, &priv->base_clk);
+
+	/* This core will may provide important Timer functionality
+	 * to other drivers and the RTEMS kernel, the Clock driver
+	 * may for example use this device. So the Timer driver must be
+	 * initialized in the first iiitialization stage.
+	 */
+
+	/*** Initialize Hardware ***/
+
+	/* If user request to set prescaler, we will do that. However, note
+	 * that doing so for the Root-Bus GPTIMER may affect the RTEMS Clock
+	 * so that Clock frequency is wrong.
+	 */
+	value = drvmgr_dev_key_get(priv->dev, "prescaler", DRVMGR_KT_INT);
+	if ( value )
+		regs->scaler_reload = value->i;
+
+	/* Get Frequency that the timers are operating in (after prescaler) */
+	priv->base_freq = priv->base_clk / (priv->regs->scaler_reload + 1);
+
+	/* Stop Timer and probe Pending bit. In newer hardware the
+	 * timer has pending bit is cleared by writing a one to it,
+	 * whereas older versions it is cleared with a zero.
+	 */
+	priv->regs->timer[timer_start].ctrl = GPTIMER_CTRL_IP;
+	if ((priv->regs->timer[timer_start].ctrl & GPTIMER_CTRL_IP) != 0)
+		irq_ack_mask = ~GPTIMER_CTRL_IP;
+	else
+		irq_ack_mask = ~0;
+
+	/* Probe timer register width mask */
+	priv->regs->timer[timer_start].value = 0xffffffff;
+	priv->widthmask = priv->regs->timer[timer_start].value;
+
+	priv->timer_cnt = timer_cnt;
+	for (i=0; i<timer_cnt; i++) {
+		timer = &priv->timers[i];
+		timer->index = i;
+		timer->tindex = i + timer_start;
+		timer->tregs = &regs->timer[(int)timer->tindex];
+		timer->tdev.drv = &gptimer_tlib_drv;
+		timer->irq_ack_mask = irq_ack_mask;
+
+		/* Register Timer at Timer Library */
+		tlib_dev_reg(&timer->tdev);
+	}
+
+	/* Check Interrupt support implementation, two cases:
+	 *  A. All Timers share one IRQ
+	 *  B. Each Timer have an individual IRQ. The number is:
+	 *        BASE_IRQ + timer_index
+	 */
+	priv->separate_interrupt = (regs->cfg & GPTIMER_CFG_SI) != 0;
+
+	return DRVMGR_OK;
+}
+
+#ifdef GPTIMER_INFO_AVAIL
+static int gptimer_info(
+	struct drvmgr_dev *dev,
+	void (*print_line)(void *p, char *str),
+	void *p, int argc, char *argv[])
+{
+	struct gptimer_priv *priv = dev->priv;
+	struct gptimer_timer *timer;
+	char buf[64];
+	int i;
+
+	if (priv == NULL || argc != 0)
+		return -DRVMGR_EINVAL;
+
+	sprintf(buf, "Timer Count: %d", priv->timer_cnt);
+	print_line(p, buf);
+	sprintf(buf, "REGS:        0x%08x", (unsigned int)priv->regs);
+	print_line(p, buf);
+	sprintf(buf, "BASE SCALER: %d", priv->regs->scaler_reload);
+	print_line(p, buf);
+	sprintf(buf, "BASE FREQ:   %dkHz", priv->base_freq / 1000);
+	print_line(p, buf);
+	sprintf(buf, "SeparateIRQ: %s", priv->separate_interrupt ? "YES":"NO");
+	print_line(p, buf);
+
+	for (i=0; i<priv->timer_cnt; i++) {
+		timer = &priv->timers[i];
+		sprintf(buf, " - TIMER HW Index %d -", timer->tindex);
+		print_line(p, buf);
+		sprintf(buf, " TLIB Index: %d", timer->index);
+		print_line(p, buf);
+		sprintf(buf, " RELOAD REG: %d", timer->tregs->reload);
+		print_line(p, buf);
+		sprintf(buf, " CTRL REG:   %d", timer->tregs->ctrl);
+		print_line(p, buf);
+	}
+
+	return DRVMGR_OK;
+}
+#endif
+
+static inline struct gptimer_priv *priv_from_timer(struct gptimer_timer *t)
+{
+	return (struct gptimer_priv *)
+		((unsigned int)t -
+		sizeof(struct gptimer_priv) -
+		t->index * sizeof(struct gptimer_timer));
+}
+
+static int gptimer_tlib_int_pend(struct tlib_dev *hand, int ack)
+{
+	struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+	unsigned int ctrl = timer->tregs->ctrl;
+
+	if ((ctrl & (GPTIMER_CTRL_IP | GPTIMER_CTRL_IE)) ==
+		(GPTIMER_CTRL_IP | GPTIMER_CTRL_IE)) {
+		/* clear Pending IRQ ? */
+		if (ack)
+			timer->tregs->ctrl = ctrl & timer->irq_ack_mask;
+		return 1; /* timer generated IRQ */
+	} else
+		return 0; /* was not timer causing IRQ */
+}
+
+void gptimer_isr(void *data)
+{
+	struct gptimer_priv *priv = data;
+	int i;
+
+	/* Check all timers for IRQ */
+	for (i=0;i<priv->timer_cnt; i++) {
+		if (gptimer_tlib_int_pend((void *)&priv->timers[i], 0)) {
+			/* IRQ Was generated by Timer and Pending flag has *not*
+			 * yet been cleared, this is to allow ISR to look at
+			 * pending bit. Call ISR registered. Clear pending bit.
+			 */
+			if (priv->timers[i].tdev.isr_func) {
+				priv->timers[i].tdev.isr_func(
+					priv->timers[i].tdev.isr_data);
+			}
+			gptimer_tlib_int_pend((void *)&priv->timers[i], 1);
+		}
+	}
+}
+
+static void gptimer_tlib_reset(struct tlib_dev *hand)
+{
+	struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+
+	timer->tregs->ctrl = (timer->tregs->ctrl & timer->irq_ack_mask) &
+			     GPTIMER_CTRL_IP;
+	timer->tregs->reload = 0xffffffff;
+	timer->tregs->ctrl = GPTIMER_CTRL_LD;
+}
+
+static void gptimer_tlib_get_freq(
+	struct tlib_dev *hand,
+	unsigned int *basefreq,
+	unsigned int *tickrate)
+{
+	struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+	struct gptimer_priv *priv = priv_from_timer(timer);
+
+	/* Calculate base frequency from Timer Clock and Prescaler */
+	if ( basefreq )
+		*basefreq = priv->base_freq;
+	if ( tickrate )
+		*tickrate = timer->tregs->reload + 1;
+}
+
+static int gptimer_tlib_set_freq(struct tlib_dev *hand, unsigned int tickrate)
+{
+	struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+
+	timer->tregs->reload = tickrate - 1;
+
+	/*Check that value was allowed (Timer may not be as wide as expected)*/
+	if ( timer->tregs->reload != (tickrate - 1) )
+		return -1;
+	else
+		return 0;
+}
+
+static void gptimer_tlib_irq_reg(struct tlib_dev *hand, tlib_isr_t func, void *data, int flags)
+{
+	struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+	struct gptimer_priv *priv = priv_from_timer(timer);
+
+	if ( priv->separate_interrupt ) {
+		drvmgr_interrupt_register(priv->dev, timer->tindex,
+						"gptimer", func, data);
+	} else {
+		if (priv->isr_installed == 0) {
+			/* Shared IRQ handler */
+			drvmgr_interrupt_register(
+				priv->dev,
+				0,
+				"gptimer_shared",
+				gptimer_isr,
+				priv);
+		}
+		priv->isr_installed++;
+	}
+
+#if RTEMS_SMP
+	if (flags & TLIB_FLAGS_BROADCAST) {
+		int tindex = 0;
+
+		if (priv->separate_interrupt) {
+			/* Offset interrupt number with HW subtimer index */
+			tindex = timer->tindex;
+		}
+		drvmgr_interrupt_set_affinity(priv->dev, tindex,
+					      _SMP_Get_online_processors());
+	}
+#endif
+
+	timer->tregs->ctrl |= GPTIMER_CTRL_IE;
+}
+
+static void gptimer_tlib_irq_unreg(struct tlib_dev *hand, tlib_isr_t func, void *data)
+{
+	struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+	struct gptimer_priv *priv = priv_from_timer(timer);
+
+	/* Turn off IRQ at source, unregister IRQ handler */
+	timer->tregs->ctrl &= ~GPTIMER_CTRL_IE;
+
+	if ( priv->separate_interrupt ) {
+		drvmgr_interrupt_unregister(priv->dev, timer->tindex,
+						func, data);
+	} else {
+		timer->tdev.isr_func = NULL;
+		priv->isr_installed--;
+		if (priv->isr_installed == 0) {
+			drvmgr_interrupt_unregister(priv->dev, 0,
+							gptimer_isr, priv);
+		}
+	}
+}
+
+static void gptimer_tlib_start(struct tlib_dev *hand, int once)
+{
+	struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+	unsigned int ctrl;
+
+	/* Load the selected frequency before starting Frequency */
+	ctrl = GPTIMER_CTRL_LD | GPTIMER_CTRL_EN;
+	if ( once == 0 )
+		ctrl |= GPTIMER_CTRL_RS; /* Restart Timer */
+	timer->tregs->ctrl = ctrl | (timer->tregs->ctrl & timer->irq_ack_mask &
+			     ~GPTIMER_CTRL_RS);
+}
+
+static void gptimer_tlib_stop(struct tlib_dev *hand)
+{
+	struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+
+	/* Load the selected Frequency */
+	timer->tregs->ctrl &= ~(GPTIMER_CTRL_EN|GPTIMER_CTRL_IP);
+}
+
+static void gptimer_tlib_restart(struct tlib_dev *hand)
+{
+	struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+
+	timer->tregs->ctrl |= GPTIMER_CTRL_LD | GPTIMER_CTRL_EN;
+}
+
+static void gptimer_tlib_get_counter(
+	struct tlib_dev *hand,
+	unsigned int *counter)
+{
+	struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+
+	*counter = timer->tregs->value;
+}
+
+static void gptimer_tlib_get_widthmask(
+	struct tlib_dev *hand,
+	unsigned int *widthmask)
+{
+	struct gptimer_timer *timer = (struct gptimer_timer *)hand;
+	struct gptimer_priv *priv = priv_from_timer(timer);
+
+	*widthmask = priv->widthmask;
+}
+
+static struct tlib_drv gptimer_tlib_drv =
+{
+	.reset = gptimer_tlib_reset,
+	.get_freq = gptimer_tlib_get_freq,
+	.set_freq = gptimer_tlib_set_freq,
+	.irq_reg = gptimer_tlib_irq_reg,
+	.irq_unreg = gptimer_tlib_irq_unreg,
+	.start = gptimer_tlib_start,
+	.stop = gptimer_tlib_stop,
+	.restart = gptimer_tlib_restart,
+	.get_counter = gptimer_tlib_get_counter,
+	.custom = NULL,
+	.int_pend = gptimer_tlib_int_pend,
+	.get_widthmask = gptimer_tlib_get_widthmask,
+};
Index: bsps/sparc/shared/btimer/tlib.c
===================================================================
--- bsps/sparc/shared/btimer/tlib.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/sparc/shared/btimer/tlib.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,77 @@
+/*
+ *  Timer Library (TLIB)
+ *
+ *  COPYRIGHT (c) 2011.
+ *  Cobham Gaisler AB.
+ *
+ *  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/tlib.h>
+
+struct tlib_dev *tlib_dev_head = NULL;
+struct tlib_dev *tlib_dev_tail = NULL;
+static int tlib_dev_cnt = 0;
+
+/* Register Timer device to Timer Library */
+int tlib_dev_reg(struct tlib_dev *newdev)
+{
+	/* Reset device */
+	newdev->status = 0;
+	newdev->isr_func = NULL;
+	newdev->index = tlib_dev_cnt;
+
+	/* Insert last in queue */
+	newdev->next = NULL;
+	if ( tlib_dev_tail == NULL ) {
+		tlib_dev_head = newdev;
+	} else {
+		tlib_dev_tail->next = newdev;
+	}
+	tlib_dev_tail = newdev;
+
+	/* Return Index of Registered Timer */
+	return tlib_dev_cnt++;
+}
+
+void *tlib_open(int timer_no)
+{
+	struct tlib_dev *dev;
+
+	if ( timer_no < 0 )
+		return NULL;
+
+	dev = tlib_dev_head;
+	while ( (timer_no > 0) && dev ) {
+		timer_no--;
+		dev = dev->next;
+	}
+	if ( dev ) {
+		if ( dev->status )
+			return NULL;
+		dev->status = 1;
+		/* Reset Timer to initial state */
+		tlib_reset(dev);
+	}
+	return dev;
+}
+
+void tlib_close(void *hand)
+{
+	struct tlib_dev *dev = hand;
+
+	/* Stop any ongoing timer operation and unregister IRQ if registered */
+	tlib_stop(dev);
+	tlib_irq_unregister(dev);
+
+	/* Mark not open */
+	dev->status = 0;
+}
+
+int tlib_ntimer(void)
+{
+	return tlib_dev_cnt;
+}
Index: bsps/sparc/shared/btimer/tlib_ckinit.c
===================================================================
--- bsps/sparc/shared/btimer/tlib_ckinit.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
+++ bsps/sparc/shared/btimer/tlib_ckinit.c	(revision e0dd8a5ad830798bc8082b03b8c42c32fb9660e0)
@@ -0,0 +1,453 @@
+/*
+ *  Clock Tick Device Driver using Timer Library implemented
+ *  by the GRLIB GPTIMER / LEON2 Timer drivers.
+ *
+ *  COPYRIGHT (c) 2010 - 2017.
+ *  Cobham Gaisler AB.
+ *
+ *  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.
+ *
+ */
+
+/*
+ * This is an implementation of the RTEMS "clockdrv_shell" interface for
+ * LEON2/3/4 systems using the Driver Manager. It is clock hardware agnostic
+ * and compatible with SMP and UP. Availability of free running counters is
+ * probed and selected as needed.
+ */
+#include <rtems.h>
+#include <rtems/timecounter.h>
+#include <rtems/clockdrv.h>
+#include <stdlib.h>
+#include <bsp.h>
+#include <bsp/tlib.h>
+
+#ifdef RTEMS_DRVMGR_STARTUP
+
+#if defined(LEON3)
+#include <leon.h>
+#endif
+
+struct ops {
+  /*
+   * Set up the free running counter using the Timecounter or Simple
+   * Timecounter interface.
+   */
+  rtems_device_driver (*initialize_counter)(void);
+
+  /*
+   * Hardware-specific support at tick interrupt which runs early in Clock_isr.
+   * It can for example be used to check if interrupt was actually caused by
+   * the timer hardware. If return value is not RTEMS_SUCCESSFUL then Clock_isr
+   * returns immediately. at_tick can be initialized with NULL.
+   */
+  rtems_device_driver (*at_tick)(void);
+
+  /*
+   * Typically calls rtems_timecounter_tick(). A specialized clock driver may
+   * use for example rtems_timecounter_tick_simple() instead.
+   */
+  void (*timecounter_tick)(void);
+
+  /*
+   * Called when the clock driver exits. It can be used to stop functionality
+   * started by initialize_counter. The tick timer is stopped by default.
+   * shutdown_hardware can be initialized with NULL
+   */
+  void (*shutdown_hardware)(void);
+};
+
+/*
+ * Different implementation depending on available free running counter for the
+ * timecounter.
+ *
+ * NOTE: The clock interface is not compatible with shared interrupts on the
+ * clock (tick) timer in SMP configuration.
+ */
+
+/* "simple timecounter" interface. Only for non-SMP. */
+static const struct ops ops_simple;
+/* Hardware support up-counter using LEON3 %asr23. */
+static const struct ops ops_timetag;
+/* Timestamp counter available in some IRQ(A)MP instantiations. */
+static const struct ops ops_irqamp;
+/* Separate GPTIMER subtimer as timecounter */
+static const struct ops ops_subtimer;
+
+struct clock_priv {
+  const struct ops *ops;
+  /*
+   * Timer number in Timer Library for tick timer used by this interface.
+   * Defaults to the first Timer in the System.
+   */
+  int tlib_tick_index;
+  /* Timer number for timecounter timer if separate GPTIMER subtimer is used */
+  int tlib_counter_index;
+  void *tlib_tick;
+  void *tlib_counter;
+  rtems_timecounter_simple tc_simple;
+  struct timecounter tc;
+};
+static struct clock_priv priv;
+
+/** Common interface **/
+
+/* Set system clock timer instance */
+void Clock_timer_register(int timer_number)
+{
+  priv.tlib_tick_index = timer_number;
+  priv.tlib_counter_index = timer_number + 1;
+}
+
+static rtems_device_driver tlib_clock_find_timer(void)
+{
+  /* Take Timer that should be used as system timer. */
+  priv.tlib_tick = tlib_open(priv.tlib_tick_index);
+  if (priv.tlib_tick == NULL) {
+    /* System Clock Timer not found */
+    return RTEMS_NOT_DEFINED;
+  }
+
+  /* Select which operation set to use */
+#ifndef RTEMS_SMP
+  priv.ops = &ops_simple;
+#else
+  /* When on LEON3 try to use dedicated hardware free running counter. */
+  leon3_up_counter_enable();
+  if (leon3_up_counter_is_available()) {
+    priv.ops = &ops_timetag;
+    return RTEMS_SUCCESSFUL;
+  } else {
+    volatile struct irqmp_timestamp_regs *irqmp_ts;
+
+    irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0];
+    if (leon3_irqmp_has_timestamp(irqmp_ts)) {
+      priv.ops = &ops_irqamp;
+      return RTEMS_SUCCESSFUL;
+    }
+  }
+
+  /* Take another subtimer as the final option. */
+  priv.ops = &ops_subtimer;
+#endif
+
+  return RTEMS_SUCCESSFUL;
+}
+
+static rtems_device_driver tlib_clock_initialize_hardware(void)
+{
+  /* Set tick rate in number of "Base-Frequency ticks" */
+  tlib_set_freq(priv.tlib_tick, rtems_configuration_get_microseconds_per_tick());
+  priv.ops->initialize_counter();
+  tlib_start(priv.tlib_tick, 0);
+
+  return RTEMS_SUCCESSFUL;
+}
+
+static rtems_device_driver tlib_clock_at_tick(void)
+{
+  if (priv.ops->at_tick) {
+    return priv.ops->at_tick();
+  }
+
+  return RTEMS_SUCCESSFUL;
+}
+
+static void tlib_clock_timecounter_tick(void)
+{
+  priv.ops->timecounter_tick();
+}
+
+/* Return a value not equal to RTEMS_SUCCESFUL to make Clock_initialize fail. */
+static rtems_device_driver tlib_clock_install_isr(rtems_isr *isr)
+{
+  int flags = 0;
+
+#ifdef RTEMS_SMP
+  /* We shall broadcast the clock interrupt to all processors. */
+  flags = TLIB_FLAGS_BROADCAST;
+#endif
+  tlib_irq_register(priv.tlib_tick, isr, NULL, flags);
+
+  return RTEMS_SUCCESSFUL;
+}
+
+static void tlib_clock_shutdown_hardware(void)
+{
+  if (priv.tlib_tick) {
+    tlib_stop(priv.tlib_tick);
+    priv.tlib_tick = NULL;
+  }
+  if (priv.ops->shutdown_hardware) {
+    priv.ops->shutdown_hardware();
+  }
+}
+
+/** Simple counter **/
+static uint32_t simple_tlib_tc_get(rtems_timecounter_simple *tc)
+{
+  unsigned int clicks = 0;
+
+  if (priv.tlib_tick != NULL) {
+    tlib_get_counter(priv.tlib_tick, &clicks);
+  }
+
+  return clicks;
+}
+
+static bool simple_tlib_tc_is_pending(rtems_timecounter_simple *tc)
+{
+  bool pending = false;
+
+  if (priv.tlib_tick != NULL) {
+    pending = tlib_interrupt_pending(priv.tlib_tick, 0) != 0;
+  }
+
+  return pending;
+}
+
+static uint32_t simple_tlib_tc_get_timecount(struct timecounter *tc)
+{
+  return rtems_timecounter_simple_downcounter_get(
+    tc,
+    simple_tlib_tc_get,
+    simple_tlib_tc_is_pending
+  );
+}
+
+static rtems_device_driver simple_initialize_counter(void)
+{
+  uint64_t frequency;
+  unsigned int tick_hz;
+
+  frequency = 1000000;
+  tick_hz = rtems_configuration_get_microseconds_per_tick();
+
+  rtems_timecounter_simple_install(
+    &priv.tc_simple,
+    frequency,
+    tick_hz,
+    simple_tlib_tc_get_timecount
+  );
+
+  return RTEMS_NOT_DEFINED;
+}
+
+static void simple_tlib_tc_at_tick(rtems_timecounter_simple *tc)
+{
+  /* Nothing to do */
+}
+
+/*
+ * Support for shared interrupts. Ack IRQ at source, only handle interrupts
+ * generated from the tick-timer. This is called early in Clock_isr.
+ */
+static rtems_device_driver simple_at_tick(void)
+{
+  if (tlib_interrupt_pending(priv.tlib_tick, 1) == 0) {
+    return RTEMS_NOT_DEFINED;
+  }
+  return RTEMS_SUCCESSFUL;
+}
+
+static void simple_timecounter_tick(void)
+{
+  rtems_timecounter_simple_downcounter_tick(
+    &priv.tc_simple,
+    simple_tlib_tc_get,
+    simple_tlib_tc_at_tick
+  );
+}
+
+static const struct ops ops_simple = {
+  .initialize_counter = simple_initialize_counter,
+  .at_tick            = simple_at_tick,
+  .timecounter_tick   = simple_timecounter_tick,
+  .shutdown_hardware  = NULL,
+};
+
+/** Subtimer as counter **/
+static uint32_t subtimer_get_timecount(struct timecounter *tc)
+{
+  unsigned int counter;
+
+  tlib_get_counter(priv.tlib_counter, &counter);
+
+  return 0xffffffff - counter;
+}
+
+static rtems_device_driver subtimer_initialize_counter(void)
+{
+  unsigned int mask;
+  unsigned int basefreq;
+
+  if (priv.tlib_counter_index == priv.tlib_tick_index) {
+    priv.tlib_counter_index = priv.tlib_tick_index + 1;
+  }
+  /* Take Timer that should be used as timecounter upcounter timer. */
+  priv.tlib_counter = tlib_open(priv.tlib_counter_index);
+  if (priv.tlib_counter == NULL) {
+    /* Timecounter timer not found */
+    return RTEMS_NOT_DEFINED;
+  }
+
+  /* Configure free running counter: GPTIMER */
+  tlib_get_freq(priv.tlib_counter, &basefreq, NULL);
+  tlib_get_widthmask(priv.tlib_counter, &mask);
+
+  priv.tc.tc_get_timecount = subtimer_get_timecount;
+  priv.tc.tc_counter_mask = mask;
+  priv.tc.tc_frequency = basefreq;
+  priv.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+  rtems_timecounter_install(&priv.tc);
+  /* Start free running counter */
+  tlib_start(priv.tlib_counter, 0);
+
+  return RTEMS_SUCCESSFUL;
+}
+
+static void subtimer_timecounter_tick(void)
+{
+  rtems_timecounter_tick();
+}
+
+static void subtimer_shutdown_hardware(void)
+{
+  if (priv.tlib_counter) {
+    tlib_stop(priv.tlib_counter);
+    priv.tlib_counter = NULL;
+  }
+}
+
+static const struct ops ops_subtimer = {
+  .initialize_counter = subtimer_initialize_counter,
+  .timecounter_tick   = subtimer_timecounter_tick,
+  .shutdown_hardware  = subtimer_shutdown_hardware,
+};
+
+#if defined(LEON3)
+/** DSU timetag as counter **/
+static uint32_t timetag_get_timecount(struct timecounter *tc)
+{
+  return leon3_up_counter_low();
+}
+
+static rtems_device_driver timetag_initialize_counter(void)
+{
+  /* Configure free running counter: timetag */
+  priv.tc.tc_get_timecount = timetag_get_timecount;
+  priv.tc.tc_counter_mask = 0xffffffff;
+  priv.tc.tc_frequency = leon3_up_counter_frequency();
+  priv.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+  rtems_timecounter_install(&priv.tc);
+
+  return RTEMS_SUCCESSFUL;
+}
+
+static void timetag_timecounter_tick(void)
+{
+  rtems_timecounter_tick();
+}
+
+static const struct ops ops_timetag = {
+  .initialize_counter = timetag_initialize_counter,
+  .at_tick            = NULL,
+  .timecounter_tick   = timetag_timecounter_tick,
+  .shutdown_hardware  = NULL,
+};
+#endif
+
+#if defined(LEON3)
+/** IRQ(A)MP timestamp as counter **/
+static uint32_t irqamp_get_timecount(struct timecounter *tc)
+{
+  return LEON3_IrqCtrl_Regs->timestamp[0].counter;
+}
+
+static rtems_device_driver irqamp_initialize_counter(void)
+{
+  volatile struct irqmp_timestamp_regs *irqmp_ts;
+  static const uint32_t A_TSISEL_FIELD = 0xf;
+
+  /* Configure free running counter: timetag */
+  priv.tc.tc_get_timecount = irqamp_get_timecount;
+  priv.tc.tc_counter_mask = 0xffffffff;
+  priv.tc.tc_frequency = leon3_up_counter_frequency();
+  priv.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+  rtems_timecounter_install(&priv.tc);
+
+  /*
+   * The counter increments whenever a TSISEL field in a Timestamp Control
+   * Register is non-zero.
+   */
+  irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0];
+  irqmp_ts->control = A_TSISEL_FIELD;
+
+  return RTEMS_SUCCESSFUL;
+}
+
+static void irqamp_timecounter_tick(void)
+{
+  rtems_timecounter_tick();
+}
+
+static const struct ops ops_irqamp = {
+  .initialize_counter = irqamp_initialize_counter,
+  .at_tick            = NULL,
+  .timecounter_tick   = irqamp_timecounter_tick,
+  .shutdown_hardware  = NULL,
+};
+#endif
+
+/** Interface to the Clock Driver Shell (dev/clock/clockimpl.h) **/
+#define Clock_driver_support_find_timer() \
+  do { \
+    rtems_device_driver ret; \
+    ret = tlib_clock_find_timer(); \
+    if (RTEMS_SUCCESSFUL != ret) { \
+      return ret; \
+    } \
+  } while (0)
+
+#define Clock_driver_support_install_isr( isr ) \
+  do { \
+    rtems_device_driver ret; \
+    ret = tlib_clock_install_isr( isr ); \
+    if (RTEMS_SUCCESSFUL != ret) { \
+      return ret; \
+    } \
+  } while (0)
+
+#define Clock_driver_support_set_interrupt_affinity(online_processors) \
+  /* Done by tlib_clock_install_isr() */
+
+#define Clock_driver_support_initialize_hardware() \
+  do { \
+    rtems_device_driver ret; \
+    ret = tlib_clock_initialize_hardware(); \
+    if (RTEMS_SUCCESSFUL != ret) { \
+      return ret; \
+    } \
+  } while (0)
+
+#define Clock_driver_support_shutdown_hardware() \
+  tlib_clock_shutdown_hardware()
+
+#define Clock_driver_timecounter_tick() \
+  tlib_clock_timecounter_tick()
+
+#define Clock_driver_support_at_tick() \
+  do { \
+    rtems_device_driver ret; \
+    ret = tlib_clock_at_tick(); \
+    if (RTEMS_SUCCESSFUL != ret) { \
+      return; \
+    } \
+  } while (0)
+
+#include "../../../shared/dev/clock/clockimpl.h"
+
+#endif /* RTEMS_DRVMGR_STARTUP */
+
