Index: soft/giet_vm/giet_common/utils.c
===================================================================
--- soft/giet_vm/giet_common/utils.c	(revision 378)
+++ soft/giet_vm/giet_common/utils.c	(revision 399)
@@ -22,117 +22,7 @@
 extern static_scheduler_t* _schedulers[NB_PROCS_MAX<<(X_WIDTH+Y_WIDTH)];
 
-///////////////////////////////////////////////////////////////////////////////////
-// This function implements a pseudo-random delay.
-// The val argument define approximately an exponentially increasing mean delay,
-// and should not be larger than 32.
-///////////////////////////////////////////////////////////////////////////////////
-void _random_wait( unsigned int val )
-{
-    unsigned int mask  = (1<<(val&0x1F))-1;
-    unsigned int delay = (_get_proctime() ^ (_get_procid()<<4)) & mask;
-    asm volatile( "move  $3,   %0                 \n"
-                  "loop_nic_completed:            \n"
-                  "addi  $3,   $3, -1             \n"
-                  "bnez  $3,   loop_nic_completed \n"
-                  "nop                            \n"
-                  :
-                  : "r" (delay)
-                  : "$3" ); 
-}
-///////////////////////////////////////////////////////////////////////////////////
-// Copy a source memory buffer content to a dest memory buffer (size bytes)
-// Code taken from MutekH.
-///////////////////////////////////////////////////////////////////////////////////
-void* memcpy( void*        dest,     // dest buffer vbase
-                     const void*  source,   // source buffer vbase
-                     unsigned int size )    // bytes
-{
-    unsigned int* idst = (unsigned int*)dest;
-    unsigned int* isrc = (unsigned int*)source;
-
-    // word-by-word copy
-    if (!((unsigned int) idst & 3) && !((unsigned int) isrc & 3)) 
-    {
-        while (size > 3) 
-        {
-            *idst++ = *isrc++;
-            size -= 4;
-        }
-    }
-
-    unsigned char* cdst = (unsigned char*)dest;
-    unsigned char* csrc = (unsigned char*)source;
-
-    /* byte-by-byte copy */
-    while (size--) 
-    {
-        *cdst++ = *csrc++;
-    }
-    return dest;
-}
-//////////////////////////////////////////////////////////////////////////////////
-// Fill a byte string with a byte value.
-//////////////////////////////////////////////////////////////////////////////////
-void * memset( void*        dest, 
-                      int          value, 
-                      unsigned int count ) 
-{
-    // word-by-word copy
-    unsigned int* idst = dest;
-    unsigned int  data = (((unsigned char)value)      ) |
-                         (((unsigned char)value) <<  8) |
-                         (((unsigned char)value) << 16) |
-                         (((unsigned char)value) << 24) ;
-
-    if ( ! ((unsigned int)idst & 3) )
-    {
-        while ( count > 3 )
-        {
-            *idst++ = data;
-            count -= 4;
-        }
-    }
-   
-    // byte-by-byte copy
-    unsigned char* cdst = dest;
-    while (count--) 
-    {
-        *cdst++ = (unsigned char)value;
-    }
-    return dest;
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// This function implements an interactive break for debug.
-// Execution continue when typing any character on TTY0. 
-// The "str" argument is supposed to indicate the break location.
-//////////////////////////////////////////////////////////////////////////////////
-void _break( char* string ) 
-{
-    char byte;
-
-    _printf("\n[GIET DEBUG] break from %s / continue ?\n", string );
-    _getc( &byte );
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Processor suicide: infinite loop  
-//////////////////////////////////////////////////////////////////////////////////
-__attribute__((noreturn))
-void _exit() 
-{
-    unsigned int procid     = _get_procid();
-    unsigned int lpid       = procid % NB_PROCS_MAX;
-    unsigned int cluster_xy = procid / NB_PROCS_MAX;
-    unsigned int x          = cluster_xy >> Y_WIDTH;
-    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
-
-
-    _printf("\n[GIET PANIC] processor[%d,%d,%d] suicide...\n", x, y, lpid );
-
-    while (1) { asm volatile ("nop"); }
-}
-///////////////////////////////////////////////////////////////////////////////////
-//         CP0 and CP2 registers access functions
+
+///////////////////////////////////////////////////////////////////////////////////
+//         CP0 registers access functions
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -149,24 +39,4 @@
 }
 ///////////////////////////////////////////////////////////////////////////////////
-// Returns PTPR register content.
-///////////////////////////////////////////////////////////////////////////////////
-unsigned int _get_mmu_ptpr() 
-{
-    unsigned int ret;
-    asm volatile( "mfc2      %0,     $0      \n"
-                  : "=r"(ret) );
-    return ret;
-}
-///////////////////////////////////////////////////////////////////////////////////
-// Returns MODE register content.
-///////////////////////////////////////////////////////////////////////////////////
-unsigned int _get_mmu_mode() 
-{
-    unsigned int ret;
-    asm volatile( "mfc2      %0,     $1      \n"
-                  : "=r"(ret) );
-    return ret;
-}
-///////////////////////////////////////////////////////////////////////////////////
 // Returns EPC register content.
 ///////////////////////////////////////////////////////////////////////////////////
@@ -238,13 +108,4 @@
     return ret;
 }
