summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--c/src/lib/libbsp/sparc/erc32/Makefile.am1
-rw-r--r--c/src/lib/libbsp/sparc/leon2/Makefile.am1
-rw-r--r--c/src/lib/libbsp/sparc/leon3/Makefile.am1
-rw-r--r--cpukit/Makefile.am2
-rw-r--r--cpukit/score/cpu/sparc/cpu.c51
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/cpu.h53
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h22
-rw-r--r--cpukit/score/cpu/sparc/sparc-bad-trap.S231
-rw-r--r--cpukit/score/cpu/sparc/sparc-exception-frame-print.c157
9 files changed, 515 insertions, 4 deletions
diff --git a/c/src/lib/libbsp/sparc/erc32/Makefile.am b/c/src/lib/libbsp/sparc/erc32/Makefile.am
index a718284c3a..1c1c35a6b5 100644
--- a/c/src/lib/libbsp/sparc/erc32/Makefile.am
+++ b/c/src/lib/libbsp/sparc/erc32/Makefile.am
@@ -28,7 +28,6 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/gettargethash-default.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/sbrk.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/erc32/start/setvec.c
-librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/erc32/start/spurious.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/erc32/start/erc32mec.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/erc32/start/boardinit.S
librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/erc32/start/bspidle.c
diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am
index a2570e1784..b2c55f83ad 100644
--- a/c/src/lib/libbsp/sparc/leon2/Makefile.am
+++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am
@@ -30,7 +30,6 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/gettargethash-default.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/sbrk.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon2/start/setvec.c
-librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon2/start/spurious.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon2/start/bspidle.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon2/start/bspdelay.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/start/bsp_fatal_exit.c
diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am
index c10dbe9467..464f225ab2 100644
--- a/c/src/lib/libbsp/sparc/leon3/Makefile.am
+++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am
@@ -32,7 +32,6 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/gettargethash-defau
librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/start/bspgetworkarea.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/sbrk.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/start/setvec.c
-librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/start/spurious.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/start/bspidle.S
librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/start/bspdelay.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c
diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am
index 8947d7eb5a..83c14cd2ab 100644
--- a/cpukit/Makefile.am
+++ b/cpukit/Makefile.am
@@ -1618,9 +1618,11 @@ librtemscpu_a_SOURCES += score/cpu/sparc/access_le.c
librtemscpu_a_SOURCES += score/cpu/sparc/cpu.c
librtemscpu_a_SOURCES += score/cpu/sparc/cpu_asm.S
librtemscpu_a_SOURCES += score/cpu/sparc/sparc-access.S
+librtemscpu_a_SOURCES += score/cpu/sparc/sparc-bad-trap.S
librtemscpu_a_SOURCES += score/cpu/sparc/sparc-context-validate.S
librtemscpu_a_SOURCES += score/cpu/sparc/sparc-context-volatile-clobber.S
librtemscpu_a_SOURCES += score/cpu/sparc/sparc-counter-asm.S
+librtemscpu_a_SOURCES += score/cpu/sparc/sparc-exception-frame-print.c
librtemscpu_a_SOURCES += score/cpu/sparc/sparc-isr-install.c
librtemscpu_a_SOURCES += score/cpu/sparc/syscall.S
librtemscpu_a_SOURCES += score/cpu/sparc/window.S
diff --git a/cpukit/score/cpu/sparc/cpu.c b/cpukit/score/cpu/sparc/cpu.c
index a7bf7dfcaf..10ad44049a 100644
--- a/cpukit/score/cpu/sparc/cpu.c
+++ b/cpukit/score/cpu/sparc/cpu.c
@@ -147,6 +147,57 @@ RTEMS_STATIC_ASSERT(
CPU_Interrupt_frame_alignment
);
+#define SPARC_ASSERT_REGISTER_WINDOW_OFFSET( member, off ) \
+ RTEMS_STATIC_ASSERT( \
+ offsetof( SPARC_Register_window, member ) == \
+ RTEMS_XCONCAT( SPARC_REGISTER_WINDOW_OFFSET_, off ), \
+ SPARC_Register_window ## member \
+ )
+
+SPARC_ASSERT_REGISTER_WINDOW_OFFSET( local[ 0 ], LOCAL( 0 ) );
+SPARC_ASSERT_REGISTER_WINDOW_OFFSET( local[ 1 ], LOCAL( 1 ) );
+SPARC_ASSERT_REGISTER_WINDOW_OFFSET( input[ 0 ], INPUT( 0 ) );
+SPARC_ASSERT_REGISTER_WINDOW_OFFSET( input[ 1 ], INPUT( 1 ) );
+
+RTEMS_STATIC_ASSERT(
+ sizeof( SPARC_Register_window ) == SPARC_REGISTER_WINDOW_SIZE,
+ SPARC_REGISTER_WINDOW_SIZE
+);
+
+#define SPARC_ASSERT_EXCEPTION_OFFSET( member, off ) \
+ RTEMS_STATIC_ASSERT( \
+ offsetof( CPU_Exception_frame, member ) == \
+ RTEMS_XCONCAT( SPARC_EXCEPTION_OFFSET_, off ), \
+ CPU_Exception_frame_offset_ ## member \
+ )
+
+SPARC_ASSERT_EXCEPTION_OFFSET( psr, PSR );
+SPARC_ASSERT_EXCEPTION_OFFSET( pc, PC );
+SPARC_ASSERT_EXCEPTION_OFFSET( npc, NPC );
+SPARC_ASSERT_EXCEPTION_OFFSET( trap, TRAP );
+SPARC_ASSERT_EXCEPTION_OFFSET( wim, WIM );
+SPARC_ASSERT_EXCEPTION_OFFSET( y, Y );
+SPARC_ASSERT_EXCEPTION_OFFSET( global[ 0 ], GLOBAL( 0 ) );
+SPARC_ASSERT_EXCEPTION_OFFSET( global[ 1 ], GLOBAL( 1 ) );
+SPARC_ASSERT_EXCEPTION_OFFSET( output[ 0 ], OUTPUT( 0 ) );
+SPARC_ASSERT_EXCEPTION_OFFSET( output[ 1 ], OUTPUT( 1 ) );
+
+#if SPARC_HAS_FPU == 1
+SPARC_ASSERT_EXCEPTION_OFFSET( fsr, FSR );
+SPARC_ASSERT_EXCEPTION_OFFSET( fp[ 0 ], FP( 0 ) );
+SPARC_ASSERT_EXCEPTION_OFFSET( fp[ 1 ], FP( 1 ) );
+#endif
+
+RTEMS_STATIC_ASSERT(
+ sizeof( CPU_Exception_frame ) == SPARC_EXCEPTION_FRAME_SIZE,
+ SPARC_EXCEPTION_FRAME_SIZE
+);
+
+RTEMS_STATIC_ASSERT(
+ sizeof( CPU_Exception_frame ) % CPU_ALIGNMENT == 0,
+ CPU_Exception_frame_alignment
+);
+
/*
* _CPU_Initialize
*
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/cpu.h b/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
index 0daf1d9a28..f3f50d4f78 100644
--- a/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
@@ -1023,9 +1023,60 @@ RTEMS_NO_RETURN void _CPU_Context_restore( Context_Control *new_context );
} while ( 0 )
#endif
+/**
+ * @brief This structure contains the local and input registers of a register
+ * window.
+ */
typedef struct {
+ /** @brief This member contains the local 0..7 register values. */
+ uint32_t local[ 8 ];
+
+ /** @brief This member contains the input 0..7 register values. */
+ uint32_t input[ 8 ];
+} SPARC_Register_window;
+
+/**
+ * @brief This structure contains the register set of a context which caused an
+ * unexpected trap.
+ */
+typedef struct {
+ /** @brief This member contains the PSR register value. */
+ uint32_t psr;
+
+ /** @brief This member contains the PC value. */
+ uint32_t pc;
+
+ /** @brief This member contains the nPC value. */
+ uint32_t npc;
+
+ /** @brief This member contains the trap number. */
uint32_t trap;
- CPU_Interrupt_frame *isf;
+
+ /** @brief This member contains the WIM register value. */
+ uint32_t wim;
+
+ /** @brief This member contains the Y register value. */
+ uint32_t y;
+
+ /** @brief This member contains the global 0..7 register values. */
+ uint32_t global[ 8 ];
+
+ /** @brief This member contains the output 0..7 register values. */
+ uint32_t output[ 8 ] ;
+
+ /**
+ * @brief This member contains the additional register windows according to
+ * the saved WIM.
+ */
+ SPARC_Register_window windows[ SPARC_NUMBER_OF_REGISTER_WINDOWS - 1 ];
+
+#if SPARC_HAS_FPU == 1
+ /** This member contain the FSR register value. */
+ uint32_t fsr;
+
+ /** @brief This member contains the floating point 0..31 register values. */
+ uint64_t fp[ 16 ];
+#endif
} CPU_Exception_frame;
void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h
index a99da74fa9..a8ed0aec23 100644
--- a/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h
@@ -117,6 +117,28 @@
#endif
#endif
+#define SPARC_REGISTER_WINDOW_OFFSET_LOCAL( i ) ( ( i ) * 4 )
+#define SPARC_REGISTER_WINDOW_OFFSET_INPUT( i ) ( ( i ) * 4 + 32 )
+#define SPARC_REGISTER_WINDOW_SIZE 64
+
+#define SPARC_EXCEPTION_OFFSET_PSR 0
+#define SPARC_EXCEPTION_OFFSET_PC 4
+#define SPARC_EXCEPTION_OFFSET_NPC 8
+#define SPARC_EXCEPTION_OFFSET_TRAP 12
+#define SPARC_EXCEPTION_OFFSET_WIM 16
+#define SPARC_EXCEPTION_OFFSET_Y 20
+#define SPARC_EXCEPTION_OFFSET_GLOBAL( i ) ( ( i ) * 4 + 24 )
+#define SPARC_EXCEPTION_OFFSET_OUTPUT( i ) ( ( i ) * 4 + 56 )
+#define SPARC_EXCEPTION_OFFSET_WINDOWS( i ) ( ( i ) * 64 + 88 )
+
+#if SPARC_HAS_FPU == 1
+#define SPARC_EXCEPTION_OFFSET_FSR 536
+#define SPARC_EXCEPTION_OFFSET_FP( i ) ( ( i ) * 8 + 544 )
+#define SPARC_EXCEPTION_FRAME_SIZE 672
+#else
+#define SPARC_EXCEPTION_FRAME_SIZE 536
+#endif
+
#ifndef ASM
#ifdef __cplusplus
diff --git a/cpukit/score/cpu/sparc/sparc-bad-trap.S b/cpukit/score/cpu/sparc/sparc-bad-trap.S
new file mode 100644
index 0000000000..2e73a4a7da
--- /dev/null
+++ b/cpukit/score/cpu/sparc/sparc-bad-trap.S
@@ -0,0 +1,231 @@
+/* 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 <rtems/asm.h>
+#include <rtems/score/percpu.h>
+
+ /*
+ * 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
diff --git a/cpukit/score/cpu/sparc/sparc-exception-frame-print.c b/cpukit/score/cpu/sparc/sparc-exception-frame-print.c
new file mode 100644
index 0000000000..f216c1dc63
--- /dev/null
+++ b/cpukit/score/cpu/sparc/sparc-exception-frame-print.c
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreCPUSPARC
+ *
+ * @brief This source file contains the SPARC-specific implementation of
+ * _CPU_Exception_frame_print().
+ */
+
+/*
+ * 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 <rtems/score/cpu.h>
+#include <rtems/bspIo.h>
+#include <inttypes.h>
+
+void _CPU_Exception_frame_print( const CPU_Exception_frame *frame )
+{
+ size_t i;
+ size_t j;
+ const char *desc;
+
+ switch ( SPARC_REAL_TRAP_NUMBER( frame->trap ) ) {
+ case 0x01:
+ desc = " (instruction access exception)";
+ break;
+ case 0x02:
+ desc = " (illegal instruction)";
+ break;
+ case 0x03:
+ desc = " (privileged instruction)";
+ break;
+ case 0x04:
+ desc = " (fp disabled)";
+ break;
+ case 0x05:
+ desc = " (window overflow)";
+ break;
+ case 0x06:
+ desc = " (window underflow)";
+ break;
+ case 0x07:
+ desc = " (memory address not aligned)";
+ break;
+ case 0x08:
+ desc = " (fp exception)";
+ break;
+ case 0x09:
+ desc = " (data access exception)";
+ break;
+ case 0x0A:
+ desc = " (tag overflow)";
+ break;
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ case 0x17:
+ case 0x18:
+ case 0x19:
+ case 0x1A:
+ case 0x1B:
+ case 0x1C:
+ case 0x1D:
+ case 0x1E:
+ case 0x1F:
+ desc = " (external interrupt)";
+ break;
+ case 0x24:
+ desc = " (cp disabled)";
+ break;
+ case 0x28:
+ desc = " (cp exception)";
+ break;
+ default:
+ desc = "";
+ break;
+ }
+
+ printk(
+ "\n"
+ "unexpected trap %" PRIu32 "%s\n"
+ "PSR = 0x%08" PRIx32 "\n"
+ "PC = 0x%08" PRIx32 "\n"
+ "nPC = 0x%08" PRIx32 "\n"
+ "WIM = 0x%08" PRIx32 "\n"
+ "Y = 0x%08" PRIx32 "\n",
+ frame->trap,
+ desc,
+ frame->psr,
+ frame->pc,
+ frame->npc,
+ frame->wim,
+ frame->y
+ );
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( frame->global ); ++i ) {
+ printk( "g%zu = 0x%08" PRIx32 "\n", i, frame->global[ i ] );
+ }
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( frame->output ); ++i ) {
+ printk( "o%zu[CWP - 0] = 0x%08" PRIx32 "\n", i, frame->output[ i ] );
+ }
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( frame->windows ); ++i ) {
+ const SPARC_Register_window *win;
+
+ win = &frame->windows[ i ];
+
+ for ( j = 0; j < RTEMS_ARRAY_SIZE( win->local ); ++j ) {
+ printk( "l%zu[CWP - %zu] = 0x%08" PRIx32 "\n", j, i, win->local[ j ] );
+ }
+
+ for ( j = 0; j < RTEMS_ARRAY_SIZE( win->input ); ++j ) {
+ printk( "i%zu[CWP - %zu] = 0x%08" PRIx32 "\n", j, i, win->input[ j ] );
+ }
+ }
+
+#if SPARC_HAS_FPU == 1
+ printk( "FSR = 0x%08" PRIx32 "\n", frame->fsr );
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( frame->fp ); ++i ) {
+ j = i * 2;
+ printk( "fp%zu:fp%zu = 0x%016" PRIx64 "\n", j, j + 1, frame->fp[ i ] );
+ }
+#endif
+}