Index: trunk/kernel/mm/vmm.c
===================================================================
--- trunk/kernel/mm/vmm.c	(revision 401)
+++ trunk/kernel/mm/vmm.c	(revision 406)
@@ -62,5 +62,5 @@
     intptr_t  size;
 
-    vmm_dmsg("\n[INFO] %s : enter for process %x\n", __FUNCTION__ , process->pid );
+    vmm_dmsg("\n[DMSG] %s : enter for process %x\n", __FUNCTION__ , process->pid );
 
     // get pointer on VMM
@@ -83,46 +83,47 @@
     vmm->vsegs_nr = 0;
 	list_root_init( &vmm->vsegs_root );
-    error = grdxt_init( &vmm->grdxt,
-                        CONFIG_VMM_GRDXT_W1,
-                        CONFIG_VMM_GRDXT_W2,
-                        CONFIG_VMM_GRDXT_W3 );
- 
-    assert( (error == 0) , __FUNCTION__ , "cannot initialize radix tree\n" );
 
     // register kentry vseg in VMM
-    base = 1 << CONFIG_PPM_PAGE_SHIFT;
+    base = CONFIG_VMM_KENTRY_BASE << CONFIG_PPM_PAGE_SHIFT;
     size = CONFIG_VMM_KENTRY_SIZE << CONFIG_PPM_PAGE_SHIFT;
+
     vseg_kentry = vmm_create_vseg( process , base , size , VSEG_TYPE_CODE );
 
     assert( (vseg_kentry != NULL) , __FUNCTION__ , "cannot register kentry vseg\n" );
 
-    vmm->kent_vpn_base = 1;
-
-    // register the args vseg in VMM
-    base = (CONFIG_VMM_KENTRY_SIZE + 1 )<<CONFIG_PPM_PAGE_SHIFT;
+    vmm->kent_vpn_base = base;
+
+    // register args vseg in VMM
+    base = (CONFIG_VMM_KENTRY_BASE + 
+            CONFIG_VMM_KENTRY_SIZE ) << CONFIG_PPM_PAGE_SHIFT;
     size = CONFIG_VMM_ARGS_SIZE << CONFIG_PPM_PAGE_SHIFT;
+
     vseg_args = vmm_create_vseg( process , base , size , VSEG_TYPE_DATA );
 
     assert( (vseg_args != NULL) , __FUNCTION__ , "cannot register args vseg\n" );
 
-    vmm->args_vpn_base = CONFIG_VMM_KENTRY_SIZE + 1;
+    vmm->args_vpn_base = base;
 
     // register the envs vseg in VMM
-    base = (CONFIG_VMM_KENTRY_SIZE + CONFIG_VMM_ARGS_SIZE + 1 )<<CONFIG_PPM_PAGE_SHIFT;
+    base = (CONFIG_VMM_KENTRY_BASE + 
+            CONFIG_VMM_KENTRY_SIZE +
+            CONFIG_VMM_ARGS_SIZE   ) << CONFIG_PPM_PAGE_SHIFT;
     size = CONFIG_VMM_ENVS_SIZE << CONFIG_PPM_PAGE_SHIFT;
+
     vseg_envs = vmm_create_vseg( process , base , size , VSEG_TYPE_DATA );
 
     assert( (vseg_envs != NULL) , __FUNCTION__ , "cannot register envs vseg\n" );
 
-    vmm->envs_vpn_base = CONFIG_VMM_KENTRY_SIZE + CONFIG_VMM_ARGS_SIZE + 1;
+    vmm->envs_vpn_base = base;
 
     // register the heap vseg in VMM
     base = CONFIG_VMM_HEAP_BASE << CONFIG_PPM_PAGE_SHIFT;
     size = (CONFIG_VMM_MMAP_BASE-CONFIG_VMM_HEAP_BASE) << CONFIG_PPM_PAGE_SHIFT;