-//////////////////////////////////////////////////////////////////////////////
-// Returns index of the currently running task from the processor scheduler.
-//////////////////////////////////////////////////////////////////////////////
-unsigned int _get_current_task_id() 
-{
-    static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
-    return (unsigned int) (psched->current);
-}
-
 //////////////////////////////////////////////////////////////////////////////
 // Save SR value into save_sr_ptr variable and disable IRQs. 
@@ -262,15 +123,4 @@
     *save_sr_ptr = sr;
 }
-//////////////////////////////////////////////////////////////////////////////
-// Enables IRQs
-//////////////////////////////////////////////////////////////////////////////
-void _it_enable() 
-{
-    asm volatile( "li      $3,        0x00000001    \n"
-                  "mfc0    $4,        $12           \n"
-                  "or      $3,        $3, $4        \n"
-                  "mtc0    $3,        $12           \n"  
-                  ::: "$3", "$4", "memory" );
-}
 
 //////////////////////////////////////////////////////////////////////////////
@@ -287,4 +137,39 @@
 
 //////////////////////////////////////////////////////////////////////////////
+// This function set a new value in CP0 SCHED register.
+// (virtual base address of the processor scheduler).
+//////////////////////////////////////////////////////////////////////////////
+void _set_sched(unsigned int val) 
+{
+    asm volatile ( "mtc0     %0,     $4, 2          \n"
+                   :
+                   :"r" (val) );
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+//         CP2 registers access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// Returns PTPR register content.
+///////////////////////////////////////////////////////////////////////////////////
+unsigned int _get_mmu_ptpr() 
+{
+    unsigned int ret;
+    asm volatile( "mfc2      %0,     $0      \n"
+                  : "=r"(ret) );
+    return ret;
+}
+///////////////////////////////////////////////////////////////////////////////////
+// Returns MODE register content.
+///////////////////////////////////////////////////////////////////////////////////
+unsigned int _get_mmu_mode() 
+{
+    unsigned int ret;
+    asm volatile( "mfc2      %0,     $1      \n"
+                  : "=r"(ret) );
+    return ret;
+}
+//////////////////////////////////////////////////////////////////////////////
 // This function set a new value for the MMU PTPR register.
 //////////////////////////////////////////////////////////////////////////////
@@ -305,14 +190,4 @@
                    :"r" (val)
                    :"memory" );
-}
-//////////////////////////////////////////////////////////////////////////////
-// This function set a new value in CP0 SCHED register.
-// (virtual base address of the processor scheduler).
-//////////////////////////////////////////////////////////////////////////////
-void _set_sched(unsigned int val) 
-{
-    asm volatile ( "mtc0     %0,     $4, 2          \n"
-                   :
-                   :"r" (val) );
 }
 
@@ -355,5 +230,5 @@
 ////////////////////////////////////////////////////////////////////////////
 void _physical_write( unsigned long long paddr, 
-                             unsigned int       value ) 
+                               unsigned int       value ) 
 {
     unsigned int lsb = (unsigned int)paddr;
@@ -419,5 +294,5 @@
 ////////////////////////////////////////////////////////////////////////////
 void _physical_write_ull( unsigned long long paddr, 
-                                 unsigned long long value ) 
+                          unsigned long long value ) 
 {
     unsigned int addr_lsb = (unsigned int)paddr;
@@ -450,10 +325,10 @@
 // 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
+// source and destination buffers must be word aligned, and size must be
 // multiple of 4 bytes. 
 ///////////////////////////////////////////////////////////////////////////////////
 void _physical_memcpy( unsigned long long dst_paddr,  // dest buffer paddr
-                              unsigned long long src_paddr,  // source buffer paddr
-                              unsigned int size )            // bytes
+                       unsigned long long src_paddr,  // source buffer paddr
+                       unsigned int size )            // bytes
 {
     // check alignment constraints
@@ -509,5 +384,5 @@
 ///////////////////////////////////////////////////////////////////////////////////
 void _io_extended_write( unsigned int*  vaddr,
-                                unsigned int   value )
+                         unsigned int   value )
 {
     unsigned long long paddr;
@@ -892,65 +767,20 @@
 }
 
