Index: /soft/giet_vm/boot/boot_init.c
===================================================================
--- /soft/giet_vm/boot/boot_init.c	(revision 254)
+++ /soft/giet_vm/boot/boot_init.c	(revision 255)
@@ -69,4 +69,5 @@
 #include <stdarg.h>
 
+
 #if !defined(NB_CLUSTERS)
 # error The NB_CLUSTERS value must be defined in the 'giet_config.h' file !
@@ -80,4 +81,7 @@
 # error The GIET_NB_VSPACE_MAX value must be defined in the 'giet_config.h' file !
 #endif
+
+#define max(x, y) (((x) > (y)) ? (x) : (y))
+
 
 ////////////////////////////////////////////////////////////////////////////
@@ -555,5 +559,5 @@
 
 /////////////////////////////////////////////////////////////////////
-// This function build the page table for a given vspace. 
+// This function builds the page table for a given vspace. 
 // The physical base addresses for all vsegs (global and private)
 // must have been previously computed and stored in the mapping.
@@ -577,5 +581,5 @@
     for (vseg_id = vspace[vspace_id].vseg_offset;
          vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs);
-         vseg_id++) 
+         vseg_id++)
     {
         vpn = vseg[vseg_id].vbase >> 12;
@@ -597,4 +601,6 @@
         boot_puts(" / npages = ");
         boot_putd(npages);
+        boot_puts(" / vbase = ");
+        boot_putx(vseg[vseg_id].vbase);
         boot_puts(" / pbase = ");
         boot_putl(vseg[vseg_id].pbase);
@@ -614,5 +620,5 @@
     {
         vpn = vseg[vseg_id].vbase >> 12;
-        ppn = (unsigned int)(vseg[vseg_id].pbase >> 12);
+        ppn = (unsigned int) (vseg[vseg_id].pbase >> 12);
         npages = vseg[vseg_id].length >> 12;
         if ((vseg[vseg_id].length & 0xFFF) != 0) npages++;
@@ -630,4 +636,6 @@
         boot_puts(" / npages = ");
         boot_putd(npages);
+        boot_puts(" / vbase = ");
+        boot_putx(vseg[vseg_id].vbase);
         boot_puts(" / pbase = ");
         boot_putl(vseg[vseg_id].pbase);
@@ -646,5 +654,5 @@
 
 ///////////////////////////////////////////////////////////////////////////
-// Align the value of paddr or vaddr to the required alignement,
+// Aligns the value of paddr or vaddr to the required alignement,
 // defined by alignPow2 == L2(alignement).
 ///////////////////////////////////////////////////////////////////////////
@@ -660,4 +668,191 @@
     return ((vaddr + mask) & ~mask);
 }
+
+
+
+///////////////////////////////////////////////////////////
+// Maps vseg on a pbase with identity mapping required
+// The pseg is already set
+// The length of the vseg must already be known
+///////////////////////////////////////////////////////////
+void boot_vseg_set_paddr_ident(mapping_vseg_t * vseg) {
+    unsigned int vseg_id;
+
+    mapping_header_t * header = (mapping_header_t *) & seg_mapping_base;
+    mapping_vseg_t * vseg_base = boot_get_vseg_base(header);
+ 
+    if (vseg->pbase_set != 0) {
+        boot_puts("\n[BOOT ERROR] in boot_vseg_set_paddr() function (internal error):\n");
+        boot_puts("*** vseg->pbase already set\n");
+        boot_exit();
+    }
+
+    for (vseg_id = 0; vseg_id < header->vsegs; vseg_id++) {
+        // Already mapped vseg on the same pseg
+        if (vseg_base[vseg_id].psegid == vseg->psegid && vseg_base[vseg_id].pbase_set == 1) {
+            // Checking overlap condition
+            if (vseg->vbase == vseg_base[vseg_id].pbase || 
+                    ((vseg->vbase < vseg_base[vseg_id].pbase) && (vseg->vbase + vseg->length > vseg_base[vseg_id].pbase)) ||
+                    ((vseg->vbase > vseg_base[vseg_id].pbase) && (vseg_base[vseg_id].pbase + vseg_base[vseg_id].length > vseg->vbase))) {
+                boot_puts("\n[BOOT ERROR] in boot_vseg_set_paddr_ident() function\n");
+                boot_puts("*** Overlapping segments:\n");
+                boot_puts("    seg with base = ");
+                boot_putl(vseg->vbase);
+                boot_puts(" - length = ");
+                boot_putl(vseg->length);
+                boot_puts("\n");
+                boot_puts("    seg with base = \n");
+                boot_putl(vseg_base[vseg_id].vbase);
+                boot_puts(" - length = ");
+                boot_putl(vseg_base[vseg_id].length);
+                boot_puts("\n");
+                boot_exit();
+            }
+        }
+    }
+    vseg->pbase = vseg->vbase;
+    vseg->pbase_set = 1;
+}
+
+
+
+///////////////////////////////////////////////////////////
+// Maps vseg on a pbase with no identity mapping required
+// The pseg is already set
+// The length of the vseg must already be known
+///////////////////////////////////////////////////////////
+void boot_vseg_set_paddr(mapping_vseg_t * vseg) {
+    unsigned int vseg_id;
+    unsigned int nb_vsegs_mapped = 0;
+    unsigned int mapped = 0;
+    int i = 0;
+
+    paddr_t prev_base;
+    paddr_t prev_length = 0;
+    paddr_t curr_base = 0;
+    paddr_t curr_length = 0;
+    paddr_t next_base = 0;
+    paddr_t next_length = 0;
+
+    mapping_header_t * header = (mapping_header_t *) & seg_mapping_base;
+    mapping_vseg_t * vseg_base = boot_get_vseg_base(header);
+    mapping_vobj_t * vobj_base = boot_get_vobj_base(header);
+    mapping_pseg_t * pseg = boot_pseg_get(vseg->psegid);
+
+    const int align = max(vobj_base[vseg->vobj_offset].align, 12);
+
+    prev_base = pseg->base;
+ 
+    if (vseg->pbase_set != 0) {
+        boot_puts("\n[BOOT ERROR] in boot_vseg_set_paddr() function (internal error):\n");
+        boot_puts("*** vseg->pbase already set\n");
+        boot_exit();
+    }
+
+    // We now determinine the physical base address of the vseg
+    // Method:
+    // Now that all identity segments have been mapped
+    // We are free to place the vseg where we want
+    // From a logical point of view, we have the list of mapped vsegs ordered by their pbase (increasing)
+    // We try to place the vseg between two consecutive elements of this list
+    // If this fails, we try between the next two mapped vsegs
+
+    // Counting the number of vsegs mapped on this pseg
+    // We also initialize curr_base and curr_length with some values 
+    for (vseg_id = 0; vseg_id < header->vsegs; vseg_id++) {
+        if (vseg_base[vseg_id].psegid == vseg->psegid && vseg_base[vseg_id].pbase_set == 1) {
+           nb_vsegs_mapped++;
+           curr_base = vseg_base[vseg_id].pbase;
+           curr_length = vseg_base[vseg_id].length;
+        }
+    }
+
+    if (nb_vsegs_mapped == 0) {
+        if (vseg->length <= pseg->length) {
+            vseg->pbase = pseg->base;
+            vseg->pbase_set = 1;
+            return;
+        }
+        else {
+            boot_puts("\n[BOOT ERROR] in boot_vseg_set_paddr() function\n");
+            boot_puts("*** PSEG is too small for mapping vseg (base:");
+            boot_putl(vseg->vbase);
+            boot_puts(" - length: ");
+            boot_putl(vseg->length);
+            boot_puts(")\n");
+            boot_exit();
+        }
+    }
+
+    // We look for the vseg mapped on the same pseg having the smallest vaddr
+    for (vseg_id = 0; vseg_id < header->vsegs; vseg_id++) {
+        if (vseg_base[vseg_id].psegid == vseg->psegid
+                && &vseg_base[vseg_id] != vseg
+                && vseg_base[vseg_id].pbase_set == 1
+                && vseg_base[vseg_id].pbase < curr_base) {
+            curr_base = vseg_base[vseg_id].pbase;
+            curr_length = vseg_base[vseg_id].length;            
+        }
+    }
+
+    // We iterate on each vseg mapped in the order of their growing pbase
+    // and try to insert the current vseg right after each
+    while (i < nb_vsegs_mapped) {
+        if (paddr_align_to(prev_base + prev_length, align) + vseg->length <= curr_base) {
+            vseg->pbase = paddr_align_to(prev_base + prev_length, align);
+            vseg->pbase_set = 1;
+            mapped = 1;
+            break;
+        }
+        else if (i < nb_vsegs_mapped - 1) {
+            int found = 0;
+            next_base = 0;
+            // We search for the vseg having the minimal pbase which is more than the pbase of the current vseg
+            for (vseg_id = 0; vseg_id < header->vsegs; vseg_id++) {
+                if (vseg_base[vseg_id].psegid == vseg->psegid
+                        && &vseg_base[vseg_id] != vseg
+                        && vseg_base[vseg_id].pbase_set == 1
+                        && (vseg_base[vseg_id].pbase < next_base || !found)
+                        && vseg_base[vseg_id].pbase > curr_base) {
+                    found = 1;
+                    next_base = vseg_base[vseg_id].pbase;
+                    next_length = vseg_base[vseg_id].length;
+                }
+            }
+            if (!found) {
+                boot_puts("\n[BOOT ERROR] in boot_vseg_set_paddr() function (internal error):\n");
+                boot_puts("*** Next vseg not found\n");
+                boot_exit();
+            }
+
+            prev_base = curr_base;
+            prev_length = curr_length;
+
+            curr_base = next_base;
+            curr_length = next_length;
+        }
+        else {
+            // The current vseg is the last one (highest mapped paddr on this pseg)
+            // We try to insert the current vseg after it
+            if (paddr_align_to(curr_base + curr_length, align) + vseg->length <= pseg->base + pseg->length) {
+                vseg->pbase = paddr_align_to(curr_base + curr_length, align);
+                vseg->pbase_set = 1;
+                mapped = 1;
+            }
+        }
+        i++;
+    }
+
+    if (!mapped) {
+        boot_puts("\n[BOOT ERROR] in boot_vseg_set_paddr() function:\n");
+        boot_puts("*** Not enough space to map vseg (base: ");
+        boot_putl(vseg->vbase);
+        boot_puts(" - length: ");
+        boot_putl(vseg->length);
+        boot_puts(")\n");
+        boot_exit();
+    }
+}
+
 
 ///////////////////////////////////////////////////////////////////////////
@@ -666,5 +861,4 @@
 // It updates the pbase and the length fields of the vseg.
 // It updates the pbase and vbase fields of all vobjs in the vseg.
-// It updates the next_base field of the pseg, and checks overflow.
 // It updates the boot_ptabs_paddr[] and boot_ptabs_vaddr[] arrays. 
 // It is a global vseg if vspace_id = (-1). 
@@ -675,41 +869,43 @@
     unsigned int cur_vaddr;
     paddr_t      cur_paddr;
+    paddr_t      cur_length;
     unsigned int offset;
 
     mapping_header_t * header = (mapping_header_t *) & seg_mapping_base;
-    mapping_vobj_t   * vobj   = boot_get_vobj_base(header);
-
-    // get physical segment pointer
-    mapping_pseg_t* pseg = boot_pseg_get(vseg->psegid);
-
-    // compute vseg physical base address
-    if (vseg->ident != 0)                   // identity mapping required
-    {
-        vseg->pbase = vseg->vbase;
-    }
-    else                                   // unconstrained mapping
-    {
-        vseg->pbase = pseg->next_base;
-
-        // test alignment constraint
-        if (vobj[vseg->vobj_offset].align) 
-        {
-            vseg->pbase = paddr_align_to(vseg->pbase, vobj[vseg->vobj_offset].align);
-        }
-    }
+    mapping_vobj_t * vobj = boot_get_vobj_base(header);
+
+    // We make a first loop on the vobj of the vseg to determine the real length of the vseg
+    // This length is required to determine the pbase of the vseg
+    cur_length = 0;
+    for (vobj_id = vseg->vobj_offset; vobj_id < (vseg->vobj_offset + vseg->vobjs); vobj_id++) {
+        if (vobj[vobj_id].align) {
+            cur_length = vaddr_align_to(cur_length, vobj[vobj_id].align);
+        }
+        cur_length += vobj[vobj_id].length;
+    }
+    vseg->length = paddr_align_to(cur_length, 12);
+
+    // We can now compute the vseg physical base address
+    if (vseg->ident != 0) { 
+        // identity mapping required
+        boot_vseg_set_paddr_ident(vseg);
+    }
+    else {
+        // unconstrained mapping
+        boot_vseg_set_paddr(vseg);
+    }
+
 
     // loop on vobjs contained in vseg to :
     // (1) computes the length of the vseg,
     // (2) initialize the vaddr and paddr fields of all vobjs,
-    // (3) initialize the page table pointers arrays 
+    // (3) initialize the page table pointers arrays
 
     cur_vaddr = vseg->vbase;
     cur_paddr = vseg->pbase;
 
-    for (vobj_id = vseg->vobj_offset; 
-         vobj_id < (vseg->vobj_offset + vseg->vobjs); vobj_id++) 
-    {
-        if (vobj[vobj_id].align) 
-        {
+    for (vobj_id = vseg->vobj_offset;
+         vobj_id < (vseg->vobj_offset + vseg->vobjs); vobj_id++) {
+        if (vobj[vobj_id].align) {
             cur_paddr = paddr_align_to(cur_paddr, vobj[vobj_id].align);
             cur_vaddr = vaddr_align_to(cur_vaddr, vobj[vobj_id].align);
@@ -729,5 +925,5 @@
             }
             // we need at least one PT2
-            if (vobj[vobj_id].length < (PT1_SIZE + PT2_SIZE)) 
+            if (vobj[vobj_id].length < (PT1_SIZE + PT2_SIZE))
             {
                 boot_puts("\n[BOOT ERROR] in boot_vseg_map() function, ");
@@ -741,5 +937,5 @@
             
             // reset all valid bits in PT1
-            for ( offset = 0 ; offset < 8192 ; offset = offset + 4)
+            for (offset = 0; offset < 8192; offset = offset + 4)
             {
                 boot_physical_write(cur_paddr + offset, 0);
@@ -754,30 +950,4 @@
         cur_paddr = cur_paddr + vobj[vobj_id].length;
     } // end for vobjs
-
-    //set the vseg length
-    vseg->length = vaddr_align_to((unsigned int)(cur_paddr - vseg->pbase), 12);
-
-    // checking pseg overflow
-    if ((vseg->pbase < pseg->base) ||
-        ((vseg->pbase + vseg->length) > (pseg->base + pseg->length))) 
-    {
-        boot_puts("\n[BOOT ERROR] in boot_vseg_map() function\n");
-        boot_puts("impossible mapping for virtual segment: ");
-        boot_puts(vseg->name);
-        boot_puts("\n");
-        boot_puts("vseg pbase = ");
-        boot_putl(vseg->pbase);
-        boot_puts("\n");
-        boot_puts("vseg length = ");
-        boot_putx(vseg->length);
-        boot_puts("\n");
-        boot_puts("pseg pbase = ");
-        boot_putl(pseg->base);
-        boot_puts("\n");
-        boot_puts("pseg length = ");
-        boot_putl(pseg->length);
-        boot_puts("\n");
-        boot_exit();
-    }
 
 #if BOOT_DEBUG_PT
@@ -792,9 +962,4 @@
 #endif
 
-    // set the next_base field in pseg when it's a RAM
-    if ( pseg->type == PSEG_TYPE_RAM ) 
-    {
-        pseg->next_base = vseg->pbase + vseg->length;
-    }
 }    // end boot_vseg_map()
 
@@ -835,30 +1000,30 @@
 
 #if BOOT_DEBUG_MAPPING
-boot_puts("\nclusters  = ");
-boot_putd( header->clusters );
-boot_puts("\nprocs     = ");
-boot_putd( header->procs );
-boot_puts("\nperiphs   = ");
-boot_putd( header->periphs );
-boot_puts("\nvspaces   = ");
-boot_putd( header->vspaces );
-boot_puts("\ntasks     = ");
-boot_putd( header->tasks );
-boot_puts("\n");
-
-unsigned int        cluster_id;
-mapping_cluster_t * cluster = boot_get_cluster_base(header);
-for (cluster_id = 0; cluster_id < NB_CLUSTERS; cluster_id++) 
-{
-boot_puts("\n cluster = ");
-boot_putd( cluster_id );
-boot_puts("\n procs   = ");
-boot_putd( cluster[cluster_id].procs );
-boot_puts("\n psegs   = ");
-boot_putd( cluster[cluster_id].psegs );
-boot_puts("\n periphs = ");
-boot_putd( cluster[cluster_id].periphs );
-boot_puts("\n");
-}
+    boot_puts("\nclusters  = ");
+    boot_putd( header->clusters );
+    boot_puts("\nprocs     = ");
+    boot_putd( header->procs );
+    boot_puts("\nperiphs   = ");
+    boot_putd( header->periphs );
+    boot_puts("\nvspaces   = ");
+    boot_putd( header->vspaces );
+    boot_puts("\ntasks     = ");
+    boot_putd( header->tasks );
+    boot_puts("\n");
+
+    unsigned int        cluster_id;
+    mapping_cluster_t * cluster = boot_get_cluster_base(header);
+    for (cluster_id = 0; cluster_id < NB_CLUSTERS; cluster_id++) 
+    {
+        boot_puts("\n cluster = ");
+        boot_putd( cluster_id );
+        boot_puts("\n procs   = ");
+        boot_putd( cluster[cluster_id].procs );
+        boot_puts("\n psegs   = ");
+        boot_putd( cluster[cluster_id].psegs );
+        boot_puts("\n periphs = ");
+        boot_putd( cluster[cluster_id].periphs );
+        boot_puts("\n");
+    }
 #endif
 
@@ -871,54 +1036,4 @@
 } // end boot_check_mapping()
 
-/////////////////////////////////////////////////////////////////////
-// This function initialises the physical pages table allocators 
-// for all psegs (i.e. next_base field of the pseg). 
-/////////////////////////////////////////////////////////////////////
-void boot_psegs_init() 
-{
-    mapping_header_t* header   = (mapping_header_t *) &seg_mapping_base;
-    mapping_cluster_t* cluster = boot_get_cluster_base(header);
-    mapping_pseg_t* pseg       = boot_get_pseg_base(header);
-
-    unsigned int cluster_id;
-    unsigned int pseg_id;
-
-#if BOOT_DEBUG_PT
-boot_puts ("\n[BOOT DEBUG] ****** psegs allocators initialisation ******\n");
-#endif
-
-    for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) 
-    {
-        if (cluster[cluster_id].procs > NB_PROCS_MAX) 
-        {
-            boot_puts("\n[BOOT ERROR] The number of processors in cluster ");
-            boot_putd(cluster_id);
-            boot_puts(" is larger than NB_PROCS_MAX \n");
-            boot_exit();
-        }
-
-        for (pseg_id = cluster[cluster_id].pseg_offset;
-                pseg_id < cluster[cluster_id].pseg_offset + cluster[cluster_id].psegs;
-                pseg_id++) 
-        {
-            pseg[pseg_id].next_base = pseg[pseg_id].base;
-
-#if BOOT_DEBUG_PT
-boot_puts("cluster ");
-boot_putd(cluster_id);
-boot_puts(" / pseg ");
-boot_puts(pseg[pseg_id].name);
-boot_puts(" : next_base = ");
-boot_putl(pseg[pseg_id].next_base);
-boot_puts("\n");
-#endif
-        }
-    }
-
-    boot_puts("\n[BOOT] Pseg allocators initialisation completed at cycle ");
-    boot_putd(boot_proctime());
-    boot_puts("\n");
-
-} // end boot_psegs_init()
 
 /////////////////////////////////////////////////////////////////////
@@ -941,12 +1056,23 @@
 
 #if BOOT_DEBUG_PT
-boot_puts("\n[BOOT DEBUG] ****** mapping global vsegs ******\n");
+    boot_puts("\n[BOOT DEBUG] ****** mapping global vsegs ******\n");
 #endif
 
     // step 1 : loop on virtual spaces to map global vsegs
+    // Identity vseg first
     for (vseg_id = 0; vseg_id < header->globals; vseg_id++) 
     {
-        boot_vseg_map(&vseg[vseg_id], ((unsigned int) (-1)));
-    }
+        if (vseg[vseg_id].ident == 1) {
+            boot_vseg_map(&vseg[vseg_id], ((unsigned int) (-1)));
+        }
+    }
+    // Non identity vseg second
+    for (vseg_id = 0; vseg_id < header->globals; vseg_id++) 
+    {
+        if (vseg[vseg_id].ident == 0) {
+            boot_vseg_map(&vseg[vseg_id], ((unsigned int) (-1)));
+        }
+    }
+
 
     // step 2 : loop on virtual vspaces to map private vsegs
@@ -955,14 +1081,24 @@
 
 #if BOOT_DEBUG_PT
-boot_puts("\n[BOOT DEBUG] ****** mapping private vsegs in vspace ");
-boot_puts(vspace[vspace_id].name);
-boot_puts(" ******\n");
-#endif
-
+        boot_puts("\n[BOOT DEBUG] ****** mapping private vsegs in vspace ");
+        boot_puts(vspace[vspace_id].name);
+        boot_puts(" ******\n");
+#endif
+
+        // Identity vseg first
         for (vseg_id = vspace[vspace_id].vseg_offset;
              vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs);
-             vseg_id++) 
-        {
-            boot_vseg_map(&vseg[vseg_id], vspace_id);
+             vseg_id++) {
+            if (vseg[vseg_id].ident == 1) {
+                boot_vseg_map(&vseg[vseg_id], vspace_id);
+            }
+        }
+        // Non identity vseg second
+        for (vseg_id = vspace[vspace_id].vseg_offset;
+             vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs);
+             vseg_id++) {
+            if (vseg[vseg_id].ident == 0) {
+                boot_vseg_map(&vseg[vseg_id], vspace_id);
+            }
         }
     }
