Index: soft/giet_vm/giet_drivers/bdv_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/bdv_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/bdv_driver.c	(revision 437)
@@ -6,47 +6,7 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The bdv_driver.c and bdv_driver.h files are part ot the GIET-VM kernel.
-// This driver supports the SocLib vci_block_device component, that is
-// a single channel, block oriented, external storage contrÃŽler.
-//
-// The _bdv_read() and _bdv_write() functions are always blocking.
-// They can be called in 3 modes:
-//
-// - In BOOT mode, these functions use a polling policy on the BDV STATUS 
-//   register to detect transfer completion, as interrupts are not activated. 
-//   This mode is used by the boot code to load the map.bin file into memory
-//   (before MMU activation), or to load the .elf files (after MMU activation). 
-//
-// - In KERNEL mode, these functions use a descheduling strategy:
-//   The ISR executed when transfer completes should restart the calling task.
-//   There is no checking of user access right to the memory buffer. 
-//   This mode must be used, for an "open" system call.
-//
-// - In USER mode, these functions use a descheduling strategy:
-//   The ISR executed when transfer completes should restart the calling task, 
-//   The user access right to the memory buffer must be checked.
-//   This mode must be used for a "read/write" system call.
-//
-// As the BDV component can be used by several programs running in parallel,
-// the _bdv_lock variable guaranties exclusive access to the device.  The
-// _bdv_read() and _bdv_write() functions use atomic LL/SC to get the lock.
-//
-// Finally, the memory buffer must fulfill the following conditions:
-// - The buffer must be word aligned, 
-// - The buffer must be mapped in user space for an user access, 
-// - The buffer must be writable in case of (to_mem) access,
-// - The total number of physical pages occupied by the user buffer cannot
-//   be larger than 512 pages if the IOMMU is activated,
-// - All physical pages occupied by the user buffer must be contiguous
-//   if the IOMMU is not activated.
-// An error code is returned if these conditions are not verified.
-//
-// The SEG_IOC_BASE address must be defined in the hard_config.h file.
-///////////////////////////////////////////////////////////////////////////////////
 // Implementation notes:
-//
 // 1. In order to share code, the two _bdv_read() and _bdv_write() functions
 //    call the same _bdv_access() function.
-//
 // 2. All accesses to BDV registers are done by the two
 //    _bdv_set_register() and _bdv_get_register() low-level functions,
@@ -126,11 +86,23 @@
 
 #if GIET_DEBUG_IOC_DRIVER
-_printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] enters at cycle %d\n"
-        " - to_mem  = %d\n"
-        " - mode    = %d\n"
-        " - paddr   = %l\n"
-        " - sectors = %x\n"
-        " - lba     = %x\n",
-        x, y, p, _get_proctime(), to_mem, mode, buf_paddr, count, lba );
+_puts("\n[BDV DEBUG] _bdv_access() : P[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts(",");
+_putd( p );
+_puts("] enters at cycle ");
+_putd( _get_proctime() );
+_puts("\n - to_mem  = ");
+_putd( to_mem );
+_puts("\n - mode    = ");
+_putd( mode );
+_puts("\n - paddr   = ");
+_putl( buf_paddr );
+_puts("\n - sectors = ");
+_putd( count );
+_puts("\n - lba     = ");
+_putx( lba );
+_puts("\n");
 #endif
 
@@ -141,6 +113,13 @@
 
 #if GIET_DEBUG_IOC_DRIVER
-_printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] get bdv_lock at cycle %d \n",
-        x, y, p, _get_proctime() );
+_puts("\n[BDV DEBUG] _bdv_access() : P[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts(",");
+_putd( p );
+_puts("] get bdv_lock at cycle ");
+_pud( _get_proctime() );
+_puts("\n");
 #endif
 
@@ -160,6 +139,11 @@
 
 #if GIET_DEBUG_IOC_DRIVER
-_printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] launch transfer in polling mode\n",
-        x, y, p );
+_puts("\n[BDV DEBUG] _bdv_access() : P[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts(",");
+_putd( p );
+_puts("] launch transfer in polling mode\n");
 #endif
         unsigned int status;
@@ -169,6 +153,11 @@
 
 #if GIET_DEBUG_IOC_DRIVER
-_printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] wait on BDV_STATUS register ...\n",
-        x, y, p );
+_puts("\n[BDV DEBUG] _bdv_access() : P[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts(",");
+_putd( p );
+_puts("] wait on BDV_STATUS register ...\n");
 #endif
         }
@@ -214,21 +203,28 @@
 
 #if GIET_DEBUG_IOC_DRIVER
-_printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] launch transfer in interrupt mode\n",
-        x, y, p );
-#endif
+_puts("\n[BDV DEBUG] _bdv_access() : P[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts(",");
+_putd( p );
+_puts("] launch transfer in nterrupt mode\n");
+#endif
+
         // deschedule task
         _ctx_switch();                      
 
 #if GIET_DEBUG_IOC_DRIVER
-_printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] resume execution after descheduling\n",
-        x, y, p );
+_puts("\n[BDV DEBUG] _bdv_access() : P[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts(",");
+_putd( p );
+_puts("] resume execution after descheduling\n");
 #endif
         // restore SR
         _it_restore( &save_sr );
 
-#if GIET_DEBUG_IOC_DRIVER
-_printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] returns from _it_restore()\n",
-        x, y, p );
-#endif
         // analyse status
         error = ( (_bdv_status == BLOCK_DEVICE_READ_ERROR) ||
@@ -241,6 +237,15 @@
 
 #if GIET_DEBUG_IOC_DRIVER
-_printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] exit at cycle %d / error = %d\n",
-        x, y, p, _get_proctime(), error );
+_puts("\n[BDV DEBUG] _bdv_access() : P[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts(",");
+_putd( p );
+_puts("] exit at cycle ");
+_putd( _get_proctime() );
+_puts(" / error = ");
+_putd( error )
+_puts("\n");
 #endif
 
@@ -249,12 +254,13 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-// This function cheks block size, and desactivates the interrupts.
-// Return 0 for success, > 0 if error
-///////////////////////////////////////////////////////////////////////////////
+//      External functions
+///////////////////////////////////////////////////////////////////////////////
+
+////////////////////////
 unsigned int _bdv_init()
 {
     if ( _bdv_get_register( BLOCK_DEVICE_BLOCK_SIZE ) != 512 )
     {
-        _printf("\n[GIET ERROR] in _bdv_init() : block size must be 512 bytes\n");
+        _puts("\n[GIET ERROR] in _bdv_init() : block size must be 512 bytes\n");
         return 1; 
     }
@@ -264,12 +270,5 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// Transfer data from the block device to a memory buffer. 
-// - mode     : BOOT / KERNEL / USER
-// - lba      : first block index on the block device
-// - buffer   : base address of the memory buffer (must be word aligned)
-// - count    : number of blocks to be transfered.
-// Returns 0 if success, > 0 if error.
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////
 unsigned int _bdv_read( unsigned int       mode,  
                         unsigned int       lba, 
@@ -284,12 +283,5 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// Transfer data from a memory buffer to the block device. 
-// - mode     : BOOT / KERNEL / USER
-// - lba      : first block index on the block device
-// - buffer   : base address of the memory buffer (must be word aligned)
-// - count    : number of blocks to be transfered.
-// Returns 0 if success, > 0 if error.
-///////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////
 unsigned int _bdv_write( unsigned int       mode,  
                          unsigned int       lba, 
@@ -304,7 +296,5 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// Returns device status.
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////
 unsigned int _bdv_get_status()
 {
@@ -312,7 +302,5 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// Returns block size.
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////
 unsigned int _bdv_get_block_size()
 {
@@ -320,12 +308,5 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////////
-// This ISR save the status, acknowledge the IRQ,
-// and activates the task waiting on IO transfer.
-// It can be an HWI or a SWI.
-//
-// TODO the _set_task_slot access should be replaced by an atomic LL/SC
-//      when the CTX_RUN bool will be replaced by a bit_vector. 
-///////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////
 void _bdv_isr( unsigned int irq_type,   // HWI / WTI
                unsigned int irq_id,     // index returned by ICU
Index: soft/giet_vm/giet_drivers/bdv_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/bdv_driver.h	(revision 436)
+++ soft/giet_vm/giet_drivers/bdv_driver.h	(revision 437)
@@ -5,4 +5,42 @@
 // Maintainer: cesar fuguet
 // Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The bdv_driver.c and bdv_driver.h files are part ot the GIET-VM kernel.
+// This driver supports the SocLib vci_block_device component, that is
+// a single channel, block oriented, external storage contrÃŽler.
+//
+// The _bdv_read() and _bdv_write() functions are always blocking.
+// They can be called in 3 modes:
+//
+// - In BOOT mode, these functions use a polling policy on the BDV STATUS 
+//   register to detect transfer completion, as interrupts are not activated. 
+//   This mode is used by the boot code to load the map.bin file into memory
+//   (before MMU activation), or to load the .elf files (after MMU activation). 
+//
+// - In KERNEL mode, these functions use a descheduling strategy:
+//   The ISR executed when transfer completes should restart the calling task.
+//   There is no checking of user access right to the memory buffer. 
+//   This mode must be used, for an "open" system call.
+//
+// - In USER mode, these functions use a descheduling strategy:
+//   The ISR executed when transfer completes should restart the calling task, 
+//   The user access right to the memory buffer must be checked.
+//   This mode must be used for a "read/write" system call.
+//
+// As the BDV component can be used by several programs running in parallel,
+// the _bdv_lock variable guaranties exclusive access to the device.  The
+// _bdv_read() and _bdv_write() functions use atomic LL/SC to get the lock.
+//
+// Finally, the memory buffer must fulfill the following conditions:
+// - The buffer must be word aligned, 
+// - The buffer must be mapped in user space for an user access, 
+// - The buffer must be writable in case of (to_mem) access,
+// - The total number of physical pages occupied by the user buffer cannot
+//   be larger than 512 pages if the IOMMU is activated,
+// - All physical pages occupied by the user buffer must be contiguous
+//   if the IOMMU is not activated.
+// An error code is returned if these conditions are not verified.
+//
+// The SEG_IOC_BASE address must be defined in the hard_config.h file.
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -56,9 +94,34 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-// BDV access functions (vci_block_device)
+//            Access functions
 ///////////////////////////////////////////////////////////////////////////////////
 
+///////////////////////////////////////////////////////////////////////////////////
+// This function cheks block size == 512, and desactivates the interrupts.
+// Return 0 for success, > 0 if error
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _bdv_init();
 
+///////////////////////////////////////////////////////////////////////////////////
+// Transfer data from the block device to a memory buffer. 
+// - mode     : BOOT / KERNEL / USER
+// - lba      : first block index on the block device
+// - buffer   : base address of the memory buffer (must be word aligned)
+// - count    : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+////////////////////////////////////////////////////////////////////////////////////
+extern unsigned int _bdv_read(  unsigned int       mode,
+                                unsigned int       lba, 
+                                unsigned long long buffer,
+                                unsigned int       count );
+
+///////////////////////////////////////////////////////////////////////////////////
+// Transfer data from a memory buffer to the block device. 
+// - mode     : BOOT / KERNEL / USER
+// - lba      : first block index on the block device
+// - buffer   : base address of the memory buffer (must be word aligned)
+// - count    : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _bdv_write( unsigned int       mode,
                                 unsigned int       lba, 
@@ -66,18 +129,25 @@
                                 unsigned int       count );
 
-extern unsigned int _bdv_read(  unsigned int       mode,
-                                unsigned int       lba, 
-                                unsigned long long buffer,
-                                unsigned int       count );
-
+///////////////////////////////////////////////////////////////////////////////////
+// Returns device status.
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _bdv_get_status();
 
+///////////////////////////////////////////////////////////////////////////////////
+// Returns block size.
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _bdv_get_block_size();
 
+///////////////////////////////////////////////////////////////////////////////////
+// This ISR save the status, acknowledge the IRQ, and activates the task 
+// waiting on IO transfer. It can be an HWI or a SWI.
+//
+// TODO the _set_task_slot access should be replaced by an atomic LL/SC
+//      when the CTX_RUN bool will be replaced by a bit_vector. 
+///////////////////////////////////////////////////////////////////////////////////
 extern void _bdv_isr( unsigned irq_type,
                       unsigned irq_id,
                       unsigned channel );
 
-///////////////////////////////////////////////////////////////////////////////////
 
 #endif
Index: soft/giet_vm/giet_drivers/cma_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/cma_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/cma_driver.c	(revision 437)
@@ -4,21 +4,4 @@
 // Author    : alain greiner
 // Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
-// The cma_driver.c and cma_driver.h files are part ot the GIET-VM kernel.
-// This driver supports the SocLib vci_chbuf_dma component, that is
-// a multi channels, chained buffer DMA controller.
-//
-// This component can be used in conjonction with the SocLib vci_frame_buffer 
-// to display images, or with the SocLib vci_multi_nic controller to tranfer
-// both RX and TX packets between NIC and memory buffers.
-//
-// The SEG_DMA_BASE address must be defined in the hard_config.h file
-////////////////////////////////////////////////////////////////////////////////////
-// Implementation notes:
-// 1. The higher level access functions can be found in the fbf_driver and 
-//    nic_driver files.
-// 2. All accesses to CMA registers are done by the two
-//    _cma_set_register() and _cma_get_register() low-level functions,
-//    that are handling virtual / physical extended addressing.
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -31,7 +14,5 @@
 #endif
 
-///////////////////////////////////////////////////////////////////////////////
-// This low_level function returns the value contained in register (index).
-///////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////
 unsigned int _cma_get_register( unsigned int channel,
                                 unsigned int index )
@@ -42,7 +23,5 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// This low-level function set a new value in register (index).
-///////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////
 void _cma_set_register( unsigned int channel,
                         unsigned int index,
@@ -54,12 +33,35 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// This ISR handles the IRQ generated by a CMA channel.
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////
+void _cma_start_channel( unsigned int       channel,
+                         unsigned long long src_paddr,
+                         unsigned int       src_nbufs,
+                         unsigned long long dst_paddr,
+                         unsigned int       dst_nbufs,
+                         unsigned int       buf_length )
+{
+    _cma_set_register( channel, CHBUF_SRC_DESC , (unsigned int)(src_paddr & 0xFFFFFFFF) );
+    _cma_set_register( channel, CHBUF_SRC_EXT  , (unsigned int)(src_paddr >> 32) );
+    _cma_set_register( channel, CHBUF_SRC_NBUFS, src_nbufs );
+    _cma_set_register( channel, CHBUF_DST_DESC , (unsigned int)(dst_paddr & 0xFFFFFFFF) );
+    _cma_set_register( channel, CHBUF_DST_EXT  , (unsigned int)(dst_paddr >> 32) );
+    _cma_set_register( channel, CHBUF_DST_NBUFS, dst_nbufs );
+    _cma_set_register( channel, CHBUF_BUF_SIZE , buf_length );
+    _cma_set_register( channel, CHBUF_PERIOD   , 300 );
+    _cma_set_register( channel, CHBUF_RUN      , 1 );
+}
+
+//////////////////////////////////////////////
+void _cma_stop_channel( unsigned int channel )
+{
+    _cma_set_register( channel, CHBUF_RUN      , 0 );
+}
+
+//////////////////////////////////////
 void _cma_isr( unsigned int irq_type,
                unsigned int irq_id,
                unsigned int channel )
 {
-    _printf("\n[GIET ERROR] _cma_isr() not implemented\n");
+    _puts("\n[GIET ERROR] _cma_isr() not implemented\n");
     _exit();
 }
Index: soft/giet_vm/giet_drivers/cma_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/cma_driver.h	(revision 436)
+++ soft/giet_vm/giet_drivers/cma_driver.h	(revision 437)
@@ -5,4 +5,21 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
+// The cma_driver.c and cma_driver.h files are part ot the GIET-VM kernel.
+// This driver supports the SocLib vci_chbuf_dma component, that is
+// a multi channels, chained buffer DMA controller.
+//
+// This component can be used in conjonction with the SocLib vci_frame_buffer 
+// to display images, or with the SocLib vci_multi_nic controller to tranfer
+// RX or TX packets between NIC and memory buffers.
+//
+// The SEG_CMA_BASE address must be defined in the hard_config.h file
+//
+// All accesses to CMA registers are done by the two _cma_set_register() 
+// and _cma_get_register() low-level functions, that are handling virtual 
+// to physical extended addressing.
+//
+// The higher level access functions are defined in the fbf_driver 
+// and nic_driver files.
+///////////////////////////////////////////////////////////////////////////////////
 
 #ifndef _GIET_CMA_DRIVERS_H_
@@ -10,5 +27,5 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-// CMA (vci_chbuf_dma) registers offsets
+//  registers offsets
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -30,19 +47,31 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-// CMA (vci_chbuf_dma) low-level access functions
+//    access functions
 ///////////////////////////////////////////////////////////////////////////////////
 
+////////////////////////////////////////////////////////////
 extern unsigned int _cma_get_register( unsigned int channel,
                                        unsigned int index );
 
+///////////////////////////////////////////////////
 extern void _cma_set_register( unsigned int channel,
                                unsigned int index,
                                unsigned int value );
 
+///////////////////////////////////////////////////
+void _cma_start_channel( unsigned int       channel,
+                         unsigned long long src_paddr,
+                         unsigned int       src_nbufs,
+                         unsigned long long dst_paddr,
+                         unsigned int       dst_nbufs,
+                         unsigned int       buf_length );
+
+//////////////////////////////////////////////
+void _cma_stop_channel( unsigned int channel );
+
+////////////////////////////////////////////
 extern void _cma_isr( unsigned int irq_type,
                       unsigned int irq_id,
                       unsigned int channel );
-
-///////////////////////////////////////////////////////////////////////////////////
 
 #endif
Index: soft/giet_vm/giet_drivers/dma_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/dma_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/dma_driver.c	(revision 437)
@@ -5,24 +5,4 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The dma_driver.c and dma_driver.h files are part ot the GIET-VM nano-kernel.
-// This driver supports the SoCLib vci_multi_dma component.
-// 
-// It can exist several DMA controlers in the architecture (one per cluster),
-// and each controller can contain several channels.
-// 
-// There is  (NB_CLUSTERS * NB_DMA_CHANNELS) channels, indexed by a global index:
-//        dma_id = cluster_xy * NB_DMA_CHANNELS + loc_id
-//
-// A DMA channel is a private ressource allocated to a given processor.
-// It is exclusively used by the kernet to speedup data transfers, and
-// there is no lock protecting exclusive access to the channel.
-// As the kernel uses a polling policy on the DMA_STATUS register to detect
-// transfer completion, the DMA IRQ is not used.
-//
-// The virtual base address of the segment associated to a channel is:
-//    SEG_DMA_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + DMA_SPAN * channel_id
-//
-// The SEG_DMA_BASE virtual address mus be defined in the hard_config.h file.
-////////////////////////////////////////////////////////////////////////////////////
 
 #include <giet_config.h>
@@ -101,10 +81,5 @@
 }
 
-//////////////////////////////////////////////////////////////////////////////////
-// AS the GIET-VM uses a polling policy to detect transfer completion,
-// The DMA component initialisation must disable interrupts.
-// This function disables interrupts for one DMA channel in one cluster.
-// Returns 0 if success, returns > 0 if error.
-//////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////
 unsigned int _dma_init( unsigned int cluster_xy,
                         unsigned int channel_id )
@@ -127,8 +102,5 @@
 }
 
-//////////////////////////////////////////////////////////////////////////////////
-// This function re-initialises one DMA channel in one cluster after a transfer
-// completion. It actually forces the channel to return in iDLE state.
-//////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////
 unsigned int _dma_reset( unsigned int cluster_xy, 
                          unsigned int channel_id ) 
@@ -151,7 +123,5 @@
 }
 
-//////////////////////////////////////////////////////////////////////////////////
-// This function returns the status of a DMA channel in a given cluster
-//////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
 unsigned int _dma_get_status( unsigned int cluster_xy, 
                               unsigned int channel_id ) 
@@ -173,9 +143,5 @@
 }
 
-//////////////////////////////////////////////////////////////////////////////////
-// This function sets the physical address (including 64 bits extension)
-// for the source and destination buffers in a DMA channel in a given cluster
-// and sets the transfer size to lauch the transfer.
-//////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////
 void _dma_start_transfer( unsigned int       cluster_xy,  // DMA cluster
                           unsigned int       channel_id,  // DMA channel
@@ -201,15 +167,5 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////////
-// This function copies a source memory buffer to a destination memory buffer,
-// using directly physical addresses.
-// This blocking function is supposed to be used by the kernel only, 
-// and uses a polling policy on DMA_STATUS register to detect completion.
-// Therefore, the DMA_IRQ is NOT used.
-// The source and destination buffers base addresses must be word aligned, 
-// and the buffer's size must be multiple of 4.
-// In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error 
-// message is displayed on TTY0, and the system crash.
-///////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////
 void _dma_physical_copy( unsigned int       cluster_xy,  // DMA cluster
                          unsigned int       channel_id,  // DMA channel
@@ -225,5 +181,5 @@
     if ( (x >= X_SIZE) || (y >= Y_SIZE) || (channel_id >= NB_DMA_CHANNELS) )
     {
-        _printf("\n[GIET ERROR] in _dma_physical_copy() : illegal DMA channel ");
+        _puts("\n[DMA ERROR] in _dma_physical_copy() : illegal DMA channel ");
         _exit();
     }
@@ -232,14 +188,24 @@
     if ( (dst_paddr & 0x3)   || (src_paddr & 0x3) || (size & 0x3) )
     {
-        _printf("\n[GIET ERROR] in _dma_physical_copy() : buffer unaligned\n");
-        _exit();
-    }
-
-#if GIET_DEBUG_DMA_DRIVER
-_printf("\n[DMA DEBUG] Start a dma_physical_copy on channel[%d,%d,%d] at cycle %d\n"
-        " - src_paddr   = %l\n"
-        " - dst_paddr   = %l\n"
-        " - bytes       = %x\n",
-        x, y, channel_id, _get_proctime(), src_paddr, dst_paddr, size );
+        _puts("\n[DMA ERROR] in _dma_physical_copy() : buffer unaligned\n");
+        _exit();
+    }
+
+#if GIET_DEBUG_DMA_DRIVER
+_puts("\n[DMA DEBUG] enter _dma_physical_copy() for channel[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts(",");
+_putd( channel_id );
+_puts("] at cycle ");
+_putd( _get_proctime() );
+_puts("\n - src_paddr   = ");
+_putl( src_paddr );
+_puts("\n - dst_paddr   = ");
+_putl( dst_paddr );
+_puts("\n - bytes       = ");
+_putd( size );
+_puts("\n");
 #endif
 
@@ -256,5 +222,5 @@
 
 #if GIET_DEBUG_DMA_DRIVER
-_printf("\n[DMA DEBUG] _dma_physical_copy() : ... waiting on DMA_STATUS register\n");
+_puts("\n[DMA DEBUG] _dma_physical_copy() : ... waiting on DMA_STATUS register\n");
 #endif
 
@@ -264,32 +230,27 @@
     if( status != DMA_SUCCESS )
     {
-        _printf("\n[GIET ERROR] in _dma_physical_copy() : DMA_STATUS = %x\n", status );
-        _exit();
-    }
+        _puts("\n[DMA ERROR] in _dma_physical_copy() : bad DMA_STATUS");
+        _exit();
+    }
+
     // reset dma channel
     _dma_reset( cluster_xy, channel_id );
 
 #if GIET_DEBUG_DMA_DRIVER
-_printf("\n[DMA DEBUG] _dma_physical_copy() completed at cycle %d\n", _get_proctime() );
+_puts("\n[DMA DEBUG] exit _dma_physical_copy() at cycle ");
+_putd( _get_proctime() );
+_puts("\n");
 #endif
 
 #else // NB_DMA_CHANNELS == 0
-    _printf("\n[GIET ERROR] in _dma_physical_copy() : NB_DMA_CHANNELS == 0 / cycle %d\n",
-            _get_proctime );
+
+    _puts("\n[DMA ERROR] in _dma_physical_copy() : NB_DMA_CHANNELS == 0\n");
     _exit();
-#endif
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-// This function copies a source memory buffer to a destination memory buffer,
-// making virtual to physical address translation: the MMU should be activated. 
-// This blocking function is supposed to be used by the kernel only, 
-// and uses a polling policy on DMA_STATUS register to detect completion.
-// Therefore, the DMA_IRQ is NOT used.
-// The source and destination buffers base addresses must be word aligned, 
-// and the buffer's size must be multiple of 4.
-// In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error 
-// message is displayed on TTY0, and the system crash.
-///////////////////////////////////////////////////////////////////////////////////
+
+#endif
+}
+
+
+////////////////////////////////////////
 void  _dma_copy( unsigned int cluster_xy,    // DMA cluster
                  unsigned int channel_id,    // DMA channel
@@ -306,5 +267,5 @@
     if ( (x >= X_SIZE) || (y >= Y_SIZE) || (channel_id >= NB_DMA_CHANNELS) )
     {
-        _printf("\n[GIET ERROR] in _dma_copy() : illegal DMA channel ");
+        _puts("\n[DMA ERROR] in _dma_copy() : illegal DMA channel ");
         _exit();
     }
@@ -313,5 +274,5 @@
     if ( (dst_vaddr & 0x3)   || (src_vaddr & 0x3) || (size & 0x3) )
     {
-        _printf("\n[GIET ERROR] in _dma_copy() : buffer unaligned\n");
+        _puts("\n[DMA ERROR] in _dma_copy() : buffer unaligned\n");
         _exit();
     }
@@ -322,9 +283,19 @@
 
 #if GIET_DEBUG_DMA_DRIVER
-_printf("\n[DMA DEBUG] Start a dma_copy on channel[%d,%d,%d] at cycle %d\n"
-        " - src_vaddr   = %x\n"
-        " - dst_vaddr   = %x\n"
-        " - bytes       = %x\n",
-        x, y, channel_id, _get_proctime(), src_vaddr, dst_vaddr, size );
+_puts("\n[DMA DEBUG] enter _dma_copy() for channel[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts(",");
+_putd( channel_id );
+_puts("] at cycle ");
+_putd( _get_proctime() );
+_puts("\n - src_vaddr   = ");
+_putx( src_vaddr );
+_puts("\n - dst_vaddr   = ");
+_putx( dst_vaddr );
+_puts("\n - bytes       = ");
+_putd( size );
+_puts("\n");
 #endif
 
@@ -334,5 +305,5 @@
          (size & 0x3) )
     {
-        _printf("\n[GIET ERROR] in _dma_copy() : buffer unaligned\n");
+        _puts("\n[DMA ERROR] in _dma_copy() : buffer unaligned\n");
         _exit();
     }
@@ -348,5 +319,5 @@
     if ( ko ) 
     {
-        _printf("\n[GIET ERROR] in _dma_copy() : source buffer unmapped\n");
+        _puts("\n[DMA ERROR] in _dma_copy() : source buffer unmapped\n");
         _exit();
     }
@@ -361,5 +332,5 @@
     if ( ko ) 
     {
-        _printf("\n[GIET ERROR] in _dma_copy() : dest buffer unmapped\n");
+        _puts("\n[DMA ERROR] in _dma_copy() : dest buffer unmapped\n");
         _exit();
     }
@@ -368,7 +339,9 @@
 
 #if GIET_DEBUG_DMA_DRIVER
-_printf(" - src_paddr   = %l\n"
-        " - dst_paddr   = %l\n",
-        src_paddr, dst_paddr );
+_puts("\n - src_paddr   = ");
+_putl( src_paddr );
+_puts("\n - dst_paddr   = ");
+_putl( dst_paddr );
+_puts("\n");
 #endif
 
@@ -385,5 +358,5 @@
 
 #if GIET_DEBUG_DMA_DRIVER
-_printf("\n[DMA DEBUG] _dma_copy() : ... waiting on DMA_STATUS register\n");
+_puts("\n[DMA DEBUG] _dma_copy() : ... waiting on DMA_STATUS register\n");
 #endif
 
@@ -393,5 +366,5 @@
     if( status != DMA_SUCCESS )
     {
-        _printf("\n[GIET ERROR] in _dma_copy() : DMA_STATUS = %x\n", status );
+        _puts("\n[DMA ERROR] in _dma_copy() : bad DMA_STATUS\n");
         _exit();
     }
@@ -400,23 +373,23 @@
 
 #if GIET_DEBUG_DMA_DRIVER
-_printf("\n[DMA DEBUG] _dma_copy() completed at cycle %d\n", _get_proctime() );
+_puts("\n[DMA DEBUG] exit _dma_copy() at cycle ");
+_putd( _get_proctime() );
+_puts("\n");
 #endif
 
 #else // NB_DMA_CHANNELS == 0
-    _printf("\n[GIET ERROR] in _dma_copy() : NB_DMA_CHANNELS == 0 / cycle %d\n",
-            _get_proctime );
+
+    _puts("\n[DMA ERROR] in _dma_copy() : NB_DMA_CHANNELS == 0\n");
     _exit();
+
 #endif
 } // end _dma_copy
 
-///////////////////////////////////////////////////////////////////////////////
-// This ISR handles the IRQ generated by a DMA channel.
-///////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////
 void _dma_isr( unsigned int irq_type,
                unsigned int irq_id,
                unsigned int channel )
 {
-    _printf("\n[GIET ERROR] _dma_isr() not implemented / cycle %d\n",
-            _get_proctime() );
+    _puts("\n[DMA ERROR] _dma_isr() not implemented\n");
     _exit();
 }
Index: soft/giet_vm/giet_drivers/dma_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/dma_driver.h	(revision 436)
+++ soft/giet_vm/giet_drivers/dma_driver.h	(revision 437)
@@ -5,4 +5,24 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
+// The dma_driver.c and dma_driver.h files are part ot the GIET-VM nano-kernel.
+// This driver supports the SoCLib vci_multi_dma component.
+// 
+// It can exist several DMA controlers in the architecture (one per cluster),
+// and each controller can contain several channels.
+// 
+// There is  (NB_CLUSTERS * NB_DMA_CHANNELS) channels, indexed by a global index:
+//        dma_id = cluster_xy * NB_DMA_CHANNELS + loc_id
+//
+// A DMA channel is a private ressource allocated to a given processor.
+// It is exclusively used by the kernet to speedup data transfers, and
+// there is no lock protecting exclusive access to the channel.
+// As the kernel uses a polling policy on the DMA_STATUS register to detect
+// transfer completion, the DMA IRQ is not used.
+//
+// The virtual base address of the segment associated to a channel is:
+//    SEG_DMA_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + DMA_SPAN * channel_id
+//
+// The SEG_DMA_BASE virtual address mus be defined in the hard_config.h file.
+////////////////////////////////////////////////////////////////////////////////////
 
 #ifndef _GIET_DMA_DRIVER_H_
@@ -37,18 +57,35 @@
 
 
-///////////////////////////////////////////////////////////////////////////////////
-// Multi DMA variables and access functions  (vci_multi_dma)
-///////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+//                  low-level access functions  
+///////////////////////////////////////////////////////////////////////////////
 
-// low level access functions
+//////////////////////////////////////////////////////////////////////////////////
+// This function disables interrupts for one DMA channel in one cluster.
+// AS the GIET-VM uses a polling policy to detect DMA transfer completion,
+// the DMA component initialisation must disable interrupts.
+// Returns 0 if success, returns > 0 if error.
+//////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _dma_init( unsigned int cluster_xy,
                                unsigned int channel_id );
 
+//////////////////////////////////////////////////////////////////////////////////
+// This function re-initialises one DMA channel in one cluster after transfer
+// completion. It actually forces the channel to return in IDLE state.
+//////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _dma_reset( unsigned int  cluster_xy, 
                                 unsigned int  channel_id );
 
+//////////////////////////////////////////////////////////////////////////////////
+// This function returns the status of a DMA channel in a given cluster
+//////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _dma_get_status( unsigned int  cluster_xy, 
                                      unsigned int  channel_id );
 
