summaryrefslogtreecommitdiffstats
path: root/cpukit/score
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score')
-rw-r--r--cpukit/score/cpu/no_cpu/include/rtems/score/cpu.h7
-rw-r--r--cpukit/score/cpu/or1k/include/rtems/score/cpu.h7
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/cpu.h23
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h61
-rw-r--r--cpukit/score/cpu/sparc/sparc-counter-asm.S105
-rw-r--r--cpukit/score/cpu/sparc/sparc-counter.c48
6 files changed, 150 insertions, 101 deletions
diff --git a/cpukit/score/cpu/no_cpu/include/rtems/score/cpu.h b/cpukit/score/cpu/no_cpu/include/rtems/score/cpu.h
index 7ab09d990e..6b6094ae10 100644
--- a/cpukit/score/cpu/no_cpu/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/no_cpu/include/rtems/score/cpu.h
@@ -1219,10 +1219,13 @@ CPU_Counter_ticks _CPU_Counter_read( void );
*
* @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
/**
diff --git a/cpukit/score/cpu/or1k/include/rtems/score/cpu.h b/cpukit/score/cpu/or1k/include/rtems/score/cpu.h
index 0d1566a0c9..663a1755ba 100644
--- a/cpukit/score/cpu/or1k/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/or1k/include/rtems/score/cpu.h
@@ -712,10 +712,13 @@ uint32_t _CPU_Counter_frequency( void );
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. */
typedef uintptr_t CPU_Uint32ptr;
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/cpu.h b/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
index 252aa4026e..abc813cfa5 100644
--- a/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
@@ -1103,29 +1103,28 @@ uint32_t _CPU_Counter_frequency( void );
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;
extern const SPARC_Counter _SPARC_Counter;
static inline CPU_Counter_ticks _CPU_Counter_read( void )
{
- return ( *_SPARC_Counter.counter_read )();
+ return ( *_SPARC_Counter.read )();
}
static inline CPU_Counter_ticks _CPU_Counter_difference(
@@ -1133,7 +1132,7 @@ static inline CPU_Counter_ticks _CPU_Counter_difference(
CPU_Counter_ticks first
)
{
- return ( *_SPARC_Counter.counter_difference )( second, first );
+ return second - first;
}
/** Type that can store a 32-bit integer or a pointer. */
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h b/cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h
index 81b4441b25..edc03bd074 100644
--- a/cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h
+++ b/cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2016, 2018 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -21,6 +21,8 @@
extern "C" {
#endif /* __cplusplus */
+struct timecounter;
+
/*
* Provides a mutable alias to _SPARC_Counter for use in
* _SPARC_Counter_initialize(). The _SPARC_Counter and _SPARC_Counter_mutable
@@ -28,40 +30,27 @@ extern "C" {
*/
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
-);
-
-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_clock( struct timecounter * );
+
+uint32_t _SPARC_Get_timecount_asr23( struct timecounter * );
/*
* Defines the _SPARC_Counter and _SPARC_Counter_mutable global variables.
@@ -75,12 +64,16 @@ static inline void _SPARC_Counter_initialize(
"\t.section\t.data._SPARC_Counter,\"aw\",@progbits\n" \
"\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" \
)
diff --git a/cpukit/score/cpu/sparc/sparc-counter-asm.S b/cpukit/score/cpu/sparc/sparc-counter-asm.S
index 8ed079f48b..6f3e61c12b 100644
--- a/cpukit/score/cpu/sparc/sparc-counter-asm.S
+++ b/cpukit/score/cpu/sparc/sparc-counter-asm.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2016, 2018 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -18,17 +18,116 @@
#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
jmp %o7 + 8
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
diff --git a/cpukit/score/cpu/sparc/sparc-counter.c b/cpukit/score/cpu/sparc/sparc-counter.c
deleted file mode 100644
index 9bc4061e9e..0000000000
--- a/cpukit/score/cpu/sparc/sparc-counter.c
+++ /dev/null
@@ -1,48 +0,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;
-}