Index: /soft/giet_vm/giet_common/utils.c
===================================================================
--- /soft/giet_vm/giet_common/utils.c	(revision 343)
+++ /soft/giet_vm/giet_common/utils.c	(revision 344)
@@ -330,17 +330,18 @@
 
     _it_disable(&sr);
-    asm volatile(
-            "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
-            "andi   $3,     $2,        0xb     \n"
-            "mtc2   $3,     $1                 \n"     /* DTLB off         */    
-
-            "mtc2   %2,     $24                \n"     /* PADDR_EXT <= msb */   
-            "lw     %0,     0(%1)              \n"     /* value <= *paddr  */
-            "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0   */   
-
-            "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
-            : "=r" (value)
-            : "r" (lsb), "r" (msb)
-            : "$2", "$3");
+
+    asm volatile( "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
+                  "andi   $3,     $2,        0xb     \n"
+                  "mtc2   $3,     $1                 \n"     /* DTLB off         */    
+
+                  "mtc2   %2,     $24                \n"     /* PADDR_EXT <= msb */   
+                  "lw     %0,     0(%1)              \n"     /* value <= *paddr  */
+                  "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0   */   
+
+                  "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
+                  : "=r" (value)
+                  : "r" (lsb), "r" (msb)
+                  : "$2", "$3" );
+
     _it_restore(&sr);
     return value;
@@ -358,17 +359,74 @@
 
     _it_disable(&sr);
-    asm volatile(
-            "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
-            "andi   $3,     $2,        0xb     \n"
-            "mtc2   $3,     $1                 \n"     /* DTLB off         */    
-
-            "mtc2   %2,     $24                \n"     /* PADDR_EXT <= msb */   
-            "sw     %0,     0(%1)              \n"     /* *paddr <= value  */
-            "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0   */   
-
-            "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
-            :
-            : "r" (value), "r" (lsb), "r" (msb)
-            : "$2", "$3");
+
+    asm volatile( "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
+                  "andi   $3,     $2,        0xb     \n"
+                  "mtc2   $3,     $1                 \n"     /* DTLB off         */    
+
+                  "mtc2   %2,     $24                \n"     /* PADDR_EXT <= msb */   
+                  "sw     %0,     0(%1)              \n"     /* *paddr <= value  */
+                  "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0   */   
+
+                  "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
+                  :
+                  : "r" (value), "r" (lsb), "r" (msb)
+                  : "$2", "$3" );
+
+    _it_restore(&sr);
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// This function makes a memcpy from a source buffer to a destination buffer
+// using physical addresses, after a temporary DTLB de-activation.
+// source and destination buffers must be aligned, and size must be
+// multiple of 4 bytes. 
+///////////////////////////////////////////////////////////////////////////////////
+inline void _physical_memcpy( unsigned long long dst_paddr,  // dest buffer paddr
+                              unsigned long long src_paddr,  // source buffer paddr
+                              unsigned int size )            // bytes
+{
+    // check alignment constraints
+    if ( (dst_paddr & 3) || (src_paddr & 3) || (size & 3) ) 
+    {
+        _printf("\n[GIET ERROR] in _physical_memcpy() : buffer unaligned\n");
+        _exit();
+    }
+
+    unsigned int src_lsb = (unsigned int)src_paddr;
+    unsigned int src_msb = (unsigned int)(src_paddr >> 32);
+    unsigned int dst_lsb = (unsigned int)dst_paddr;
+    unsigned int dst_msb = (unsigned int)(dst_paddr >> 32);
+    unsigned int iter    = size>>2;
+    unsigned int data;
+    unsigned int sr;
+
+    _it_disable(&sr);
+
+    asm volatile( "mfc2   $2,     $1                 \n"     /* $2 <= current MMU_MODE */
+                  "andi   $3,     $2,        0xb     \n"     /* $3 <= new MMU_MODE     */
+                  "mtc2   $3,     $1                 \n"     /* DTLB off               */    
+
+                  "move   $4,     %5                 \n"     /* $4 < iter              */
+                  "move   $5,     %1                 \n"     /* $5 < src_lsb           */
+                  "move   $6,     %3                 \n"     /* $6 < src_lsb           */
+
+                  "ph_memcpy_loop:                   \n"
+                  "mtc2   %2,     $24                \n"     /* PADDR_EXT <= src_msb   */   
+                  "lw     %0,     0($5)              \n"     /* data <= *src_paddr     */
+                  "mtc2   %4,     $24                \n"     /* PADDR_EXT <= dst_msb   */   
+                  "sw     %0,     0($6)              \n"     /* *dst_paddr <= data     */
+
+                  "addi   $4,     $4,       -1       \n"     /* iter = iter - 1        */
+                  "addi   $5,     $5,        4       \n"     /* src_lsb += 4           */
+                  "addi   $6,     $6,        4       \n"     /* dst_lsb += 4           */
+                  "bne    $4,     $0, ph_memcpy_loop \n"
+                  "nop                               \n"
+
+                  "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0         */   
+                  "mtc2   $2,     $1                 \n"     /* restore MMU_MODE       */
+                  : "=r" (data)
+                  : "r" (src_lsb), "r" (src_msb), "r" (dst_lsb), "r"(dst_msb), "r"(iter)
+                  : "$2", "$3", "$4", "$5", "$6" );
+
     _it_restore(&sr);
 }
Index: /soft/giet_vm/giet_common/utils.h
===================================================================
--- /soft/giet_vm/giet_common/utils.h	(revision 343)
+++ /soft/giet_vm/giet_common/utils.h	(revision 344)
@@ -120,4 +120,8 @@
 extern void         _physical_write( unsigned long long paddr,
                                      unsigned int       value );
+
+extern void         _physical_memcpy( unsigned long long dst_paddr,
+                                      unsigned long long src_paddr,
+                                      unsigned int       size );
 
 extern unsigned int _io_extended_read(  unsigned int* vaddr );
