Index: cpukit/Makefile.am
===================================================================
--- cpukit/Makefile.am	(revision ef23838543337105de4070ff2ef0d45b078f6812)
+++ cpukit/Makefile.am	(revision 0a1f5df98e52b028bf8b4de3bf63e39702fa5f34)
@@ -1754,5 +1754,4 @@
 librtemscpu_a_SOURCES += score/cpu/sparc/sparc-context-volatile-clobber.S
 librtemscpu_a_SOURCES += score/cpu/sparc/sparc-counter-asm.S
-librtemscpu_a_SOURCES += score/cpu/sparc/sparc-counter.c
 librtemscpu_a_SOURCES += score/cpu/sparc/syscall.S
 librtemscpu_a_SOURCES += score/cpu/sparc/window.S
Index: cpukit/score/cpu/no_cpu/include/rtems/score/cpu.h
===================================================================
--- cpukit/score/cpu/no_cpu/include/rtems/score/cpu.h	(revision ef23838543337105de4070ff2ef0d45b078f6812)
+++ cpukit/score/cpu/no_cpu/include/rtems/score/cpu.h	(revision 0a1f5df98e52b028bf8b4de3bf63e39702fa5f34)
@@ -1220,8 +1220,11 @@
  * @return Returns second minus first modulo counter period.
  */
-CPU_Counter_ticks _CPU_Counter_difference(
+static inline CPU_Counter_ticks _CPU_Counter_difference(
   CPU_Counter_ticks second,
   CPU_Counter_ticks first
-);
+)
+{
+  return second - first;
+}
 
 #ifdef RTEMS_SMP
Index: cpukit/score/cpu/or1k/include/rtems/score/cpu.h
===================================================================
--- cpukit/score/cpu/or1k/include/rtems/score/cpu.h	(revision ef23838543337105de4070ff2ef0d45b078f6812)
+++ cpukit/score/cpu/or1k/include/rtems/score/cpu.h	(revision 0a1f5df98e52b028bf8b4de3bf63e39702fa5f34)
@@ -713,8 +713,11 @@
 CPU_Counter_ticks _CPU_Counter_read( void );
 
-CPU_Counter_ticks _CPU_Counter_difference(
+static inline CPU_Counter_ticks _CPU_Counter_difference(
   CPU_Counter_ticks second,
   CPU_Counter_ticks first
-);
+)
+{
+  return second - first;
+}
 
 /** Type that can store a 32-bit integer or a pointer. */
Index: cpukit/score/cpu/sparc/include/rtems/score/cpu.h
===================================================================
--- cpukit/score/cpu/sparc/include/rtems/score/cpu.h	(revision ef23838543337105de4070ff2ef0d45b078f6812)
+++ cpukit/score/cpu/sparc/include/rtems/score/cpu.h	(revision 0a1f5df98e52b028bf8b4de3bf63e39702fa5f34)
@@ -1104,20 +1104,19 @@
 typedef CPU_Counter_ticks ( *SPARC_Counter_read )( void );
 
-typedef CPU_Counter_ticks ( *SPARC_Counter_difference )(
-  CPU_Counter_ticks second,
-  CPU_Counter_ticks first
-);
-
 /*
  * The SPARC processors supported by RTEMS have no built-in CPU counter
  * support.  We have to use some hardware counter module for this purpose, for
  * example the GPTIMER instance used by the clock driver.  The BSP must provide
- * an implementation of the CPU counter read and difference functions.  This
- * allows the use of dynamic hardware enumeration.
+ * an implementation of the CPU counter read function.  This allows the use of
+ * dynamic hardware enumeration.
  */
 typedef struct {
-  SPARC_Counter_read                counter_read;
-  SPARC_Counter_difference          counter_difference;
-  volatile const CPU_Counter_ticks *counter_address;
+  SPARC_Counter_read                read_isr_disabled;
+  SPARC_Counter_read                read;
+  volatile const CPU_Counter_ticks *counter_register;
+  volatile const uint32_t          *pending_register;
+  uint32_t                          pending_mask;
+  CPU_Counter_ticks                 accumulated;
+  CPU_Counter_ticks                 interval;
 } SPARC_Counter;
 
@@ -1126,5 +1125,5 @@
 static inline CPU_Counter_ticks _CPU_Counter_read( void )
 {
-  return ( *_SPARC_Counter.counter_read )();
+  return ( *_SPARC_Counter.read )();
 }
 
@@ -1134,5 +1133,5 @@
 )
 {
-  return ( *_SPARC_Counter.counter_difference )( second, first );
+  return second - first;
 }
 
Index: cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h
===================================================================
--- cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h	(revision ef23838543337105de4070ff2ef0d45b078f6812)
+++ cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h	(revision 0a1f5df98e52b028bf8b4de3bf63e39702fa5f34)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2016, 2018 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
@@ -22,4 +22,6 @@
 #endif /* __cplusplus */
 
