Index: /soft/giet_vm/Makefile
===================================================================
--- /soft/giet_vm/Makefile	(revision 296)
+++ /soft/giet_vm/Makefile	(revision 297)
@@ -11,5 +11,5 @@
 ### partition sectors    = 524832 
 
-MAP_XML      = mappings/4c_4p_sort_leti_ext.xml
+MAP_XML      = mappings/4c_1p_four_leti_ext.xml
 
 ### Objects to be linked for kernel.elf
Index: /soft/giet_vm/display/main.c
===================================================================
--- /soft/giet_vm/display/main.c	(revision 296)
+++ /soft/giet_vm/display/main.c	(revision 297)
@@ -24,15 +24,8 @@
     ///////////////////////////////////////////
     fd = giet_fat_open( "misc/images.raw", 0 );
-    if ( fd < 0 )
-    {
-        giet_tty_printf("\n*** echec giet_fat_open for misc/images.raw at cycle %d\n", 
-                        giet_proctime() );
-        giet_exit();
-    }
-    else
-    {
-        giet_tty_printf("\ngiet_fat_open completed for misc/images.raw at cycle %d\n", 
-                        giet_proctime() );
-    }
+    if ( fd < 0 ) giet_exit("echec giet_fat_open for misc/images.raw");
+
+    giet_tty_printf("\ngiet_fat_open completed for misc/images.raw at cycle %d\n", 
+                    giet_proctime() );
 
     /////////////////////////////////////////
@@ -40,35 +33,18 @@
     {
         // lecture image sur le disque
-        blocks = giet_fat_read( fd, buf, NBLOCKS, blocks_to_skip );
-        if ( blocks != NBLOCKS )
-        {
-            giet_tty_printf("\n*** echec giet_fat_read at cycle %d\n", 
-                            giet_proctime() );
-            giet_exit();
-        }
-        else
-        {
-            giet_tty_printf("\ngiet_fat_read for image %d completed at cycle %d \n", 
-                            (blocks_to_skip>>5), giet_proctime());
-        }
+        giet_fat_read( fd, buf, NBLOCKS, blocks_to_skip );
+        
+        giet_tty_printf("\ngiet_fat_read for image %d completed at cycle %d \n", 
+                        (blocks_to_skip>>5), giet_proctime());
 
         // transfert vers le frame buffer  
-        ko = giet_fb_sync_write( 0, buf, 128 * 128 );
-        if ( ko )
-        {
-            giet_tty_printf("\n*** echec giet_fb_sync_write at cycle %d\n", 
-                            giet_proctime() );
-            giet_exit();
-        }
-        else
-        {
-            giet_tty_printf("\ndisplay completed for image %d at cycle %d \n", 
-                            (blocks_to_skip>>5), giet_proctime());
-        }
+        giet_fb_sync_write( 0, buf, 128 * 128 );
+
+        giet_tty_printf("\ndisplay completed for image %d at cycle %d \n", 
+                        (blocks_to_skip>>5), giet_proctime());
 
         blocks_to_skip = blocks_to_skip + NBLOCKS;
     }
 
-    giet_tty_printf("\n*** Tak display exit at cycle %d ***\n", giet_proctime());
-    giet_exit();
+    giet_exit("completed");
 }
Index: /soft/giet_vm/display/main_cma.c
===================================================================
--- /soft/giet_vm/display/main_cma.c	(revision 296)
+++ /soft/giet_vm/display/main_cma.c	(revision 297)
@@ -20,19 +20,10 @@
                       x, y, lpid, giet_proctime() );
 
-    //////////////////////////////////////////
     fd = giet_fat_open( "misc/images.raw", 0 );
-    if ( fd < 0 )
-    {
-        giet_tty_printf("\n*** echec giet_fat_open for misc/images.raw at cycle %d\n", 
-                        giet_proctime() );
-        giet_exit();
-    }
-    else
-    {
-        giet_tty_printf("\ngiet_fat_open completed for misc/images.raw at cycle %d\n", 
-                        giet_proctime() );
-    }
+    if ( fd < 0 ) giet_exit("echec giet_fat_open for misc/images.raw");
 
-    ////////////////////////////////////////
+    giet_tty_printf("\ngiet_fat_open completed for misc/images.raw at cycle %d\n", 
+                    giet_proctime() );
+
     giet_fb_cma_init( buf0, buf1, 128*128 );
 
