This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PowerPC - Fix serial driver lockups


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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]