summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-02-12 10:31:38 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-02-14 10:28:29 +0100
commit24bf11eca11947d961cc9bb5f7d92dabff169e93 (patch)
treeb28f3aa8a21df91e8feaf324613aa76460559837 /cpukit
parentbsps/arm: Fix Cortex-A9 MPCore nanoseconds handler (diff)
downloadrtems-24bf11eca11947d961cc9bb5f7d92dabff169e93.tar.bz2
score: Add CPU counter support
Add a CPU counter interface to allow access to a free-running counter. It is useful to measure short time intervals. This can be used for example to enable profiling of critical low-level functions. Add two busy wait functions rtems_counter_delay_ticks() and rtems_counter_delay_nanoseconds() implemented via the CPU counter.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/sapi/Makefile.am4
-rw-r--r--cpukit/sapi/include/rtems/counter.h160
-rw-r--r--cpukit/sapi/preinstall.am4
-rw-r--r--cpukit/sapi/src/cpucounterconverter.c39
-rw-r--r--cpukit/sapi/src/delaynano.c27
-rw-r--r--cpukit/sapi/src/delayticks.c35
-rw-r--r--cpukit/score/cpu/arm/rtems/score/cpu.h9
-rw-r--r--cpukit/score/cpu/avr/Makefile.am1
-rw-r--r--cpukit/score/cpu/avr/rtems/score/cpu.h12
-rw-r--r--cpukit/score/cpu/bfin/Makefile.am1
-rw-r--r--cpukit/score/cpu/bfin/rtems/score/cpu.h12
-rw-r--r--cpukit/score/cpu/h8300/Makefile.am1
-rw-r--r--cpukit/score/cpu/h8300/rtems/score/cpu.h12
-rw-r--r--cpukit/score/cpu/i386/Makefile.am1
-rw-r--r--cpukit/score/cpu/i386/rtems/score/cpu.h12
-rw-r--r--cpukit/score/cpu/lm32/Makefile.am1
-rw-r--r--cpukit/score/cpu/lm32/rtems/score/cpu.h12
-rw-r--r--cpukit/score/cpu/m32c/Makefile.am1
-rw-r--r--cpukit/score/cpu/m32c/rtems/score/cpu.h12
-rw-r--r--cpukit/score/cpu/m32r/Makefile.am1
-rw-r--r--cpukit/score/cpu/m32r/rtems/score/cpu.h12
-rw-r--r--cpukit/score/cpu/m68k/Makefile.am1
-rw-r--r--cpukit/score/cpu/m68k/rtems/score/cpu.h12
-rw-r--r--cpukit/score/cpu/mips/Makefile.am1
-rw-r--r--cpukit/score/cpu/mips/rtems/score/cpu.h11
-rw-r--r--cpukit/score/cpu/moxie/Makefile.am1
-rw-r--r--cpukit/score/cpu/moxie/rtems/score/cpu.h12
-rw-r--r--cpukit/score/cpu/nios2/Makefile.am1
-rw-r--r--cpukit/score/cpu/nios2/rtems/score/cpu.h12
-rw-r--r--cpukit/score/cpu/no_cpu/Makefile.am1
-rw-r--r--cpukit/score/cpu/no_cpu/cpucounterread.c27
-rw-r--r--cpukit/score/cpu/no_cpu/rtems/score/cpu.h34
-rw-r--r--cpukit/score/cpu/powerpc/rtems/score/cpu.h24
-rw-r--r--cpukit/score/cpu/sh/Makefile.am1
-rw-r--r--cpukit/score/cpu/sh/rtems/score/cpu.h12
-rw-r--r--cpukit/score/cpu/sparc/rtems/score/cpu.h12
-rw-r--r--cpukit/score/cpu/sparc64/Makefile.am1
-rw-r--r--cpukit/score/cpu/sparc64/rtems/score/cpu.h12
-rw-r--r--cpukit/score/cpu/v850/Makefile.am1
-rw-r--r--cpukit/score/cpu/v850/rtems/score/cpu.h12
40 files changed, 557 insertions, 0 deletions
diff --git a/cpukit/sapi/Makefile.am b/cpukit/sapi/Makefile.am
index 65acfc7a01..63eb60595f 100644
--- a/cpukit/sapi/Makefile.am
+++ b/cpukit/sapi/Makefile.am
@@ -6,6 +6,7 @@ include_rtemsdir = $(includedir)/rtems
include_rtems_HEADERS = include/confdefs.h
include_rtems_HEADERS += include/rtems/chain.h
include_rtems_HEADERS += include/rtems/config.h
+include_rtems_HEADERS += include/rtems/counter.h
include_rtems_HEADERS += include/rtems/extension.h
include_rtems_HEADERS += include/rtems/extensionimpl.h
include_rtems_HEADERS += include/rtems/fatal.h
@@ -32,6 +33,9 @@ libsapi_a_SOURCES = src/debug.c src/extension.c src/extensioncreate.c \
src/chainprependnotify.c src/rbheap.c src/interrtext.c \
src/fatal2.c src/fatalsrctext.c
libsapi_a_SOURCES += src/chainsmp.c
+libsapi_a_SOURCES += src/cpucounterconverter.c
+libsapi_a_SOURCES += src/delayticks.c
+libsapi_a_SOURCES += src/delaynano.c
libsapi_a_CPPFLAGS = $(AM_CPPFLAGS)
include $(srcdir)/preinstall.am
diff --git a/cpukit/sapi/include/rtems/counter.h b/cpukit/sapi/include/rtems/counter.h
new file mode 100644
index 0000000000..31b808ad8b
--- /dev/null
+++ b/cpukit/sapi/include/rtems/counter.h
@@ -0,0 +1,160 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicCounter
+ *
+ * @brief Free-Running Counter and Busy Wait Delay API
+ */
+
+/*
+ * Copyright (c) 2014 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.com/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SAPI_COUNTER_H
+#define _RTEMS_SAPI_COUNTER_H
+
+#include <rtems/score/cpu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ClassicCounter Free-Running Counter and Busy Wait Delay
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * @brief Free-running counter and busy wait delay functions.
+ *
+ * The RTEMS counter is some free-running counter. It ticks usually with a
+ * frequency close to the CPU or system bus clock.
+ *
+ * The counter can be used in case the overhead of the
+ * rtems_clock_get_uptime_nanoseconds() is too high. The step from counter
+ * ticks to/from nanoseconds is explicit in this API unlike to
+ * rtems_clock_get_uptime_nanoseconds() which performs the conversion on each
+ * invocation.
+ *
+ * This counter works without a clock driver and during system initialization.
+ *
+ * The counter can be used to profile low-level operations like SMP locks or
+ * interrupt disabled critical sections. The counter can act also as an
+ * entropy source for a random number generator.
+ *
+ * The period of the counter depends on the actual hardware.
+ *
+ * @{
+ */
+
+/**
+ * @brief Unsigned integer type for counter values.
+ */
+typedef CPU_Counter_ticks rtems_counter_ticks;
+
+/**
+ * @brief Reads the current counter values.
+ *
+ * @return The current counter values.
+ */
+static inline rtems_counter_ticks rtems_counter_read( void )
+{
+ return _CPU_Counter_read();
+}
+
+/**
+ * @brief Returns the difference between the second and first CPU counter
+ * value.
+ *
+ * This operation may be carried out as a modulo operation depending on the
+ * range of the CPU counter device.
+ *
+ * @param[in] second The second CPU counter value.
+ * @param[in] first The first CPU counter value.
+ *
+ * @return Returns second minus first modulo counter period.
+ */
+static inline rtems_counter_ticks rtems_counter_difference(
+ rtems_counter_ticks second,
+ rtems_counter_ticks first
+)
+{
+ return _CPU_Counter_difference( second, first );
+}
+
+/**
+ * brief Converts counter ticks into nanoseconds.
+ *
+ * @param[in] ticks Some counter ticks.
+ *
+ * @return The nanoseconds corresponding to the counter ticks. The value is
+ * rounded up.
+ */
+uint64_t rtems_counter_ticks_to_nanoseconds(
+ rtems_counter_ticks ticks
+);
+
+/**
+ * brief Converts nanoseconds into counter ticks.
+ *
+ * @param[in] nanoseconds Some nanoseconds.
+ *
+ * @return The counter ticks corresponding to the nanoseconds. The value is
+ * rounded up.
+ */
+rtems_counter_ticks rtems_counter_nanoseconds_to_ticks(
+ uint32_t nanoseconds
+);
+
+/**
+ * brief Initializes the counter ticks to/from nanoseconds converter functions.
+ *
+ * This function must be used to initialize the
+ * rtems_counter_ticks_to_nanoseconds() and
+ * rtems_counter_nanoseconds_to_ticks() functions. It should be called during
+ * system initialization by the board support package.
+ *
+ * @param[in] uint32_t frequency The current counter frequency in Hz.
+ */
+void rtems_counter_initialize_converter( uint32_t frequency );
+
+/**
+ * @brief Busy wait for some counter ticks.
+ *
+ * This function does not disable interrupts. Thus task switches and
+ * interrupts can interfere with this busy wait may prolong the delay. This
+ * function busy waits at least the specified time. Due to some overhead the
+ * actual delay may be longer.
+ *
+ * @param[in] ticks The minimum busy wait time in counter ticks.
+ */
+void rtems_counter_delay_ticks( rtems_counter_ticks ticks );
+
+/**
+ * @brief Busy wait for some nanoseconds.
+ *
+ * This function does not disable interrupts. Thus task switches and
+ * interrupts can interfere with this busy wait may prolong the delay. This
+ * function busy waits at least the specified time. Due to some overhead the
+ * actual delay may be longer.
+ *
+ * @param[in] nanoseconds The minimum busy wait time in nanoseconds.
+ */
+void rtems_counter_delay_nanoseconds( uint32_t nanoseconds );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SAPI_COUNTER_H */
diff --git a/cpukit/sapi/preinstall.am b/cpukit/sapi/preinstall.am
index 2b247bce58..79eceef405 100644
--- a/cpukit/sapi/preinstall.am
+++ b/cpukit/sapi/preinstall.am
@@ -40,6 +40,10 @@ $(PROJECT_INCLUDE)/rtems/config.h: include/rtems/config.h $(PROJECT_INCLUDE)/rte
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/config.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/config.h
+$(PROJECT_INCLUDE)/rtems/counter.h: include/rtems/counter.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/counter.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/counter.h
+
$(PROJECT_INCLUDE)/rtems/extension.h: include/rtems/extension.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/extension.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/extension.h
diff --git a/cpukit/sapi/src/cpucounterconverter.c b/cpukit/sapi/src/cpucounterconverter.c
new file mode 100644
index 0000000000..5b03d3c7a1
--- /dev/null
+++ b/cpukit/sapi/src/cpucounterconverter.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014 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.com/license/LICENSE.
+ */
+
+#include <rtems/counter.h>
+
+RTEMS_STATIC_ASSERT(sizeof(rtems_counter_ticks) <= sizeof(uint32_t), type);
+
+static uint64_t to_ns_scaler = UINT64_C(1) << 32;
+
+static uint64_t from_ns_scaler = UINT64_C(1) << 32;
+
+uint64_t rtems_counter_ticks_to_nanoseconds( rtems_counter_ticks counter )
+{
+ return (uint32_t) ((counter * to_ns_scaler) >> 32);
+}
+
+rtems_counter_ticks rtems_counter_nanoseconds_to_ticks( uint32_t nanoseconds )
+{
+ return (rtems_counter_ticks) ((nanoseconds * from_ns_scaler) >> 32);
+}
+
+void rtems_counter_initialize_converter( uint32_t frequency )
+{
+ uint64_t ns_per_s = UINT64_C(1000000000);
+
+ to_ns_scaler = ((ns_per_s << 32) + frequency - 1) / frequency;
+ from_ns_scaler = ((UINT64_C(1) << 32) * frequency + ns_per_s - 1) / ns_per_s;
+}
diff --git a/cpukit/sapi/src/delaynano.c b/cpukit/sapi/src/delaynano.c
new file mode 100644
index 0000000000..f8a49e2da8
--- /dev/null
+++ b/cpukit/sapi/src/delaynano.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2014 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.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/counter.h>
+
+void rtems_counter_delay_nanoseconds( uint32_t nanoseconds )
+{
+ rtems_counter_ticks ticks =
+ rtems_counter_nanoseconds_to_ticks( nanoseconds );
+
+ rtems_counter_delay_ticks( ticks );
+}
diff --git a/cpukit/sapi/src/delayticks.c b/cpukit/sapi/src/delayticks.c
new file mode 100644
index 0000000000..45198adecb
--- /dev/null
+++ b/cpukit/sapi/src/delayticks.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 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.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/counter.h>
+
+void rtems_counter_delay_ticks( rtems_counter_ticks ticks )
+{
+ rtems_counter_ticks a = rtems_counter_read();
+ rtems_counter_ticks delta = 0;
+
+ do {
+ rtems_counter_ticks b;
+
+ ticks -= delta;
+
+ b = rtems_counter_read();
+ delta = rtems_counter_difference( b, a );
+ a = b;
+ } while ( ticks > delta );
+}
diff --git a/cpukit/score/cpu/arm/rtems/score/cpu.h b/cpukit/score/cpu/arm/rtems/score/cpu.h
index a2498aa489..b423dbac0a 100644
--- a/cpukit/score/cpu/arm/rtems/score/cpu.h
+++ b/cpukit/score/cpu/arm/rtems/score/cpu.h
@@ -555,6 +555,15 @@ static inline uint16_t CPU_swap_u16( uint16_t value )
#endif
}
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+);
+
#if CPU_PROVIDES_IDLE_THREAD_BODY == TRUE
void *_CPU_Thread_Idle_body( uintptr_t ignored );
#endif
diff --git a/cpukit/score/cpu/avr/Makefile.am b/cpukit/score/cpu/avr/Makefile.am
index bb5ce35331..10ab19b195 100644
--- a/cpukit/score/cpu/avr/Makefile.am
+++ b/cpukit/score/cpu/avr/Makefile.am
@@ -162,6 +162,7 @@ include_rtems_avr_HEADERS += avr/wdt.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c cpu_asm.S
+libscorecpu_a_SOURCES += ../no_cpu/cpucounterread.c
libscorecpu_a_SOURCES += avr-exception-frame-print.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/cpukit/score/cpu/avr/rtems/score/cpu.h b/cpukit/score/cpu/avr/rtems/score/cpu.h
index f82b7637d3..324f48cfae 100644
--- a/cpukit/score/cpu/avr/rtems/score/cpu.h
+++ b/cpukit/score/cpu/avr/rtems/score/cpu.h
@@ -1180,6 +1180,18 @@ static inline uint32_t CPU_swap_u32(
#define CPU_swap_u16( value ) \
(((value&0xff) << 8) | ((value >> 8)&0xff))
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
#endif /* ASM */
#ifdef __cplusplus
diff --git a/cpukit/score/cpu/bfin/Makefile.am b/cpukit/score/cpu/bfin/Makefile.am
index 48dfed4203..cc0bddb732 100644
--- a/cpukit/score/cpu/bfin/Makefile.am
+++ b/cpukit/score/cpu/bfin/Makefile.am
@@ -17,6 +17,7 @@ include_rtems_score_HEADERS += rtems/score/cpuatomic.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c cpu_asm.S
+libscorecpu_a_SOURCES += ../no_cpu/cpucounterread.c
libscorecpu_a_SOURCES += bfin-exception-frame-print.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/cpukit/score/cpu/bfin/rtems/score/cpu.h b/cpukit/score/cpu/bfin/rtems/score/cpu.h
index a8c60a5c44..1f7faa2dcf 100644
--- a/cpukit/score/cpu/bfin/rtems/score/cpu.h
+++ b/cpukit/score/cpu/bfin/rtems/score/cpu.h
@@ -1280,6 +1280,18 @@ static inline uint32_t CPU_swap_u32(
#define CPU_swap_u16( value ) \
(((value&0xff) << 8) | ((value >> 8)&0xff))
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
#endif /* ASM */
#ifdef __cplusplus
diff --git a/cpukit/score/cpu/h8300/Makefile.am b/cpukit/score/cpu/h8300/Makefile.am
index db04025581..6a80409fe1 100644
--- a/cpukit/score/cpu/h8300/Makefile.am
+++ b/cpukit/score/cpu/h8300/Makefile.am
@@ -11,6 +11,7 @@ include_rtems_score_HEADERS += rtems/score/cpuatomic.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c cpu_asm.S
+libscorecpu_a_SOURCES += ../no_cpu/cpucounterread.c
libscorecpu_a_SOURCES += h8300-exception-frame-print.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/cpukit/score/cpu/h8300/rtems/score/cpu.h b/cpukit/score/cpu/h8300/rtems/score/cpu.h
index 66774d4039..e73a974f9f 100644
--- a/cpukit/score/cpu/h8300/rtems/score/cpu.h
+++ b/cpukit/score/cpu/h8300/rtems/score/cpu.h
@@ -1162,6 +1162,18 @@ static inline uint32_t CPU_swap_u32(
#define CPU_swap_u16( value ) \
(((value&0xff) << 8) | ((value >> 8)&0xff))
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
/* to be provided by the BSP */
extern void H8BD_Install_IRQ(
uint32_t vector,
diff --git a/cpukit/score/cpu/i386/Makefile.am b/cpukit/score/cpu/i386/Makefile.am
index e35a81c333..bfc45c56e6 100644
--- a/cpukit/score/cpu/i386/Makefile.am
+++ b/cpukit/score/cpu/i386/Makefile.am
@@ -15,6 +15,7 @@ include_rtems_score_HEADERS += rtems/score/cpusmplock.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c cpu_asm.S
+libscorecpu_a_SOURCES += ../no_cpu/cpucounterread.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
include $(srcdir)/preinstall.am
diff --git a/cpukit/score/cpu/i386/rtems/score/cpu.h b/cpukit/score/cpu/i386/rtems/score/cpu.h
index b308ccf531..4fe254c171 100644
--- a/cpukit/score/cpu/i386/rtems/score/cpu.h
+++ b/cpukit/score/cpu/i386/rtems/score/cpu.h
@@ -694,6 +694,18 @@ static inline void _CPU_Context_validate( uintptr_t pattern )
void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
#endif /* ASM */
#ifdef __cplusplus
diff --git a/cpukit/score/cpu/lm32/Makefile.am b/cpukit/score/cpu/lm32/Makefile.am
index 51be260ce7..fdbd83ce02 100644
--- a/cpukit/score/cpu/lm32/Makefile.am
+++ b/cpukit/score/cpu/lm32/Makefile.am
@@ -12,6 +12,7 @@ include_rtems_score_HEADERS += rtems/score/cpuatomic.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c cpu_asm.S irq.c
+libscorecpu_a_SOURCES += ../no_cpu/cpucounterread.c
libscorecpu_a_SOURCES += lm32-exception-frame-print.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/cpukit/score/cpu/lm32/rtems/score/cpu.h b/cpukit/score/cpu/lm32/rtems/score/cpu.h
index 4699c1a226..ad888f85bf 100644
--- a/cpukit/score/cpu/lm32/rtems/score/cpu.h
+++ b/cpukit/score/cpu/lm32/rtems/score/cpu.h
@@ -1282,6 +1282,18 @@ static inline uint16_t CPU_swap_u16(uint16_t v)
return v << 8 | v >> 8;
}
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/m32c/Makefile.am b/cpukit/score/cpu/m32c/Makefile.am
index 469df12d5c..7f284b271f 100644
--- a/cpukit/score/cpu/m32c/Makefile.am
+++ b/cpukit/score/cpu/m32c/Makefile.am
@@ -15,6 +15,7 @@ include_rtems_score_HEADERS += rtems/score/cpuatomic.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c cpu_asm.c context_switch.S context_init.c \
varvects.S
+libscorecpu_a_SOURCES += ../no_cpu/cpucounterread.c
libscorecpu_a_SOURCES += m32c-exception-frame-print.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/cpukit/score/cpu/m32c/rtems/score/cpu.h b/cpukit/score/cpu/m32c/rtems/score/cpu.h
index 681fb4bcd0..7b615a287d 100644
--- a/cpukit/score/cpu/m32c/rtems/score/cpu.h
+++ b/cpukit/score/cpu/m32c/rtems/score/cpu.h
@@ -1233,6 +1233,18 @@ static inline uint32_t CPU_swap_u32(
#define CPU_swap_u16( value ) \
(((value&0xff) << 8) | ((value >> 8)&0xff))
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/m32r/Makefile.am b/cpukit/score/cpu/m32r/Makefile.am
index 81ee9ac8c6..dcf0871d9d 100644
--- a/cpukit/score/cpu/m32r/Makefile.am
+++ b/cpukit/score/cpu/m32r/Makefile.am
@@ -14,6 +14,7 @@ include_rtems_score_HEADERS += rtems/score/cpuatomic.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c cpu_asm.c context_switch.S context_init.c
+libscorecpu_a_SOURCES += ../no_cpu/cpucounterread.c
libscorecpu_a_SOURCES += m32r-exception-frame-print.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/cpukit/score/cpu/m32r/rtems/score/cpu.h b/cpukit/score/cpu/m32r/rtems/score/cpu.h
index 95a897a1e2..b846b6e83a 100644
--- a/cpukit/score/cpu/m32r/rtems/score/cpu.h
+++ b/cpukit/score/cpu/m32r/rtems/score/cpu.h
@@ -1274,6 +1274,18 @@ static inline uint32_t CPU_swap_u32(
#define CPU_swap_u16( value ) \
(((value&0xff) << 8) | ((value >> 8)&0xff))
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/m68k/Makefile.am b/cpukit/score/cpu/m68k/Makefile.am
index 9d8d333dab..360dca784a 100644
--- a/cpukit/score/cpu/m68k/Makefile.am
+++ b/cpukit/score/cpu/m68k/Makefile.am
@@ -19,6 +19,7 @@ include_rtems_score_HEADERS += rtems/score/types.h
include_rtems_score_HEADERS += rtems/score/cpuatomic.h
libscorecpu_a_SOURCES = cpu.c cpu_asm.S
+libscorecpu_a_SOURCES += ../no_cpu/cpucounterread.c
libscorecpu_a_SOURCES += m68k-exception-frame-print.c
libscorecpu_a_SOURCES += __m68k_read_tp.c
diff --git a/cpukit/score/cpu/m68k/rtems/score/cpu.h b/cpukit/score/cpu/m68k/rtems/score/cpu.h
index 9981f5393d..d73b53586e 100644
--- a/cpukit/score/cpu/m68k/rtems/score/cpu.h
+++ b/cpukit/score/cpu/m68k/rtems/score/cpu.h
@@ -723,6 +723,18 @@ void _CPU_Exception_frame_print(
const CPU_Exception_frame *frame
);
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
#if (M68K_HAS_FPSP_PACKAGE == 1)
/*
* Hooks for the Floating Point Support Package (FPSP) provided by Motorola
diff --git a/cpukit/score/cpu/mips/Makefile.am b/cpukit/score/cpu/mips/Makefile.am
index 7a06faecc5..de4d957986 100644
--- a/cpukit/score/cpu/mips/Makefile.am
+++ b/cpukit/score/cpu/mips/Makefile.am
@@ -15,6 +15,7 @@ include_rtems_score_HEADERS += rtems/score/cpuatomic.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c cpu_asm.S
+libscorecpu_a_SOURCES += ../no_cpu/cpucounterread.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
include $(srcdir)/preinstall.am
diff --git a/cpukit/score/cpu/mips/rtems/score/cpu.h b/cpukit/score/cpu/mips/rtems/score/cpu.h
index 629996117a..2f7c12a381 100644
--- a/cpukit/score/cpu/mips/rtems/score/cpu.h
+++ b/cpukit/score/cpu/mips/rtems/score/cpu.h
@@ -1193,6 +1193,17 @@ static inline uint32_t CPU_swap_u32(
#define CPU_swap_u16( value ) \
(((value&0xff) << 8) | ((value >> 8)&0xff))
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
#endif
diff --git a/cpukit/score/cpu/moxie/Makefile.am b/cpukit/score/cpu/moxie/Makefile.am
index a4fb31be63..209a077010 100644
--- a/cpukit/score/cpu/moxie/Makefile.am
+++ b/cpukit/score/cpu/moxie/Makefile.am
@@ -14,6 +14,7 @@ include_rtems_score_HEADERS += rtems/score/cpuatomic.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c moxie-exception-frame-print.c cpu_asm.S
+libscorecpu_a_SOURCES += ../no_cpu/cpucounterread.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
include $(srcdir)/preinstall.am
diff --git a/cpukit/score/cpu/moxie/rtems/score/cpu.h b/cpukit/score/cpu/moxie/rtems/score/cpu.h
index 36a956cdc8..f8633516da 100644
--- a/cpukit/score/cpu/moxie/rtems/score/cpu.h
+++ b/cpukit/score/cpu/moxie/rtems/score/cpu.h
@@ -1049,6 +1049,18 @@ static inline uint32_t CPU_swap_u32(
#define CPU_swap_u16( value ) \
(((value&0xff) << 8) | ((value >> 8)&0xff))
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/nios2/Makefile.am b/cpukit/score/cpu/nios2/Makefile.am
index 6fdc786a2c..62286cd754 100644
--- a/cpukit/score/cpu/nios2/Makefile.am
+++ b/cpukit/score/cpu/nios2/Makefile.am
@@ -21,6 +21,7 @@ include_rtems_score_HEADERS += rtems/score/cpuatomic.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES =
+libscorecpu_a_SOURCES += ../no_cpu/cpucounterread.c
libscorecpu_a_SOURCES += nios2-context-initialize.c
libscorecpu_a_SOURCES += nios2-context-switch.S
libscorecpu_a_SOURCES += nios2-context-validate.S
diff --git a/cpukit/score/cpu/nios2/rtems/score/cpu.h b/cpukit/score/cpu/nios2/rtems/score/cpu.h
index bdd8f57e96..3a4cb50806 100644
--- a/cpukit/score/cpu/nios2/rtems/score/cpu.h
+++ b/cpukit/score/cpu/nios2/rtems/score/cpu.h
@@ -364,6 +364,18 @@ static inline uint32_t CPU_swap_u32( uint32_t value )
#define CPU_swap_u16( value ) \
(((value&0xff) << 8) | ((value >> 8)&0xff))
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
#endif /* ASM */
#ifdef __cplusplus
diff --git a/cpukit/score/cpu/no_cpu/Makefile.am b/cpukit/score/cpu/no_cpu/Makefile.am
index 24517431e7..4c812575e9 100644
--- a/cpukit/score/cpu/no_cpu/Makefile.am
+++ b/cpukit/score/cpu/no_cpu/Makefile.am
@@ -12,6 +12,7 @@ include_rtems_score_HEADERS += rtems/score/cpusmplock.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c cpu_asm.c
+libscorecpu_a_SOURCES += cpucounterread.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
include $(srcdir)/preinstall.am
diff --git a/cpukit/score/cpu/no_cpu/cpucounterread.c b/cpukit/score/cpu/no_cpu/cpucounterread.c
new file mode 100644
index 0000000000..0a09376b63
--- /dev/null
+++ b/cpukit/score/cpu/no_cpu/cpucounterread.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2014 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.com/license/LICENSE.
+ */
+
+#include <rtems/score/cpu.h>
+
+CPU_Counter_ticks _CPU_Counter_read( void )
+{
+ static CPU_Counter_ticks counter;
+
+ CPU_Counter_ticks snapshot;
+
+ snapshot = counter;
+ counter = snapshot + 1;
+
+ return snapshot;
+}
diff --git a/cpukit/score/cpu/no_cpu/rtems/score/cpu.h b/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
index 783da76dee..9fdc7fc5a2 100644
--- a/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
+++ b/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
@@ -1426,6 +1426,40 @@ static inline uint32_t CPU_swap_u32(
#define CPU_swap_u16( value ) \
(((value&0xff) << 8) | ((value >> 8)&0xff))
+/**
+ * @brief Unsigned integer type for CPU counter values.
+ */
+typedef uint32_t CPU_Counter_ticks;
+
+/**
+ * @brief Returns the current CPU counter value.
+ *
+ * A CPU counter is some free-running counter. It ticks usually with a
+ * frequency close to the CPU or system bus clock. The board support package
+ * must ensure that this function works before the RTEMS initialization.
+ * Otherwise invalid profiling statistics will be gathered.
+ *
+ * @return The current CPU counter value.
+ */
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+/**
+ * @brief Returns the difference between the second and first CPU counter
+ * value.
+ *
+ * This operation may be carried out as a modulo operation depending on the
+ * range of the CPU counter device.
+ *
+ * @param[in] second The second CPU counter value.
+ * @param[in] first The first CPU counter value.
+ *
+ * @return Returns second minus first modulo counter period.
+ */
+CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+);
+
#ifdef RTEMS_SMP
/**
* @brief Returns the index of the current processor.
diff --git a/cpukit/score/cpu/powerpc/rtems/score/cpu.h b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
index 45b8827235..647c665ee6 100644
--- a/cpukit/score/cpu/powerpc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
@@ -769,6 +769,30 @@ static inline uint32_t CPU_swap_u32(
#define CPU_swap_u16( value ) \
(((value&0xff) << 8) | ((value >> 8)&0xff))
+typedef uint32_t CPU_Counter_ticks;
+
+static inline CPU_Counter_ticks _CPU_Counter_read( void )
+{
+ CPU_Counter_ticks value;
+
+#ifdef ppc8540
+ /* Book E has no mftb */
+ __asm__ volatile( "mfspr %0, 268" : "=r" (value) );
+#else
+ __asm__ volatile( "mftb %0" : "=r" (value) );
+#endif
+
+ return value;
+}
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
#endif /* ASM */
diff --git a/cpukit/score/cpu/sh/Makefile.am b/cpukit/score/cpu/sh/Makefile.am
index 7eb229795f..68be19fffa 100644
--- a/cpukit/score/cpu/sh/Makefile.am
+++ b/cpukit/score/cpu/sh/Makefile.am
@@ -12,6 +12,7 @@ include_rtems_score_HEADERS += rtems/score/cpuatomic.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c context.c
+libscorecpu_a_SOURCES += ../no_cpu/cpucounterread.c
libscorecpu_a_SOURCES += sh-exception-frame-print.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/cpukit/score/cpu/sh/rtems/score/cpu.h b/cpukit/score/cpu/sh/rtems/score/cpu.h
index ff9ad55ae4..f228c4060d 100644
--- a/cpukit/score/cpu/sh/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sh/rtems/score/cpu.h
@@ -910,6 +910,18 @@ typedef CPU_Interrupt_frame CPU_Exception_frame;
void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h
index 7e54d2257f..6246b9158e 100644
--- a/cpukit/score/cpu/sparc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h
@@ -1269,6 +1269,18 @@ static inline uint32_t CPU_swap_u32(
#define CPU_swap_u16( value ) \
(((value&0xff) << 8) | ((value >> 8)&0xff))
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
#endif /* ASM */
#ifdef __cplusplus
diff --git a/cpukit/score/cpu/sparc64/Makefile.am b/cpukit/score/cpu/sparc64/Makefile.am
index 02babb4c60..01230661fb 100644
--- a/cpukit/score/cpu/sparc64/Makefile.am
+++ b/cpukit/score/cpu/sparc64/Makefile.am
@@ -14,6 +14,7 @@ include_rtems_score_HEADERS += rtems/score/cpuatomic.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = context.S cpu.c
+libscorecpu_a_SOURCES += ../no_cpu/cpucounterread.c
libscorecpu_a_SOURCES += sparc64-exception-frame-print.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/cpukit/score/cpu/sparc64/rtems/score/cpu.h b/cpukit/score/cpu/sparc64/rtems/score/cpu.h
index 22ec97d17a..616c665da1 100644
--- a/cpukit/score/cpu/sparc64/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc64/rtems/score/cpu.h
@@ -1089,6 +1089,18 @@ static inline uint32_t CPU_swap_u32(
#define CPU_swap_u16( value ) \
(((value&0xff) << 8) | ((value >> 8)&0xff))
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
#endif /* ASM */
#ifdef __cplusplus
diff --git a/cpukit/score/cpu/v850/Makefile.am b/cpukit/score/cpu/v850/Makefile.am
index c873bae591..c1baae7b52 100644
--- a/cpukit/score/cpu/v850/Makefile.am
+++ b/cpukit/score/cpu/v850/Makefile.am
@@ -12,6 +12,7 @@ include_rtems_score_HEADERS += rtems/score/cpuatomic.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c
libscorecpu_a_SOURCES += cpu_asm.S
+libscorecpu_a_SOURCES += ../no_cpu/cpucounterread.c
libscorecpu_a_SOURCES += v850-exception-frame-print.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/cpukit/score/cpu/v850/rtems/score/cpu.h b/cpukit/score/cpu/v850/rtems/score/cpu.h
index f41bde0953..18f722f2bd 100644
--- a/cpukit/score/cpu/v850/rtems/score/cpu.h
+++ b/cpukit/score/cpu/v850/rtems/score/cpu.h
@@ -1233,6 +1233,18 @@ static inline uint16_t CPU_swap_u16( uint16_t value )
return swapped;
}
+typedef uint32_t CPU_Counter_ticks;
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
#ifdef __cplusplus
}
#endif