Index: trunk/hal/tsar_mips32/drivers/soclib_tty.c
===================================================================
--- trunk/hal/tsar_mips32/drivers/soclib_tty.c	(revision 296)
+++ trunk/hal/tsar_mips32/drivers/soclib_tty.c	(revision 407)
@@ -27,14 +27,27 @@
 #include <remote_spinlock.h>
 #include <thread.h>
+#include <printk.h>
 #include <hal_special.h>
+
+#if CONFIG_READ_DEBUG
+extern uint32_t  enter_tty_cmd;
+extern uint32_t  exit_tty_cmd;
+
+extern uint32_t  enter_tty_isr;
+extern uint32_t  exit_tty_isr;
+#endif
 
 ///////////////////////////////////////
 void soclib_tty_init( chdev_t * chdev )
 {
+    xptr_t reg_xp;
+
     chdev->cmd = &soclib_tty_cmd;
     chdev->isr = &soclib_tty_isr;
-
-    // get extended pointer on TTY-SOCLIB peripheral base address
-    xptr_t tty_xp = chdev->base;
+    chdev->aux = &soclib_tty_aux;
+
+    // get TTY channel and extended pointer on TTY peripheral base address
+    xptr_t   tty_xp  = chdev->base;
+    uint32_t channel = chdev->channel;
 
     // get SOCLIB_TTY device cluster and local pointer
@@ -42,6 +55,11 @@
     uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );
 
-    // mask both TTY_RX_IRQ and TTY_TX_IRQ
-    hal_remote_sw( XPTR( tty_cxy , tty_ptr + TTY_CONFIG_REG ) , 0 );
+    // reset TTY_RX_IRQ_ENABLE 
+    reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_RX_IRQ_ENABLE );
+    hal_remote_sw( reg_xp , 0 );
+
+    // reset TTY_TX_IRQ_ENABLE
+    reg_xp = XPTR( tty_cxy , tty_ptr + (channel * TTY_SPAN) + TTY_TX_IRQ_ENABLE );
+    hal_remote_sw( reg_xp , 0 );
 }
 
@@ -49,4 +67,12 @@
 void __attribute__ ((noinline)) soclib_tty_cmd( xptr_t th_xp )
 {
+
+#if CONFIG_READ_DEBUG
+enter_tty_cmd = hal_time_stamp();
+#endif
+
+txt_dmsg("\n[DBG] %s : core[%x,%d] / DEV thread enter / cycle %d\n", 
+__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
+
     // get client thread cluster and local pointer
     cxy_t      th_cxy = GET_CXY( th_xp );
@@ -57,4 +83,6 @@
     xptr_t   dev_xp = (xptr_t)hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.dev_xp ) );
 
+    assert( (type == TXT_READ) || (type == TXT_WRITE) , __FUNCTION__, "illegal command type");
+
     // get TXT device cluster and local pointer
     cxy_t     dev_cxy = GET_CXY( dev_xp );
@@ -72,60 +100,69 @@
     uint32_t * base    = tty_ptr + TTY_SPAN * channel;
 
