Index: soft/giet_vm/giet_common/io.h
===================================================================
--- soft/giet_vm/giet_common/io.h	(revision 407)
+++ soft/giet_vm/giet_common/io.h	(revision 408)
@@ -7,4 +7,5 @@
 // Utility functions to write or read memory mapped hardware registers
 ///////////////////////////////////////////////////////////////////////////////////
+
 #ifndef IO_H
 #define IO_H
Index: soft/giet_vm/giet_common/iommu.c
===================================================================
--- soft/giet_vm/giet_common/iommu.c	(revision 408)
+++ soft/giet_vm/giet_common/iommu.c	(revision 408)
@@ -0,0 +1,91 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : iommu.c
+// Date     : 01/09/2014
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The iommu.c and iommu.h files are part ot the GIET-VM nano kernel.
+// They contain the functions used to dynamically handle the iommu page table.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <utils.h>
+#include <tty_driver.h>
+#include <vmem.h>
+#include <giet_config.h>
+#include <tty_driver.h>
+
+///////////////////////////////////////////////////////////////////////////////////
+//    Global variable : IOMMU page table.
+///////////////////////////////////////////////////////////////////////////////////
+
+extern page_table_t _iommu_ptab;
+
+///////////////////////////////////////////////////////////////////////////////////
+// This function map a PTE2 in IOMMU page table
+///////////////////////////////////////////////////////////////////////////////////
+void _iommu_add_pte2( unsigned int ix1,
+                      unsigned int ix2,
+                      unsigned int ppn,
+                      unsigned int flags ) 
+{
+    unsigned int ptba;
+    unsigned int * pt_ppn;
+    unsigned int * pt_flags;
+
+    // get pointer on iommu page table
+    page_table_t* pt = &_iommu_ptab;
+
+    // get ptba and update PT2
+    if ((pt->pt1[ix1] & PTE_V) == 0) 
+    {
+        _printf("\n[GIET ERROR] in iommu_add_pte2() : "
+                "IOMMU PT1 entry not mapped / ix1 = %d\n", ix1 );
+        _exit();
+    }
+    else 
+    {
+        ptba = pt->pt1[ix1] << 12;
+        pt_flags = (unsigned int *) (ptba + 8 * ix2);
+        pt_ppn = (unsigned int *) (ptba + 8 * ix2 + 4);
+        *pt_flags = flags;
+        *pt_ppn = ppn;
+    }
+} // end _iommu_add_pte2()
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// This function unmap a PTE2 in IOMMU page table
+///////////////////////////////////////////////////////////////////////////////////
+void _iommu_inval_pte2( unsigned int ix1, 
+                        unsigned int ix2 ) 
+{
+    unsigned int ptba;
+    unsigned int * pt_flags;
+
+    // get pointer on iommu page table
+    page_table_t * pt = &_iommu_ptab;
+
+    // get ptba and inval PTE2
+    if ((pt->pt1[ix1] & PTE_V) == 0)
+    {
+        _printf("\n[GIET ERROR] in iommu_inval_pte2() "
+              "IOMMU PT1 entry not mapped / ix1 = %d\n", ix1 );
+        _exit();
+    }
+    else 
+    {
+        ptba = pt->pt1[ix1] << 12;
+        pt_flags = (unsigned int *) (ptba + 8 * ix2);
+        *pt_flags = 0;
+    }   
+} // end _iommu_inval_pte2()
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
+
Index: soft/giet_vm/giet_common/iommu.h
===================================================================
--- soft/giet_vm/giet_common/iommu.h	(revision 408)
+++ soft/giet_vm/giet_common/iommu.h	(revision 408)
@@ -0,0 +1,35 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : iommu.h
+// Date     : 01/09/2014
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _IOMMU_H_
+#define _IOMMU_H_
+
+#include <giet_config.h>
+#include <mapping_info.h>
+
+////////////////////////////////////////////////////////////////////////////////////
+// functions prototypes
+////////////////////////////////////////////////////////////////////////////////////
+
+void _iommu_add_pte2( unsigned int ix1, 
+                      unsigned int ix2, 
+                      unsigned int ppn, 
+                      unsigned int flags );
+
+void _iommu_inval_pte2( unsigned int ix1, 
+                        unsigned int ix2 );
+
+#endif 
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: soft/giet_vm/giet_common/pmem.c
===================================================================
--- soft/giet_vm/giet_common/pmem.c	(revision 408)
+++ soft/giet_vm/giet_common/pmem.c	(revision 408)
@@ -0,0 +1,120 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : pmem.c
+// Date     : 01/07/2012
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <utils.h>
+#include <pmem.h>
+#include <giet_config.h>
+
+///////////////////////////////////////////////////////////////////////////////////
+//     Global variable : array of physical memory allocators (one per cluster)
+///////////////////////////////////////////////////////////////////////////////////
+
+extern pmem_alloc_t boot_pmem_alloc[X_SIZE][Y_SIZE];
+
+////////////////////////////////////////
+void _pmem_alloc_init( unsigned int x,
+                       unsigned int y,
+                       unsigned int base,
+                       unsigned int size )
+{
+    if ( (base & 0x1FFFFF) || (size & 0x1FFFFF) )
+    {
+        _printf("\n[GIET ERROR] in _pmem_alloc_init() : "
+                " pseg in cluster[%d][%d] not aligned on 2 Mbytes\n", x, y );
+        _exit();
+    }
+
+    pmem_alloc_t* p       = &boot_pmem_alloc[x][y];
+
+    unsigned int  bppi_min = base >> 21;
+    unsigned int  bppi_max = (base + size) >> 21;
+
+    p->x        = x;
+    p->y        = y;
+
+    p->nxt_bppi = bppi_min;
+    p->max_bppi = bppi_max;
+
+    p->nxt_sppi = 0;
+    p->max_sppi = 0;
+
+    // first page reserved in cluster [0][0]
+    if ( (x==0) && (y==0) ) p->nxt_bppi = p->nxt_bppi + 1;
+
+} // end pmem_alloc_init()
+
+/////////////////////////////////////////////
+unsigned int _get_big_ppn( pmem_alloc_t*  p, 
+                           unsigned int   n )
+{
+    unsigned int x   = p->x;
+    unsigned int y   = p->y;
+    unsigned int bpi = p->nxt_bppi;  // bpi : BPPI of the first allocated big page
+
+    if ( (bpi + n) > p->max_bppi )
+    {
+        _printf("\n[GIET ERROR] in _get_big_ppn() : "
+                " not enough big physical pages in cluster[%d][%d]", x, y );
+        _exit();
+    }
+    
+    // update allocator state
+    p->nxt_bppi = bpi + n;
+
+    return (x << 24) + (y << 20) + (bpi << 9);
+
+} // end get_big_ppn()
+
+///////////////////////////////////////////////
+unsigned int _get_small_ppn( pmem_alloc_t*  p,
+                             unsigned int   n )
+{
+    unsigned int x    = p->x;
+    unsigned int y    = p->y;
+    unsigned int spi  = p->nxt_sppi;   // spi : SPPI of the first allocated small page 
+    unsigned int bpi  = p->spp_bppi;   // bpi : BPPI of the first allocated small page
+
+    // get a new big page if not enough contiguous small pages
+    // in the big page currently used to allocate small pages
+    if ( spi + n > p->max_sppi )  
+    {
+        if ( p->nxt_bppi + 1 > p->max_bppi )
+        {
+            _printf("\n[GIET ERROR] in _get_small_ppn() : "
+                    " not enough big physical pages in cluster[%d][%d]", x, y );
+            _exit();
+        }
+
+        // update the allocator state for the new big page
+        p->spp_bppi = p->nxt_bppi;
+        p->nxt_bppi = p->nxt_bppi + 1;
+        p->nxt_sppi = 0;
+        p->max_sppi = 512;
+
+        // set the spi and bpi values
+        spi = p->nxt_sppi;
+        bpi = p->spp_bppi;
+    }
+
+    // update allocator state for the n small pages
+    p->nxt_sppi = p->nxt_sppi + n;
+
+    return (x << 24) + (y << 20) + (bpi << 9) + spi;
+
+} // end _get_small_ppn()
+
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
+
Index: soft/giet_vm/giet_common/pmem.h
===================================================================
--- soft/giet_vm/giet_common/pmem.h	(revision 408)
+++ soft/giet_vm/giet_common/pmem.h	(revision 408)
@@ -0,0 +1,97 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : pmem.h
+// Date     : 01/09/2014
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The pmem.c and pmem.h files are part ot the GIET-VM nano kernel.
+// They define the data structures and functions used by the boot code
+// to allocate physical memory. 
+///////////////////////////////////////////////////////////////////////////////////
+// The physical address format is 40 bits, structured in five fields:
+//     | 4 | 4 |  11  |  9   |   12   |
+//     | X | Y | BPPI | SPPI | OFFSET |
+// - The (X,Y) fields define the cluster index
+// - The BPPI field is the Big Physical Page Index
+// - The SPPI field is the Small Physical Page Index
+// - The |X|Y|BPPI|SPPI| concatenation is the PPN (Physical Page Number)
+//
+// The physical memory allocation is statically done by the boot-loader.
+// As the physical memory can be distributed in all clusters, there is
+// one physical memory allocator in each cluster, and the allocation
+// state is defined by the boot_pmem_alloc[x][y] array (defined in the
+// boot.c file).
+// As the allocated physical memory is never released, the allocator structure
+// is very simple and is defined below in the pmem_alloc_t structure.
+// As the boot-loader is executed by one single processor, this structure 
+// does not contain any lock protecting exclusive access.
+// Both small pages allocator and big pages allocators allocate a variable
+// number of CONTIGUOUS pages in the physical space.
+// The first big page in cluster[0][0] is reserved for identity mapping vsegs,
+// and is not allocated by the pmem allocator.
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _PMEM_H_
+#define _PMEM_H_
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Physical memory allocator in cluster[x][y]
+/////////////////////////////////////////////////////////////////////////////////////
+
+typedef struct PmemAlloc 
+{ 
+    unsigned int x;          // allocator x coordinate
+    unsigned int y;          // allocator y coordinate
+    unsigned int max_bppi;   // max bppi value in cluster[x][y]
+    unsigned int nxt_bppi;   // next free bppi in cluster[x][y]
+    unsigned int max_sppi;   // max sppi value in cluster[x][y]
+    unsigned int nxt_sppi;   // next free sppi in cluster[x][y]
+    unsigned int spp_bppi;   // current bppi for small pages 
+}  pmem_alloc_t;
+
+////////////////////////////////////////////////////////////////////////////////////
+// functions prototypes
+////////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// This function initialises the physical memory allocator in cluster (x,y)
+// The pseg base address and the pseg size must be multiple of 2 Mbytes
+// (one big page).
+// - base is the pseg local base address (no cluster extension)
+// - size is the pseg length (bytes)
+// The first page in cluster[0][0] is reserved for identity mapped vsegs.
+///////////////////////////////////////////////////////////////////////////////////
+void _pmem_alloc_init( unsigned int x,
+                       unsigned int y,
+                       unsigned int base,
+                       unsigned int size );
+
+///////////////////////////////////////////////////////////////////////////////////
+// This function allocates n contiguous small pages (4 Kbytes), 
+// from the physical memory allocator defined by the p pointer. 
+// It returns the PPN (28 bits) of the first physical small page. 
+// Exit if not enough free space.
+///////////////////////////////////////////////////////////////////////////////////
+unsigned int _get_small_ppn( pmem_alloc_t* p,
+                             unsigned int  n );
+
+///////////////////////////////////////////////////////////////////////////////////
+// This function allocates n contiguous big pages (2 Mbytes), 
+// from the physical memory allocator defined by the p pointer. 
+// It returns the PPN (28 bits) of the first physical big page
+// (the SPPI field of the ppn is always 0). 
+// Exit if not enough free space.
+///////////////////////////////////////////////////////////////////////////////////
+unsigned int _get_big_ppn( pmem_alloc_t* p,
+                           unsigned int  n );
+
+#endif 
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: soft/giet_vm/giet_common/utils.c
===================================================================
--- soft/giet_vm/giet_common/utils.c	(revision 407)
+++ soft/giet_vm/giet_common/utils.c	(revision 408)
@@ -22,13 +22,9 @@
 extern static_scheduler_t* _schedulers[NB_PROCS_MAX<<(X_WIDTH+Y_WIDTH)];
 