+//////////////////////////////////////////////////////////////////////////////////
+// This function sets the physical address (including 64 bits extension)
+// for the source and destination buffers in a DMA channel in a given cluster
+// and sets the transfer size to lauch the transfer.
+//////////////////////////////////////////////////////////////////////////////////
 extern void _dma_start_transfer( unsigned int       cluster_xy,
                                  unsigned int       channel_id,
@@ -57,5 +94,19 @@
                                  unsigned int       size );
 
-// higher level access function
+//////////////////////////////////////////////////////////////////////////////////
+//                     higher level access function
+//////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// This function copies a source memory buffer to a destination memory buffer,
+// using directly physical addresses.
+// This blocking function is supposed to be used by the kernel only, 
+// and uses a polling policy on DMA_STATUS register to detect completion.
+// Therefore, the DMA_IRQ is NOT used.
+// The source and destination buffers base addresses must be word aligned, 
+// and the buffer's size must be multiple of 4.
+// In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error 
+// message is displayed on TTY0, and system crash.
+///////////////////////////////////////////////////////////////////////////////////
 extern void _dma_physical_copy( unsigned int       cluster_xy,
                                 unsigned int       channel_id,
@@ -64,4 +115,15 @@
                                 unsigned int       size ); 
 
+///////////////////////////////////////////////////////////////////////////////////
+// This function copies a source memory buffer to a destination memory buffer,
+// making virtual to physical address translation: the MMU should be activated. 
+// This blocking function is supposed to be used by the kernel only, 
+// and uses a polling policy on DMA_STATUS register to detect completion.
+// Therefore, the DMA_IRQ is NOT used.
+// The source and destination buffers base addresses must be word aligned, 
+// and the buffer's size must be multiple of 4.
+// In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error 
+// message is displayed on TTY0, and system crash.
+///////////////////////////////////////////////////////////////////////////////////
 extern void _dma_copy(  unsigned int cluster_xy,
                         unsigned int channel_id,
@@ -71,9 +133,12 @@
                         unsigned int size ); 
 
+///////////////////////////////////////////////////////////////////////////////
+// This ISR should not be used by the GIET_VM, because the DMA is only
+// used by the kernel in the boot phase, with a polling strategy.
+///////////////////////////////////////////////////////////////////////////////
 extern void _dma_isr( unsigned int irq_type,
                       unsigned int irq_id,
                       unsigned int channel );
 
-///////////////////////////////////////////////////////////////////////////////////
 
 #endif