@@ -42,5 +33,4 @@
     while ( blocks_to_skip < 10 * NBLOCKS )
     {
-        ///////////////////////////////////////////////////
         giet_fat_read( fd, buf0, NBLOCKS, blocks_to_skip );
 
@@ -48,5 +38,4 @@
                             giet_proctime() );
 
-        ///////////////////////
         giet_fb_cma_write( 0 );
 
@@ -56,5 +45,4 @@
         blocks_to_skip = blocks_to_skip + NBLOCKS;
 
-        ///////////////////////////////////////////////////
         giet_fat_read( fd, buf1, NBLOCKS, blocks_to_skip );
 
@@ -62,5 +50,4 @@
                             giet_proctime() );
 
-        ///////////////////////
         giet_fb_cma_write( 1 );
         
@@ -71,9 +58,6 @@
     }
 
-    ///////////////////
     giet_fb_cma_stop();
 
-    giet_tty_printf("\n*** Task display exit at cycle %d ***\n", giet_proctime());
-
-    giet_exit();
+    giet_exit("display completed");
 }
Index: /soft/giet_vm/giet_drivers/bdv_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/bdv_driver.c	(revision 296)
+++ /soft/giet_vm/giet_drivers/bdv_driver.c	(revision 297)
@@ -304,10 +304,20 @@
     unsigned int lpid       = procid % NB_PROCS_MAX;
 
-    // acknowledge WTI in local XCU if required 
-    unsigned int value;
-    if ( irq_type == IRQ_TYPE_WTI ) _xcu_get_wti_value( cluster_xy, irq_id, &value );
-
-    // save status in _bdv_status variable and reset IRQ
-    _bdv_status = _bdv_get_register( BLOCK_DEVICE_STATUS ); 
+    // get BDV status (and reset IRQ)
+    unsigned int status =  _bdv_get_register( BLOCK_DEVICE_STATUS ); 
+
+    // check status: does nothing if IDLE or BUSY
+    if ( (status == BLOCK_DEVICE_IDLE) ||
+         (status == BLOCK_DEVICE_BUSY) )   return;
+ 
+    // reset WTI in XCU if WTI type
+    if ( irq_type == IRQ_TYPE_WTI ) 
+    {
+        unsigned int value;
+        _xcu_get_wti_value( cluster_xy, irq_id, &value );
+    }
+    
+    // save status in kernel buffer _bdv_status
+    _bdv_status = status; 
 
     // identify task waiting on BDV
@@ -315,4 +325,15 @@
     unsigned int ltid       = _bdv_gtid & 0xFFFF;
     unsigned int remote_xy  = rprocid / NB_PROCS_MAX;
+
+    // re-activates sleeping task
+    _set_task_slot( rprocid,     // global processor index
+                    ltid,        // local task index on processor
+                    CTX_RUN_ID,  // CTX_RUN slot 
+                    1 );         // running
+
+    // requires a context switch for remote processor running the waiting task 
+    _xcu_send_wti( remote_xy,    // cluster index
+                   lpid,         // local processor index
+                   0 );          // don't force context switch if not idle
 
 #if GIET_DEBUG_IRQS  // we don't take the TTY lock to avoid deadlock
@@ -343,14 +364,4 @@
 #endif
 
-    // re-activates sleeping task
-    _set_task_slot( rprocid,     // global processor index
-                    ltid,        // local task index on processor
-                    CTX_RUN_ID,  // CTX_RUN slot 
-                    1 );         // running
-
-    // requires a context switch for remote processor running the waiting task 
-    _xcu_send_wti( remote_xy,    // cluster index
-                   lpid,         // local processor index
-                   0 );          // don't force context switch if not idle
 }
 
Index: /soft/giet_vm/giet_drivers/fbf_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/fbf_driver.c	(revision 296)
+++ /soft/giet_vm/giet_drivers/fbf_driver.c	(revision 297)
@@ -258,5 +258,5 @@
     {
         // SYNC request for channel descriptor
-        _memc_sync( desc_paddr, 32 );
+        _mmc_sync( desc_paddr, 32 );
     }
 
