forked from Imagelibrary/rtems
185 lines
4.6 KiB
C
185 lines
4.6 KiB
C
/**
|
|
* @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);
|
|
|
|
}
|