diff options
Diffstat (limited to 'bsps/sparc/leon2/start/spurious.c')
-rw-r--r-- | bsps/sparc/leon2/start/spurious.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/bsps/sparc/leon2/start/spurious.c b/bsps/sparc/leon2/start/spurious.c new file mode 100644 index 0000000000..971c3cd44b --- /dev/null +++ b/bsps/sparc/leon2/start/spurious.c @@ -0,0 +1,184 @@ +/** + * @file + * @ingroup sparc_leon2 + * @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); + +} |