Index: cpukit/sapi/Makefile.am
===================================================================
--- cpukit/sapi/Makefile.am	(revision cc6938455edfa4dff79ce98320292e3a9c2e434b)
+++ cpukit/sapi/Makefile.am	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -5,4 +5,5 @@
 
 include_rtems_HEADERS = include/confdefs.h
+include_rtems_HEADERS += include/rtems/bsd.h
 include_rtems_HEADERS += include/rtems/chain.h
 include_rtems_HEADERS += include/rtems/config.h
@@ -20,4 +21,5 @@
 include_rtems_HEADERS += include/rtems/scheduler.h
 include_rtems_HEADERS += include/rtems/sptables.h
+include_rtems_HEADERS += include/rtems/timecounter.h
 include_rtems_HEADERS += include/rtems/timespec.h
 
@@ -40,4 +42,5 @@
 libsapi_a_SOURCES += src/profilingiterate.c
 libsapi_a_SOURCES += src/profilingreportxml.c
+libsapi_a_SOURCES += src/tcsimpleinstall.c
 libsapi_a_CPPFLAGS = $(AM_CPPFLAGS)
 
Index: cpukit/sapi/include/rtems/bsd.h
===================================================================
--- cpukit/sapi/include/rtems/bsd.h	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
+++ cpukit/sapi/include/rtems/bsd.h	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -0,0 +1,141 @@
+/**
+ * @file
+ *
+ * @ingroup BSD
+ *
+ * @brief BSD Compatibility API
+ */
+
+/*
+ * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_BSD_H
+#define _RTEMS_BSD_H
+
+#include <rtems/score/timecounter.h>
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup BSD BSD Compatibility Support
+ *
+ * @{
+ */
+
+/**
+ * @copydoc _Timecounter_Bintime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_bintime( struct bintime *bt )
+{
+  _Timecounter_Bintime( bt );
+}
+
+/**
+ * @copydoc _Timecounter_Nanotime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_nanotime( struct timespec *ts )
+{
+  _Timecounter_Nanotime( ts );
+}
+
+/**
+ * @copydoc _Timecounter_Microtime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_microtime( struct timeval *tv )
+{
+  _Timecounter_Microtime( tv );
+}
+
+/**
+ * @copydoc _Timecounter_Binuptime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_binuptime( struct bintime *bt )
+{
+  _Timecounter_Binuptime( bt );
+}
+
+/**
+ * @copydoc _Timecounter_Nanouptime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_nanouptime( struct timespec *ts )
+{
+  _Timecounter_Nanouptime( ts );
+}
+
+/**
+ * @copydoc _Timecounter_Microtime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_microuptime( struct timeval *tv )
+{
+  _Timecounter_Microuptime( tv );
+}
+
+/**
+ * @copydoc _Timecounter_Getbintime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_getbintime( struct bintime *bt )
+{
+  _Timecounter_Getbintime( bt );
+}
+
+/**
+ * @copydoc _Timecounter_Getnanotime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_getnanotime( struct timespec *ts )
+{
+  _Timecounter_Getnanotime( ts );
+}
+
+/**
+ * @copydoc _Timecounter_Getmicrotime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_getmicrotime( struct timeval *tv )
+{
+  _Timecounter_Getmicrotime( tv );
+}
+
+/**
+ * @copydoc _Timecounter_Getbinuptime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_getbinuptime( struct bintime *bt )
+{
+  _Timecounter_Getbinuptime( bt );
+}
+
+/**
+ * @copydoc _Timecounter_Getnanouptime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_getnanouptime( struct timespec *ts )
+{
+  _Timecounter_Getnanouptime( ts );
+}
+
+/**
+ * @copydoc _Timecounter_Getmicrouptime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_getmicrouptime( struct timeval *tv )
+{
+  _Timecounter_Getmicrouptime( tv );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_BSD_H */
Index: cpukit/sapi/include/rtems/timecounter.h
===================================================================
--- cpukit/sapi/include/rtems/timecounter.h	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
+++ cpukit/sapi/include/rtems/timecounter.h	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -0,0 +1,304 @@
+/**
+ * @file
+ *
+ * @ingroup SAPITimecounter
+ *
+ * @brief Timecounter API
+ */
+
+/*
+ * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_TIMECOUNTER_H
+#define _RTEMS_TIMECOUNTER_H
+
+#include <rtems/score/timecounter.h>
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup SAPITimecounter Timecounter Support
+ *
+ * @{
+ */
+
+/**
+ * @brief Timecounter quality for the clock drivers.
+ *
+ * Timecounter with higher quality value are used in favour of those with lower
+ * quality value.
+ */
+#define RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER 100
+
+/**
+ * @copydoc _Timecounter_Install()
+ *
+ * Below is an exemplary code snippet that shows the adjustable parameters and
+ * the following call of the install routine.
+ *
+ * @code
+ * struct timecounter tc;
+ *
+ * uint32_t get_timecount( struct timecounter *tc )
+ * {
+ *   return some_free_running_counter;
+ * }
+ *
+ * void install( void )
+ * {
+ *   tc.tc_get_timecount = get_timecount;
+ *   tc.tc_counter_mask = 0xffffffff;
+ *   tc.tc_frequency = 123456;
+ *   tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ *   rtems_timecounter_install( &tc );
+ * }
+ * @endcode
+ */
+RTEMS_INLINE_ROUTINE void rtems_timecounter_install(
+  struct timecounter *tc
+)
+{
+  _Timecounter_Install( tc );
+}
+
+/**
+ * @copydoc _Timecounter_Tick()
+ */
+RTEMS_INLINE_ROUTINE void rtems_timecounter_tick(void)
+{
+  _Timecounter_Tick();
+}
+
+/**
+ * @brief Simple timecounter to support legacy clock drivers.
+ */
+typedef struct {
+  struct timecounter tc;
+  uint64_t scaler;
+  uint32_t real_interval;
+  uint32_t binary_interval;
+} rtems_timecounter_simple;
+
+/**
+ * @brief Returns the current value of a simple timecounter.
+ */
+typedef uint32_t rtems_timecounter_simple_get(
+  rtems_timecounter_simple *tc
+);
+
+/**
+ * @brief Returns true if the interrupt of a simple timecounter is pending, and
+ * false otherwise.
+ */
+typedef bool rtems_timecounter_simple_is_pending(
+  rtems_timecounter_simple *tc
+);
+
+/**
+ * @brief Initializes and installs a simple timecounter.
+ *
+ * A simple timecounter can be used if the hardware provides no free running
+ * counter or only the module used for the clock tick is available.  The period
+ * of the simple timecounter equals the clock tick interval.  The interval is
+ * scaled up to the next power of two.
+ *
+ * @param[in] tc Zero initialized simple timecounter.
+ * @param[in] frequency_in_hz The timecounter frequency in Hz.
+ * @param[in] timecounter_ticks_per_clock_tick The timecounter ticks per clock tick.
+ * @param[in] get_timecount The method to get the current time count.
+ *
+ * @code
+ * #include <rtems/timecounter.h>
+ *
+ * static rtems_timecounter_simple some_tc;
+ *
+ * static uint32_t some_tc_get( rtems_timecounter_simple *tc )
+ * {
+ *   return some.value;
+ * }
+ *
+ * static bool some_tc_is_pending( rtems_timecounter_simple *tc )
+ * {
+ *   return some.is_pending;
+ * }
+ *
+ * static uint32_t some_tc_get_timecount( struct timecounter *tc )
+ * {
+ *   return rtems_timecounter_simple_downcounter_get(
+ *     tc,
+ *     some_tc_get,
+ *     some_tc_is_pending
+ *   );
+ * }
+ *
+ * static void some_tc_tick( void )
+ * {
+ *   rtems_timecounter_simple_downcounter_tick( &some_tc, some_tc_get );
+ * }
+ *
+ * void install( void )
+ * {
+ *   uint32_t frequency = 123456;
+ *   uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
+ *   uint32_t timecounter_ticks_per_clock_tick =
+ *     ( frequency * us_per_tick ) / 1000000;
+ *
+ *   rtems_timecounter_simple_install(
+ *     &some_tc,
+ *     frequency,
+ *     timecounter_ticks_per_clock_tick,
+ *     some_tc_get_timecount
+ *   );
+ * }
+ * @endcode
+ *
+ * @see rtems_timecounter_simple_downcounter_get(),
+ * rtems_timecounter_simple_downcounter_tick(),
+ * rtems_timecounter_simple_upcounter_get() and
+ * rtems_timecounter_simple_upcounter_tick().
+ */
+void rtems_timecounter_simple_install(
+  rtems_timecounter_simple *tc,
+  uint32_t                  frequency_in_hz,
+  uint32_t                  timecounter_ticks_per_clock_tick,
+  timecounter_get_t        *get_timecount
+);
+
+/**
+ * @brief Maps a simple timecounter value into its binary frequency domain.
+ *
+ * @param[in] tc The simple timecounter.
+ * @param[in] value The value of the simple timecounter.
+ *
+ * @return The scaled value.
+ */
+RTEMS_INLINE_ROUTINE uint32_t rtems_timecounter_simple_scale(
+  const rtems_timecounter_simple *tc,
+  uint32_t value
+)
+{
+  return (uint32_t) ( ( value * tc->scaler ) >> 32 );
+}
+
+/**
+ * @brief Performs a simple timecounter tick for downcounters.
+ *
+ * @param[in] tc The simple timecounter.
+ * @param[in] get The method to get the value of the simple timecounter.
+ */
+RTEMS_INLINE_ROUTINE void rtems_timecounter_simple_downcounter_tick(
+  rtems_timecounter_simple     *tc,
+  rtems_timecounter_simple_get  get
+)
+{
+  uint32_t current;
+
+  current = rtems_timecounter_simple_scale(
+    tc,
+    tc->real_interval - ( *get )( tc )
+  );
+
+  _Timecounter_Tick_simple( tc->binary_interval, current );
+}
+
+/**
+ * @brief Performs a simple timecounter tick for upcounters.
+ *
+ * @param[in] tc The simple timecounter.
+ * @param[in] get The method to get the value of the simple timecounter.
+ */
+RTEMS_INLINE_ROUTINE void rtems_timecounter_simple_upcounter_tick(
+  rtems_timecounter_simple     *tc,
+  rtems_timecounter_simple_get  get
+)
+{
+  uint32_t current;
+
+  current = rtems_timecounter_simple_scale( tc, ( *get )( tc ) );
+
+  _Timecounter_Tick_simple( tc->binary_interval, current );
+}
+
+/**
+ * @brief Gets the simple timecounter value mapped to its binary frequency
+ * domain for downcounters.
+ *
+ * @param[in] tc The simple timecounter.
+ * @param[in] get The method to get the value of the simple timecounter.
+ * @param[in] is_pending The method which indicates if the interrupt of the
+ * simple timecounter is pending.
+ */
+RTEMS_INLINE_ROUTINE uint32_t rtems_timecounter_simple_downcounter_get(
+  struct timecounter                  *tc_base,
+  rtems_timecounter_simple_get         get,
+  rtems_timecounter_simple_is_pending  is_pending
+)
+{
+  rtems_timecounter_simple *tc;
+  uint32_t counter;
+  uint32_t interval;
+
+  tc = (rtems_timecounter_simple *) tc_base;
+  counter = ( *get )( tc );
+  interval = tc->real_interval;
+
+  if ( ( *is_pending )( tc ) ) {
+    counter = ( *get )( tc );
+    interval *= 2;
+  }
+
+  return rtems_timecounter_simple_scale( tc, interval - counter );
+}
+
+/**
+ * @brief Gets the simple timecounter value mapped to its binary frequency
+ * domain for upcounters.
+ *
+ * @param[in] tc The simple timecounter.
+ * @param[in] get The method to get the value of the simple timecounter.
+ * @param[in] is_pending The method which indicates if the interrupt of the
+ * simple timecounter is pending.
+ */
+RTEMS_INLINE_ROUTINE uint32_t rtems_timecounter_simple_upcounter_get(
+  struct timecounter                  *tc_base,
+  rtems_timecounter_simple_get         get,
+  rtems_timecounter_simple_is_pending  is_pending
+)
+{
+  rtems_timecounter_simple *tc;
+  uint32_t counter;
+  uint32_t interval;
+
+  tc = (rtems_timecounter_simple *) tc_base;
+  counter = ( *get )( tc );
+  interval = 0;
+
+  if ( ( *is_pending )( tc ) ) {
+    counter = ( *get )( tc );
+    interval = tc->real_interval;
+  }
+
+  return rtems_timecounter_simple_scale( tc, interval + counter );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_TIMECOUNTER_H */
Index: cpukit/sapi/preinstall.am
===================================================================
--- cpukit/sapi/preinstall.am	(revision cc6938455edfa4dff79ce98320292e3a9c2e434b)
+++ cpukit/sapi/preinstall.am	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -22,4 +22,8 @@
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/confdefs.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/confdefs.h
+
+$(PROJECT_INCLUDE)/rtems/bsd.h: include/rtems/bsd.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/bsd.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/bsd.h
 
 $(PROJECT_INCLUDE)/rtems/chain.h: include/rtems/chain.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
@@ -83,4 +87,8 @@
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/sptables.h
 
+$(PROJECT_INCLUDE)/rtems/timecounter.h: include/rtems/timecounter.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/timecounter.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/timecounter.h
+
 $(PROJECT_INCLUDE)/rtems/timespec.h: include/rtems/timespec.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/timespec.h
Index: cpukit/sapi/src/tcsimpleinstall.c
===================================================================
--- cpukit/sapi/src/tcsimpleinstall.c	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
+++ cpukit/sapi/src/tcsimpleinstall.c	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/timecounter.h>
+
+void rtems_timecounter_simple_install(
+  rtems_timecounter_simple *tc,
+  uint32_t                  frequency_in_hz,
+  uint32_t                  counter_ticks_per_clock_tick,
+  timecounter_get_t        *get_timecount
+)
+{
+  uint32_t power_of_two = 1;
+  uint32_t mask;
+  uint64_t scaler;
+  int i;
+
+  for ( i = 0; i < 32; ++i ) {
+    if ( power_of_two >= counter_ticks_per_clock_tick ) {
+      break;
+    }
+
+    power_of_two *= 2;
+  }
+
+  mask = ( 2 * power_of_two ) - 1;
+  scaler = ( (uint64_t) power_of_two << 32 ) / counter_ticks_per_clock_tick;
+
+  tc->scaler = scaler;
+  tc->real_interval = counter_ticks_per_clock_tick;
+  tc->binary_interval = ( mask + 1 ) / 2;
+  tc->tc.tc_get_timecount = get_timecount;
+  tc->tc.tc_counter_mask = mask;
+  tc->tc.tc_frequency = (uint32_t) ( ( frequency_in_hz * scaler ) >> 32 );
+  tc->tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+  _Timecounter_Install( &tc->tc );
+}
Index: cpukit/score/Makefile.am
===================================================================
--- cpukit/score/Makefile.am	(revision cc6938455edfa4dff79ce98320292e3a9c2e434b)
+++ cpukit/score/Makefile.am	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -5,4 +5,13 @@
 
 ## include
+
+include_sysdir = $(includedir)/sys
+
+include_sys_HEADERS =
+include_sys_HEADERS += include/sys/_ffcounter.h
+include_sys_HEADERS += include/sys/timeffc.h
+include_sys_HEADERS += include/sys/timepps.h
+include_sys_HEADERS += include/sys/timetc.h
+include_sys_HEADERS += include/sys/timex.h
 
 include_rtemsdir = $(includedir)/rtems
@@ -86,4 +95,6 @@
 include_rtems_score_HEADERS += include/rtems/score/timestamp.h
 include_rtems_score_HEADERS += include/rtems/score/timestamp64.h
+include_rtems_score_HEADERS += include/rtems/score/timecounter.h
+include_rtems_score_HEADERS += include/rtems/score/timecounterimpl.h
 include_rtems_score_HEADERS += include/rtems/score/tls.h
 include_rtems_score_HEADERS += include/rtems/score/tod.h
@@ -345,4 +356,5 @@
 libscore_a_SOURCES += src/resourceiterate.c
 libscore_a_SOURCES += src/smpbarrierwait.c
+libscore_a_SOURCES += src/kern_tc.c
 
 EXTRA_DIST = src/Unlimited.txt
Index: cpukit/score/include/rtems/score/timecounter.h
===================================================================
--- cpukit/score/include/rtems/score/timecounter.h	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
+++ cpukit/score/include/rtems/score/timecounter.h	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -0,0 +1,199 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreTimecounter
+ *
+ * @brief Timecounter API
+ */
+
+/*
+ * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_TIMECOUNTER_H
+#define _RTEMS_SCORE_TIMECOUNTER_H
+
+#include <sys/time.h>
+#include <sys/timetc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreTimecounter Timecounter Handler
+ *
+ * @ingroup Score
+ *
+ * @{
+ */
+
+/**
+ * @brief Returns the wall clock time in the bintime format.
+ *
+ * @param[out] bt Returns the wall clock time.
+ */
+void _Timecounter_Bintime( struct bintime *bt );
+
+/**
+ * @brief Returns the wall clock time in the timespec format.
+ *
+ * @param[out] ts Returns the wall clock time.
+ */
+void _Timecounter_Nanotime( struct timespec *ts );
+
+/**
+ * @brief Returns the wall clock time in the timeval format.
+ *
+ * @param[out] tv Returns the wall clock time.
+ */
+void _Timecounter_Microtime( struct timeval *tv );
+
+/**
+ * @brief Returns the uptime in the bintime format.
+ *
+ * @param[out] bt Returns the uptime.
+ */
+void _Timecounter_Binuptime( struct bintime *bt );
+
+/**
+ * @brief Returns the uptime in the timespec format.
+ *
+ * @param[out] ts Returns the uptime.
+ */
+void _Timecounter_Nanouptime( struct timespec *ts );
+
+/**
+ * @brief Returns the uptime in the timeval format.
+ *
+ * @param[out] tv Returns the uptime.
+ */
+void _Timecounter_Microuptime( struct timeval *tv );
+
+/**
+ * @brief Returns the wall clock time in the bintime format.
+ *
+ * This function obtains the time with a lower overhead and lower accuracy
+ * compared to the _Timecounter_Bintime() variant.
+ *
+ * @param[out] ts Returns the wall clock time.
+ */
+void _Timecounter_Getbintime( struct bintime *bt );
+
+/**
+ * @brief Returns the wall clock time in the timespec format.
+ *
+ * This function obtains the time with a lower overhead and lower accuracy
+ * compared to the _Timecounter_Nanotime() variant.
+ *
+ * @param[out] ts Returns the wall clock time.
+ *
+ * @see _Timecounter_Getbintime().
+ */
+void _Timecounter_Getnanotime( struct timespec *ts );
+
+/**
+ * @brief Returns the wall clock time in the timeval format.
+ *
+ * This function obtains the time with a lower overhead and lower accuracy
+ * compared to the _Timecounter_Microtime() variant.
+ *
+ * @param[out] tv Returns the wall clock time.
+ *
+ * @see _Timecounter_Getbintime().
+ */
+void _Timecounter_Getmicrotime( struct timeval *tv );
+
+/**
+ * @brief Returns the uptime in the bintime format.
+ *
+ * This function obtains the time with a lower overhead and lower accuracy
+ * compared to the _Timecounter_Binuptime() variant.
+ *
+ * @param[out] ts Returns the uptime.
+ */
+void _Timecounter_Getbinuptime( struct bintime *bt );
+
+/**
+ * @brief Returns the uptime in the timespec format.
+ *
+ * This function obtains the time with a lower overhead and lower accuracy
+ * compared to the _Timecounter_Nanouptime() variant.
+ *
+ * @param[out] ts Returns the uptime.
+ */
+void _Timecounter_Getnanouptime( struct timespec *ts );
+
+/**
+ * @brief Returns the uptime in the timeval format.
+ *
+ * This function obtains the time with a lower overhead and lower accuracy
+ * compared to the _Timecounter_Microuptime() variant.
+ *
+ * @param[out] tv Returns the uptime.
+ */
+void _Timecounter_Getmicrouptime( struct timeval *tv );
+
+/**
+ * @brief Installs the timecounter.
+ *
+ * The timecounter structure must contain valid values in the fields
+ * tc_get_timecount, tc_counter_mask, tc_frequency and tc_quality.  All other
+ * fields must be zero initialized.
+ *
+ * @param[in] tc The timecounter.
+ */
+void _Timecounter_Install( struct timecounter *tc );
+
+/**
+ * @brief Performs a timecounter tick.
+ */
+void _Timecounter_Tick( void );
+
+/**
+ * @brief Performs a simple timecounter tick.
+ *
+ * This is a special purpose tick function for simple timecounter to support
+ * legacy clock drivers.
+ *
+ * @param[in] delta The time in timecounter ticks elapsed since the last call
+ * to _Timecounter_Tick_simple().
+ * @param[in] offset The current value of the timecounter.
+ */
+void _Timecounter_Tick_simple( uint32_t delta, uint32_t offset );
+
+/**
+ * @brief The wall clock time in seconds.
+ */
+extern volatile time_t _Timecounter_Time_second;
+
+/**
+ * @brief The uptime in seconds.
+ *
+ * For compatibility with the FreeBSD network stack the initial value is one
+ * second.
+ */
+extern volatile time_t _Timecounter_Time_uptime;
+
+/**
+ * @brief The current timecounter.
+ */
+extern struct timecounter *_Timecounter;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_TIMECOUNTER_H */
Index: cpukit/score/include/rtems/score/timecounterimpl.h
===================================================================
--- cpukit/score/include/rtems/score/timecounterimpl.h	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
+++ cpukit/score/include/rtems/score/timecounterimpl.h	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -0,0 +1,49 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreTimecounter
+ *
+ * @brief Timecounter Implementation
+ */
+
+/*
+ * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_TIMECOUNTERIMPL_H
+#define _RTEMS_SCORE_TIMECOUNTERIMPL_H
+
+#include <rtems/score/timecounter.h>
+#include <sys/timetc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup ScoreTimecounter
+ *
+ * @{
+ */
+
+void _Timecounter_Initialize( void );
+
+void _Timecounter_Set_clock( const struct timespec *ts );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_TIMECOUNTERIMPL_H */
Index: cpukit/score/include/sys/timeffc.h
===================================================================
--- cpukit/score/include/sys/timeffc.h	(revision cc6938455edfa4dff79ce98320292e3a9c2e434b)
+++ cpukit/score/include/sys/timeffc.h	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -56,4 +56,5 @@
 #ifdef _KERNEL
 
+#ifndef __rtems__
 /* Define the kern.sysclock sysctl tree. */
 SYSCTL_DECL(_kern_sysclock);
@@ -61,4 +62,5 @@
 /* Define the kern.sysclock.ffclock sysctl tree. */
 SYSCTL_DECL(_kern_sysclock_ffclock);
+#endif /* __rtems__ */
 
 /*
Index: cpukit/score/include/sys/timetc.h
===================================================================
--- cpukit/score/include/sys/timetc.h	(revision cc6938455edfa4dff79ce98320292e3a9c2e434b)
+++ cpukit/score/include/sys/timetc.h	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -13,7 +13,9 @@
 #define	_SYS_TIMETC_H_
 
+#ifndef __rtems__
 #ifndef _KERNEL
 #error "no user-serviceable parts inside"
 #endif
+#endif /* __rtems__ */
 
 /*-
Index: cpukit/score/preinstall.am
===================================================================
--- cpukit/score/preinstall.am	(revision cc6938455edfa4dff79ce98320292e3a9c2e434b)
+++ cpukit/score/preinstall.am	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -14,4 +14,29 @@
 CLEANFILES = $(PREINSTALL_FILES)
 
+$(PROJECT_INCLUDE)/sys/$(dirstamp):
+	@$(MKDIR_P) $(PROJECT_INCLUDE)/sys
+	@: > $(PROJECT_INCLUDE)/sys/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/sys/$(dirstamp)
+
+$(PROJECT_INCLUDE)/sys/_ffcounter.h: include/sys/_ffcounter.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/_ffcounter.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/_ffcounter.h
+
+$(PROJECT_INCLUDE)/sys/timeffc.h: include/sys/timeffc.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/timeffc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/timeffc.h
+
+$(PROJECT_INCLUDE)/sys/timepps.h: include/sys/timepps.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/timepps.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/timepps.h
+
+$(PROJECT_INCLUDE)/sys/timetc.h: include/sys/timetc.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/timetc.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/timetc.h
+
+$(PROJECT_INCLUDE)/sys/timex.h: include/sys/timex.h $(PROJECT_INCLUDE)/sys/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/sys/timex.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/sys/timex.h
+
 $(PROJECT_INCLUDE)/rtems/$(dirstamp):
 	@$(MKDIR_P) $(PROJECT_INCLUDE)/rtems
@@ -323,4 +348,12 @@
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/timestamp64.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/timestamp64.h
+
+$(PROJECT_INCLUDE)/rtems/score/timecounter.h: include/rtems/score/timecounter.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/timecounter.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/timecounter.h
+
+$(PROJECT_INCLUDE)/rtems/score/timecounterimpl.h: include/rtems/score/timecounterimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/timecounterimpl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/timecounterimpl.h
 
 $(PROJECT_INCLUDE)/rtems/score/tls.h: include/rtems/score/tls.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
Index: cpukit/score/src/kern_tc.c
===================================================================
--- cpukit/score/src/kern_tc.c	(revision cc6938455edfa4dff79ce98320292e3a9c2e434b)
+++ cpukit/score/src/kern_tc.c	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -14,4 +14,25 @@
  */
 
+#ifdef __rtems__
+#define _KERNEL
+#define bintime _Timecounter_Bintime
+#define binuptime _Timecounter_Binuptime
+#define boottimebin _Timecounter_Boottimebin
+#define getbintime _Timecounter_Getbintime
+#define getbinuptime _Timecounter_Getbinuptime
+#define getmicrotime _Timecounter_Getmicrotime
+#define getmicrouptime _Timecounter_Getmicrouptime
+#define getnanotime _Timecounter_Getnanotime
+#define getnanouptime _Timecounter_Getnanouptime
+#define microtime _Timecounter_Microtime
+#define microuptime _Timecounter_Microuptime
+#define nanotime _Timecounter_Nanotime
+#define nanouptime _Timecounter_Nanouptime
+#define tc_init _Timecounter_Install
+#define timecounter _Timecounter
+#define time_second _Timecounter_Time_second
+#define time_uptime _Timecounter_Time_uptime
+#include <rtems/score/timecounterimpl.h>
+#endif /* __rtems__ */
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD r277406 2015-01-20T03:54:30Z$");
@@ -22,18 +43,40 @@
 
 #include <sys/param.h>
+#ifndef __rtems__
 #include <sys/kernel.h>
 #include <sys/limits.h>
+#else /* __rtems__ */
+#include <limits.h>
+#endif /* __rtems__ */
 #ifdef FFCLOCK
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #endif
+#ifndef __rtems__
 #include <sys/sysctl.h>
 #include <sys/syslog.h>
 #include <sys/systm.h>
+#endif /* __rtems__ */
 #include <sys/timeffc.h>
 #include <sys/timepps.h>
 #include <sys/timetc.h>
 #include <sys/timex.h>
+#ifndef __rtems__
 #include <sys/vdso.h>
+#endif /* __rtems__ */
+#ifdef __rtems__
+#include <rtems.h>
+ISR_LOCK_DEFINE(static, _Timecounter_Lock, "Timecounter");
+#define hz rtems_clock_get_ticks_per_second()
+#define printf(...)
+#define log(...)
+static inline int
+fls(int x)
+{
+        return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
+}
+/* FIXME: https://devel.rtems.org/ticket/2348 */
+#define ntp_update_second(a, b) do { (void) a; (void) b; } while (0)
+#endif /* __rtems__ */
 
 /*
@@ -54,7 +97,11 @@
 dummy_get_timecount(struct timecounter *tc)
 {
+#ifndef __rtems__
 	static uint32_t now;
 
 	return (++now);
+#else /* __rtems__ */
+	return 0;
+#endif /* __rtems__ */
 }
 