-///////////////////////////////////////////////////////////////////////////////////
-// Compare two strings s1 & s2 (no more than n characters)
-///////////////////////////////////////////////////////////////////////////////////
-unsigned int _strncmp( const char * s1, 
-                       const char * s2, 
-                       unsigned int n ) 
-{
-    unsigned int i;
-    for (i = 0; i < n; i++) 
-    {
-        if (s1[i] != s2[i])  return 1; 
-        if (s1[i] == 0)      break;
-    }
-    return 0;
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-// Copy source string to dest string
-///////////////////////////////////////////////////////////////////////////////////
-char* _strcpy( char* dest, char* source )
-{
-    if (!dest || !source) return dest;
-
-    while (*source)
-        *(dest++) = *(source++);
-
-    return dest;
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-// Invalidate all data cache lines corresponding to a memory 
-// buffer (identified by an address and a size).
-// TODO This should be replaced by a write to the CP2 MMU_DCACHE_INVAL
-// register, to be more processor independant.
-///////////////////////////////////////////////////////////////////////////////////
-void _dcache_buf_invalidate( void * buffer, 
-                             unsigned int size) 
-{
-    unsigned int i;
-    unsigned int tmp;
-    unsigned int line_size;
-
-    // compute data cache line size based on config register (bits 12:10)
-    asm volatile(
-                 "mfc0 %0, $16, 1" 
-                 : "=r" (tmp) );
-    tmp = ((tmp >> 10) & 0x7);
-    line_size = 2 << tmp;
-
-    // iterate on cache lines 
-    for (i = 0; i < size; i += line_size) 
-    {
-        asm volatile(
-                " cache %0, %1"
-                : :"i" (0x11), "R" (*((unsigned char *) buffer + i)) );
-    }
-}
-
+
+//////////////////////////////////////////////////////////////////////////////
+//           Scheduler and tasks context access functions
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+// Returns index of the currently running task from the processor scheduler.
+//////////////////////////////////////////////////////////////////////////////
+unsigned int _get_current_task_id() 
+{
+    static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
+    return (unsigned int) (psched->current);
+}
 ////////////////////////////////////////////////////////////////////////////////////
 // This function returns the content of a context slot 
-// for any task identified by the ltid argument (local task index),
+// for a task identified by the ltid argument (local task index),
 // and the gpid argument (global processor index)
 ////////////////////////////////////////////////////////////////////////////////////
@@ -962,5 +792,4 @@
     return psched->context[ltid][slot];
 }
-
 ////////////////////////////////////////////////////////////////////////////////////
 // This function updates the content of a context slot 
@@ -976,5 +805,4 @@
     psched->context[ltid][slot] = value;
 }
-
 ////////////////////////////////////////////////////////////////////////////////////
 // This function returns the content of a context slot 
@@ -987,5 +815,4 @@
     return psched->context[task_id][slot];
 }
-
 ////////////////////////////////////////////////////////////////////////////////////
 // This function updates the content of a context slot for the running task.
@@ -998,67 +825,4 @@
     psched->context[task_id][slot] = value;
 }
-
-///////////////////////////////////////////////////////////////////////////////////
-// This function returns the information associated to a heap : vaddr and length.
-// - If (x < X_SIZE) and (y < Y_SIZE), it return the heap associated to any task
-// running in cluster(x,y). 
-// - Else, it return the heap associated to the calling task.
-// It uses the global task index (CTX_GTID_ID, unique for each giet task) and the
-// vspace index (CTX_VSID_ID), that are defined in the calling task context
-// to find the vobj_id containing the heap. 
-// Return 0 if success. Return non zero if not found.
-///////////////////////////////////////////////////////////////////////////////////
-unsigned int _heap_info( unsigned int* vaddr, 
-                         unsigned int* length,
-                         unsigned int  x,
-                         unsigned int  y ) 
-{
-    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
-    mapping_task_t *   tasks   = _get_task_base(header);
-    mapping_vobj_t *   vobjs   = _get_vobj_base(header);
-    mapping_vspace_t * vspaces = _get_vspace_base(header);
-
-    unsigned int task_id;
-    unsigned int vspace_id;
-    unsigned int vobj_id = 0xFFFFFFFF;
-
-    // searching the heap vobj_id
-    if ( (x < X_SIZE) && (y < Y_SIZE) )  // searching a task in cluster(x,y)
-    {
-        // get vspace global index
-        vspace_id = _get_context_slot(CTX_VSID_ID);
-
-        // scan all tasks in vspace
-        unsigned int min = vspaces[vspace_id].task_offset ;
-        unsigned int max = min + vspaces[vspace_id].tasks ;
-        for ( task_id = min ; task_id < max ; task_id++ )
-        {
-            if ( tasks[task_id].clusterid == (x * Y_SIZE + y) )
-            {
-                vobj_id = tasks[task_id].heap_vobj_id;
-                if ( vobj_id != 0xFFFFFFFF ) break;
-            }
-        }
-    }
-    else                                // searching in the calling task 
-    {
-        task_id = _get_context_slot(CTX_GTID_ID);
-        vobj_id = tasks[task_id].heap_vobj_id;
-    }
-
-    // analysing the vobj_id
-    if ( vobj_id != 0xFFFFFFFF ) 
-    {
-        *vaddr  = vobjs[vobj_id].vaddr;
-        *length = vobjs[vobj_id].length;
-        return 0;
-    }
-    else 
-    {
-        *vaddr = 0;
-        *length = 0;
-        return 1;
-    }
-}  // end _heap_info()
 
 /////////////////////////////////////////////////////////////////////////////
