/* SPDX-License-Identifier: BSD-2-Clause */ /** * @file * * @ingroup RTEMSScoreCPUSPARC * * @brief This source file contains the implementation of _SPARC_Bad_trap(). */ /* * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) * * 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 #include /* * The trap handler entry was set up by TRAP(). */ PUBLIC(_SPARC_Bad_trap) SYM(_SPARC_Bad_trap): /* * Do not use the existing stack since it may be invalid. Use the ISR * stack for this processor. If the trap was caused from within * interrupt context, then a return to the context which caused the * trap would be unreliable. */ set SYM(_ISR_Stack_size), %l5 #if defined(RTEMS_SMP) && defined(__leon__) rd %asr17, %l6 srl %l6, LEON3_ASR17_PROCESSOR_INDEX_SHIFT, %l6 add %l6, 1, %l4 smul %l4, %l5, %l5 #endif set SYM(_ISR_Stack_area_begin), %l7 add %l7, %l5, %l7 andn %l7, CPU_STACK_ALIGNMENT - 1, %l7 /* * Establish an area on the stack for a CPU_Exception_frame. */ sub %l7, SPARC_EXCEPTION_FRAME_SIZE, %l7 /* * Start saving the context which caused the trap. */ mov %wim, %l4 rd %y, %l5 std %l0, [%l7 + SPARC_EXCEPTION_OFFSET_PSR] SPARC_LEON3FT_B2BST_NOP std %l2, [%l7 + SPARC_EXCEPTION_OFFSET_NPC] SPARC_LEON3FT_B2BST_NOP st %l4, [%l7 + SPARC_EXCEPTION_OFFSET_WIM] st %l5, [%l7 + SPARC_EXCEPTION_OFFSET_Y] std %g0, [%l7 + SPARC_EXCEPTION_OFFSET_GLOBAL(0)] SPARC_LEON3FT_B2BST_NOP std %g2, [%l7 + SPARC_EXCEPTION_OFFSET_GLOBAL(2)] SPARC_LEON3FT_B2BST_NOP std %g4, [%l7 + SPARC_EXCEPTION_OFFSET_GLOBAL(4)] SPARC_LEON3FT_B2BST_NOP std %g6, [%l7 + SPARC_EXCEPTION_OFFSET_GLOBAL(6)] SPARC_LEON3FT_B2BST_NOP std %i0, [%l7 + SPARC_EXCEPTION_OFFSET_OUTPUT(0)] SPARC_LEON3FT_B2BST_NOP std %i2, [%l7 + SPARC_EXCEPTION_OFFSET_OUTPUT(2)] SPARC_LEON3FT_B2BST_NOP std %i4, [%l7 + SPARC_EXCEPTION_OFFSET_OUTPUT(4)] SPARC_LEON3FT_B2BST_NOP std %i6, [%l7 + SPARC_EXCEPTION_OFFSET_OUTPUT(6)] /* * Initialize %g6 since it may be corrupt. */ set SYM(_Per_CPU_Information), %g6 #if defined(RTEMS_SMP) && defined(__leon__) sll %l6, PER_CPU_CONTROL_SIZE_LOG2, %l4 add %g6, %l4, %g6 #endif /* * Disable WIM traps. */ mov %g0, %wim nop nop nop /* * Save the remaining register windows. */ set SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g2 add %l7, SPARC_EXCEPTION_OFFSET_WINDOWS(0), %g3 .Lsave_register_windows: restore std %l0, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_LOCAL(0)] SPARC_LEON3FT_B2BST_NOP std %l2, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_LOCAL(2)] SPARC_LEON3FT_B2BST_NOP std %l4, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_LOCAL(4)] SPARC_LEON3FT_B2BST_NOP std %l6, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_LOCAL(6)] SPARC_LEON3FT_B2BST_NOP std %i0, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_INPUT(0)] SPARC_LEON3FT_B2BST_NOP std %i2, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_INPUT(2)] SPARC_LEON3FT_B2BST_NOP std %i4, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_INPUT(4)] SPARC_LEON3FT_B2BST_NOP std %i6, [%g3 + SPARC_REGISTER_WINDOW_OFFSET_INPUT(6)] add %g3, SPARC_REGISTER_WINDOW_SIZE, %g3 subcc %g2, 1, %g2 bne .Lsave_register_windows nop /* * Go back to register window at trap entry. */ restore /* * Initialize the WIM based on the PSR[CWP] to have all register * windows available for the fatal error procedure. */ and %l0, SPARC_PSR_CWP_MASK, %l4 set 1, %l5 sll %l5, %l4, %l5 mov %l5, %wim #if SPARC_HAS_FPU == 1 /* * Enable the FPU in the new PSR (PSR[EF] == 1). */ sethi %hi(SPARC_PSR_EF_MASK), %l4 or %l0, %l4, %l0 #endif /* * Enable traps and disable interrupts. */ or %l0, 0xf20, %l0 wr %l0, %psr nop nop nop #if SPARC_HAS_FPU == 1 st %fsr, [%l7 + SPARC_EXCEPTION_OFFSET_FSR] std %f0, [%l7 + SPARC_EXCEPTION_OFFSET_FP(0)] SPARC_LEON3FT_B2BST_NOP std %f2, [%l7 + SPARC_EXCEPTION_OFFSET_FP(1)] SPARC_LEON3FT_B2BST_NOP std %f4, [%l7 + SPARC_EXCEPTION_OFFSET_FP(2)] SPARC_LEON3FT_B2BST_NOP std %f6, [%l7 + SPARC_EXCEPTION_OFFSET_FP(3)] SPARC_LEON3FT_B2BST_NOP std %f8, [%l7 + SPARC_EXCEPTION_OFFSET_FP(4)] SPARC_LEON3FT_B2BST_NOP std %f10, [%l7 + SPARC_EXCEPTION_OFFSET_FP(5)] SPARC_LEON3FT_B2BST_NOP std %f12, [%l7 + SPARC_EXCEPTION_OFFSET_FP(6)] SPARC_LEON3FT_B2BST_NOP std %f14, [%l7 + SPARC_EXCEPTION_OFFSET_FP(7)] SPARC_LEON3FT_B2BST_NOP std %f16, [%l7 + SPARC_EXCEPTION_OFFSET_FP(8)] SPARC_LEON3FT_B2BST_NOP std %f18, [%l7 + SPARC_EXCEPTION_OFFSET_FP(9)] SPARC_LEON3FT_B2BST_NOP std %f20, [%l7 + SPARC_EXCEPTION_OFFSET_FP(10)] SPARC_LEON3FT_B2BST_NOP std %f22, [%l7 + SPARC_EXCEPTION_OFFSET_FP(11)] SPARC_LEON3FT_B2BST_NOP std %f24, [%l7 + SPARC_EXCEPTION_OFFSET_FP(12)] SPARC_LEON3FT_B2BST_NOP std %f26, [%l7 + SPARC_EXCEPTION_OFFSET_FP(13)] SPARC_LEON3FT_B2BST_NOP std %f28, [%l7 + SPARC_EXCEPTION_OFFSET_FP(14)] SPARC_LEON3FT_B2BST_NOP std %f30, [%l7 + SPARC_EXCEPTION_OFFSET_FP(15)] #endif #if !defined(SPARC_USE_LAZY_FP_SWITCH) /* * Call * _Internal_error( INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT ) * if necessary. */ cmp %l3, 4 bne .Lno_fp_disable_trap nop call SYM(_Internal_error) set 38, %o0 .Lno_fp_disable_trap: #endif /* * Call _Terminate( RTEMS_FATAL_SOURCE_EXCEPTION, %l0 ). */ sub %l7, SPARC_MINIMUM_STACK_FRAME_SIZE, %sp set 9, %o0 call SYM(_Terminate) mov %l7, %o1