@@ -77,4 +124,5 @@
 };
 
+#if defined(RTEMS_SMP)
 static struct timehands th0;
 static struct timehands th9 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th0};
@@ -87,4 +135,5 @@
 static struct timehands th2 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th3};
 static struct timehands th1 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th2};
+#endif
 static struct timehands th0 = {
 	&dummy_timecounter,
@@ -96,5 +145,9 @@
 	{0, 0},
 	1,
+#if defined(RTEMS_SMP)
 	&th1
+#else
+	&th0
+#endif
 };
 
@@ -103,5 +156,7 @@
 static struct timecounter *timecounters = &dummy_timecounter;
 
+#ifndef __rtems__
 int tc_min_ticktock_freq = 1;
+#endif /* __rtems__ */
 
 volatile time_t time_second = 1;
@@ -109,4 +164,5 @@
 
 struct bintime boottimebin;
+#ifndef __rtems__
 struct timeval boottime;
 static int sysctl_kern_boottime(SYSCTL_HANDLER_ARGS);
@@ -134,10 +190,14 @@
     sysctl_kern_timecounter_adjprecision, "I",
     "Allowed time interval deviation in percents");
+#endif /* __rtems__ */
 
 static void tc_windup(void);
+#ifndef __rtems__
 static void cpu_tick_calibrate(int);
