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  * @file
0005  *
0006  * @ingroup RTEMSScoreCPUSPARC
0007  *
0008  * @brief This source file contains the implementation of _SPARC_Bad_trap().
0009  */
0010 
0011 /*
0012  * Copyright (C) 2021 embedded brains GmbH & Co. KG
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #ifdef HAVE_CONFIG_H
0037 #include "config.h"
0038 #endif
0039 
0040 #include <rtems/asm.h>
0041 #include <rtems/score/percpu.h>
0042 
0043         /*
0044          * The trap handler entry was set up by TRAP().
0045          */
0046         PUBLIC(_SPARC_Bad_trap)
0047 SYM(_SPARC_Bad_trap):
0048 
0049         /*
0050          * Do not use the existing stack since it may be invalid.  Use the ISR
0051          * stack for this processor.  If the trap was caused from within
0052          * interrupt context, then a return to the context which caused the
0053          * trap would be unreliable.
0054          */
0055         set     SYM(_ISR_Stack_size), %l5
0056 
0057 #if defined(RTEMS_SMP) && defined(__leon__)
0058         rd      %asr17, %l6
0059         srl     %l6, LEON3_ASR17_PROCESSOR_INDEX_SHIFT, %l6
0060         add     %l6, 1, %l4
0061         smul    %l4, %l5, %l5
0062 #endif
0063         set     SYM(_ISR_Stack_area_begin), %l7
0064         add     %l7, %l5, %l7
0065         andn    %l7, CPU_STACK_ALIGNMENT - 1, %l7
0066 
0067         /*
0068          * Establish an area on the stack for a CPU_Exception_frame.
0069          */
0070         sub     %l7, SPARC_EXCEPTION_FRAME_SIZE, %l7
0071 
0072         /*
0073          * Start saving the context which caused the trap.
0074          */
0075         mov     %wim, %l4
0076         rd      %y, %l5
0077         std     %l0, [%l7 + SPARC_EXCEPTION_OFFSET_PSR]
0078         SPARC_LEON3FT_B2BST_NOP
0079         std     %l2, [%l7 + SPARC_EXCEPTION_OFFSET_NPC]
0080         SPARC_LEON3FT_B2BST_NOP
0081         st      %l4, [%l7 + SPARC_EXCEPTION_OFFSET_WIM]
0082         st      %l5, [%l7 + SPARC_EXCEPTION_OFFSET_Y]
0083         std     %g0, [%l7 + SPARC_EXCEPTION_OFFSET_GLOBAL(0)]
0084         SPARC_LEON3FT_B2BST_NOP
0085         std     %g2, [%l7 + SPARC_EXCEPTION_OFFSET_GLOBAL(2)]
0086         SPARC_LEON3FT_B2BST_NOP
0087         std     %g4, [%l7 + SPARC_EXCEPTION_OFFSET_GLOBAL(4)]
0088         SPARC_LEON3FT_B2BST_NOP
0089         std     %g6, [%l7 + SPARC_EXCEPTION_OFFSET_GLOBAL(6)]
0090         SPARC_LEON3FT_B2BST_NOP
0091         std     %i0, [%l7 + SPARC_EXCEPTION_OFFSET_OUTPUT(0)]
0092         SPARC_LEON3FT_B2BST_NOP
0093         std     %i2, [%l7 + SPARC_EXCEPTION_OFFSET_OUTPUT(2)]
0094         SPARC_LEON3FT_B2BST_NOP
0095         std     %i4, [%l7 + SPARC_EXCEPTION_OFFSET_OUTPUT(4)]
0096         SPARC_LEON3FT_B2BST_NOP
0097         std     %i6, [%l7 + SPARC_EXCEPTION_OFFSET_OUTPUT(6)]
0098 
0099         /*
0100          * Initialize %g6 since it may be corrupt.
0101          */
0102         set     SYM(_Per_CPU_Information), %g6
0103 #if defined(RTEMS_SMP) && defined(__leon__)
0104         sll     %l6, PER_CPU_CONTROL_SIZE_LOG2, %l4
0105         add     %g6, %l4, %g6
0106 #endif
0107 
0108         /*
0109          * Disable WIM traps.
0110          */
0111         mov     %g0, %wim
0112         nop
0113         nop
0114         nop
0115 
0116         /*
0117          * Save the remaining register windows.
0118          */
0119         set     SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g2
0120         add     %l7, SPARC_EXCEPTION_OFFSET_WINDOWS(0), %g3
0121 
0122 .Lsave_register_windows:
0123 
0124         restore
0125         std     %l0, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_LOCAL(0)]
0126         SPARC_LEON3FT_B2BST_NOP
0127         std     %l2, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_LOCAL(2)]
0128         SPARC_LEON3FT_B2BST_NOP
0129         std     %l4, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_LOCAL(4)]
0130         SPARC_LEON3FT_B2BST_NOP
0131         std     %l6, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_LOCAL(6)]
0132         SPARC_LEON3FT_B2BST_NOP
0133         std     %i0, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_INPUT(0)]
0134         SPARC_LEON3FT_B2BST_NOP
0135         std     %i2, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_INPUT(2)]
0136         SPARC_LEON3FT_B2BST_NOP
0137         std     %i4, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_INPUT(4)]
0138         SPARC_LEON3FT_B2BST_NOP
0139         std     %i6, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_INPUT(6)]
0140         add     %g3, SPARC_REGISTER_WINDOW_SIZE, %g3
0141         subcc   %g2, 1, %g2
0142         bne     .Lsave_register_windows
0143          nop
0144 
0145         /*
0146          * Go back to register window at trap entry.
0147          */
0148         restore
0149 
0150         /*
0151          * Initialize the WIM based on the PSR[CWP] to have all register
0152          * windows available for the fatal error procedure.
0153          */
0154         and     %l0, SPARC_PSR_CWP_MASK, %l4
0155         set     1, %l5
0156         sll     %l5, %l4, %l5
0157         mov     %l5, %wim
0158 
0159 #if SPARC_HAS_FPU == 1
0160         /*
0161          * Enable the FPU in the new PSR (PSR[EF] == 1).
0162          */
0163         sethi   %hi(SPARC_PSR_EF_MASK), %l4
0164         or      %l0, %l4, %l0
0165 #endif
0166 
0167         /*
0168          * Enable traps and disable interrupts.
0169          */
0170         or      %l0, 0xf20, %l0
0171         wr      %l0, %psr
0172         nop
0173         nop
0174         nop
0175 
0176 #if SPARC_HAS_FPU == 1
0177         st      %fsr, [%l7 + SPARC_EXCEPTION_OFFSET_FSR]
0178         std     %f0, [%l7 + SPARC_EXCEPTION_OFFSET_FP(0)]
0179         SPARC_LEON3FT_B2BST_NOP
0180         std     %f2, [%l7 + SPARC_EXCEPTION_OFFSET_FP(1)]
0181         SPARC_LEON3FT_B2BST_NOP
0182         std     %f4, [%l7 + SPARC_EXCEPTION_OFFSET_FP(2)]
0183         SPARC_LEON3FT_B2BST_NOP
0184         std     %f6, [%l7 + SPARC_EXCEPTION_OFFSET_FP(3)]
0185         SPARC_LEON3FT_B2BST_NOP
0186         std     %f8, [%l7 + SPARC_EXCEPTION_OFFSET_FP(4)]
0187         SPARC_LEON3FT_B2BST_NOP
0188         std     %f10, [%l7 + SPARC_EXCEPTION_OFFSET_FP(5)]
0189         SPARC_LEON3FT_B2BST_NOP
0190         std     %f12, [%l7 + SPARC_EXCEPTION_OFFSET_FP(6)]
0191         SPARC_LEON3FT_B2BST_NOP
0192         std     %f14, [%l7 + SPARC_EXCEPTION_OFFSET_FP(7)]
0193         SPARC_LEON3FT_B2BST_NOP
0194         std     %f16, [%l7 + SPARC_EXCEPTION_OFFSET_FP(8)]
0195         SPARC_LEON3FT_B2BST_NOP
0196         std     %f18, [%l7 + SPARC_EXCEPTION_OFFSET_FP(9)]
0197         SPARC_LEON3FT_B2BST_NOP
0198         std     %f20, [%l7 + SPARC_EXCEPTION_OFFSET_FP(10)]
0199         SPARC_LEON3FT_B2BST_NOP
0200         std     %f22, [%l7 + SPARC_EXCEPTION_OFFSET_FP(11)]
0201         SPARC_LEON3FT_B2BST_NOP
0202         std     %f24, [%l7 + SPARC_EXCEPTION_OFFSET_FP(12)]
0203         SPARC_LEON3FT_B2BST_NOP
0204         std     %f26, [%l7 + SPARC_EXCEPTION_OFFSET_FP(13)]
0205         SPARC_LEON3FT_B2BST_NOP
0206         std     %f28, [%l7 + SPARC_EXCEPTION_OFFSET_FP(14)]
0207         SPARC_LEON3FT_B2BST_NOP
0208         std     %f30, [%l7 + SPARC_EXCEPTION_OFFSET_FP(15)]
0209 #endif
0210 
0211         /*
0212          * Call _Terminate( RTEMS_FATAL_SOURCE_EXCEPTION, %l0 ).
0213          */
0214         sub     %l7, SPARC_MINIMUM_STACK_FRAME_SIZE, %sp
0215         set     9, %o0
0216         call    SYM(_Terminate)
0217          mov    %l7, %o1