@@ -320,5 +320,5 @@
         {
             // INVAL L2 cache for the channel descriptor,
-            _memc_inval( _fb_cma_desc_paddr[channel_id], 32 );
+            _mmc_inval( _fb_cma_desc_paddr[channel_id], 32 );
 
             // INVAL L1 cache for the channel descriptor,
@@ -339,5 +339,5 @@
         // SYNC request for the user buffer because 
         // this buffer will be read from XRAM by the CMA component
-        _memc_sync( buf_paddr, _fb_cma_channel[channel_id].length );
+        _mmc_sync( buf_paddr, _fb_cma_channel[channel_id].length );
     }
 
@@ -356,5 +356,5 @@
         // SYNC request for the channel descriptor, because
         // it will be read in XRAM by the CMA component
-        _memc_sync( _fb_cma_desc_paddr[channel_id], 32 );
+        _mmc_sync( _fb_cma_desc_paddr[channel_id], 32 );
     }
 
Index: /soft/giet_vm/giet_drivers/ioc_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/ioc_driver.c	(revision 296)
+++ /soft/giet_vm/giet_drivers/ioc_driver.c	(revision 297)
@@ -286,5 +286,5 @@
 
         // L2 cache (only if IOB used)
-        if ( USE_IOB ) _memc_inval( buf_paddr, length );
+        if ( USE_IOB ) _mmc_inval( buf_paddr, length );
     }
     else         // memory read : update data caches
@@ -293,5 +293,5 @@
 
         // L2 cache (only if IOB used)
-        if ( USE_IOB ) _memc_sync( buf_paddr, length );
+        if ( USE_IOB ) _mmc_sync( buf_paddr, length );
     }
 
Index: /soft/giet_vm/giet_drivers/mmc_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/mmc_driver.c	(revision 296)
+++ /soft/giet_vm/giet_drivers/mmc_driver.c	(revision 297)
@@ -41,11 +41,10 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-// _memc_inval()
 // This function invalidates all cache lines covering a memory buffer defined
 // by the physical base address, and the length.
 // The buffer address MSB are used to compute the cluster index.
 ///////////////////////////////////////////////////////////////////////////////////
-void _memc_inval( paddr_t      buf_paddr,
-                  unsigned int buf_length )
+void _mmc_inval( paddr_t      buf_paddr,
+                 unsigned int buf_length )
 {
     // compute cluster coordinates
@@ -78,11 +77,10 @@
 }
 ///////////////////////////////////////////////////////////////////////////////////
-// _memc_sync()
 // This function copies to external RAM all cache lines covering a memory buffer 
 // defined by the physical base address, and the length, if they are dirty.
 // The buffer address MSB are used to compute the cluster index.
 ///////////////////////////////////////////////////////////////////////////////////
-void _memc_sync( paddr_t      buf_paddr,
-                 unsigned int buf_length )
+void _mmc_sync( paddr_t      buf_paddr,
+                unsigned int buf_length )
 {
     // compute cluster coordinates
@@ -115,4 +113,19 @@
 }
 
+//////////////////////////////////////////////////////////////////////////////////
+// This ISR access the vci_mem_cache component to get the faulty physical
+// address and the associated SRCID. It must also acknowledge the IRQ.
+//
+// TODO implement...
+//////////////////////////////////////////////////////////////////////////////////
+void _mmc_isr( unsigned int irq_type,  // should be HWI 
+               unsigned int irq_id,    // index returned by ICU
+               unsigned int channel )  // unused
+{
+    _printf("[GIET ERROR] MMC IRQ received, but _mmc_isr() not implemented...\n");
+}
+
+
+
 // Local Variables:
 // tab-width: 4
Index: /soft/giet_vm/giet_drivers/mmc_driver.h
===================================================================
--- /soft/giet_vm/giet_drivers/mmc_driver.h	(revision 296)
+++ /soft/giet_vm/giet_drivers/mmc_driver.h	(revision 297)
@@ -33,9 +33,13 @@
 ///////////////////////////////////////////////////////////////////////////////////
 
-extern void _memc_inval( unsigned long long buf_paddr, 
-                         unsigned int buf_length );
+extern void _mmc_inval( unsigned long long buf_paddr, 
+                        unsigned int buf_length );
 