+#endif /* __rtems__ */
 
 void dtrace_getnanotime(struct timespec *tsp);
 
+#ifndef __rtems__
 static int
 sysctl_kern_boottime(SYSCTL_HANDLER_ARGS)
@@ -176,4 +236,5 @@
 	return sysctl_handle_64(oidp, &freq, 0, req);
 }
+#endif /* __rtems__ */
 
 /*
@@ -977,4 +1038,5 @@
 #endif /* FFCLOCK */
 
+#ifndef __rtems__
 /*
  * This is a clone of getnanotime and used for walltimestamps.
@@ -994,4 +1056,5 @@
 	} while (gen == 0 || gen != th->th_generation);
 }
+#endif /* __rtems__ */
 
 #ifdef FFCLOCK
@@ -1007,4 +1070,5 @@
 extern long time_esterror;
 
+#ifndef __rtems__
 /*
  * Take a snapshot of sysclock data which can be used to compare system clocks
@@ -1138,4 +1202,5 @@
 	return (0);
 }
+#endif /* __rtems__ */
 
 /*
@@ -1145,4 +1210,5 @@
 tc_init(struct timecounter *tc)
 {
+#ifndef __rtems__
 	uint32_t u;
 	struct sysctl_oid *tc_root;
@@ -1164,7 +1230,9 @@
 		    tc->tc_quality);
 	}
+#endif /* __rtems__ */
 
 	tc->tc_next = timecounters;
 	timecounters = tc;
