Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (c) 2015 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 #include <rtems/score/cpuimpl.h>
0034 
0035 #define SCRATCH_0 (SPARC_MINIMUM_STACK_FRAME_SIZE)
0036 #define SCRATCH_1 (SCRATCH_0 + 0x04)
0037 #define FRAME_END (SCRATCH_1 + 0x04)
0038 #define FRAME_SIZE \
0039   ((FRAME_END + CPU_STACK_ALIGNMENT - 1) & ~(CPU_STACK_ALIGNMENT - 1))
0040 
0041 .macro clobber_register reg
0042     sub %g2, 1, %g2
0043     mov %g2, \reg
0044 .endm
0045 
0046 .macro clobber_fp_register reg
0047     sub %g2, 1, %g2
0048     st  %g2, [%sp + SCRATCH_0]
0049     ld  [%sp + SCRATCH_0], \reg
0050 .endm
0051 
0052     .section    ".bss"
0053     .align 4
0054 
0055     /*
0056      * Use a global variable to vary the clobbered windows in each
0057      * invocation to test the window overflow and underflow conditions.
0058      */
0059 window_clobber_count:
0060     .skip   4
0061 
0062     .section    ".text"
0063     .align  4
0064 
0065         PUBLIC(_CPU_Context_volatile_clobber)
0066 SYM(_CPU_Context_volatile_clobber):
0067 
0068     /* Increment number of flushed windows by one */
0069     sethi   %hi(window_clobber_count), %o1
0070     ld  [%o1 + %lo(window_clobber_count)], %o2
0071     add %o2, 1, %o2
0072     st  %o2, [%o1 + %lo(window_clobber_count)]
0073 
0074     /* Clear window counter number */
0075     clr %g1
0076 
0077     /* Save pattern to global register */
0078     mov %o0, %g2
0079 
0080 window_clobber:
0081 
0082     /* Switch window */
0083 
0084     save    %sp, -FRAME_SIZE, %sp
0085 
0086     /* Check how many windows shall be flushed */
0087     sethi   %hi(window_clobber_count), %o1
0088     ld  [%o1 + %lo(window_clobber_count)], %o2
0089     st  %o2, [%o1 + %lo(window_clobber_count)]
0090     and %o2, (SPARC_NUMBER_OF_REGISTER_WINDOWS - 1), %o1
0091     cmp %o1, 0
0092     bne no_manual_update
0093      nop
0094     add %o1, SPARC_NUMBER_OF_REGISTER_WINDOWS, %o1
0095 
0096 no_manual_update:
0097     /* Register to determine whether FPU is switched on */
0098     mov %psr, %o2
0099     sethi   %hi(SPARC_PSR_EF_MASK), %o3
0100     and     %o3, %o2, %o2
0101 
0102     clobber_register    %o3
0103     clobber_register    %o4
0104     clobber_register    %o5
0105     /* Don't overwrite return address $o7 */
0106     clobber_register    %g3
0107     clobber_register    %g4
0108     clobber_register    %y
0109 
0110     cmp %o2, 0
0111     be  window_update_check
0112      nop
0113 
0114     clobber_fp_register %f0
0115     clobber_fp_register %f1
0116     clobber_fp_register %f2
0117     clobber_fp_register %f3
0118     clobber_fp_register %f4
0119     clobber_fp_register %f5
0120     clobber_fp_register %f6
0121     clobber_fp_register %f7
0122     clobber_fp_register %f8
0123     clobber_fp_register %f9
0124     clobber_fp_register %f10
0125     clobber_fp_register %f11
0126     clobber_fp_register %f12
0127     clobber_fp_register %f13
0128     clobber_fp_register %f14
0129     clobber_fp_register %f15
0130     clobber_fp_register %f16
0131     clobber_fp_register %f17
0132     clobber_fp_register %f18
0133     clobber_fp_register %f19
0134     clobber_fp_register %f20
0135     clobber_fp_register %f21
0136     clobber_fp_register %f22
0137     clobber_fp_register %f23
0138     clobber_fp_register %f24
0139     clobber_fp_register %f25
0140     clobber_fp_register %f26
0141     clobber_fp_register %f27
0142     clobber_fp_register %f28
0143     clobber_fp_register %f29
0144     clobber_fp_register %f30
0145     clobber_fp_register %f31
0146 
0147 window_update_check:
0148 
0149     /* Counter to how many windows were switched */
0150     add %g1, 1, %g1
0151     cmp %g1, %o1
0152     bl  window_clobber
0153      nop
0154 
0155 restore_check:
0156 
0157     cmp %g1, 0
0158     be  clobber_return
0159      nop
0160 
0161     restore
0162     sub %g1, 1, %g1
0163     ba  restore_check
0164      nop
0165 
0166 clobber_return:
0167 
0168     jmp %o7 + 8
0169      nop