-
 ///////////////////////////////////////////////////////////////////////////////////
 //         CP0 registers access functions
 ///////////////////////////////////////////////////////////////////////////////////
 
-///////////////////////////////////////////////////////////////////////////////////
-// Returns the value contained in CP0 SCHED register
-// (virtual base address of the processor scheduler).
-///////////////////////////////////////////////////////////////////////////////////
+/////////////////////////
 unsigned int _get_sched() 
 {
@@ -38,7 +34,5 @@
     return ret;
 }
-///////////////////////////////////////////////////////////////////////////////////
-// Returns EPC register content.
-///////////////////////////////////////////////////////////////////////////////////
+///////////////////////
 unsigned int _get_epc() 
 {
@@ -48,7 +42,5 @@
     return ret;
 }
-///////////////////////////////////////////////////////////////////////////////////
-// Returns BVAR register content.
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////
 unsigned int _get_bvar() 
 {
@@ -58,7 +50,5 @@
     return ret;
 }
-///////////////////////////////////////////////////////////////////////////////////
-// Returns CR register content.
-///////////////////////////////////////////////////////////////////////////////////
+//////////////////////
 unsigned int _get_cr() 
 {
@@ -68,7 +58,5 @@
     return ret;
 }
-///////////////////////////////////////////////////////////////////////////////////
-// Returns SR register content
-///////////////////////////////////////////////////////////////////////////////////
+//////////////////////
 unsigned int _get_sr() 
 {
@@ -78,16 +66,5 @@
     return ret;
 }