+#ifndef __rtems__
 	/*
 	 * Set up sysctl tree for this counter.
@@ -1197,9 +1265,14 @@
 	    tc->tc_frequency < timecounter->tc_frequency)
 		return;
+#endif /* __rtems__ */
 	(void)tc->tc_get_timecount(tc);
 	(void)tc->tc_get_timecount(tc);
 	timecounter = tc;
-}
-
+#ifdef __rtems__
+	tc_windup();
+#endif /* __rtems__ */
+}
+
+#ifndef __rtems__
 /* Report the frequency of the current timecounter. */
 uint64_t
@@ -1209,4 +1282,5 @@
 	return (timehands->th_counter->tc_frequency);
 }
+#endif /* __rtems__ */
 
 /*
@@ -1215,12 +1289,21 @@
  * XXX: not locked.
  */
+#ifndef __rtems__
 void
 tc_setclock(struct timespec *ts)
-{
+#else /* __rtems__ */
+void
+_Timecounter_Set_clock(const struct timespec *ts)
+#endif /* __rtems__ */
+{
+#ifndef __rtems__
 	struct timespec tbef, taft;
+#endif /* __rtems__ */
 	struct bintime bt, bt2;
 
+#ifndef __rtems__
 	cpu_tick_calibrate(1);
 	nanotime(&tbef);
+#endif /* __rtems__ */
 	timespec2bintime(ts, &bt);
 	binuptime(&bt2);
@@ -1228,8 +1311,11 @@
 	bintime_add(&bt2, &boottimebin);
 	boottimebin = bt;
+#ifndef __rtems__
 	bintime2timeval(&bt, &boottime);
+#endif /* __rtems__ */
 
 	/* XXX fiddle all the little crinkly bits around the fiords... */
 	tc_windup();
+#ifndef __rtems__
 	nanotime(&taft);
 	if (timestepwarnings) {
@@ -1241,4 +1327,5 @@
 	}
 	cpu_tick_calibrate(1);
+#endif /* __rtems__ */
 }
 
@@ -1257,4 +1344,9 @@
 	int i;
 	time_t t;
+#ifdef __rtems__
+	ISR_lock_Context lock_context;
+
+	_ISR_lock_ISR_disable_and_acquire(&_Timecounter_Lock, &lock_context);
+#endif /* __rtems__ */
 
 	/*
@@ -1334,4 +1426,5 @@
 	/* Now is a good time to change timecounters. */
 	if (th->th_counter != timecounter) {
+#ifndef __rtems__
 #ifndef __arm__
 		if ((timecounter->tc_flags & TC_FLAGS_C2STOP) != 0)
@@ -1340,8 +1433,11 @@
 			cpu_disable_c2_sleep--;
 #endif
+#endif /* __rtems__ */
 		th->th_counter = timecounter;
 		th->th_offset_count = ncount;
+#ifndef __rtems__
 		tc_min_ticktock_freq = max(1, timecounter->tc_frequency /
 		    (((uint64_t)timecounter->tc_counter_mask + 1) / 3));
+#endif /* __rtems__ */
 #ifdef FFCLOCK
 		ffclock_change_tc(th);
@@ -1402,7 +1498,13 @@
 
 	timehands = th;
+#ifndef __rtems__
 	timekeep_push_vdso();
-}
-
+#endif /* __rtems__ */
+#ifdef __rtems__
+	_ISR_lock_Release_and_ISR_enable(&_Timecounter_Lock, &lock_context);
+#endif /* __rtems__ */
+}
+
+#ifndef __rtems__
 /* Report or change the active timecounter hardware. */
 static int