-    if( type == TXT_READ )              // descheduling strategy for calling thread
+    // compute extended pointer on relevant TTY register
+    xptr_t reg_xp; 
+    if( type == TXT_READ )  reg_xp = XPTR( tty_cxy , base + TTY_RX_IRQ_ENABLE );
+    else                    reg_xp = XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE );
+
+    // enable relevant IRQ : data transfer will be done by the TTY_RX ISR)
+    hal_remote_sw( reg_xp , 1 );
+
+txt_dmsg("\n[DBG] %s : core[%x,%d] DEV thread deschedule / cycle %d\n",
+__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
+
+    // Block and deschedule server thread
+    thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
+    sched_yield();
+
+txt_dmsg("\n[DBG] %s : core[%x,%d] / DEV thread resume / cycle %d\n",
+__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
+
+#if CONFIG_READ_DEBUG
+exit_tty_cmd = hal_time_stamp();
+#endif
+
+}  // end soclib_tty_cmd()
+
+/////////////////////////////////////////////////////////////
+void __attribute__ ((noinline)) soclib_tty_aux( void * args )
+{
+    uint32_t   status;
+    bool_t     empty;
+    uint32_t   i;
+
+    xptr_t     dev_xp = ((txt_aux_t *)args)->dev_xp;
+    char     * buffer = ((txt_aux_t *)args)->buffer;
+    uint32_t   count  = ((txt_aux_t *)args)->count;
+    
+    // get TXT0 chdev cluster and local pointer
+    cxy_t     dev_cxy = GET_CXY( dev_xp );
+    chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
+
+    // get extended pointer on TTY channel base address
+    xptr_t tty_xp = (xptr_t)hal_remote_lwd( XPTR( dev_cxy , &dev_ptr->base ) );
+
+    // get TTY channel segment cluster and local pointer
+    cxy_t      tty_cxy = GET_CXY( tty_xp );
+    uint32_t * tty_ptr = (uint32_t *)GET_PTR( tty_xp );
+
+    // get extended pointers on TTY_WRITE & TTY_STATUS registers
+    xptr_t write_xp  = XPTR( tty_cxy , tty_ptr + TTY_WRITE );
+    xptr_t status_xp = XPTR( tty_cxy , tty_ptr + TTY_STATUS );
+
+    // loop on characters (busy waiting strategy)
+    for( i = 0 ; i < count ; i++ )
     {
-        // unmask RX_IRQ (data transfer will be done by the TTY_RX ISR)
-        xptr_t config_xp = XPTR( tty_cxy , base + TTY_CONFIG_REG );
-        uint32_t old = hal_remote_lw( config_xp );
-        uint32_t new = old | TTY_CONFIG_RX_ENABLE;
-        hal_remote_atomic_cas( config_xp , old , new );
-
-        // Block and deschedule server thread
-        thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
-        sched_yield( NULL );
+        do
+        {
+            // get TTY_STATUS
+            status = hal_remote_lw( status_xp );
+            empty  = ( (status & TTY_STATUS_TX_FULL) == 0 );
+
+            // transfer one byte if TX buffer empty
+            if ( empty )  hal_remote_sb( write_xp , buffer[i] );
+        }
+        while ( empty == false );
     }
-    else if( type == TXT_WRITE )        // descheduling strategy for calling thread
-    {
-        // unmask TX_IRQ (data transfer will be done by the TTY_TX ISR)
-        xptr_t config_xp = XPTR( tty_cxy , base + TTY_CONFIG_REG );
-        uint32_t old = hal_remote_lw( config_xp );
-        uint32_t new = old | TTY_CONFIG_TX_ENABLE;
-        hal_remote_atomic_cas( config_xp , old , new );
-
-        // Block and deschedule server thread
-        thread_block( CURRENT_THREAD , THREAD_BLOCKED_DEV_ISR );
-        sched_yield( NULL );
-    }
-    else if( type == TXT_SYNC_WRITE )  // busy waiting strategy for calling thread
-    {
-        uint32_t   status;
-        bool_t     empty;
-        uint32_t   i;
-
-        // get source buffer extended pointer & bytes count
-        uint32_t count  = hal_remote_lw ( XPTR( th_cxy , &th_ptr->txt_cmd.count ) );
-        xptr_t   buf_xp = hal_remote_lwd( XPTR( th_cxy , &th_ptr->txt_cmd.buf_xp ) );
-
-        // loop on characters
-        for( i = 0 ; i < count ; i++ )
-        {
-            do
-            {
-                // get TTY_STATUS_REG
-                status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );
-                empty  = ( (status & TTY_STATUS_TX_FULL) == 0 );
-
-                if ( empty )  // TTY_TX empty => transfer one byte
-                {
-                    // get one byte from command buffer in client cluster
-                    char byte = (char)hal_remote_lb( buf_xp + i );
-
-                    // write byte to TTY_WRITE_REG in TTY cluster
-                    hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , byte );
-                }
-            }
-            while ( empty == false );
-        }
-    }
-}  // end soclib_tty_cmd()
+}  // end soclib_tty_aux()
 
 
@@ -135,8 +172,15 @@
     uint32_t   type;         // command type
     uint32_t   count;        // number of bytes in buffer
-    xptr_t     buf_xp;       // Rextended pointer on buffer
+    xptr_t     buf_xp;       // extended pointer on buffer
+    xptr_t     status_xp;    // extended pointer on TTY_STATUS register
+    xptr_t     write_xp;     // extended pointer on TTY_WRITE register
+    xptr_t     read_xp;      // extended pointer on TTY_READ register
     uint32_t   status;       // TTY terminal status
     char       byte;         // read byte
     uint32_t   i;
+
+#if CONFIG_READ_DEBUG
+enter_tty_isr = hal_time_stamp();
+#endif
 
     // get extended pointer on client thread
@@ -153,4 +197,7 @@
     buf_xp  = hal_remote_lwd( XPTR( client_cxy , &client_ptr->txt_cmd.buf_xp ) );
 
+txt_dmsg("\n[DBG] %s : core[%x,%d] enter / cycle %d\n", 
+__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid , hal_time_stamp() );
+
     // get SOCLIB_TTY peripheral cluster and local pointer
     cxy_t      tty_cxy = GET_CXY( chdev->base );