+
     vseg_heap = vmm_create_vseg( process , base , size , VSEG_TYPE_HEAP );
 
     assert( (vseg_heap != NULL) , __FUNCTION__ , "cannot register heap vseg\n" );
 
-    vmm->heap_vpn_base = CONFIG_VMM_HEAP_BASE;
+    vmm->heap_vpn_base = base;
 
     // initialize generic page table
@@ -149,5 +150,6 @@
     hal_fence();
 
-    vmm_dmsg("\n[INFO] %s : exit for process %x\n", __FUNCTION__ , process->pid );
+    vmm_dmsg("\n[DMSG] %s : exit for process %x / entry_point = %x\n",
+    __FUNCTION__ , process->pid , process->vmm.entry_point );
 
 }  // end vmm_init()
@@ -171,14 +173,4 @@
     dst_vmm->vsegs_nr = 0;
     list_root_init( &dst_vmm->vsegs_root );
-    error = grdxt_init( &dst_vmm->grdxt,
-                        CONFIG_VMM_GRDXT_W1,
-                        CONFIG_VMM_GRDXT_W2,
-                        CONFIG_VMM_GRDXT_W3 );
-    if( error )
-    {
-        printk("\n[ERROR] in %s : cannot initialize radix tree for process %x\n",
-               __FUNCTION__ , dst_process->pid );
-        return ENOMEM;
-    }
 
     // loop on src_vmm list of vsegs to create
@@ -292,7 +284,4 @@
         vseg_free( vseg );
 	}
-
-    // delete vsegs radix_tree
-    grdxt_destroy( &vmm->grdxt );
 
     // release lock
@@ -456,5 +445,5 @@
 	vmm_t * vmm = &process->vmm;
 
-	vmm_dmsg("\n[INFO] %s : enter for process %x / base = %x / size = %x / type = %s\n",
+	vmm_dmsg("\n[DMSG] %s : enter for process %x / base = %x / size = %x / type = %s\n",
 		     __FUNCTION__ , process->pid , base , size , vseg_type_str(type) );
 
@@ -527,5 +516,5 @@
 
     // update "heap_vseg" in VMM
-	process->vmm.heap_vseg = vseg;
+	if( type == VSEG_TYPE_HEAP ) process->vmm.heap_vseg = vseg;
 
     // attach vseg to vmm
@@ -534,9 +523,10 @@
 	rwlock_wr_unlock( &vmm->vsegs_lock );
 
-	vmm_dmsg("\n[INFO] %s : exit for process %x / vseg [%x, %x] has been mapped\n",
+	vmm_dmsg("\n[DMSG] %s : exit for process %x / vseg [%x, %x] registered\n",
 		     __FUNCTION__ , process->pid , vseg->min , vseg->max );
 
 	return vseg;
-}
+
+}  // vmm_create_vseg()
 
 /////////////////////////////////////
@@ -665,4 +655,35 @@
 }
 