@@ -1469,5 +1571,7 @@
 SYSCTL_PROC(_kern_timecounter, OID_AUTO, choice, CTLTYPE_STRING | CTLFLAG_RD,
     0, 0, sysctl_kern_timecounter_choice, "A", "Timecounter hardware detected");
-
+#endif /* __rtems__ */
+
+#ifndef __rtems__
 /*
  * RFC 2783 PPS-API implementation.
@@ -1750,4 +1854,7 @@
 	wakeup(pps);
 }
+#else /* __rtems__ */
+/* FIXME: https://devel.rtems.org/ticket/2349 */
+#endif /* __rtems__ */
 
 /*
@@ -1758,8 +1865,11 @@
  */
 
+#ifndef __rtems__
 static int tc_tick;
 SYSCTL_INT(_kern_timecounter, OID_AUTO, tick, CTLFLAG_RD, &tc_tick, 0,
     "Approximate number of hardclock ticks in a millisecond");
-
+#endif /* __rtems__ */
+
+#ifndef __rtems__
 void
 tc_ticktock(int cnt)
@@ -1771,7 +1881,52 @@
 		return;
 	count = 0;
+#else /* __rtems__ */
+void
+_Timecounter_Tick(void)
+{
+#endif /* __rtems__ */
 	tc_windup();
 }
