diff --git a/bsps/mips/include/libcpu/isr_entries.h b/bsps/mips/include/libcpu/isr_entries.h index 3e8af2ac05..94ea18912a 100644 --- a/bsps/mips/include/libcpu/isr_entries.h +++ b/bsps/mips/include/libcpu/isr_entries.h @@ -39,6 +39,11 @@ extern void mips_install_isr_entries( void ); extern void mips_vector_isr_handlers( CPU_Interrupt_frame *frame ); +/* + * The frame of the exception being vectored, or NULL outside such a vector. + */ +extern CPU_Exception_frame *mips_exception_frame; + #if __mips == 1 extern void exc_utlb_code(void); extern void exc_dbg_code(void); diff --git a/bsps/mips/shared/irq/irq.c b/bsps/mips/shared/irq/irq.c index e5153e4704..c1d99ad27d 100644 --- a/bsps/mips/shared/irq/irq.c +++ b/bsps/mips/shared/irq/irq.c @@ -36,48 +36,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include - #include #include #include #include -#include - -static const char *const cause_strings[32] = { - /* 0 */ "Int", - /* 1 */ "TLB Mods", - /* 2 */ "TLB Load", - /* 3 */ "TLB Store", - /* 4 */ "Address Load", - /* 5 */ "Address Store", - /* 6 */ "Instruction Bus Error", - /* 7 */ "Data Bus Error", - /* 8 */ "Syscall", - /* 9 */ "Breakpoint", - /* 10 */ "Reserved Instruction", - /* 11 */ "Coprocessor Unuseable", - /* 12 */ "Overflow", - /* 13 */ "Trap", - /* 14 */ "Instruction Virtual Coherency Error", - /* 15 */ "FP Exception", - /* 16 */ "Reserved 16", - /* 17 */ "Reserved 17", - /* 18 */ "Reserved 18", - /* 19 */ "Reserved 19", - /* 20 */ "Reserved 20", - /* 21 */ "Reserved 21", - /* 22 */ "Reserved 22", - /* 23 */ "Watch", - /* 24 */ "Reserved 24", - /* 25 */ "Reserved 25", - /* 26 */ "Reserved 26", - /* 27 */ "Reserved 27", - /* 28 */ "Reserved 28", - /* 29 */ "Reserved 29", - /* 30 */ "Reserved 30", - /* 31 */ "Data Virtual Coherency Error" -}; +#include +#include static inline bool bsp_irq_is_valid(rtems_vector_number vector) { @@ -185,17 +149,19 @@ void bsp_interrupt_facility_initialize(void) void bsp_interrupt_handler_default(rtems_vector_number vector) { - uint32_t sr; - uint32_t cause; + /* + * An exception which no handler consumed is reported with the source and + * the argument every other port uses, so that a fatal error extension can + * recognise it and, where the exception is expected, resume with a + * longjmp(). Do not report it here: the extension prints the frame if the + * system really terminates. + */ + if ( mips_exception_frame != NULL ) { + rtems_fatal( + RTEMS_FATAL_SOURCE_EXCEPTION, + (rtems_fatal_code) mips_exception_frame + ); + } - mips_get_sr( sr ); - mips_get_cause( cause ); - - printk( "Unhandled exception %" PRId32 "\n", vector ); - printk( "sr: 0x%08" PRIu32 " cause: 0x%08" PRIu32 " --> %s\n", sr, cause, - cause_strings[(cause >> 2) &0x1f] ); - #if 0 - mips_dump_exception_frame( frame ); - #endif - rtems_fatal_error_occurred(1); + _Terminate( RTEMS_FATAL_SOURCE_SPURIOUS_INTERRUPT, vector ); } diff --git a/bsps/mips/shared/irq/vectorexceptions.c b/bsps/mips/shared/irq/vectorexceptions.c index bb9b9d6760..56d540ba39 100644 --- a/bsps/mips/shared/irq/vectorexceptions.c +++ b/bsps/mips/shared/irq/vectorexceptions.c @@ -50,6 +50,41 @@ struct regdef char *name; }; +static const char *const cause_strings[32] = { + /* 0 */ "Int", + /* 1 */ "TLB Mods", + /* 2 */ "TLB Load", + /* 3 */ "TLB Store", + /* 4 */ "Address Load", + /* 5 */ "Address Store", + /* 6 */ "Instruction Bus Error", + /* 7 */ "Data Bus Error", + /* 8 */ "Syscall", + /* 9 */ "Breakpoint", + /* 10 */ "Reserved Instruction", + /* 11 */ "Coprocessor Unuseable", + /* 12 */ "Overflow", + /* 13 */ "Trap", + /* 14 */ "Instruction Virtual Coherency Error", + /* 15 */ "FP Exception", + /* 16 */ "Reserved 16", + /* 17 */ "Reserved 17", + /* 18 */ "Reserved 18", + /* 19 */ "Reserved 19", + /* 20 */ "Reserved 20", + /* 21 */ "Reserved 21", + /* 22 */ "Reserved 22", + /* 23 */ "Watch", + /* 24 */ "Reserved 24", + /* 25 */ "Reserved 25", + /* 26 */ "Reserved 26", + /* 27 */ "Reserved 27", + /* 28 */ "Reserved 28", + /* 29 */ "Reserved 29", + /* 30 */ "Reserved 30", + /* 31 */ "Data Virtual Coherency Error" +}; + static const struct regdef dumpregs[]= { { R_RA, "R_RA" }, { R_V0, "R_V0" }, { R_V1, "R_V1" }, { R_A0, "R_A0" }, { R_A1, "R_A1" }, { R_A2, "R_A2" }, @@ -67,6 +102,12 @@ void _CPU_Exception_frame_print( const CPU_Exception_frame *frame ) int i; size_t j; + printk( + " CAUSE %08" PRIx32 " --> %s\n", + (uint32_t) frame->cause, + cause_strings[ ( (uint32_t) frame->cause >> 2 ) & 0x1f ] + ); + frame_u32 = (uint32_t *)frame; for(i=0; dumpregs[i].offset > -1; i++) { @@ -89,6 +130,13 @@ void _CPU_Exception_frame_print( const CPU_Exception_frame *frame ) * all be close to the same set. */ +/* + * The frame of the exception being vectored, or NULL outside such a vector. + * bsp_interrupt_handler_default() uses it to tell an exception which no + * handler consumed from a spurious interrupt. + */ +CPU_Exception_frame *mips_exception_frame; + void mips_vector_exceptions( CPU_Interrupt_frame *frame ) { (void) frame; @@ -99,5 +147,7 @@ void mips_vector_exceptions( CPU_Interrupt_frame *frame ) mips_get_cause( cause ); exc = (cause >> 2) & 0x1f; + mips_exception_frame = frame; bsp_interrupt_handler_dispatch( exc ); + mips_exception_frame = NULL; }