summaryrefslogtreecommitdiffstats
path: root/bsps/sparc/erc32/start/spurious.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/sparc/erc32/start/spurious.c')
-rw-r--r--bsps/sparc/erc32/start/spurious.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/bsps/sparc/erc32/start/spurious.c b/bsps/sparc/erc32/start/spurious.c
new file mode 100644
index 0000000000..b022f96f5c
--- /dev/null
+++ b/bsps/sparc/erc32/start/spurious.c
@@ -0,0 +1,194 @@
+/*
+ * 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);
+
+}