-//////////////////////////////////////////////////////////////////////////////
-// This function set a new value for the CP0 status register.
-//////////////////////////////////////////////////////////////////////////////
-void _set_sr(unsigned int val) 
-{
-    asm volatile( "mtc0      %0,     $12    \n"
-                  :
-                  :"r" (val) );
-}
-//////////////////////////////////////////////////////////////////////////////
-// Returns processor index
-//////////////////////////////////////////////////////////////////////////////
+//////////////////////////
 unsigned int _get_procid() 
 {
@@ -97,8 +74,5 @@
     return (ret & 0x3FF);
 }
-//////////////////////////////////////////////////////////////////////////////
-// Returns local time (32 bits value)
-// boot_proctime() 
-//////////////////////////////////////////////////////////////////////////////
+////////////////////////////
 unsigned int _get_proctime() 
 {
@@ -108,7 +82,6 @@
     return ret;
 }
-//////////////////////////////////////////////////////////////////////////////
-// Save SR value into save_sr_ptr variable and disable IRQs. 
-//////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////
 void _it_disable( unsigned int * save_sr_ptr) 
 {
@@ -123,8 +96,5 @@
     *save_sr_ptr = sr;
 }
-
-//////////////////////////////////////////////////////////////////////////////
-// Restores previous SR value.
-//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////
 void _it_restore( unsigned int * save_sr_ptr ) 
 {
@@ -136,8 +106,5 @@
 }
 