-
+#ifdef __rtems__
+void
+_Timecounter_Tick_simple(uint32_t delta, uint32_t offset)
+{
+	struct bintime bt;
+	struct timehands *th;
+	uint32_t ogen;
+	ISR_lock_Context lock_context;
+
+	_ISR_lock_ISR_disable_and_acquire(&_Timecounter_Lock, &lock_context);
+
+	th = timehands;
+	ogen = th->th_generation;
+	th->th_offset_count = offset;
+	bintime_addx(&th->th_offset, th->th_scale * delta);
+
+	bt = th->th_offset;
+	bintime_add(&bt, &boottimebin);
+
+	/* Update the UTC timestamps used by the get*() functions. */
+	/* XXX shouldn't do this here.  Should force non-`get' versions. */
+	bintime2timeval(&bt, &th->th_microtime);
+	bintime2timespec(&bt, &th->th_nanotime);
+
+	/*
+	 * Now that the struct timehands is again consistent, set the new
+	 * generation number, making sure to not make it zero.
+	 */
+	if (++ogen == 0)
+		ogen = 1;
+	th->th_generation = ogen;
+
+	/* Go live with the new struct timehands. */
+	time_second = th->th_microtime.tv_sec;
+	time_uptime = th->th_offset.sec;
+
+	_ISR_lock_Release_and_ISR_enable(&_Timecounter_Lock, &lock_context);
+}
+#endif /* __rtems__ */
+
+#ifndef __rtems__
 static void __inline
 tc_adjprecision(void)
@@ -1795,5 +1950,7 @@
 	sbt_tickthreshold = bttosbt(bt_tickthreshold);
 }
-
+#endif /* __rtems__ */
+
+#ifndef __rtems__
 static int
 sysctl_kern_timecounter_adjprecision(SYSCTL_HANDLER_ARGS)
@@ -1812,8 +1969,15 @@
 	return (0);
 }
-
+#endif /* __rtems__ */
+
+#ifndef __rtems__
 static void
 inittimecounter(void *dummy)
-{
+#else /* __rtems__ */
+void
+_Timecounter_Initialize(void)
+#endif /* __rtems__ */
+{
+#ifndef __rtems__
 	u_int p;
 	int tick_rate;
@@ -1839,4 +2003,5 @@
 	p = (tc_tick * 1000000) / hz;
 	printf("Timecounters tick every %d.%03u msec\n", p / 1000, p % 1000);
+#endif /* __rtems__ */
 
 #ifdef FFCLOCK
@@ -1849,6 +2014,9 @@
 }
 
+#ifndef __rtems__
 SYSINIT(timecounter, SI_SUB_CLOCKS, SI_ORDER_SECOND, inittimecounter, NULL);
-
+#endif /* __rtems__ */
+
+#ifndef __rtems__
 /* Cpu tick handling -------------------------------------------------*/
 
@@ -1983,5 +2151,7 @@
 
 cpu_tick_f	*cpu_ticks = tc_cpu_ticks;
-
+#endif /* __rtems__ */
+
+#ifndef __rtems__
 static int vdso_th_enable = 1;
 static int
@@ -2019,4 +2189,5 @@
 	return (enabled);
 }
+#endif /* __rtems__ */
 
 #ifdef COMPAT_FREEBSD32
Index: doc/bsp_howto/clock.t
===================================================================
--- doc/bsp_howto/clock.t	(revision cc6938455edfa4dff79ce98320292e3a9c2e434b)
+++ doc/bsp_howto/clock.t	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -8,83 +8,281 @@
 @section Introduction
 