Index: soft/giet_vm/giet_drivers/fbf_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/fbf_driver.c	(revision 436)
+++ 	(revision )
@@ -1,413 +1,0 @@
-///////////////////////////////////////////////////////////////////////////////////
-// File     : fbf_driver.c
-// Date     : 23/05/2013
-// Author   : alain greiner
-// Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
-// The fbf_driver.c and fbf_driver.h files are part ot the GIET-VM kernel.
-// This driver supports the SoCLib vci_framebuffer component.
-//
-// There exist two methods to access the VciFrameBuffer device:
-//  
-// 1) The _fb_sync_write() and _fb_sync_read() functions use a memcpy strategy 
-// to implement the transfer between a data buffer (user space) and the frame
-// buffer (kernel space). They are blocking until completion of the transfer.
-//
-// 2) The _fb_cma_init(), _fb_cma_write() and _fb_cma_stop() functions use
-// the VciChbufDma component (non replicated) to transfer a flow of images from
-// an user space chained buffer (two buffers) to the frame buffer.
-// A CMA channel must be allocated to the task requesting it in the mapping_info,
-// and stored in the task context.
-//
-// The SEG_FBF_BASE virtual address must be defined in hard_config.h file.
-///////////////////////////////////////////////////////////////////////////////////
-
-#include <giet_config.h>
-#include <hard_config.h>
-#include <fbf_driver.h>
-#include <utils.h>
-#include <dma_driver.h>
-#include <cma_driver.h>
-#include <tty_driver.h>
-#include <ctx_handler.h>
-#include <mmc_driver.h>
-#include <vmem.h>
-
-#if !defined(SEG_FBF_BASE) 
-# error: You must define SEG_FBF_BASE in the hard_config.h file
-#endif
-
-#if !defined(GIET_USE_IOMMU) 
-# error: You must define GIET_USE_IOMMU in the giet_config.h file
-#endif
-
-#if !defined( USE_IOB )
-# error: You must define USE_IOB in the hard_config.h file
-#endif
-
-#define in_unckdata __attribute__((section (".unckdata")))
-
-////////////// memcpy approach //////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////////////////
-// _fb_sync_write()
-// Transfer data from an memory buffer to the frame_buffer device using a memcpy. 
-// - offset : offset (in bytes) in the frame buffer.
-// - buffer : base address of the memory buffer.
-// - length : number of bytes to be transfered.
-//////////////////////////////////////////////////////////////////////////////////
-
-unsigned int _fb_sync_write(unsigned int offset, 
-                            const void * buffer, 
-                            unsigned int length) 
-{
-    char* fbf_address = (char *)SEG_FBF_BASE + offset;
-
-    memcpy( fbf_address, buffer, length);
-
-    return 0;
-}
-//////////////////////////////////////////////////////////////////////////////////
-// _fb_sync_read()
-// Transfer data from the frame_buffer device to a memory buffer using a memcpy.
-// - offset : offset (in bytes) in the frame buffer.
-// - buffer : base address of the memory buffer.
-// - length : number of bytes to be transfered.
-//////////////////////////////////////////////////////////////////////////////////
-unsigned int _fb_sync_read( unsigned int   offset, 
-                            void*          buffer, 
-                            unsigned int   length) 
-{
-    char* fbf_address = (char *)SEG_FBF_BASE + offset;
-
-    memcpy( buffer, fbf_address, length);
-
-    return 0;
-}
-
-
-///////////////// CDMA approach //////////////////////////////////////////////////
-
-// This structure contains two chbuf descriptors that can be used by 
-// the VciChbufDma component to tranfer a flow of images:
-// - The SRC chbuf descriptor contain two slots (two user buffers)
-// - The DST chbuf descriptor contains only one slot (frame buffer)
-
-typedef struct fb_cma_channel_s
-{
-    paddr_t       buf0;     // physical address + status for user buffer 0 
-    paddr_t       buf1;     // physical address + status for user buffer 1
-    paddr_t       fbf;      // physical address + status for frame buffer
-    unsigned int  length;   // buffer length (number of bytes)
-    unsigned int  padding;  // unused (just to have channel size = 32 bytes)
-} fb_cma_channel_t;
-
-// array of FB_CMA channels descriptors (32 bytes per entry)
-// each entry contains one SRC and one DST chbuf descriptors.
-in_unckdata volatile fb_cma_channel_t 
-_fb_cma_channel[NB_CMA_CHANNELS] __attribute__((aligned(64)));
-
-// array of physical addresses for the FB_CMA channels descriptors
-in_unckdata volatile paddr_t          
-_fb_cma_desc_paddr[NB_CMA_CHANNELS];
-
-//////////////////////////////////////////////////////////////////////////////////////
-// _fb_cma_init()
-// This function uses the _fb_cma_channel[] and _fb_cma_desc_paddr[] arrays,
-// (that are both indexed by the channel index), and does four things:
-//
-// 1) computes the physical addresses for the two source user buffers, for 
-//    the destination frame buffer. It initialises the channel descriptor 
-//    _fb_cma_channel[i], containing the SRC chbuf descriptor (two buffers), 
-//    the DST chbuf descriptor (one single buffer), and the buffer length. 
-// 
-// 2) computes the physical address for the channel descriptor and register it
-//    in the _fb_cma_desc_paddr[i]. 
-//    
-// 3) makes a SYNC request to L2 cache for channel descriptor, because the
-//    channel descriptor is directly accessed in XRAM by the CMA component.
-//
-// 4) Starts the CMA hardware channel, that will poll the channel descriptor
-//    to fransfer an user buffer to the frame buffer as soon as the source 
-//    user buffer is marked valid.
-//
-// Returns 0 if success, > 0 if error 
-//////////////////////////////////////////////////////////////////////////////////////
-unsigned int _fb_cma_init( const void*  vbase0,  // first user buffer vbase address
-                           const void*  vbase1,  // second user buffer vbase address
-                           unsigned int length ) // buffer length (number of bytes)
-{
-#if NB_CMA_CHANNELS > 0
-
-    unsigned int  channel_id;          // CMA channel index
-    unsigned int  user_ptab;           // page table virtual address
-    unsigned int  ko;                  // unsuccessfull V2P translation
-    unsigned int  vaddr;               // virtual address
-    unsigned int  flags;               // protection flags
-    unsigned int  ppn;                 // physical page number
-    paddr_t       desc_paddr;          // physical address of channel descriptor
-
-    // get CMA channel index
-    channel_id = _get_context_slot(CTX_CMA_ID);
-    if ( channel_id >= NB_CMA_CHANNELS )
-    {
-        _printf("\n[GIET ERROR] in _fb_cma_init() : CMA channel index too large\n");
-        return 1;
-    }
-
-    // checking size for channel descriptor
-    if ( sizeof(fb_cma_channel_t) != 32 )
-    {
-        _printf("\n[GIET ERROR] in _fb_cma_init() : bad fb_cma_channel size\n");
-        return 1;
-    }
-
-    // checking channel descriptor alignment (32 bytes)
-    if ( (unsigned int)(&_fb_cma_channel[channel_id]) & 0x1F ) 
-    {
-        _printf("\n[GIET ERROR] in _fb_cma_init() : bad fb_cma_channel alignment\n");
-        return 1;
-    }
-
-    // checking user buffer virtual addresses and length alignment
-    if ( ((unsigned int)vbase0 & 0x3) || ((unsigned int)vbase1 & 0x3) || (length & 0x3) ) 
-    {
-        _printf("\n[GIET ERROR] in _fb_cma_init() : user buffer not word aligned\n");
-        return 1;
-    }
-
-    // get page table virtual address
-    user_ptab = _get_context_slot(CTX_PTAB_ID);
-
-    // compute and register frame buffer physical address
-    vaddr = ((unsigned int)SEG_FBF_BASE);
-    ko    = _v2p_translate( (page_table_t*) user_ptab, 
-                         (vaddr >> 12),
-                         &ppn, 
-                         &flags );
-    if (ko) 
-    {
-        _printf("\n[GIET ERROR] in _fb_cma_init() : frame buffer unmapped\n");
-        return 1;
-    }
-    _fb_cma_channel[channel_id].fbf = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
-
-    // Compute and register first user buffer physical address
-    vaddr = (unsigned int)vbase0; 
-    ko = _v2p_translate( (page_table_t*) user_ptab, 
-                         (vaddr >> 12),
-                         &ppn, 
-                         &flags );
-    if (ko) 
-    {
-        _printf("\n[GIET ERROR] in _fb_cma_init() : user buffer 0 unmapped\n");
-        return 1;
-    } 
-    if ((flags & PTE_U) == 0) 
-    {
-        _printf("[GIET ERROR] in _fb_cma_init() : user buffer 0 not in user space\n");
-        return 1; 
-    }
-    _fb_cma_channel[channel_id].buf0 = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
-
-    // Compute and register second user buffer physical address
-    vaddr = (unsigned int)vbase1; 
-    ko = _v2p_translate( (page_table_t*) user_ptab, 
-                         (vaddr >> 12),
-                         &ppn, 
-                         &flags );
-    if (ko) 
-    {
-        _printf("\n[GIET ERROR] in _fb_cma_init() : user buffer 1 unmapped\n");
-        return 1;
-    } 
-    if ((flags & PTE_U) == 0) 
-    {
-        _printf("[GIET ERROR] in _fb_cma_init() : user buffer 1 not in user space\n");
-        return 1; 
-    }
-    _fb_cma_channel[channel_id].buf1 = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
-
-    // register buffer length in channel descriptor
-    _fb_cma_channel[channel_id].length = length;
-
-    // Compute and register physical adress of the channel descriptor
-    vaddr = (unsigned int)(&_fb_cma_channel[channel_id]);
-    ko = _v2p_translate( (page_table_t*) user_ptab, 
-                         (vaddr >> 12),
-                         &ppn, 
-                         &flags );
-    if (ko) 
-    {
-        _printf("\n[GIET ERROR] in _fb_cma_init() : channel descriptor unmapped\n");
-        return 1;
-    } 
-    _fb_cma_desc_paddr[channel_id] = (((paddr_t)ppn) << 12) | (vaddr & 0x00000FFF);
-
-    desc_paddr                     = (((paddr_t)ppn) << 12) | (vaddr & 0x00000FFF);
-    
-
-#if GIET_DEBUG_FBF_DRIVER
-_printf("\n[CMA DEBUG] enters _fb_cma_init()\n"
-        " - fbf       pbase = %l\n"
-        " - buf0      pbase = %l\n"
-        " - buf1      pbase = %l\n"
-        " - channel   pbase = %l\n"
-        _fb_cma_channel[channel_id].fbf,
-        _fb_cma_channel[channel_id].buf0,
-        _fb_cma_channel[channel_id].buf1,
-        _fb_cma_desc_paddr[channel_id] );
-#endif
-
-    if ( USE_IOB )
-    {
-        // SYNC request for channel descriptor
-        _mmc_sync( desc_paddr, 32 );
-    }
-
-    // CMA channel activation
-    _cma_set_register( channel_id, CHBUF_SRC_DESC , (unsigned int)(desc_paddr & 0xFFFFFFFF) );
-    _cma_set_register( channel_id, CHBUF_SRC_EXT  , (unsigned int)(desc_paddr >> 32) );
-    _cma_set_register( channel_id, CHBUF_SRC_NBUFS, 2 );
-    _cma_set_register( channel_id, CHBUF_DST_DESC , (unsigned int)(desc_paddr & 0xFFFFFFFF) + 16 );
-    _cma_set_register( channel_id, CHBUF_DST_EXT  , (unsigned int)(desc_paddr >> 32) );
-    _cma_set_register( channel_id, CHBUF_DST_NBUFS, 1 );
-    _cma_set_register( channel_id, CHBUF_BUF_SIZE , length );
-    _cma_set_register( channel_id, CHBUF_PERIOD   , 300 );
-    _cma_set_register( channel_id, CHBUF_RUN      , 1 );
-    return 0;
-
-#else
-    _printf("\n[GIET ERROR] in _fb_cma_init() : no CMA channel allocated\n");
-    return 1;
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////
-// _fb_cma_write()
-//
-// It updates the status of the SRC and DST chbuf descriptors, to allow the CMA
-// component to transfer the source user buffer to the frame buffer.
-//
-// If the IO Bridge component is used:
-// 1) it makes an INVAL request for the channel descriptor, before testing the
-//    source buffer status, because it is modified in XRAM by the CMA component.
-// 2) it makes a SYNC request for the source user buffer before activating the CMA 
-//    transfer, because the data will be read from XRAM by the CMA component.
-// 3) it makes a SYNC request for the channel descriptor after modification 
-//    of the SRC and DST status, because these descriptors will be read from XRAM 
-//    by the CMA component.
-//
-// The buffer_id argument is the user buffer index (0 => buf0 / not 0 => buf1)
-// Returns 0 if success, > 0 if error 
-////////////////////////////////////////////////////////////////////////////////////
-unsigned int _fb_cma_write( unsigned int buffer_id )
-{
-#if NB_CMA_CHANNELS > 0
-
-    volatile paddr_t buf_paddr;
-    unsigned int     full = 1;
-
-    unsigned int     count = 0;
-
-    // get CMA channel index 
-    unsigned int channel_id = _get_context_slot(CTX_CMA_ID);
-
-#if GIET_DEBUG_FBF_DRIVER
-_printf("\n[CMA DEBUG] _fb_cma_write() for CMA channel %d / bufid = %d at cycle %d\n",
-        channel_id, buffer_id, _get_proctime() );
-#endif
-
-    // waiting buffer empty
-    while ( full )
-    {  
-        if ( USE_IOB )
-        {
-            // INVAL L2 cache for the channel descriptor,
-            _mmc_inval( _fb_cma_desc_paddr[channel_id], 32 );
-
-            // INVAL L1 cache for the channel descriptor,
-            _dcache_buf_invalidate( (unsigned int)&_fb_cma_channel[channel_id], 32 );
-        }
-
-        // read SRC buffer descriptor
-        if ( buffer_id == 0 ) buf_paddr = _fb_cma_channel[channel_id].buf0;
-        else                  buf_paddr = _fb_cma_channel[channel_id].buf1;
-        full = ( (unsigned int)(buf_paddr>>63) );
-
-        count++;
-        if ( count == 10 ) _exit();
-    }
-
-    if ( USE_IOB )
-    {
-        // SYNC request for the user buffer because 
-        // this buffer will be read from XRAM by the CMA component
-        _mmc_sync( buf_paddr, _fb_cma_channel[channel_id].length );
-    }
-
-    // set SRC full 
-    if ( buffer_id == 0 )
-    _fb_cma_channel[channel_id].buf0 = buf_paddr | 0x8000000000000000ULL;
-    else
-    _fb_cma_channel[channel_id].buf1 = buf_paddr | 0x8000000000000000ULL;
-
-    // set DST empty
-    _fb_cma_channel[channel_id].fbf  = _fb_cma_channel[channel_id].fbf
-                                       & 0x7FFFFFFFFFFFFFFFULL;
-
-    if ( USE_IOB )
-    {
-        // SYNC request for the channel descriptor, because
-        // it will be read in XRAM by the CMA component
-        _mmc_sync( _fb_cma_desc_paddr[channel_id], 32 );
-    }
-
-    return 0;
-
-#else
-
-    _printf("\n[GIET ERROR] in _fb_cma_channel() : no CMA channel allocated\n");
-    return 1;
-
-#endif
-}
-//////////////////////////////////////////////////////////////////////////////////
-// _fb_cma_stop()
-// This function desactivates the CMA channel allocated to the calling task.
-// Returns 0 if success, > 0 if error 
-//////////////////////////////////////////////////////////////////////////////////
-unsigned int _fb_cma_stop( unsigned int buffer_id )
-{
-#if NB_CMA_CHANNELS > 0
-
-    // get CMA channel allocated 
-    unsigned int channel_id = _get_context_slot(CTX_CMA_ID);
-
-#if GIET_DEBUG_FBF_DRIVER
-_printf("\n[CMA DEBUG] _fb_cma_stop() for CMA channel %d at cycle %d\n",
-        channel_id, _get_proctime() );
-#endif
-
-    // CMA channel desactivation
-    _cma_set_register( channel_id, CHBUF_RUN, 0 );
-
-    return 0;
-
-#else
-
-    _printf("\n[GIET ERROR] in _fb_cma_stop() : no CMA channel allocated\n");
-    return 1;
-
-#endif
-}
-    
-
-// Local Variables:
-// tab-width: 4
-// c-basic-offset: 4
-// c-file-offsets:((innamespace . 0)(inline-open . 0))
-// indent-tabs-mode: nil
-// End:
-// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
-
Index: soft/giet_vm/giet_drivers/fbf_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/fbf_driver.h	(revision 436)
+++ 	(revision )
@@ -1,43 +1,0 @@
-///////////////////////////////////////////////////////////////////////////////////
-// File     : fbf_driver.h
-// Date     : 01/11/2013
-// Author   : alain greiner
-// Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
-
-#ifndef _GIET_FBF_DRIVERS_H_
-#define _GIET_FBF_DRIVERS_H_
-
-///////////////////////////////////////////////////////////////////////////////////
-// Frame Buffer access functions  (vci_frame_buffer)
-///////////////////////////////////////////////////////////////////////////////////
-
-extern unsigned int _fb_sync_write( unsigned int offset, 
-                                    const void * buffer, 
-                                    unsigned int length );
-
-extern unsigned int _fb_sync_read(  unsigned int offset, 
-                                    void *       buffer, 
-                                    unsigned int length );
-
-extern unsigned int _fb_cma_init( const void*  vbase0,
-                                  const void*  vbase1,
-                                  unsigned int length );
-
-extern unsigned int _fb_cma_write( unsigned int buffer_id );
-
-extern unsigned int _fb_cma_stop();
-
-///////////////////////////////////////////////////////////////////////////////////
-
-
-#endif
-
-// Local Variables:
-// tab-width: 4
-// c-basic-offset: 4
-// c-file-offsets:((innamespace . 0)(inline-open . 0))
-// indent-tabs-mode: nil
-// End:
-// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
-
Index: soft/giet_vm/giet_drivers/hba_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/hba_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/hba_driver.c	(revision 437)
@@ -5,15 +5,7 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The hba_driver.c and hba_driver.h files are part ot the GIET-VM kernel.
-// This driver supports the SocLib VciMultiAhci component, that is a multi-channels,
-// block oriented, external storage contrÃŽler, respecting the AHCI standard.
-//
-// The SEG_IOC_BASE virtual address must be defined in the hard_config.h file.
-//////////////////////////////////////////////////////////////////////////////////
 // Implementation notes:
-//
 // 1. In order to share code, the two _hba_read() and _hba_write() functions
 //    call the same _hba_set_cmd() function.
-//
 // 2. All accesses to HBA registers are done by the two
 //    _hba_set_register() and _hba_get_register() low-level functions,
@@ -42,5 +34,5 @@
 
 //////////////////////////////////////////////////////////////////
-//  Global variables
+//               Global variables
 //////////////////////////////////////////////////////////////////
 
@@ -89,5 +81,5 @@
 // buffer must be an integer number of blocks entirely contained in a single
 // page frame. 
-// return 0 if success, > 0 if error
+// return 0 if success, -1 if error
 ///////////////////////////////////////////////////////////////////////////////
 unsigned int _hba_cmd_set( unsigned int  channel,     // channel index
@@ -109,6 +101,6 @@
     if( buffer & (block_size-1) )
     {
-        _printf("\n[GIET ERROR] in _hba_set_cmd() : user buffer not block aligned\n");
-        return 1;
+        _puts("\n[GIET ERROR] in _hba_set_cmd() : user buffer not block aligned\n");
+        return -1;
     }
 
@@ -120,7 +112,8 @@
     if( pxci & (1<<cmd_id ) ) 
     {
-        _printf("\n[GIET ERROR] in _hba_set_cmd() : command list full for channel %d\n",
-                channel );
-        return 1;
+        _puts("\n[GIET ERROR] in _hba_set_cmd() : command list full for channel ");
+        _putd( channel );
+        _puts("\n");
+        return -1;
     }
 
@@ -188,16 +181,16 @@
         if ( ko )
         {
-            _printf("[GIET ERROR] in _hba_set_cmd() : user buffer unmapped\n");
-            return 1;
+            _puts("[GIET ERROR] in _hba_set_cmd() : user buffer unmapped\n");
+            return -1;
         }
         if ((flags & PTE_U) == 0)
         {
-            _printf("[GIET ERROR] in _hba_set_cmd() : user buffer not in user space\n");
-            return 1;
+            _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not in user space\n");
+            return -1;
         }
         if (((flags & PTE_W) == 0 ) && (is_read == 0) )
         {
-            _printf("[GIET ERROR] in _hba_set_cmd() : user buffer not writable\n");
-            return 1;
+            _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not writable\n");
+            return -1;
         }
 
@@ -205,6 +198,6 @@
         if( buf_id > 245 )
         {
-            _printf("[GIET ERROR] in _hba_set_cmd() : max number of buffers is 248\n");
-            return 1;
+            _puts("[GIET ERROR] in _hba_set_cmd() : max number of buffers is 248\n");
+            return -1;   
         }
 
@@ -218,13 +211,4 @@
             cmd_table->entry[buf_id].dbc  = count;
 
-#if GIET_DEBUG_HBA_DRIVER
-_printf("\n- buf_index = ");
-_putd( buf_id );
-_printf(" / paddr = ");
-_putl( paddr );
-_printf(" / count = ");
-_putd( count );
-_printf("\n");
-#endif
             buf_id++;
         }
@@ -237,13 +221,4 @@
             cmd_table->entry[buf_id].dbc  = count;
 
-#if GIET_DEBUG_HBA_DRIVER
-_printf("\n- buf_index = ");
-_putd( buf_id );
-_printf(" / paddr = ");
-_putl( paddr );
-_printf(" / count = ");
-_putd( count );
-_printf("\n");
-#endif
             buf_id++;
         }
@@ -257,13 +232,4 @@
             cmd_table->entry[buf_id].dbc  = count;
 
-#if GIET_DEBUG_HBA_DRIVER
-_printf("\n- buf_index = ");
-_putd( buf_id );
-_printf(" / paddr = ");
-_putl( paddr );
-_printf(" / count = ");
-_putd( count );
-_printf("\n");
-#endif
             buf_id++;
 
@@ -274,13 +240,4 @@
             cmd_table->entry[buf_id].dbc  = count;
 
-#if GIET_DEBUG_HBA_DRIVER
-_printf("\n- buf_index = ");
-_putd( buf_id );
-_printf(" / paddr = ");
-_putl( paddr );
-_printf(" / count = ");
-_putd( count );
-_printf("\n");
-#endif
             buf_id++;
         }
@@ -293,13 +250,4 @@
             cmd_table->entry[buf_id].dbc  = count;
 
-#if GIET_DEBUG_HBA_DRIVER
-_printf("\n- buf_index = ");
-_putd( buf_id );
-_printf(" / paddr = ");
-_putl( paddr );
-_printf(" / count = ");
-_putd( count );
-_printf("\n");
-#endif
             buf_id++;
         }
@@ -308,47 +256,5 @@
 
 
-///////////////////////////////////////////////////////////////////
-// Register a write command in Command List and Command Table
-// for a single physical buffer.
-// Returns 0 if success, > 0 if error.
-///////////////////////////////////////////////////////////////////
-unsigned int _hba_write( unsigned int  channel,
-                         unsigned int  mode,
-                         unsigned int  lba,
-                         paddr_t       buffer, 
-                         unsigned int  count )
-{
-    return _hba_cmd_set( channel, 
-                         0,         // write 
-                         lba, 
-                         buffer, 
-                         count );
-}
-
-///////////////////////////////////////////////////////////////////
-// Register a read command in Command List and Command Table
-// for a single physical buffer.
-// Returns 0 if success, > 0 if error.
-///////////////////////////////////////////////////////////////////
-unsigned int _hba_read( unsigned int  channel,
-                        unsigned int  mode,
-                        unsigned int  lba, 
-                        paddr_t       buffer, 
-                        unsigned int  count )
-{
-    return _hba_cmd_set( channel,
-                         1,          // read
-                         lba, 
-                         buffer, 
-                         count );
-}
-
-//////////////////////////////////////////////////////////////////
-// This function initializes for a given channel
-// - the HBA hardware registers,
-// - the command list pointer,
-// - the command lists physical addresse,
-// - the command tables physical addresses array,
-//////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////
 unsigned int _hba_init( unsigned int channel )
 {
@@ -381,6 +287,6 @@
     if ( fail )
     {
-        _printf("[GIET ERROR] in _hba_init() : command list unmapped\n");
-        return 1;
+        _puts("[GIET ERROR] in _hba_init() : command list unmapped\n");
+        return -1;
     }
     hba_cmd_list_paddr[channel] = ((paddr_t)ppn) | (vbase & 0xFFF);
@@ -396,6 +302,6 @@
         if ( fail )
         {
-            _printf("[GIET ERROR] in _hba_init() : command table unmapped\n");
-            return 1;
+            _puts("[GIET ERROR] in _hba_init() : command table unmapped\n");
+            return -1;
         }
         hba_cmd_table_paddr[channel][c] = ((paddr_t)ppn) | (vbase & 0xFFF);
@@ -405,8 +311,33 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////
-//     _hba_get_block_size()
-// This function returns the block_size of HBA controller
-///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////
+unsigned int _hba_write( unsigned int  channel,
+                         unsigned int  mode,
+                         unsigned int  lba,
+                         paddr_t       buffer, 
+                         unsigned int  count )
+{
+    return _hba_cmd_set( channel, 
+                         0,         // write 
+                         lba, 
+                         buffer, 
+                         count );
+}
+
+//////////////////////////////////////////////
+unsigned int _hba_read( unsigned int  channel,
+                        unsigned int  mode,
+                        unsigned int  lba, 
+                        paddr_t       buffer, 
+                        unsigned int  count )
+{
+    return _hba_cmd_set( channel,
+                         1,          // read
+                         lba, 
+                         buffer, 
+                         count );
+}
+
+//////////////////////////////////
 unsigned int _hba_get_block_size()
 {
@@ -415,9 +346,5 @@
 }
 
-/////////////////////////////////////////////////////////////////////////////////////
-// This function returns the content of the HBA_PXIS register for a given channel, 
-// and reset this register to acknoledge IRQ.
-// return 0 if success, > 0 if error
-/////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////
 unsigned int _hba_get_status( unsigned int channel ) 
 {
@@ -425,5 +352,5 @@
     if( channel >= NB_IOC_CHANNELS )
     {
-        _printf("\n[GIET ERROR] in _hba_get_status() : illegal channel\n");
+        _puts("\n[GIET ERROR] in _hba_get_status() : illegal channel\n");
         _exit();
     }
Index: soft/giet_vm/giet_drivers/hba_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/hba_driver.h	(revision 436)
+++ soft/giet_vm/giet_drivers/hba_driver.h	(revision 437)
@@ -5,4 +5,10 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
+// The hba_driver.c and hba_driver.h files are part ot the GIET-VM kernel.
+// This driver supports the SocLib VciMultiAhci component, that is a multi-channels,
+// block oriented, external storage contrÃŽler, respecting the AHCI standard.
+//
+// The SEG_IOC_BASE virtual address must be defined in the hard_config.h file.
+//////////////////////////////////////////////////////////////////////////////////
 
 #ifndef _GIET_HBA_DRIVERS_H_
@@ -94,9 +100,21 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-// HBA device access functions  (vci_hba)
+//              access functions  
 ///////////////////////////////////////////////////////////////////////////////////
 
+///////////////////////////////////////////////////////////////////////////////////
+// This function initializes for a given channel
+// - the HBA hardware registers,
+// - the command list pointer,
+// - the command lists physical addresse,
+// - the command tables physical addresses array,
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _hba_init ( unsigned int channel ); 
 
+///////////////////////////////////////////////////////////////////////////////////
+// This function register a write command in Command List and Command Table
+// for a single physical buffer, and updates the HBA_PXCI register.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _hba_write( unsigned int channel,     // channel index
                                 unsigned int mode,        // BOOT / KERNEL / USER
@@ -105,4 +123,9 @@
                                 unsigned int count );     // number of blocs
 
+//////////////////////////////////////////////////////////////////////////////////
+// This function register a read command in Command List and Command Table
+// for a single physical buffer, and updates the HBA_PXCI register.
+// Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _hba_read ( unsigned int channel,     // channel index
                                 unsigned int mode,        // BOOT / KERNEL / USER
@@ -111,7 +134,15 @@
                                 unsigned int count );     // number of blocks
 