@@ -972,20 +1108,21 @@
     {
 #if BOOT_DEBUG_PT
-boot_puts("\n[BOOT DEBUG] ****** building page table for vspace ");
-boot_puts(vspace[vspace_id].name);
-boot_puts(" ******\n");
-#endif
+        boot_puts("\n[BOOT DEBUG] ****** building page table for vspace ");
+        boot_puts(vspace[vspace_id].name);
+        boot_puts(" ******\n");
+#endif
+
         boot_vspace_pt_build(vspace_id);
 
 #if BOOT_DEBUG_PT
-boot_puts("\n>>> page table physical address = ");
-boot_putl(boot_ptabs_paddr[vspace_id]);
-boot_puts(", number of PT2 = ");
-boot_putd((unsigned int) boot_max_pt2[vspace_id]);
-boot_puts("\n");
-#endif
-    }
-
-    boot_puts("\n[BOOT] Page Tables initialisation completed at cycle ");
+        boot_puts("\n>>> page table physical address = ");
+        boot_putl(boot_ptabs_paddr[vspace_id]);
+        boot_puts(", number of PT2 = ");
+        boot_putd((unsigned int) boot_max_pt2[vspace_id]);
+        boot_puts("\n");
+#endif
+    }
+
+    boot_puts("\n[BOOT] Page Tables initialization completed at cycle ");
     boot_putd(boot_proctime());
     boot_puts("\n");
