Index: soft/giet_vm/giet_drivers/dma_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/dma_driver.c	(revision 333)
+++ soft/giet_vm/giet_drivers/dma_driver.c	(revision 343)
@@ -152,18 +152,11 @@
 // and sets the transfer size to lauch the transfer.
 //////////////////////////////////////////////////////////////////////////////////
-unsigned int _dma_start_transfer( unsigned int       cluster_xy,
-                                  unsigned int       channel_id,
-                                  unsigned long long dst_paddr,   // physical address
-                                  unsigned long long src_paddr,   // physical address
-                                  unsigned int       size )       // bytes
-{
-#if NB_DMA_CHANNELS > 0
-
-    // 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 (channel_id >= NB_DMA_CHANNELS)  return 1;
+void _dma_start_transfer( unsigned int       cluster_xy,  // DMA cluster
+                          unsigned int       channel_id,  // DMA channel
+                          unsigned long long dst_paddr,   // physical address
+                          unsigned long long src_paddr,   // physical address
+                          unsigned int       size )       // bytes
+{
+#if NB_DMA_CHANNELS > 0
 
     // compute DMA base address
@@ -177,15 +170,14 @@
     dma_address[channel_id * DMA_SPAN + DMA_DST_EXT] = (unsigned int)(dst_paddr>>32);
     dma_address[channel_id * DMA_SPAN + DMA_LEN]     = (unsigned int)size;
-    return 0;
-#else
-    return 1;
-#endif
-}
-///////////////////////////////////////////////////////////////////////////////////
-// This function copies a source memory buffer to a destination memory buffer, 
-// using the distributed DMA. As it makes virtual to physical address translation, 
-// the MMU should be activated. 
-// This driver makes the assumption that each processor has a private DMA channel: 
-// the DMA cluster and channel indexes are obtained from the processor index.
+
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// 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.
@@ -193,90 +185,38 @@
 // message is displayed on TTY0, and the system crash.
 ///////////////////////////////////////////////////////////////////////////////////
-// Note: 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.
-///////////////////////////////////////////////////////////////////////////////////
-inline void  _dma_copy( unsigned int vspace_id, // vspace index for V2P
-                        void*        dest,      // dest buffer vbase
-                        const void*  source,    // source buffer vbase
-                        unsigned int size )     // bytes
-{
-#if NB_DMA_CHANNELS > 0
-
-    unsigned int procid     = _get_procid();
-    unsigned int cluster_xy = procid/NB_PROCS_MAX;
-    unsigned int channel_id = procid%NB_PROCS_MAX;
-
-    unsigned int ko;
-    unsigned int ppn;
-    unsigned int flags;
-
-#if GIET_DEBUG_DMA_DRIVER
-unsigned int x          = cluster_xy >> Y_WIDTH;
-unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
-
-_printf("\n[DMA DEBUG] Processor[%d,%d,%d] enters _dma_copy() at cycle %d\n"
-        " - vspace_id   = %d\n"
-        " - src_vaddr   = %x\n"
-        " - dst_vaddr   = %x\n"
+void _dma_physical_copy( unsigned int       cluster_xy,  // DMA cluster
+                         unsigned int       channel_id,  // DMA channel
+                         unsigned long long dst_paddr,   // destination physical address
+                         unsigned long long src_paddr,   // source physical address
+                         unsigned int       size )       // bytes
+{
+#if NB_DMA_CHANNELS > 0
+
+    // check DMA channel parameters 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (channel_id >= NB_DMA_CHANNELS) )
+    {
+        _printf("\n[GIET ERROR] in _dma_physical_copy() : illegal DMA channel ");
+        _exit();
+    }
+
+    // check buffers alignment constraints
+    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(), vspace_id, 
-        (unsigned int)source, (unsigned int)dest, size );
-#endif
-
-    // checking alignment constraints
-    if ( (((unsigned int)dest) & 0x3)   ||
-         (((unsigned int)source) & 0x3) ||
-         (size & 0x3) )
-    {
-        _printf("\n[GIET ERROR] in _dma_copy() : buffer unaligned\n");
-        _exit();
-    }
-
-    // get vspace 0 page table pointer 
-    unsigned int pt =  _ptabs_vaddr[vspace_id];
-
-    // get source buffer physical addresse
-    ko = _v2p_translate( (page_table_t*)pt,              // page table pointer
-                         ((unsigned int)source)>>12,     // vpn 
-                         &ppn,                           // ppn
-                         &flags );                       // flags
-    if ( ko ) 
-    {
-        _printf("\n[GIET ERROR] in _dma_copy() : source buffer unmapped\n");
-        _exit();
-    }
-    unsigned long long src_paddr = (((unsigned long long)ppn) << 12) | 
-                                   ((unsigned int)source & 0x00000FFF);
-
-    // get dest buffer physical addresse
-    ko = _v2p_translate( (page_table_t*)pt,              // page table pointer
-                         ((unsigned int)dest)>>12,       // vpn 
-                         &ppn,                           // ppn
-                         &flags );                       // flags
-    if ( ko ) 
-    {
-        _printf("\n[GIET ERROR] in _dma_copy() : dest buffer unmapped\n");
-        _exit();
-    }
-    unsigned long long dst_paddr = (((unsigned long long)ppn) << 12) | 
-                                   ((unsigned int)dest & 0x00000FFF);
-
-#if GIET_DEBUG_DMA_DRIVER
-_printf(" - src_paddr   = %l\n"
-        " - dst_paddr   = %l\n",
-        src_paddr, dst_paddr );
-#endif
-
-    // invalidate L1 cache if no hardware cache coherence
-    if ( GIET_NO_HARD_CC ) _dcache_buf_invalidate( dest, size );
+        x, y, channel_id, _get_proctime(), src_paddr, dst_paddr, size );
+#endif
 
     // dma channel configuration & lauching
-    ko = _dma_start_transfer(  cluster_xy, channel_id, dst_paddr, src_paddr, size ); 
-    if ( ko ) 
-    {
-        _printf("\n[GIET ERROR] in _dma_copy() : cannot start transfer\n");
-        _exit();
-    }
+    _dma_start_transfer( cluster_xy, channel_id, dst_paddr, src_paddr, size ); 
 
     // scan dma channel status 
@@ -289,5 +229,134 @@
 
 #if GIET_DEBUG_DMA_DRIVER
-_printf("\n[DMA DEBUG] _dma_copy() : ... waiting on DMA_STATUS register ...\n");
+_printf("\n[DMA DEBUG] _dma_physical_copy() : ... waiting on DMA_STATUS register\n");
+#endif
+
+    }
+    
+    // analyse status
+    if( status != DMA_SUCCESS )
+    {
+        _printf("\n[GIET ERROR] in _dma_physical_copy() : DMA_STATUS = %x\n", 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() );
+#endif
+
+#else // NB_DMA_CHANNELS == 0
+    _printf("\n[GIET ERROR] in _dma_physical_copy() : NB_DMA_CHANNELS == 0 / cycle %d\n",
+            _get_proctime );
+    _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.
+///////////////////////////////////////////////////////////////////////////////////
+void  _dma_copy( unsigned int cluster_xy,    // DMA cluster
+                 unsigned int channel_id,    // DMA channel
+                 unsigned int vspace_id,     // vspace index for v2p translation
+                 unsigned int dst_vaddr,     // dst_vaddr buffer vbase
+                 unsigned int src_vaddr,     // src_vaddr buffer vbase
+                 unsigned int size )         // bytes
+{
+#if NB_DMA_CHANNELS > 0
+
+    // check DMA channel parameters 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (channel_id >= NB_DMA_CHANNELS) )
+    {
+        _printf("\n[GIET ERROR] in _dma_copy() : illegal DMA channel ");
+        _exit();
+    }
+
+    // check buffers alignment constraints
+    if ( (dst_vaddr & 0x3)   || (src_vaddr & 0x3) || (size & 0x3) )
+    {
+        _printf("\n[GIET ERROR] in _dma_copy() : buffer unaligned\n");
+        _exit();
+    }
+
+    unsigned int ko;
+    unsigned int ppn;
+    unsigned int flags;
+
+#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 );
+#endif
+
+    // checking alignment constraints
+    if ( (((unsigned int)dst_vaddr) & 0x3) ||
+         (((unsigned int)src_vaddr) & 0x3) ||
+         (size & 0x3) )
+    {
+        _printf("\n[GIET ERROR] in _dma_copy() : buffer unaligned\n");
+        _exit();
+    }
+
+    // get vspace page table pointer 
+    unsigned int pt =  _ptabs_vaddr[vspace_id];
+
+    // get src_paddr buffer physical addresse
+    ko = _v2p_translate( (page_table_t*)pt,              // page table pointer
+                         src_vaddr>>12,                  // vpn 
+                         &ppn,                           // ppn
+                         &flags );                       // flags
+    if ( ko ) 
+    {
+        _printf("\n[GIET ERROR] in _dma_copy() : source buffer unmapped\n");
+        _exit();
+    }
+    unsigned long long src_paddr = (((unsigned long long)ppn) << 12) | 
+                                   (unsigned long long)(src_vaddr & 0x00000FFF);
+
+    // get dst_paddr buffer physical addresse
+    ko = _v2p_translate( (page_table_t*)pt,              // page table pointer
+                         dst_vaddr>>12,                  // vpn 
+                         &ppn,                           // ppn
+                         &flags );                       // flags
+    if ( ko ) 
+    {
+        _printf("\n[GIET ERROR] in _dma_copy() : dest buffer unmapped\n");
+        _exit();
+    }
+    unsigned long long dst_paddr = (((unsigned long long)ppn) << 12) | 
+                                   (unsigned long long)(dst_vaddr & 0x00000FFF);
+
+#if GIET_DEBUG_DMA_DRIVER
+_printf(" - src_paddr   = %l\n"
+        " - dst_paddr   = %l\n",
+        src_paddr, dst_paddr );
+#endif
+
+    // dma channel configuration & lauching
+    _dma_start_transfer(  cluster_xy, channel_id, dst_paddr, src_paddr, size ); 
+
+    // scan dma channel status 
+    unsigned int status = _dma_get_status( cluster_xy, channel_id );
+    while( (status != DMA_SUCCESS) && 
+           (status != DMA_READ_ERROR) &&
+           (status != DMA_WRITE_ERROR) )
+    {
+        status = _dma_get_status( cluster_xy, channel_id );
+
+#if GIET_DEBUG_DMA_DRIVER
+_printf("\n[DMA DEBUG] _dma_copy() : ... waiting on DMA_STATUS register\n");
 #endif
 