+/////////////////////////////////////////////////////////////////////////////////
+// This function returns the block_size of HBA controller
+/////////////////////////////////////////////////////////////////////////////////
+extern unsigned int _hba_get_block_size ();
+
+/////////////////////////////////////////////////////////////////////////////////////
+// This function returns the content of the HBA_PXIS register for a given channel, 
+// and reset this register to acknoledge IRQ.
+// return 0 if success, > 0 if error
+/////////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _hba_get_status( unsigned int   channel );
-
-extern unsigned int _hba_get_block_size ();
 
 
Index: soft/giet_vm/giet_drivers/icu_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/icu_driver.c	(revision 436)
+++ 	(revision )
@@ -1,124 +1,0 @@
-///////////////////////////////////////////////////////////////////////////////////
-// File     : icu_driver.c
-// Date     : 23/05/2013
-// Author   : alain greiner
-// Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
-// The icu_driver.c and icu_driver.h files are part ot the GIET-VM nano-kernel.
-// This driver supports the SoCLib vci_icu component, That is a vectorised
-// interrupt controler.
-//
-// It can exist several interrupt controller unit in the architecture 
-// (one per cluster), and each one can contain several channels.
-// The number of ICU channels is equal to NB_PROCS_MAX, because there is 
-// one private ICU channel per processor in a cluster.
-////////////////////////////////////////////////////////////////////////////////
-// The virtual base address of the segment associated to the component is:
-//      SEG_ICU_BASE + cluster_xy * PERI_CLUSTER_INCREMENT 
-//
-// SEG_ICU_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h 
-////////////////////////////////////////////////////////////////////////////////
-
-#include <giet_config.h>
-#include <icu_driver.h>
-#include <tty_driver.h>
-#include <utils.h>
-
-#if !defined(X_SIZE) 
-# error: You must define X_SIZE in the hard_config.h file
-#endif
-
-#if !defined(Y_SIZE) 
-# error: You must define X_SIZE in the hard_config.h file
-#endif
-
-#if !defined(X_WIDTH) 
-# error: You must define X_WIDTH in the hard_config.h file
-#endif
-
-#if !defined(Y_WIDTH) 
-# error: You must define X_WIDTH in the hard_config.h file
-#endif
-
-#if !defined(NB_PROCS_MAX) 
-# error: You must define NB_PROCS_MAX in the hard_config.h file
-#endif
-
-#if !defined( USE_XCU )
-# error: You must define USE_XCU in the hard_config.h file
-#endif
-
-#if !defined(SEG_ICU_BASE) 
-# error: You must define SEG_ICU_BASE in the hard_config.h file
-#endif
-
-#if !defined(PERI_CLUSTER_INCREMENT) 
-# error: You must define PERI_CLUSTER_INCREMENT in the hard_config.h file
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-//     _icu_set_mask()
-// This function set the mask register for the ICU channel identified 
-// by the cluster index and the processor index.
-// All '1' bits are set / all '0' bits are not modified.
-// Returns 0 if success, > 0 if error.
-////////////////////////////////////////////////////////////////////////////////
-unsigned int _icu_set_mask( unsigned int cluster_xy,
-                            unsigned int proc_id,
-                            unsigned int value )
-{
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if (x >= X_SIZE)             return 1; 
-    if (y >= Y_SIZE)             return 1; 
-    if (proc_id >= NB_PROCS_MAX) return 1; 
-
-#if USE_XCU
-    _printf("[GIET ERROR] _icu_set_mask() should not be used if USE_XICU is set\n");
-    return 1;
-#else
-    unsigned int * icu_address = (unsigned int *) ( SEG_ICU_BASE + 
-                                 (cluster_xy * PERI_CLUSTER_INCREMENT) );
-    icu_address[proc_id * ICU_SPAN + ICU_MASK_SET] = value; 
-    return 0;
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//     _icu_get_index()
-// This function returns the index of the highest priority (smaller index) IRQ.
-// The ICU channel is identified by the cluster index and the processor index.
-// Returns 0 if success, > 0 if error.
-////////////////////////////////////////////////////////////////////////////////
-unsigned int _icu_get_index( unsigned int cluster_xy, 
-                             unsigned int proc_id, 
-                             unsigned int * buffer) 
-{
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if (x >= X_SIZE)             return 1; 
-    if (y >= Y_SIZE)             return 1; 
-    if (proc_id >= NB_PROCS_MAX) return 1;
-
-#if USE_XCU
-    _printf("[GIET ERROR] _icu_set_mask() should not be used if USE_XICU is set\n");
-    return 1;
-#else
-    unsigned int * icu_address = (unsigned int *) ( SEG_ICU_BASE + 
-                                 (cluster_xy * PERI_CLUSTER_INCREMENT) );
-    *buffer = icu_address[proc_id * ICU_SPAN + ICU_IT_VECTOR]; 
-    return 0;
-#endif
-}
-
-
-// Local Variables:
-// tab-width: 4
-// c-basic-offset: 4
-// c-file-offsets:((innamespace . 0)(inline-open . 0))
-// indent-tabs-mode: nil
-// End:
-// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
-
Index: soft/giet_vm/giet_drivers/icu_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/icu_driver.h	(revision 436)
+++ 	(revision )
@@ -1,50 +1,0 @@
-///////////////////////////////////////////////////////////////////////////////////
-// File     : icu_driver.h
-// Date     : 01/11/2013
-// Author   : alain greiner
-// Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
-
-#ifndef _GIET_ICU_DRIVER_H_
-#define _GIET_ICU_DRIVER_H_
-
-///////////////////////////////////////////////////////////////////////////////////
-// ICU registers offsets
-///////////////////////////////////////////////////////////////////////////////////
-
-enum ICU_registers 
-{
-    ICU_INT         = 0,
-    ICU_MASK        = 1,
-    ICU_MASK_SET    = 2,
-    ICU_MASK_CLEAR  = 3,
-    ICU_IT_VECTOR   = 4,
-    /**/
-    ICU_END         = 5,
-    ICU_SPAN        = 8,
-};
-
-///////////////////////////////////////////////////////////////////////////////////
-// ICU and XICU access functions 
-///////////////////////////////////////////////////////////////////////////////////
-
-extern unsigned int _icu_get_index( unsigned int cluster_xy, 
-                                    unsigned int proc_id, 
-                                    unsigned int * buffer );
-
-extern unsigned int _icu_set_mask( unsigned int cluster_xy,
-                                   unsigned int proc_id,
-                                   unsigned int value );
-
-///////////////////////////////////////////////////////////////////////////////////
-
-#endif
-
-// Local Variables:
-// tab-width: 4
-// c-basic-offset: 4
-// c-file-offsets:((innamespace . 0)(inline-open . 0))
-// indent-tabs-mode: nil
-// End:
-// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
-
Index: soft/giet_vm/giet_drivers/iob_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/iob_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/iob_driver.c	(revision 437)
@@ -4,12 +4,4 @@
 // Author   : alain greiner
 // Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
-// The iob_driver.c and iob_driver.h files are part ot the GIET-VM kernel.
-// This driver supports the TSAR vci_io_bridge, that is a bridge to access
-// The external peripherals, implementing an IO_MMU.
-// This component can be instanciated in more than one cluster.
-///////////////////////////////////////////////////////////////////////////////////
-// The SEG_IOB_BASE virtual addresses must be defined in hard_config.h file.
-// The physical base address is supposed to be (cluster_xy << 32) | SEG_IOB_BASE.
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -61,7 +53,6 @@
 
 
-///////////////////////////////////////////////////////////////////////////////
-// This function invalidates a TLB entry identified by a virtual address.
-///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////
 void _iob_inval_tlb_entry( unsigned int cluster_xy,
                            unsigned int vaddr )
@@ -72,7 +63,5 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// This function sets a new value in IOB_IOMMU_PTPR register.
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////
 void _iob_set_iommu_ptpr( unsigned int cluster_xy,
                           unsigned int value )
Index: soft/giet_vm/giet_drivers/iob_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/iob_driver.h	(revision 436)
+++ soft/giet_vm/giet_drivers/iob_driver.h	(revision 437)
@@ -5,4 +5,10 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
+// The iob_driver.c and iob_driver.h files are part ot the GIET-VM kernel.
+// This driver supports the TSAR vci_io_bridge, that is a bridge to access
+// The external peripherals, implementing an IO_MMU.
+// The SEG_IOB_BASE virtual addresses must be defined in hard_config.h file.
+// The physical base address is (cluster_io << 32) | SEG_IOB_BASE.
+///////////////////////////////////////////////////////////////////////////////////
 
 #ifndef _GIET_IOB_DRIVER_H_
@@ -10,5 +16,5 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-// vci_io_bridge : registers offsets and iommu error codes
+//                registers offsets and iommu error codes
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -40,14 +46,20 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-// TSAR IOB access functions
+//                       access functions
 ///////////////////////////////////////////////////////////////////////////////////
 
+///////////////////////////////////////////////////////////////////////////////
+// This function invalidates a TLB entry identified by a virtual address.
+///////////////////////////////////////////////////////////////////////////////
 extern void _iob_inval_tlb_entry( unsigned int cluster_xy,
                                   unsigned int vaddr );
 
+///////////////////////////////////////////////////////////////////////////////
+// This function sets a new value in IOB_IOMMU_PTPR register.
+///////////////////////////////////////////////////////////////////////////////
 extern void _iob_set_iommu_ptpr(  unsigned int cluster_xy,
                                   unsigned int value );
 
-///////////////////////////////////////////////////////////////////////////////////
+
 
 #endif
Index: soft/giet_vm/giet_drivers/ioc_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/ioc_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/ioc_driver.c	(revision 437)
@@ -6,9 +6,8 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// Implementation note:
-//
+// Implementation notes:
 // 1) In order to share the code, the two _ioc_read() and _ioc_write() functions
-// call the same _ioc_access() function.
-//
+// call the same _ioc_access() function, and this function call the selected
+// physical driver (BDV / HBA / SPI / RDK).
 // 2) The IOMMU is not supported yet, but the method is the following:
 // A fixed size 2 Mbytes vseg is allocated to the IOC peripheral, in the I/O 
@@ -97,11 +96,23 @@
 unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
 unsigned int p       = procid & ((1<<P_WIDTH)-1);
-_printf("\n[IOC DEBUG] _ioc_access() : P[%d,%d,%d] enters at cycle %d\n"
-        " - channel  = %d\n"
-        " - mode     = %d\n"
-        " - vaddr    = %x\n"
-        " - sectors  = %d\n"
-        " - lba      = %x\n",
-        x, y, p, _get_proctime(), channel, mode, buf_vaddr, count, lba );
+_puts("\n[IOC DEBUG] _ioc_access() : P[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts(",");
+_putd( p );
+_puts("] enters at cycle ");
+_putd( _get_proctime() );
+_puts("\n - channel  = ");
+_putd( channel );
+_puts("\n - mode     = ");
+_putd( mode );
+_puts("\n - vaddr    = ");
+_putx( buf_vaddr );
+_puts("\n - sectors  = ");
+_putd( count );
+_puts("\n - lba      = ");
+_putx( lba );
+_puts("\n");
 #endif
 
@@ -115,5 +126,5 @@
     if ((unsigned int) buf_vaddr & 0x3)
     {
-        _printf("\n[IOC ERROR] in _ioc_access() : buffer not word aligned\n");
+        _puts("\n[IOC ERROR] in _ioc_access() : buffer not word aligned\n");
         _exit(); 
     }
@@ -122,5 +133,5 @@
     if ( (USE_IOC_HBA == 0) && (channel > 0) )
     {
-        _printf("\n[IOC ERROR] in _ioc_access() : channel must be 0 when HBA not used\n");
+        _puts("\n[IOC ERROR] in _ioc_access() : channel must be 0 when HBA not used\n");
         _exit(); 
     }
@@ -146,5 +157,5 @@
         if ( ko )
         {
-            _printf("\n[IOC ERROR] in _ioc_access() : buffer unmapped\n");
+            _puts("\n[IOC ERROR] in _ioc_access() : buffer unmapped\n");
             _exit(); 
         }
@@ -152,5 +163,5 @@
         if ( (mode == IOC_USER_MODE) && ((flags & PTE_U) == 0) )
         {
-            _printf("\n[IOC ERROR] in _ioc_access() : buffer not user accessible\n");
+            _puts("\n[IOC ERROR] in _ioc_access() : buffer not user accessible\n");
             _exit(); 
         }
@@ -158,5 +169,5 @@
         if ( ((flags & PTE_W) == 0 ) && to_mem )
         {
-            _printf("\n[IOC ERROR] in _ioc_access() : buffer not writable\n");
+            _puts("\n[IOC ERROR] in _ioc_access() : buffer not writable\n");
             _exit(); 
         }
@@ -274,9 +285,5 @@
 #elif ( USE_IOC_RDK )
 
-    _printf("[GIET ERROR] _ioc_get_status() should not be called");
-    _printf(" when RAMDISK  is used...\n");
-    _exit();
-
-    return 0;
+    return rdk_get_status();
 
 #endif
Index: soft/giet_vm/giet_drivers/ioc_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/ioc_driver.h	(revision 436)
+++ soft/giet_vm/giet_drivers/ioc_driver.h	(revision 437)
@@ -18,11 +18,6 @@
 // USE_IOC_BDV, USE_IOC_SDC, USE_IOC_HBA, USE_IOC_RDK.
 //
-// Any physical block device driver xxx must provide the following API:
-// - _xxx_init()
-// - _xxx_read()
-// - _xxx_write()
-// - _xxx_get_status()
-// - _xxx_get_block_size()
-// The "channel" parameter is no transmited to single channel devices.
+// Any physical block device driver must provide the 5 five functions defined
+// by this generic driver.
 //
 // The _ioc_read() and _ioc_write() functions are always blocking for
@@ -67,11 +62,6 @@
 // If the RAMDISK is used, an extra memory segment with virtual base address
 // SEG_RDK_BASE, used by RDK driver, must be defined in hard_config.h.
-///////////////////////////////////////////////////////////////////////////////////
-// Implementation note:
 //
-// 1) In order to share the code, the two _ioc_read() and _ioc_write() functions
-// call the same _ioc_access() function.
-//
-// 2) The IOMMU is not supported yet, but the method is the following:
+// The IOMMU is not supported yet, but the method is the following:
 // A fixed size 2 Mbytes vseg is allocated to the IOC peripheral, in the I/O 
 // virtual space, and the user buffer is dynamically remapped to one single
@@ -103,9 +93,9 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-// IOC access functions  (generic disk controller)
+//      External functions                            
 ///////////////////////////////////////////////////////////////////////////////////
 
 ///////////////////////////////////////////////////////////////////////////////
-// This function cheks block size, and desactivates the IOC interrupts.
+// This function cheks block size, and desactivates interrupts.
 // Return 0 for success, non zero if error.
 ///////////////////////////////////////////////////////////////////////////////
@@ -113,6 +103,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-// Transfer data from a memory buffer to the block device. 
-// - mode     : BOOT_PA / BOOT_VA / KERNEL / USER 
+// Transfer data from a memory buffer to the disk. 
+// - mode     : BOOT / KERNEL / USER 
 // - lba      : first block index on the block device
 // - buffer   : base address of the memory buffer (must be word aligned)
@@ -127,6 +117,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-// Transfer data from the block device to a memory buffer. 
-// - mode     : BOOT_PA / BOOT_VA / KERNEL / USER 
+// Transfer data from the disk to a memory buffer. 
+// - mode     : BOOT / KERNEL / USER 
 // - lba      : first block index on the block device
 // - buffer   : base address of the memory buffer (must be word aligned)
@@ -142,5 +132,5 @@
 ///////////////////////////////////////////////////////////////////////////////
 // This function returns in the status variable, the transfert status, and
-// acknowledge the IRQ if the IOC controler is not busy.
+// acknowledge the IRQ if required.
 // Returns 0 if success, > 0 if error
 ///////////////////////////////////////////////////////////////////////////////
Index: soft/giet_vm/giet_drivers/mmc_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/mmc_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/mmc_driver.c	(revision 437)
@@ -5,15 +5,4 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The mmc_driver.c and mmc_driver.h files are part ot the GIET-VM nano-kernel.
-// This driver supports the vci_mem_cache component used in the TSAR architecture.
-//
-// This component is replicated in all clusters, and can be accessed through 
-// a configuration interface as a set of uncached, memory mapped registers.
-//
-// The (virtual) base address of the associated segment is:
-//       SEG_MMC_BASE + cluster_id * PERI_CLUSTER_INCREMENT
-//
-// SEG_MMC_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h.
-////////////////////////////////////////////////////////////////////////////////
 
 #include <giet_config.h>
@@ -82,9 +71,5 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////////
-// 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 _mmc_inval( paddr_t      buf_paddr,
                  unsigned int buf_length )
@@ -98,6 +83,5 @@
     if ( (x >= X_SIZE) || (y >= Y_SIZE) )
     {
-        _printf("\n[GIET ERROR] in _memc_inval() : illegal cluster_xy for paddr %l\n",
-                 buf_paddr );
+        _puts("\n[GIET ERROR] in _memc_inval() : illegal cluster coordinates\n");
         _exit();
     }
@@ -115,9 +99,6 @@
     _mmc_set_register(cluster_xy, 0, MEMC_LOCK, 0);
 }
-///////////////////////////////////////////////////////////////////////////////////
-// 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 _mmc_sync( paddr_t      buf_paddr,
                 unsigned int buf_length )
@@ -131,6 +112,5 @@
     if ( (x >= X_SIZE) || (y >= Y_SIZE) )
     {
-        _printf( "\n[GIET ERROR] in _memc_sync() : illegal cluster_xy for paddr %l\n",
-                 buf_paddr );
+        _puts( "\n[GIET ERROR] in _memc_sync() : illegal cluster coordinates");
         _exit();
     }
@@ -149,10 +129,5 @@
 }
 
-//////////////////////////////////////////////////////////////////////////////////
-// 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
@@ -163,8 +138,13 @@
     unsigned int x          = cluster_xy >> Y_WIDTH;
     unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
-    unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
+    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
 
-    _printf("[GIET ERROR] MMC IRQ received by processor[%d,%d,%d]"
-            " but _mmc_isr() not implemented...\n", x, y, lpid );
+    _puts("[GIET ERROR] MMC IRQ received by processor[");
+    _putd( x );
+    _puts(",");
+    _putd( y );
+    _puts(",");
+    _putd( p );
+    _puts("] but _mmc_isr() not implemented\n");
 }
 
