summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/mips/mongoosev/vectorisrs/vectorisrs.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libcpu/mips/mongoosev/vectorisrs/vectorisrs.c')
-rw-r--r--c/src/lib/libcpu/mips/mongoosev/vectorisrs/vectorisrs.c321
1 files changed, 283 insertions, 38 deletions
diff --git a/c/src/lib/libcpu/mips/mongoosev/vectorisrs/vectorisrs.c b/c/src/lib/libcpu/mips/mongoosev/vectorisrs/vectorisrs.c
index 92c752aff0..50e1272bac 100644
--- a/c/src/lib/libcpu/mips/mongoosev/vectorisrs/vectorisrs.c
+++ b/c/src/lib/libcpu/mips/mongoosev/vectorisrs/vectorisrs.c
@@ -15,65 +15,310 @@
#include <stdlib.h>
#include <libcpu/mongoose-v.h>
-#define mips_get_cause( _cause ) \
- do { \
- asm volatile( "mfc0 %0, $13; nop" : "=r" (_cause) : ); \
- } while (0)
+#include "iregdef.h"
+#include "idtcpu.h"
-#define CALL_ISR(_vector) \
+
+#define CALL_ISR(_vector,_frame) \
do { \
if ( _ISR_Vector_table[_vector] ) \
- (_ISR_Vector_table[_vector])(_vector); \
+ (_ISR_Vector_table[_vector])(_vector,_frame); \
else \
- mips_default_exception(_vector); \
+ mips_default_isr(_vector); \
} while (0)
#include <bspIo.h> /* for printk */
-void mips_default_exception( int vector )
+
+
+
+
+
+void mips_vector_isr_handlers( CPU_Interrupt_frame *frame )
{
- printk( "Unhandled exception %d\n", vector );
+ unsigned32 sr, srmaskoff;
+ unsigned32 cause, cshifted;
+ unsigned32 bit;
+ unsigned32 pf_icr;
+
+ /* mips_get_sr( sr ); */
+ sr = frame->regs[ R_SR ];
+
+ mips_get_cause( cause );
+
+ /* mask off everything other than the interrupt bits */
+ cause &= SR_IMASK;
+
+ /* mask off the pending interrupts in the status register */
+ srmaskoff = sr & ~cause;
+ mips_set_sr( srmaskoff );
+
+ /* allow nesting for all non-pending interrupts */
+ asm volatile( "rfe" );
+
+ cshifted = (cause & (sr & SR_IMASK)) >> CAUSE_IPSHIFT;
+
+ if ( cshifted & 0x04 ) /* IP[0] ==> INT0 == TIMER1 */
+ CALL_ISR( MONGOOSEV_IRQ_TIMER1, frame );
+
+ if ( cshifted & 0x08 ) /* IP[1] ==> INT1 == TIMER2*/
+ CALL_ISR( MONGOOSEV_IRQ_TIMER2, frame );
+
+ if ( cshifted & 0x10 ) /* IP[2] ==> INT2 */
+ CALL_ISR( MONGOOSEV_IRQ_INT2, frame );
+
+ if ( cshifted & 0x20 ) /* IP[3] ==> INT3 == FPU interrupt */
+ CALL_ISR( MONGOOSEV_IRQ_INT3, frame );
+
+ if ( cshifted & 0x40 ) /* IP[4] ==> INT4, external interrupt */
+ CALL_ISR( MONGOOSEV_IRQ_INT4, frame );
+
+ if ( cshifted & 0x80 ) /* IP[5] ==> INT5, peripheral interrupt */
+ {
+ pf_icr = MONGOOSEV_READ( MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_CAUSE_REGISTER );
+
+ /* if !pf_icr */
+ for ( bit=0 ; bit <= 31 ; bit++, pf_icr >>= 1 )
+ {
+ if ( pf_icr & 1 )
+ {
+ CALL_ISR( MONGOOSEV_IRQ_PERIPHERAL_BASE + bit, frame );
+ }
+ }
+ }
+
+
+ /* all the pending interrupts were serviced, now re-enable them */
+ mips_get_sr( sr );
+
+ /* we allow the 2 software interrupts to nest freely, under the
+ * assumption that the program knows what its doing...
+ */
+
+ if( cshifted & 0x3 )
+ {
+ sr |= (SR_IBIT1 | SR_IBIT1);
+ cause &= ~(SR_IBIT1 | SR_IBIT1);
+
+ mips_set_cause(cause);
+ mips_set_sr(sr);
+
+ if ( cshifted & 0x01 ) /* SW[0] */
+ {
+ CALL_ISR( MONGOOSEV_IRQ_SOFTWARE_1, frame );
+ }
+ if ( cshifted & 0x02 ) /* SW[1] */
+ {
+ CALL_ISR( MONGOOSEV_IRQ_SOFTWARE_2, frame );
+ }
+ }
+
+ sr |= cause;
+ mips_set_sr( sr );
+}
+
+
+
+
+
+
+
+void mips_default_isr( int vector )
+{
+ unsigned int sr;
+ unsigned int cause;
+
+ mips_get_sr( sr );
+ mips_get_cause( cause );
+
+ printk( "Unhandled isr exception: vector 0x%02x, cause 0x%08X, sr 0x%08X\n", vector, cause, sr );
rtems_fatal_error_occurred(1);
}
-void mips_vector_isr_handlers( void )
+
+
+
+
+
+
+
+/* userspace routine to assert either software interrupt */
+
+int assertSoftwareInterrupt( unsigned32 n )
+{
+ if( n >= 0 && n<2 )
+ {
+ unsigned32 c;
+
+ mips_get_cause(c);
+ c = ((n+1) << 8);
+ mips_set_cause(c);
+
+ return n;
+ }
+ else return -1;
+}
+
+
+
+
+
+
+
+
+
+
+
+/* exception vectoring, from vectorexceptions.c */
+
+/*#include <rtems.h>
+#include <stdlib.h>
+#include "iregdef.h"
+#include <bsp.h>
+#include <bspIo.h>*/
+
+
+
+
+char *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",
+ /* 9 */ "Syscall",
+ /* 10 */ "Breakpoint",
+ /* 11 */ "Reserved Instruction",
+ /* 12 */ "Coprocessor Unuseable",
+ /* 13 */ "Overflow",
+ /* 14 */ "Trap",
+ /* 15 */ "Instruction Virtual Coherency Error",
+ /* 16 */ "FP Exception",
+ /* 17 */ "Reserved 17",
+ /* 18 */ "Reserved 17",
+ /* 19 */ "Reserved 17",
+ /* 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"
+};
+
+
+
+struct regdef
+{
+ int offset;
+ char *name;
+};
+
+
+/*
+ * this struct holds the set of registers we're going to dump on an
+ * exception, the symbols are defined by iregdef.h, and they are set
+ * by cpu_asm.S into the CPU_Interrupt_frame passed here by
+ * ISR_Handler. Note not all registers are stored, only those used
+ * by the cpu_asm.S code. Refer to cpu_asm.S
+ */
+
+
+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" }, \
+ { R_A3, "R_A3" }, { R_T0, "R_T0" }, { R_T1, "R_T1" }, { R_T2, "R_T2" }, { R_T3, "R_T3" }, { R_T4, "R_T4" }, \
+ { R_T5, "R_T5" }, { R_T6, "R_T6" }, { R_T7, "R_T7" }, { R_T8, "R_T8" }, { R_MDLO, "R_MDLO" }, { R_MDHI, "R_MDHI" }, \
+ { R_GP, "R_GP" }, { R_FP, "R_FP" }, { R_AT, "R_AT" }, { R_EPC,"R_EPC"}, { -1, NULL } };
+
+
+
+void mips_default_exception_code_handler( int exc, CPU_Interrupt_frame *frame )
{
unsigned int sr;
unsigned int cause;
- int bit;
- unsigned int pf_icr;
+ int i, j;
mips_get_sr( sr );
mips_get_cause( cause );
- cause &= (sr & SR_IMASK);
- cause >>= CAUSE_IPSHIFT;
+ printk( "Unhandled exception %d\n", exc );
+ printk( "sr: 0x%08x cause: 0x%08x --> %s\n", sr, cause, cause_strings[(cause >> 2) &0x1f] );
- if ( cause & 0x04 ) /* IP[0] ==> INT0 == TIMER1 */
- CALL_ISR( MONGOOSEV_IRQ_TIMER1 );
-
- if ( cause & 0x08 ) /* IP[1] ==> INT1 == TIMER2*/
- CALL_ISR( MONGOOSEV_IRQ_TIMER2 );
-
- if ( cause & 0x10 ) /* IP[2] ==> INT2 */
- CALL_ISR( MONGOOSEV_IRQ_INT2 );
-
- if ( cause & 0x20 ) /* IP[3] ==> INT4 */
- CALL_ISR( MONGOOSEV_IRQ_INT4 );
-
- if ( cause & 0x40 ) { /* IP[4] ==> INT5 */
- pf_icr =
- MONGOOSEV_READ( MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_CAUSE_REGISTER );
- /* XXX if !pf_icr */
- for ( bit=0 ; bit <= 31 ; bit++, pf_icr >>= 1 ) {
- if ( pf_icr & 1 )
- CALL_ISR( MONGOOSEV_IRQ_PERIPHERAL_BASE + bit );
- }
+ for(i=0; dumpregs[i].offset > -1; i++)
+ {
+ printk(" %s", dumpregs[i].name);
+ for(j=0; j< 7-strlen(dumpregs[i].name); j++) printk(" ");
+ printk(" %08X\n", frame->regs[dumpregs[i].offset] );
}
+
+ rtems_fatal_error_occurred(1);
+}
+
+
+
+
+
+
+
+#define CALL_EXC(_vector,_frame) \
+ do { \
+ if( _ISR_Vector_table[_vector] ) \
+ (_ISR_Vector_table[_vector])(_vector,_frame); \
+ else \
+ mips_default_exception_code_handler( _vector, _frame ); \
+ } while(0)
+
+
+
+
- if ( cause & 0x02 ) /* SW[0] */
- CALL_ISR( MONGOOSEV_IRQ_SOFTWARE_1 );
+void mips_vector_exceptions( CPU_Interrupt_frame *frame )
+{
+ unsigned32 cause;
+ unsigned32 exc;
+
+ mips_get_cause( cause );
+ exc = (cause >> 2) & 0x1f;
+
+ if( exc == 4 )
+ CALL_EXC( MONGOOSEV_EXCEPTION_ADEL, frame );
+
+ else if( exc == 5 )
+ CALL_EXC( MONGOOSEV_EXCEPTION_ADES, frame );
+
+ else if( exc == 6 )
+ CALL_EXC( MONGOOSEV_EXCEPTION_IBE, frame );
+
+ else if( exc == 7 )
+ CALL_EXC( MONGOOSEV_EXCEPTION_DBE, frame );
+
+ else if( exc == 8 )
+ CALL_EXC( MONGOOSEV_EXCEPTION_SYSCALL, frame );
- if ( cause & 0x01 ) /* IP[1] */
- CALL_ISR( MONGOOSEV_IRQ_SOFTWARE_2 );
+ else if( exc == 9 )
+ CALL_EXC( MONGOOSEV_EXCEPTION_BREAK, frame );
+
+ else if( exc == 10 )
+ CALL_EXC( MONGOOSEV_EXCEPTION_RI, frame );
+
+ else if( exc == 11 )
+ CALL_EXC( MONGOOSEV_EXCEPTION_CPU, frame );
+
+ else if( exc == 12 )
+ CALL_EXC( MONGOOSEV_EXCEPTION_OVERFLOW, frame );
+
+ else
+ mips_default_exception_code_handler( exc, frame );
}
+
+
+// eof
+