summaryrefslogtreecommitdiffstats
path: root/c/src/lib
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2001-05-22 23:20:14 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2001-05-22 23:20:14 +0000
commit2e7ed911d7a99274d5268498a3466de06f580d8a (patch)
treef6e2ab890ba4cc1b1adef8b4a7ab08a82973c33a /c/src/lib
parent2001-05-22 Greg Menke <gregory.menke@gsfc.nasa.gov> (diff)
downloadrtems-2e7ed911d7a99274d5268498a3466de06f580d8a.tar.bz2
2001-05-22 Greg Menke <gregory.menke@gsfc.nasa.gov>
* Assisted in design and debug by Joel Sherrill <joel@OARcorp.com>. * 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.
Diffstat (limited to 'c/src/lib')
-rw-r--r--c/src/lib/libcpu/mips/ChangeLog9
-rw-r--r--c/src/lib/libcpu/mips/mongoosev/duart/mg5uart.c417
-rw-r--r--c/src/lib/libcpu/mips/mongoosev/duart/mg5uart.h22
-rw-r--r--c/src/lib/libcpu/mips/mongoosev/include/mongoose-v.h244
-rw-r--r--c/src/lib/libcpu/mips/mongoosev/vectorisrs/vectorisrs.c321
-rw-r--r--c/src/lib/libcpu/mips/shared/interrupts/Makefile.am2
-rw-r--r--c/src/lib/libcpu/mips/shared/interrupts/maxvectors.c5
-rw-r--r--c/src/lib/libcpu/mips/shared/interrupts/vectorexceptions.c90
8 files changed, 721 insertions, 389 deletions
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 <gregory.menke@gsfc.nasa.gov>
+
+ * Assisted in design and debug by Joel Sherrill <joel@OARcorp.com>.
+ * 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 <joel@OARcorp.com>
* 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 ; port<Console_Port_Count ; port++ ) {
- if ( Console_Port_Tbl[port].ulCtrlPort1 == pMG5UART &&
+ if ( Console_Port_Tbl[port].ulCtrlPort1 == pMG5UART &&
Console_Port_Tbl[port].ulCtrlPort2 != pMG5UART_port ) {
pmg5uartContext->mate = 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<Console_Port_Count ; minor++) { \
if( Console_Port_Tbl[minor].deviceType == SERIAL_MG5UART && \
vector == Console_Port_Tbl[minor].ulIntVector + _OFFSET ) { \
mg5uart_process_isr_ ## _TYPE (minor); \
+ return; \
} \
} \
+ mips_default_isr( vector ); \
}
__ISR(rx_frame_error, MG5UART_IRQ_RX_FRAME_ERROR)
@@ -416,33 +467,14 @@ __ISR(rx_overrun_error, MG5UART_IRQ_RX_OVERRUN_ERROR)
__ISR(tx_empty, MG5UART_IRQ_TX_EMPTY)
__ISR(tx_ready, MG5UART_IRQ_TX_READY)
__ISR(rx_ready, MG5UART_IRQ_RX_READY)
-
-
-MG5UART_STATIC void mg5uart_process_isr_rx_frame_error(
- int minor
-)
-{
- unsigned32 pMG5UART;
- int shift;
- pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1;
- if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
- shift = MONGOOSEV_UART0_IRQ_SHIFT;
- else
- shift = MONGOOSEV_UART1_IRQ_SHIFT;
- /* now clear the error */
- MG5UART_SETREG(
- pMG5UART,
- MG5UART_STATUS_REGISTER,
- MONGOOSEV_UART_RX_FRAME_ERROR << shift
- );
-}
-MG5UART_STATIC void mg5uart_process_isr_rx_overrun_error(
- int minor
+MG5UART_STATIC void mg5uart_process_isr_rx_error(
+ int minor,
+ unsigned32 mask
)
{
unsigned32 pMG5UART;
@@ -458,69 +490,90 @@ MG5UART_STATIC void mg5uart_process_isr_rx_overrun_error(
/* now clear the error */
MG5UART_SETREG(
- pMG5UART,
- MG5UART_STATUS_REGISTER,
- MONGOOSEV_UART_RX_OVERRUN_ERROR << shift
- );
+ pMG5UART,
+ MG5UART_STATUS_REGISTER,
+ mask << shift );
}
-MG5UART_STATIC void mg5uart_process_tx_isr(
- int minor,
- unsigned32 source_mask
-);
-MG5UART_STATIC void mg5uart_process_isr_tx_empty(
+MG5UART_STATIC void mg5uart_process_isr_rx_frame_error(
int minor
)
{
- mg5uart_process_tx_isr( minor, MONGOOSEV_UART_TX_EMPTY );
+ mg5uart_process_isr_rx_error( minor, MONGOOSEV_UART_RX_FRAME_ERROR );
}
-MG5UART_STATIC void mg5uart_process_isr_tx_ready(
+MG5UART_STATIC void mg5uart_process_isr_rx_overrun_error(
int minor
)
{
- mg5uart_process_tx_isr( minor, MONGOOSEV_UART_TX_READY );
+ mg5uart_process_isr_rx_error( minor, MONGOOSEV_UART_RX_OVERRUN_ERROR );
}
+
+
+
+
+
+
+
MG5UART_STATIC void mg5uart_process_tx_isr(
- int minor,
- unsigned32 source_mask
+ int minor,
+ unsigned32 source
)
{
- unsigned32 pMG5UART;
- int shift;
+ unsigned32 pMG5UART;
+ int shift;
+
+ pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1;
+
+ mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX);
+
+ if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
+ shift = MONGOOSEV_UART0_IRQ_SHIFT;
+ else
+ shift = MONGOOSEV_UART1_IRQ_SHIFT;
+
+ MG5UART_SETREG(
+ pMG5UART,
+ MG5UART_STATUS_REGISTER,
+ source << shift );
+
+ if( rtems_termios_dequeue_characters( Console_Port_Data[minor].termios_data, 1) )
+ {
+ mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL);
+ return;
+ }
- pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1;
+ /*
+ * There are no more characters to transmit. The tx interrupts are be cleared
+ * by writing data to the uart, so just disable the tx interrupt sources.
+ */
+
+ Console_Port_Data[minor].bActive = FALSE;
- if (!rtems_termios_dequeue_characters(
- Console_Port_Data[minor].termios_data, 1))
- return;
+ /* mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX); */
+}
- /*
- * There are no more characters to transmit so clear the interrupt
- * source and disable TX interrupts.
- */
- Console_Port_Data[minor].bActive = FALSE;
+MG5UART_STATIC void mg5uart_process_isr_tx_empty(
+ int minor
+)
+{
+ /* mg5uart_process_tx_isr( minor, MONGOOSEV_UART_TX_EMPTY ); */
+}
- if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
- shift = MONGOOSEV_UART0_IRQ_SHIFT;
- else
- shift = MONGOOSEV_UART1_IRQ_SHIFT;
+MG5UART_STATIC void mg5uart_process_isr_tx_ready(
+ int minor
+)
+{
+ mg5uart_process_tx_isr( minor, MONGOOSEV_UART_TX_READY );
+}
- /* now clear the interrupt source */
- MG5UART_SETREG(
- pMG5UART,
- MG5UART_STATUS_REGISTER,
- source_mask << shift
- );
- mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX);
-}
MG5UART_STATIC void mg5uart_process_isr_rx_ready(
int minor
@@ -531,16 +584,20 @@ MG5UART_STATIC void mg5uart_process_isr_rx_ready(
pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
+ /* reading the RX buffer automatically resets the interrupt flag */
+
c = (unsigned char) MG5UART_GETREG(pMG5UART_port, MG5UART_RX_BUFFER);
- rtems_termios_enqueue_raw_characters(
- Console_Port_Data[minor].termios_data,
- &c,
- 1
- );
- /* reading the RX buffer automatically resets the error */
+ rtems_termios_enqueue_raw_characters(
+ Console_Port_Data[minor].termios_data,
+ &c, 1 );
}
+
+
+
+
+
/*
* mg5uart_initialize_interrupts
*
@@ -565,15 +622,19 @@ MG5UART_STATIC void mg5uart_initialize_interrupts(int minor)
mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX);
}
-/*
+
+
+
+
+/*
* mg5uart_write_support_int
*
* Console Termios output entry point when using interrupt driven output.
*/
MG5UART_STATIC int mg5uart_write_support_int(
- int minor,
- const char *buf,
+ int minor,
+ const char *buf,
int len
)
{
@@ -588,24 +649,30 @@ MG5UART_STATIC int mg5uart_write_support_int(
*/
if ( !len )
- return 0;
+ return 0;
/*
* Put the character out and enable interrupts if necessary.
*/
rtems_interrupt_disable(Irql);
- if ( Console_Port_Data[minor].bActive == FALSE ) {
- Console_Port_Data[minor].bActive = TRUE;
- mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL);
- }
- MG5UART_SETREG(pMG5UART_port, MG5UART_TX_BUFFER, *buf);
- rtems_interrupt_enable(Irql);
+ MG5UART_SETREG(pMG5UART_port, MG5UART_TX_BUFFER, *buf);
+
+ if( Console_Port_Data[minor].bActive == FALSE )
+ {
+ Console_Port_Data[minor].bActive = TRUE;
+ mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL);
+ }
+
+ rtems_interrupt_enable(Irql);
return 1;
}
-/*
+
+
+
+/*
* mg5uart_write_support_polled
*
* Console Termios output entry point when using polled output.
@@ -613,8 +680,8 @@ MG5UART_STATIC int mg5uart_write_support_int(
*/
MG5UART_STATIC int mg5uart_write_support_polled(
- int minor,
- const char *buf,
+ int minor,
+ const char *buf,
int len
)
{
@@ -623,10 +690,8 @@ MG5UART_STATIC int mg5uart_write_support_polled(
/*
* poll each byte in the string out of the port.
*/
- while (nwrite < len) {
- /*
- * transmit character
- */
+ while (nwrite < len)
+ {
mg5uart_write_polled(minor, *buf++);
nwrite++;
}
@@ -637,20 +702,20 @@ MG5UART_STATIC int mg5uart_write_support_polled(
return nwrite;
}
-/*
- * mg5uart_inbyte_nonblocking_polled
+/*
+ * mg5uart_inbyte_nonblocking_polled
*
* Console Termios polling input entry point.
*/
-MG5UART_STATIC int mg5uart_inbyte_nonblocking_polled(
- int minor
+MG5UART_STATIC int mg5uart_inbyte_nonblocking_polled(
+ int minor
)
{
unsigned32 pMG5UART;
unsigned32 pMG5UART_port;
unsigned32 status;
- int shift;
+ unsigned32 tmp,shift;
pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1;
pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
@@ -660,11 +725,22 @@ MG5UART_STATIC int mg5uart_inbyte_nonblocking_polled(
else
shift = MONGOOSEV_UART1_IRQ_SHIFT;
+ /* reset overrrun or framing errors */
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;
+
+ 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 <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
+
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 <rtems.h>
-#include <stdlib.h>
-
-#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 <bspIo.h> /* 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 );
-}