Index: soft/giet_vm/giet_drivers/mwr_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/mwr_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/mwr_driver.c	(revision 437)
@@ -63,5 +63,5 @@
                            paddr_t                channel_pbase ) 
 {
-    _printf(" [GIET_ERROR] _mwr_hw_init() function not supported yet\n");
+    _puts(" [GIET_ERROR] _mwr_hw_init() function not supported yet\n");
     _exit();
 
Index: soft/giet_vm/giet_drivers/nic_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/nic_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/nic_driver.c	(revision 437)
@@ -5,30 +5,11 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The nic_driver.c and nic_driver.h files are part ot the GIET-VM nano-kernel.
-// This driver supports the vci_multi_nic component.
-// 
-// It can exist only one network controller in the architecture, but this
-// component supports several channels.
-//
-// It can be accessed directly by software with memcpy(),
-// or it can be accessed through the vci_chbuf_dma component:
-//  
-// The '_nic_sync_write' and '_nic_sync_read' functions use a memcpy strategy to
-// implement the transfer between a data buffer (user space) and the NIC
-// buffer (kernel space). They are blocking until completion of the transfer.
-//
-// The _nic_cma_*_init() and _nic_cma_stop() functions use the VciChbufDma component 
-// to transfer a flow of packets from the NIC RX hard chbuf (two containers) 
-// to an user RX chbuf (two containers), and to transfer another flow of packets
-// from an user TX chbuf (two containers) to the NIC TX chbuf (two containers).
-// One NIC channel and two CMA channels must be allocated to the task 
-// in the mapping_info data structure.
-//
-// The SEG_NIC_BASE address must be defined in the hard_config.h file.
-//////////////////////////////////////////////////////////////////////////////////
 
 #include <giet_config.h>
 #include <nic_driver.h>
+#include <cma_driver.h>
 #include <utils.h>
+#include <ctx_handler.h>
+#include <vmem.h>
 
 #if !defined(GIET_USE_IOMMU) 
@@ -44,4 +25,12 @@
 #endif
 
+#if !defined(X_IO)
+# error: You must define X_IO in the hard_config.h file
+#endif
+
+#if !defined(Y_IO)
+# error: You must define Y_IO in the hard_config.h file
+#endif
+
 #if ( NB_NIC_CHANNELS > 8 )
 # error: NB_NIC_CHANNELS cannot be larger than 8
@@ -60,11 +49,15 @@
 #endif
 
+#if !defined( GIET_CHBUF_NBUFS )
+# error: You must define GIET_CHBUF_NBUFS in the giet_config.h file
+#endif
+
 #define in_unckdata __attribute__((section (".unckdata")))
 
 ///////////////////////////////////////////////////////////////////////////////
-// This low_level function returns the value contained in register (index).
-///////////////////////////////////////////////////////////////////////////////
-unsigned int _nic_get_register( unsigned int channel,
-                                unsigned int index )
+// This low_level function returns the value contained in a channel register. 
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _nic_get_channel_register( unsigned int channel,
+                                        unsigned int index )
 {
     unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + 
@@ -74,9 +67,9 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-// This low-level function set a new value in register (index).
-///////////////////////////////////////////////////////////////////////////////
-void _nic_set_register( unsigned int channel,
-                        unsigned int index,
-                        unsigned int value ) 
+// This low-level function set a new value in a channel register.
+///////////////////////////////////////////////////////////////////////////////
+void _nic_set_channel_register( unsigned int channel,
+                                unsigned int index,
+                                unsigned int value ) 
 {
     unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + 
@@ -85,77 +78,324 @@
 }
 
-//////////////////////////////////////////////////////////////////////////////////
-// Transfer data from an memory buffer to the NIC device using a memcpy.
-// - buffer : base address of the memory buffer.
-// - length : number of bytes to be transfered.
-//////////////////////////////////////////////////////////////////////////////////
-unsigned int _nic_sync_write( const void*    buffer,
-                              unsigned int   length ) 
-{
-    _printf("[GIET ERROR] _nic_sync_write function not implemented / cycle %d\n",
-            _get_proctime() );
-    _exit();
-
-    return 0;
-}
-//////////////////////////////////////////////////////////////////////////////////
-// Transfer data from the NIC device to a memory buffer using a memcpy. 
-// - buffer : base address of the memory buffer.
-// - length : number of bytes to be transfered.
-//////////////////////////////////////////////////////////////////////////////////
-unsigned int _nic_sync_read( const void*    buffer, 
-                             unsigned int   length ) 
-{
-    _printf("[GIET ERROR] _nic_sync_read function not implemented / cycle %d\n",
-            _get_proctime() );
-    _exit();
-
-    return 0;
-}
-//////////////////////////////////////////////////////////////////////////////////
-// Returns 0 if success, > 0 if error.
-//////////////////////////////////////////////////////////////////////////////////
-unsigned int _nic_cma_start( )
-{
-    _printf("[GIET ERROR] _nic_cma_start() not implemented / cycle %d\n",
-            _get_proctime() );
-    _exit();
-
-    return 0;
-}
-//////////////////////////////////////////////////////////////////////////////////
-// Returns 0 if success, > 0 if error.
-//////////////////////////////////////////////////////////////////////////////////
-unsigned int _nic_cma_stop()
-{
-    _printf("[GIET ERROR] _nic_cma_stop() not implemented / cycle %d\n",
-            _get_proctime() );
-    _exit();
-
-    return 0;
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// This ISR handles IRQx from a NIC RX channeL
-//////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// This low_level function returns the value contained in a global register. 
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _nic_get_global_register( unsigned int index )
+{
+    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + 
+                           NIC_CHANNEL_SPAN * NB_NIC_CHANNELS + index;
+    return _io_extended_read( vaddr );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This low-level function set a new value in a global register.
+///////////////////////////////////////////////////////////////////////////////
+void _nic_set_global_register( unsigned int index,
+                               unsigned int value ) 
+{
+    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + 
+                           NIC_CHANNEL_SPAN * NB_NIC_CHANNELS + index;
+    _io_extended_write( vaddr, value );
+}
+
+////////////////////////////////////////////
+int _nic_global_init( unsigned int channels,
+                      unsigned int vis,
+                      unsigned int bc_enable,
+                      unsigned int bypass_enable )
+{
+    _nic_set_global_register( NIC_G_VIS          , vis );
+    _nic_set_global_register( NIC_G_NB_CHAN      , channels );
+    _nic_set_global_register( NIC_G_BC_ENABLE    , bc_enable );
+    _nic_set_global_register( NIC_G_BYPASS_ENABLE, bypass_enable );
+    _nic_set_global_register( NIC_G_ON           , 1 );
+
+    return 0;
+}
+
+////////////////////////////////////////////
+int _nic_channel_init( unsigned int index,
+                       unsigned int mac4,
+                       unsigned int mac2 )
+{
+    unsigned int base     = SEG_NIC_BASE;
+    unsigned int extend   = (X_IO << Y_WIDTH) + Y_IO;
+
+    _nic_set_channel_register( index, NIC_RX_DESC_LO_0 + 4096, base );
+    _nic_set_channel_register( index, NIC_RX_DESC_LO_1 + 4096, base + 0x1000 );
+    _nic_set_channel_register( index, NIC_TX_DESC_LO_0 + 4096, base + 0x2000 );
+    _nic_set_channel_register( index, NIC_TX_DESC_LO_1 + 4096, base + 0x3000 );
+
+    _nic_set_channel_register( index, NIC_RX_DESC_HI_0       , extend );
+    _nic_set_channel_register( index, NIC_RX_DESC_HI_1       , extend );
+    _nic_set_channel_register( index, NIC_TX_DESC_HI_0       , extend );
+    _nic_set_channel_register( index, NIC_TX_DESC_HI_1       , extend );
+
+    _nic_set_channel_register( index, NIC_MAC_4              , mac4 );
+    _nic_set_channel_register( index, NIC_MAC_2              , mac2 );
+    
+    _nic_set_channel_register( index, NIC_RX_RUN             , 1 );
+    _nic_set_channel_register( index, NIC_TX_RUN             , 1 );
+
+    return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+//             Synchronous access functions
+/////////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////
+int _nic_sync_send( unsigned int        channel,
+                    unsigned long long  user_paddr )
+{
+    unsigned long long nic_paddr;   // nic buffer physical address
+    unsigned int       done = 0;
+    unsigned int       lsb;
+    unsigned int       msb;
+
+    if ( channel >= NB_NIC_CHANNELS )
+    {
+        _puts("[GIET ERROR] in _timer_sync_send()\n");
+        return -1;
+    }
+
+    // poll the NIC buffers
+    while ( done == 0 )
+    {
+        // test availability of NIC TX buffer 0
+        lsb  = _nic_get_channel_register( channel, NIC_TX_DESC_LO_0 );
+        msb  = _nic_get_channel_register( channel, NIC_TX_DESC_HI_0 );
+        if ( (msb & 0x80000000) == 0 )
+        {
+            msb  = msb & 0x0000FFFF;
+            done = 1;
+            continue;
+        }
+
+        // test availability of NIC TX buffer 1
+        lsb  = _nic_get_channel_register( channel, NIC_TX_DESC_LO_1 );
+        msb  = _nic_get_channel_register( channel, NIC_TX_DESC_HI_1 );
+        if ( (msb & 0x80000000) == 0 )
+        {
+            msb  = msb & 0x0000FFFF;
+            done = 1;
+            continue;
+        }
+
+        // random delay (average value: 380 cycle)
+        _random_wait( 8 );
+    }
+
+    // make the transfer
+    nic_paddr = (unsigned long long)lsb + (((unsigned long long)msb) << 32);
+
+    _physical_memcpy( nic_paddr , user_paddr, 4096 );
+
+    return 0;
+}
+
+///////////////////////////////////////////////////
+int _nic_sync_receive( unsigned int        channel,
+                       unsigned long long  user_paddr )
+{
+    unsigned long long nic_paddr;   // nic  buffer physical address
+    unsigned int       done = 0;
+    unsigned int       lsb;
+    unsigned int       msb;
+
+    if ( channel >= NB_NIC_CHANNELS )
+    {
+        _puts("[GIET ERROR] in _timer_sync_receive()\n");
+        return -1;
+    }
+
+    // polling the NIC buffers
+    while ( done == 0 )
+    {
+        // test availability of NIC RX buffer 0
+        lsb  = _nic_get_channel_register( channel, NIC_RX_DESC_LO_0 );
+        msb  = _nic_get_channel_register( channel, NIC_RX_DESC_HI_0 );
+        if ( (msb & 0x80000000) == 1 )
+        {
+            msb  = msb & 0x0000FFFF;
+            done = 1;
+            continue;
+        }
+
+        // test availability of NIC RX buffer 1
+        lsb  = _nic_get_channel_register( channel, NIC_RX_DESC_LO_1 );
+        msb  = _nic_get_channel_register( channel, NIC_RX_DESC_HI_1 );
+        if ( (msb & 0x80000000) == 1 )
+        {
+            msb  = msb & 0x0000FFFF;
+            done = 1;
+            continue;
+        }
+
+        // random delay (average value: 380 cycle)
+        _random_wait( 8 );
+    }
+
+    // make the transfer
+    nic_paddr = (unsigned long long)lsb + (((unsigned long long)msb) << 32);
+
+    _physical_memcpy( user_paddr, nic_paddr , 4096 );
+
+    return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+//             CMA access functions
+/////////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+int _nic_cma_receive( unsigned int  nic_channel,
+                      unsigned int  cma_channel,
+                      nic_chbuf_t*  kernel_chbuf )
+                             
+{
+    unsigned int nic_chbuf_lsb;     // 32 LSB bits of the NIC chbuf physical address
+    unsigned int nic_chbuf_msb;     // 16 MSB bits of the NIC chbuf physical address
+    unsigned int mem_chbuf_lsb;     // 32 LSB bits of the kernel chbuf physical address
+    unsigned int mem_chbuf_msb;     // 16 MSB bits of the kernel chbuf physical address
+
+    unsigned int ppn;
+    unsigned int flags;
+
+    // checking parameters
+    if ( nic_channel >= NB_NIC_CHANNELS )
+    {
+        _puts("[GIET ERROR] in _nic_cma_start_receive() : nic_channel index too large\n");
+        return -1;
+    }
+    if ( cma_channel >= NB_CMA_CHANNELS )
+    {
+        _puts("[GIET ERROR] in _nic_cma_start_receive() : cma_channel index too large\n");
+        return -1;
+    }
+
+    // get the NIC_RX chbuf descriptor physical address
+    nic_chbuf_lsb = SEG_NIC_BASE + (nic_channel * NIC_CHANNEL_SPAN) + 0x1000;
+    nic_chbuf_msb = (X_IO << Y_WIDTH) + Y_IO;
+
+    // compute the kernel chbuf physical address
+    unsigned int ptab  = _get_context_slot(CTX_PTAB_ID);
+    unsigned int vaddr = (unsigned int)kernel_chbuf;
+    unsigned int ko    = _v2p_translate( (page_table_t*)ptab,
+                                          vaddr,
+                                          &ppn,
+                                          &flags );
+    if ( ko )
+    {
+        _puts("\n[GIET ERROR] in _nic_cma_start_receive() : kernel buffer unmapped\n");
+        return -1;
+    }
+
+    mem_chbuf_lsb = (ppn << 12) | (vaddr & 0x00000FFF);
+    mem_chbuf_msb = ppn >> 20;
+
+    // initializes CMA registers defining the source chbuf (NIC_RX)
+    _cma_set_register( cma_channel, CHBUF_SRC_DESC , nic_chbuf_lsb );
+    _cma_set_register( cma_channel, CHBUF_DST_EXT  , nic_chbuf_msb );
+    _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, 2 );
+
+    // initializes CMA registers defining the destination chbuf (kernel memory)
+    _cma_set_register( cma_channel, CHBUF_DST_DESC , mem_chbuf_lsb );
+    _cma_set_register( cma_channel, CHBUF_DST_EXT  , mem_chbuf_msb );
+    _cma_set_register( cma_channel, CHBUF_DST_NBUFS, GIET_CHBUF_NBUFS );
+
+    // set buffer size, polling period, and start
+    _cma_set_register( cma_channel, CHBUF_BUF_SIZE , 4096 );
+    _cma_set_register( cma_channel, CHBUF_PERIOD   , 300 );
+    _cma_set_register( cma_channel, CHBUF_RUN      , 1 );
+
+    return 0;
+}
+
+//////////////////////////////////////////////////////////
+int _nic_cma_send( unsigned int  nic_channel,
+                   unsigned int  cma_channel,
+                   nic_chbuf_t*  kernel_chbuf )
+{
+    unsigned int nic_chbuf_lsb;     // 32 LSB bits of the NIC chbuf physical address
+    unsigned int nic_chbuf_msb;     // 16 MSB bits of the NIC chbuf physical address
+    unsigned int mem_chbuf_lsb;     // 32 LSB bits of the kernel chbuf physical address
+    unsigned int mem_chbuf_msb;     // 16 MSB bits of the kernel chbuf physical address
+
+    unsigned int ppn;
+    unsigned int flags;
+
+    // checking parameters
+    if ( nic_channel >= NB_NIC_CHANNELS )
+    {
+        _puts("[GIET ERROR] in _nic_cma_start_send() : nic_channel index too large\n");
+        return -1;
+    }
+    if ( cma_channel >= NB_CMA_CHANNELS )
+    {
+        _puts("[GIET ERROR] in _nic_cma_start_send() : cma_channel index too large\n");
+        return -1;
+    }
+
+    // get the NIC_TX chbuf descriptor physical address
+    nic_chbuf_lsb = SEG_NIC_BASE + (nic_channel * NIC_CHANNEL_SPAN) + 0x1010;
+    nic_chbuf_msb = (X_IO << Y_WIDTH) + Y_IO;
+
+    // compute the kernel chbuf physical address
+    unsigned int ptab  = _get_context_slot(CTX_PTAB_ID);
+    unsigned int vaddr = (unsigned int)kernel_chbuf;
+    unsigned int ko    = _v2p_translate( (page_table_t*)ptab,
+                                          vaddr,
+                                          &ppn,
+                                          &flags );
+    if ( ko )
+    {
+        _puts("\n[GIET ERROR] in _nic_cma_start_send() : kernel buffer unmapped\n");
+        return -1;
+    }
+
+    mem_chbuf_lsb = (ppn << 12) | (vaddr & 0x00000FFF);
+    mem_chbuf_msb = ppn >> 20;
+
+    // initializes CMA registers defining the source chbuf (kernel memory)
+    _cma_set_register( cma_channel, CHBUF_SRC_DESC , mem_chbuf_lsb );
+    _cma_set_register( cma_channel, CHBUF_DST_EXT  , mem_chbuf_msb );
+    _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, GIET_CHBUF_NBUFS );
+
+    // initializes CMA registers defining the destination chbuf (NIC_TX)
+    _cma_set_register( cma_channel, CHBUF_DST_DESC , nic_chbuf_lsb );
+    _cma_set_register( cma_channel, CHBUF_DST_EXT  , nic_chbuf_msb );
+    _cma_set_register( cma_channel, CHBUF_DST_NBUFS, 2 );
+
+    // set buffer size, polling period, and start
+    _cma_set_register( cma_channel, CHBUF_BUF_SIZE , 4096 );
+    _cma_set_register( cma_channel, CHBUF_PERIOD   , 300 );
+    _cma_set_register( cma_channel, CHBUF_RUN      , 1 );
+
+    return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//            Interrupt Service Routines
+////////////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////
 void _nic_rx_isr( unsigned int irq_type,
                   unsigned int irq_id,
                   unsigned int channel )
 {
-    _printf("[GIET ERROR] _nic_rx_isr() not implemented / cycle %d\n",
-            _get_proctime() );
-    _exit();
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// This ISR handles IRQx from a NIC RX channeL
-//////////////////////////////////////////////////////////////////////////////////
+    _puts("[NIC WARNING] RX buffers are full for NIC channel ");
+    _putd( channel );
+    _puts("\n");
+}
+
+////////////////////////////////////////
 void _nic_tx_isr( unsigned int irq_type,
                   unsigned int irq_id,
                   unsigned int channel )
 {
-    _printf("[GIET ERROR] _nic_tx_isr() not implemented / cycle %d\n",
-            _get_proctime() );
-    _exit();
+    _puts("[NIC WARNING] TX buffers are full for NIC channel ");
+    _putd( channel );
+    _puts("\n");
 }
 
Index: soft/giet_vm/giet_drivers/nic_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/nic_driver.h	(revision 436)
+++ soft/giet_vm/giet_drivers/nic_driver.h	(revision 437)
@@ -5,10 +5,36 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
+// The nic_driver.c and nic_driver.h files are part ot the GIET-VM nano-kernel.
+// This driver supports the vci_multi_nic component.
+// 
+// It can exist only one network controller in the architecture, but this
+// component supports several channels.
+//
+// It can be accessed directly by software with memcpy(),
+// or it can be accessed through the vci_chbuf_dma component:
+//  
+// The '_nic_sync_write' and '_nic_sync_read' functions use a memcpy strategy to
+// implement the transfer between a data buffer (user space) and the NIC
+// buffer (kernel space). They are blocking until completion of the transfer.
+//
+// The _nic_cma_start() and _nic_cma_stop() functions use the VciChbufDma component 
+// to transfer a flow of packets from the NIC RX hard chbuf (two containers) 
+// to an user RX chbuf (two containers), and to transfer another flow of packets
+// from an user TX chbuf (two containers) to the NIC TX chbuf (two containers).
+// One NIC channel and two CMA channels must be allocated to the task 
+// in the mapping_info data structure.
+//
+// All these access functions return -1 in case of error.
+//
+// The SEG_NIC_BASE address must be defined in the hard_config.h file.
+//////////////////////////////////////////////////////////////////////////////////
 
 #ifndef _GIET_NIC_DRIVERS_H_
 #define _GIET_NIC_DRIVERS_H_
 
+#include <giet_config.h>
+
 ///////////////////////////////////////////////////////////////////////////////////
-// NIC Registers  (vci_multi_nic)
+//           Global Addressable Registers
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -50,10 +76,10 @@
 };
 
-/////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+//            Channel Addressable Registers
 // A container descriptor has the following form: 
-// LOW WORD : Container LSB base address     
-// HIGH WORD: Container status (leftmost bit), '1' means full 
-//            Base address MSB extension, if needed (right aligned)
-//////////////////////////////////////////////////////////////////////
+// LOW WORD  : 32 LSB bits of the container physical base address     
+// HIGH WORD : 16 MSB bits of the container physical base address + status (bit 31)  
+/////////////////////////////////////////////////////////////////////////////////////
 enum SoclibMultiNicChannelRegisters 
 {
@@ -72,17 +98,53 @@
 };
 
+
+////////////////////////////////////////////////////////////////////////////////////
+//              Chained Buffer Descriptor Structure
+////////////////////////////////////////////////////////////////////////////////////
+typedef struct nic_chbuf_s
+{
+    unsigned long long buf[GIET_CHBUF_NBUFS]; // array of buffer descriptors 
+    unsigned int       buf_length;            // buffer length (bytes)
+    unsigned int       nb_buffers;            // actual number of buffers
+} nic_chbuf_t;
+
 ///////////////////////////////////////////////////////////////////////////////////
-// NIC device access functions  (vci_multi_nic)
+//              Initialization functions
 ///////////////////////////////////////////////////////////////////////////////////
 
-extern unsigned int _nic_sync_write( const void*  buffer, 
-                                     unsigned int length );
+extern int _nic_global_init( unsigned int channels,
+                             unsigned int vis,
+                             unsigned int bc_enable,
+                             unsigned int bypass_enable );
 
-extern unsigned int _nic_sync_read(  const void*  buffer, 
-                                     unsigned int length );
+extern int _nic_channel_init( unsigned int index,
+                              unsigned int mac4,
+                              unsigned int mac2 );
 
-extern unsigned int _nic_cma_start();
+///////////////////////////////////////////////////////////////////////////////////
+//              Blocking functions using a physical_memcpy()
+///////////////////////////////////////////////////////////////////////////////////
 
-extern unsigned int _nic_cma_stop();
+extern int _nic_sync_receive( unsigned int       channel, 
+                              unsigned long long user_paddr );
+
+extern int _nic_sync_send( unsigned int       channel,
+                           unsigned long long user_paddr );
+
+///////////////////////////////////////////////////////////////////////////////////
+//              Non blocking functions using the chained buffer DMA
+///////////////////////////////////////////////////////////////////////////////////
+
+extern int _nic_cma_receive( unsigned int  nic_channel,
+                             unsigned int  cma_channel,
+                             nic_chbuf_t*  kernel_chbuf );
+
+extern int _nic_cma_send( unsigned int  nic_channel,
+                          unsigned int  cma_channel,
+                          nic_chbuf_t*  kernel_chbuf );
+
+///////////////////////////////////////////////////////////////////////////////////
+//              Interrupt Service Routines
+///////////////////////////////////////////////////////////////////////////////////
 
 extern void _nic_rx_isr( unsigned int irq_type,
@@ -94,5 +156,4 @@
                          unsigned int channel );
 
-///////////////////////////////////////////////////////////////////////////////////
 
 
Index: soft/giet_vm/giet_drivers/pic_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/pic_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/pic_driver.c	(revision 437)
@@ -5,11 +5,8 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// Implementation note:
-// All physical accesses to device registers are done by the two
-// _pic_get_register(), _pic_set_register() low-level functions,
-// that are handling virtual / physical addressing.
-///////////////////////////////////////////////////////////////////////////////////
 
 #include <pic_driver.h>
+#include <giet_config.h>
+#include <hard_config.h>
 #include <utils.h>
 
@@ -18,5 +15,5 @@
 #endif
 
-/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////
 unsigned int _pic_get_register( unsigned int channel,
                                 unsigned int index )
@@ -26,5 +23,5 @@
 }
 
-/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////
 void _pic_set_register( unsigned int channel,
                         unsigned int index,
@@ -36,5 +33,5 @@
 
 
-/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////
 void _pic_init( unsigned int channel,      // source PIC HWI channel
                 unsigned int vaddr,        // dest XCU WTI address
@@ -46,5 +43,5 @@
 }
 
-/////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////
 unsigned int _pic_get_status( unsigned int channel )
 {
Index: soft/giet_vm/giet_drivers/pic_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/pic_driver.h	(revision 436)
+++ soft/giet_vm/giet_drivers/pic_driver.h	(revision 437)
@@ -15,5 +15,5 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-// PIC (vci_iopic) registers offsets
+//                      registers offsets
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -29,5 +29,5 @@
 
 //////////////////////////////////////////////////////////////////////////////////
-// PIC access functions
+//                      access functions
 //////////////////////////////////////////////////////////////////////////////////
 
Index: soft/giet_vm/giet_drivers/rdk_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/rdk_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/rdk_driver.c	(revision 437)
@@ -6,17 +6,4 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The rdk_driver.c and rdk_driver.h files are part ot the GIET-VM kernel.
-//
-// This driver supports a virtual disk implemented as a memory segment, 
-// in the address space. 
-//
-// The _rdk_read() and _rdk_write() blocking functions use a software memcpy,
-// whatever the selected mode. They return only when the transfer is completed.
-// As the number of concurrent accesses is not bounded, these functions
-// don't use the _ioc_lock variable.
-//
-// The SEG_RDK_BASE virtual address must be defined in the hard_config.h
-// file when the USE_RAMDISK flag is set.
-///////////////////////////////////////////////////////////////////////////////////
 
 #include <giet_config.h>
@@ -24,6 +11,4 @@
 #include <rdk_driver.h>
 #include <utils.h>
-#include <tty_driver.h>
-#include <ctx_handler.h>
 
 #if !defined(SEG_RDK_BASE) 
@@ -31,8 +16,5 @@
 #endif
 
-///////////////////////////////////////////////////////////////////////////////
-//       _rdk_init()
-// This function does nothing, and return 0 for success.
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////
 unsigned int _rdk_init( unsigned int channel )
 {
@@ -40,77 +22,78 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////
-//     _rdk_read()
-// Transfer data from the RAMDISK to a memory buffer. 
-// - mode     : BOOT / KERNEL / USER
-// - lba      : first block index on the block device
-// - buffer   : virtual base address of the memory buffer
-// - count    : number of blocks to be transfered.
-// Returns 0 if success, > 0 if error.
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////
 unsigned int _rdk_read( unsigned int lba, 
                         unsigned int buffer, 
                         unsigned int count) 
 {
+#if USE_IOC_RDK
 
 #if GIET_DEBUG_IOC_DRIVER
-_printf("\n[IOC DEBUG] Enter _rdk_read() at cycle %d"
-        "\n - vaddr   = %x"
-        "\n - sectors = %d"
-        "\n - lba     = %x",
-        _get_proctime(), buffer, count, lba );
+_puts("\n[IOC DEBUG] Enter _rdk_read() at cycle ");
+_putd( _get_proctime() );
+_puts("\n - vaddr   = "); 
+_putx( buffer );
+-puts("\n - sectors = "); 
+_putd( count );
+-puts("\n - lba     = "); 
+_putx( lba );
+_puts("\n");
 #endif
 
-#if USE_IOC_RDK
     char* src = (char*)SEG_RDK_BASE + (512*lba);
     char* dst = (char*)buffer;
     memcpy( dst, src, count*512 );
     return 0;
+
 #else
-    _printf("[GIET ERROR] _rdk_read() should not be used if USE_IOC_RDK not set\n");
+
+    _puts("[GIET ERROR] _rdk_read() should not be used if USE_IOC_RDK not set\n");
     return 1;
+
 #endif
 }
 
-///////////////////////////////////////////////////////////////////////////////
-//     _rdk_write()
-// Transfer data from a memory buffer to the block device. 
-// - mode     : BOOT / KERNEL / USER
-// - lba      : first block index on the block device
-// - buffer   : virtual base address of the memory buffer 
-// - count    : number of blocks to be transfered.
-// Returns 0 if success, > 0 if error.
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////
 unsigned int _rdk_write( unsigned int lba, 
                          unsigned int buffer, 
                          unsigned int count ) 
 {
+#if USE_IOC_RDK
 
 #if GIET_DEBUG_IOC_DRIVER
-_printf("\n[IOC DEBUG] Enter _rdk_write() at cycle %d"
-        "\n - vaddr   = %x"
-        "\n - sectors = %d"
-        "\n - lba     = %x",
-        _get_proctime(), buffer, count, lba );
+_puts("\n[IOC DEBUG] Enter _rdk_write() at cycle ");
+_putd( _get_proctime() );
+_puts("\n - vaddr   = "); 
+_putx( buffer );
+-puts("\n - sectors = "); 
+_putd( count );
+-puts("\n - lba     = "); 
+_putx( lba );
+_puts("\n");
 #endif
 
-#if USE_IOC_RDK
     char* dst = (char*)SEG_RDK_BASE + (512*lba);
     char* src = (char*)buffer;
     memcpy( dst, src, count*512 );
     return 0;
+
 #else
-    _printf("[GIET ERROR] _rdk_write() should not be used if USE_IOC_RDK not set\n");
+
+    _puts("[GIET ERROR] _rdk_write() should not be used if USE_IOC_RDK not set\n");
     return 1;
+
 #endif
 }
 
-///////////////////////////////////////////////////////////////////////////////
-//     _rdk_get_block_size()
-// This function returns the block_size.
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////
 unsigned int _rdk_get_block_size() 
 {
     return 512;
+}
+
+//////////////////////////////
+unsigned int _rdk_get_status() 
+{
+    return 0;
 }
 
Index: soft/giet_vm/giet_drivers/rdk_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/rdk_driver.h	(revision 436)
+++ soft/giet_vm/giet_drivers/rdk_driver.h	(revision 437)
@@ -5,9 +5,20 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
+// The rdk_driver.c and rdk_driver.h files are part ot the GIET-VM kernel.
+//
+// This driver supports a virtual disk implemented as a memory segment, 
+// in the physical address space. 
+//
+// The _rdk_read() and _rdk_write() blocking functions use a software memcpy,
+// whatever the selected mode. They return only when the transfer is completed.
+// As the number of concurrent accesses is not bounded, these functions
+// don't use the _ioc_lock variable.
+//
+// The SEG_RDK_BASE virtual address must be defined in the hard_config.h
+// file when the USE_RAMDISK flag is set.
+///////////////////////////////////////////////////////////////////////////////////
 
 #ifndef _GIET_RDK_DRIVERS_H_
 #define _GIET_RDK_DRIVERS_H_
-
-#include <mapping_info.h>
 
 ///////////////////////////////////////////////////////////////////////////////////
@@ -15,17 +26,42 @@
 ///////////////////////////////////////////////////////////////////////////////////
 
+///////////////////////////////////////////////////////////////////////////////
+// This function does nothing, but is required by the IOC API.
+///////////////////////////////////////////////////////////////////////////////
 extern unsigned int _rdk_init();
 
+///////////////////////////////////////////////////////////////////////////////
+// Transfer data from a memory buffer to the RAMDISK. 
+// - mode     : BOOT / KERNEL / USER (unused)
+// - lba      : first block index on the block device
+// - buffer   : virtual base address of the memory buffer
+// - count    : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////////////////
 extern unsigned int _rdk_write( unsigned int lba, 
                                 unsigned int buffer, 
                                 unsigned int count );
 
+///////////////////////////////////////////////////////////////////////////////
+// Transfer data from the RAMDISK to a memory buffer. 
+// - mode     : BOOT / KERNEL / USER (unused)
+// - lba      : first block index on the block device
+// - buffer   : virtual base address of the memory buffer
+// - count    : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////////////////
 extern unsigned int _rdk_read(  unsigned int lba, 
                                 unsigned int buffer,
                                 unsigned int count );
 
+///////////////////////////////////////////////////////////////////////////////
+// This function returns the block size.
+///////////////////////////////////////////////////////////////////////////////
 extern unsigned int _rdk_get_block_size();
 
 ///////////////////////////////////////////////////////////////////////////////////
+// This function returns always 0, but is required by the IOC API.
+///////////////////////////////////////////////////////////////////////////////
+extern unsigned int _rdk_get_status();
 
 #endif
Index: soft/giet_vm/giet_drivers/sdc_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/sdc_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/sdc_driver.c	(revision 437)
@@ -18,5 +18,4 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-//      _sdc_enable()
 // This function enables SD Card select signal
 ///////////////////////////////////////////////////////////////////////////////
@@ -27,5 +26,4 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-//      _sdc_enable()
 // This function disables SD Card select signal
 ///////////////////////////////////////////////////////////////////////////////
@@ -36,5 +34,4 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-//      _sdc_gen_tick()
 // This function writes on the SPI tx register to generate SD card clock ticks
 // - tick_count: number of ticks to generate (1 tick -> 8 clocks) 
@@ -47,5 +44,4 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-//      _sdc_lseek()
 // This function changes the SD card access pointer position in terms of
 // blocks
@@ -58,5 +54,4 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-//      _sdc_receive_char()
 // This function gets a byte from the SD card
 ///////////////////////////////////////////////////////////////////////////////
@@ -69,5 +64,4 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-//      _sdc_wait_response()
 // This function returns when a valid response from the SD card is received or
 // a timeout has been triggered
@@ -94,5 +88,4 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-//      _sdc_wait_data_block()
 // This function returns when a data block from the SD card is received (data
 // block start marker received).
@@ -105,5 +98,4 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-//      _sdc_send_command()
 // This function sends a command to the SD card
 // - index: CMD index
@@ -153,5 +145,4 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-//      _sdc_open()
 // This function initializes the SD card (reset procedure)
 // - channel: channel index (only channel 0 is supported)
@@ -182,5 +173,5 @@
 	if ( sdcard_rsp != 0x01 )
 	{
-		_printf("[SDC ERROR] card CMD0 failed\n");
+		_puts("[SDC ERROR] card CMD0 failed\n");
 		return sdcard_rsp;
 	}
@@ -198,5 +189,5 @@
 	if (!SDCARD_CHECK_R1_VALID(sdcard_rsp))
     {
-		_printf("[SDC ERROR] card CMD8 failed\n");
+		_puts("[SDC ERROR] card CMD8 failed\n");
 		return sdcard_rsp;
 	}
@@ -211,8 +202,8 @@
         {
 			// voltage mismatch
-			_printf("[SDC ERROR] card CMD8 mismatch : ersp = %x\n");
+			_puts("[SDC ERROR] card CMD8 mismatch : ersp = %x\n");
 			return sdcard_rsp;
 		}
-		_printf("[SDC WARNING] v2 or later ");
+		_puts("[SDC WARNING] v2 or later ");
 		sdcard.sdhc = 1;
 	}
@@ -220,5 +211,5 @@
     {
 		// other error
-		_printf("[SDC ERROR] card CMD8 error\n");
+		_puts("[SDC ERROR] card CMD8 error\n");
 		return sdcard_rsp;
 	}
@@ -251,5 +242,5 @@
 	if (sdcard_rsp)
     {
-		_printf("[SDC ERROR] ACMD41 failed\n");
+		_puts("[SDC ERROR] ACMD41 failed\n");
 		return sdcard_rsp;
 	}
@@ -265,5 +256,5 @@
 		if (sdcard_rsp)
         {
-			_printf("[SDC ERROR] CMD58 failed\n");
+			_puts("[SDC ERROR] CMD58 failed\n");
 			return sdcard_rsp;
 		}
@@ -274,5 +265,5 @@
 		if (ersp & 0x40000000)
         {
-			_printf(" SDHC ");
+			_puts(" SDHC ");
 		} 
         else
@@ -282,11 +273,10 @@
 		_sdc_disable();
 	}
-	_printf("card detected\n");
+	_puts("card detected\n");
 	return 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-//      _sdc_set_block_size()
-// This function sets the block size in bytes of the SD card
+// This function sets the block size in the SD card.
 // - len: block size in bytes (only 512 bytes supported)
 // Returns 0 if success, other value if failure
@@ -330,11 +320,9 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////
-//      _sdc_init()
-// This function initializes the SPI controller and call sdc_open to
-// initializes SD card
-// - channel: channel to initialize (only channel 0 supported)
-// Returns 0 if success, other value if failure
-///////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+//           Extern functions
+/////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////
 unsigned int _sdc_init()
 {
@@ -358,14 +346,14 @@
     while(1)
     {
-        _printf("[SDC WARNING] Trying to initialize SD card...\n");
+        _puts("[SDC WARNING] Trying to initialize SD card...\n");
 
         sdcard_rsp = _sdc_open( 0 );  // only channel 0
         if (sdcard_rsp == 0)
         {
-            _printf("OK\n");
+            _puts("OK\n");
             break;
         }
 
-        _printf("KO\n");
+        _puts("KO\n");
 
         for (i = 0; i < 1000; i++);
@@ -373,6 +361,7 @@
         if (++iter >= SDCARD_RESET_ITER_MAX)
         {
-            _printf("\n[SDC ERROR] During SD card reset to IDLE state "
-                    "/ card response = %x\n", sdcard_rsp );
+            _puts("\n[SDC ERROR] During SD card reset / card response = ");
+            _putx( sdcard_rsp );
+            _puts("\n");
             _exit();
         }
@@ -383,5 +372,5 @@
     if (sdcard_rsp)
     {
-        _printf("[SDC ERROR] During SD card blocklen initialization\n");
+        _puts("[SDC ERROR] During SD card blocklen initialization\n");
         _exit();
     }
@@ -397,5 +386,5 @@
     );
 
-    _printf("[SDC WARNING] Finish SD card initialization\n\r");
+    _puts("[SDC WARNING] Finish SD card initialization\n\r");
 
     return 0;
@@ -403,13 +392,5 @@
 
 
-///////////////////////////////////////////////////////////////////////////////
-//     _sdc_read()
-// Transfer data from the block device to a memory buffer. 
-// - mode     : BOOT / KERNEL / USER
-// - lba      : first block index on the block device
-// - buffer   : base address of the memory buffer (must be word aligned)
-// - count    : number of blocks to be transfered.
-// Returns 0 if success, > 0 if error.
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////
 unsigned int _sdc_read( unsigned int mode,
                         unsigned int lba,
@@ -461,13 +442,5 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////
-//     _sdc_write() (not supported for now)
-// Transfer data from memory buffer to SD card device. 
-// - mode     : BOOT / KERNEL / USER
-// - lba      : destination first block index on the SD card
-// - buffer   : base address of the memory buffer (must be word aligned)
-// - count    : number of blocks to be transfered.
-// Returns 0 if success, > 0 if error.
-///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////
 unsigned int _sdc_write( unsigned int mode,
                          unsigned int lba,
@@ -475,16 +448,14 @@
                          unsigned int count )
 {
-	return 0;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Transfer data from memory buffer to SD card device. 
-// - channel: channel index
-// - status: this pointer is used to transmit the status value to caller. 
-// Returns 0 if success, > 0 if error.
-///////////////////////////////////////////////////////////////////////////////
+    _puts("[SDC ERROR] function _sdc_write() not iplemented yet\n");
+    _exit();
+
+    return 0;  // to avoid a warning
+}
+
+//////////////////////////////
 unsigned int _sdc_get_status()
 {
-    _printf("[SDC ERROR] function _sdc_get_status() should not be called\n");
+    _puts("[SDC ERROR] function _sdc_get_status() should not be called\n");
     _exit();
 
@@ -492,7 +463,5 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// Returns the block size in bytes of the SD card
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////
 unsigned int _sdc_get_block_size()
 {
Index: soft/giet_vm/giet_drivers/sdc_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/sdc_driver.h	(revision 436)
+++ soft/giet_vm/giet_drivers/sdc_driver.h	(revision 437)
@@ -5,4 +5,5 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
+
 #ifndef _GIET_SDC_DRIVER_H_
 #define _GIET_SDC_DRIVER_H_
@@ -36,6 +37,20 @@
 };
 
+///////////////////////////////////////////////////////////////////////////////
+// This function initializes the SPI controller and call sdc_open to
+// initialize  the SD card
+// - channel: channel to initialize (only channel 0 supported)
+// Returns 0 if success, other value if failure
+///////////////////////////////////////////////////////////////////////////////
 unsigned int _sdc_init();
 
+///////////////////////////////////////////////////////////////////////////////
+// Transfer data from the block device to a memory buffer. 
+// - mode     : BOOT / KERNEL / USER
+// - lba      : first block index on the block device
+// - buffer   : base address of the memory buffer (must be word aligned)
+// - count    : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////////////////
 unsigned int _sdc_read( unsigned int mode,
                         unsigned int lba,
@@ -44,4 +59,13 @@
 
 
+///////////////////////////////////////////////////////////////////////////////
+// Transfer data from memory buffer to SD card device. 
+// - mode     : BOOT / KERNEL / USER
+// - lba      : destination first block index on the SD card
+// - buffer   : base address of the memory buffer (must be word aligned)
+// - count    : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+// WARNING: The _sdc_write() is not implemented yet.
+///////////////////////////////////////////////////////////////////////////////
 unsigned int _sdc_write( unsigned int mode,
                          unsigned int lba,
@@ -49,6 +73,12 @@
                          unsigned int count);
 
+///////////////////////////////////////////////////////////////////////////////
+// This function should not be called for the SDC card.
+///////////////////////////////////////////////////////////////////////////////
 unsigned int _sdc_get_status();
 
+///////////////////////////////////////////////////////////////////////////////
+// Returns the block size in bytes of the SD card.
+///////////////////////////////////////////////////////////////////////////////
 unsigned int _sdc_get_block_size();
 
Index: soft/giet_vm/giet_drivers/sim_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/sim_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/sim_driver.c	(revision 437)
@@ -5,10 +5,4 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The sim_driver.c and sim_driver.h files are part ot the GIET-VM nano-kernel.
-// This driver supports the vci_sim_helper component.
-// There is at most one such component in the architecture.
-//
-// The SEG_SIM_BASE address must be defined in the hard_config.h file.
-////////////////////////////////////////////////////////////////////////////////
 
 #include <hard_config.h>
@@ -20,39 +14,25 @@
 #endif
 
-////////////////////////////////////////////////////////////////////////////////
-// _sim_helper_access()
-// Accesses the Simulation Helper Component.
-//
-// If the access is on a writable register (except SIMHELPER_PAUSE_SIM),
-// the simulation will stop.
-// If the access is on a readable register, value is written in retval buffer.
-// Returns 0 on success, 1 on failure.
-////////////////////////////////////////////////////////////////////////////////
-unsigned int _sim_helper_access( unsigned int register_index,
-                                 unsigned int value,
-                                 unsigned int * retval) 
+/////////////////////////////////////////////////////
+void _sim_helper_access( unsigned int register_index,
+                         unsigned int value,
+                         unsigned int * retval ) 
 {
     volatile unsigned int* sim_helper_address = (unsigned int*)&seg_sim_base;
     
-    if (register_index == SIMHELPER_SC_STOP         ||
-        register_index == SIMHELPER_END_WITH_RETVAL ||
-        register_index == SIMHELPER_EXCEPT_WITH_VAL ||
-        register_index == SIMHELPER_PAUSE_SIM       ||
-        register_index == SIMHELPER_SIGINT) 
+    if (register_index == SIMHELPER_SC_STOP)
     {
         sim_helper_address[register_index] = value;
-        return 0;
     }
     else if (register_index == SIMHELPER_CYCLES) 
     {
         *retval = sim_helper_address[register_index];
-        return 0;
     }
     else 
     {
         _tty_get_lock( 0 );
-        _puts("\n[GIET ERROR] in _sim_helper_access() : access to unmapped register\n");
+        _puts("\n[GIET ERROR] in _sim_helper_access() : undefined register\n");
         _tty_release_lock( 0 );
-        return 1;
+        _exit();
     }
 }
Index: soft/giet_vm/giet_drivers/sim_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/sim_driver.h	(revision 436)
+++ soft/giet_vm/giet_drivers/sim_driver.h	(revision 437)
@@ -5,4 +5,14 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
+// The sim_driver.c and sim_driver.h files are part ot the GIET-VM nano-kernel.
+//
+// This driver supports the vci_sim_helper component, that is a pseudo hardware
+// component available in the SoCLib library, and providing a monitoring service
+// in a virtual prototyping environment.
+//
+// There is at most one such component in the architecture.
+//
+// The SEG_SIM_BASE address must be defined in the hard_config.h file.
+////////////////////////////////////////////////////////////////////////////////
 
 #ifndef _GIET_SIM_DRIVERS_H_
@@ -15,21 +25,21 @@
 enum SoclibSimhelperRegisters
 {
-    SIMHELPER_SC_STOP,
-    SIMHELPER_END_WITH_RETVAL,
-    SIMHELPER_EXCEPT_WITH_VAL,
-    SIMHELPER_PAUSE_SIM,
-    SIMHELPER_CYCLES,
-    SIMHELPER_SIGINT,
+    SIMHELPER_SC_STOP,                 // stop simulation
+    SIMHELPER_END_WITH_RETVAL,         // Not supported
+    SIMHELPER_EXCEPT_WITH_VAL,         // Not supported
+    SIMHELPER_PAUSE_SIM,               // Not supported
+    SIMHELPER_CYCLES,                  // Return number of cycles
+    SIMHELPER_SIGINT,                  // Not supported
 };
 
-///////////////////////////////////////////////////////////////////////////////////
-// SIM_HELPER access functions
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+// Accesses the Simulation Helper Component.
+// - If the access is on a write register, the simulation will stop.
+// - If the access is on a read register, value is written in retval buffer.
+////////////////////////////////////////////////////////////////////////////////
+extern void _sim_helper_access( unsigned int  register_index,
+                                unsigned int  value,
+                                unsigned int* retval ); 
 
-extern unsigned int _sim_helper_access( unsigned int  register_index,
-                                        unsigned int  value,
-                                        unsigned int* retval ); 
-
-///////////////////////////////////////////////////////////////////////////////////
 
 #endif
Index: soft/giet_vm/giet_drivers/spi_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/spi_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/spi_driver.c	(revision 437)
@@ -258,5 +258,5 @@
                unsigned int channel )
 {
-    _printf("\n[GIET ERROR] _spi_isr() not implemented\n");
+    _puts("\n[GIET ERROR] _spi_isr() not implemented\n");
     _exit();
 }
Index: soft/giet_vm/giet_drivers/tim_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/tim_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/tim_driver.c	(revision 437)
@@ -1,33 +1,12 @@
 //////////////////////////////////////////////////////////////////////////////////////
-// File     : timer_driver.c
+// File     : tim_driver.c
 // Date     : 23/05/2013
 // Author   : alain greiner
 // Copyright (c) UPMC-LIP6
 //////////////////////////////////////////////////////////////////////////////////////
-// The timer_driver.c and timer_driver.h files are part ot the GIET-VM nano-kernel.
-// This driver supports the SoCLib vci_multi_timer component.
-//
-// It can exist several multi_timers in the architecture (at most one per cluster),
-// and each one can contain several timers (called channels).
-//
-// There is two types of timers: 
-// - "system" timers : one per processor, used for context switch.
-//   local_id in [0, NB_PROCS_MAX-1],
-// - "user" timers : requested by the task in the mapping_info data structure.
-//   For each user timer, the timer_id is stored in the context of the task.
-// The global index is cluster_xy * (NB_PROCS_MAX + NB_TIM_CHANNELS) + local_id
-//
-// The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in hard_config.h file.
-//
-// The virtual base address of the segment associated to a channel is:
-//     SEG_TIM_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + TIMER_SPAN * timer_id
-//
-// The SEG_TIM_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h.
-/////////////////////////////////////////////////////////////////////////////////////
 
 #include <giet_config.h>
+#include <hard_config.h>
 #include <tim_driver.h>
-#include <xcu_driver.h>
-#include <tty_driver.h>
 #include <utils.h>
 
@@ -68,153 +47,109 @@
 #endif
 
-///////////////////  Timer global variables ////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+//                      global variables
+/////////////////////////////////////////////////////////////////////////////////
 
 #define in_unckdata __attribute__((section (".unckdata")))
 
 #if (NB_TIM_CHANNELS > 0)
-in_unckdata volatile unsigned char _user_timer_event[(1<<X_WIDTH)*(1<<Y_WIDTH)*NB_TIM_CHANNELS] 
-                        = { [0 ... (((1<<X_WIDTH)*(1<<Y_WIDTH)*NB_TIM_CHANNELS) - 1)] = 0 };
+in_unckdata volatile unsigned char _user_timer_event[NB_TIM_CHANNELS]
+                        = { [0 ... ((1<<NB_TIM_CHANNELS) - 1)] = 0 };
 #endif
 
-////////////////////////////////////////////////////////////////////////////////////
-// This function activates a timer in the vci_timer component
-// by writing in the proper register the period value.
-// It can be used by both the kernel to initialise a "system" timer,
-// or by a task (through a system call) to configure an "user" timer.
-///////////////////////////////////////////////////////////////////////////////////
-void _timer_start( unsigned int cluster_xy, 
-                   unsigned int local_id, 
-                   unsigned int period) 
+/////////////////////////////////////////////////////////////////////////////////
+//                      access functions
+/////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+unsigned int _timer_get_register( unsigned int channel,
+                                  unsigned int index )
+{
+    unsigned int* vaddr = (unsigned int*)SEG_TIM_BASE + channel*TIMER_SPAN + index;
+    return _io_extended_read( vaddr );
+}
+
+//////////////////////////////////////////////////////
+void _timer_set_register( unsigned int channel,
+                          unsigned int index,
+                          unsigned int value )
+{
+    unsigned int* vaddr = (unsigned int*)SEG_TIM_BASE + channel*TIMER_SPAN + index;
+    _io_extended_write( vaddr, value );
+}
+
+///////////////////////////////////////
+int _timer_start( unsigned int channel, 
+                  unsigned int period ) 
 {
 #if NB_TIM_CHANNELS
 
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
+    if ( channel >= NB_TIM_CHANNELS )
     {
-        _printf("[GIET ERROR] in _timer_start()\n");
-        _exit();
+        _puts("[GIET ERROR] in _timer_start()\n");
+        return -1;
     }
 
-    unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE +
-                                  (cluster_xy * PERI_CLUSTER_INCREMENT) );
-
-    timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
-    timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0x3;
+    _timer_set_register( channel, TIMER_PERIOD, period );
+    _timer_set_register( channel, TIMER_MODE  , 0x3 );
+    
+    return 0;
 
 #else
-    _printf("[GIET ERROR] _timer_start() should not be called when NB_TIM_CHANNELS is 0\n");
-    _exit();
+
+    _puts("[GIET ERROR] _timer_start() should not be called when NB_TIM_CHANNELS is 0\n");
+    return -1;
+
 #endif
 }
 
-//////////////////////////////////////////////////////////////////////////////
-// This function desactivates a timer in the vci_timer component
-// by writing in the proper register.
-// Returns 0 if success, > 0 if error.
-//////////////////////////////////////////////////////////////////////////////
-void _timer_stop( unsigned int cluster_xy, 
-                  unsigned int local_id) 
+///////////////////////////////////////
+int _timer_stop( unsigned int channel ) 
 {
 #if NB_TIM_CHANNELS
 
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
+    if ( channel >= NB_TIM_CHANNELS )
     {
-        _printf("[GIET ERROR] in _timer_stop()\n");
-        _exit();
+        _puts("[GIET ERROR] in _timer_stop()\n");
+        return -1;
     }
 
-    unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE +
-                                  (cluster_xy * PERI_CLUSTER_INCREMENT) );
+    _timer_set_register( channel, TIMER_MODE  , 0 );
 
-    timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0;
+    return 0;
 
 #else
-    _printf("[GIET ERROR] _timer_stop() should not be called when NB_TIM_CHANNELS is 0\n");
-    _exit();
+
+    _puts("[GIET ERROR] _timer_stop() should not be called when NB_TIM_CHANNELS is 0\n");
+    return -1;
+
 #endif
 }
 
-//////////////////////////////////////////////////////////////////////////////
-// This function acknowlegge a timer interrupt in the vci_timer  
-// component by writing in the proper register.
-// It can be used by both the isr_switch() for a "system" timer, 
-// or by the _isr_timer() for an "user" timer.
-// Returns 0 if success, > 0 if error.
-//////////////////////////////////////////////////////////////////////////////
-void _timer_reset_irq( unsigned int cluster_xy, 
-                       unsigned int local_id ) 
+////////////////////////////////////////////
+int _timer_reset_cpt( unsigned int channel ) 
 {
 #if NB_TIM_CHANNELS
 
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
+    if ( channel >= NB_TIM_CHANNELS )
     {
-        _printf("[GIET ERROR] in _timer_reset_irq()\n");
-        _exit();
+        _puts("[GIET ERROR in _timer_reset_cpt()\n");
+        return -1;
     }
 
-    unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE +
-                                  (cluster_xy * PERI_CLUSTER_INCREMENT) );
+    unsigned int period = _timer_get_register( channel, TIMER_PERIOD );
+    _timer_set_register( channel, TIMER_PERIOD, period );
 
-    timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0;
+    return 0;
 
 #else
-    _printf("[GIET ERROR] _timer_reset_irq() should not be called when NB_TIM_CHANNELS is 0\n");
-    _exit();
+
+    _puts("[GIET ERROR] _timer_reset_cpt should not be called when NB_TIM_CHANNELS is 0\n");
+    return -1;
+
 #endif
 }
 
-/////////////////////////////////////////////////////////////////////////////
-// This function resets the timer counter. To do so, we re-write the period
-// in the proper register, what causes the count to restart.
-// The period value is read from the same (TIMER_PERIOD) register,
-// this is why in appearance we do nothing useful (read a value
-// from a register and write this value in the same register)
-// This function is called during a context switch (user or preemptive)
-//////////////////////////////////////////////////////////////////////i//////
-void _timer_reset_cpt( unsigned int cluster_xy, 
-                       unsigned int local_id) 
-{
-#if NB_TIM_CHANNELS
-
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
-    {
-        _printf("[GIET ERROR in _timer_reset_cpt()\n");
-        _exit();
-    }
-
-    // We suppose that the TIMER_MODE register value is 0x3
-    unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE +
-                                  (cluster_xy * PERI_CLUSTER_INCREMENT) );
-
-    unsigned int period = timer_address[local_id * TIMER_SPAN + TIMER_PERIOD];
-    timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
-
-#else
-    _printf("[GIET ERROR] _timer_reset_cpt should not be called when NB_TIM_CHANNELS is 0\n");
-    _exit();
-#endif
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-// This ISR handles the IRQs generated by the "user" timers that are
-// replicated in all clusters.
-// The IRQs generated by the "system" timers should be handled by _isr_switch().
-// It can be a HWI or a PTI.
-// The channel argument is the user timer local index.
-//     timer_global_id = cluster_id*(NB_TIM_CHANNELS) + channel
-// The ISR acknowledges the IRQ and registers the event in the proper entry
-// of the _user_timer_event[] array, and a log message is displayed on TTY0.
-///////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////
 void _timer_isr( unsigned int irq_type,   // HWI / PTI
                  unsigned int irq_id,     // index returned by XCU
@@ -223,20 +158,19 @@
 #if NB_TIM_CHANNELS
 
-    unsigned int cluster_xy = _get_procid() >> P_WIDTH;
-
-    // acknowledge IRQ depending on type 
-    if   ( irq_type == IRQ_TYPE_HWI )  _timer_reset_irq( cluster_xy, channel );
-    else                               _xcu_timer_reset_irq( cluster_xy, irq_id );
+    // acknowledge IRQ
+    _timer_set_register( channel, TIMER_RESETIRQ, 0 ); 
 
     // register the event
-    _user_timer_event[cluster_xy * NB_TIM_CHANNELS + channel] = 1;
+    _user_timer_event[channel] = 1;
 
     // display a message on TTY 0 
-    _printf("\n[GIET WARNING] User Timer IRQ at cycle %d / cluster = %x / channel = %d\n",
-            _get_proctime(), cluster_xy, channel );
+    _puts("\n[GIET WARNING] User Timer IRQ at cycle %d for channel = %d\n",
+            _get_proctime(), channel );
 
 #else
-    _printf("[GIET ERROR] _timer_isr() should not be called when NB_TIM_CHANNELS == 0\n");
+
+    _puts("[GIET ERROR] _timer_isr() should not be called when NB_TIM_CHANNELS == 0\n");
     _exit();
+
 #endif
 }
Index: soft/giet_vm/giet_drivers/tim_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/tim_driver.h	(revision 436)
+++ soft/giet_vm/giet_drivers/tim_driver.h	(revision 437)
@@ -1,3 +1,3 @@
-///////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////
 // File     : tim_driver.h
 // Date     : 01/11/2013
@@ -5,4 +5,24 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
+// The tim_driver.c and tim_driver.h files are part ot the GIET-VM nano-kernel.
+// This driver supports the SoCLib vci_multi_timer component.
+//
+// It can exist several multi_timers in the architecture (at most one per cluster),
+// and each one can contain several timers (called channels).
+//
+// There is two types of timers: 
+// - "system" timers : one per processor, used for context switch.
+//   local_id in [0, NB_PROCS_MAX-1],
+// - "user" timers : requested by the task in the mapping_info data structure.
+//   For each user timer, the timer_id is stored in the context of the task.
+// The global index is cluster_xy * (NB_PROCS_MAX + NB_TIM_CHANNELS) + local_id
+//
+// The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in hard_config.h file.
+//
+// The virtual base address of the segment associated to a channel is:
+//     SEG_TIM_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + TIMER_SPAN * timer_id
+//
+// The SEG_TIM_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h.
+/////////////////////////////////////////////////////////////////////////////////////
 
 #ifndef _GIET_TIM_DRIVER_H_
@@ -10,5 +30,5 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-// TIMER (vci_multi_timer) registers offsets
+//                    registers offsets
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -24,25 +44,37 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-// Timer access functions and global variables
+//                   access functions 
 ///////////////////////////////////////////////////////////////////////////////////
 
-extern void _timer_start( unsigned int cluster_xy, 
-                          unsigned int local_id, 
-                          unsigned int period );
+///////////////////////////////////////////////////////////////////////////////////
+// This function activates a timer in the vci_timer external peripheral.
+// - channel : Timer channel global index
+// - period  : interrupt period (cycles)
+///////////////////////////////////////////////////////////////////////////////////
+extern int _timer_start( unsigned int channel, 
+                         unsigned int period );
 
-extern void _timer_stop( unsigned int cluster_xy,
-                         unsigned int local_id );
+///////////////////////////////////////////////////////////////////////////////////
+// This function desactivates a timer in the vci_timer external component.
+///////////////////////////////////////////////////////////////////////////////////
+extern int _timer_stop( unsigned int channel );
 
-extern void _timer_reset_irq( unsigned int cluster_xy, 
-                              unsigned int local_id );
+///////////////////////////////////////////////////////////////////////////////////
+// This function resets the timer counter. To do so, it read the period,
+// and re-write it in the timer register, what causes the count to restart.
+///////////////////////////////////////////////////////////////////////////////////
+extern int _timer_reset_cpt( unsigned int channel );
 
-extern void _timer_reset_cpt( unsigned int cluster_xy, 
-                              unsigned int local_id);
-
+///////////////////////////////////////////////////////////////////////////////////
+// This Interrupt Service Routine handles the IRQs generated by the "user" timers.
+// It can be a HWI or a PTI.
+// The channel argument is the user timer global index.
+// The ISR acknowledges the IRQ, registers the event in the proper entry
+// of the _user_timer_event[] array, and a log message is displayed on TTY0.
+///////////////////////////////////////////////////////////////////////////////////
 extern void _timer_isr( unsigned int irq_type,
                         unsigned int irq_id,
                         unsigned int channel );
 
-///////////////////////////////////////////////////////////////////////////////////
 
 #endif
Index: soft/giet_vm/giet_drivers/tty_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/tty_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/tty_driver.c	(revision 437)
@@ -5,25 +5,7 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The tty_driver.c and tty_drivers.h files are part ot the GIET-VM kernel.
-// This driver supports the SocLib vci_multi_tty component.
-//
-// The total number of TTY terminals must be defined by the configuration 
-// parameter NB_TTY_CHANNELS in the hard_config.h file.
-//
-// The "system" terminal is TTY[0].
-// The "user" TTYs are allocated to applications by the GIET in the boot phase,
-// as defined in the mapping_info data structure. The corresponding tty_id must 
-// be stored in the context of the task by the boot code.
-//
-// The SEG_TTY_BASE address must be defined in the hard_config.h file.
-///////////////////////////////////////////////////////////////////////////////////
-// Implementation note:
-// 
-// All physical accesses to device registers are done by the two
-// _tty_get_register(), _tty_set_register() low-level functions,
-// that are handling virtual / physical addressing.
-///////////////////////////////////////////////////////////////////////////////////
 
 #include <giet_config.h>
+#include <hard_config.h>
 #include <tty_driver.h>
 #include <xcu_driver.h>
@@ -48,5 +30,5 @@
 
 //////////////////////////////////////////////////////////////////////////////
-//   TTY global variables
+//                global variables
 //////////////////////////////////////////////////////////////////////////////
 
@@ -65,6 +47,8 @@
 
 //////////////////////////////////////////////////////////////////////////////
-// This low level function returns the value of register (channel / index)
+//               access functions
 //////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////
 unsigned int _tty_get_register( unsigned int channel,
                                 unsigned int index )
@@ -74,7 +58,5 @@
 }
 
-//////////////////////////////////////////////////////////////////////////////
-// This low level function set a new value in register (channel / index)  
-//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////
 void _tty_set_register( unsigned int channel,
                         unsigned int index,
@@ -85,113 +67,6 @@
 }
 
-/////////////////////////////////////////////////////////////////////////////////
-// This non-blocking function writes a character string from a fixed-length 
-// buffer to a TTY terminal identified by the channel argument. 
-// This function is intended to be used to handle a system call, and should
-// not be used by the kernel for log messages on TTY 0.
-// protecting exclusive access to the selected terminal.
-// If channel argument is 0xFFFFFFFF, the TTY index is found in the task context. 
-// This is a non blocking call: it tests the TTY_STATUS register, and stops
-// the transfer as soon as the TTY_STATUS[WRITE] bit is set. 
-/////////////////////////////////////////////////////////////////////////////////
-// Returns  the number of characters that have been written.
-/////////////////////////////////////////////////////////////////////////////////
-unsigned int _tty_write( const char*  buffer,    
-                         unsigned int length,    // number of characters
-                         unsigned int channel)   // channel index 
-{
-    unsigned int  nwritten;
 
-    // compute and check tty channel
-    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
-    if( channel >= NB_TTY_CHANNELS ) return -1;
-
-    // write string to TTY channel
-    for (nwritten = 0; nwritten < length; nwritten++) 
-    {
-        // check tty's status 
-        if ( _tty_get_register( channel, TTY_STATUS ) & 0x2 )  break;
-
-        // write one byte
-        if (buffer[nwritten] == '\n') {
-            _tty_set_register( channel, TTY_WRITE, (unsigned int)'\r' );
-        }
-        _tty_set_register( channel, TTY_WRITE, (unsigned int)buffer[nwritten] );
-    }
-    
-    return nwritten;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// This non-blocking function fetches one character from the 
-// terminal identified by the channel argument. If the channel argument 
-// is 0xFFFFFFFF, the channel index is obtained from the current task context. 
-// It uses the TTY_GET_IRQ[tty_id] interrupt and the buffer must have been
-// filled by the TTY_ISR.
-// It test the _tty_rx_full[tty_id] variable, read the _tty_rx_buf[tty_id] 
-// buffer, writes this character to the target buffer, and resets the
-// _tty_rx_full[tty_id] register.
-// The length argument is not used.
-//////////////////////////////////////////////////////////////////////////////
-// Returns  the number of characters that have been read (0/1).
-//////////////////////////////////////////////////////////////////////////////
-unsigned int _tty_read( char*        buffer, 
-                        unsigned int length,    // unused
-                        unsigned int channel)   // channel index
-{
-    // compute and check tty channel
-    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
-    if( channel >= NB_TTY_CHANNELS ) return -1;
-
-    // read one character from TTY channel
-    if (_tty_rx_full[channel] == 0) 
-    {
-        return 0;
-    }
-    else 
-    {
-        *buffer = _tty_rx_buf[channel];
-        _tty_rx_full[channel] = 0;
-        return 1;
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// This function try to take the lock protecting 
-// exclusive access to TTY terminal identified by the "channel" argument.
-// It enters a critical section before taking the lock, and save the SR value
-// at address defined by the "save_sr_ptr" argument.
-// It returns only when the lock has been successfully taken.
-//////////////////////////////////////////////////////////////////////////////
-void _tty_get_lock( unsigned int   channel,
-                    unsigned int * save_sr_ptr )
-{
-    if( channel >= NB_TTY_CHANNELS ) _exit();
-    _it_disable( save_sr_ptr );
-    _get_lock( &_tty_lock[channel] );
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// This function releases the hardwired lock protecting 
-// exclusive access to TTY terminal identified by the channel argument.
-// It exit the critical section after lock release, and restore SR value
-// from address defined by the "save_sr_ptr" argument.
-//////////////////////////////////////////////////////////////////////////////
-void _tty_release_lock( unsigned int   channel,
-                        unsigned int * save_sr_ptr )
-{
-    if( channel >= NB_TTY_CHANNELS ) _exit();
-    _release_lock( &_tty_lock[channel] );
-    _it_restore( save_sr_ptr );
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-// This ISR handles the IRQ signaling that the RX buffer is not empty.
-// IT can be an HWI or an SWI.
-// There is one communication buffer _tty_rx_buf[i] and one synchronisation
-// variable _tty_rx_full[i] per channel.
-// 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
                   unsigned int irq_id,     // index returned by XCU
@@ -242,12 +117,5 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////////
-// This ISR handles the IRQ signaling that the TX buffer is 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.
-///////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////
 void _tty_tx_isr( unsigned int irq_type,   // HWI / WTI
                   unsigned int irq_id,     // index returned by XCU
Index: soft/giet_vm/giet_drivers/tty_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/tty_driver.h	(revision 436)
+++ soft/giet_vm/giet_drivers/tty_driver.h	(revision 437)
@@ -5,12 +5,27 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
+// The tty_driver.c and tty_drivers.h files are part ot the GIET-VM kernel.
+// This driver supports the SocLib vci_multi_tty component.
+//
+// The total number of TTY terminals must be defined by the configuration 
+// parameter NB_TTY_CHANNELS in the hard_config.h file.
+//
+// The "system" terminal is TTY[0].
+// The "user" TTYs are allocated to applications requesting it.
+//
+// The SEG_TTY_BASE address must be defined in the hard_config.h file.
+//
+// All physical accesses to device registers are done by the two
+// _tty_get_register(), _tty_set_register() low-level functions,
+// that are handling virtual / physical addressing.
+///////////////////////////////////////////////////////////////////////////////////
 
 #ifndef _GIET_TTY_DRIVERS_H_
 #define _GIET_TTY_DRIVERS_H_
 
-#include "utils.h"
+#include <utils.h>
 
 ///////////////////////////////////////////////////////////////////////////////////
-// TTY (vci_multi_tty) registers offsets
+//                     registers offsets
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -26,5 +41,5 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-// TTY variables
+//                   external variables
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -36,20 +51,17 @@
 
 //////////////////////////////////////////////////////////////////////////////////
-// TTY access functions
+//                    access functions
 //////////////////////////////////////////////////////////////////////////////////
 
-extern unsigned int _tty_write( const char*  buffer,
-                                unsigned int length,     
-                                unsigned int channel );  
+extern unsigned int _tty_get_register( unsigned int channel,
+                                       unsigned int index );
 
-extern unsigned int _tty_read(  char*        buffer,
-                                unsigned int length,  
-                                unsigned int channel ); 
+extern void _tty_set_register( unsigned int channel,
+                               unsigned int index,
+                               unsigned int value );
 
-extern void _tty_get_lock( unsigned int  channel, 
-                           unsigned int* save_sr_ptr );
-
-extern void _tty_release_lock( unsigned int  channel,
-                               unsigned int* save_sr_ptr );
+///////////////////////////////////////////////////////////////////////////////////
+//                 Interrupt Service Routine 
+///////////////////////////////////////////////////////////////////////////////////
 
 extern void _tty_rx_isr( unsigned int irq_type,
@@ -61,14 +73,4 @@
                          unsigned int channel );
 
-///////////////////////////////////////////////////////////////////////////////////
-// low-level access functions
-///////////////////////////////////////////////////////////////////////////////////
-
-extern unsigned int _tty_get_register( unsigned int channel,
-                                       unsigned int index );
-
-extern void _tty_set_register( unsigned int channel,
-                               unsigned int index,
-                               unsigned int value );
 
 #endif
Index: soft/giet_vm/giet_drivers/xcu_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/xcu_driver.c	(revision 436)
+++ soft/giet_vm/giet_drivers/xcu_driver.c	(revision 437)
@@ -4,8 +4,4 @@
 // Author   : alain greiner
 // Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
-// This peripheral is replicated in all clusters containing processors.
-//
-// SEG_XCU_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h file.
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -85,9 +81,5 @@
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// This function set the mask register for the IRQ type defined by "irq_type",
-// and for the channel identified by the "cluster_xy" and "channel" arguments.
-// All '1' bits are set / all '0' bits are not modified.
-////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////
 void _xcu_set_mask( unsigned int cluster_xy, 
                     unsigned int channel,  
@@ -109,5 +101,5 @@
     else
     { 
-        _printf("[GIET ERROR] _xcu_set_mask() receives illegal IRQ type\n");
+        _puts("[GIET ERROR] _xcu_set_mask() receives illegal IRQ type\n");
         _exit();
     }
@@ -116,17 +108,10 @@
 
 #else
-    _printf("[GIET ERROR] _xcu_set_mask() should not be used if USE_XCU not set\n");
-    _exit();
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// This function returns the index and the type of the highest priority 
-// - active PTI (Timer Interrupt), then
-// - active HWI (Hardware Interrupt), then
-// - active WTI (Software Interrupt)
-// As the hardware can define more than one IRQ per processor, but the GIET
-// use only one, channel = lpid * IRQ_PER_PROCESSOR.
-////////////////////////////////////////////////////////////////////////////////
+    _puts("[GIET ERROR] _xcu_set_mask() should not be used if USE_XCU not set\n");
+    _exit();
+#endif
+}
+
+/////////////////////////////////////////////
 void _xcu_get_index( unsigned int cluster_xy, 
                      unsigned int channel,   
@@ -170,13 +155,10 @@
  
 #else
-    _printf("[GIET ERROR] _xcu_get_index should not be used if USE_XCU is not set\n");
-    _exit();
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// This function writes the "wdata" value in the mailbox defined 
-// by the "cluster_xy" and "wti_index" arguments.
-////////////////////////////////////////////////////////////////////////////////
+    _puts("[GIET ERROR] _xcu_get_index should not be used if USE_XCU is not set\n");
+    _exit();
+#endif
+}
+
+////////////////////////////////////////////
 void _xcu_send_wti( unsigned int cluster_xy,
                     unsigned int wti_index,
@@ -194,15 +176,10 @@
 
 #else
-    _printf("[GIET ERROR] _xcu_send_wti() should not be used if USE_XCU is not set\n");
+    _puts("[GIET ERROR] _xcu_send_wti() should not be used if USE_XCU is not set\n");
     _exit();
 #endif
 } 
 
-////////////////////////////////////////////////////////////////////////////////
-// This function returns the value contained in a WTI mailbox defined by
-// the cluster_xy and "wti_index" arguments. This value is written in
-// the "value" argument, and the corresponding WTI is acknowledged.
-// returns 0 if success, > 0 if error.
-////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////
 void _xcu_get_wti_value( unsigned int   cluster_xy,
                          unsigned int   wti_index,
@@ -220,16 +197,10 @@
 
 #else
-    _printf("[GIET ERROR] in _xcu_get_wti_value() USE_XCU is not set\n");
-    _exit();
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// This function returns the address of a WTI mailbox defined by
-// the "wti_index" argument, in the unsigned int "address" argument.
-// It is used by the GIET to configurate the IOPIC component.
-// There is no access to a specific XCU component in a specific cluster.
-// returns 0 if success, > 0 if error.
-////////////////////////////////////////////////////////////////////////////////
+    _puts("[GIET ERROR] in _xcu_get_wti_value() USE_XCU is not set\n");
+    _exit();
+#endif
+}
+
+////////////////////////////////////////////////////
 void _xcu_get_wti_address( unsigned int   wti_index,
                            unsigned int * address )
@@ -241,13 +212,10 @@
 
 #else
-    _printf("[GIET ERROR] in _xcu_get_wti_address() USE_XCU is not set\n");
-    _exit();
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// This function activates a timer contained in XCU by writing in the
-// proper register the period value.
-////////////////////////////////////////////////////////////////////////////////
+    _puts("[GIET ERROR] in _xcu_get_wti_address() USE_XCU is not set\n");
+    _exit();
+#endif
+}
+
+///////////////////////////////////////////////
 void _xcu_timer_start( unsigned int cluster_xy,
                        unsigned int pti_index,
@@ -264,13 +232,10 @@
 
 #else
-    _printf("[GIET ERROR] in _xcu_timer_start() USE_XCU is not set\n");
-    _exit();
-#endif
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// This function desactivates a timer in XCU component
-// by writing in the proper register.
-//////////////////////////////////////////////////////////////////////////////
+    _puts("[GIET ERROR] in _xcu_timer_start() USE_XCU is not set\n");
+    _exit();
+#endif
+}
+
+//////////////////////////////////////////////
 void _xcu_timer_stop( unsigned int cluster_xy, 
                       unsigned int pti_index) 
@@ -286,15 +251,10 @@
 
 #else
-    _printf("[GIET ERROR] in _xcu_timer_stop() USE_XCU is not set\n");
-    _exit();
-#endif
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// This function acknowlegge a timer interrupt in XCU 
-// component by reading in the proper XCU register.
-// It can be used by both the isr_switch() for a "system" timer, 
-// or by the _isr_timer() for an "user" timer.
-//////////////////////////////////////////////////////////////////////////////
+    _puts("[GIET ERROR] in _xcu_timer_stop() USE_XCU is not set\n");
+    _exit();
+#endif
+}
+
+///////////////////////////////////////////////////////////
 unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy, 
                                    unsigned int pti_index ) 
@@ -311,5 +271,5 @@
 
 #else
-    _printf("[GIET ERROR] in _xcu_timer_reset_irq() USE_XCU is not set\n");
+    _puts("[GIET ERROR] in _xcu_timer_reset_irq() USE_XCU is not set\n");
     _exit();
     return 0;
@@ -317,12 +277,5 @@
 }
 
-//////////////////////////////////////////////////////////////////////////////
-// This function resets a timer counter. To do so, we re-write the period
-// in the proper register, what causes the count to restart.
-// The period value is read from the same (TIMER_PERIOD) register,
-// this is why in appearance we do nothing useful (read a value
-// from a register and write this value in the same register).
-// This function is called during a context switch (user or preemptive)
-/////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////
 void _xcu_timer_reset_cpt( unsigned int cluster_xy, 
                            unsigned int pti_index ) 
@@ -343,5 +296,5 @@
 
 #else
-    _printf("[GIET ERROR] in _xcu_timer_reset_cpt() USE_XCU is not set\n");
+    _puts("[GIET ERROR] in _xcu_timer_reset_cpt() USE_XCU is not set\n");
     _exit();
 #endif
Index: soft/giet_vm/giet_drivers/xcu_driver.h
===================================================================
--- soft/giet_vm/giet_drivers/xcu_driver.h	(revision 436)
+++ soft/giet_vm/giet_drivers/xcu_driver.h	(revision 437)
@@ -7,17 +7,21 @@
 // The xcu_driver.c and xcu_driver.h files are part ot the GIET-VM nano-kernel.
 // This driver supports the SoCLib vci_xicu, that is a vectorised interrupt
-// controler supporting IPI (Inter Processor Interrupts) and integrated timers.
+// controler supporting three types of interrupts:
+//
+// - HWI : HardWare Interrupts (from hardware peripherals)
+// - PTI : Programmable Timer Interrupts (contained in the XCU component)
+// - WTI : Write Trigered Interrupts (from software, or from a PIC controller) 
 //
 // It can exist several interrupt controller unit in the architecture 
-// (one per cluster), and each one can contain several channels.
+// (one per cluster), and each one can contain several channels:
 // The number of XICU channels is equal to NB_PROCS_MAX, because there is 
 // one private XICU channel per processor in a cluster.
-////////////////////////////////////////////////////////////////////////////////
+//
 // The virtual base address of the segment associated to the component is:
 //
-//      seg_xcu_base + cluster_xy * vseg_cluster_increment
+//      vbase = SEG_XCU_BASE + cluster_xy * PERI_CLUSTER_INCREMENT
 //
-// The seg_xcu_base and vseg_cluster_increment values must be defined 
-// in giet_vsegs.ld file.
+// The SEG_XCU_BSE  and PERI_CLUSTER_INCREMENT values must be defined 
+// in the hard_config.h file.
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -56,8 +60,13 @@
 #define XCU_REG(func, index) (((func)<<5)|(index))
  
-///////////////////////////////////////////////////////////////////////////////////
-// XICU access functions 
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+//                           access functions 
+////////////////////////////////////////////////////////////////////////////////
 
+////////////////////////////////////////////////////////////////////////////////
+// This function set the mask register for the IRQ type defined by "irq_type",
+// and for the channel identified by the "cluster_xy" and "channel" arguments.
+// All '1' bits are set / all '0' bits are not modified.
+////////////////////////////////////////////////////////////////////////////////
 extern void _xcu_set_mask( unsigned int cluster_xy,
                            unsigned int channel,  
@@ -65,4 +74,10 @@
                            unsigned int irq_type );
 
+////////////////////////////////////////////////////////////////////////////////
+// This function returns the index and the type of the highest priority 
+// - active PTI (Timer Interrupt), then
+// - active HWI (Hardware Interrupt), then
+// - active WTI (Software Interrupt)
+////////////////////////////////////////////////////////////////////////////////
 extern void _xcu_get_index( unsigned int   cluster_xy, 
                             unsigned int   channel,   
@@ -70,29 +85,64 @@
                             unsigned int * irq_type );
 
+////////////////////////////////////////////////////////////////////////////////
+// This function writes the "wdata" value in the mailbox defined 
+// by the "cluster_xy" and "wti_index" arguments.
+////////////////////////////////////////////////////////////////////////////////
 extern void _xcu_send_wti( unsigned int cluster_xy,
                            unsigned int wti_index,
                            unsigned int wdata );
 
+////////////////////////////////////////////////////////////////////////////////
+// This function returns the value contained in a WTI mailbox defined by
+// the cluster_xy and "wti_index" arguments. This value is written in
+// the "value" argument, and the corresponding WTI is acknowledged.
+////////////////////////////////////////////////////////////////////////////////
 extern void _xcu_get_wti_value( unsigned int   cluster_xy,
                                 unsigned int   wti_index,
                                 unsigned int * value );
 
+////////////////////////////////////////////////////////////////////////////////
+// This function returns the address of a WTI mailbox defined by
+// the "wti_index" argument, in the unsigned int "address" argument.
+// It is used by the GIET to configurate the IOPIC component.
+// There is no access to a specific XCU component in a specific cluster.
+////////////////////////////////////////////////////////////////////////////////
 extern void _xcu_get_wti_address( unsigned int   wti_index,
                                   unsigned int * address );
 
+////////////////////////////////////////////////////////////////////////////////
+// This function activates a timer contained in XCU by writing in the
+// proper register the period value.
+////////////////////////////////////////////////////////////////////////////////
 extern void _xcu_timer_start( unsigned int cluster_xy, 
                               unsigned int pti_index,
                               unsigned int period ); 
 
+//////////////////////////////////////////////////////////////////////////////
+// This function desactivates a timer in XCU component
+// by writing in the proper register.
+//////////////////////////////////////////////////////////////////////////////
 extern void _xcu_timer_stop( unsigned int cluster_xy, 
                              unsigned int pti_index ); 
 
+//////////////////////////////////////////////////////////////////////////////
+// This function acknowlegge a timer interrupt in XCU 
+// component by reading in the proper XCU register.
+// It can be used by both the isr_switch() for a "system" timer, 
+// or by the _isr_timer() for an "user" timer.
+//////////////////////////////////////////////////////////////////////////////
 extern unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy, 
                                           unsigned int pti_index );
 
+//////////////////////////////////////////////////////////////////////////////
+// This function resets a timer counter. To do so, we re-write the period
+// in the proper register, what causes the count to restart.
+// The period value is read from the same (TIMER_PERIOD) register,
+// this is why in appearance we do nothing useful (read a value
+// from a register and write this value in the same register).
+// This function is called during a context switch (user or preemptive)
+/////////////////////////////////////////////////////////////////////////////
 extern void _xcu_timer_reset_cpt( unsigned int cluster_xy, 
                                   unsigned int pti_index ); 
-
-///////////////////////////////////////////////////////////////////////////////////
 
 #endif
