diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-06-20 10:08:39 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-06-21 15:54:18 +0200 |
commit | 9460333e9910471eda010423dcb493f758d997d4 (patch) | |
tree | d479396b21572626f835e0d78794a9811129661a /cpukit/score/cpu | |
parent | bsp/leon3: Fix LEON3_Cpu_Index initialization (diff) | |
download | rtems-9460333e9910471eda010423dcb493f758d997d4.tar.bz2 |
sparc: Rework CPU counter support
Rework CPU counter support to enable use of the GR740 up-counter via
%asr22 and %asr23.
Diffstat (limited to 'cpukit/score/cpu')
-rw-r--r-- | cpukit/score/cpu/sparc/Makefile.am | 1 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/rtems/score/cpu.h | 49 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/sparc-counter-asm.S | 34 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/sparc-counter.c | 30 |
4 files changed, 88 insertions, 26 deletions
diff --git a/cpukit/score/cpu/sparc/Makefile.am b/cpukit/score/cpu/sparc/Makefile.am index edebbb6041..11b5d11d7f 100644 --- a/cpukit/score/cpu/sparc/Makefile.am +++ b/cpukit/score/cpu/sparc/Makefile.am @@ -14,6 +14,7 @@ libscorecpu_a_SOURCES = cpu.c cpu_asm.S libscorecpu_a_SOURCES += sparc-context-volatile-clobber.S libscorecpu_a_SOURCES += sparc-context-validate.S libscorecpu_a_SOURCES += sparc-counter.c +libscorecpu_a_SOURCES += sparc-counter-asm.S libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS) include $(srcdir)/preinstall.am diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h index ea90e36752..c87618db85 100644 --- a/cpukit/score/cpu/sparc/rtems/score/cpu.h +++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h @@ -1304,6 +1304,8 @@ static inline uint32_t CPU_swap_u32( typedef uint32_t CPU_Counter_ticks; +typedef CPU_Counter_ticks ( *SPARC_Counter_read )( void ); + typedef CPU_Counter_ticks (*SPARC_Counter_difference)( CPU_Counter_ticks second, CPU_Counter_ticks first @@ -1311,46 +1313,57 @@ typedef CPU_Counter_ticks (*SPARC_Counter_difference)( /* * The SPARC processors supported by RTEMS have no built-in CPU counter - * support. We have to use some hardware counter module for this purpose. The - * BSP must provide a 32-bit register which contains the current CPU counter - * value and a function for the difference calculation. It can use for example - * the GPTIMER instance used for the clock driver. + * 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. */ typedef struct { - volatile const CPU_Counter_ticks *counter_register; - SPARC_Counter_difference counter_difference; + SPARC_Counter_read counter_read; + SPARC_Counter_difference counter_difference; + volatile const CPU_Counter_ticks *counter_address; } SPARC_Counter; extern SPARC_Counter _SPARC_Counter; +CPU_Counter_ticks _SPARC_Counter_read_address( void ); + +CPU_Counter_ticks _SPARC_Counter_read_asr23( void ); + +CPU_Counter_ticks _SPARC_Counter_difference_normal( + CPU_Counter_ticks second, + CPU_Counter_ticks first +); + +CPU_Counter_ticks _SPARC_Counter_difference_clock_period( + CPU_Counter_ticks second, + CPU_Counter_ticks first +); + /* * 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_default( +CPU_Counter_ticks _SPARC_Counter_difference_one( CPU_Counter_ticks second, CPU_Counter_ticks first ); -static inline bool _SPARC_Counter_is_default( void ) -{ - return _SPARC_Counter.counter_difference - == _SPARC_Counter_difference_default; -} - static inline void _SPARC_Counter_initialize( - volatile const CPU_Counter_ticks *counter_register, - SPARC_Counter_difference counter_difference + SPARC_Counter_read counter_read, + SPARC_Counter_difference counter_difference, + volatile const CPU_Counter_ticks *counter_address ) { - _SPARC_Counter.counter_register = counter_register; + _SPARC_Counter.counter_read = counter_read; _SPARC_Counter.counter_difference = counter_difference; + _SPARC_Counter.counter_address = counter_address; } static inline CPU_Counter_ticks _CPU_Counter_read( void ) { - return *_SPARC_Counter.counter_register; + return ( *_SPARC_Counter.counter_read )(); } static inline CPU_Counter_ticks _CPU_Counter_difference( @@ -1358,7 +1371,7 @@ static inline CPU_Counter_ticks _CPU_Counter_difference( CPU_Counter_ticks first ) { - return (*_SPARC_Counter.counter_difference)( second, first ); + return ( *_SPARC_Counter.counter_difference )( second, first ); } #endif /* ASM */ diff --git a/cpukit/score/cpu/sparc/sparc-counter-asm.S b/cpukit/score/cpu/sparc/sparc-counter-asm.S new file mode 100644 index 0000000000..8ed079f48b --- /dev/null +++ b/cpukit/score/cpu/sparc/sparc-counter-asm.S @@ -0,0 +1,34 @@ +/* + * Copyright (c) 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/asm.h> + + .section ".text" + .align 4 + + PUBLIC(_SPARC_Counter_read_address) +SYM(_SPARC_Counter_read_address): + sethi %hi(_SPARC_Counter + 8), %o0 + ld [%o0 + %lo(_SPARC_Counter + 8)], %o0 + jmp %o7 + 8 + ld [%o0], %o0 + + PUBLIC(_SPARC_Counter_read_asr23) +SYM(_SPARC_Counter_read_asr23): + jmp %o7 + 8 + mov %asr23, %o0 diff --git a/cpukit/score/cpu/sparc/sparc-counter.c b/cpukit/score/cpu/sparc/sparc-counter.c index d254503651..658a47c37e 100644 --- a/cpukit/score/cpu/sparc/sparc-counter.c +++ b/cpukit/score/cpu/sparc/sparc-counter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -17,18 +17,32 @@ #endif #include <rtems/score/cpu.h> +#include <rtems/config.h> -static CPU_Counter_ticks _SPARC_Counter_register_dummy; +CPU_Counter_ticks _SPARC_Counter_difference_normal( + CPU_Counter_ticks second, + CPU_Counter_ticks first +) +{ + return second - first; +} -CPU_Counter_ticks _SPARC_Counter_difference_default( +CPU_Counter_ticks _SPARC_Counter_difference_clock_period( CPU_Counter_ticks second, CPU_Counter_ticks first ) { - return 1; + CPU_Counter_ticks period; + + period = rtems_configuration_get_microseconds_per_tick(); + + return ( first + period - second ) % period; } -SPARC_Counter _SPARC_Counter = { - .counter_register = &_SPARC_Counter_register_dummy, - .counter_difference = _SPARC_Counter_difference_default -}; +CPU_Counter_ticks _SPARC_Counter_difference_one( + CPU_Counter_ticks second, + CPU_Counter_ticks first +) +{ + return 1; +} |