+struct timecounter;
+
 /*
  * Provides a mutable alias to _SPARC_Counter for use in
@@ -29,38 +31,25 @@
 extern SPARC_Counter _SPARC_Counter_mutable;
 
-CPU_Counter_ticks _SPARC_Counter_read_address( void );
+void _SPARC_Counter_at_tick_clock( void );
+
+CPU_Counter_ticks _SPARC_Counter_read_default( void );
+
+CPU_Counter_ticks _SPARC_Counter_read_up( void );
+
+CPU_Counter_ticks _SPARC_Counter_read_down( void );
+
+CPU_Counter_ticks _SPARC_Counter_read_clock_isr_disabled( void );
+
+CPU_Counter_ticks _SPARC_Counter_read_clock( void );
 
 CPU_Counter_ticks _SPARC_Counter_read_asr23( void );
 
-CPU_Counter_ticks _SPARC_Counter_difference_normal(
-  CPU_Counter_ticks second,
-  CPU_Counter_ticks first
-);
+uint32_t _SPARC_Get_timecount_up( struct timecounter * );
 
-CPU_Counter_ticks _SPARC_Counter_difference_clock_period(
-  CPU_Counter_ticks second,
-  CPU_Counter_ticks first
-);
+uint32_t _SPARC_Get_timecount_down( struct timecounter * );
 
-/*
- * Returns always a value of one regardless of the parameters.  This prevents
- * an infinite loop in rtems_counter_delay_ticks().  Its only a reasonably safe
- * default.
- */
-CPU_Counter_ticks _SPARC_Counter_difference_one(
-  CPU_Counter_ticks second,
-  CPU_Counter_ticks first
-);
+uint32_t _SPARC_Get_timecount_clock( struct timecounter * );
 
-static inline void _SPARC_Counter_initialize(
-  SPARC_Counter_read                counter_read,
-  SPARC_Counter_difference          counter_difference,
-  volatile const CPU_Counter_ticks *counter_address
-)
-{
-  _SPARC_Counter_mutable.counter_read = counter_read;
-  _SPARC_Counter_mutable.counter_difference = counter_difference;
-  _SPARC_Counter_mutable.counter_address = counter_address;
-}
+uint32_t _SPARC_Get_timecount_asr23( struct timecounter * );
 
 /*
@@ -76,10 +65,14 @@
     "\t.align\t4\n" \
     "\t.type\t_SPARC_Counter, #object\n" \
-    "\t.size\t_SPARC_Counter, 12\n" \
+    "\t.size\t_SPARC_Counter, 28\n" \
     "_SPARC_Counter:\n" \
     "_SPARC_Counter_mutable:\n" \
-    "\t.long\t_SPARC_Counter_read_address\n" \
-    "\t.long\t_SPARC_Counter_difference_one\n" \
-    "\t.long\t_SPARC_Counter\n" \
+    "\t.long\t_SPARC_Counter_read_default\n" \
+    "\t.long\t_SPARC_Counter_read_default\n" \
+    "\t.long\t0\n" \
+    "\t.long\t0\n" \
+    "\t.long\t0\n" \
+    "\t.long\t0\n" \
+    "\t.long\t0\n" \
     "\t.previous\n" \
   )
Index: cpukit/score/cpu/sparc/sparc-counter-asm.S
===================================================================
--- cpukit/score/cpu/sparc/sparc-counter-asm.S	(revision ef23838543337105de4070ff2ef0d45b078f6812)
+++ cpukit/score/cpu/sparc/sparc-counter-asm.S	(revision 0a1f5df98e52b028bf8b4de3bf63e39702fa5f34)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2016, 2018 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
@@ -19,9 +19,24 @@
 #include <rtems/asm.h>
 
+	/*
+	 * All functions except _SPARC_Counter_read_clock() in this module are
+	 * sometimes called with traps disabled.
+	 */
+
 	.section	".text"
 	.align	4
 
-	PUBLIC(_SPARC_Counter_read_address)
-SYM(_SPARC_Counter_read_address):
+	PUBLIC(_SPARC_Counter_read_default)
+SYM(_SPARC_Counter_read_default):
+	sethi	%hi(_SPARC_Counter + 12), %o1
+	ld	[%o1 + %lo(_SPARC_Counter + 12)], %o0
+	add	%o0, 1, %o0
+	jmp	%o7 + 8
+	 st	%o0, [%o1 + %lo(_SPARC_Counter + 12)]
+
+	PUBLIC(_SPARC_Counter_read_up)
+	PUBLIC(_SPARC_Get_timecount_up)
+SYM(_SPARC_Counter_read_up):
+SYM(_SPARC_Get_timecount_up):
 	sethi	%hi(_SPARC_Counter + 8), %o0
 	ld	[%o0 + %lo(_SPARC_Counter + 8)], %o0
@@ -29,6 +44,90 @@
 	 ld	[%o0], %o0
 
