/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2016, 2018 embedded brains GmbH. All rights reserved.
*
* 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
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
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
#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
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