From 24bf11eca11947d961cc9bb5f7d92dabff169e93 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 12 Feb 2014 10:31:38 +0100 Subject: 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. --- cpukit/sapi/Makefile.am | 4 + cpukit/sapi/include/rtems/counter.h | 160 +++++++++++++++++++++++++++++ cpukit/sapi/preinstall.am | 4 + cpukit/sapi/src/cpucounterconverter.c | 39 +++++++ cpukit/sapi/src/delaynano.c | 27 +++++ cpukit/sapi/src/delayticks.c | 35 +++++++ cpukit/score/cpu/arm/rtems/score/cpu.h | 9 ++ cpukit/score/cpu/avr/Makefile.am | 1 + cpukit/score/cpu/avr/rtems/score/cpu.h | 12 +++ cpukit/score/cpu/bfin/Makefile.am | 1 + cpukit/score/cpu/bfin/rtems/score/cpu.h | 12 +++ cpukit/score/cpu/h8300/Makefile.am | 1 + cpukit/score/cpu/h8300/rtems/score/cpu.h | 12 +++ cpukit/score/cpu/i386/Makefile.am | 1 + cpukit/score/cpu/i386/rtems/score/cpu.h | 12 +++ cpukit/score/cpu/lm32/Makefile.am | 1 + cpukit/score/cpu/lm32/rtems/score/cpu.h | 12 +++ cpukit/score/cpu/m32c/Makefile.am | 1 + cpukit/score/cpu/m32c/rtems/score/cpu.h | 12 +++ cpukit/score/cpu/m32r/Makefile.am | 1 + cpukit/score/cpu/m32r/rtems/score/cpu.h | 12 +++ cpukit/score/cpu/m68k/Makefile.am | 1 + cpukit/score/cpu/m68k/rtems/score/cpu.h | 12 +++ cpukit/score/cpu/mips/Makefile.am | 1 + cpukit/score/cpu/mips/rtems/score/cpu.h | 11 ++ cpukit/score/cpu/moxie/Makefile.am | 1 + cpukit/score/cpu/moxie/rtems/score/cpu.h | 12 +++ cpukit/score/cpu/nios2/Makefile.am | 1 + cpukit/score/cpu/nios2/rtems/score/cpu.h | 12 +++ cpukit/score/cpu/no_cpu/Makefile.am | 1 + cpukit/score/cpu/no_cpu/cpucounterread.c | 27 +++++ cpukit/score/cpu/no_cpu/rtems/score/cpu.h | 34 ++++++ cpukit/score/cpu/powerpc/rtems/score/cpu.h | 24 +++++ cpukit/score/cpu/sh/Makefile.am | 1 + cpukit/score/cpu/sh/rtems/score/cpu.h | 12 +++ cpukit/score/cpu/sparc/rtems/score/cpu.h | 12 +++ cpukit/score/cpu/sparc64/Makefile.am | 1 + cpukit/score/cpu/sparc64/rtems/score/cpu.h | 12 +++ cpukit/score/cpu/v850/Makefile.am | 1 + cpukit/score/cpu/v850/rtems/score/cpu.h | 12 +++ 40 files changed, 557 insertions(+) create mode 100644 cpukit/sapi/include/rtems/counter.h create mode 100644 cpukit/sapi/src/cpucounterconverter.c create mode 100644 cpukit/sapi/src/delaynano.c create mode 100644 cpukit/sapi/src/delayticks.c create mode 100644 cpukit/score/cpu/no_cpu/cpucounterread.c (limited to 'cpukit') 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 + * + * + * 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 + +#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 + * + * + * 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_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 + * + * + * 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 + +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 + * + * + * 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 + +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 + * + * + * 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 + +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 -- cgit v1.2.3