summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/sparc/sparc-counter-asm.S
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-05-03 13:03:27 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-12-07 14:22:01 +0100
commit0a1f5df98e52b028bf8b4de3bf63e39702fa5f34 (patch)
tree7b3d8bfe7a9e760ee2bbb8916d3284f34edfec89 /cpukit/score/cpu/sparc/sparc-counter-asm.S
parentscore: Avoid sbintime_t in API headers (diff)
downloadrtems-0a1f5df98e52b028bf8b4de3bf63e39702fa5f34.tar.bz2
Simplify _CPU_Counter_difference()
In order to simplify the use of CPU counter values it is beneficial to have monotonic increasing values within the range of the CPU counter ticks data type, e.g. 32-bit unsigned integer. This eases the use of CPU counter timestamps in external tools which do not know the details of the CPU counter hardware. The CPU counter is the fastest way to get a time on an RTEMS system. Such a CPU counter may be also used as the timecounter. Use it on SPARC for this purpose to simplify the clock drivers. Update #3456.
Diffstat (limited to 'cpukit/score/cpu/sparc/sparc-counter-asm.S')
-rw-r--r--cpukit/score/cpu/sparc/sparc-counter-asm.S105
1 files changed, 102 insertions, 3 deletions
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