-The purpose of the clock driver is to provide a steady time
-basis to the kernel, so that the RTEMS primitives that need
-a clock tick work properly.  See the @code{Clock Manager} chapter
-of the @b{RTEMS Application C User's Guide} for more details.
-
-The clock driver is located in the @code{clock} directory of the BSP. 
-
-@section Clock Driver Global Variables
-
-This section describes the global variables expected to be provided by
-this driver.
-
-@subsection Ticks Counter
-
-Most of the clock device drivers provide a global variable
-that is simply a count of the number of clock driver interrupt service
-routines that have occured.  This information is valuable when debugging
-a system.  This variable is declared as follows:
+The purpose of the clock driver is to provide two services for the operating
+system.
+@itemize @bullet
+@item A steady time basis to the kernel, so that the RTEMS primitives that need
+a clock tick work properly.  See the @cite{Clock Manager} chapter of the
+@cite{RTEMS Application C User's Guide} for more details.
+@item An optional time counter to generate timestamps of the uptime and wall
+clock time.
+@end itemize
+
+The clock driver is usually located in the @file{clock} directory of the BSP.
+Clock drivers should use the @dfn{Clock Driver Shell} available via the
+@file{clockdrv_shell.h} include file.
+
+@section Clock Driver Shell
+
+The @dfn{Clock Driver Shell} include file defines the clock driver functions
+declared in @code{#include <rtems/clockdrv.h>} which are used by RTEMS
+configuration file @code{#include <rtems/confdefs.h>}.  In case the application
+configuration defines @code{#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER},
+then the clock driver is registered and should provide its services to the
+operating system.  A hardware specific clock driver must provide some
+functions, defines and macros for the @dfn{Clock Driver Shell} which are
+explained here step by step.  A clock driver file looks in general like this.
+
+@example
+/*
+ * A section with functions, defines and macros to provide hardware specific
+ * functions for the Clock Driver Shell.
+ */
+
+#include "../../../shared/clockdrv_shell.h"
+@end example
+
+@subsection Initialization
+
+Depending on the hardware capabilities one out of three clock driver variants
+must be selected.
+@itemize @bullet
+@item The most basic clock driver provides only a periodic interrupt service
+routine which calls @code{rtems_clock_tick()}.  The interval is determined by
+the application configuration via @code{#define
+CONFIGURE_MICROSECONDS_PER_TICK} and can be obtained via
+@code{rtems_configuration_get_microseconds_per_tick()}.  The timestamp
+resolution is limited to the clock tick interval.
+@item In case the hardware lacks support for a free running counter, then the
+module used for the clock tick may provide support for timestamps with a
+resolution below the clock tick interval.  For this so called simple
+timecounters can be used.
+@item The desired variant uses a free running counter to provide accurate
+timestamps.  This variant is mandatory on SMP configurations.
+@end itemize
+
+@subsubsection Clock Tick Only Variant
+
+@example
+static void some_support_initialize_hardware( void )
+@{
+  /* Initialize hardware */
+@}
+
+#define Clock_driver_support_initialize_hardware() \
+  some_support_initialize_hardware()
+
+/* Indicate that this clock driver lacks a proper timecounter in hardware */
+#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
+
+#include "../../../shared/clockdrv_shell.h"
+@end example
+
+@subsubsection Simple Timecounter Variant
+
+@example
+#include <rtems/timecounter.h>
+
+static rtems_timecounter_simple some_tc;
+
+static uint32_t some_tc_get( rtems_timecounter_simple *tc )
+@{
+  return some.counter;
+@}
+
+static bool some_tc_is_pending( rtems_timecounter_simple *tc )
+@{
+  return some.is_pending;
+@}
+
+static uint32_t some_tc_get_timecount( struct timecounter *tc )
+@{
+  return rtems_timecounter_simple_downcounter_get(
+    tc,
+    some_tc_get,
+    some_tc_is_pending
+  );
+@}
+
+static void some_tc_tick( void )
+@{
+  rtems_timecounter_simple_downcounter_tick( &some_tc, some_tc_get );
+@}
+
+static void some_support_initialize_hardware( void )
+@{
+  uint32_t frequency = 123456;
+  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
+  uint32_t timecounter_ticks_per_clock_tick =
+    ( frequency * us_per_tick ) / 1000000;
+
+  /* Initialize hardware */
+
+  rtems_timecounter_simple_install(
+    &some_tc,
+    frequency,
+    timecounter_ticks_per_clock_tick,
+    some_tc_get_timecount
+  );
+@}
+
+#define Clock_driver_support_initialize_hardware() \
+  some_support_initialize_hardware()
+
+#define Clock_driver_timecounter_tick() \
+  some_tc_tick()
+
+#include "../../../shared/clockdrv_shell.h"
+@end example
+
+@subsubsection Timecounter Variant
+
+This variant is preferred since it is the most efficient and yields the most
+accurate timestamps.  It is also mandatory on SMP configurations to obtain
+valid timestamps.  The hardware must provide a periodic interrupt to service
+the clock tick and a free running counter for the timecounter.  The free
+running counter must have a power of two period.  The @code{tc_counter_mask}
+must be initialized to the free running counter period minus one, e.g. for a
+32-bit counter this is 0xffffffff.  The @code{tc_get_timecount} function must
+return the current counter value (the counter values must increase, so if the
+counter counts down, a conversion is necessary).  Use
+@code{RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER} for the @code{tc_quality}.  Set
+@code{tc_frequency} to the frequency of the free running counter in Hz.  All
+other fields of the @code{struct timecounter} must be zero initialized.
+Install the initialized timecounter via @code{rtems_timecounter_install()}.
+
+@example
+#include <rtems/timecounter.h>
+
+static struct timecounter some_tc;
+
+static uint32_t some_tc_get_timecount( struct timecounter *tc )
+@{
+  some.free_running_counter;
+@}
+
+static void some_support_initialize_hardware( void )
+@{
+  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
+  uint32_t frequency = 123456;
+
+  /*
+   * The multiplication must be done in 64-bit arithmetic to avoid an integer
+   * overflow on targets with a high enough counter frequency.
+   */
+  uint32_t interval = (uint32_t) ( ( frequency * us_per_tick ) / 1000000 );
+
+  /*
+   * Initialize hardware and set up a periodic interrupt for the configuration
+   * based interval.
+   */
+
+  some_tc.tc_get_timecount = some_tc_get_timecount;
+  some_tc.tc_counter_mask = 0xffffffff;
+  some_tc.tc_frequency = frequency;
+  some_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+  rtems_timecounter_install( &some_tc );
+@}
+
+#define Clock_driver_support_initialize_hardware() \
+  some_support_initialize_hardware()
+
+#include "../../../shared/clockdrv_shell.h"
+@end example
+
+@subsection Install Clock Tick Interrupt Service Routine
+
+The clock driver must provide a function to install the clock tick interrupt
+service routine via @code{Clock_driver_support_install_isr()}.
+
+@example
+#include <bsp/irq.h>
+#include <bsp/fatal.h>
+
+static void some_support_install_isr( rtems_interrupt_handler isr )
+@{
+  rtems_status_code sc;
+
+  sc = rtems_interrupt_handler_install(
+    SOME_IRQ,
+    "Clock",
+    RTEMS_INTERRUPT_UNIQUE,
+    isr,
+    NULL
+  );
+  if ( sc != RTEMS_SUCCESSFUL ) @{
+    bsp_fatal( SOME_FATAL_IRQ_INSTALL );
+  @}
+@}
+
+#define Clock_driver_support_install_isr( isr, old ) \
+  some_support_install_isr( isr )
+
+#include "../../../shared/clockdrv_shell.h"
+@end example
+
+@subsection Support At Tick
+
+The hardware specific support at tick is specified by
+@code{Clock_driver_support_at_tick()}.
+
+@example
+static void some_support_at_tick( void )
+@{
+  /* Clear interrupt */
+@}
+
+#define Clock_driver_support_at_tick() \
+  some_support_at_tick()
+
+#include "../../../shared/clockdrv_shell.h"
+@end example
+
+@subsection System Shutdown Support
+
+The @dfn{Clock Driver Shell} provides the routine @code{Clock_exit()} that is
+scheduled to be run during system shutdown via the @code{atexit()} routine.
+The hardware specific shutdown support is specified by
+@code{Clock_driver_support_shutdown_hardware()} which is used by
+@code{Clock_exit()}.  It should disable the clock tick source if it was
+enabled.  This can be used to prevent clock ticks after the system is shutdown.
+
+@example
+static void some_support_shutdown_hardware( void )
+@{
+  /* Shutdown hardware */
+@}
+
+#define Clock_driver_support_shutdown_hardware() \
+  some_support_shutdown_hardware()
+
+#include "../../../shared/clockdrv_shell.h"
+@end example
+
+@subsection Multiple Clock Driver Ticks Per Clock Tick
+
+In case the hardware needs more than one clock driver tick per clock tick (e.g.
+due to a limited range of the hardware timer), then this can be specified with
+the optional @code{#define CLOCK_DRIVER_ISRS_PER_TICK} and @code{#define
+CLOCK_DRIVER_ISRS_PER_TICK_VALUE} defines.  This is currently used only for x86
+and it hopefully remains that way.
+
+@example
+/* Enable multiple clock driver ticks per clock tick */
+#define CLOCK_DRIVER_ISRS_PER_TICK 1
+
+/* Specifiy the clock driver ticks per clock tick value */
+#define CLOCK_DRIVER_ISRS_PER_TICK_VALUE 123
+
+#include "../../../shared/clockdrv_shell.h"
+@end example
+
+@subsection Clock Driver Ticks Counter
+
+The @dfn{Clock Driver Shell} provide a global variable that is simply a count
+of the number of clock driver interrupt service routines that have occurred.
+This information is valuable when debugging a system.  This variable is
+declared as follows:
 
 @example
 volatile uint32_t Clock_driver_ticks;
 @end example
-
-@section Initialization
-
-The initialization routine is responsible for
-programming the hardware that will periodically
-generate an interrupt.  A programmable interval timer is commonly
-used as the source of the clock tick.
-
-The device should be programmed such that an interrupt is generated
-every @i{m} microseconds, where @i{m} is equal to 
-@code{rtems_configuration_get_microseconds_per_tick()}. Sometimes
-the periodic interval timer can use a prescaler so you have to look
-carefully at your user's manual to determine the correct value. 
-
-You must use the RTEMS primitive @code{rtems_interrupt_catch} to install
-your clock interrupt service routine:
-
-@example
-rtems_interrupt_catch (Clock_ISR, CLOCK_VECTOR, &old_handler); 
-@end example
-
-Since there is currently not a driver entry point invoked at system
-shutdown, many clock device drivers use the @code{atexit} routine
-to schedule their @code{Clock_exit} routine to execute when the
-system is shutdown.
-
-By convention, many of the clock drivers do not install the clock
-tick if the @code{ticks_per_timeslice} field of the Configuration
-Table is 0.
-
-@section System shutdown
-
-Many drivers provide the routine @code{Clock_exit} that is scheduled
-to be run during system shutdown via the @code{atexit} routine.
-The @code{Clock_exit} routine will disable the clock tick source
-if it was enabled.  This can be used to prevent clock ticks after the
-system is shutdown.
-
-@section Clock Interrupt Subroutine
-
-It only has to inform the kernel that a ticker has elapsed, so call : 
-
-@example
-@group
-rtems_isr Clock_isr( rtems_vector_number vector )
-@{
-  invoke the rtems_clock_tick() directive to announce the tick
-  if necessary for this hardware
-    reload the programmable timer
-@}
-@end group
-@end example
-
-@section IO Control
-
-Prior to RTEMS 4.9, the Shared Memory MPCI Driver required a special
-IOCTL in the Clock Driver.  This is no longer required and the Clock
-Driver does not have to provide an IOCTL method at all.
-
Index: testsuites/sptests/Makefile.am
===================================================================
--- testsuites/sptests/Makefile.am	(revision cc6938455edfa4dff79ce98320292e3a9c2e434b)
+++ testsuites/sptests/Makefile.am	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -39,4 +39,5 @@
 endif
 _SUBDIRS += spintrcritical23
+_SUBDIRS += sptimecounter01
 _SUBDIRS += spatomic01
 _SUBDIRS += spintrcritical22
Index: testsuites/sptests/configure.ac
===================================================================
--- testsuites/sptests/configure.ac	(revision cc6938455edfa4dff79ce98320292e3a9c2e434b)
+++ testsuites/sptests/configure.ac	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -42,4 +42,5 @@
 AC_CONFIG_FILES([Makefile
 spintrcritical23/Makefile
+sptimecounter01/Makefile
 spatomic01/Makefile
 spglobalcon01/Makefile
Index: testsuites/sptests/sptimecounter01/Makefile.am
===================================================================
--- testsuites/sptests/sptimecounter01/Makefile.am	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
+++ testsuites/sptests/sptimecounter01/Makefile.am	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = sptimecounter01
+sptimecounter01_SOURCES = init.c
+
+dist_rtems_tests_DATA = sptimecounter01.scn sptimecounter01.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(sptimecounter01_OBJECTS)
+LINK_LIBS = $(sptimecounter01_LDLIBS)
+
+sptimecounter01$(EXEEXT): $(sptimecounter01_OBJECTS) $(sptimecounter01_DEPENDENCIES)
+	@rm -f sptimecounter01$(EXEEXT)
+	$(make-exe)
+
+include $(top_srcdir)/../automake/local.am
Index: testsuites/sptests/sptimecounter01/init.c
===================================================================
--- testsuites/sptests/sptimecounter01/init.c	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
+++ testsuites/sptests/sptimecounter01/init.c	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <assert.h>
+
+#include <bsp/bootcard.h>
+
+#include <rtems/test.h>
+
+#include <rtems/score/timecounterimpl.h>
+#include <rtems/score/watchdogimpl.h>
+#include <rtems/timecounter.h>
+#include <rtems/bsd.h>
+
+const char rtems_test_name[] = "SPTIMECOUNTER_1";
+
+typedef struct {
+  struct timecounter tc_soft;
+  u_int tc_soft_counter;
+} test_context;
+
+static test_context test_instance;
+
+static uint32_t test_get_timecount_soft(struct timecounter *tc)
+{
+  test_context *ctx = tc->tc_priv;
+
+  ++ctx->tc_soft_counter;
+
+  return ctx->tc_soft_counter;
+}
+
+void boot_card(const char *cmdline)
+{
+  test_context *ctx = &test_instance;
+  struct timecounter *tc_soft = &ctx->tc_soft;
+  uint64_t soft_freq = 1000000;
+  struct bintime bt;
+
+  rtems_test_begink();
+
+  _Timecounter_Initialize();
+  _Watchdog_Handler_initialization();
+
+  rtems_bsd_binuptime(&bt);
+  assert(bt.sec == 1);
+  assert(bt.frac== 0);
+
+  rtems_bsd_binuptime(&bt);
+  assert(bt.sec == 1);
+  assert(bt.frac == 0);
+
+  rtems_timecounter_tick();
+  rtems_bsd_binuptime(&bt);
+  assert(bt.sec == 1);
+  assert(bt.frac == 0);
+
+  ctx->tc_soft_counter = 0;
+  tc_soft->tc_get_timecount = test_get_timecount_soft;
+  tc_soft->tc_counter_mask = 0x0fffffff;
+  tc_soft->tc_frequency = soft_freq;
+  tc_soft->tc_quality = 1234;
+  tc_soft->tc_priv = ctx;
+  _Timecounter_Install(tc_soft);
+  assert(ctx->tc_soft_counter == 3);
+
+  rtems_bsd_binuptime(&bt);
+  assert(ctx->tc_soft_counter == 4);
+
+  assert(bt.sec == 1);
+  assert(bt.frac == 18446744073708);
+
+  ctx->tc_soft_counter = 0xf0000000 | 3;
+  rtems_bsd_binuptime(&bt);
+  assert(ctx->tc_soft_counter == (0xf0000000 | 4));
+
+  assert(bt.sec == 1);
+  assert(bt.frac == 18446744073708);
+
+  /* Ensure that the fraction overflows and the second remains constant */
+  ctx->tc_soft_counter = (0xf0000000 | 3) + soft_freq;
+  rtems_bsd_binuptime(&bt);
+  assert(ctx->tc_soft_counter == (0xf0000000 | 4) + soft_freq);
+  assert(bt.sec == 1);
+  assert(bt.frac == 18446742522092);
+
+  rtems_test_endk();
+
+  _Terminate(RTEMS_FATAL_SOURCE_EXIT, false, 0);
+}
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_SCHEDULER_USER
+
+#define CONFIGURE_SCHEDULER_CONTEXT
+
+#define CONFIGURE_SCHEDULER_CONTROLS { }
+
+#define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER 0
+
+#define CONFIGURE_TASK_STACK_ALLOCATOR NULL
+
+#define CONFIGURE_TASK_STACK_DEALLOCATOR NULL
+
+#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
+
+#define CONFIGURE_IDLE_TASK_BODY NULL
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
Index: testsuites/sptests/sptimecounter01/sptimecounter01.scn
===================================================================
--- testsuites/sptests/sptimecounter01/sptimecounter01.scn	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
+++ testsuites/sptests/sptimecounter01/sptimecounter01.scn	(revision 31be41653a659a52460734cb8fe1da27e6d5629e)
@@ -0,0 +1,2 @@
+*** BEGIN OF TEST SPTIMECOUNTER_1 ***
+*** END OF TEST SPTIMECOUNTER_1 ***