+///////////////////////////////////////////////////////////////////////////////////////
+// This low-level static function is called by the vmm_get_vseg() and vmm_resize_vseg()
+// functions.  It scan the list of registered vsegs to find the unique vseg containing
+// a given virtual address.
+///////////////////////////////////////////////////////////////////////////////////////
+// @ vmm     : pointer on the process VMM.
+// @ vaddr   : virtual address.
+// @ return vseg pointer if success / return NULL if not found.
+///////////////////////////////////////////////////////////////////////////////////////
+static vseg_t * vseg_from_vaddr( vmm_t    * vmm,
+                                 intptr_t   vaddr )
+{
+    list_entry_t * iter;
+    vseg_t       * vseg = NULL;
+
+    // get lock protecting the vseg list
+    rwlock_rd_lock( &vmm->vsegs_lock );
+
+    // scan the list of vsegs
+    LIST_FOREACH( &vmm->vsegs_root , iter )
+    {
+        vseg = LIST_ELEMENT( iter , vseg_t , list );
+        if( (vaddr >= vseg->min) && (vaddr < vseg->max) ) break;
+    }
+
+    // release the lock
+    rwlock_rd_unlock( &vmm->vsegs_lock );
+
+    return vseg;
+}
+
 /////////////////////////////////////////////
 error_t vmm_resize_vseg( process_t * process,
@@ -670,5 +691,8 @@
                          intptr_t    size )
 {
-	error_t error;
+    error_t   error;
+    vseg_t  * new;
+    vpn_t     vpn_min;
+    vpn_t     vpn_max;
 
     // get pointer on process VMM
@@ -677,8 +701,7 @@
     intptr_t addr_min = base;
 	intptr_t addr_max = base + size;
-    uint32_t shift    = CONFIG_PPM_PAGE_SHIFT;
 
     // get pointer on vseg
-	vseg_t * vseg = grdxt_lookup( &vmm->grdxt , (uint32_t)(base >> shift) );
+	vseg_t * vseg = vseg_from_vaddr( vmm , base );
 
 	if( vseg == NULL)  return EINVAL;
@@ -696,18 +719,43 @@
         error = 0;
     }
-	else if( vseg->min == addr_min )                              // vseg must be resized
-    {
-        panic("resize not implemented yet");
-		error = 0;
-    }
-	else if( vseg->max == addr_max )                              // vseg must be resized
-    {
-        panic("resize not implemented yet");
-		error = 0;
-    }
-    else            // vseg cut in three regions => vseg must be resized & new vseg created
-    {
-        panic("resize not implemented yet");
-		error = 0;
+	else if( vseg->min == addr_min )                         // vseg must be resized
+    {
+        // update vseg base address
+        vseg->min = addr_max;
+
+        // update vpn_base and vpn_size
+        vpn_min        = vseg->min >> CONFIG_PPM_PAGE_SHIFT;
+        vpn_max        = (vseg->max - 1) >> CONFIG_PPM_PAGE_SHIFT;
+        vseg->vpn_base = vpn_min;
+        vseg->vpn_size = vpn_max - vpn_min + 1;
+        error = 0;
+    }
+	else if( vseg->max == addr_max )                          // vseg must be resized
+    {
+        // update vseg max address
+        vseg->max = addr_min;
+
+        // update vpn_base and vpn_size
+        vpn_min        = vseg->min >> CONFIG_PPM_PAGE_SHIFT;
+        vpn_max        = (vseg->max - 1) >> CONFIG_PPM_PAGE_SHIFT;
+        vseg->vpn_base = vpn_min;
+        vseg->vpn_size = vpn_max - vpn_min + 1;
+        error = 0;
+    }
+    else                                                      // vseg cut in three regions 
+    {
+        // resize existing vseg
+        vseg->max = addr_min;
+
+        // update vpn_base and vpn_size
+        vpn_min        = vseg->min >> CONFIG_PPM_PAGE_SHIFT;
+        vpn_max        = (vseg->max - 1) >> CONFIG_PPM_PAGE_SHIFT;
+        vseg->vpn_base = vpn_min;
+        vseg->vpn_size = vpn_max - vpn_min + 1;
+
+        // create new vseg
+        new = vmm_create_vseg( process , addr_min , (vseg->max - addr_max) , vseg->type ); 
+        if( new == NULL ) error = EINVAL;
+        else              error = 0;
     }
 
@@ -716,5 +764,6 @@
 
 	return error;
-}
+
+}  // vmm_resize_vseg()
 
 ///////////////////////////////////////////