@@ -1186,4 +950,245 @@
 }
 
+///////////////////////////////////////////////////////////////////////////////////
+// Miscelaneous functions
+///////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// This function implements a pseudo-random delay.
+// The val argument define approximately an exponentially increasing mean delay,
+// and should not be larger than 32.
+///////////////////////////////////////////////////////////////////////////////////
+void _random_wait( unsigned int val )
+{
+    unsigned int mask  = (1<<(val&0x1F))-1;
+    unsigned int delay = (_get_proctime() ^ (_get_procid()<<4)) & mask;
+    asm volatile( "move  $3,   %0                 \n"
+                  "loop_nic_completed:            \n"
+                  "addi  $3,   $3, -1             \n"
+                  "bnez  $3,   loop_nic_completed \n"
+                  "nop                            \n"
+                  :
+                  : "r" (delay)
+                  : "$3" ); 
+}
+//////////////////////////////////////////////////////////////////////////////////
+// This function implements an interactive break for debug.
+// Execution continue when typing any character on TTY0. 
+// The "str" argument is supposed to indicate the break location.
+//////////////////////////////////////////////////////////////////////////////////
+void _break( char* string ) 
+{
+    char byte;
+
+    _printf("\n[GIET DEBUG] break from %s / continue ?\n", string );
+    _getc( &byte );
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+// Processor suicide: infinite loop  
+//////////////////////////////////////////////////////////////////////////////////
+__attribute__((noreturn))
+void _exit() 
+{
+    unsigned int procid     = _get_procid();
+    unsigned int lpid       = procid % NB_PROCS_MAX;
+    unsigned int cluster_xy = procid / NB_PROCS_MAX;
+    unsigned int x          = cluster_xy >> Y_WIDTH;
+    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
+
+
+    _printf("\n[GIET PANIC] processor[%d,%d,%d] suicide...\n", x, y, lpid );
+
+    while (1) { asm volatile ("nop"); }
+}
+///////////////////////////////////////////////////////////////////////////////////
+// Compare two strings s1 & s2 (no more than n characters)
+///////////////////////////////////////////////////////////////////////////////////
+unsigned int _strncmp( const char * s1, 
+                       const char * s2, 
+                       unsigned int n ) 
+{
+    unsigned int i;
+    for (i = 0; i < n; i++) 
+    {
+        if (s1[i] != s2[i])  return 1; 
+        if (s1[i] == 0)      break;
+    }
+    return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// Copy source string to dest string
+///////////////////////////////////////////////////////////////////////////////////
+char* _strcpy( char* dest, char* source )
+{
+    if (!dest || !source) return dest;
+
+    while (*source)
+        *(dest++) = *(source++);
+
+    return dest;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// Invalidate all data cache lines corresponding to a memory 
+// buffer (identified by an address and a size).
+// TODO This should be replaced by a write to the CP2 MMU_DCACHE_INVAL
+// register, to be more processor independant.
+///////////////////////////////////////////////////////////////////////////////////
+void _dcache_buf_invalidate( void * buffer, 
+                             unsigned int size) 
+{
+    unsigned int i;
+    unsigned int tmp;
+    unsigned int line_size;
+
+    // compute data cache line size based on config register (bits 12:10)
+    asm volatile(
+                 "mfc0 %0, $16, 1" 
+                 : "=r" (tmp) );
+    tmp = ((tmp >> 10) & 0x7);
+    line_size = 2 << tmp;
+
+    // iterate on cache lines 
+    for (i = 0; i < size; i += line_size) 
+    {
+        asm volatile(
+                " cache %0, %1"
+                : :"i" (0x11), "R" (*((unsigned char *) buffer + i)) );
+    }
+}
+///////////////////////////////////////////////////////////////////////////////////
+// This function returns the information associated to a heap : vaddr and length.
+// - If (x < X_SIZE) and (y < Y_SIZE), it return the heap associated to any task
+// running in cluster(x,y). 
+// - Else, it return the heap associated to the calling task.
+// It uses the global task index (CTX_GTID_ID, unique for each giet task) and the
+// vspace index (CTX_VSID_ID), that are defined in the calling task context
+// to find the vobj_id containing the heap. 
+// Return 0 if success. Return non zero if not found.
+///////////////////////////////////////////////////////////////////////////////////
+unsigned int _heap_info( unsigned int* vaddr, 
+                         unsigned int* length,
+                         unsigned int  x,
+                         unsigned int  y ) 
+{
+    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
+    mapping_task_t *   tasks   = _get_task_base(header);
+    mapping_vobj_t *   vobjs   = _get_vobj_base(header);
+    mapping_vspace_t * vspaces = _get_vspace_base(header);
+
+    unsigned int task_id;
+    unsigned int vspace_id;
+    unsigned int vobj_id = 0xFFFFFFFF;
+
+    // searching the heap vobj_id
+    if ( (x < X_SIZE) && (y < Y_SIZE) )  // searching a task in cluster(x,y)
+    {
+        // get vspace global index
+        vspace_id = _get_context_slot(CTX_VSID_ID);
+
+        // scan all tasks in vspace
+        unsigned int min = vspaces[vspace_id].task_offset ;
+        unsigned int max = min + vspaces[vspace_id].tasks ;
+        for ( task_id = min ; task_id < max ; task_id++ )
+        {
+            if ( tasks[task_id].clusterid == (x * Y_SIZE + y) )
+            {
+                vobj_id = tasks[task_id].heap_vobj_id;
+                if ( vobj_id != 0xFFFFFFFF ) break;
+            }
+        }
+    }
+    else                                // searching in the calling task 
+    {
+        task_id = _get_context_slot(CTX_GTID_ID);
+        vobj_id = tasks[task_id].heap_vobj_id;
+    }
+
+    // analysing the vobj_id
+    if ( vobj_id != 0xFFFFFFFF ) 
+    {
+        *vaddr  = vobjs[vobj_id].vaddr;
+        *length = vobjs[vobj_id].length;
+        return 0;
+    }
+    else 
+    {
+        *vaddr = 0;
+        *length = 0;
+        return 1;
+    }
+}  // end _heap_info()
+
+
+///////////////////////////////////////////////////////////////////////////////////
+//   Required by GCC
+///////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// Copy a source memory buffer content to a dest memory buffer (size bytes)
+// Code taken from MutekH.
+///////////////////////////////////////////////////////////////////////////////////
+void* memcpy( void*        dest,     // dest buffer vbase
+              const void*  source,   // source buffer vbase
+              unsigned int size )    // bytes
+{
+    unsigned int* idst = (unsigned int*)dest;
+    unsigned int* isrc = (unsigned int*)source;
+
+    // word-by-word copy
+    if (!((unsigned int) idst & 3) && !((unsigned int) isrc & 3)) 
+    {
+        while (size > 3) 
+        {
+            *idst++ = *isrc++;
+            size -= 4;
+        }
+    }
+
+    unsigned char* cdst = (unsigned char*)dest;
+    unsigned char* csrc = (unsigned char*)source;
+
+    /* byte-by-byte copy */
+    while (size--) 
+    {
+        *cdst++ = *csrc++;
+    }
+    return dest;
+}
+//////////////////////////////////////////////////////////////////////////////////
+// Fill a byte string with a byte value.
+//////////////////////////////////////////////////////////////////////////////////
+void * memset( void*        dest, 
+                      int          value, 
+                      unsigned int count ) 
+{
+    // word-by-word copy
+    unsigned int* idst = dest;
+    unsigned int  data = (((unsigned char)value)      ) |
+                         (((unsigned char)value) <<  8) |
+                         (((unsigned char)value) << 16) |
+                         (((unsigned char)value) << 24) ;
+
+    if ( ! ((unsigned int)idst & 3) )
+    {
+        while ( count > 3 )
+        {
+            *idst++ = data;
+            count -= 4;
+        }
+    }
+   
+    // byte-by-byte copy
+    unsigned char* cdst = dest;
+    while (count--) 
+    {
+        *cdst++ = (unsigned char)value;
+    }
+    return dest;
+}
+
+
 // Local Variables:
 // tab-width: 4