+	PUBLIC(_SPARC_Counter_read_down)
+	PUBLIC(_SPARC_Get_timecount_down)
+SYM(_SPARC_Counter_read_down):
+SYM(_SPARC_Get_timecount_down):
+	sethi	%hi(_SPARC_Counter + 8), %o0
+	ld	[%o0 + %lo(_SPARC_Counter + 8)], %o0
+	ld	[%o0], %o0
+	jmp	%o7 + 8
+	 xnor	%g0, %o0, %o0
+
+	/*
+	 * For the corresponding C code is something like this:
+	 *
+	 * CPU_Counter_ticks _SPARC_Counter_read_clock_isr_disabled( void )
+	 * {
+	 *   const SPARC_Counter *ctr;
+	 *   CPU_Counter_ticks    ticks;
+	 *   CPU_Counter_ticks    accumulated;
+	 *
+	 *   ctr = &_SPARC_Counter;
+	 *   ticks = *ctr->counter_register;
+	 *   accumulated = ctr->accumulated;
+	 *
+	 *   if ( ( *ctr->pending_register & ctr->pending_mask ) != 0 ) {
+	 *     ticks = *ctr->counter_register;
+	 *     accumulated += ctr->interval;
+	 *   }
+	 *
+	 *   return accumulated - ticks;
+	 * }
+	 */
+	PUBLIC(_SPARC_Counter_read_clock_isr_disabled)
+SYM(_SPARC_Counter_read_clock_isr_disabled):
+	sethi	%hi(_SPARC_Counter), %o5
+	or	%o5, %lo(_SPARC_Counter), %o5
+	ld	[%o5 + 8], %o3
+	ld	[%o5 + 12], %o4
+	ld	[%o5 + 16], %o2
+	ld	[%o3], %o0
+	ld	[%o4], %o1
+	btst	%o1, %o2
+	bne	.Lpending_isr_disabled
+	 ld	[%o5 + 20], %o4
+	jmp	%o7 + 8
+	 sub	%o4, %o0, %o0
+.Lpending_isr_disabled:
+	ld	[%o5 + 24], %o5
+	ld	[%o3], %o0
+	add	%o4, %o5, %o4
+	jmp	%o7 + 8
+	 sub	%o4, %o0, %o0
+
+	/*
+	 * For the corresponding C code see
+	 * _SPARC_Counter_read_clock_isr_disabled() above.
+	 */
+	PUBLIC(_SPARC_Counter_read_clock)
+	PUBLIC(_SPARC_Get_timecount_clock)
+SYM(_SPARC_Counter_read_clock):
+SYM(_SPARC_Get_timecount_clock):
+	sethi	%hi(_SPARC_Counter), %o5
+	or	%o5, %lo(_SPARC_Counter), %o5
+	ta	SPARC_SWTRAP_IRQDIS
+	ld	[%o5 + 8], %o3
+	ld	[%o5 + 12], %o4
+	ld	[%o5 + 16], %o2
+	ld	[%o3], %o0
+	ld	[%o4], %o1
+	btst	%o1, %o2
+	bne	.Lpending
+	 ld	[%o5 + 20], %o4
+	ta	SPARC_SWTRAP_IRQEN
+	jmp	%o7 + 8
+	 sub	%o4, %o0, %o0
+.Lpending:
+	ld	[%o5 + 24], %o5
+	ld	[%o3], %o0
+	ta	SPARC_SWTRAP_IRQEN
+	add	%o4, %o5, %o4
+	jmp	%o7 + 8
+	 sub	%o4, %o0, %o0
+
 	PUBLIC(_SPARC_Counter_read_asr23)
+	PUBLIC(_SPARC_Get_timecount_asr23)
 SYM(_SPARC_Counter_read_asr23):
+SYM(_SPARC_Get_timecount_asr23):
 	jmp	%o7 + 8
 	 mov	%asr23, %o0
Index: cpukit/score/cpu/sparc/sparc-counter.c
===================================================================
--- cpukit/score/cpu/sparc/sparc-counter.c	(revision ef23838543337105de4070ff2ef0d45b078f6812)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
- *
- *  embedded brains GmbH
- *  Dornierstr. 4
- *  82178 Puchheim
- *  Germany
- *  <rtems@embedded-brains.de>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-  #include "config.h"
-#endif
-
-#include <rtems/score/sparcimpl.h>
-#include <rtems/config.h>
-
-CPU_Counter_ticks _SPARC_Counter_difference_normal(
-  CPU_Counter_ticks second,
-  CPU_Counter_ticks first
-)
-{
-  return second - first;
-}
-
-CPU_Counter_ticks _SPARC_Counter_difference_clock_period(
-  CPU_Counter_ticks second,
-  CPU_Counter_ticks first
-)
-{
-  CPU_Counter_ticks period;
-
-  period = rtems_configuration_get_microseconds_per_tick();
-
-  return ( first + period - second ) % period;
-}
-
-CPU_Counter_ticks _SPARC_Counter_difference_one(
-  CPU_Counter_ticks second,
-  CPU_Counter_ticks first
-)
-{
-  return 1;
-}