@@ -723,18 +772,8 @@
                        vseg_t   ** found_vseg )
 {
-    vmm_t    * vmm;
-    vseg_t   * vseg;
-
-    // get pointer on process VMM
-    vmm = &process->vmm;
-
-    // get lock protecting the vseg list
-    rwlock_rd_lock( &vmm->vsegs_lock );
-
-    // get pointer on vseg from local radix tree
-	vseg = grdxt_lookup( &vmm->grdxt, (uint32_t)(vaddr >> CONFIG_PPM_PAGE_SHIFT) );
-
-    // release the lock
-    rwlock_rd_unlock( &vmm->vsegs_lock );
+    vmm_t  * vmm = &process->vmm;
+
+    // get vseg from vaddr
+    vseg_t * vseg = vseg_from_vaddr( vmm , vaddr );
 
     if( vseg == NULL )   // vseg not found in local cluster => try to get it from ref
@@ -752,4 +791,5 @@
         xptr_t   vseg_xp;
         error_t  error;
+
         rpc_vmm_get_vseg_client( ref_cxy , ref_ptr , vaddr , &vseg_xp , &error );
             
@@ -759,5 +799,5 @@
         vseg = vseg_alloc();
 
-        if( vseg == NULL ) panic("no memory for vseg copy in cluster %x", local_cxy );
+        if( vseg == NULL ) return -1;
 
         // initialise local vseg from reference
@@ -765,7 +805,5 @@
 
         // register local vseg in local VMM
-        error = vseg_attach( &process->vmm , vseg );
-
-        if( error ) panic("no memory for vseg registration in cluster %x", local_cxy );
+        vseg_attach( &process->vmm , vseg );
     }   
     
@@ -784,18 +822,25 @@
     cxy_t      page_cxy;          // physical page cluster
     page_t   * page_ptr;          // local pointer on physical page descriptor
-
-    uint32_t   type      = vseg->type;
-    xptr_t     mapper_xp = vseg->mapper_xp;
-    uint32_t   flags     = vseg->flags;
-
-    // get mapper cluster and local pointer
-    cxy_t      mapper_cxy = GET_CXY( mapper_xp );
-    mapper_t * mapper_ptr = (mapper_t *)GET_PTR( mapper_xp );
-
-    // FILE type : simply get the physical page from the file mapper
+    uint32_t   index;             // missing page index in vseg mapper
+    uint32_t   type;              // vseg type;
+
+    type      = vseg->type;
+    index     = vpn - vseg->vpn_base;
+
+    vmm_dmsg("\n[DMSG] %s : core[%x,%d] enter for vpn = %x / type = %s / index = %d\n",
+    __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn, vseg_type_str(type), index );
+
+    // FILE type : get the physical page from the file mapper
     if( type == VSEG_TYPE_FILE )
     {
-        // compute index in file mapper
-        uint32_t index = vpn - vseg->vpn_base;
+        // get extended pointer on mapper
+        xptr_t     mapper_xp = vseg->mapper_xp;
+
+        assert( (mapper_xp != XPTR_NULL), __FUNCTION__,
+        "mapper not defined for a FILE vseg\n" );
+        
+        // get mapper cluster and local pointer
+        cxy_t      mapper_cxy = GET_CXY( mapper_xp );
+        mapper_t * mapper_ptr = (mapper_t *)GET_PTR( mapper_xp );
 
         // get page descriptor from mapper
@@ -814,13 +859,15 @@
     }
 