-extern void _memc_sync(  unsigned long long buf_paddr, 
-                         unsigned int buf_length);
+extern void _mmc_sync(  unsigned long long buf_paddr, 
+                        unsigned int buf_length);
+
+extern void _mmc_isr( unsigned int irq_type,
+                      unsigned int irq_id,
+                      unsigned int channel );
 
 ///////////////////////////////////////////////////////////////////////////////////
Index: /soft/giet_vm/giet_drivers/tty_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/tty_driver.c	(revision 296)
+++ /soft/giet_vm/giet_drivers/tty_driver.c	(revision 297)
@@ -170,10 +170,10 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-// This ISR handles the IRQ signaling that the RX buffer is full.
+// This ISR handles the IRQ signaling that the RX buffer is not empty.
 // IT can be an HWI or an SWI.
-// There is one single multi_tty component controling all channels.
 // There is one communication buffer _tty_rx_buf[i] and one synchronisation
 // variable _tty_rx_full[i] per channel.
-// A character is lost if the buffer is full when the ISR is executed.
+// Does nothing if the TTY_RX buffer is empty, or if the kernel buffer is full
+// when the ISR is called.
 ///////////////////////////////////////////////////////////////////////////////////
 void _tty_rx_isr( unsigned int irq_type,   // HWI / WTI
@@ -183,12 +183,25 @@
     unsigned int cluster_xy = _get_procid() / NB_PROCS_MAX;
 
-    if ( irq_type == IRQ_TYPE_WTI )   // reset SWI in XCU if required
+    // get TTY status
+    unsigned int status = _tty_get_register( channel, TTY_STATUS );
+
+    // check both TTY status and kernel buffer status:
+    // does nothing if kernel buffer full or tty_buffer empty
+    if ( ((status & 0x1) == 0) || 
+         (_tty_rx_full[channel] != 0) )  return;
+ 
+    // reset WTI in XCU if WTI type
+    if ( irq_type == IRQ_TYPE_WTI ) 
     {
         unsigned int value;
         _xcu_get_wti_value( cluster_xy, irq_id, &value );
     }
-      
-    // get character and reset TTY IRQ
-    _tty_rx_buf[channel] = _tty_get_register( channel, TTY_READ ); 
+
+    // transfer character to kernel buffer and acknowledge TTY IRQ 
+    _tty_rx_buf[channel]  = _tty_get_register( channel, TTY_READ ); 
+
+    // set kernel buffer status
+    asm volatile( "sync" );
+    _tty_rx_full[channel] = 1;
 
 #if GIET_DEBUG_IRQS  // we don't take the TTY lock to avoid deadlock
@@ -209,6 +222,4 @@
 #endif
 
-    // signals character available 
-    _tty_rx_full[channel] = 1;
 }
 
Index: /soft/giet_vm/giet_kernel/irq_handler.c
===================================================================
--- /soft/giet_vm/giet_kernel/irq_handler.c	(revision 296)
+++ /soft/giet_vm/giet_kernel/irq_handler.c	(revision 297)
@@ -16,4 +16,5 @@
 #include <nic_driver.h>
 #include <cma_driver.h>
+#include <mmc_driver.h>
 #include <bdv_driver.h>
 #include <dma_driver.h>
@@ -116,4 +117,5 @@
         else if ( isr_type == ISR_NIC_TX ) _nic_tx_isr ( irq_type, irq_id, channel );
         else if ( isr_type == ISR_TIMER  ) _timer_isr  ( irq_type, irq_id, channel );
+        else if ( isr_type == ISR_MMC    ) _mmc_isr    ( irq_type, irq_id, channel );
         else
         {
Index: /soft/giet_vm/giet_kernel/irq_handler.h
===================================================================
--- /soft/giet_vm/giet_kernel/irq_handler.h	(revision 296)
+++ /soft/giet_vm/giet_kernel/irq_handler.h	(revision 297)
@@ -31,4 +31,5 @@
     ISR_NIC_TX  = 8,
     ISR_CMA     = 9,
+    ISR_MMC     = 10,
 };
 
Index: /soft/giet_vm/hello/main.c
===================================================================
--- /soft/giet_vm/hello/main.c	(revision 296)
+++ /soft/giet_vm/hello/main.c	(revision 297)
@@ -5,6 +5,4 @@
 {
 	char		    byte;
-    unsigned int	proc = giet_procid();
-
     unsigned int    procid     = giet_procid();
     unsigned int    cluster_xy = procid/NB_PROCS_MAX;
