Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:09

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (C) 2016, 2023 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031 
0032 #include <rtems/asm.h>
0033 
0034     /*
0035      * All functions except _SPARC_Counter_read_clock() in this module are
0036      * sometimes called with traps disabled.
0037      */
0038 
0039     .section    ".text"
0040     .align  4
0041 
0042     /*
0043      * This is a workaround for:
0044      * https://gcc.gnu.org/bugzilla//show_bug.cgi?id=69027
0045      */
0046     PUBLIC(_CPU_Counter_read)
0047 SYM(_CPU_Counter_read):
0048     sethi   %hi(_SPARC_Counter + 4), %o1
0049     ld  [%o1 + %lo(_SPARC_Counter + 4)], %o1
0050     or  %o7, %g0, %g1
0051     call    %o1, 0
0052      or %g1, %g0, %o7
0053 
0054 #if defined(RTEMS_PROFILING)
0055     /*
0056      * This is a workaround for:
0057      * https://gcc.gnu.org/bugzilla//show_bug.cgi?id=69027
0058      */
0059     PUBLIC(_SPARC_Counter_read_ISR_disabled)
0060 SYM(_SPARC_Counter_read_ISR_disabled):
0061     sethi   %hi(_SPARC_Counter), %o1
0062     ld  [%o1 + %lo(_SPARC_Counter)], %o1
0063     or  %o7, %g0, %g1
0064     call    %o1, 0
0065      or %g1, %g0, %o7
0066 #endif
0067 
0068     PUBLIC(_SPARC_Counter_read_default)
0069 SYM(_SPARC_Counter_read_default):
0070     sethi   %hi(_SPARC_Counter + 12), %o1
0071     ld  [%o1 + %lo(_SPARC_Counter + 12)], %o0
0072     add %o0, 1, %o0
0073     st  %o0, [%o1 + %lo(_SPARC_Counter + 12)]
0074     jmp %o7 + 8
0075      nop
0076 
0077     /*
0078      * For the corresponding C code is something like this:
0079      *
0080      * CPU_Counter_ticks _SPARC_Counter_read_clock_isr_disabled( void )
0081      * {
0082      *   const SPARC_Counter *ctr;
0083      *   CPU_Counter_ticks    ticks;
0084      *   CPU_Counter_ticks    accumulated;
0085      *
0086      *   ctr = &_SPARC_Counter;
0087      *   ticks = *ctr->counter_register;
0088      *   accumulated = ctr->accumulated;
0089      *
0090      *   if ( ( *ctr->pending_register & ctr->pending_mask ) != 0 ) {
0091      *     ticks = *ctr->counter_register;
0092      *     accumulated += ctr->interval;
0093      *   }
0094      *
0095      *   return accumulated - ticks;
0096      * }
0097      */
0098     PUBLIC(_SPARC_Counter_read_clock_isr_disabled)
0099 SYM(_SPARC_Counter_read_clock_isr_disabled):
0100     sethi   %hi(_SPARC_Counter), %o5
0101     or  %o5, %lo(_SPARC_Counter), %o5
0102     ld  [%o5 + 8], %o3
0103     ld  [%o5 + 12], %o4
0104     ld  [%o5 + 16], %o2
0105     ld  [%o3], %o0
0106     ld  [%o4], %o1
0107     btst    %o1, %o2
0108     bne .Lpending_isr_disabled
0109      ld [%o5 + 20], %o4
0110     jmp %o7 + 8
0111      sub    %o4, %o0, %o0
0112 .Lpending_isr_disabled:
0113     ld  [%o5 + 24], %o5
0114     ld  [%o3], %o0
0115     add %o4, %o5, %o4
0116     jmp %o7 + 8
0117      sub    %o4, %o0, %o0
0118 
0119     /*
0120      * For the corresponding C code see
0121      * _SPARC_Counter_read_clock_isr_disabled() above.
0122      */
0123     PUBLIC(_SPARC_Counter_read_clock)
0124     PUBLIC(_SPARC_Get_timecount_clock)
0125 SYM(_SPARC_Counter_read_clock):
0126 SYM(_SPARC_Get_timecount_clock):
0127     sethi   %hi(_SPARC_Counter), %o5
0128     or  %o5, %lo(_SPARC_Counter), %o5
0129     ta  SPARC_SWTRAP_IRQDIS
0130     ld  [%o5 + 8], %o3
0131     ld  [%o5 + 12], %o4
0132     ld  [%o5 + 16], %o2
0133     ld  [%o3], %o0
0134     ld  [%o4], %o1
0135     btst    %o1, %o2
0136     bne .Lpending
0137      ld [%o5 + 20], %o4
0138     ta  SPARC_SWTRAP_IRQEN
0139 #ifdef __FIX_LEON3FT_TN0018
0140     /* A nop is added to work around the GRLIB-TN-0018 errata */
0141     nop
0142 #endif
0143     jmp %o7 + 8
0144      sub    %o4, %o0, %o0
0145 .Lpending:
0146     ld  [%o5 + 24], %o5
0147     ld  [%o3], %o0
0148     ta  SPARC_SWTRAP_IRQEN
0149     add %o4, %o5, %o4
0150     jmp %o7 + 8
0151      sub    %o4, %o0, %o0