-    // all other types : allocate a physical page from target cluster,
+    // Other types : allocate a physical page from target cluster,
     else
     {
+        uint32_t flags = vseg->flags;
+
         // get target cluster for physical page
         if( flags & VSEG_DISTRIB ) // depends on VPN LSB
         {
-            uint32_t x_width = LOCAL_CLUSTER->x_width;
-            uint32_t y_width = LOCAL_CLUSTER->y_width;
-            page_cxy = vpn & ((1<<(x_width + y_width)) - 1);
+            uint32_t x_size = LOCAL_CLUSTER->x_size;
+            uint32_t y_size = LOCAL_CLUSTER->y_size;
+            page_cxy = vpn & ((x_size * y_size) - 1);
         }
         else                       // defined in vseg descriptor
@@ -831,5 +878,5 @@
         // allocate a physical page in target cluster
         kmem_req_t   req;
-        if( page_cxy == local_cxy )    // target cluster is the local cluster
+        if( page_cxy == local_cxy )  // target cluster is the local cluster
         {
             req.type  = KMEM_PAGE;
@@ -845,22 +892,38 @@
         if( page_ptr == NULL ) return ENOMEM;
 
-        // initialise page from .elf file mapper for DATA and CODE types
+        // initialise missing page from .elf file mapper for DATA and CODE types
+        // => the mapper_xp field is an extended pointer on the .elf file mapper
         if( (type == VSEG_TYPE_CODE) || (type == VSEG_TYPE_DATA) )
         {
-            // compute missing page index in vseg
-            vpn_t page_index = vpn - vseg->vpn_base;
+            // get extended pointer on mapper
+            xptr_t     mapper_xp = vseg->mapper_xp;
+
+            assert( (mapper_xp != XPTR_NULL), __FUNCTION__,
+            "mapper not defined for a CODE or DATA vseg\n" );
+        
+            // get mapper cluster and local pointer
+            cxy_t      mapper_cxy = GET_CXY( mapper_xp );
+            mapper_t * mapper_ptr = (mapper_t *)GET_PTR( mapper_xp );
+
+            // compute missing page offset in vseg
+            uint32_t offset = index << CONFIG_PPM_PAGE_SHIFT;
 
             // compute missing page offset in .elf file
-            intptr_t page_offset = vseg->file_offset + 
-                                   (page_index << CONFIG_PPM_PAGE_SHIFT);
-
-            // compute extended pointer on page first byte 
-            xptr_t base_xp = ppm_page2base( XPTR( page_cxy , page_ptr ) );
-
-            // file_size can be smaller than vseg_size for BSS
-            intptr_t file_size = vseg->file_size;
-
-            if( file_size < page_offset )                                // fully in  BSS 
+            uint32_t elf_offset = vseg->file_offset + offset;
+
+            vmm_dmsg("\n[DMSG] %s : core[%x,%d] for vpn = %x / elf_offset = %x\n",
+            __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn, elf_offset );
+
+            // compute extended pointer on page base 
+            xptr_t base_xp  = ppm_page2base( XPTR( page_cxy , page_ptr ) );
+
+            // file_size (in .elf mapper) can be smaller than vseg_size (BSS)
+            uint32_t file_size = vseg->file_size;
+
+            if( file_size < offset )                 // missing page fully in  BSS 
             {
+                vmm_dmsg("\n[DMSG] %s : core[%x,%d] for vpn = %x / fully in BSS\n",
+                __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn );
+
                 if( page_cxy == local_cxy )
                 {
@@ -872,11 +935,14 @@
                 }
             }
-            else if( file_size >= (page_offset + CONFIG_PPM_PAGE_SIZE) )  // fully in  mapper
+            else if( file_size >= (offset + CONFIG_PPM_PAGE_SIZE) )  // fully in  mapper
             {
+                vmm_dmsg("\n[DMSG] %s : core[%x,%d] for vpn = %x / fully in mapper\n",
+                __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn );
+
                 if( mapper_cxy == local_cxy ) 
                 {
                     error = mapper_move_kernel( mapper_ptr,
                                                 true,             // to_buffer
-                                                page_offset,
+                                                elf_offset,
                                                 base_xp,
                                                 CONFIG_PPM_PAGE_SIZE ); 
@@ -888,6 +954,6 @@
                                                    true,         // to buffer
                                                    false,        // kernel buffer
-                                                   page_offset,
-                                                   (uint64_t)base_xp,
+                                                   elf_offset,
+                                                   base_xp,
                                                    CONFIG_PPM_PAGE_SIZE,
                                                    &error );
@@ -895,7 +961,13 @@
                 if( error ) return EINVAL;
             }
-            else  // in mapper : from page_offset -> (file_size - page_offset)
-                  // in BSS    : from file_size   -> (page_offset + page_size)
+            else  // both in mapper and in BSS :
+                  // - (file_size - offset)             bytes from mapper
+                  // - (page_size + offset - file_size) bytes from BSS
             {
+                vmm_dmsg("\n[DMSG] %s : core[%x,%d] for vpn = %x / both mapper & BSS\n"
+                         "      %d bytes from mapper / %d bytes from BSS\n",
+                __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, vpn,
+                file_size - offset , offset + CONFIG_PPM_PAGE_SIZE - file_size  );
+
                 // initialize mapper part
                 if( mapper_cxy == local_cxy )
@@ -903,7 +975,7 @@
                     error = mapper_move_kernel( mapper_ptr,
                                                 true,         // to buffer
-                                                page_offset,
+                                                elf_offset,
                                                 base_xp,
-                                                file_size - page_offset ); 
+                                                file_size - offset ); 
                 }
                 else                                
@@ -913,7 +985,7 @@
                                                    true,         // to buffer
                                                    false,        // kernel buffer
-                                                   page_offset,
-                                                   (uint64_t)base_xp,
-                                                   file_size - page_offset, 
+                                                   elf_offset,
+                                                   base_xp,
+                                                   file_size - offset, 
                                                    &error );
                 }
