This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
PowerPC - Fix serial driver lockups
- From: Gary Thomas <gary at mlbassoc dot com>
- To: eCos patches <ecos-patches at ecos dot sourceware dot org>
- Date: 13 Oct 2003 09:39:12 -0600
- Subject: PowerPC - Fix serial driver lockups
- Organization: MLB Associates
BUG #90391 - enabling serial drivers caused the debug I/O
to lock up on any platform with QUICC drivers. This was
because of some out of order instructions (thanks to the
newer compilers). Added some I/O barriers and now it
seems to be happy.
--
Gary Thomas <gary@mlbassoc.com>
MLB Associates
Index: devs/serial/powerpc/quicc/current/ChangeLog
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/devs/serial/powerpc/quicc/current/ChangeLog,v
retrieving revision 1.20
diff -u -5 -p -r1.20 ChangeLog
--- devs/serial/powerpc/quicc/current/ChangeLog 8 Oct 2003 19:35:07 -0000 1.20
+++ devs/serial/powerpc/quicc/current/ChangeLog 13 Oct 2003 15:35:44 -0000
@@ -1,5 +1,10 @@
+2003-10-13 Gary Thomas <gary@mlbassoc.com>
+
+ * src/quicc_smc_serial.c: Add some I/O barriers to make sure that
+ operations happen in the correct order. Fixes BUG #90391
+
2003-10-08 Gary Thomas <gary@mlbassoc.com>
* src/quicc_smc_serial.c: Fix compile error for Adder-II (852T)
2003-09-08 Gary Thomas <gary@mlbassoc.com>
Index: devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c,v
retrieving revision 1.16
diff -u -5 -p -r1.16 quicc_smc_serial.c
--- devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c 8 Oct 2003 19:35:07 -0000 1.16
+++ devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c 13 Oct 2003 15:34:17 -0000
@@ -341,21 +341,24 @@ quicc_smc_serial_config_port(serial_chan
volatile struct smc_regs *ctl = (volatile struct smc_regs *)smc_chan->ctl;
if (baud_divisor == 0) return false;
// Disable channel during setup
ctl->smc_smcmr = QUICC_SMCMR_UART; // Disabled, UART mode
+ HAL_IO_BARRIER(); // Inforce I/O ordering
// Disable port interrupts while changing hardware
_lcr = smc_select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
smc_select_stop_bits[new_config->stop] |
smc_select_parity[new_config->parity];
// Stop transmitter while changing baud rate
eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_StopTx;
+ HAL_IO_BARRIER(); // Inforce I/O ordering
// Set baud rate generator
*smc_chan->brg = 0x10000 | (UART_BITRATE(baud_divisor)<<1);
// Enable channel with new configuration
ctl->smc_smcmr = QUICC_SMCMR_UART|QUICC_SMCMR_TEN|QUICC_SMCMR_REN|_lcr;
+ HAL_IO_BARRIER(); // Inforce I/O ordering
eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_RestartTx;
if (new_config != &chan->config) {
chan->config = *new_config;
}
return true;
@@ -374,19 +377,20 @@ quicc_smc_serial_init_info(quicc_sxx_ser
int port)
{
EPPC *eppc = eppc_base();
struct cp_bufdesc *txbd, *rxbd;
int i;
-
- // Disable channel during setup
- ctl->smc_smcmr = QUICC_SMCMR_UART; // Disabled, UART mode
+
smc_chan->pram = (void *)uart_pram;
smc_chan->ctl = (void *)ctl;
// Set up baud rate generator
smc_chan->brg = _mpc8xx_allocate_brg(port);
+ // Disable channel during setup
+ ctl->smc_smcmr = QUICC_SMCMR_UART; // Disabled, UART mode
+
/*
* Set up the PortB pins for UART operation.
* Set PAR and DIR to allow SMCTXDx and SMRXDx
* (Table 16-39)
*/
@@ -447,11 +451,13 @@ quicc_smc_serial_init_info(quicc_sxx_ser
txbd++;
}
/*
* Reset Rx & Tx params
*/
+ HAL_IO_BARRIER(); // Inforce I/O ordering
eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_InitTxRx;
+ HAL_IO_BARRIER(); // Inforce I/O ordering
/*
* Clear any previous events. Enable interrupts.
* (Section 16.15.7.14 and 16.15.7.15)
*/
ctl->smc_smce = 0xFF;
@@ -469,10 +475,11 @@ quicc_scc_serial_config_port(serial_chan
if (baud_divisor == 0) return false;
// Set baud rate generator
*scc_chan->brg = 0x10000 | (UART_BITRATE(baud_divisor)<<1);
// Disable channel during setup
+ HAL_IO_BARRIER(); // Inforce I/O ordering
regs->scc_gsmr_l = 0;
regs->scc_psmr = QUICC_SCC_PSMR_ASYNC |
scc_select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
scc_select_stop_bits[new_config->stop] |
scc_select_parity[new_config->parity];
@@ -482,12 +489,14 @@ quicc_scc_serial_config_port(serial_chan
regs->scc_gsmr_l = 0x00028004; // 16x TxCLK, 16x RxCLK, UART
/*
* Init Rx & Tx params for SCCX
*/
+ HAL_IO_BARRIER(); // Inforce I/O ordering
eppc->cp_cr = QUICC_CPM_CR_INIT_TXRX | scc_chan->channel | QUICC_CPM_CR_BUSY;
+ HAL_IO_BARRIER(); // Inforce I/O ordering
regs->scc_gsmr_l |= (QUICC_SCC_GSMR_L_Tx | QUICC_SCC_GSMR_L_Rx); // Enable Rx, Tx
if (new_config != &chan->config) {
chan->config = *new_config;
}
return true;
@@ -592,15 +601,17 @@ quicc_scc_serial_init_info(quicc_sxx_ser
txbd++;
}
/*
* Reset Rx & Tx params
*/
+ HAL_IO_BARRIER(); // Inforce I/O ordering
eppc->cp_cr = scc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_InitTxRx;
/*
* Clear any previous events. Enable interrupts.
* (Section 16.15.7.14 and 16.15.7.15)
*/
+ HAL_IO_BARRIER(); // Inforce I/O ordering
ctl->scc_scce = 0xFFFF;
ctl->scc_sccm = (QUICC_SCCE_BSY | QUICC_SCCE_TX | QUICC_SCCE_RX);
}
// Function to initialize the device. Called at bootstrap time.