@@ -999,5 +1136,5 @@
 // Warning : The MMU is supposed to be activated...
 ///////////////////////////////////////////////////////////////////////////////
-void boot_vobjs_init() 
+void boot_vobjs_init()
 {
     mapping_header_t* header = (mapping_header_t *) & seg_mapping_base;
@@ -1011,9 +1148,10 @@
     for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
     {
+        boot_set_mmu_ptpr((unsigned int) (boot_ptabs_paddr[vspace_id] >> 13));
 
 #if BOOT_DEBUG_VOBJS
-boot_puts("\n[BOOT DEBUG] ****** vobjs initialisation in vspace ");
-boot_puts(vspace[vspace_id].name);
-boot_puts(" ******\n");
+        boot_puts("\n[BOOT DEBUG] ****** vobjs initialisation in vspace ");
+        boot_puts(vspace[vspace_id].name);
+        boot_puts(" ******\n");
 #endif
 
@@ -1023,5 +1161,5 @@
         for (vobj_id = vspace[vspace_id].vobj_offset;
              vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs);
-             vobj_id++) 
+             vobj_id++)
         {
             switch (vobj[vobj_id].type) 
@@ -1037,11 +1175,11 @@
                     mwmr->lock = 0;
 #if BOOT_DEBUG_VOBJS
-boot_puts("MWMR    : ");
-boot_puts(vobj[vobj_id].name);
-boot_puts(" / depth = ");
-boot_putd(mwmr->depth);
-boot_puts(" / width = ");
-boot_putd(mwmr->width);
-boot_puts("\n");
+                    boot_puts("MWMR    : ");
+                    boot_puts(vobj[vobj_id].name);
+                    boot_puts(" / depth = ");
+                    boot_putd(mwmr->depth);
+                    boot_puts(" / width = ");
+                    boot_putd(mwmr->width);
+                    boot_puts("\n");
 #endif
                     break;
@@ -1050,9 +1188,9 @@
                 {
 #if BOOT_DEBUG_VOBJS
-boot_puts("ELF     : ");
-boot_puts(vobj[vobj_id].name);
-boot_puts(" / length = ");
-boot_putx(vobj[vobj_id].length);
-boot_puts("\n");
+                    boot_puts("ELF     : ");
+                    boot_puts(vobj[vobj_id].name);
+                    boot_puts(" / length = ");
+                    boot_putx(vobj[vobj_id].length);
+                    boot_puts("\n");
 #endif
                     break;
@@ -1061,9 +1199,9 @@
                 {
 #if BOOT_DEBUG_VOBJS
-boot_puts("BLOB     : ");
-boot_puts(vobj[vobj_id].name);
-boot_puts(" / length = ");
-boot_putx(vobj[vobj_id].length);
-boot_puts("\n");
+                    boot_puts("BLOB     : ");
+                    boot_puts(vobj[vobj_id].name);
+                    boot_puts(" / length = ");
+                    boot_putx(vobj[vobj_id].length);
+                    boot_puts("\n");
 #endif
                     break;
@@ -1075,9 +1213,9 @@
                     barrier->init = vobj[vobj_id].init;
 #if BOOT_DEBUG_VOBJS
-boot_puts("BARRIER : ");
-boot_puts(vobj[vobj_id].name);
-boot_puts(" / init_value = ");
-boot_putd(barrier->init);
-boot_puts("\n");
+                    boot_puts("BARRIER : ");
+                    boot_puts(vobj[vobj_id].name);
+                    boot_puts(" / init_value = ");
+                    boot_putd(barrier->init);
+                    boot_puts("\n");
 #endif
                     break;
@@ -1088,7 +1226,7 @@
                     *lock = 0;
 #if BOOT_DEBUG_VOBJS
-boot_puts("LOCK    : ");
-boot_puts(vobj[vobj_id].name);
-boot_puts("\n");
+                    boot_puts("LOCK    : ");
+                    boot_puts(vobj[vobj_id].name);
+                    boot_puts("\n");
 #endif
                     break;
@@ -1097,11 +1235,11 @@
                 {
 #if BOOT_DEBUG_VOBJS
-boot_puts("BUFFER  : ");
-boot_puts(vobj[vobj_id].name);
-boot_puts(" / paddr = ");
-boot_putl(vobj[vobj_id].paddr);
-boot_puts(" / length = ");
-boot_putx(vobj[vobj_id].length);
-boot_puts("\n");
+                    boot_puts("BUFFER  : ");
+                    boot_puts(vobj[vobj_id].name);
+                    boot_puts(" / paddr = ");
+                    boot_putl(vobj[vobj_id].paddr);
+                    boot_puts(" / length = ");
+                    boot_putx(vobj[vobj_id].length);
+                    boot_puts("\n");
 #endif
                     break;
@@ -1109,19 +1247,19 @@
                 case VOBJ_TYPE_MEMSPACE:
                 {
-                    giet_memspace_t* memspace = (giet_memspace_t *) vobj[vobj_id].vaddr;
+                    giet_memspace_t * memspace = (giet_memspace_t *) vobj[vobj_id].vaddr;
                     memspace->buffer = (void *) vobj[vobj_id].vaddr + 8;
                     memspace->size = vobj[vobj_id].length - 8;
 #if BOOT_DEBUG_VOBJS
-boot_puts("MEMSPACE  : ");
-boot_puts(vobj[vobj_id].name);
-boot_puts(" / vaddr = ");
-boot_putx(vobj[vobj_id].vaddr);
-boot_puts(" / length = ");
-boot_putx(vobj[vobj_id].length);
-boot_puts(" / buffer = ");
-boot_putx((unsigned int)memspace->buffer);
-boot_puts(" / size = ");
-boot_putx(memspace->size);
-boot_puts("\n");
+                    boot_puts("MEMSPACE  : ");
+                    boot_puts(vobj[vobj_id].name);
+                    boot_puts(" / vaddr = ");
+                    boot_putx(vobj[vobj_id].vaddr);
+                    boot_puts(" / length = ");
+                    boot_putx(vobj[vobj_id].length);
+                    boot_puts(" / buffer = ");
+                    boot_putx((unsigned int) memspace->buffer);
+                    boot_puts(" / size = ");
+                    boot_putx(memspace->size);
+                    boot_puts("\n");
 #endif
                     break;
@@ -1131,9 +1269,9 @@
                     ptab_found = 1;
 #if BOOT_DEBUG_VOBJS
-boot_puts("PTAB    : ");
-boot_puts(vobj[vobj_id].name);
-boot_puts(" / length = ");
-boot_putx(vobj[vobj_id].length);
-boot_puts("\n");
+                    boot_puts("PTAB    : ");
+                    boot_puts(vobj[vobj_id].name);
+                    boot_puts(" / length = ");
+                    boot_putx(vobj[vobj_id].length);
+                    boot_puts("\n");
 #endif
                     break;
@@ -1144,11 +1282,11 @@
                     *addr = vobj[vobj_id].init;
 #if BOOT_DEBUG_VOBJS
-boot_puts("CONST   : ");
-boot_puts(vobj[vobj_id].name);
-boot_puts(" / Paddr :");
-boot_putl(vobj[vobj_id].paddr);
-boot_puts(" / init = ");
-boot_putx(*addr);
-boot_puts("\n");
+                    boot_puts("CONST   : ");
+                    boot_puts(vobj[vobj_id].name);
+                    boot_puts(" / Paddr :");
+                    boot_putl(vobj[vobj_id].paddr);
+                    boot_puts(" / init = ");
+                    boot_putx(*addr);
+                    boot_puts("\n");
 #endif
                     break;
@@ -1238,7 +1376,7 @@
 
 #if BOOT_DEBUG_PERI
-boot_puts("\n[BOOT DEBUG] ****** peripherals initialisation in cluster ");
-boot_putd(cluster_id);
-boot_puts(" ******\n");
+        boot_puts("\n[BOOT DEBUG] ****** peripherals initialisation in cluster ");
+        boot_putd(cluster_id);
+        boot_puts(" ******\n");
 #endif
 
@@ -1254,11 +1392,11 @@
 
 #if BOOT_DEBUG_PERI
-boot_puts("- peripheral type : ");
-boot_putd(type);
-boot_puts(" / pbase = ");
-boot_putl(pbase);
-boot_puts(" / channels = ");
-boot_putd(channels);
-boot_puts("\n");
+            boot_puts("- peripheral type : ");
+            boot_putd(type);
+            boot_puts(" / pbase = ");
+            boot_putl(pbase);
+            boot_puts(" / channels = ");
+            boot_putd(channels);
+            boot_puts("\n");
 #endif
 
@@ -1270,5 +1408,5 @@
                     boot_physical_write(paddr, 1);
 #if BOOT_DEBUG_PERI
-boot_puts("- IOC initialised\n");
+                    boot_puts("- IOC initialised\n");
 #endif
                 }
@@ -1281,5 +1419,5 @@
                     }
 #if BOOT_DEBUG_PERI
-boot_puts("- DMA initialised\n");
+                    boot_puts("- DMA initialised\n");
 #endif
                 break;
@@ -1290,10 +1428,10 @@
                     }
 #if BOOT_DEBUG_PERI
-boot_puts("- NIC initialised\n");
+                    boot_puts("- NIC initialised\n");
 #endif
                 break;
                 case PERIPH_TYPE_TTY:    // vci_multi_tty component
 #if BOOT_DEBUG_PERI
-boot_puts("- TTY initialised\n");
+                boot_puts("- TTY initialised\n");
 #endif
                 break;
@@ -1310,5 +1448,5 @@
                     }
 #if BOOT_DEBUG_PERI
-boot_puts("- IOB initialised\n");
+                    boot_puts("- IOB initialised\n");
 #endif
                 break;
@@ -1317,7 +1455,7 @@
 
 #if BOOT_DEBUG_PERI
-boot_puts("\n[BOOT DEBUG] ****** coprocessors initialisation in cluster ");
-boot_putd(cluster_id);
-boot_puts(" ******\n");
+        boot_puts("\n[BOOT DEBUG] ****** coprocessors initialisation in cluster ");
+        boot_putd(cluster_id);
+        boot_puts(" ******\n");
 #endif
 
@@ -1333,9 +1471,9 @@
 
 #if BOOT_DEBUG_PERI
-boot_puts("- coprocessor name : ");
-boot_puts(coproc[coproc_id].name);
-boot_puts(" / nb ports = ");
-boot_putd((unsigned int) coproc[coproc_id].ports);
-boot_puts("\n");
+            boot_puts("- coprocessor name : ");
+            boot_puts(coproc[coproc_id].name);
+            boot_puts(" / nb ports = ");
+            boot_putd((unsigned int) coproc[coproc_id].ports);
+            boot_puts("\n");
 #endif
 
@@ -1354,5 +1492,5 @@
                 {
 #if BOOT_DEBUG_PERI
-boot_puts("     port direction: PORT_TO_COPROC");
+                    boot_puts("     port direction: PORT_TO_COPROC");
 #endif
                     mwmr_hw_init(coproc_pbase, 
@@ -1365,5 +1503,5 @@
                 {
 #if BOOT_DEBUG_PERI
-boot_puts("     port direction: PORT_FROM_COPROC");
+                    boot_puts("     port direction: PORT_FROM_COPROC");
 #endif
                     mwmr_hw_init(coproc_pbase, 
@@ -1374,8 +1512,8 @@
                 }
 #if BOOT_DEBUG_PERI
-boot_puts(", with mwmr: ");
-boot_puts(vobj[vobj_id].name);
-boot_puts(" of vspace: ");
-boot_puts(vspace[vspace_id].name);
+                boot_puts(", with mwmr: ");
+                boot_puts(vobj[vobj_id].name);
+                boot_puts(" of vspace: ");
+                boot_puts(vspace[vspace_id].name);
 #endif
             } // end for cp_ports
@@ -1473,7 +1611,7 @@
 
 #if BOOT_DEBUG_SCHED
-boot_puts("\n[BOOT DEBUG] Initialise schedulers in cluster ");
-boot_putd(cluster_id);
-boot_puts("\n");
+        boot_puts("\n[BOOT DEBUG] Initialise schedulers in cluster ");
+        boot_putd(cluster_id);
+        boot_puts("\n");
 #endif
 
@@ -1523,9 +1661,9 @@
 
 #if BOOT_DEBUG_SCHED
-boot_puts("\nProc ");
-boot_putd(lpid);
-boot_puts(" : scheduler virtual base address = ");
-boot_putx( sched_vbase + (lpid<<12) );
-boot_puts("\n");
+            boot_puts("\nProc ");
+            boot_putd(lpid);
+            boot_puts(" : scheduler virtual base address = ");
+            boot_putx( sched_vbase + (lpid<<12) );
+            boot_puts("\n");
 #endif
             // current processor scheduler pointer : psched
@@ -1552,15 +1690,15 @@
 
 #if BOOT_DEBUG_SCHED
-boot_puts("- IRQ : icu = ");
-boot_putd(icu_id);
-boot_puts(" / type = ");
-boot_putd(type);
-boot_puts(" / isr = ");
-boot_putd(isr_id);
-boot_puts(" / channel = ");
-boot_putd(channel);
-boot_puts(" => vector_entry = ");
-boot_putx( value );
-boot_puts("\n");
+                boot_puts("- IRQ : icu = ");
+                boot_putd(icu_id);
+                boot_puts(" / type = ");
+                boot_putd(type);
+                boot_puts(" / isr = ");
+                boot_putd(isr_id);
+                boot_puts(" / channel = ");
+                boot_putd(channel);
+                boot_puts(" => vector_entry = ");
+                boot_putx( value );
+                boot_puts("\n");
 #endif
             }
@@ -1580,7 +1718,7 @@
 
 #if BOOT_DEBUG_SCHED
-boot_puts("\n[BOOT DEBUG] Initialise task contexts for vspace ");
-boot_puts(vspace[vspace_id].name);
-boot_puts("\n");
+        boot_puts("\n[BOOT DEBUG] Initialise task contexts for vspace ");
+        boot_puts(vspace[vspace_id].name);
+        boot_puts("\n");
 #endif
         // We must set the PTPR depending on the vspace, because the start_vector 
@@ -1781,41 +1919,41 @@
 
 #if BOOT_DEBUG_SCHED
-boot_puts("\nTask ");
-boot_puts(task[task_id].name);
-boot_puts(" (");
-boot_putd(task_id);
-boot_puts(") allocated to processor ");
-boot_putd(gpid);
-boot_puts("\n  - ctx[LTID]   = ");
-boot_putd(ltid);
-boot_puts("\n  - ctx[SR]     = ");
-boot_putx(ctx_sr);
-boot_puts("\n  - ctx[SR]     = ");
-boot_putx(ctx_sp);
-boot_puts("\n  - ctx[RA]     = ");
-boot_putx(ctx_ra);
-boot_puts("\n  - ctx[EPC]    = ");
-boot_putx(ctx_epc);
-boot_puts("\n  - ctx[PTPR]   = ");
-boot_putx(ctx_ptpr);
-boot_puts("\n  - ctx[TTY]    = ");
-boot_putd(ctx_tty);
-boot_puts("\n  - ctx[NIC]    = ");
-boot_putd(ctx_nic);
-boot_puts("\n  - ctx[CMA]    = ");
-boot_putd(ctx_cma);
-boot_puts("\n  - ctx[IOC]    = ");
-boot_putd(ctx_ioc);
-boot_puts("\n  - ctx[TIM]    = ");
-boot_putd(ctx_tim);
-boot_puts("\n  - ctx[DMA]    = ");
-boot_putd(ctx_dma);
-boot_puts("\n  - ctx[PTAB]   = ");
-boot_putx(ctx_ptab);
-boot_puts("\n  - ctx[GTID]   = ");
-boot_putd(task_id);
-boot_puts("\n  - ctx[VSID]   = ");
-boot_putd(vspace_id);
-boot_puts("\n");
+            boot_puts("\nTask ");
+            boot_puts(task[task_id].name);
+            boot_puts(" (");
+            boot_putd(task_id);
+            boot_puts(") allocated to processor ");
+            boot_putd(gpid);
+            boot_puts("\n  - ctx[LTID]   = ");
+            boot_putd(ltid);
+            boot_puts("\n  - ctx[SR]     = ");
+            boot_putx(ctx_sr);
+            boot_puts("\n  - ctx[SR]     = ");
+            boot_putx(ctx_sp);
+            boot_puts("\n  - ctx[RA]     = ");
+            boot_putx(ctx_ra);
+            boot_puts("\n  - ctx[EPC]    = ");
+            boot_putx(ctx_epc);
+            boot_puts("\n  - ctx[PTPR]   = ");
+            boot_putx(ctx_ptpr);
+            boot_puts("\n  - ctx[TTY]    = ");
+            boot_putd(ctx_tty);
+            boot_puts("\n  - ctx[NIC]    = ");
+            boot_putd(ctx_nic);
+            boot_puts("\n  - ctx[CMA]    = ");
+            boot_putd(ctx_cma);
+            boot_puts("\n  - ctx[IOC]    = ");
+            boot_putd(ctx_ioc);
+            boot_puts("\n  - ctx[TIM]    = ");
+            boot_putd(ctx_tim);
+            boot_puts("\n  - ctx[DMA]    = ");
+            boot_putd(ctx_dma);
+            boot_puts("\n  - ctx[PTAB]   = ");
+            boot_putx(ctx_ptab);
+            boot_puts("\n  - ctx[GTID]   = ");
+            boot_putd(task_id);
+            boot_puts("\n  - ctx[VSID]   = ");
+            boot_putd(vspace_id);
+            boot_puts("\n");
 #endif
 
@@ -1848,11 +1986,8 @@
     boot_check_mapping();
 
-    // pseg allocators initialisation 
-    boot_psegs_init();
-
     // page table building
     boot_pt_init();
 
-    // mmu activation ( with page table [0] )
+    // mmu activation (with page table [0])
     boot_set_mmu_ptpr((unsigned int) (boot_ptabs_paddr[0] >> 13));
     boot_set_mmu_mode(0xF);
@@ -1864,4 +1999,7 @@
     // vobjs initialisation
     boot_vobjs_init();
+
+    // reset ptpr with page table 0
+    boot_set_mmu_ptpr((unsigned int) (boot_ptabs_paddr[0] >> 13));
 
     // peripherals initialisation
Index: /soft/giet_vm/libs/spin_lock.c
===================================================================
--- /soft/giet_vm/libs/spin_lock.c	(revision 254)
+++ /soft/giet_vm/libs/spin_lock.c	(revision 255)
@@ -39,4 +39,5 @@
             "sc   $3,    0($16)             \n" /* try to get lock */
             "bnez $3,    giet_lock_ok       \n" /* exit if atomic */
+            "nop                            \n"
 
             "giet_lock_delay:               \n"
Index: /soft/giet_vm/libs/stdio.c
===================================================================
--- /soft/giet_vm/libs/stdio.c	(revision 254)
+++ /soft/giet_vm/libs/stdio.c	(revision 255)
@@ -45,4 +45,5 @@
 #define SYSCALL_NIC_SYNC_READ     0x1E
 #define SYSCALL_NIC_SYNC_WRITE    0x1F
+#define SYSCALL_SIM_HELPER_ACCESS 0x20
 
 //////////////////////////////////////////////////////////////////////////////////
@@ -851,4 +852,72 @@
 
 
+////////////////////////////////////////////////////////////////////////////////////
+// giet_sc_stop()
+// This function causes the Sim Helper to cause sc_stop()
+////////////////////////////////////////////////////////////////////////////////////
+unsigned int giet_sc_stop()
+{
+    unsigned int reg_index = 0; // Index of the SIMHELPER_SC_STOP register
+    return sys_call(SYSCALL_SIM_HELPER_ACCESS, reg_index, 0, 0, 0);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+// giet_end_simu()
+// This function causes the Sim Helper to cause exit(val)
+////////////////////////////////////////////////////////////////////////////////////
+unsigned int giet_end_simu(unsigned int val)
+{
+    unsigned int reg_index = 1; // Index of the SIMHELPER_END_WITH_RETVAL register
+    return sys_call(SYSCALL_SIM_HELPER_ACCESS, reg_index, val, 0, 0);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+// giet_throw_soclib_exception()
+// This function causes the Sim Helper to launch a soclib exception with val in message
+////////////////////////////////////////////////////////////////////////////////////
+unsigned int giet_throw_soclib_exception(unsigned int val)
+{
+    unsigned int reg_index = 2; // Index of the SIMHELPER_EXCEPT_WITH_VAL register
+    return sys_call(SYSCALL_SIM_HELPER_ACCESS, reg_index, val, 0, 0);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+// giet_pause_simu()
+// This function causes the Sim Helper to pause the simulation
+////////////////////////////////////////////////////////////////////////////////////
+unsigned int giet_pause_simu()
+{
+    unsigned int reg_index = 3; // Index of the SIMHELPER_PAUSE_SIM register
+    return sys_call(SYSCALL_SIM_HELPER_ACCESS, reg_index, 0, 0, 0);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+// giet_raise_sigint()
+// This function causes the Sim Helper to call raise(SIGINT) to interrupt simulation
+////////////////////////////////////////////////////////////////////////////////////
+unsigned int giet_raise_sigint()
+{
+    unsigned int reg_index = 5; // Index of the SIMHELPER_PAUSE_SIM register
+    return sys_call(SYSCALL_SIM_HELPER_ACCESS, reg_index, 0, 0, 0);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+// giet_simhelper_cycles()
+// This function causes the Sim Helper to write the number of simulated cycles
+// at address *retval
+////////////////////////////////////////////////////////////////////////////////////
+unsigned int giet_simhelper_cycles(unsigned int * retval)
+{
+    unsigned int reg_index = 4; // Index of the SIMHELPER_PAUSE_SIM register
+    return sys_call(SYSCALL_SIM_HELPER_ACCESS, reg_index, 0, (unsigned int) retval, 0);
+}
+
+
+
 // Local Variables:
 // tab-width: 4
Index: /soft/giet_vm/libs/stdio.h
===================================================================
--- /soft/giet_vm/libs/stdio.h	(revision 254)
+++ /soft/giet_vm/libs/stdio.h	(revision 255)
@@ -50,8 +50,16 @@
 unsigned int giet_fb_cma_stop();
 
-/* Network controller relate functions */
+/* Network controller related functions */
 unsigned int giet_nic_cma_rx_init(void* buf0, void* buf1, unsigned int length);
 unsigned int giet_nic_cma_tx_init(void* buf0, void* buf1, unsigned int length);
 unsigned int giet_nic_cma_stop();
+
+/* Simulation Helper related functions */
+unsigned int giet_sc_stop();
+unsigned int giet_end_simu(unsigned int retval);
+unsigned int giet_throw_soclib_exception(unsigned int val);
+unsigned int giet_pause_simu();
+unsigned int giet_raise_sigint();
+unsigned int giet_simhelper_cycles(unsigned int * retval);
 
 /* Misc */
Index: /soft/giet_vm/memo/include/pseg.h
===================================================================
--- /soft/giet_vm/memo/include/pseg.h	(revision 254)
+++ /soft/giet_vm/memo/include/pseg.h	(revision 255)
@@ -58,4 +58,5 @@
 public:
 
+    int32_t     m_align;    // alignment of the first vobj
     bool        m_ident;    // identity mapping required if true
 
@@ -66,7 +67,6 @@
     size_t length() const;
     size_t type() const;
-    //void add( VObj& vobj );//add a VObj
 
-    void print( std::ostream &o ) const;
+    void print(std::ostream &o) const;
     friend std::ostream &operator<<( std::ostream &o, const VSeg &s )
     {
@@ -75,8 +75,8 @@
     }
 
-    VSeg& operator=( const VSeg &ref );
+    VSeg& operator=(const VSeg &ref);
 
     VSeg();
-    VSeg( const VSeg &ref );
+    VSeg(const VSeg &ref);
     VSeg(std::string&   binaryName, 
          std::string&   name, 
@@ -97,8 +97,5 @@
     size_t        m_type;
 
-    paddr_t       m_pageLimit;  // m_lma + m_length aligned on page size 
-    paddr_t       m_nextLma;    // next free base 
-    
-    void confNextLma();         // check m_nextLma is whithin the seg limits
+    static size_t m_pageSize;
 
 public:
@@ -106,49 +103,45 @@
     std::vector<VSeg> m_vsegs;
 
-    paddr_t     m_limit;        // m_lma + m_length
-
     const std::string& name() const;
     paddr_t lma() const;
     paddr_t length() const;
     size_t type() const;
-    paddr_t limit() const;
-    paddr_t nextLma() const;
 
     void check() const;
 
     void setName(std::string& name);
-    void setLma( paddr_t lma);
+    void setLma(paddr_t lma);
     void setLength(paddr_t length);
 
-    static paddr_t align( paddr_t toAlign, unsigned alignPow2);
-    static paddr_t pageAlign( paddr_t toAlign );
+    static paddr_t align(paddr_t toAlign, unsigned alignPow2);
+    static paddr_t pageAlign(paddr_t toAlign);
 
-    static void setPageSize(size_t pg);
+    static void setPageSize(size_t pg) {
+       m_pageSize = pg;
+    }
+    static size_t pageSize() {
+       return m_pageSize;
+    }
 
-    static size_t& pageSize();
+    void add(VSeg& vseg);    //add a VSeg
+    void addIdent(VSeg& vseg);
 
-    void add( VSeg& vseg );    //add a VSeg
-    void addIdent( VSeg& vseg );
 
-    void setNextLma( paddr_t nextLma);
-    void incNextLma( size_t inc);
+    void print(std::ostream &o) const;
 
-    void print( std::ostream &o ) const;
-
-    friend std::ostream &operator<<( std::ostream &o, const PSeg &s )
+    friend std::ostream &operator<<(std::ostream &o, const PSeg &s )
     {
         s.print(o);
         return o;
     }
-    PSeg & operator=( const PSeg &ref );
+    PSeg & operator=(const PSeg &ref);
 
     PSeg();
-    PSeg( const PSeg &ref );
-    PSeg( const std::string &name);
-    PSeg( const paddr_t lma);
-    PSeg( const std::string &name,
-          paddr_t lma,
-          paddr_t length,
-          size_t type);
+    PSeg(const PSeg &ref );
+    PSeg(const std::string &name);
+    PSeg(const std::string &name,
+         paddr_t lma,
+         paddr_t length,
+         size_t type);
     ~PSeg();
 };
Index: /soft/giet_vm/memo/src/memo.cpp
===================================================================
--- /soft/giet_vm/memo/src/memo.cpp	(revision 254)
+++ /soft/giet_vm/memo/src/memo.cpp	(revision 255)
@@ -41,7 +41,10 @@
 //#define MOVER_DEBUG
 
+size_t PSeg::m_pageSize;
+
+
 ////////////////////////////////////////////
-MeMo::MeMo( const std::string     &filename, 
-            const size_t          pageSize)
+MeMo::MeMo(const std::string     &filename, 
+           const size_t          pageSize)
         : m_path(filename),
           m_pathHandler(filename),
@@ -58,5 +61,5 @@
     m_size = load_bin(m_path, m_data);
 
-    // checking signature 
+    // checking signature
     mapping_header_t*   header = (mapping_header_t*)m_data; 
     if((IN_MAPPING_SIGNATURE != header->signature))
@@ -92,8 +95,8 @@
 
 /////////////////////////////////////////
-void MeMo::print( std::ostream &o ) const
+void MeMo::print(std::ostream &o) const
 {
     std::cout << "All sections:" << std::endl;
-    FOREACH( sect, m_generator->get_section_table() )
+    FOREACH(sect, m_generator->get_section_table())
     {
         assert(&*sect != NULL);
@@ -340,39 +343,37 @@
 void MeMo::vseg_map( mapping_vseg_t* vseg)
 {
-    mapping_vobj_t*  vobj   = get_vobj_base( (mapping_header_t*) m_data );
-    PSeg             *ps = &(m_psegh.get(vseg->psegid));
-    elfpp::section*  sect = NULL;
+    mapping_vobj_t * vobj = get_vobj_base((mapping_header_t*) m_data );
+    PSeg            * ps = &(m_psegh.get(vseg->psegid));
+    elfpp::section * sect = NULL;
     size_t           cur_vaddr;
-    paddr_t          cur_paddr;
+    paddr_t          cur_length;
     bool             first = true;
     bool             aligned = false;
-    VSeg*            vSO = new VSeg;
-    mapping_vobj_t*  cur_vobj;
+    VSeg *           vSO = new VSeg;
+    mapping_vobj_t * cur_vobj;
 
     vSO->m_name = std::string(vseg->name);
     vSO->m_vma  = vseg->vbase;
-    vSO->m_lma  = ps->nextLma();
+    vSO->m_lma  = 0;
 
     cur_vaddr = vseg->vbase;
-    cur_paddr = ps->nextLma();
-
-    size_t simple_size = 0; //for debug
-
-#ifdef MOVER_DEBUG
-std::cout << "--------------- vseg_map "<< vseg->name <<" ------------------" << std::endl;
-#endif
-
-    for ( size_t vobj_id = vseg->vobj_offset ; 
-          vobj_id < (vseg->vobj_offset + vseg->vobjs) ; vobj_id++ )
+    cur_length = 0; // curr_length of the vseg; a new vseg is necessarily aligned on a page boundary
+
+#ifdef MOVER_DEBUG
+    std::cout << "--------------- vseg_map "<< vseg->name <<" ------------------" << std::endl;
+#endif
+
+    for (size_t vobj_id = vseg->vobj_offset; 
+          vobj_id < (vseg->vobj_offset + vseg->vobjs); vobj_id++)
     {
         cur_vobj = &vobj[vobj_id];
 
 #ifdef MOVER_DEBUG
-std::cout << std::hex << "current vobj("<< vobj_id <<"): " << cur_vobj->name 
-          << " (" <<cur_vobj->vaddr << ")"
-          << " size: "<< cur_vobj->length 
-          << " type: " <<  cur_vobj->type << std::endl;
-#endif
-        if(cur_vobj->type == VOBJ_TYPE_BLOB)
+        std::cout << std::hex << "current vobj("<< vobj_id <<"): " << cur_vobj->name 
+                  << " (" <<cur_vobj->vaddr << ")"
+                  << " size: "<< cur_vobj->length 
+                  << " type: " <<  cur_vobj->type << std::endl;
+#endif
+        if (cur_vobj->type == VOBJ_TYPE_BLOB)
         {
             size_t blob_size;
@@ -380,11 +381,11 @@
 
 #ifdef MOVER_DEBUG
-std::cout << std::hex << "Handling: " << filePath << " ..." << std::endl;
-#endif
-
-            if(!filePath.compare(m_path))    // local blob: map_info
-            {
-#ifdef MOVER_DEBUG
-std::cout << "Found the vseg of the mapping info" << std::endl;
+            std::cout << std::hex << "Handling: " << filePath << " ..." << std::endl;
+#endif
+
+            if (!filePath.compare(m_path))    // local blob: map_info
+            {
+#ifdef MOVER_DEBUG
+                std::cout << "Found the vseg of the mapping info" << std::endl;
 #endif
                 blob_size = this->m_size;
@@ -394,5 +395,5 @@
             {
 #ifdef MOVER_DEBUG
-std::cout << "Found an BLOB vseg" << std::endl;
+                std::cout << "Found an BLOB vseg" << std::endl;
 #endif
                 blob_size = bin_size(filePath);
@@ -408,13 +409,16 @@
             assert(sect->get_content());//check allocation
 
-            if(!filePath.compare(m_path))    //local blob: map_info
+            if (!filePath.compare(m_path)) {   //local blob: map_info
                 //memcpy(sect->get_content(), m_data, sect->get_size());
                 /* this way the modification of the elf size are propageted to the giet */
                 sect->set_content(this->m_data);
+            }
             else
+            {
                 load_bin(filePath, sect->get_content());
-
-
-            if(blob_size > cur_vobj->length)
+            }
+
+
+            if (blob_size > cur_vobj->length)
             {
                 std::cout << std::hex << "!!! Warning, specified blob type vobj ("<<
@@ -424,12 +428,12 @@
             }
 
-            cur_vobj->length = blob_size;//set the true size of this BLOB vobj
+            cur_vobj->length = blob_size; //set the true size of this BLOB vobj
 
             vSO->m_file = filePath;
             vSO->m_loadable = true;
         }
-        else if(cur_vobj->type == VOBJ_TYPE_ELF)
+        else if (cur_vobj->type == VOBJ_TYPE_ELF)
         {
-            if(!first)
+            if (!first)
                 throw exception::RunTimeError(std::string("elf vobj type, must be placed first in a vseg"));
 
@@ -440,9 +444,9 @@
             std::cout << "Found an ELF vseg" << std::endl;
 #endif
-            if(m_loaders.count(filePath) == 0 )
+            if (m_loaders.count(filePath) == 0)
                 m_loaders[filePath] = new elfpp::object(filePath);
-            elfpp::object* loader = m_loaders[filePath];//TODO:free!?
-
-            sect =  new elfpp::section(*get_sect_by_addr(loader, cur_vaddr));//copy: for the case we replicate the code
+            elfpp::object * loader = m_loaders[filePath]; //TODO:free!?
+
+            sect =  new elfpp::section(*get_sect_by_addr(loader, cur_vaddr)); //copy: for the case we replicate the code
             if (!sect)
             {
@@ -457,19 +461,18 @@
             assert((elf_size > 0) and "ELF section empty ?");
 
-            if(!m_ginit)
+            if (!m_ginit)
             {
                 /** Initailising the header of the generator from the first binary,
                 ** we suppose that the header is the same for all the binarys **/
                 m_generator->copy_info(*loader, 64);
-                m_ginit=true;
-            }
-
-            if(elf_size > cur_vobj->length)
-            {
-                std::cout << "Warning, specified elf type vobj ("<<
-                cur_vobj->name  <<") size is "<< cur_vobj->length << ", the actual size is "
+                m_ginit = true;
+            }
+
+            if (elf_size > cur_vobj->length)
+            {
+                std::cout << "Warning, specified elf type vobj (" <<
+                cur_vobj->name  << ") size is " << cur_vobj->length << ", the actual size is "
                 << elf_size  << std::endl;
-                //assert((elf_size < cur_vobj->length) and "elf vobj length smaller than the actual content" );//???
-                assert((0) and "elf vobj length smaller than the actual content" );//???
+                assert((0) and "elf vobj length smaller than the actual content");
             }
 
@@ -481,51 +484,29 @@
 
         //aligning the vobj->paddr if necessary
-        //
-        if(cur_vobj->align)
+        if (cur_vobj->align)
         {
-            cur_paddr = PSeg::align(cur_paddr, cur_vobj->align);
+            cur_length = PSeg::align(cur_length, cur_vobj->align);
             aligned = true;
         }
 
         cur_vaddr += cur_vobj->length;
-        cur_paddr += cur_vobj->length;
-        simple_size += cur_vobj->length;
+        cur_length += cur_vobj->length;
         first = false;
     }
 
-    assert((cur_vaddr >= vseg->vbase ));
-    assert((cur_paddr >= ps->nextLma() ));
-
-    vSO->m_length = (cur_paddr - ps->nextLma()); //pageAlign is done by the psegs
-
-#ifdef MOVER_DEBUG
-    if(aligned)
-    {
-        std::cout << "vseg base "<< std::hex << ps->nextLma()
-        <<(ps->nextLma()+simple_size)  <<" size " << std::dec << simple_size <<
-        std::endl;
-
-        std::cout << "vseg aligned to: base: " << std::hex << ps->nextLma()
-        <<" to "<< std::hex << ps->nextLma()+vSO->m_length<< " size " << std::dec <<
-        vSO->m_length << std::endl;
-    }
-#endif
-
+    assert(cur_vaddr >= vseg->vbase);
+
+    vSO->m_length = cur_length; //pageAlign is done by the psegs
     vSO->m_ident = vseg->ident;
+    vSO->m_align = vobj[vseg->vobj_offset].align;
 
     //set the lma for vseg that are not peripherals
-    if(ps->type() != PSEG_TYPE_PERI)
-    {
-        if ( vseg->ident != 0 )    ps->addIdent( *vSO );
-        else                       ps->add( *vSO );
-    }
-
-    // increment NextLma if required
-    if(ps->type() == PSEG_TYPE_RAM)
-    {
-        ps->incNextLma( vSO->m_length );
-    }
-
-    if(!sect) return;
+    if (ps->type() != PSEG_TYPE_PERI)
+    {
+        if (vseg->ident != 0) ps->addIdent(*vSO);
+        else                  ps->add(*vSO);
+    }
+
+    if (!sect) return;
 
 #ifdef MOVER_DEBUG
@@ -540,30 +521,28 @@
 
 ///////////////////////////////
-void MeMo::buildMap(void* desc)
-{
-    mapping_header_t*   header = (mapping_header_t*)desc;  
-
-    mapping_cluster_t*  cluster = get_cluster_base( header );     
-    mapping_vspace_t*   vspace = get_vspace_base( header );     
-    mapping_pseg_t*     pseg   = get_pseg_base( header ); 
-    mapping_vseg_t*     vseg   = get_vseg_base( header );
+void MeMo::buildMap(void * desc)
+{
+    mapping_header_t * header  = (mapping_header_t *) desc;  
+
+    mapping_cluster_t * cluster = get_cluster_base(header);     
+    mapping_vspace_t *  vspace  = get_vspace_base(header);     
+    mapping_pseg_t *    pseg    = get_pseg_base(header); 
+    mapping_vseg_t *    vseg    = get_vseg_base(header);
 
     // get the psegs
 
 #ifdef MOVER_DEBUG
-std::cout << "\n******* Storing Pseg information *********\n" << std::endl;
-#endif
-
-    for ( size_t cluster_id = 0 ; cluster_id < header->clusters ; cluster_id++ )
-    {
-        for ( size_t pseg_id = cluster[cluster_id].pseg_offset ;
-              pseg_id < cluster[cluster_id].pseg_offset + cluster[cluster_id].psegs ;
-              pseg_id++ )
-        {
+    std::cout << "\n******* Storing Pseg information *********\n" << std::endl;
+#endif
+
+    for (size_t cluster_id = 0; cluster_id < header->clusters; cluster_id++) {
+        for (size_t pseg_id = cluster[cluster_id].pseg_offset;
+              pseg_id < cluster[cluster_id].pseg_offset + cluster[cluster_id].psegs;
+              pseg_id++) {
             std::string name(pseg[pseg_id].name);
-            PSeg *ps = new PSeg( name, 
-                                 pseg[pseg_id].base, 
-                                 pseg[pseg_id].length, 
-                                 pseg[pseg_id].type );
+            PSeg *ps = new PSeg(name, 
+                                pseg[pseg_id].base, 
+                                pseg[pseg_id].length, 
+                                pseg[pseg_id].type);
             m_psegh.m_pSegs.push_back(*ps);
         }
@@ -573,28 +552,44 @@
 
 #ifdef MOVER_DEBUG
-std::cout << "\n******* mapping global vsegs *********\n" << std::endl;
-#endif
-
-    for ( size_t vseg_id = 0 ; vseg_id < header->globals ; vseg_id++ )
-    {
-        vseg_map( &vseg[vseg_id]);
-    }
+    std::cout << "\n******* mapping global vsegs *********\n" << std::endl;
+#endif
+
+    // Mapping identity segments first
+    for (size_t vseg_id = 0; vseg_id < header->globals; vseg_id++) {
+        if (vseg[vseg_id].ident == 1) {
+            vseg_map(&vseg[vseg_id]);
+        }
+    }
+
+    // Mapping non-identity segments second
+    for (size_t vseg_id = 0; vseg_id < header->globals; vseg_id++) {
+        if (vseg[vseg_id].ident == 0) {
+            vseg_map(&vseg[vseg_id]);
+        }
+    }
+
+
 
     // loop on virtual spaces to map private vsegs
-    for (size_t vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
-    {
-
-#ifdef MOVER_DEBUG
-std::cout << "\n******* mapping all vsegs of " << vspace[vspace_id].name << " *********\n" << std::endl;
-#endif
-            
-        for ( size_t vseg_id = vspace[vspace_id].vseg_offset ; 
-              vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs) ; 
-              vseg_id++ )
-        {
-            vseg_map( &vseg[vseg_id]); 
+    for (size_t vspace_id = 0; vspace_id < header->vspaces; vspace_id++) {
+#ifdef MOVER_DEBUG
+        std::cout << "\n******* mapping all vsegs of " << vspace[vspace_id].name << " *********\n" << std::endl;
+#endif
+        for (size_t vseg_id = vspace[vspace_id].vseg_offset; 
+             vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs); 
+             vseg_id++) {
+            if (vseg[vseg_id].ident == 1) {
+                vseg_map(&vseg[vseg_id]); 
+            }
+        }
+ 
+        for (size_t vseg_id = vspace[vspace_id].vseg_offset; 
+             vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs); 
+             vseg_id++) {
+            if (vseg[vseg_id].ident == 0) {
+                vseg_map(&vseg[vseg_id]); 
+            }
         }
     } 
-
 } // end buildMap()
 
Index: /soft/giet_vm/memo/src/pseg.cpp
===================================================================
--- /soft/giet_vm/memo/src/pseg.cpp	(revision 254)
+++ /soft/giet_vm/memo/src/pseg.cpp	(revision 255)
@@ -35,6 +35,11 @@
 #include <iomanip>
 
+#include <cstdio>
+
 #include "pseg.h"
 #include "exception.h"
+
+
+#define max(x, y) (((x) > (y)) ? (x) : (y))
 
 
@@ -44,41 +49,35 @@
 
 //////////////////////////////////////
-const std::string & VSeg::name() const
-{
+const std::string & VSeg::name() const {
 	return m_name;
 }
 
 //////////////////////////////////////
-const std::string & VSeg::file() const
-{
+const std::string & VSeg::file() const {
 	return m_file;
 }
 
 ///////////////////////////
-uintptr_t VSeg::vma() const
-{
+uintptr_t VSeg::vma() const {
 	return m_vma;
 }
 
 /////////////////////////
-paddr_t VSeg::lma() const
-{
+paddr_t VSeg::lma() const {
 	return m_lma;
 }
 
 ///////////////////////////
-size_t VSeg::length() const
-{
+size_t VSeg::length() const {
 	return m_length;
 }
 
 /////////////////////////
-size_t VSeg::type() const
-{
+size_t VSeg::type() const {
 	return m_type;
 }
 
 /////////////////////////////////////////
-void VSeg::print( std::ostream &o ) const
+void VSeg::print(std::ostream &o) const
 {
 	o << std::hex << std::noshowbase 
@@ -89,21 +88,19 @@
       << m_lma << ", size: 0x"
       << std::setw (8) << std::setfill('0') 
-      << m_length  << ",ident: " 
-      << (m_ident ? "yes" : "no") << ", in(file): "
-      << m_file << ", name: " << m_name << ">";
+          << m_length  << ",ident: " 
+          << (m_ident ? "yes" : "no") << ", in(file): "
+          << m_file << ", name: " << m_name << ">";
 }
 
 /////////////
-VSeg::~VSeg()
-{
-}
+VSeg::~VSeg() {}
 
 /////////////////////////////////////////
-VSeg & VSeg::operator=( const VSeg &ref )
-{
-    if ( &ref == this )
+VSeg & VSeg::operator=(const VSeg & ref)
+{
+    if (&ref == this)
         return *this;
 
-    m_name = ref.m_name,
+    m_name = ref.m_name;
     m_file = ref.m_file;
     m_vma = ref.m_vma;
@@ -111,5 +108,5 @@
     m_length = ref.m_length;
     m_ident = ref.m_ident;
-	return *this;
+    return *this;
 }
 
@@ -117,9 +114,9 @@
 VSeg::VSeg()
     : m_name("No Name"),
-      m_file("Empty section"),
-      m_vma(0),
-      m_length(0),
-      m_loadable(false),
-      m_ident(0)
+    m_file("Empty section"),
+    m_vma(0),
+    m_length(0),
+    m_loadable(false),
+    m_ident(0)
 {
 }
@@ -127,26 +124,26 @@
 ////////////////////////////////////
 VSeg::VSeg(std::string&  binaryName, 
-           std::string&  name, 
-           uintptr_t     vma, 
-           size_t        length, 
-           bool          loadable, 
-           bool          ident)
-    : m_name(name),
-      m_file(binaryName),
-      m_vma(vma),
-      m_length(length),
-      m_loadable(loadable),
-      m_ident(ident)
+        std::string&  name, 
+        uintptr_t     vma, 
+        size_t        length, 
+        bool          loadable, 
+        bool          ident)
+: m_name(name),
+    m_file(binaryName),
+    m_vma(vma),
+    m_length(length),
+    m_loadable(loadable),
+    m_ident(ident)
 {
 }
 
 /////////////////////////////
-VSeg::VSeg( const VSeg &ref )
-    : m_name("To be copied"),
-      m_file("Empty"),
-      m_vma(0),
-      m_length(0),
-      m_loadable(false),
-      m_ident(0)
+VSeg::VSeg(const VSeg &ref):
+    m_name(ref.m_name),
+    m_file(ref.m_file),
+    m_vma(ref.m_vma),
+    m_length(ref.m_length),
+    m_loadable(ref.m_loadable),
+    m_ident(ref.m_ident)
 {
     (*this) = ref;
@@ -159,37 +156,21 @@
 
 /////////////////////////
-paddr_t PSeg::lma() const
-{
-	return m_lma;
+paddr_t PSeg::lma() const {
+    return m_lma;
 }
 
 ///////////////////////////
-paddr_t PSeg::limit() const
-{
-	return m_limit;
-}
-
-/////////////////////////////
-paddr_t PSeg::length() const
-{
-	return m_length;
+paddr_t PSeg::length() const {
+    return m_length;
 }
 
 /////////////////////////
-size_t PSeg::type() const
-{
-	return m_type;
-}
-
-/////////////////////////////
-paddr_t PSeg::nextLma() const
-{
-	return m_nextLma;
+size_t PSeg::type() const {
+    return m_type;
 }
 
 //////////////////////////////////////
-const std::string & PSeg::name() const
-{
-	return m_name;
+const std::string & PSeg::name() const {
+    return m_name;
 }
 
@@ -198,5 +179,5 @@
 {
 
-    if(this->m_type == PSEG_TYPE_PERI)
+    if (this->m_type == PSEG_TYPE_PERI)
         return;
 
@@ -204,25 +185,24 @@
     size_t    size = m_vsegs.size();
     paddr_t   used[size][2];          // lma, lma+length
-    size_t    i,j,error=0;
-    
-    for(it = m_vsegs.begin(), i= 0 ; it < m_vsegs.end() ; it++, i++)
+    size_t    i, j, error = 0;
+
+    for (it = m_vsegs.begin(), i = 0; it < m_vsegs.end(); it++, i++)
     {
         paddr_t it_limit = (*it).lma() + (*it).length();
-        for(j=0; j< i; j++)
+        for(j = 0; j < i; j++)
         {
-            if( used[j][0] == (*it).lma() ) //not the same lma ,
-            {
-                error = 1;
-                std::cout << "ok \n";
-            }
-            if( used[j][1] == it_limit )  // and not the same limit
+            if (used[j][0] == (*it).lma()) //not the same lma ,
+                {
+                    error = 1;
+                }
+            if (used[j][1] == it_limit)  // and not the same limit
             {
                 error = 2;
             }
-            if( (used[j][0] < (*it).lma()) and ((*it).lma() < used[j][1]) ) // lma  within
+            if ((used[j][0] < (*it).lma()) and ((*it).lma() < used[j][1])) // lma  within
             {
                 error = 3;
             }
-            if(  ((used[j][0] < it_limit) and (it_limit < used[j][1] )) ) // limit no within
+            if (((used[j][0] < it_limit) and (it_limit < used[j][1]))) // limit no within
             {
                 error = 4;
@@ -232,8 +212,8 @@
                 std::cout << "used[j][1]: " << std::hex << used[j][1] << std::endl;
             }
-            if(error)
+            if (error)
             {
                 std::ostringstream err;
-                err << " Error" << error << " ,ovelapping Buffers:" << std::endl 
+                err << " Error" << error << ", ovelapping Buffers:" << std::endl 
                     << *it << std::endl << m_vsegs[j] << std::endl; 
                 throw exception::RunTimeError( err.str().c_str() );
@@ -246,128 +226,138 @@
 }
 
-//////////////////////////////////////
-void PSeg::setName(std::string& name )
-{
-    m_name = name;
-}
 
 /////////////////////////////////////////////////////////
-paddr_t PSeg::align( paddr_t toAlign, unsigned alignPow2)
-{
+paddr_t PSeg::align(paddr_t toAlign, unsigned alignPow2) {
     return ((toAlign + (1 << alignPow2) - 1 ) >> alignPow2) << alignPow2; 
 }
 
 //////////////////////////////////////////
-paddr_t PSeg::pageAlign( paddr_t toAlign )
-{
+paddr_t PSeg::pageAlign(paddr_t toAlign) {
     size_t pgs = pageSize();
     size_t pageSizePow2 = __builtin_ctz(pgs);
-    
+
     return align(toAlign, pageSizePow2); 
 }
 
-////////////////////////////////
-void PSeg::setLma( paddr_t lma )
-{
-    m_lma = lma;
-    
-    m_nextLma = pageAlign(lma);
-
-    m_pageLimit = pageAlign(m_lma+m_length); 
-
-    m_limit = (m_lma + m_length);
-}
-
-/////////////////////////////////////
-void PSeg::setLength( paddr_t length )
-{
-    m_length = length;
-
-    m_pageLimit = pageAlign(m_lma+m_length); 
-
-    m_limit = (m_lma + m_length);
-}
+
 
 ////////////////////////////
-void PSeg::add( VSeg& vseg )
-{
-    vseg.m_lma = m_nextLma;
-//    incNextLma(vseg.length());   //for the next vseg
+void PSeg::add(VSeg& vseg) {
+    std::vector<VSeg>::iterator it;
+    int nb_elems = m_vsegs.size();
+    int i = 0;
+    bool mapped = false;
+    paddr_t prev_base = m_lma;
+    paddr_t prev_length = 0x0;
+    paddr_t curr_base = 0x0;
+    paddr_t curr_length = 0x0;
+    paddr_t next_base = 0x0;
+    paddr_t next_length = 0x0;
+
+    const int alignment = max(vseg.m_align, __builtin_ctz(pageSize())); // 12
+
+    if (vseg.length() == 0) {
+        std::cout << "*** Error: Adding a vseg of size 0 (base " << vseg.vma() << ")" << std::endl;
+        exit(1);
+    }
+
+    if (nb_elems == 0) {
+        if (vseg.length() <= m_length) {
+            vseg.m_lma = m_lma;
+            m_vsegs.push_back(vseg);
+            return;
+        }
+        else {
+            std::cout << "*** Error: Not enough space to map first VSeg (base = "
+                      << std::hex << vseg.vma() << " - Size = " << vseg.length() << ")" << std::endl;
+            std::cout << "    PSeg too small! (base = " << m_lma << " - size = "
+                      << m_length << ")" << std::endl;
+            exit(1);
+        }
+    }
+
+    curr_base = m_vsegs[0].lma(); // Initialisation avant recherche du min
+    curr_length = m_vsegs[0].length();
+    for (it = m_vsegs.begin(); it != m_vsegs.end(); it++) {
+        if ((*it).lma() < curr_base) {
+            curr_base = (*it).lma();
+            curr_length = (*it).length();
+        }
+    }
+
+    while (i < nb_elems) {
+        if (align(prev_base + prev_length, alignment) + vseg.length() <= curr_base) {
+            vseg.m_lma = align(prev_base + prev_length, alignment);
+            mapped = true;
+            break;
+        }
+        else if (i < nb_elems - 1) {
+            // Searching for the vseg already mapped with lowest paddr > curr_base
+            next_base = 0;
+            bool found = false;
+            for (it = m_vsegs.begin(); it != m_vsegs.end(); it++) {
+                if ((!found || (*it).lma() < next_base) && (*it).lma() > curr_base) {
+                    found = true;
+                    next_base = (*it).lma();
+                    next_length = (*it).length();
+                }
+            }
+            assert(found);
+
+            prev_base = curr_base;
+            prev_length = curr_length;
+
+            curr_base = next_base;
+            curr_length = next_length;
+        }
+        else {
+            if (align(curr_base + curr_length, alignment) + vseg.length() <= m_lma + m_length) {
+                vseg.m_lma = align(curr_base + curr_length, alignment);
+                mapped = true;
+            }
+        }
+        i++;
+    }
+
+    if (!mapped) {
+        std::cout << "*** Error: Not enough space to map VSeg (base = " << std::hex << vseg.vma() << " - Size = " << vseg.length() << ")" << std::endl;
+        exit(1);
+    }
+
     m_vsegs.push_back(vseg); 
 }
 
+
 /////////////////////////////////
-void PSeg::addIdent( VSeg& vseg )
-{
+void PSeg::addIdent(VSeg& vseg) {
+    std::vector<VSeg>::iterator it;
+
+    for (it = m_vsegs.begin(); it != m_vsegs.end(); it++) {
+        if ((vseg.vma() == (*it).lma()) ||
+            ((vseg.vma() < (*it).lma()) && (vseg.vma() + vseg.length() > (*it).lma())) ||
+            ((vseg.vma() > (*it).lma()) && ((*it).lma() + (*it).length() > vseg.vma()))) {
+            std::cout << "*** Error: Identity VSeg overlaps another segment:" << std::endl
+                      << "Added Segment Base : " << std::hex << vseg.vma()
+                      << " - Size : " << vseg.length() << std::endl;
+            std::cout << "Existing Segment Base : " << (*it).lma()
+                      << " - size : " << (*it).length() << std::endl;
+            exit(1);
+        }
+    }
+
     vseg.m_lma = vseg.m_vma;
     m_vsegs.push_back(vseg); 
 }
 
+
 /////////////////////////////////////////
-void PSeg::setNextLma( paddr_t nextLma)
-{
-    m_nextLma = nextLma;
-    confNextLma();
-}
-
-//////////////////////////////////
-void PSeg::incNextLma( size_t inc)
-{
-    m_nextLma += inc;
-    confNextLma();
-}
-
-////////////////////////
-void PSeg::confNextLma()
-{
-    if(m_nextLma > m_limit)
-    {
-        std::cerr << "Erreur pseg overflow... nextLma: "
-                  << std::hex << m_nextLma << ", limit: " 
-                  << m_limit << std::endl;
-        exit(1); 
-    }
-
-    m_nextLma = pageAlign( m_nextLma );
-
-    if(m_nextLma > m_pageLimit)
-    {
-        std::cerr << "Erreur pseg page overflow... nextLma: "
-                  << std::hex << m_nextLma << ", limit: " 
-                  << m_pageLimit << std::endl;
-        exit(1); 
-    }
-}
-
-/////////////////////////////////
-void PSeg::setPageSize(size_t pg)
-{
-    if( pg == 0)
-    {
-        std::cerr << "PageSize must be positive" << std::endl;
-        return;
-    }
-    pageSize() = pg;
-}
-
-////////////////////////
-size_t& PSeg::pageSize()
-{
-    static size_t m_pageSize;
-    return m_pageSize;
-}
-
-/////////////////////////////////////////
-PSeg & PSeg::operator=( const PSeg &ref )
-{
-    if ( &ref == this )
+PSeg & PSeg::operator=(const PSeg &ref) {
+    if (&ref == this) {
         return *this;
+    }
 
     m_name = ref.m_name;
     m_length = ref.m_length;
-    m_limit = ref.m_limit;
-    m_pageLimit = ref.m_pageLimit;
     m_lma = ref.m_lma;
-    m_nextLma = ref.m_nextLma;
     m_vsegs = ref.m_vsegs;
     m_type = ref.m_type;
@@ -377,12 +367,11 @@
 
 //////////////////////////////////////////
-void PSeg::print( std::ostream &o ) const
+void PSeg::print(std::ostream &o) const
 {
 	o << "<Physical segment "
 	  << std::showbase << m_name
 	  << ", from: " << std::hex 
-      << m_lma << " to " << m_limit 
+      << m_lma
       << ", size : "  << m_length 
-      << ", filled to: "  << m_nextLma 
       << ", type : "  << m_type 
       << ", containing: "<< std::endl;
@@ -403,54 +392,27 @@
     m_length = length;
     m_type = type;
-
-    setLma(lma);
+    m_lma = lma;
 }
 
 ////////////////////////////////////
-PSeg::PSeg( const std::string &name):
+PSeg::PSeg(const std::string &name):
       m_lma(0),
-      m_length(0),
-      m_nextLma(0),
-      m_limit(0)
-{
+      m_length(0) {
     m_name = name;
 }
 
-////////////////////////
-PSeg::PSeg( paddr_t lma):
-      m_name("No name"),
-      m_lma(0),
-      m_length(0),
-      m_nextLma(0),
-      m_limit(0)
-{
-    setLma(lma);
-}
-
-////////////
-PSeg::PSeg()
-    :
-      m_name("Empty section"),
-      m_lma(0),
-      m_length(0),
-      m_nextLma(0),
-      m_limit(0)
-{
-}
-
-/////////////////////////////
-PSeg::PSeg( const PSeg &ref )
-    : m_name("To be copied"),
-      m_lma(0),
-      m_length(0),
-      m_nextLma(0),
-      m_limit(0)
-{
-    (*this) = ref;
-}
-
-PSeg::~PSeg()
-{
-}
+
+////////////////////////////////////
+PSeg::PSeg(const PSeg& pseg) {
+    m_name = pseg.m_name;
+    m_length = pseg.m_length;
+    m_lma = pseg.m_lma;
+    m_vsegs = pseg.m_vsegs;
+    m_type = pseg.m_type;
+
+    (*this) = pseg;
+}
+
+PSeg::~PSeg() {}
 
 
Index: /soft/giet_vm/sys/common.h
===================================================================
--- /soft/giet_vm/sys/common.h	(revision 254)
+++ /soft/giet_vm/sys/common.h	(revision 255)
@@ -31,4 +31,5 @@
 extern _ld_symbol_t seg_mmc_base;
 extern _ld_symbol_t seg_cma_base;
+extern _ld_symbol_t seg_sim_base;
 
 extern _ld_symbol_t vseg_cluster_increment;
Index: /soft/giet_vm/sys/drivers.c
===================================================================
--- /soft/giet_vm/sys/drivers.c	(revision 254)
+++ /soft/giet_vm/sys/drivers.c	(revision 255)
@@ -1834,4 +1834,40 @@
 }
 
+
+////////////////////////////////////////////////////////////////////////////////
+// _sim_helper_access()
+// Accesses the Simulation Helper Component
+// If the access is on a writable register (except SIMHELPER_PAUSE_SIM),
+// the function should never return since the simulation will stop before
+// If the access is on a readable register, returns 0 on success, 1 on failure,
+// and writes the return value at address retval
+////////////////////////////////////////////////////////////////////////////////
+unsigned int _sim_helper_access(unsigned int register_index,
+                                unsigned int value,
+                                unsigned int * retval) {
+    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) {
+        sim_helper_address[register_index] = value;
+    }
+    else if (register_index == SIMHELPER_CYCLES) {
+        *retval = sim_helper_address[register_index];
+    }
+    else {
+        _get_lock(&_tty_put_lock);
+        _puts("\n[GIET ERROR] in _sim_helper_access() : access to unmapped register\n");
+        _release_lock(&_tty_put_lock);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+
 // Local Variables:
 // tab-width: 4
Index: /soft/giet_vm/sys/drivers.h
===================================================================
--- /soft/giet_vm/sys/drivers.h	(revision 254)
+++ /soft/giet_vm/sys/drivers.h	(revision 255)
@@ -132,4 +132,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
+// Sim Helper access function
+///////////////////////////////////////////////////////////////////////////////////
+unsigned int _sim_helper_access(unsigned int register_index,
+                                unsigned int value,
+                                unsigned int * retval);
+
+///////////////////////////////////////////////////////////////////////////////////
 // MEMC access functions
 ///////////////////////////////////////////////////////////////////////////////////
Index: /soft/giet_vm/sys/giet.s
===================================================================
--- /soft/giet_vm/sys/giet.s	(revision 254)
+++ /soft/giet_vm/sys/giet.s	(revision 255)
@@ -9,5 +9,5 @@
 * - the _cause_vector[16] array defines the 16 causes to enter the GIET
 *   it is initialized in th exc_handler.c file
-* - the _syscall_vector[32] array defines the 32 system calls entry points
+* - the _syscall_vector[64] array defines the 64 system calls entry points
 *   it is initialised in the sys_handler.c file 
 ***********************************************************************************/
@@ -38,5 +38,5 @@
  *
  * A system call is handled as a special function call.
- *  - $2 contains the system call index (< 16).
+ *  - $2 contains the system call index (< 64).
  *  - $3 is used to store the syscall address
  *  - $4, $5, $6, $7 contain the arguments values.
@@ -62,5 +62,5 @@
     sw      $27,    20($29)         /* save it in the stack */
 
-    andi    $26,    $2,     0x1F    /* $26 <= syscall index (i < 32) */
+    andi    $26,    $2,     0x3F    /* $26 <= syscall index (i < 64) */
     sll     $26,    $26,    2       /* $26 <= index * 4 */
     la      $27,    _syscall_vector /* $27 <= &_syscall_vector[0] */
Index: /soft/giet_vm/sys/hwr_mapping.h
===================================================================
--- /soft/giet_vm/sys/hwr_mapping.h	(revision 254)
+++ /soft/giet_vm/sys/hwr_mapping.h	(revision 255)
@@ -192,4 +192,16 @@
 };
 
+enum SoclibSimhelperRegisters
+{
+    SIMHELPER_SC_STOP,
+    SIMHELPER_END_WITH_RETVAL,
+    SIMHELPER_EXCEPT_WITH_VAL,
+    SIMHELPER_PAUSE_SIM,
+    SIMHELPER_CYCLES,
+    SIMHELPER_SIGINT,
+};
+
+
+
 #endif
 
Index: /soft/giet_vm/sys/sys_handler.c
===================================================================
--- /soft/giet_vm/sys/sys_handler.c	(revision 254)
+++ /soft/giet_vm/sys/sys_handler.c	(revision 255)
@@ -6,5 +6,5 @@
 ///////////////////////////////////////////////////////////////////////////////////
 // The sys_handler.c and sys_handler.h files are part of the GIET-VM nano-kernel.
-// It define the syscall_vector[] (at the end of this file), as well as the 
+// It defines the syscall_vector[], as well as the 
 // associated syscall handlers that are not related to peripherals.
 // The syscall handlers for peripherals are defined in the drivers.c file.
@@ -21,5 +21,5 @@
 //    Initialize the syscall vector with syscall handlers
 ////////////////////////////////////////////////////////////////////////////
-const void * _syscall_vector[32] = 
+const void * _syscall_vector[64] = 
 {
     &_procid,              /* 0x00 */
@@ -55,4 +55,5 @@
     &_nic_sync_read,       /* 0x1E */
     &_nic_sync_write,      /* 0x1F */
+    &_sim_helper_access,   /* 0x20 */
 };
 
Index: /soft/giet_vm/sys/sys_handler.h
===================================================================
--- /soft/giet_vm/sys/sys_handler.h	(revision 254)
+++ /soft/giet_vm/sys/sys_handler.h	(revision 255)
@@ -13,5 +13,5 @@
 //////////////////////////////////////////////////////////////////////////////////
 
-extern const void * _syscall_vector[32];
+extern const void * _syscall_vector[64];
 
 //////////////////////////////////////////////////////////////////////////////////
Index: /soft/giet_vm/xml/mapping_info.h
===================================================================
--- /soft/giet_vm/xml/mapping_info.h	(revision 254)
+++ /soft/giet_vm/xml/mapping_info.h	(revision 255)
@@ -106,6 +106,7 @@
     PERIPH_TYPE_GCD       = 10,
     PERIPH_TYPE_XCU       = 11,
-
-    PERIPH_TYPE_MAX_VALUE = 12,
+    PERIPH_TYPE_SIM       = 12,
+
+    PERIPH_TYPE_MAX_VALUE = 13,
 };
 
@@ -142,4 +143,6 @@
     unsigned int iob_cluster;        // index of cluster containing IOB controler
     unsigned int iob_cluster_bis;    // index of cluster containing second IOB controler
+    unsigned int sim_cluster;        // index of cluster containing the Simulation Helper
+    unsigned int sim_cluster_bis;    // index of cluster containing the Simulation Helper
 
     unsigned int psegs;              // total number of physical segments (for all clusters)
@@ -182,5 +185,4 @@
     unsigned int type;           // RAM / ROM / PERI
     unsigned int cluster;        // index of cluster containing pseg
-    paddr_t      next_base;      // first free page base address
 } mapping_pseg_t;
 
@@ -206,4 +208,5 @@
     unsigned int vbase;          // base address in virtual space
     paddr_t      pbase;          // base address in physical space
+    unsigned int pbase_set;
     unsigned int length;         // size (bytes)
     unsigned int psegid;         // physical segment global index
@@ -234,5 +237,5 @@
 
 /////////////////////////////
-typedef struct __attribute__((packed))  mapping_vobj_s 
+typedef struct __attribute__((packed))  mapping_vobj_s
 {
     char         name[32];       // vobj name (unique in a vspace)
Index: /soft/giet_vm/xml/xml_parser.c
===================================================================
--- /soft/giet_vm/xml/xml_parser.c	(revision 254)
+++ /soft/giet_vm/xml/xml_parser.c	(revision 255)
@@ -748,4 +748,6 @@
     ////////// set vobj_offset attributes
     vseg[vseg_index]->vobj_offset = vobj_index;
+    // Init pbase_set to false
+    vseg[vseg_index]->pbase_set = 0;
 
 #if XML_PARSER_DEBUG
@@ -1273,4 +1275,20 @@
             }
         }
+        else if (strcmp(str, "SIM") == 0) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_SIM;
+            if (header->sim_cluster == 0xFFFFFFFF)  
+            {
+                header->sim_cluster = cluster_index; 
+            }
+            else if (header->sim_cluster_bis == 0xFFFFFFFF) 
+            {
+                header->sim_cluster_bis = cluster_index; 
+            }
+            else
+            {
+                error = 1;
+            }
+        }
         // The TIM, ICU, XICU, DMA, MEMC peripherals are replicated in all clusters
         // but it must exist only one component of each type per cluster
@@ -2086,4 +2104,5 @@
     header->cma_cluster = 0xFFFFFFFF;
     header->iob_cluster = 0xFFFFFFFF;
+    header->sim_cluster = 0xFFFFFFFF;
     header->tty_cluster_bis = 0xFFFFFFFF;
     header->nic_cluster_bis = 0xFFFFFFFF;
@@ -2092,4 +2111,5 @@
     header->cma_cluster_bis = 0xFFFFFFFF;
     header->iob_cluster_bis = 0xFFFFFFFF;
+    header->sim_cluster_bis = 0xFFFFFFFF;
 
     ///////// set signature
@@ -2162,7 +2182,7 @@
     }
 
-    //#if XML_PARSER_DEBUG
+    #if XML_PARSER_DEBUG
     printf("%s\n", file_path);
-    //#endif
+    #endif
 
     return fdout;
@@ -2424,4 +2444,5 @@
     ld_write(fdout, "seg_iob_base            ",   periph_vbase_array[PERIPH_TYPE_IOB]);
     ld_write(fdout, "seg_gcd_base            ",   periph_vbase_array[PERIPH_TYPE_GCD]);
+    ld_write(fdout, "seg_sim_base            ",   periph_vbase_array[PERIPH_TYPE_SIM]);
 
     file_write(fdout, "\n");