-//////////////////////////////////////////////////////////////////////////////
-// This function set a new value in CP0 SCHED register.
-// (virtual base address of the processor scheduler).
-//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////
 void _set_sched(unsigned int val) 
 {
@@ -146,4 +113,12 @@
                    :"r" (val) );
 }
+//////////////////////////////
+void _set_sr(unsigned int val) 
+{
+    asm volatile ( "mtc0     %0,     $12            \n"
+                   :
+                   :"r" (val) );
+}
+
 
 ///////////////////////////////////////////////////////////////////////////////////
@@ -151,7 +126,5 @@
 ///////////////////////////////////////////////////////////////////////////////////
 
-///////////////////////////////////////////////////////////////////////////////////
-// Returns PTPR register content.
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////
 unsigned int _get_mmu_ptpr() 
 {
@@ -161,7 +134,5 @@
     return ret;
 }
-///////////////////////////////////////////////////////////////////////////////////
-// Returns MODE register content.
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////
 unsigned int _get_mmu_mode() 
 {
@@ -171,24 +142,29 @@
     return ret;
 }
-//////////////////////////////////////////////////////////////////////////////
-// This function set a new value for the MMU PTPR register.
-//////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////
 void _set_mmu_ptpr(unsigned int val) 
 {
-    asm volatile ( "mtc2     %0,     $0            \n"
+    asm volatile ( "mtc2     %0,     $0      \n"
                    :
                    :"r" (val)
                    :"memory" );
 }
-//////////////////////////////////////////////////////////////////////////////
-// This function set a new value for the MMU MODE register.
-//////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////
 void _set_mmu_mode(unsigned int val) 
 {
-    asm volatile ( "mtc2     %0,     $1             \n"
+    asm volatile ( "mtc2     %0,     $1      \n"
                    :
                    :"r" (val)
                    :"memory" );
 }
+////////////////////////////////////////////
+void _set_mmu_dcache_inval(unsigned int val) 
+{
+    asm volatile ( "mtc2     %0,     $7      \n"
+                   :
+                   :"r" (val)
+                   :"memory" );
+}
+
 
 ////////////////////////////////////////////////////////////////////////////
@@ -1033,14 +1009,12 @@
 ///////////////////////////////////////////////////////////////////////////////////
 // Invalidate all data cache lines corresponding to a memory 
-// buffer (identified by an address and a size).
-// TODO This should be replaced by a write to the CP2 MMU_DCACHE_INVAL
-// register, to be more processor independant.
-///////////////////////////////////////////////////////////////////////////////////
-void _dcache_buf_invalidate( void * buffer, 
-                             unsigned int size) 
-{
-    unsigned int i;
+// buffer (identified by virtual base address and size).
+///////////////////////////////////////////////////////////////////////////////////
+void _dcache_buf_invalidate( unsigned int buf_vbase, 
+                             unsigned int buf_size ) 
+{
+    unsigned int offset;
     unsigned int tmp;
-    unsigned int line_size;
+    unsigned int line_size;   // bytes
 
     // compute data cache line size based on config register (bits 12:10)
@@ -1048,13 +1022,12 @@
                  "mfc0 %0, $16, 1" 
                  : "=r" (tmp) );
+
     tmp = ((tmp >> 10) & 0x7);
     line_size = 2 << tmp;
 
     // iterate on cache lines 
-    for (i = 0; i < size; i += line_size) 
-    {
-        asm volatile(
-                " cache %0, %1"
-                : :"i" (0x11), "R" (*((unsigned char *) buffer + i)) );
+    for ( offset = 0; offset < buf_size; offset += line_size) 
+    {
+        _set_mmu_dcache_inval( buf_vbase + offset );
     }
 }
@@ -1110,5 +1083,5 @@
     if ( vobj_id != 0xFFFFFFFF ) 
     {
-        *vaddr  = vobjs[vobj_id].vaddr;
+        *vaddr  = vobjs[vobj_id].vbase;
         *length = vobjs[vobj_id].length;
         return 0;
Index: soft/giet_vm/giet_common/utils.h
===================================================================
--- soft/giet_vm/giet_common/utils.h	(revision 407)
+++ soft/giet_vm/giet_common/utils.h	(revision 408)
@@ -45,33 +45,111 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////
 //     CP0 registers access functions
 ///////////////////////////////////////////////////////////////////////////////////
-
+///////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// Returns CP0_SCHED register content
+// (virtual base address of the processor scheduler)
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _get_sched(void);
+
+///////////////////////////////////////////////////////////////////////////////////
+// Returns CP0_EPC register content.
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _get_epc(void);
+
+///////////////////////////////////////////////////////////////////////////////////
+// Returns CP0_BVAR register content.
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _get_bvar(void);
+
+///////////////////////////////////////////////////////////////////////////////////
+// Returns CP0_CR register content.
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _get_cr(void);
+
+///////////////////////////////////////////////////////////////////////////////////
+// Returns CP0_SR register content.
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _get_sr(void);
+
+///////////////////////////////////////////////////////////////////////////////////
+// Returns CP0_PROCID register content.
+// Processor identifier (12 bits)
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _get_procid(void);
+
+///////////////////////////////////////////////////////////////////////////////////
+// Returns CP0_TIME register content.
+// Processor local time (32 bits)
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _get_proctime(void);
 
+///////////////////////////////////////////////////////////////////////////////////
+// Save CP0_SR value to variable pointed by save_sr_ptr and disable IRQs.
+///////////////////////////////////////////////////////////////////////////////////
 extern void         _it_disable( unsigned int* save_sr_ptr );
+
+///////////////////////////////////////////////////////////////////////////////////
+// Restore CP0_SR register from variable pointed by save_sr_ptr.
+///////////////////////////////////////////////////////////////////////////////////
 extern void         _it_restore( unsigned int* save_sr_ptr );
 
+///////////////////////////////////////////////////////////////////////////////////
+// Set a new value in CP0_SCHED register.
+// (virtual base address of the processor scheduler)
+///////////////////////////////////////////////////////////////////////////////////
 extern void         _set_sched(unsigned int value);
+
+///////////////////////////////////////////////////////////////////////////////////
+// Set a new value in CP0_SR register.
+///////////////////////////////////////////////////////////////////////////////////
 extern void         _set_sr(unsigned int value);
 
+
+///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 //     CP2 registers access functions
 ///////////////////////////////////////////////////////////////////////////////////
-
+///////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// Returns CP2_PTPR register value.
+// Page table physical base address for the running context.
+// Contains only the 27 MSB bits, right justified.
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _get_mmu_ptpr(void);
+
+///////////////////////////////////////////////////////////////////////////////////
+// Returns CP2_MODE register value.
+// MMU current mode, defined by 4 bits, right justified: ITLB/DTLB/ICACHE/DCACHE
+///////////////////////////////////////////////////////////////////////////////////
 extern unsigned int _get_mmu_mode(void);
 
+///////////////////////////////////////////////////////////////////////////////////
+// Set a new value in CP2_PTPR register.
+///////////////////////////////////////////////////////////////////////////////////
 extern void         _set_mmu_ptpr(unsigned int value);
+
+///////////////////////////////////////////////////////////////////////////////////
+// Set a new value in CP2_MODE register.
+///////////////////////////////////////////////////////////////////////////////////
 extern void         _set_mmu_mode(unsigned int value);
 
 ///////////////////////////////////////////////////////////////////////////////////
+// Set a value in  CP2_DCACHE_INVAL register.
+// It invalidates the data cache line, if the virtual address defined by the 
+// value argument hit in DCACHE.
+///////////////////////////////////////////////////////////////////////////////////
+extern void         _set_mmu_dcache_inval(unsigned int value);
+
+
+
+///////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////
 //     Physical addressing related functions
+///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -163,6 +241,6 @@
                              char*        source );
 
-extern void         _dcache_buf_invalidate( void * buffer, 
-                                            unsigned int size );
+extern void         _dcache_buf_invalidate( unsigned int buf_vbase, 
+                                            unsigned int buf_size );
 
 extern unsigned int _heap_info( unsigned int* vaddr,
Index: soft/giet_vm/giet_common/vmem.c
===================================================================
--- soft/giet_vm/giet_common/vmem.c	(revision 407)
+++ soft/giet_vm/giet_common/vmem.c	(revision 408)
@@ -5,87 +5,11 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The vmem.c and vmem.h files are part ot the GIET-VM nano kernel.
-// They contain the kernel data structures and functions used to dynamically
-// handle the paged virtual memory.
-///////////////////////////////////////////////////////////////////////////////////
 
 #include <utils.h>
-#include <tty_driver.h>
 #include <vmem.h>
 #include <giet_config.h>
-#include <tty_driver.h>
 
-/////////////////////////////////////////////////////////////////////////////
-//     Global variable : IOMMU page table
-/////////////////////////////////////////////////////////////////////////////
-
-__attribute__((section (".iommu"))) page_table_t _iommu_ptab;
-
-//////////////////////////////////////////////////////////////////////////////
-// _iommu_add_pte2()
-//////////////////////////////////////////////////////////////////////////////
-void _iommu_add_pte2( unsigned int ix1,
-                      unsigned int ix2,
-                      unsigned int ppn,
-                      unsigned int flags ) 
-{
-    unsigned int ptba;
-    unsigned int * pt_ppn;
-    unsigned int * pt_flags;
-
-    // get pointer on iommu page table
-    page_table_t * pt = &_iommu_ptab;
-
-    // get ptba and update PT2
-    if ((pt->pt1[ix1] & PTE_V) == 0) 
-    {
-        _printf("\n[GIET ERROR] in iommu_add_pte2() : "
-                "IOMMU PT1 entry not mapped / ix1 = %d\n", ix1 );
-        _exit();
-    }
-    else 
-    {
-        ptba = pt->pt1[ix1] << 12;
-        pt_flags = (unsigned int *) (ptba + 8 * ix2);
-        pt_ppn = (unsigned int *) (ptba + 8 * ix2 + 4);
-        *pt_flags = flags;
-        *pt_ppn = ppn;
-    }
-} // end _iommu_add_pte2()
-
-
-//////////////////////////////////////////////////////////////////////////////
-// _iommu_inval_pte2()
-//////////////////////////////////////////////////////////////////////////////
-void _iommu_inval_pte2( unsigned int ix1, 
-                        unsigned int ix2 ) 
-{
-    unsigned int ptba;
-    unsigned int * pt_flags;
-
-    // get pointer on iommu page table
-    page_table_t * pt = &_iommu_ptab;
-
-    // get ptba and inval PTE2
-    if ((pt->pt1[ix1] & PTE_V) == 0)
-    {
-        _printf("\n[GIET ERROR] in iommu_inval_pte2() "
-              "IOMMU PT1 entry not mapped / ix1 = %d\n", ix1 );
-        _exit();
-    }
-    else {
-        ptba = pt->pt1[ix1] << 12;
-        pt_flags = (unsigned int *) (ptba + 8 * ix2);
-        *pt_flags = 0;
-    }   
-} // end _iommu_inval_pte2()
-
-//////////////////////////////////////////////////////////////////////////////
-// This function makes a "vpn" to "ppn" translation, from the page table 
-// defined by the virtual address "pt". The MMU is supposed to be activated.
-// It uses the address extension mechanism for physical addressing.
-// Return 0 if success. Return 1 if PTE1 or PTE2 unmapped.
-//////////////////////////////////////////////////////////////////////////////
-unsigned int _v2p_translate( page_table_t*  pt,
+//////////////////////////////////////////////////
+unsigned int _v2p_translate( page_table_t*  ptab,
                              unsigned int   vpn,
                              unsigned int*  ppn,
@@ -106,20 +30,35 @@
 
     // get PTE1
-    unsigned int pte1 = pt->pt1[ix1];
+    unsigned int pte1 = ptab->pt1[ix1];
 
     // check PTE1 mapping
-    if ( (pte1 & PTE_V) == 0 )  return 1;
+    if ( (pte1 & PTE_V) == 0 )
+    {
+        _printf("\n[VMEM ERROR] _v2p_translate() : pte1 unmapped\n");
+        _exit();
+    }
 
-    // get physical addresses of pte2 (two 32 bits words)
-    ptba       = (unsigned long long) (pte1 & 0x0FFFFFFF) << 12;
-    pte2_paddr = ptba + 8*ix2;
-    pte2_lsb   = (unsigned int) pte2_paddr;
-    pte2_msb   = (unsigned int) (pte2_paddr >> 32);
+    // test big/small page
+    if ( (pte1 & PTE_T) == 0 )  // big page
+    {
+        // set return values
+        *ppn   = ((pte1 << 9) & 0x0FFFFE00) | (vpn & 0X000001FF);
+        *flags = pte1 & 0xFFC00000;
+    }
+    else                        // small page
+    {
 
-    // disable interrupts and save status register
-    _it_disable( &save_sr );
+        // get physical addresses of pte2 (two 32 bits words)
+        ptba       = (unsigned long long) (pte1 & 0x0FFFFFFF) << 12;
+        pte2_paddr = ptba + 8*ix2;
+        pte2_lsb   = (unsigned int) pte2_paddr;
+        pte2_msb   = (unsigned int) (pte2_paddr >> 32);
 
-    // gets ppn_value and flags_value, after temporary DTLB desactivation
-    asm volatile (
+        // disable interrupts and save status register
+        _it_disable( &save_sr );
+
+        // get ppn_value and flags_value, using a physical read
+        // after temporary DTLB desactivation
+        asm volatile (
                 "mfc2    $2,     $1          \n"     /* $2 <= MMU_MODE       */
                 "andi    $3,     $2,    0xb  \n"
@@ -127,5 +66,5 @@
 
                 "move    $4,     %3          \n"     /* $4 <= pte_lsb        */
-                "mtc2    %2,     $24         \n"     /* PADDR_EXT <= msb     */
+                "mtc2    %2,     $24         \n"     /* PADDR_EXT <= pte_msb */
                 "lw      %0,     0($4)       \n"     /* read flags           */ 
                 "lw      %1,     4($4)       \n"     /* read ppn             */
@@ -137,14 +76,18 @@
                 : "$2", "$3", "$4" );
 
-    // restore saved status register
-    _it_restore( &save_sr );
+        // restore saved status register
+        _it_restore( &save_sr );
 
-    // check PTE2 mapping
-    if ( (flags_value & PTE_V) == 0 )  return 1;
+        // set return values 
+        *ppn   = ppn_value   & 0x0FFFFFFF;
+        *flags = flags_value & 0xFFC00000;
 
-    // set return values 
-    *ppn   = ppn_value;
-    *flags = flags_value;
-
+        // check PTE2 mapping
+        if ( (flags_value & PTE_V) == 0 )
+        {
+            _printf("\n[VMEM ERROR] _v2p_translate() : pte2 unmapped\n");
+            _exit();
+        }
+    }
     return 0;
 } // end _v2p_translate()
Index: soft/giet_vm/giet_common/vmem.h
===================================================================
--- soft/giet_vm/giet_common/vmem.h	(revision 407)
+++ soft/giet_vm/giet_common/vmem.h	(revision 408)
@@ -1,14 +1,22 @@
 ///////////////////////////////////////////////////////////////////////////////////
-// File     : vm_handler.h
+// File     : vmem.h
 // Date     : 01/07/2012
 // Author   : alain greiner
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
+// The vmem.c and vmem.h files are part ot the GIET-VM nano kernel.
+// They define  the data structures implementing the page tables,
+// and the function used for VPN to PPN translation.
+///////////////////////////////////////////////////////////////////////////////////
+// The virtual address format is 32 bits: structures in 3 fields:
+//             |  11  |  9   |   12   |
+//             | IX1  | IX2  | OFFSET |
+// - The IX1 field is the index in the first level page table
+// - The IX2 field is the index in the second level page table
+// - The |IX1|IX2\ concatenation defines the VPN (Virtual Page Number)
+///////////////////////////////////////////////////////////////////////////////////
 
-#ifndef _VM_HANDLER_H_
-#define _VM_HANDLER_H_
-
-#include <giet_config.h>
-#include <mapping_info.h>
+#ifndef _VMEM_H_
+#define _VMEM_H_
 
 /////////////////////////////////////////////////////////////////////////////////////
@@ -18,4 +26,7 @@
 #define PT1_SIZE    8192
 #define PT2_SIZE    4096
+
+#define VPN_MASK    0xFFFFF000
+#define BPN_MASK    0xFFE00000
 
 /////////////////////////////////////////////////////////////////////////////////////
@@ -51,4 +62,5 @@
 // Page table structure definition
 /////////////////////////////////////////////////////////////////////////////////////
+
 typedef struct PageTable 
 {
@@ -57,23 +69,15 @@
 } page_table_t;
 
-
-////////////////////////////////////////////////////////////////////////////////////
-// Global variable
-////////////////////////////////////////////////////////////////////////////////////
-
-extern page_table_t _iommu_ptab;
-
 ////////////////////////////////////////////////////////////////////////////////////
 // functions prototypes
 ////////////////////////////////////////////////////////////////////////////////////
 
-void _iommu_add_pte2( unsigned int ix1, 
-                      unsigned int ix2, 
-                      unsigned int ppn, 
-                      unsigned int flags );
-
-void _iommu_inval_pte2( unsigned int ix1, 
-                        unsigned int ix2 );
-
+///////////////////////////////////////////////////////////////////////////////////
+// This function makes a "vpn" to "ppn" translation, from the page table 
+// defined by the virtual address "pt". The MMU is supposed to be activated.
+// It supports both small (4 Kbytes) & big (2 Mbytes) pages.
+// It uses the address extension mechanism for physical addressing.
+// Return 0 if success. Return 1 if PTE1 or PTE2 unmapped.
+///////////////////////////////////////////////////////////////////////////////////
 unsigned int _v2p_translate( page_table_t* pt, 
                              unsigned int  vpn, 
