* 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.
This commit is contained in:
Joel Sherrill
2001-05-22 23:20:14 +00:00
parent a355e3ea98
commit 2e7ed911d7
8 changed files with 730 additions and 398 deletions

View File

@@ -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> 2001-05-07 Joel Sherrill <joel@OARcorp.com>
* shared/interrupts/vectorexceptions.c: New file to decode * shared/interrupts/vectorexceptions.c: New file to decode

View File

@@ -45,12 +45,15 @@ typedef struct _mg5uart_context
/* #define MG5UART_STATIC static */ /* #define MG5UART_STATIC static */
#define MG5UART_SETREG( _base, _register, _value ) \ #define MG5UART_SETREG( _base, _register, _value ) \
MONGOOSEV_WRITE_REGISTER( _base, _register, _value ) MONGOOSEV_WRITE_REGISTER( _base, _register, _value )
#define MG5UART_GETREG( _base, _register ) \ #define MG5UART_GETREG( _base, _register ) \
MONGOOSEV_READ_REGISTER( _base, _register ) MONGOOSEV_READ_REGISTER( _base, _register )
/* /*
* Console Device Driver Support Functions * Console Device Driver Support Functions
*/ */
@@ -73,16 +76,16 @@ MG5UART_STATIC void mg5uart_enable_interrupts(
* port settings. * port settings.
*/ */
MG5UART_STATIC int mg5uart_set_attributes( MG5UART_STATIC int mg5uart_set_attributes(
int minor, int minor,
const struct termios *t const struct termios *t
) )
{ {
unsigned32 pMG5UART_port; unsigned32 pMG5UART_port;
unsigned32 pMG5UART; unsigned32 pMG5UART;
unsigned int cmd; unsigned32 cmd, cmdSave;
unsigned int baudcmd; unsigned32 baudcmd;
unsigned int portshift; unsigned32 shift;
rtems_interrupt_level Irql; rtems_interrupt_level Irql;
pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1; pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1;
@@ -103,7 +106,7 @@ MG5UART_STATIC int mg5uart_set_attributes(
* Base settings * 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 * Parity
@@ -125,22 +128,22 @@ MG5UART_STATIC int mg5uart_set_attributes(
if (t->c_cflag & CSIZE) { if (t->c_cflag & CSIZE) {
switch (t->c_cflag & CSIZE) { switch (t->c_cflag & CSIZE) {
case CS5: case CS5:
case CS6: case CS6:
case CS7: case CS7:
return -1; return -1;
break; break;
case CS8: case CS8:
/* Mongoose-V only supports CS8 */ /* Mongoose-V only supports CS8 */
break; break;
} }
} /* else default to CS8 */ } /* else default to CS8 */
/* /*
* Stop Bits * Stop Bits
*/ */
#if 0 #if 0
if (t->c_cflag & CSTOPB) { if (t->c_cflag & CSTOPB) {
/* 2 stop bits not supported by Mongoose-V uart */ /* 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 ) if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
portshift = MONGOOSEV_UART0_CMD_SHIFT; shift = MONGOOSEV_UART0_CMD_SHIFT;
else else
portshift = MONGOOSEV_UART1_CMD_SHIFT; shift = MONGOOSEV_UART1_CMD_SHIFT;
rtems_interrupt_disable(Irql); 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); rtems_interrupt_enable(Irql);
return 0; return 0;
} }
@@ -184,14 +196,14 @@ MG5UART_STATIC void mg5uart_initialize_context(
int port; int port;
unsigned int pMG5UART; unsigned int pMG5UART;
unsigned int pMG5UART_port; unsigned int pMG5UART_port;
pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1; pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1;
pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2; pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
pmg5uartContext->mate = -1; pmg5uartContext->mate = -1;
for (port=0 ; port<Console_Port_Count ; port++ ) { 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 ) { Console_Port_Tbl[port].ulCtrlPort2 != pMG5UART_port ) {
pmg5uartContext->mate = port; pmg5uartContext->mate = port;
break; break;
@@ -208,8 +220,11 @@ MG5UART_STATIC void mg5uart_initialize_context(
MG5UART_STATIC void mg5uart_init(int minor) MG5UART_STATIC void mg5uart_init(int minor)
{ {
unsigned32 pMG5UART_port; unsigned32 pMG5UART_port;
unsigned32 pMG5UART; unsigned32 pMG5UART;
unsigned32 cmdSave;
unsigned32 shift;
mg5uart_context *pmg5uartContext; mg5uart_context *pmg5uartContext;
pmg5uartContext = (mg5uart_context *) malloc(sizeof(mg5uart_context)); 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 = Console_Port_Tbl[minor].ulCtrlPort1;
pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2; 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 * Disable interrupts on RX and TX for this port
*/ */
mg5uart_enable_interrupts( minor, MG5UART_DISABLE_ALL ); mg5uart_enable_interrupts( minor, MG5UART_DISABLE_ALL );
} }
@@ -248,37 +269,46 @@ MG5UART_STATIC int mg5uart_open(
void *arg void *arg
) )
{ {
unsigned32 pMG5UART; unsigned32 pMG5UART;
unsigned32 pMG5UART_port; unsigned32 pMG5UART_port;
unsigned int vector; unsigned32 vector;
unsigned int cmd; unsigned32 cmd, cmdSave;
unsigned int baudcmd; unsigned32 baudcmd;
unsigned int portshift; unsigned32 shift;
rtems_interrupt_level Irql; rtems_interrupt_level Irql;
pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1; pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1;
pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2; pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
vector = Console_Port_Tbl[minor].ulIntVector; 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 */ /* XXX default baud rate could be from configuration table */
(void) mg5uart_baud_rate( minor, B19200, &baudcmd ); (void) mg5uart_baud_rate( minor, B19200, &baudcmd );
/* /*
* Set the DUART channel to a default useable state * 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; 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); 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); rtems_interrupt_enable(Irql);
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
@@ -296,10 +326,11 @@ MG5UART_STATIC int mg5uart_close(
void *arg void *arg
) )
{ {
unsigned32 pMG5UART; unsigned32 pMG5UART;
unsigned32 pMG5UART_port; unsigned32 pMG5UART_port;
unsigned int cmd; unsigned32 cmd, cmdSave;
unsigned int portshift; unsigned32 shift;
rtems_interrupt_level Irql;
pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1; pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1;
pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2; 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; cmd = MONGOOSEV_UART_CMD_TX_DISABLE | MONGOOSEV_UART_CMD_RX_DISABLE;
if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 ) if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
portshift = MONGOOSEV_UART0_CMD_SHIFT; shift = MONGOOSEV_UART0_CMD_SHIFT;
else else
portshift = MONGOOSEV_UART1_CMD_SHIFT; shift = MONGOOSEV_UART1_CMD_SHIFT;
MG5UART_SETREG( pMG5UART, MG5UART_COMMAND_REGISTER, cmd << portshift );
rtems_interrupt_disable(Irql);
cmdSave = MG5UART_GETREG( pMG5UART, MG5UART_COMMAND_REGISTER );
MG5UART_SETREG( pMG5UART,
MG5UART_COMMAND_REGISTER,
(cmdSave & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift)) | (cmd << shift) );
rtems_interrupt_enable(Irql);
return(RTEMS_SUCCESSFUL); return(RTEMS_SUCCESSFUL);
} }
/*
/*
* mg5uart_write_polled * mg5uart_write_polled
* *
* This routine polls out the requested character. * This routine polls out the requested character.
*/ */
MG5UART_STATIC void mg5uart_write_polled( MG5UART_STATIC void mg5uart_write_polled(
int minor, int minor,
char c char c
) )
{ {
@@ -350,27 +391,31 @@ MG5UART_STATIC void mg5uart_write_polled(
/* /*
* wait for transmitter holding register to be empty * wait for transmitter holding register to be empty
*/ */
timeout = 1000; timeout = 2000;
status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER);
while ( 1 ) { while( --timeout )
{
status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER) >> shift; 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; break;
*/
if( (status & (MONGOOSEV_UART_TX_READY | MONGOOSEV_UART_TX_EMPTY)) )
break;
/* /*
* Yield while we wait * Yield while we wait
*/ */
#if 0 #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); rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
} }
#endif #endif
if(!--timeout) {
break;
}
} }
/* /*
@@ -380,6 +425,9 @@ MG5UART_STATIC void mg5uart_write_polled(
MG5UART_SETREG(pMG5UART_port, MG5UART_TX_BUFFER, c); MG5UART_SETREG(pMG5UART_port, MG5UART_TX_BUFFER, c);
} }
/* /*
* mg5uart_isr_XXX * mg5uart_isr_XXX
* *
@@ -388,7 +436,7 @@ MG5UART_STATIC void mg5uart_write_polled(
* shared handler gets the right arguments. * shared handler gets the right arguments.
* *
* NOTE: Yes .. this is ugly but it provides 5 interrupt source * 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 \ rtems_vector_number vector \
) \ ) \
{ \ { \
int minor; \ int minor; \
extern void mips_default_isr(int vector); \
\ \
for(minor=0 ; minor<Console_Port_Count ; minor++) { \ for(minor=0 ; minor<Console_Port_Count ; minor++) { \
if( Console_Port_Tbl[minor].deviceType == SERIAL_MG5UART && \ if( Console_Port_Tbl[minor].deviceType == SERIAL_MG5UART && \
vector == Console_Port_Tbl[minor].ulIntVector + _OFFSET ) { \ vector == Console_Port_Tbl[minor].ulIntVector + _OFFSET ) { \
mg5uart_process_isr_ ## _TYPE (minor); \ mg5uart_process_isr_ ## _TYPE (minor); \
return; \
} \ } \
} \ } \
mips_default_isr( vector ); \
} }
__ISR(rx_frame_error, MG5UART_IRQ_RX_FRAME_ERROR) __ISR(rx_frame_error, MG5UART_IRQ_RX_FRAME_ERROR)
@@ -416,10 +467,14 @@ __ISR(rx_overrun_error, MG5UART_IRQ_RX_OVERRUN_ERROR)
__ISR(tx_empty, MG5UART_IRQ_TX_EMPTY) __ISR(tx_empty, MG5UART_IRQ_TX_EMPTY)
__ISR(tx_ready, MG5UART_IRQ_TX_READY) __ISR(tx_ready, MG5UART_IRQ_TX_READY)
__ISR(rx_ready, MG5UART_IRQ_RX_READY) __ISR(rx_ready, MG5UART_IRQ_RX_READY)
MG5UART_STATIC void mg5uart_process_isr_rx_frame_error(
int minor
MG5UART_STATIC void mg5uart_process_isr_rx_error(
int minor,
unsigned32 mask
) )
{ {
unsigned32 pMG5UART; unsigned32 pMG5UART;
@@ -435,92 +490,90 @@ MG5UART_STATIC void mg5uart_process_isr_rx_frame_error(
/* now clear the error */ /* now clear the error */
MG5UART_SETREG( MG5UART_SETREG(
pMG5UART, pMG5UART,
MG5UART_STATUS_REGISTER, MG5UART_STATUS_REGISTER,
MONGOOSEV_UART_RX_FRAME_ERROR << shift mask << shift );
); }
MG5UART_STATIC void mg5uart_process_isr_rx_frame_error(
int minor
)
{
mg5uart_process_isr_rx_error( minor, MONGOOSEV_UART_RX_FRAME_ERROR );
} }
MG5UART_STATIC void mg5uart_process_isr_rx_overrun_error( MG5UART_STATIC void mg5uart_process_isr_rx_overrun_error(
int minor int minor
) )
{ {
unsigned32 pMG5UART; mg5uart_process_isr_rx_error( minor, MONGOOSEV_UART_RX_OVERRUN_ERROR );
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_OVERRUN_ERROR << shift
);
} }
MG5UART_STATIC void mg5uart_process_tx_isr( MG5UART_STATIC void mg5uart_process_tx_isr(
int minor, int minor,
unsigned32 source_mask unsigned32 source
); )
{
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;
}
/*
* 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;
/* mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX); */
}
MG5UART_STATIC void mg5uart_process_isr_tx_empty( MG5UART_STATIC void mg5uart_process_isr_tx_empty(
int minor int minor
) )
{ {
mg5uart_process_tx_isr( minor, MONGOOSEV_UART_TX_EMPTY ); /* mg5uart_process_tx_isr( minor, MONGOOSEV_UART_TX_EMPTY ); */
} }
MG5UART_STATIC void mg5uart_process_isr_tx_ready( MG5UART_STATIC void mg5uart_process_isr_tx_ready(
int minor int minor
) )
{ {
mg5uart_process_tx_isr( minor, MONGOOSEV_UART_TX_READY ); mg5uart_process_tx_isr( minor, MONGOOSEV_UART_TX_READY );
} }
MG5UART_STATIC void mg5uart_process_tx_isr(
int minor,
unsigned32 source_mask
)
{
unsigned32 pMG5UART;
int shift;
pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1;
if (!rtems_termios_dequeue_characters(
Console_Port_Data[minor].termios_data, 1))
return;
/*
* There are no more characters to transmit so clear the interrupt
* source and disable TX interrupts.
*/
Console_Port_Data[minor].bActive = FALSE;
if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
shift = MONGOOSEV_UART0_IRQ_SHIFT;
else
shift = MONGOOSEV_UART1_IRQ_SHIFT;
/* 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( MG5UART_STATIC void mg5uart_process_isr_rx_ready(
int minor int minor
@@ -531,16 +584,20 @@ MG5UART_STATIC void mg5uart_process_isr_rx_ready(
pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2; pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
c = (unsigned char) MG5UART_GETREG(pMG5UART_port, MG5UART_RX_BUFFER); /* reading the RX buffer automatically resets the interrupt flag */
rtems_termios_enqueue_raw_characters(
Console_Port_Data[minor].termios_data,
&c,
1
);
/* reading the RX buffer automatically resets the error */ c = (unsigned char) MG5UART_GETREG(pMG5UART_port, MG5UART_RX_BUFFER);
rtems_termios_enqueue_raw_characters(
Console_Port_Data[minor].termios_data,
&c, 1 );
} }
/* /*
* mg5uart_initialize_interrupts * 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_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX);
} }
/*
/*
* mg5uart_write_support_int * mg5uart_write_support_int
* *
* Console Termios output entry point when using interrupt driven output. * Console Termios output entry point when using interrupt driven output.
*/ */
MG5UART_STATIC int mg5uart_write_support_int( MG5UART_STATIC int mg5uart_write_support_int(
int minor, int minor,
const char *buf, const char *buf,
int len int len
) )
{ {
@@ -588,24 +649,30 @@ MG5UART_STATIC int mg5uart_write_support_int(
*/ */
if ( !len ) if ( !len )
return 0; return 0;
/* /*
* Put the character out and enable interrupts if necessary. * Put the character out and enable interrupts if necessary.
*/ */
rtems_interrupt_disable(Irql); 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; return 1;
} }
/*
/*
* mg5uart_write_support_polled * mg5uart_write_support_polled
* *
* Console Termios output entry point when using polled output. * 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( MG5UART_STATIC int mg5uart_write_support_polled(
int minor, int minor,
const char *buf, const char *buf,
int len int len
) )
{ {
@@ -623,10 +690,8 @@ MG5UART_STATIC int mg5uart_write_support_polled(
/* /*
* poll each byte in the string out of the port. * poll each byte in the string out of the port.
*/ */
while (nwrite < len) { while (nwrite < len)
/* {
* transmit character
*/
mg5uart_write_polled(minor, *buf++); mg5uart_write_polled(minor, *buf++);
nwrite++; nwrite++;
} }
@@ -637,20 +702,20 @@ MG5UART_STATIC int mg5uart_write_support_polled(
return nwrite; return nwrite;
} }
/* /*
* mg5uart_inbyte_nonblocking_polled * mg5uart_inbyte_nonblocking_polled
* *
* Console Termios polling input entry point. * Console Termios polling input entry point.
*/ */
MG5UART_STATIC int mg5uart_inbyte_nonblocking_polled( MG5UART_STATIC int mg5uart_inbyte_nonblocking_polled(
int minor int minor
) )
{ {
unsigned32 pMG5UART; unsigned32 pMG5UART;
unsigned32 pMG5UART_port; unsigned32 pMG5UART_port;
unsigned32 status; unsigned32 status;
int shift; unsigned32 tmp,shift;
pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1; pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1;
pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2; pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;
@@ -660,11 +725,22 @@ MG5UART_STATIC int mg5uart_inbyte_nonblocking_polled(
else else
shift = MONGOOSEV_UART1_IRQ_SHIFT; shift = MONGOOSEV_UART1_IRQ_SHIFT;
/* reset overrrun or framing errors */
status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER) >> shift; status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER) >> shift;
if ( status & MONGOOSEV_UART_RX_READY ) {
return (int) MG5UART_GETREG(pMG5UART_port, MG5UART_RX_BUFFER); if( (tmp = (status & 0x3)) )
} else { {
return -1; 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; baud_requested = baud & CBAUD;
if (!baud_requested) if (!baud_requested)
baud_requested = B9600; /* default to 9600 baud */ baud_requested = B9600; /* default to 9600 baud */
baud_requested = termios_baud_to_number( baud_requested ); baud_requested = termios_baud_to_number( baud_requested );
clock = (rtems_unsigned32) Console_Port_Tbl[minor].ulClock; 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). * 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; 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." * From section 12.7, "Keep C>100 for best receiver operation."
* That is 100 cycles which is not a lot of instructions. It is * That is 100 cycles which is not a lot of instructions. It is
* reasonable to think that the Mongoose-V could not keep * reasonable to think that the Mongoose-V could not keep
* up with C < 200. * up with C < 100.
*/ */
if ( tmp_code < 100 ) if ( tmp_code < 100 )
@@ -713,9 +792,13 @@ MG5UART_STATIC int mg5uart_baud_rate(
*/ */
*code = (tmp_code << 16) | tmp_code; *code = (tmp_code << 16) | tmp_code;
return 0; return 0;
} }
/* /*
* mg5uart_enable_interrupts * mg5uart_enable_interrupts
* *
@@ -728,8 +811,9 @@ MG5UART_STATIC void mg5uart_enable_interrupts(
) )
{ {
unsigned32 pMG5UART; unsigned32 pMG5UART;
unsigned32 shifted_mask; unsigned32 maskSave;
unsigned32 shifted_bits; unsigned32 shift;
rtems_interrupt_level Irql;
pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1; pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1;
@@ -737,24 +821,26 @@ MG5UART_STATIC void mg5uart_enable_interrupts(
* Enable interrupts on RX and TX -- not break * Enable interrupts on RX and TX -- not break
*/ */
shifted_bits = MONGOOSEV_UART_ALL_IRQ_BITS; if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )
shifted_mask = mask; 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( rtems_interrupt_disable(Irql);
MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_MASK_REGISTER,
shifted_bits, maskSave = MG5UART_GETREG( pMG5UART, MG5UART_INTERRUPT_MASK_REGISTER );
shifted_mask
); 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 * Flow control is only supported when using interrupts
*/ */
@@ -785,3 +871,4 @@ console_fns mg5uart_fns_polled =
FALSE, /* deviceOutputUsesInterrupts */ FALSE, /* deviceOutputUsesInterrupts */
}; };

