Index: trunk/kernel/mm/vmm.c
===================================================================
--- trunk/kernel/mm/vmm.c	(revision 408)
+++ trunk/kernel/mm/vmm.c	(revision 409)
@@ -28,4 +28,5 @@
 #include <hal_special.h>
 #include <hal_gpt.h>
+#include <hal_vmm.h>
 #include <printk.h>
 #include <memcpy.h>
@@ -83,5 +84,5 @@
              "STACK zone too small\n");
 
-    // register kentry vseg in VMM
+    // register kentry vseg in VSL
     base = CONFIG_VMM_KENTRY_BASE << CONFIG_PPM_PAGE_SHIFT;
     size = CONFIG_VMM_KENTRY_SIZE << CONFIG_PPM_PAGE_SHIFT;
@@ -100,5 +101,5 @@
     vmm->kent_vpn_base = base;
 
-    // register args vseg in VMM
+    // register args vseg in VSL
     base = (CONFIG_VMM_KENTRY_BASE + 
             CONFIG_VMM_KENTRY_SIZE ) << CONFIG_PPM_PAGE_SHIFT;
@@ -118,5 +119,5 @@
     vmm->args_vpn_base = base;
 
-    // register the envs vseg in VMM
+    // register the envs vseg in VSL
     base = (CONFIG_VMM_KENTRY_BASE + 
             CONFIG_VMM_KENTRY_SIZE +
@@ -137,8 +138,14 @@
     vmm->envs_vpn_base = base;
 
-    // initialize generic page table
+    // create GPT (empty)
     error = hal_gpt_create( &vmm->gpt );
 
-    assert( (error == 0) , __FUNCTION__ , "cannot initialize page table\n");
+    assert( (error == 0) , __FUNCTION__ , "cannot create GPT\n");
+
+    // architecture specific GPT initialization
+    // (For TSAR, identity map the kentry_vseg)
+    error = hal_vmm_init( vmm );
+
+    assert( (error == 0) , __FUNCTION__ , "cannot initialize GPT\n");
 
     // initialize STACK allocator
@@ -154,5 +161,5 @@
 
     // initialize instrumentation counters
-	vmm->pgfault_nr          = 0;
+	vmm->pgfault_nr = 0;
 
     hal_fence();
@@ -534,4 +541,8 @@
     vmm_t  * vmm = &process->vmm;
 
+// @@@
+vmm_display( process , true );
+// @@@
+
     // get extended pointer on VSL root and VSL lock
     xptr_t   root_xp = XPTR( local_cxy , &vmm->vsegs_root );
@@ -541,10 +552,20 @@
 	remote_rwlock_wr_lock( lock_xp );
 
-    // remove all vsegs registered in VSL
+    // remove all user vsegs registered in VSL
 	while( !xlist_is_empty( root_xp ) )
 	{
+        // get pointer on first vseg in VSL
 		vseg_xp = XLIST_FIRST_ELEMENT( root_xp , vseg_t , xlist );
         vseg = (vseg_t *)GET_PTR( vseg_xp );
+
+printk("\n@@@ %s : vseg %s\n", __FUNCTION__ , vseg_type_str( vseg->type ) );
+
+        // unmap and release all pages
+        vmm_unmap_vseg( process , vseg );
+
+        // remove vseg from VSL
 		vseg_detach( vmm , vseg );
+
+        // release memory allocated to vseg descriptor
         vseg_free( vseg );
 	}
@@ -565,5 +586,5 @@
     }
 
-    // release memory allocated to the local page table
+    // release memory allocated to the GPT itself
     hal_gpt_destroy( &vmm->gpt );
 
@@ -928,6 +949,16 @@
     vpn_t       vpn_min;    // VPN of first PTE
     vpn_t       vpn_max;    // VPN of last PTE (excluded)
-
-    // get pointer on process page table
+    ppn_t       ppn;        // current PTE ppn value
+    uint32_t    attr;       // current PTE attributes
+    kmem_req_t  req;        // request to release memory
+    xptr_t      page_xp;    // extended pointer on page descriptor
+    cxy_t       page_cxy;   // page descriptor cluster
+    page_t    * page_ptr;   // page descriptor pointer
+
+vmm_dmsg("\n[DBG] %s : core[%x, %d] enter / process %x / vseg %s / base %x / cycle %d\n",
+__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, process->pid ,
+vseg_type_str( vseg->type ), vseg->vpn_base, (uint32_t)hal_get_cycles() );
+
+    // get pointer on process GPT
     gpt_t     * gpt = &process->vmm.gpt;
 
@@ -937,7 +968,39 @@
 	for( vpn = vpn_min ; vpn < vpn_max ; vpn++ )
     {
-        hal_gpt_reset_pte( gpt , vpn );
-    }
-}
+        // get GPT entry
+        hal_gpt_get_pte( gpt , vpn , &attr , &ppn );
+
+        if( attr & GPT_MAPPED )  // entry is mapped
+        { 
+            // check small page
+            assert( (attr & GPT_SMALL) , __FUNCTION__ ,
+            "an user vseg must use small pages" );
+
+            // unmap GPT entry
+            hal_gpt_reset_pte( gpt , vpn );
+
+            // release memory if not identity mapped
+            if( (vseg->flags & VSEG_IDENT)  == 0 )
+            {
+                // get extended pointer on page descriptor
+                page_xp  = ppm_ppn2page( ppn );
+                page_cxy = GET_CXY( page_xp );
+                page_ptr = (page_t *)GET_PTR( page_xp );
+
+                // release physical page to relevant cluster
+                if( page_cxy == local_cxy )                   // local cluster
+                {
+                    req.type = KMEM_PAGE;
+                    req.ptr  = page_ptr; 
+                    kmem_free( &req );
+                }
+                else                                          // remote cluster
+                {
+                    rpc_pmem_release_pages_client( page_cxy , page_ptr );
+                }
+            }
+        }
+    }
+}  // end vmm_unmap_vseg()
 
 //////////////////////////////////////////////////////////////////////////////////////////
