summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bsps/sparc/erc32/include/bsp.h2
-rw-r--r--bsps/sparc/erc32/start/bspstart.c2
-rw-r--r--bsps/sparc/erc32/start/spurious.c194
-rw-r--r--bsps/sparc/leon2/include/bsp.h2
-rw-r--r--bsps/sparc/leon2/start/bspstart.c2
-rw-r--r--bsps/sparc/leon2/start/spurious.c184
-rw-r--r--bsps/sparc/leon3/include/bsp.h2
-rw-r--r--bsps/sparc/leon3/start/bspstart.c2
-rw-r--r--bsps/sparc/leon3/start/spurious.c183
-rw-r--r--bsps/sparc/shared/start/start.S7
-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
-rw-r--r--spec/build/bsps/sparc/erc32/bsperc32.yml1
-rw-r--r--spec/build/bsps/sparc/leon2/obj.yml1
-rw-r--r--spec/build/bsps/sparc/leon3/obj.yml1
-rw-r--r--spec/build/cpukit/cpusparc.yml2
23 files changed, 519 insertions, 585 deletions
diff --git a/bsps/sparc/erc32/include/bsp.h b/bsps/sparc/erc32/include/bsp.h
index 6347c58da3..300202bff5 100644
--- a/bsps/sparc/erc32/include/bsp.h
+++ b/bsps/sparc/erc32/include/bsp.h
@@ -90,8 +90,6 @@ rtems_isr_entry set_vector( /* returns old vector */
void BSP_fatal_exit(uint32_t error);
-void bsp_spurious_initialize( void );
-
/* Interrupt Service Routine (ISR) pointer */
typedef void (*bsp_shared_isr)(void *arg);
diff --git a/bsps/sparc/erc32/start/bspstart.c b/bsps/sparc/erc32/start/bspstart.c
index 80447b9457..d56d3b2ff2 100644
--- a/bsps/sparc/erc32/start/bspstart.c
+++ b/bsps/sparc/erc32/start/bspstart.c
@@ -20,8 +20,6 @@
*/
static void erc32_pre_driver_hook( void )
{
- bsp_spurious_initialize();
-
/* Initialize shared interrupt handling, must be done after IRQ
* controller has been found and initialized.
*/
diff --git a/bsps/sparc/erc32/start/spurious.c b/bsps/sparc/erc32/start/spurious.c
deleted file mode 100644
index b022f96f5c..0000000000
--- a/bsps/sparc/erc32/start/spurious.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * ERC32 Spurious Trap Handler
- *
- * This is just enough of a trap handler to let us know what
- * the likely source of the trap was.
- *
- * Developed as part of the port of RTEMS to the ERC32 implementation
- * of the SPARC by On-Line Applications Research Corporation (OAR)
- * under contract to the European Space Agency (ESA).
- *
- * COPYRIGHT (c) 1995. European Space Agency.
- *
- * This terms of the RTEMS license apply to this file.
- */
-
-#include <bsp.h>
-#include <rtems/bspIo.h>
-#include <inttypes.h>
-
-void _CPU_Exception_frame_print( const CPU_Exception_frame *frame )
-{
- uint32_t trap;
- uint32_t real_trap;
- const CPU_Interrupt_frame *isf;
-
- trap = frame->trap;
- real_trap = SPARC_REAL_TRAP_NUMBER(trap);
- isf = frame->isf;
-
- printk(
- "Unexpected trap (%2" PRId32 ") at address 0x%08" PRIx32 "\n",
- real_trap,
- isf->tpc
- );
-
- switch (real_trap) {
-
- /*
- * First the ones defined by the basic architecture
- */
-
- case 0x00:
- printk( "reset\n" );
- break;
- case 0x01:
- printk( "instruction access exception\n" );
- break;
- case 0x02:
- printk( "illegal instruction\n" );
- break;
- case 0x03:
- printk( "privileged instruction\n" );
- break;
- case 0x04:
- printk( "fp disabled\n" );
- break;
- case 0x07:
- printk( "memory address not aligned\n" );
- break;
- case 0x08:
- printk( "fp exception\n" );
- break;
- case 0x09:
- printk("data access exception at 0x%08" PRIx32 "\n",
- ERC32_MEC.First_Failing_Address );
- break;
- case 0x0A:
- printk( "tag overflow\n" );
- break;
-
- /*
- * Then the ones defined by the ERC32 in particular
- */
-
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_MASKED_ERRORS ):
- printk( "ERC32_INTERRUPT_MASKED_ERRORS\n" );
- break;
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_EXTERNAL_1 ):
- printk( "ERC32_INTERRUPT_EXTERNAL_1\n" );
- break;
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_EXTERNAL_2 ):
- printk( "ERC32_INTERRUPT_EXTERNAL_2\n" );
- break;
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_UART_A_RX_TX ):
- printk( "ERC32_INTERRUPT_UART_A_RX_TX\n" );
- break;
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_UART_B_RX_TX ):
- printk( "ERC32_INTERRUPT_UART_A_RX_TX\n" );
- break;
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_CORRECTABLE_MEMORY_ERROR ):
- printk( "ERC32_INTERRUPT_CORRECTABLE_MEMORY_ERROR\n" );
- break;
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_UART_ERROR ):
- printk( "ERC32_INTERRUPT_UART_ERROR\n" );
- break;
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_DMA_ACCESS_ERROR ):
- printk( "ERC32_INTERRUPT_DMA_ACCESS_ERROR\n" );
- break;
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_DMA_TIMEOUT ):
- printk( "ERC32_INTERRUPT_DMA_TIMEOUT\n" );
- break;
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_EXTERNAL_3 ):
- printk( "ERC32_INTERRUPT_EXTERNAL_3\n" );
- break;
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_EXTERNAL_4 ):
- printk( "ERC32_INTERRUPT_EXTERNAL_4\n" );
- break;
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_GENERAL_PURPOSE_TIMER ):
- printk( "ERC32_INTERRUPT_GENERAL_PURPOSE_TIMER\n" );
- break;
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_REAL_TIME_CLOCK ):
- printk( "ERC32_INTERRUPT_REAL_TIME_CLOCK\n" );
- break;
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_EXTERNAL_5 ):
- printk( "ERC32_INTERRUPT_EXTERNAL_5\n" );
- break;
- case ERC32_TRAP_TYPE( ERC32_INTERRUPT_WATCHDOG_TIMEOUT ):
- printk( "ERC32_INTERRUPT_WATCHDOG_TIMEOUT\n" );
- break;
-
- default:
- break;
- }
-}
-
-static rtems_isr bsp_spurious_handler(
- rtems_vector_number trap,
- CPU_Interrupt_frame *isf
-)
-{
- CPU_Exception_frame frame = {
- .trap = trap,
- .isf = isf
- };
-
-#if !defined(SPARC_USE_LAZY_FP_SWITCH)
- if ( SPARC_REAL_TRAP_NUMBER( trap ) == 4 ) {
- _Internal_error( INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT );
- }
-#endif
-
- rtems_fatal(
- RTEMS_FATAL_SOURCE_EXCEPTION,
- (rtems_fatal_code) &frame
- );
-}
-
-/*
- * bsp_spurious_initialize
- *
- * Install the spurious handler for most traps. Note that set_vector()
- * will unmask the corresponding asynchronous interrupt, so the initial
- * interrupt mask is restored after the handlers are installed.
- */
-
-void bsp_spurious_initialize()
-{
- uint32_t trap;
- uint32_t level = 15;
- uint32_t mask;
-
- level = sparc_disable_interrupts();
- mask = ERC32_MEC.Interrupt_Mask;
-
- for ( trap=0 ; trap<256 ; trap++ ) {
-
- /*
- * Skip window overflow, underflow, and flush as well as software
- * trap 0,9,10 which we will use as a shutdown, IRQ disable, IRQ enable.
- * Also avoid trap 0x70 - 0x7f which cannot happen and where some of the
- * space is used to pass parameters to the program.
- */
-
- if (( trap == 5 || trap == 6 ) ||
-#if defined(SPARC_USE_LAZY_FP_SWITCH)
- ( trap == 4 ) ||
-#endif
- (( trap >= 0x11 ) && ( trap <= 0x1f )) ||
- (( trap >= 0x70 ) && ( trap <= 0x83 )) ||
- ( trap == 0x80 + SPARC_SWTRAP_IRQDIS ) ||
-#if defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH)
- ( trap == 0x80 + SPARC_SWTRAP_IRQDIS_FP ) ||
-#endif
- ( trap == 0x80 + SPARC_SWTRAP_IRQEN ))
- continue;
-
- set_vector( (rtems_isr_entry) bsp_spurious_handler,
- SPARC_SYNCHRONOUS_TRAP( trap ), 1 );
- }
-
- ERC32_MEC.Interrupt_Mask = mask;
- sparc_enable_interrupts(level);
-
-}
diff --git a/bsps/sparc/leon2/include/bsp.h b/bsps/sparc/leon2/include/bsp.h
index 5fe39d09d2..f97d78ba80 100644
--- a/bsps/sparc/leon2/include/bsp.h
+++ b/bsps/sparc/leon2/include/bsp.h
@@ -114,8 +114,6 @@ rtems_isr_entry set_vector( /* returns old vector */
void BSP_fatal_exit(uint32_t error);
-void bsp_spurious_initialize( void );
-
/* Interrupt Service Routine (ISR) pointer */
typedef void (*bsp_shared_isr)(void *arg);
diff --git a/bsps/sparc/leon2/start/bspstart.c b/bsps/sparc/leon2/start/bspstart.c
index e3b9141bf5..8ffd0aa2e7 100644
--- a/bsps/sparc/leon2/start/bspstart.c
+++ b/bsps/sparc/leon2/start/bspstart.c
@@ -108,8 +108,6 @@ struct drvmgr_bus_res leon2_amba_res __attribute__((weak)) =
*/
static void leon2_pre_driver_hook( void )
{
- bsp_spurious_initialize();
-
/* Initialize shared interrupt handling, must be done after IRQ
* controller has been found and initialized.
*/
diff --git a/bsps/sparc/leon2/start/spurious.c b/bsps/sparc/leon2/start/spurious.c
deleted file mode 100644
index 0d5fb1631c..0000000000
--- a/bsps/sparc/leon2/start/spurious.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/**
- * @file
- * @ingroup RTEMSBSPsSPARCLEON2
- * @brief LEON Spurious Trap Handler
- */
-
-/*
- * LEON Spurious Trap Handler
- *
- * This is just enough of a trap handler to let us know what
- * the likely source of the trap was.
- *
- * Developed as part of the port of RTEMS to the LEON implementation
- * of the SPARC by On-Line Applications Research Corporation (OAR)
- * under contract to the European Space Agency (ESA).
- *
- * COPYRIGHT (c) 1995. European Space Agency.
- *
- * This terms of the RTEMS license apply to this file.
- */
-
-#include <bsp.h>
-#include <rtems/bspIo.h>
-#include <inttypes.h>
-
-void _CPU_Exception_frame_print( const CPU_Exception_frame *frame )
-{
- uint32_t trap;
- uint32_t real_trap;
- const CPU_Interrupt_frame *isf;
-
- trap = frame->trap;
- real_trap = SPARC_REAL_TRAP_NUMBER(trap);
- isf = frame->isf;
-
- printk(
- "Unexpected trap (%2" PRId32 ") at address 0x%08" PRIx32 "\n",
- real_trap,
- isf->tpc
- );
-
- switch (real_trap) {
-
- /*
- * First the ones defined by the basic architecture
- */
-
- case 0x00:
- printk( "reset\n" );
- break;
- case 0x01:
- printk( "instruction access exception\n" );
- break;
- case 0x02:
- printk( "illegal instruction\n" );
- break;
- case 0x03:
- printk( "privileged instruction\n" );
- break;
- case 0x04:
- printk( "fp disabled\n" );
- break;
- case 0x07:
- printk( "memory address not aligned\n" );
- break;
- case 0x08:
- printk( "fp exception\n" );
- break;
- case 0x09:
- printk("data access exception at 0x%08x\n", LEON_REG.Failed_Address );
- break;
- case 0x0A:
- printk( "tag overflow\n" );
- break;
-
- /*
- * Then the ones defined by the LEON in particular
- */
-
- case LEON_TRAP_TYPE( LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR ):
- printk( "LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_UART_2_RX_TX ):
- printk( "LEON_INTERRUPT_UART_2_RX_TX\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_UART_1_RX_TX ):
- printk( "LEON_INTERRUPT_UART_1_RX_TX\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_0 ):
- printk( "LEON_INTERRUPT_EXTERNAL_0\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_1 ):
- printk( "LEON_INTERRUPT_EXTERNAL_1\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_2 ):
- printk( "LEON_INTERRUPT_EXTERNAL_2\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_3 ):
- printk( "LEON_INTERRUPT_EXTERNAL_3\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_TIMER1 ):
- printk( "LEON_INTERRUPT_TIMER1\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_TIMER2 ):
- printk( "LEON_INTERRUPT_TIMER2\n" );
- break;
-
- default:
- break;
- }
-}
-
-static rtems_isr bsp_spurious_handler(
- rtems_vector_number trap,
- CPU_Interrupt_frame *isf
-)
-{
- CPU_Exception_frame frame = {
- .trap = trap,
- .isf = isf
- };
-
-#if !defined(SPARC_USE_LAZY_FP_SWITCH)
- if ( SPARC_REAL_TRAP_NUMBER( trap ) == 4 ) {
- _Internal_error( INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT );
- }
-#endif
-
- rtems_fatal(
- RTEMS_FATAL_SOURCE_EXCEPTION,
- (rtems_fatal_code) &frame
- );
-}
-
-/*
- * bsp_spurious_initialize
- *
- * Install the spurious handler for most traps. Note that set_vector()
- * will unmask the corresponding asynchronous interrupt, so the initial
- * interrupt mask is restored after the handlers are installed.
- */
-
-void bsp_spurious_initialize()
-{
- uint32_t trap;
- uint32_t level;
- uint32_t mask;
-
- level = sparc_disable_interrupts();
- mask = LEON_REG.Interrupt_Mask;
-
- for ( trap=0 ; trap<256 ; trap++ ) {
-
- /*
- * Skip window overflow, underflow, and flush as well as software
- * trap 0,9,10 which we will use as a shutdown, IRQ disable, IRQ enable.
- * Also avoid trap 0x70 - 0x7f which cannot happen and where some of the
- * space is used to pass parameters to the program.
- */
-
- if (( trap == 5 || trap == 6 ) ||
-#if defined(SPARC_USE_LAZY_FP_SWITCH)
- ( trap == 4 ) ||
-#endif
- (( trap >= 0x11 ) && ( trap <= 0x1f )) ||
- (( trap >= 0x70 ) && ( trap <= 0x83 )) ||
- ( trap == 0x80 + SPARC_SWTRAP_IRQDIS ) ||
-#if defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH)
- ( trap == 0x80 + SPARC_SWTRAP_IRQDIS_FP ) ||
-#endif
- ( trap == 0x80 + SPARC_SWTRAP_IRQEN ))
- continue;
-
- set_vector(
- (rtems_isr_entry) bsp_spurious_handler,
- SPARC_SYNCHRONOUS_TRAP( trap ),
- 1
- );
- }
-
- LEON_REG.Interrupt_Mask = mask;
- sparc_enable_interrupts(level);
-
-}
diff --git a/bsps/sparc/leon3/include/bsp.h b/bsps/sparc/leon3/include/bsp.h
index 85730b5e20..6a96b91bf6 100644
--- a/bsps/sparc/leon3/include/bsp.h
+++ b/bsps/sparc/leon3/include/bsp.h
@@ -129,8 +129,6 @@ rtems_isr_entry set_vector( /* returns old vector */
void BSP_fatal_exit(uint32_t error);
-void bsp_spurious_initialize( void );
-
/*
* Delay for the specified number of microseconds.
*/
diff --git a/bsps/sparc/leon3/start/bspstart.c b/bsps/sparc/leon3/start/bspstart.c
index e4c3f1045e..69ff519189 100644
--- a/bsps/sparc/leon3/start/bspstart.c
+++ b/bsps/sparc/leon3/start/bspstart.c
@@ -98,8 +98,6 @@ static void leon3_interrupt_common_init( void )
*/
static void leon3_pre_driver_hook( void )
{
- bsp_spurious_initialize();
-
#ifndef RTEMS_DRVMGR_STARTUP
leon3_interrupt_common_init();
#endif
diff --git a/bsps/sparc/leon3/start/spurious.c b/bsps/sparc/leon3/start/spurious.c
deleted file mode 100644
index 23ac4bf4cf..0000000000
--- a/bsps/sparc/leon3/start/spurious.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * LEON Spurious Trap Handler
- *
- * This is just enough of a trap handler to let us know what
- * the likely source of the trap was.
- *
- * Developed as part of the port of RTEMS to the LEON implementation
- * of the SPARC by On-Line Applications Research Corporation (OAR)
- * under contract to the European Space Agency (ESA).
- *
- * COPYRIGHT (c) 1995. European Space Agency.
- *
- * Modified for LEON3 BSP.
- * COPYRIGHT (c) 2004.
- * Gaisler Research.
- *
- * This terms of the RTEMS license apply to this file.
- */
-
-#include <bsp.h>
-#include <rtems/score/cpu.h>
-#include <rtems/bspIo.h>
-#include <inttypes.h>
-
-void _CPU_Exception_frame_print( const CPU_Exception_frame *frame )
-{
- uint32_t trap;
- uint32_t real_trap;
- const CPU_Interrupt_frame *isf;
-
- trap = frame->trap;
- real_trap = SPARC_REAL_TRAP_NUMBER(trap);
- isf = frame->isf;
-
- printk(
- "Unexpected trap (%2" PRId32 ") at address 0x%08" PRIx32 "\n",
- real_trap,
- isf->tpc
- );
-
- switch (real_trap) {
-
- /*
- * First the ones defined by the basic architecture
- */
-
- case 0x00:
- printk( "reset\n" );
- break;
- case 0x01:
- printk( "instruction access exception\n" );
- break;
- case 0x02:
- printk( "illegal instruction\n" );
- break;
- case 0x03:
- printk( "privileged instruction\n" );
- break;
- case 0x04:
- printk( "fp disabled\n" );
- break;
- case 0x07:
- printk( "memory address not aligned\n" );
- break;
- case 0x08:
- printk( "fp exception\n" );
- break;
- case 0x0A:
- printk( "tag overflow\n" );
- break;
-
- /*
- * Then the ones defined by the LEON in particular
- */
- /* FIXME */
-
- /*
- case LEON_TRAP_TYPE( LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR ):
- printk( "LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_UART_2_RX_TX ):
- printk( "LEON_INTERRUPT_UART_2_RX_TX\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_UART_1_RX_TX ):
- printk( "LEON_INTERRUPT_UART_1_RX_TX\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_0 ):
- printk( "LEON_INTERRUPT_EXTERNAL_0\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_1 ):
- printk( "LEON_INTERRUPT_EXTERNAL_1\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_2 ):
- printk( "LEON_INTERRUPT_EXTERNAL_2\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_EXTERNAL_3 ):
- printk( "LEON_INTERRUPT_EXTERNAL_3\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_TIMER1 ):
- printk( "LEON_INTERRUPT_TIMER1\n" );
- break;
- case LEON_TRAP_TYPE( LEON_INTERRUPT_TIMER2 ):
- printk( "LEON_INTERRUPT_TIMER2\n" );
- break;
- */
-
- default:
- break;
- }
-}
-
-static rtems_isr bsp_spurious_handler(
- rtems_vector_number trap,
- CPU_Interrupt_frame *isf
-)
-{
- CPU_Exception_frame frame = {
- .trap = trap,
- .isf = isf
- };
-
-#if !defined(SPARC_USE_LAZY_FP_SWITCH)
- if ( SPARC_REAL_TRAP_NUMBER( trap ) == 4 ) {
- _Internal_error( INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT );
- }
-#endif
-
- rtems_fatal(
- RTEMS_FATAL_SOURCE_EXCEPTION,
- (rtems_fatal_code) &frame
- );
-}
-
-/*
- * bsp_spurious_initialize
- *
- * Install the spurious handler for most traps. Note that set_vector()
- * will unmask the corresponding asynchronous interrupt, so the initial
- * interrupt mask is restored after the handlers are installed.
- */
-
-void bsp_spurious_initialize()
-{
- uint32_t trap;
- uint32_t level;
- /* uint32_t mask; */
-
- level = sparc_disable_interrupts();
- /* mask = LEON3_IrqCtrl_Regs->mask_p0; */
-
- for ( trap=0 ; trap<256 ; trap++ ) {
-
- /*
- * Skip window overflow, underflow, and flush as well as software
- * trap 0,9,10 which we will use as a shutdown, IRQ disable, IRQ enable.
- * Also avoid trap 0x70 - 0x7f which cannot happen and where some of the
- * space is used to pass parameters to the program.
- */
-
- if (( trap == 5 ) || ( trap == 6 ) ||
-#if defined(SPARC_USE_LAZY_FP_SWITCH)
- ( trap == 4 ) ||
-#endif
- (( trap >= 0x11 ) && ( trap <= 0x1f )) ||
- (( trap >= 0x70 ) && ( trap <= 0x83 )) ||
- ( trap == 0x80 + SPARC_SWTRAP_IRQDIS ) ||
-#if defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH)
- ( trap == 0x80 + SPARC_SWTRAP_IRQDIS_FP ) ||
-#endif
- ( trap == 0x80 + SPARC_SWTRAP_IRQEN ))
- continue;
-
- set_vector(
- (rtems_isr_entry) bsp_spurious_handler,
- SPARC_SYNCHRONOUS_TRAP( trap ),
- 1
- );
- }
-
- /* LEON3_IrqCtrl_Regs->mask_p0 = mask; */
- sparc_enable_interrupts(level);
-
-}
diff --git a/bsps/sparc/shared/start/start.S b/bsps/sparc/shared/start/start.S
index 9bdc752fa2..cd43f08f01 100644
--- a/bsps/sparc/shared/start/start.S
+++ b/bsps/sparc/shared/start/start.S
@@ -26,14 +26,11 @@
#define TRAP_SYM(_vector) SYM(trap_##_vector)
/*
- * Unexpected trap will halt the processor by forcing it to error state
+ * Unexpected trap will lead to an RTEMS fatal error.
*/
#define BAD_TRAP(_vector) \
TRAP_SYM(_vector):; \
- ta 0; \
- nop; \
- nop; \
- nop;
+ TRAP(_vector, _SPARC_Bad_trap)
/*
* System call optimized trap table entry
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
+}
diff --git a/spec/build/bsps/sparc/erc32/bsperc32.yml b/spec/build/bsps/sparc/erc32/bsperc32.yml
index 1df75fcc60..455aec13f6 100644
--- a/spec/build/bsps/sparc/erc32/bsperc32.yml
+++ b/spec/build/bsps/sparc/erc32/bsperc32.yml
@@ -65,7 +65,6 @@ source:
- bsps/sparc/erc32/start/bspstart.c
- bsps/sparc/erc32/start/erc32mec.c
- bsps/sparc/erc32/start/setvec.c
-- bsps/sparc/erc32/start/spurious.c
- bsps/sparc/shared/gnatcommon.c
- bsps/sparc/shared/irq/bsp_isr_handler.c
- bsps/sparc/shared/irq/irq-shared.c
diff --git a/spec/build/bsps/sparc/leon2/obj.yml b/spec/build/bsps/sparc/leon2/obj.yml
index 92c07b6375..f1a5e52e82 100644
--- a/spec/build/bsps/sparc/leon2/obj.yml
+++ b/spec/build/bsps/sparc/leon2/obj.yml
@@ -41,7 +41,6 @@ source:
- bsps/sparc/leon2/start/bspstart.c
- bsps/sparc/leon2/start/cache.c
- bsps/sparc/leon2/start/setvec.c
-- bsps/sparc/leon2/start/spurious.c
- bsps/sparc/shared/drvmgr/ambapp_bus_leon2.c
- bsps/sparc/shared/drvmgr/leon2_amba_bus.c
- bsps/sparc/shared/gnatcommon.c
diff --git a/spec/build/bsps/sparc/leon3/obj.yml b/spec/build/bsps/sparc/leon3/obj.yml
index 3b58835ec0..19ce633a2a 100644
--- a/spec/build/bsps/sparc/leon3/obj.yml
+++ b/spec/build/bsps/sparc/leon3/obj.yml
@@ -51,7 +51,6 @@ source:
- bsps/sparc/leon3/start/drvmgr_def_drivers.c
- bsps/sparc/leon3/start/eirq.c
- bsps/sparc/leon3/start/setvec.c
-- bsps/sparc/leon3/start/spurious.c
- bsps/sparc/shared/gnatcommon.c
- bsps/sparc/shared/irq/bsp_isr_handler.c
- bsps/sparc/shared/irq/irq-shared.c
diff --git a/spec/build/cpukit/cpusparc.yml b/spec/build/cpukit/cpusparc.yml
index 10dabed494..2186505577 100644
--- a/spec/build/cpukit/cpusparc.yml
+++ b/spec/build/cpukit/cpusparc.yml
@@ -34,9 +34,11 @@ source:
- cpukit/score/cpu/sparc/cpu.c
- cpukit/score/cpu/sparc/cpu_asm.S
- cpukit/score/cpu/sparc/sparc-access.S
+- cpukit/score/cpu/sparc/sparc-bad-trap.S
- cpukit/score/cpu/sparc/sparc-context-validate.S
- cpukit/score/cpu/sparc/sparc-context-volatile-clobber.S
- cpukit/score/cpu/sparc/sparc-counter-asm.S
+- cpukit/score/cpu/sparc/sparc-exception-frame-print.c
- cpukit/score/cpu/sparc/sparc-isr-install.c
- cpukit/score/cpu/sparc/syscall.S
- cpukit/score/cpu/sparc/window.S