View File

@@ -34,22 +34,32 @@ extern "C" {
*/ */
/* shared registers from peripheral base (i.e. from ulCtrlPort1) */ /* 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_STATUS_REGISTER 0x04
#define MG5UART_INTERRUPT_CAUSE_REGISTER 0x08 #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) */ /* port specific registers from uart base (i.e. from ulCtrlPort2) */
#define MG5UART_RX_BUFFER 0x00 #define MG5UART_RX_BUFFER 0
#define MG5UART_TX_BUFFER 0x04 #define MG5UART_TX_BUFFER 4
#define MG5UART_BAUD_RATE 0x08 #define MG5UART_BAUD_RATE 8
/* /*
* Interrupt mask values * Interrupt mask values
*/ */
#define MG5UART_ENABLE_ALL_EXCEPT_TX MONGOOSEV_UART_ALL_RX_STATUS_BITS #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 #define MG5UART_DISABLE_ALL 0x0000
/* /*

View File

@@ -18,28 +18,29 @@
* Macros to assist in accessing memory mapped Mongoose registers * Macros to assist in accessing memory mapped Mongoose registers
*/ */
#define MONGOOSEV_READ( _base ) \ #define MONGOOSEV_READ( _base ) \
*((volatile unsigned32 *)(_base)) ( *((volatile unsigned32 *)(_base)) )
#define MONGOOSEV_WRITE( _base, _value ) \ #define MONGOOSEV_WRITE( _base, _value ) \
*((volatile unsigned32 *)(_base)) = (_value) ( *((volatile unsigned32 *)(_base)) = (_value) )
#define MONGOOSEV_READ_REGISTER( _base, _register ) \ #define MONGOOSEV_READ_REGISTER( _base, _register ) \
*((volatile unsigned32 *)((_base) + (_register))) ( *((volatile unsigned32 *)((_base) + (_register))) )
#define MONGOOSEV_WRITE_REGISTER( _base, _register, _value ) \ #define MONGOOSEV_WRITE_REGISTER( _base, _register, _value ) \
*((volatile unsigned32 *)((_base) + (_register))) = (_value) ( *((volatile unsigned32 *)((_base) + (_register))) = (_value) )
/*
* Macros to read/write the Mongoose FPU control register.
*/
#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)
/* /*
* BIU and DRAM Registers * BIU and DRAM Registers
@@ -61,33 +62,22 @@
#define MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_CAUSE_REGISTER 0xFFFE0188 #define MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_CAUSE_REGISTER 0xFFFE0188
#define MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_MASK_REGISTER 0xFFFE018C #define MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_MASK_REGISTER 0xFFFE018C
#define MONGOOSEV_PFICR MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_CAUSE_REGISTER #define MONGOOSEV_WATCHDOG 0xBE000000
#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) )
/* UART Bits in Peripheral Command Register Bits (TX/RX tied together here) */ /* UART Bits in Peripheral Command Register Bits (TX/RX tied together here) */
#define MONGOOSEV_UART_CMD_RESET_BOTH_PORTS 0x0001 #define MONGOOSEV_UART_CMD_RESET_BOTH_PORTS 0x0001
#define MONGOOSEV_UART_CMD_LOOPBACK_CTSN 0x0002 #define MONGOOSEV_UART_CMD_LOOPBACK_CTSN 0x0002
#define MONGOOSEV_UART_CMD_LOOPBACK_RXTX 0x0004 #define MONGOOSEV_UART_CMD_LOOPBACK_RXTX 0x0004
#define MONGOOSEV_UART_CMD_TX_ENABLE 0x001 #define MONGOOSEV_UART_CMD_RX_ENABLE 0x001
#define MONGOOSEV_UART_CMD_TX_DISABLE 0x000 #define MONGOOSEV_UART_CMD_RX_DISABLE 0x000
#define MONGOOSEV_UART_CMD_RX_ENABLE 0x002 #define MONGOOSEV_UART_CMD_TX_ENABLE 0x002
#define MONGOOSEV_UART_CMD_RX_DISABLE 0x000 #define MONGOOSEV_UART_CMD_TX_DISABLE 0x000
#define MONGOOSEV_UART_CMD_TX_READY 0x004 #define MONGOOSEV_UART_CMD_TX_READY 0x004
#define MONGOOSEV_UART_CMD_PARITY_ENABLE 0x008 #define MONGOOSEV_UART_CMD_PARITY_ENABLE 0x008
#define MONGOOSEV_UART_CMD_PARITY_DISABLE 0x000 #define MONGOOSEV_UART_CMD_PARITY_DISABLE 0x000
#define MONGOOSEV_UART_CMD_PARITY_EVEN 0x800 #define MONGOOSEV_UART_CMD_PARITY_EVEN 0x010
#define MONGOOSEV_UART_CMD_PARITY_ODD 0x000 #define MONGOOSEV_UART_CMD_PARITY_ODD 0x000
#define MONGOOSEV_UART0_CMD_SHIFT 5 #define MONGOOSEV_UART0_CMD_SHIFT 5
#define MONGOOSEV_UART1_CMD_SHIFT 11 #define MONGOOSEV_UART1_CMD_SHIFT 11
@@ -129,9 +119,8 @@
#define MONGOOSEV_UART_TX_READY 0x0008 #define MONGOOSEV_UART_TX_READY 0x0008
#define MONGOOSEV_UART_RX_READY 0x0010 #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_STATUS_BITS 0x001F
#define MONGOOSEV_UART_ALL_IRQ_BITS 0x001F
/* /*
* The Peripheral Interrupt Status, Cause, and Mask registers have the * The Peripheral Interrupt Status, Cause, and Mask registers have the
@@ -173,21 +162,21 @@
*/ */
#define MONGOOSEV_EDAC_SERR_BIT 0x80000000 #define MONGOOSEV_EDAC_SERR_BIT 0x80000000
#define MONGOOSEV_EDAC_MERR_BIT 0x40000000 #define MONGOOSEV_EDAC_MERR_BIT 0x40000000
#define MONGOOSEV_MAVN_WRITE_ACCESS 0x00800000
#define MONGOOSEV_MAVN_READ_ACCESS 0x00400000
/* 29 - 24 reserved */ /* 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_RX_READY 0x00200000
#define MONGOOSEV_UART_1_TX_READY 0x00100000 #define MONGOOSEV_UART_1_TX_READY 0x00100000
#define MONGOOSEV_UART_1_TX_EMPTY 0x00080000 #define MONGOOSEV_UART_1_TX_EMPTY 0x00080000
#define MONGOOSEV_UART_1_RX_OVERRUN 0x00040000 #define MONGOOSEV_UART_1_RX_OVERRUN 0x00040000
#define MONGOOSEV_UART_1_FRAME_ERROR 0x00020000 #define MONGOOSEV_UART_1_FRAME_ERROR 0x00020000
#define MONGOOSEV_UART_1_RESERVED 0x00010000 #define MONGOOSEV_RESERVED_16 0x00010000
#define MONGOOSEV_MAVN_WRITE_ACCESS 0x00400000 #define MONGOOSEV_UART_0_RX_READY 0x00008000
#define MONGOOSEV_MAVN_READ_ACCESS 0x00800000 #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_9 0x00000200
#define MONGOOSEV_EXTERN_INT_8 0x00000100 #define MONGOOSEV_EXTERN_INT_8 0x00000100
#define MONGOOSEV_EXTERN_INT_7 0x00000080 #define MONGOOSEV_EXTERN_INT_7 0x00000080
@@ -264,43 +253,122 @@
#define MONGOOSEV_IRQ_INT1 1 #define MONGOOSEV_IRQ_INT1 1
#define MONGOOSEV_IRQ_TIMER2 MONGOOSEV_IRQ_INT1 #define MONGOOSEV_IRQ_TIMER2 MONGOOSEV_IRQ_INT1
#define MONGOOSEV_IRQ_INT2 2 #define MONGOOSEV_IRQ_INT2 2
#define MONGOOSEV_IRQ_INT4 3 #define MONGOOSEV_IRQ_INT3 3
/* MONGOOSEV_IRQ_INT5 indicates that a peripheral caused the IRQ. */ #define MONGOOSEV_IRQ_FPU MONGOOSEV_IRQ_INT3
#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_INT4 4
#define MONGOOSEV_IRQ_SOFTWARE_2 37
/* MONGOOSEV_IRQ_INT5 indicates that a peripheral caused the IRQ. */
#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 #endif

View File

@@ -15,65 +15,310 @@
#include <stdlib.h> #include <stdlib.h>
#include <libcpu/mongoose-v.h> #include <libcpu/mongoose-v.h>
#define mips_get_cause( _cause ) \ #include "iregdef.h"
do { \ #include "idtcpu.h"
asm volatile( "mfc0 %0, $13; nop" : "=r" (_cause) : ); \
} while (0)
#define CALL_ISR(_vector) \
#define CALL_ISR(_vector,_frame) \
do { \ do { \
if ( _ISR_Vector_table[_vector] ) \ if ( _ISR_Vector_table[_vector] ) \
(_ISR_Vector_table[_vector])(_vector); \ (_ISR_Vector_table[_vector])(_vector,_frame); \
else \ else \
mips_default_exception(_vector); \ mips_default_isr(_vector); \
} while (0) } while (0)
#include <bspIo.h> /* for printk */ #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;
rtems_fatal_error_occurred(1); 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_vector_isr_handlers( void )
void mips_default_isr( int vector )
{ {
unsigned int sr; unsigned int sr;
unsigned int cause; unsigned int cause;
int bit;
unsigned int pf_icr;
mips_get_sr( sr ); mips_get_sr( sr );
mips_get_cause( cause ); mips_get_cause( cause );
cause &= (sr & SR_IMASK); printk( "Unhandled isr exception: vector 0x%02x, cause 0x%08X, sr 0x%08X\n", vector, cause, sr );
cause >>= CAUSE_IPSHIFT; rtems_fatal_error_occurred(1);
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 );
}
}
if ( cause & 0x02 ) /* SW[0] */
CALL_ISR( MONGOOSEV_IRQ_SOFTWARE_1 );
if ( cause & 0x01 ) /* IP[1] */
CALL_ISR( MONGOOSEV_IRQ_SOFTWARE_2 );
} }
/* 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 i, j;
mips_get_sr( sr );
mips_get_cause( cause );
printk( "Unhandled exception %d\n", exc );
printk( "sr: 0x%08x cause: 0x%08x --> %s\n", sr, cause, cause_strings[(cause >> 2) &0x1f] );
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)
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 );
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

View File

@@ -6,7 +6,7 @@ AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/interrupts.rel PGM = $(ARCH)/interrupts.rel
C_FILES = installisrentries.c maxvectors.c vectorexceptions.c C_FILES = installisrentries.c maxvectors.c
S_FILES = isr_entries.S S_FILES = isr_entries.S

View File

@@ -31,10 +31,12 @@
* through the IP bits, and 32 more from the PFICR. Some of * through the IP bits, and 32 more from the PFICR. Some of
* these are reserved but for simplicity in processing, we * these are reserved but for simplicity in processing, we
* reserve slots for those bits anyway. * reserve slots for those bits anyway.
*
* gdm, 5/14, added 15 more slots so exceptions can be vectored as well.
*/ */
#if defined(MONGOOSEV) #if defined(MONGOOSEV)
#define MAX_VECTORS 37 #define MAX_VECTORS (38+10)
#endif #endif
#ifndef MAX_VECTORS #ifndef MAX_VECTORS
@@ -42,3 +44,4 @@
#endif #endif
unsigned int mips_interrupt_number_of_vectors = MAX_VECTORS; unsigned int mips_interrupt_number_of_vectors = MAX_VECTORS;

View File

@@ -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 );
}