Files
rtems/bsps/sparc/shared/start/sparc-counter-asm.S
Sebastian Huber abb2f8bd66 bsps/leon3: Use custom CPU counter implementation
Merge the timecounter and CPU counter support for the leon3 BSP family.
Remove now unused functions from the CPU counter support of the erc32
and leon3 BSPs.

Update #4954.
2023-10-20 11:16:54 +02:00

152 lines
4.1 KiB
ArmAsm

/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (C) 2016, 2023 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/asm.h>
/*
* All functions except _SPARC_Counter_read_clock() in this module are
* sometimes called with traps disabled.
*/
.section ".text"
.align 4
/*
* This is a workaround for:
* https://gcc.gnu.org/bugzilla//show_bug.cgi?id=69027
*/
PUBLIC(_CPU_Counter_read)
SYM(_CPU_Counter_read):
sethi %hi(_SPARC_Counter + 4), %o1
ld [%o1 + %lo(_SPARC_Counter + 4)], %o1
or %o7, %g0, %g1
call %o1, 0
or %g1, %g0, %o7
#if defined(RTEMS_PROFILING)
/*
* This is a workaround for:
* https://gcc.gnu.org/bugzilla//show_bug.cgi?id=69027
*/
PUBLIC(_SPARC_Counter_read_ISR_disabled)
SYM(_SPARC_Counter_read_ISR_disabled):
sethi %hi(_SPARC_Counter), %o1
ld [%o1 + %lo(_SPARC_Counter)], %o1
or %o7, %g0, %g1
call %o1, 0
or %g1, %g0, %o7
#endif
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
st %o0, [%o1 + %lo(_SPARC_Counter + 12)]
jmp %o7 + 8
nop
/*
* 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
#ifdef __FIX_LEON3FT_TN0018
/* A nop is added to work around the GRLIB-TN-0018 errata */
nop
#endif
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