From 2e7ed911d7a99274d5268498a3466de06f580d8a Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 22 May 2001 23:20:14 +0000 Subject: 2001-05-22 Greg Menke * Assisted in design and debug by Joel Sherrill . * mongoosev/duart/mg5uart.c, mongoosev/duart/mg5uart.h, mongoosev/include/mongoose-v.h, mongoosev/vectorisrs/vectorisrs.c, shared/interrupts/maxvectors.c: Now works. Significant rework of exceptions and interrupt vectoring to clean things up. * shared/interrupts/vectorexceptions.c: Removed. * shared/interrupts/Makefile.am: Reflects above. --- c/src/lib/libcpu/mips/ChangeLog | 9 + c/src/lib/libcpu/mips/mongoosev/duart/mg5uart.c | 417 +++++++++++++-------- c/src/lib/libcpu/mips/mongoosev/duart/mg5uart.h | 22 +- .../lib/libcpu/mips/mongoosev/include/mongoose-v.h | 244 +++++++----- .../libcpu/mips/mongoosev/vectorisrs/vectorisrs.c | 321 ++++++++++++++-- .../lib/libcpu/mips/shared/interrupts/Makefile.am | 2 +- .../lib/libcpu/mips/shared/interrupts/maxvectors.c | 5 +- .../mips/shared/interrupts/vectorexceptions.c | 90 ----- 8 files changed, 721 insertions(+), 389 deletions(-) delete mode 100644 c/src/lib/libcpu/mips/shared/interrupts/vectorexceptions.c (limited to 'c/src/lib') diff --git a/c/src/lib/libcpu/mips/ChangeLog b/c/src/lib/libcpu/mips/ChangeLog index 0759726250..46715a8c30 100644 --- a/c/src/lib/libcpu/mips/ChangeLog +++ b/c/src/lib/libcpu/mips/ChangeLog @@ -1,3 +1,12 @@ +2001-05-22 Greg Menke + + * Assisted in design and debug by Joel Sherrill . + * mongoosev/duart/mg5uart.c, mongoosev/duart/mg5uart.h, + mongoosev/include/mongoose-v.h, mongoosev/vectorisrs/vectorisrs.c, + shared/interrupts/maxvectors.c: Now works. Significant rework + of exceptions and interrupt vectoring to clean things up. + * shared/interrupts/vectorexceptions.c: Removed. + 2001-05-07 Joel Sherrill * shared/interrupts/vectorexceptions.c: New file to decode diff --git a/c/src/lib/libcpu/mips/mongoosev/duart/mg5uart.c b/c/src/lib/libcpu/mips/mongoosev/duart/mg5uart.c index 041a5b0819..14ed892cbb 100644 --- a/c/src/lib/libcpu/mips/mongoosev/duart/mg5uart.c +++ b/c/src/lib/libcpu/mips/mongoosev/duart/mg5uart.c @@ -45,12 +45,15 @@ typedef struct _mg5uart_context /* #define MG5UART_STATIC static */ + + #define MG5UART_SETREG( _base, _register, _value ) \ MONGOOSEV_WRITE_REGISTER( _base, _register, _value ) #define MG5UART_GETREG( _base, _register ) \ MONGOOSEV_READ_REGISTER( _base, _register ) + /* * Console Device Driver Support Functions */ @@ -73,16 +76,16 @@ MG5UART_STATIC void mg5uart_enable_interrupts( * port settings. */ -MG5UART_STATIC int mg5uart_set_attributes( +MG5UART_STATIC int mg5uart_set_attributes( int minor, const struct termios *t ) { unsigned32 pMG5UART_port; unsigned32 pMG5UART; - unsigned int cmd; - unsigned int baudcmd; - unsigned int portshift; + unsigned32 cmd, cmdSave; + unsigned32 baudcmd; + unsigned32 shift; rtems_interrupt_level Irql; pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1; @@ -103,7 +106,7 @@ MG5UART_STATIC int mg5uart_set_attributes( * Base settings */ - cmd = MONGOOSEV_UART_CMD_TX_ENABLE | MONGOOSEV_UART_CMD_TX_ENABLE; + cmd = MONGOOSEV_UART_CMD_RX_ENABLE | MONGOOSEV_UART_CMD_TX_ENABLE; /* * Parity @@ -125,22 +128,22 @@ MG5UART_STATIC int mg5uart_set_attributes( if (t->c_cflag & CSIZE) { switch (t->c_cflag & CSIZE) { - case CS5: - case CS6: - case CS7: + case CS5: + case CS6: + case CS7: return -1; break; case CS8: /* Mongoose-V only supports CS8 */ break; - + } } /* else default to CS8 */ /* * Stop Bits */ - + #if 0 if (t->c_cflag & CSTOPB) { /* 2 stop bits not supported by Mongoose-V uart */ @@ -159,13 +162,22 @@ MG5UART_STATIC int mg5uart_set_attributes( */ if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 ) - portshift = MONGOOSEV_UART0_CMD_SHIFT; + shift = MONGOOSEV_UART0_CMD_SHIFT; else - portshift = MONGOOSEV_UART1_CMD_SHIFT; + shift = MONGOOSEV_UART1_CMD_SHIFT; + + rtems_interrupt_disable(Irql); - MG5UART_SETREG( pMG5UART, MG5UART_COMMAND_REGISTER, cmd << portshift ); - MG5UART_SETREG( pMG5UART_port, MG5UART_BAUD_RATE, baudcmd ); + + cmdSave = MG5UART_GETREG( pMG5UART, MG5UART_COMMAND_REGISTER ); + + MG5UART_SETREG( pMG5UART, + MG5UART_COMMAND_REGISTER, + (cmdSave & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift)) | (cmd << shift) ); + + MG5UART_SETREG( pMG5UART_port, MG5UART_BAUD_RATE, baudcmd ); + rtems_interrupt_enable(Irql); return 0; } @@ -184,14 +196,14 @@ MG5UART_STATIC void mg5uart_initialize_context( int port; unsigned int pMG5UART; unsigned int pMG5UART_port; - + pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1; pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2; pmg5uartContext->mate = -1; for (port=0 ; portmate = port; break; @@ -208,8 +220,11 @@ MG5UART_STATIC void mg5uart_initialize_context( MG5UART_STATIC void mg5uart_init(int minor) { - unsigned32 pMG5UART_port; - unsigned32 pMG5UART; + unsigned32 pMG5UART_port; + unsigned32 pMG5UART; + unsigned32 cmdSave; + unsigned32 shift; + mg5uart_context *pmg5uartContext; pmg5uartContext = (mg5uart_context *) malloc(sizeof(mg5uart_context)); @@ -221,16 +236,22 @@ MG5UART_STATIC void mg5uart_init(int minor) pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1; pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2; + if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 ) + shift = MONGOOSEV_UART0_CMD_SHIFT; + else + shift = MONGOOSEV_UART1_CMD_SHIFT; + /* - * Reset everything and leave this port disabled. + * Disable the uart and leave this port disabled. */ - MG5UART_SETREG( pMG5UART, 0, MONGOOSEV_UART_CMD_RESET_BOTH_PORTS ); + cmdSave = MG5UART_GETREG(pMG5UART, MG5UART_COMMAND_REGISTER) & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift); + + MG5UART_SETREG( pMG5UART, MG5UART_COMMAND_REGISTER, cmdSave ); /* * Disable interrupts on RX and TX for this port */ - mg5uart_enable_interrupts( minor, MG5UART_DISABLE_ALL ); } @@ -248,37 +269,46 @@ MG5UART_STATIC int mg5uart_open( void *arg ) { - unsigned32 pMG5UART; - unsigned32 pMG5UART_port; - unsigned int vector; - unsigned int cmd; - unsigned int baudcmd; - unsigned int portshift; + unsigned32 pMG5UART; + unsigned32 pMG5UART_port; + unsigned32 vector; + unsigned32 cmd, cmdSave; + unsigned32 baudcmd; + unsigned32 shift; + rtems_interrupt_level Irql; pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1; pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2; vector = Console_Port_Tbl[minor].ulIntVector; + if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 ) + shift = MONGOOSEV_UART0_CMD_SHIFT; + else + shift = MONGOOSEV_UART1_CMD_SHIFT; + + /* XXX default baud rate could be from configuration table */ (void) mg5uart_baud_rate( minor, B19200, &baudcmd ); /* * Set the DUART channel to a default useable state - * B9600, 8Nx since there is no stop bit control. + * B19200, 8Nx since there is no stop bit control. */ cmd = MONGOOSEV_UART_CMD_TX_ENABLE | MONGOOSEV_UART_CMD_RX_ENABLE; - if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 ) - portshift = MONGOOSEV_UART0_CMD_SHIFT; - else - portshift = MONGOOSEV_UART1_CMD_SHIFT; - rtems_interrupt_disable(Irql); - MG5UART_SETREG( pMG5UART, MG5UART_COMMAND_REGISTER, cmd << portshift ); - MG5UART_SETREG( pMG5UART_port, MG5UART_BAUD_RATE, baudcmd ); + + cmdSave = MG5UART_GETREG( pMG5UART, MG5UART_COMMAND_REGISTER ); + + MG5UART_SETREG( pMG5UART_port, MG5UART_BAUD_RATE, baudcmd ); + + MG5UART_SETREG( pMG5UART, + MG5UART_COMMAND_REGISTER, + cmd = (cmdSave & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift)) | (cmd << shift) ); + rtems_interrupt_enable(Irql); return RTEMS_SUCCESSFUL; @@ -296,10 +326,11 @@ MG5UART_STATIC int mg5uart_close( void *arg ) { - unsigned32 pMG5UART; - unsigned32 pMG5UART_port; - unsigned int cmd; - unsigned int portshift; + unsigned32 pMG5UART; + unsigned32 pMG5UART_port; + unsigned32 cmd, cmdSave; + unsigned32 shift; + rtems_interrupt_level Irql; pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1; pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2; @@ -313,23 +344,33 @@ MG5UART_STATIC int mg5uart_close( cmd = MONGOOSEV_UART_CMD_TX_DISABLE | MONGOOSEV_UART_CMD_RX_DISABLE; if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 ) - portshift = MONGOOSEV_UART0_CMD_SHIFT; + shift = MONGOOSEV_UART0_CMD_SHIFT; else - portshift = MONGOOSEV_UART1_CMD_SHIFT; + shift = MONGOOSEV_UART1_CMD_SHIFT; + + + rtems_interrupt_disable(Irql); + cmdSave = MG5UART_GETREG( pMG5UART, MG5UART_COMMAND_REGISTER ); - MG5UART_SETREG( pMG5UART, MG5UART_COMMAND_REGISTER, cmd << portshift ); + MG5UART_SETREG( pMG5UART, + MG5UART_COMMAND_REGISTER, + (cmdSave & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift)) | (cmd << shift) ); + rtems_interrupt_enable(Irql); return(RTEMS_SUCCESSFUL); } -/* + + + +/* * mg5uart_write_polled * * This routine polls out the requested character. */ MG5UART_STATIC void mg5uart_write_polled( - int minor, + int minor, char c ) { @@ -350,27 +391,31 @@ MG5UART_STATIC void mg5uart_write_polled( /* * wait for transmitter holding register to be empty */ - timeout = 1000; - status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER); - while ( 1 ) { + timeout = 2000; + + while( --timeout ) + { status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER) >> shift; - - if ( (status & (MONGOOSEV_UART_TX_READY|MONGOOSEV_UART_TX_EMPTY_0)) == - (MONGOOSEV_UART_TX_READY|MONGOOSEV_UART_TX_EMPTY_0) ) + + /* + if ( (status & (MONGOOSEV_UART_TX_READY | MONGOOSEV_UART_TX_EMPTY)) == + (MONGOOSEV_UART_TX_READY | MONGOOSEV_UART_TX_EMPTY) ) break; + */ + + if( (status & (MONGOOSEV_UART_TX_READY | MONGOOSEV_UART_TX_EMPTY)) ) + break; /* * Yield while we wait */ #if 0 - if(_System_state_Is_up(_System_state_Get())) { + if(_System_state_Is_up(_System_state_Get())) + { rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); } #endif - if(!--timeout) { - break; - } } /* @@ -380,6 +425,9 @@ MG5UART_STATIC void mg5uart_write_polled( MG5UART_SETREG(pMG5UART_port, MG5UART_TX_BUFFER, c); } + + + /* * mg5uart_isr_XXX * @@ -388,7 +436,7 @@ MG5UART_STATIC void mg5uart_write_polled( * shared handler gets the right arguments. * * NOTE: Yes .. this is ugly but it provides 5 interrupt source - * wrappers which are nearly functionally identical. + * wrappers which are nearly functionally identical. */ @@ -401,14 +449,17 @@ MG5UART_STATIC void mg5uart_write_polled( rtems_vector_number vector \ ) \ { \ - int minor; \ + int minor; \ + extern void mips_default_isr(int vector); \ \ for(minor=0 ; minor> shift; - if ( status & MONGOOSEV_UART_RX_READY ) { - return (int) MG5UART_GETREG(pMG5UART_port, MG5UART_RX_BUFFER); - } else { - return -1; + + if( (tmp = (status & 0x3)) ) + { + MG5UART_SETREG(pMG5UART, MG5UART_STATUS_REGISTER, (tmp << shift) ); + status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER) >> shift; + } + + if ( status & MONGOOSEV_UART_RX_READY ) + { + return (int) MG5UART_GETREG(pMG5UART_port, MG5UART_RX_BUFFER); + } + else + { + return -1; } } @@ -685,7 +761,7 @@ MG5UART_STATIC int mg5uart_baud_rate( baud_requested = baud & CBAUD; if (!baud_requested) baud_requested = B9600; /* default to 9600 baud */ - + baud_requested = termios_baud_to_number( baud_requested ); clock = (rtems_unsigned32) Console_Port_Tbl[minor].ulClock; @@ -694,6 +770,9 @@ MG5UART_STATIC int mg5uart_baud_rate( /* * Formula is Code = round(ClockFrequency / Baud - 1). + * + * Since this is integer math, we will divide by twice the baud and + * check the remaining odd bit. */ tmp_code = (clock / baud_requested) - 1; @@ -702,7 +781,7 @@ MG5UART_STATIC int mg5uart_baud_rate( * From section 12.7, "Keep C>100 for best receiver operation." * That is 100 cycles which is not a lot of instructions. It is * reasonable to think that the Mongoose-V could not keep - * up with C < 200. + * up with C < 100. */ if ( tmp_code < 100 ) @@ -713,9 +792,13 @@ MG5UART_STATIC int mg5uart_baud_rate( */ *code = (tmp_code << 16) | tmp_code; + return 0; } + + + /* * mg5uart_enable_interrupts * @@ -728,8 +811,9 @@ MG5UART_STATIC void mg5uart_enable_interrupts( ) { unsigned32 pMG5UART; - unsigned32 shifted_mask; - unsigned32 shifted_bits; + unsigned32 maskSave; + unsigned32 shift; + rtems_interrupt_level Irql; pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1; @@ -737,24 +821,26 @@ MG5UART_STATIC void mg5uart_enable_interrupts( * Enable interrupts on RX and TX -- not break */ - shifted_bits = MONGOOSEV_UART_ALL_IRQ_BITS; - shifted_mask = mask; + if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 ) + shift = MONGOOSEV_UART0_IRQ_SHIFT; + else + shift = MONGOOSEV_UART1_IRQ_SHIFT; - if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 ) { - shifted_bits <<= MONGOOSEV_UART0_IRQ_SHIFT; - shifted_mask <<= MONGOOSEV_UART0_IRQ_SHIFT; - } else { - shifted_bits <<= MONGOOSEV_UART1_IRQ_SHIFT; - shifted_mask <<= MONGOOSEV_UART1_IRQ_SHIFT; - } - MONGOOSEV_ATOMIC_MASK( - MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_MASK_REGISTER, - shifted_bits, - shifted_mask - ); + rtems_interrupt_disable(Irql); + + maskSave = MG5UART_GETREG( pMG5UART, MG5UART_INTERRUPT_MASK_REGISTER ); + + MG5UART_SETREG( + pMG5UART, + MG5UART_INTERRUPT_MASK_REGISTER, + (maskSave & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift)) | (mask << shift) ); + + rtems_interrupt_enable(Irql); } + + /* * Flow control is only supported when using interrupts */ @@ -785,3 +871,4 @@ console_fns mg5uart_fns_polled = FALSE, /* deviceOutputUsesInterrupts */ }; + diff --git a/c/src/lib/libcpu/mips/mongoosev/duart/mg5uart.h b/c/src/lib/libcpu/mips/mongoosev/duart/mg5uart.h index 11cc7ab686..04d3d40916 100644 --- a/c/src/lib/libcpu/mips/mongoosev/duart/mg5uart.h +++ b/c/src/lib/libcpu/mips/mongoosev/duart/mg5uart.h @@ -34,22 +34,32 @@ extern "C" { */ /* shared registers from peripheral base (i.e. from ulCtrlPort1) */ -#define MG5UART_COMMAND_REGISTER 0x00 +/* +#define MG5UART_COMMAND_REGISTER 0 +#define MG5UART_STATUS_REGISTER 1 +#define MG5UART_INTERRUPT_CAUSE_REGISTER 2 +#define MG5UART_INTERRUPT_MASK_REGISTER 3 +*/ + +#define MG5UART_COMMAND_REGISTER 0 #define MG5UART_STATUS_REGISTER 0x04 #define MG5UART_INTERRUPT_CAUSE_REGISTER 0x08 -#define MG5UART_INTERRUPT_MASK_REGISTER 0x0c +#define MG5UART_INTERRUPT_MASK_REGISTER 0x0C /* port specific registers from uart base (i.e. from ulCtrlPort2) */ -#define MG5UART_RX_BUFFER 0x00 -#define MG5UART_TX_BUFFER 0x04 -#define MG5UART_BAUD_RATE 0x08 +#define MG5UART_RX_BUFFER 0 +#define MG5UART_TX_BUFFER 4 +#define MG5UART_BAUD_RATE 8 /* * Interrupt mask values */ #define MG5UART_ENABLE_ALL_EXCEPT_TX MONGOOSEV_UART_ALL_RX_STATUS_BITS -#define MG5UART_ENABLE_ALL (MONGOOSEV_UART_ALL_STATUS_BITS) + +/* all rx ints on, but only tx ready. no need to also int on tx empty */ +#define MG5UART_ENABLE_ALL (MONGOOSEV_UART_ALL_STATUS_BITS & ~MONGOOSEV_UART_TX_EMPTY) + #define MG5UART_DISABLE_ALL 0x0000 /* diff --git a/c/src/lib/libcpu/mips/mongoosev/include/mongoose-v.h b/c/src/lib/libcpu/mips/mongoosev/include/mongoose-v.h index 9aec242556..1876ee56f7 100644 --- a/c/src/lib/libcpu/mips/mongoosev/include/mongoose-v.h +++ b/c/src/lib/libcpu/mips/mongoosev/include/mongoose-v.h @@ -18,28 +18,29 @@ * Macros to assist in accessing memory mapped Mongoose registers */ + #define MONGOOSEV_READ( _base ) \ - *((volatile unsigned32 *)(_base)) + ( *((volatile unsigned32 *)(_base)) ) #define MONGOOSEV_WRITE( _base, _value ) \ - *((volatile unsigned32 *)(_base)) = (_value) + ( *((volatile unsigned32 *)(_base)) = (_value) ) #define MONGOOSEV_READ_REGISTER( _base, _register ) \ - *((volatile unsigned32 *)((_base) + (_register))) + ( *((volatile unsigned32 *)((_base) + (_register))) ) #define MONGOOSEV_WRITE_REGISTER( _base, _register, _value ) \ - *((volatile unsigned32 *)((_base) + (_register))) = (_value) - -#define MONGOOSEV_ATOMIC_MASK( _addr, _mask, _new ) \ - do { \ - rtems_interrupt_level Irql; \ - rtems_unsigned32 tmp; \ - \ - rtems_interrupt_disable(Irql); \ - tmp = *((volatile unsigned32 *)(_addr)) & ~(_mask); \ - *((volatile unsigned32 *)(_addr)) = tmp | (_new); \ - rtems_interrupt_enable(Irql); \ - } while (0) + ( *((volatile unsigned32 *)((_base) + (_register))) = (_value) ) + + + + + +/* + * Macros to read/write the Mongoose FPU control register. + */ + + + /* * BIU and DRAM Registers @@ -61,33 +62,22 @@ #define MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_CAUSE_REGISTER 0xFFFE0188 #define MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_MASK_REGISTER 0xFFFE018C -#define MONGOOSEV_PFICR MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_CAUSE_REGISTER -#define MONGOOSEV_PFIMR MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_MASK_REGISTER - -#define mongoosev_set_in_pficr( _mask, _bits ) \ - MONGOOSEV_ATOMIC_MASK( MONGOOSEV_PFICR, _mask, _bits ) -#define mongoosev_clear_in_pficr( _mask, _bits ) \ - MONGOOSEV_ATOMIC_MASK( MONGOOSEV_PFICR, _mask, ~(_bits) ) - -#define mongoosev_set_in_pfimr( _mask, _bits ) \ - MONGOOSEV_ATOMIC_MASK( MONGOOSEV_PFIMR, _mask, _bits ) -#define mongoosev_clear_in_pfimr( _mask, _bits ) \ - MONGOOSEV_ATOMIC_MASK( MONGOOSEV_PFIMR, _mask, ~(_bits) ) +#define MONGOOSEV_WATCHDOG 0xBE000000 /* UART Bits in Peripheral Command Register Bits (TX/RX tied together here) */ -#define MONGOOSEV_UART_CMD_RESET_BOTH_PORTS 0x0001 -#define MONGOOSEV_UART_CMD_LOOPBACK_CTSN 0x0002 -#define MONGOOSEV_UART_CMD_LOOPBACK_RXTX 0x0004 - -#define MONGOOSEV_UART_CMD_TX_ENABLE 0x001 -#define MONGOOSEV_UART_CMD_TX_DISABLE 0x000 -#define MONGOOSEV_UART_CMD_RX_ENABLE 0x002 -#define MONGOOSEV_UART_CMD_RX_DISABLE 0x000 -#define MONGOOSEV_UART_CMD_TX_READY 0x004 -#define MONGOOSEV_UART_CMD_PARITY_ENABLE 0x008 -#define MONGOOSEV_UART_CMD_PARITY_DISABLE 0x000 -#define MONGOOSEV_UART_CMD_PARITY_EVEN 0x800 -#define MONGOOSEV_UART_CMD_PARITY_ODD 0x000 +#define MONGOOSEV_UART_CMD_RESET_BOTH_PORTS 0x0001 +#define MONGOOSEV_UART_CMD_LOOPBACK_CTSN 0x0002 +#define MONGOOSEV_UART_CMD_LOOPBACK_RXTX 0x0004 + +#define MONGOOSEV_UART_CMD_RX_ENABLE 0x001 +#define MONGOOSEV_UART_CMD_RX_DISABLE 0x000 +#define MONGOOSEV_UART_CMD_TX_ENABLE 0x002 +#define MONGOOSEV_UART_CMD_TX_DISABLE 0x000 +#define MONGOOSEV_UART_CMD_TX_READY 0x004 +#define MONGOOSEV_UART_CMD_PARITY_ENABLE 0x008 +#define MONGOOSEV_UART_CMD_PARITY_DISABLE 0x000 +#define MONGOOSEV_UART_CMD_PARITY_EVEN 0x010 +#define MONGOOSEV_UART_CMD_PARITY_ODD 0x000 #define MONGOOSEV_UART0_CMD_SHIFT 5 #define MONGOOSEV_UART1_CMD_SHIFT 11 @@ -129,9 +119,8 @@ #define MONGOOSEV_UART_TX_READY 0x0008 #define MONGOOSEV_UART_RX_READY 0x0010 -#define MONGOOSEV_UART_ALL_RX_STATUS_BITS 0x0003 +#define MONGOOSEV_UART_ALL_RX_STATUS_BITS 0x0013 #define MONGOOSEV_UART_ALL_STATUS_BITS 0x001F -#define MONGOOSEV_UART_ALL_IRQ_BITS 0x001F /* * The Peripheral Interrupt Status, Cause, and Mask registers have the @@ -173,21 +162,21 @@ */ #define MONGOOSEV_EDAC_SERR_BIT 0x80000000 #define MONGOOSEV_EDAC_MERR_BIT 0x40000000 +#define MONGOOSEV_MAVN_WRITE_ACCESS 0x00800000 +#define MONGOOSEV_MAVN_READ_ACCESS 0x00400000 /* 29 - 24 reserved */ -#define MONGOOSEV_UART_0_RX_READY 0x00008000 -#define MONGOOSEV_UART_0_TX_READY 0x00004000 -#define MONGOOSEV_UART_0_TX_EMPTY 0x00002000 -#define MONGOOSEV_UART_0_RX_OVERRUN 0x00001000 -#define MONGOOSEV_UART_0_FRAME_ERROR 0x00000800 -#define MONGOOSEV_UART_0_RESERVED 0x00000400 #define MONGOOSEV_UART_1_RX_READY 0x00200000 #define MONGOOSEV_UART_1_TX_READY 0x00100000 #define MONGOOSEV_UART_1_TX_EMPTY 0x00080000 #define MONGOOSEV_UART_1_RX_OVERRUN 0x00040000 #define MONGOOSEV_UART_1_FRAME_ERROR 0x00020000 -#define MONGOOSEV_UART_1_RESERVED 0x00010000 -#define MONGOOSEV_MAVN_WRITE_ACCESS 0x00400000 -#define MONGOOSEV_MAVN_READ_ACCESS 0x00800000 +#define MONGOOSEV_RESERVED_16 0x00010000 +#define MONGOOSEV_UART_0_RX_READY 0x00008000 +#define MONGOOSEV_UART_0_TX_READY 0x00004000 +#define MONGOOSEV_UART_0_TX_EMPTY 0x00002000 +#define MONGOOSEV_UART_0_RX_OVERRUN 0x00001000 +#define MONGOOSEV_UART_0_FRAME_ERROR 0x00000800 +#define MONGOOSEV_RESERVED_10 0x00000400 #define MONGOOSEV_EXTERN_INT_9 0x00000200 #define MONGOOSEV_EXTERN_INT_8 0x00000100 #define MONGOOSEV_EXTERN_INT_7 0x00000080 @@ -264,43 +253,122 @@ #define MONGOOSEV_IRQ_INT1 1 #define MONGOOSEV_IRQ_TIMER2 MONGOOSEV_IRQ_INT1 #define MONGOOSEV_IRQ_INT2 2 -#define MONGOOSEV_IRQ_INT4 3 +#define MONGOOSEV_IRQ_INT3 3 +#define MONGOOSEV_IRQ_FPU MONGOOSEV_IRQ_INT3 + +#define MONGOOSEV_IRQ_INT4 4 + /* MONGOOSEV_IRQ_INT5 indicates that a peripheral caused the IRQ. */ -#define MONGOOSEV_IRQ_PERIPHERAL_BASE 4 -#define MONGOOSEV_IRQ_XINT0 4 -#define MONGOOSEV_IRQ_XINT1 5 -#define MONGOOSEV_IRQ_XINT2 6 -#define MONGOOSEV_IRQ_XINT3 7 -#define MONGOOSEV_IRQ_XINT4 8 -#define MONGOOSEV_IRQ_XINT5 9 -#define MONGOOSEV_IRQ_XINT6 10 -#define MONGOOSEV_IRQ_XINT7 11 -#define MONGOOSEV_IRQ_XINT8 12 -#define MONGOOSEV_IRQ_XINT9 13 -#define MONGOOSEV_IRQ_READ_ACCESS_VIOLATION 14 -#define MONGOOSEV_IRQ_WRITE_ACCESS_VIOLATION 15 -#define MONGOOSEV_IRQ_RESERVED_BIT_12 16 -#define MONGOOSEV_IRQ_UART1_RX_FRAME_ERROR 17 -#define MONGOOSEV_IRQ_UART1_RX_OVERRUN_ERROR 18 -#define MONGOOSEV_IRQ_UART1_TX_EMPTY 19 -#define MONGOOSEV_IRQ_UART1_TX_READY 20 -#define MONGOOSEV_IRQ_UART1_RX_READY 21 -#define MONGOOSEV_IRQ_RESERVED_BIT_18 22 -#define MONGOOSEV_IRQ_UART0_RX_FRAME_ERROR 23 -#define MONGOOSEV_IRQ_UART0_RX_OVERRUN_ERROR 24 -#define MONGOOSEV_IRQ_UART0_TX_EMPTY 25 -#define MONGOOSEV_IRQ_UART0_TX_READY 26 -#define MONGOOSEV_IRQ_UART0_RX_READY 27 -#define MONGOOSEV_IRQ_RESERVED_24 28 -#define MONGOOSEV_IRQ_RESERVED_25 29 -#define MONGOOSEV_IRQ_RESERVED_26 30 -#define MONGOOSEV_IRQ_RESERVED_27 31 -#define MONGOOSEV_IRQ_RESERVED_28 32 -#define MONGOOSEV_IRQ_RESERVED_29 33 -#define MONGOOSEV_IRQ_UNCORRECTABLE_ERROR 34 -#define MONGOOSEV_IRQ_CORRECTABLE_ERROR 35 - -#define MONGOOSEV_IRQ_SOFTWARE_1 36 -#define MONGOOSEV_IRQ_SOFTWARE_2 37 +#define MONGOOSEV_IRQ_PERIPHERAL_BASE 5 +#define MONGOOSEV_IRQ_XINT0 MONGOOSEV_IRQ_PERIPHERAL_BASE + 0 +#define MONGOOSEV_IRQ_XINT1 MONGOOSEV_IRQ_PERIPHERAL_BASE + 1 +#define MONGOOSEV_IRQ_XINT2 MONGOOSEV_IRQ_PERIPHERAL_BASE + 2 +#define MONGOOSEV_IRQ_XINT3 MONGOOSEV_IRQ_PERIPHERAL_BASE + 3 +#define MONGOOSEV_IRQ_XINT4 MONGOOSEV_IRQ_PERIPHERAL_BASE + 4 +#define MONGOOSEV_IRQ_XINT5 MONGOOSEV_IRQ_PERIPHERAL_BASE + 5 +#define MONGOOSEV_IRQ_XINT6 MONGOOSEV_IRQ_PERIPHERAL_BASE + 6 +#define MONGOOSEV_IRQ_XINT7 MONGOOSEV_IRQ_PERIPHERAL_BASE + 7 +#define MONGOOSEV_IRQ_XINT8 MONGOOSEV_IRQ_PERIPHERAL_BASE + 8 +#define MONGOOSEV_IRQ_XINT9 MONGOOSEV_IRQ_PERIPHERAL_BASE + 9 +#define MONGOOSEV_IRQ_RESERVED_BIT_10 MONGOOSEV_IRQ_PERIPHERAL_BASE + 10 +#define MONGOOSEV_IRQ_UART0_RX_FRAME_ERROR MONGOOSEV_IRQ_PERIPHERAL_BASE + 11 +#define MONGOOSEV_IRQ_UART0_RX_OVERRUN_ERROR MONGOOSEV_IRQ_PERIPHERAL_BASE + 12 +#define MONGOOSEV_IRQ_UART0_TX_EMPTY MONGOOSEV_IRQ_PERIPHERAL_BASE + 13 +#define MONGOOSEV_IRQ_UART0_TX_READY MONGOOSEV_IRQ_PERIPHERAL_BASE + 14 +#define MONGOOSEV_IRQ_UART0_RX_READY MONGOOSEV_IRQ_PERIPHERAL_BASE + 15 +#define MONGOOSEV_IRQ_RESERVED_BIT_16 MONGOOSEV_IRQ_PERIPHERAL_BASE + 16 +#define MONGOOSEV_IRQ_UART1_RX_FRAME_ERROR MONGOOSEV_IRQ_PERIPHERAL_BASE + 17 +#define MONGOOSEV_IRQ_UART1_RX_OVERRUN_ERROR MONGOOSEV_IRQ_PERIPHERAL_BASE + 18 +#define MONGOOSEV_IRQ_UART1_TX_EMPTY MONGOOSEV_IRQ_PERIPHERAL_BASE + 19 +#define MONGOOSEV_IRQ_UART1_TX_READY MONGOOSEV_IRQ_PERIPHERAL_BASE + 20 +#define MONGOOSEV_IRQ_UART1_RX_READY MONGOOSEV_IRQ_PERIPHERAL_BASE + 21 +#define MONGOOSEV_IRQ_READ_ACCESS_VIOLATION MONGOOSEV_IRQ_PERIPHERAL_BASE + 22 +#define MONGOOSEV_IRQ_WRITE_ACCESS_VIOLATION MONGOOSEV_IRQ_PERIPHERAL_BASE + 23 +#define MONGOOSEV_IRQ_RESERVED_24 MONGOOSEV_IRQ_PERIPHERAL_BASE + 24 +#define MONGOOSEV_IRQ_RESERVED_25 MONGOOSEV_IRQ_PERIPHERAL_BASE + 25 +#define MONGOOSEV_IRQ_RESERVED_26 MONGOOSEV_IRQ_PERIPHERAL_BASE + 26 +#define MONGOOSEV_IRQ_RESERVED_27 MONGOOSEV_IRQ_PERIPHERAL_BASE + 27 +#define MONGOOSEV_IRQ_RESERVED_28 MONGOOSEV_IRQ_PERIPHERAL_BASE + 28 +#define MONGOOSEV_IRQ_RESERVED_29 MONGOOSEV_IRQ_PERIPHERAL_BASE + 29 +#define MONGOOSEV_IRQ_UNCORRECTABLE_ERROR MONGOOSEV_IRQ_PERIPHERAL_BASE + 30 +#define MONGOOSEV_IRQ_CORRECTABLE_ERROR MONGOOSEV_IRQ_PERIPHERAL_BASE + 31 + +#define MONGOOSEV_IRQ_SOFTWARE_1 37 +#define MONGOOSEV_IRQ_SOFTWARE_2 38 + + +/* gdm, 5/14. Added exception vectoring to the ISR table- these +entries are never called by the ISR servicing, only by the exception +servicing routine. The ISR table is used because vector setup there +is already supported. Please note exception routines are passed 2 +parameters; one of the below vectors and a pointer to the exception's +stack frame, the register layout of which is found in + +exec/score/cpu/mips/iregdef.h + +in conjunction with + +exec/score/cpu/mips/cpu_asm.S + +*/ + +#define MONGOOSEV_EXCEPTION_BASE 39 + +#define MONGOOSEV_EXCEPTION_ADEL MONGOOSEV_EXCEPTION_BASE+0 +#define MONGOOSEV_EXCEPTION_ADES MONGOOSEV_EXCEPTION_BASE+1 +#define MONGOOSEV_EXCEPTION_IBE MONGOOSEV_EXCEPTION_BASE+2 +#define MONGOOSEV_EXCEPTION_DBE MONGOOSEV_EXCEPTION_BASE+3 +#define MONGOOSEV_EXCEPTION_SYSCALL MONGOOSEV_EXCEPTION_BASE+4 +#define MONGOOSEV_EXCEPTION_BREAK MONGOOSEV_EXCEPTION_BASE+5 +#define MONGOOSEV_EXCEPTION_RI MONGOOSEV_EXCEPTION_BASE+6 +#define MONGOOSEV_EXCEPTION_CPU MONGOOSEV_EXCEPTION_BASE+7 +#define MONGOOSEV_EXCEPTION_OVERFLOW MONGOOSEV_EXCEPTION_BASE+8 + + + + + + +#define SR_CUMASK 0xf0000000 /* coproc usable bits */ +#define SR_CU3 0x80000000 /* Coprocessor 3 usable */ +#define SR_CU2 0x40000000 /* Coprocessor 2 usable */ +#define SR_CU1 0x20000000 /* Coprocessor 1 usable */ +#define SR_CU0 0x10000000 /* Coprocessor 0 usable */ +#define SR_BEV 0x00400000 /* use boot exception vectors */ +#define SR_TS 0x00200000 /* TLB shutdown */ +#define SR_PE 0x00100000 /* cache parity error */ +#define SR_CM 0x00080000 /* cache miss */ +#define SR_PZ 0x00040000 /* cache parity zero */ +#define SR_SWC 0x00020000 /* swap cache */ +#define SR_ISC 0x00010000 /* Isolate data cache */ +#define SR_IMASK 0x0000ff00 /* Interrupt mask */ +#define SR_IMASK8 0x00000000 /* mask level 8 */ +#define SR_IMASK7 0x00008000 /* mask level 7 */ +#define SR_IMASK6 0x0000c000 /* mask level 6 */ +#define SR_IMASK5 0x0000e000 /* mask level 5 */ +#define SR_IMASK4 0x0000f000 /* mask level 4 */ +#define SR_IMASK3 0x0000f800 /* mask level 3 */ +#define SR_IMASK2 0x0000fc00 /* mask level 2 */ +#define SR_IMASK1 0x0000fe00 /* mask level 1 */ +#define SR_IMASK0 0x0000ff00 /* mask level 0 */ + +#define SR_IBIT8 0x00008000 /* bit level 8 */ +#define SR_IBIT7 0x00004000 /* bit level 7 */ +#define SR_IBIT6 0x00002000 /* bit level 6 */ +#define SR_IBIT5 0x00001000 /* bit level 5 */ +#define SR_IBIT4 0x00000800 /* bit level 4 */ +#define SR_IBIT3 0x00000400 /* bit level 3 */ +#define SR_IBIT2 0x00000200 /* bit level 2 */ +#define SR_IBIT1 0x00000100 /* bit level 1 */ + +#define SR_KUO 0x00000020 /* old kernel/user, 0 => k, 1 => u */ +#define SR_IEO 0x00000010 /* old interrupt enable, 1 => enable */ +#define SR_KUP 0x00000008 /* prev kernel/user, 0 => k, 1 => u */ +#define SR_IEP 0x00000004 /* prev interrupt enable, 1 => enable */ +#define SR_KUC 0x00000002 /* cur kernel/user, 0 => k, 1 => u */ +#define SR_IEC 0x00000001 /* cur interrupt enable, 1 => enable */ +#define SR_KUMSK (SR_KUO|SR_IEO|SR_KUP|SR_IEP|SR_KUC|SR_IEC) + +#define SR_IMASKSHIFT 8 #endif 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 #include -#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 /* 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 +#include +#include "iregdef.h" +#include +#include */ + + + + +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 + diff --git a/c/src/lib/libcpu/mips/shared/interrupts/Makefile.am b/c/src/lib/libcpu/mips/shared/interrupts/Makefile.am index 866b0247a9..c1fb455e2f 100644 --- a/c/src/lib/libcpu/mips/shared/interrupts/Makefile.am +++ b/c/src/lib/libcpu/mips/shared/interrupts/Makefile.am @@ -6,7 +6,7 @@ AUTOMAKE_OPTIONS = foreign 1.4 PGM = $(ARCH)/interrupts.rel -C_FILES = installisrentries.c maxvectors.c vectorexceptions.c +C_FILES = installisrentries.c maxvectors.c S_FILES = isr_entries.S diff --git a/c/src/lib/libcpu/mips/shared/interrupts/maxvectors.c b/c/src/lib/libcpu/mips/shared/interrupts/maxvectors.c index 64f77317f7..f2fb9d2e17 100644 --- a/c/src/lib/libcpu/mips/shared/interrupts/maxvectors.c +++ b/c/src/lib/libcpu/mips/shared/interrupts/maxvectors.c @@ -31,10 +31,12 @@ * through the IP bits, and 32 more from the PFICR. Some of * these are reserved but for simplicity in processing, we * reserve slots for those bits anyway. + * + * gdm, 5/14, added 15 more slots so exceptions can be vectored as well. */ #if defined(MONGOOSEV) -#define MAX_VECTORS 37 +#define MAX_VECTORS (38+10) #endif #ifndef MAX_VECTORS @@ -42,3 +44,4 @@ #endif unsigned int mips_interrupt_number_of_vectors = MAX_VECTORS; + diff --git a/c/src/lib/libcpu/mips/shared/interrupts/vectorexceptions.c b/c/src/lib/libcpu/mips/shared/interrupts/vectorexceptions.c deleted file mode 100644 index 708f9ffea8..0000000000 --- a/c/src/lib/libcpu/mips/shared/interrupts/vectorexceptions.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * ISR Vectoring support for the Synova Mongoose-V. - * - * COPYRIGHT (c) 1989-2001. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * $Id$ - */ - -#include -#include - -#define mips_get_cause( _cause ) \ - do { \ - asm volatile( "mfc0 %0, $13; nop" : "=r" (_cause) : ); \ - } while (0) - -#define CALL_ISR(_vector) \ - do { \ - if ( _ISR_Vector_table[_vector] ) \ - (_ISR_Vector_table[_vector])(_vector); \ - else \ - mips_default_exception_code_handler(_vector); \ - } while (0) - -#include /* for printk */ - -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" -}; - -void mips_default_exception_code_handler( int exc, CPU_Interrupt_frame *frame ) -{ - unsigned int sr; - unsigned int cause; - - mips_get_cause( cause ); - - printk( "Unhandled exception cause %d\n", exc ); - printk( "sr: 0x%08x", sr ); - printk( "cause: 0x%08x --> %s", cause, cause_strings[(cause >> 2) &0x1f] ); - /* XXX dump frame once defined */ - rtems_fatal_error_occurred(1); -} - -void mips_vector_exceptions( CPU_Interrupt_frame *frame ) -{ - unsigned int cause; - int exc; - - mips_get_cause( cause ); - exc = (cause >> 2) &0x1f; - - printk( "Exception!\n" ); - mips_default_exception_code_handler( exc, frame ); -} -- cgit v1.2.3