@@ -160,31 +207,21 @@
     uint32_t * base = tty_ptr + TTY_SPAN * chdev->channel;
 
+    // get extended pointer on TTY registers
+    status_xp = XPTR( tty_cxy , base + TTY_STATUS );
+    write_xp  = XPTR( tty_cxy , base + TTY_WRITE );
+    read_xp   = XPTR( tty_cxy , base + TTY_READ );
+
     if( type == TXT_READ )              // read one single character
     {
-        // get TTY_STATUS_REG
-        status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );
-
-        if( status & TTY_STATUS_RX_FULL )   // TTY_RX full => transfer one byte
-        {
-            // get a byte from TTY_READ_REG, and acknowledge RX_IRQ
-            byte = (char)hal_remote_lb( XPTR( tty_cxy , base + TTY_READ_REG ) );
+        // get TTY_STATUS
+        status = hal_remote_lw( status_xp );
+
+        if( status & TTY_STATUS_RX_FULL )   // TTY_RX full => move one byte
+        {
+            // get a byte from TTY_READ, and acknowledge RX_IRQ
+            byte = (char)hal_remote_lb( read_xp );
 
             // write it to command buffer
             hal_remote_sb( buf_xp , byte );
-
-            // update TTY_WRITE_REG if echo mode
-            if( CONFIG_TXT_ECHO_MODE )
-            {
-                if( (byte == '\b') || (byte == 0x7F) )
-		        {
-			        hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , '\b' );
-			        hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , ' '  );
-			        hal_remote_sb( XPTR( tty_cxy , base + TTY_WRITE_REG ) , '\b' );
-		        }
-                else
-                {
-			        hal_remote_sw( XPTR( tty_cxy , base + TTY_WRITE_REG ) , byte );
-		        }
-            }
         }
         else                               // buffer empty => exit ISR for retry
@@ -192,20 +229,24 @@
             return;
         }
+
+        // disable RX_IRQ 
+        xptr_t reg_xp = XPTR( tty_cxy , base + TTY_RX_IRQ_ENABLE );
+        hal_remote_sw( reg_xp , 0 );
     }
-    else if( type == TXT_WRITE )         // write a string
+    else if( type == TXT_WRITE )         // write all characters in string
     {
         // loop on characters
         for( i = 0 ; i < count ; i++ )
         {
-            // get TTY_STATUS_REG
-            status = hal_remote_lw( XPTR( tty_cxy , base + TTY_STATUS_REG ) );
-
-            if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => transfer one byte
+            // get TTY_STATUS
+            status = hal_remote_lw( status_xp );
+
+            if( (status & TTY_STATUS_TX_FULL) == 0 ) // TTY_TX empty => move one byte
             {
                 // get one byte from command buffer
                 byte = (char)hal_remote_lb( buf_xp + i );
 
-                // write byte to TTY_WRITE_REG, and acknowledge TX_IRQ
-                hal_remote_sb( XPTR( tty_cxy , base + TTY_STATUS_REG ) , byte );
+                // write byte to TTY_WRITE, and acknowledge TX_IRQ
+                hal_remote_sb( write_xp , byte );
             }
             else         // TTY_TX full => update command arguments and exit ISR for retry
@@ -216,10 +257,11 @@
             }
         }
+
+        // disable TX_IRQ 
+        xptr_t reg_xp = XPTR( tty_cxy , base + TTY_TX_IRQ_ENABLE );
+        hal_remote_sw( reg_xp , 0 );
     }
 
     // The I/O operation completed when we reach this point
-
-    // mask both TTY_RX_IRQ and TTY_TX_IRQ
-    hal_remote_sw( XPTR( tty_cxy , base + TTY_CONFIG_REG ) , 0 );
 
     // set I/O operation status in command
@@ -227,9 +269,18 @@
 
     // unblock server thread
-    thread_unblock( XPTR( local_cxy , &chdev->server ) , THREAD_BLOCKED_DEV_ISR );
+    thread_unblock( XPTR( local_cxy , chdev->server ) , THREAD_BLOCKED_DEV_ISR );
 
     // unblock client thread
     thread_unblock( client_xp , THREAD_BLOCKED_IO );
 
+    hal_fence();
+
+txt_dmsg("\n[DBG] %s : core[%x,%d] exit / cycle %d\n", 
+__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
+
+#if CONFIG_READ_DEBUG
+exit_tty_isr = hal_time_stamp();
+#endif
+
 }  // end soclib_tty_isr()
 