@@ -923,11 +995,11 @@
                 if( page_cxy == local_cxy )
                 {
-                    memset( GET_PTR( base_xp ) + file_size - page_offset , 0 , 
-                            page_offset + CONFIG_PPM_PAGE_SIZE - file_size );
+                    memset( GET_PTR( base_xp ) + file_size - offset , 0 , 
+                            offset + CONFIG_PPM_PAGE_SIZE - file_size );
                 }
                 else
                 {
-                   hal_remote_memset( base_xp + file_size - page_offset , 0 , 
-                                      page_offset + CONFIG_PPM_PAGE_SIZE - file_size );
+                   hal_remote_memset( base_xp + file_size - offset , 0 , 
+                                      offset + CONFIG_PPM_PAGE_SIZE - file_size );
                 }
             }    
@@ -937,4 +1009,8 @@
     // return ppn
     *ppn = ppm_page2ppn( XPTR( page_cxy , page_ptr ) );
+
+    vmm_dmsg("\n[DMSG] %s : core[%x,%d] exit for vpn = %x / ppn = %x\n",
+    __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , *ppn );
+
     return 0;
 
@@ -954,5 +1030,8 @@
     // this function must be called by a thread running in the reference cluster
     assert( (GET_CXY( process->ref_xp ) == local_cxy ) , __FUNCTION__ ,
-             " not called in the reference cluster\n" );
+    "not called in the reference cluster\n" );
+
+    vmm_dmsg("\n[DMSG] %s : core[%x,%d] enter for vpn = %x in process %x\n",
+    __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , process->pid );
 
     // get VMM pointer
@@ -968,4 +1047,7 @@
     if( (attr & GPT_MAPPED) == 0 )
     {
+        vmm_dmsg("\n[DMSG] %s : core[%x,%d] page %x unmapped => try to map it\n",
+        __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn );
+
         // 1. get vseg pointer
         error = vmm_get_vseg( process , vpn<<CONFIG_PPM_PAGE_SHIFT , &vseg );
@@ -977,4 +1059,8 @@
             return error;
         }
+
+        vmm_dmsg("\n[DMSG] %s : core[%x,%d] found vseg %s / vpn_base = %x / vpn_size = %x\n",
+        __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid ,
+        vseg_type_str(vseg->type) , vseg->vpn_base , vseg->vpn_size );
 
         // 2. get physical page number, depending on vseg type
@@ -1005,4 +1091,7 @@
     }  // end new PTE
 
+    vmm_dmsg("\n[DMSG] %s : core[%x,%d] exit for vpn = %x / ppn = %x\n",
+    __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , ppn );
+
     *ret_ppn  = ppn;
     *ret_attr = attr;
