Index: /soft/giet_vm/gameoflife/main.c
===================================================================
--- /soft/giet_vm/gameoflife/main.c	(revision 262)
+++ /soft/giet_vm/gameoflife/main.c	(revision 263)
@@ -125,17 +125,17 @@
 
 
-/////////////
+////////////////////////////////////////
 __attribute__((constructor)) void main()
 {
-   unsigned int proc_id          = giet_procid();                  // processor id
-   unsigned int nlocal_procs     = (unsigned int) NB_PROCS_MAX;    // number of processors per cluster
-   unsigned int nclusters        = (unsigned int) NB_CLUSTERS;     // number of clusters
-   unsigned int local_id         = proc_id % nlocal_procs;         // local processor id
-   unsigned int cluster_id       = proc_id / nlocal_procs;         // cluster id
-   unsigned int nglobal_procs    = nclusters * nlocal_procs;       // number of tasks
+   unsigned int proc_id       = giet_procid();              // processor id
+   unsigned int nlocal_procs  = NB_PROCS_MAX;               // processors per cluster
+   unsigned int nclusters     = X_SIZE*Y_SIZE;              // number of clusters
+   unsigned int local_id      = proc_id % nlocal_procs;     // local processor id
+   unsigned int cluster_id    = proc_id / nlocal_procs;     // cluster id
+   unsigned int nglobal_procs = nclusters * nlocal_procs;   // number of tasks
    size_t i;
 
-   size_t       nb_line          = HEIGHT / nglobal_procs;
-   size_t       base_line        = nb_line * proc_id; 
+   size_t       nb_line       = HEIGHT / nglobal_procs;
+   size_t       base_line     = nb_line * proc_id; 
    
    PRINTF("*** Starting init at cycle %d ***\n", giet_proctime());
Index: /soft/giet_vm/giet_boot/boot.c
===================================================================
--- /soft/giet_vm/giet_boot/boot.c	(revision 262)
+++ /soft/giet_vm/giet_boot/boot.c	(revision 263)
@@ -11,5 +11,5 @@
 // physicals addresses can have up to 40 bits, and use the  (unsigned long long) type.
 // It natively supports clusterised shared mmemory multi-processors architectures, 
-// where each processor is identified by a composite index (cluster_id, local_id),
+// where each processor is identified by a composite index (cluster_xy, local_id),
 // and where there is one physical memory bank per cluster.
 //
@@ -61,7 +61,13 @@
 //    Each PT2 contains 512 PTE2 of 8bytes => 4K bytes.
 //    The total size of a page table is finally = 8K + (GIET_NB_PT2_MAX)*4K bytes.
-////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////
+// Implementation Notes:
+//
+// 1) The cluster_id variable is a linear index in the mapping_info array of clusters. 
+//    We use the cluster_xy variable for the tological index = x << Y_WIDTH + y
+///////////////////////////////////////////////////////////////////////////////////////
 
 // for vobjs initialisation
+#include <giet_config.h>
 #include <mwmr_channel.h>
 #include <barrier.h>
@@ -87,10 +93,22 @@
 #include <stdarg.h>
 
-#if !defined(NB_CLUSTERS)
-# error The NB_CLUSTERS value must be defined in the 'giet_config.h' file !
+#if !defined(X_SIZE)
+# error The X_SIZE value must be defined in the 'hard_config.h' file !
+#endif
+
+#if !defined(Y_SIZE)
+# error The Y_SIZE value must be defined in the 'hard_config.h' file !
+#endif
+
+#if !defined(X_WIDTH)
+# error The X_WIDTH value must be defined in the 'hard_config.h' file !
+#endif
+
+#if !defined(Y_WIDTH)
+# error The Y_WIDTH value must be defined in the 'hard_config.h' file !
 #endif
 
 #if !defined(NB_PROCS_MAX)
-# error The NB_PROCS_MAX value must be defined in the 'giet_config.h' file !
+# error The NB_PROCS_MAX value must be defined in the 'hard_config.h' file !
 #endif
 
@@ -116,8 +134,4 @@
 unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX];
 
-// Scheduler pointers array (virtual addresses)
-__attribute__((section (".bootdata"))) 
-static_scheduler_t* _schedulers[NB_CLUSTERS * NB_PROCS_MAX];
-
 // Next free PT2 index array
 __attribute__((section (".bootdata"))) 
@@ -129,4 +143,9 @@
 unsigned int _max_pt2[GIET_NB_VSPACE_MAX] =
 { [0 ... GIET_NB_VSPACE_MAX - 1] = 0 };
+
+// Scheduler pointers array (virtual addresses)
+// indexed by (x,y,lpid) : ((x << Y_WIDTH) + y)*NB_PROCS_MAX + lpid
+__attribute__((section (".bootdata"))) 
+static_scheduler_t* _schedulers[NB_PROCS_MAX<<(X_WIDTH+Y_WIDTH)];
 
 
@@ -147,12 +166,28 @@
         _exit();
     }
+
     // checking number of clusters
-    if (header->clusters != NB_CLUSTERS) 
-    {
-        _puts("\n[BOOT ERROR] Incoherent NB_CLUSTERS");
-        _puts("\n             - In giet_config,  value = ");
-        _putd(NB_CLUSTERS);
-        _puts("\n             - In mapping_info, value = ");
-        _putd(header->clusters);
+    if ( (header->x_size  != X_SIZE)  || 
+         (header->y_size  != Y_SIZE)  ||
+         (header->x_width != X_WIDTH) ||
+         (header->y_width != Y_WIDTH) )
+    {
+        _puts("\n[BOOT ERROR] Incoherent X_SIZE or Y_SIZE ");
+        _puts("\n             - In hard_config:  X_SIZE = ");
+        _putd( X_SIZE );
+        _puts(" / Y_SIZE = ");
+        _putd( Y_SIZE );
+        _puts(" / X_WIDTH = ");
+        _putd( X_WIDTH );
+        _puts(" / Y_WIDTH = ");
+        _putd( Y_WIDTH );
+        _puts("\n             - In mapping_info: x_size = ");
+        _putd( header->x_size );
+        _puts(" / y_size = ");
+        _putd( header->y_size );
+        _puts(" / x_width = ");
+        _putd( header->x_width );
+        _puts(" / y_width = ");
+        _putd( header->y_width );
         _puts("\n");
         _exit();
@@ -167,6 +202,8 @@
 
 #if BOOT_DEBUG_MAPPING
-_puts("\n - clusters  = ");
-_putd( header->clusters );
+_puts("\n - x_size    = ");
+_putd( header->x_size );
+_puts("\n - y_size    = ");
+_putd( header->y_size );
 _puts("\n - procs     = ");
 _putd( header->procs );
@@ -196,17 +233,19 @@
 _puts("\n");
 
-unsigned int        cluster_id;
+unsigned int cluster_id;
 mapping_cluster_t * cluster = _get_cluster_base(header);
-for (cluster_id = 0; cluster_id < NB_CLUSTERS; cluster_id++) 
+for( cluster_id = 0; cluster_id < X_SIZE*Y_SIZE ; cluster_id++) 
 {
-_puts("\n cluster = ");
-_putd( cluster_id );
-_puts("\n procs   = ");
-_putd( cluster[cluster_id].procs );
-_puts("\n psegs   = ");
-_putd( cluster[cluster_id].psegs );
-_puts("\n periphs = ");
-_putd( cluster[cluster_id].periphs );
-_puts("\n");
+    _puts("\n - cluster[");
+    _putd( cluster[cluster_id].x );
+    _puts(",");
+    _putd( cluster[cluster_id].y );
+    _puts("]\n   procs   = ");
+    _putd( cluster[cluster_id].procs );
+    _puts("\n   psegs   = ");
+    _putd( cluster[cluster_id].psegs );
+    _puts("\n   periphs = ");
+    _putd( cluster[cluster_id].periphs );
+    _puts("\n");
 }
 #endif
@@ -1069,5 +1108,5 @@
     {
         if ( (vobj[vseg[vseg_id].vobj_offset].type == VOBJ_TYPE_SCHED) && 
-             (pseg[vseg[vseg_id].psegid].cluster == cluster_id ) )
+             (pseg[vseg[vseg_id].psegid].clusterid == cluster_id ) )
         {
             *vbase  = vseg[vseg_id].vbase;
@@ -1078,7 +1117,10 @@
     if ( found == 0 )
     {
-        _puts("\n[BOOT ERROR] No vobj of type SCHED in cluster ");
-        _putd(cluster_id);
-        _puts("\n");
+        mapping_cluster_t* cluster = _get_cluster_base(header);
+        _puts("\n[BOOT ERROR] No vobj of type SCHED in cluster [");
+        _putd( cluster[cluster_id].x );
+        _puts(",");
+        _putd( cluster[cluster_id].y );
+        _puts("]\n");
         _exit();
     }
@@ -1119,5 +1161,5 @@
     unsigned int alloc_cma_channel = 0;            // CMA channel allocator
     unsigned int alloc_hba_channel = 0;            // IOC channel allocator
-    unsigned int alloc_tim_channel[NB_CLUSTERS];   // user TIMER allocators
+    unsigned int alloc_tim_channel[X_SIZE*Y_SIZE]; // user TIMER allocators
 
     /////////////////////////////////////////////////////////////////////////
@@ -1129,17 +1171,21 @@
     // and lpid to access the schedulers array.
     // - the _schedulers[] array of pointers can contain "holes", because
-    //   it is indexed by the global pid = cluster_id*NB_PROCS_MAX + lpid
+    //   it is indexed by the global pid = cluster_xy*NB_PROCS_MAX + lpid
     // - the mapping info array of processors is contiguous, it is indexed 
     //   by proc_id, and use an offset specific in each cluster.
 
-    for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) 
-    {
+    for (cluster_id = 0 ; cluster_id < X_SIZE*Y_SIZE ; cluster_id++) 
+    {
+        unsigned int x          = cluster[cluster_id].x;
+        unsigned int y          = cluster[cluster_id].y;
+        unsigned int cluster_xy = (x<<Y_WIDTH) + y;
 
 #if BOOT_DEBUG_SCHED
-_puts("\n[BOOT DEBUG] Initialise schedulers in cluster ");
-_putd(cluster_id);
-_puts("\n");
-#endif
-
+_puts("\n[BOOT DEBUG] Initialise schedulers in cluster[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts("]\n");
+#endif
         alloc_tim_channel[cluster_id] = NB_PROCS_MAX;
 
@@ -1154,7 +1200,9 @@
         if ( nprocs > NB_PROCS_MAX )
         {
-            _puts("\n[BOOT ERROR] Too much processors in cluster ");
-            _putd(cluster_id);
-            _puts("\n");
+            _puts("\n[BOOT ERROR] Too much processors in cluster[");
+            _putd( x );
+            _puts(",");
+            _putd( y );
+            _puts("]\n");
             _exit();
         }
@@ -1166,7 +1214,9 @@
         if ( sched_length < (nprocs<<12) ) 
         {
-            _puts("\n[BOOT ERROR] Schedulers segment too small in cluster ");
-            _putd(cluster_id);
-            _puts("\n");
+            _puts("\n[BOOT ERROR] Schedulers segment too small in cluster[");
+            _putd( x );
+            _puts(",");
+            _putd( y );
+            _puts("]\n");
             _exit();
         }
@@ -1177,19 +1227,21 @@
               proc_id++, lpid++ ) 
         {
+            // current processor scheduler pointer : psched
+            static_scheduler_t* psched = (static_scheduler_t*)(sched_vbase+(lpid<<12));
+
             // set the schedulers pointers array
-            _schedulers[cluster_id * NB_PROCS_MAX + lpid] =
-               (static_scheduler_t*)( sched_vbase + (lpid<<12) );
+            _schedulers[cluster_xy * NB_PROCS_MAX + lpid] = psched;
 
 #if BOOT_DEBUG_SCHED
 _puts("\nProc_");
-_putd(lpid);
+_putd( x );
 _puts("_");
-_putd(cluster_id);
+_putd( y );
+_puts("_");
+_putd( lpid );
 _puts(" : scheduler virtual base address = ");
 _putx( sched_vbase + (lpid<<12) );
 _puts("\n");
 #endif
-            // current processor scheduler pointer : psched
-            static_scheduler_t* psched = (static_scheduler_t*)(sched_vbase+(lpid<<12));
 
             // initialise the "tasks" variable : default value is 0 
@@ -1269,4 +1321,9 @@
         {
 
+            // compute the cluster coordinates
+            unsigned int x          = cluster[task[task_id].clusterid].x;
+            unsigned int y          = cluster[task[task_id].clusterid].y;
+            unsigned int cluster_xy = (x<<Y_WIDTH) + y;
+
 #if BOOT_DEBUG_SCHED
 _puts("\n[BOOT DEBUG] Initialise context for task ");
@@ -1274,9 +1331,12 @@
 _puts(" in vspace ");
 _puts( vspace[vspace_id].name );
-_puts("\n");
+_puts(" running on cluster[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts("]\n");
 #endif
             // compute gpid (global processor index) and scheduler base address
-            unsigned int gpid = task[task_id].clusterid * NB_PROCS_MAX + 
-                                task[task_id].proclocid;
+            unsigned int gpid = cluster_xy * NB_PROCS_MAX + task[task_id].proclocid;
             static_scheduler_t* psched = _schedulers[gpid];
 
@@ -1827,13 +1887,21 @@
     unsigned int channel_id;
 
-    for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) 
-    {
+    // loop on all physical clusters
+    for (cluster_id = 0; cluster_id < X_SIZE*Y_SIZE; cluster_id++) 
+    {
+        // computes cluster coordinates
+        unsigned int x          = cluster[cluster_id].x;
+        unsigned int y          = cluster[cluster_id].y;
+        unsigned int cluster_xy = (x<<Y_WIDTH) + y;
 
 #if BOOT_DEBUG_PERI
-_puts("\n[BOOT DEBUG] ****** peripherals initialisation in cluster ");
-_putd(cluster_id);
-_puts(" ******\n");
-#endif
-
+_puts("\n[BOOT DEBUG] ****** peripherals initialisation in cluster[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts("] ******\n");
+#endif
+
+        // loop on peripherals
         for (periph_id = cluster[cluster_id].periph_offset;
              periph_id < cluster[cluster_id].periph_offset +
@@ -1843,11 +1911,4 @@
             unsigned int channels   = periph[periph_id].channels;
 
-#if BOOT_DEBUG_PERI
-_puts("- peripheral type : ");
-_putd(type);
-_puts(" / channels = ");
-_putd(channels);
-_puts("\n");
-#endif
             switch (type) 
             {
@@ -1856,5 +1917,7 @@
                     _ioc_init();
 #if BOOT_DEBUG_PERI
-_puts("- IOC initialised\n");
+_puts("- IOC / channels = ");
+_putd(channels);
+_puts("\n");
 #endif
                     break;
@@ -1864,12 +1927,24 @@
                     for (channel_id = 0; channel_id < channels; channel_id++) 
                     {
-                        _dma_init( cluster_id, channel_id );
+                        _dma_init( cluster_xy, channel_id );
                     }
 #if BOOT_DEBUG_PERI
-_puts("- DMA initialised\n");
+_puts("- DMA / channels = ");
+_putd(channels);
+_puts("\n");
 #endif
                     break;
                 }
-                case PERIPH_TYPE_NIC:    // vci_multi_nic component
+                case PERIPH_TYPE_FBF:    // vci_block_device component
+                {
+                    // nothing to do
+#if BOOT_DEBUG_PERI
+_puts("- FBF / channels = ");
+_putd(channels);
+_puts("\n");
+#endif
+                    break;
+                }
+                case PERIPH_TYPE_HBA:    // vci_multi_ahci component
                 {
                     for (channel_id = 0; channel_id < channels; channel_id++) 
@@ -1878,12 +1953,62 @@
                     }
 #if BOOT_DEBUG_PERI
-_puts("- NIC initialised\n");
+_puts("- HBA / channels = ");
+_putd(channels);
+_puts("\n");
 #endif
                     break;
                 }
+                case PERIPH_TYPE_CMA:    // vci_chbuf_dma component
+                {
+                    for (channel_id = 0; channel_id < channels; channel_id++) 
+                    {
+                        // TODO
+                    }
+#if BOOT_DEBUG_PERI
+_puts("- CMA / channels = ");
+_putd(channels);
+_puts("\n");
+#endif
+                    break;
+                }
+                case PERIPH_TYPE_NIC:    // vci_multi_nic component
+                {
+                    for (channel_id = 0; channel_id < channels; channel_id++) 
+                    {
+                        // TODO
+                    }
+#if BOOT_DEBUG_PERI
+_puts("- NIC / channels = ");
+_putd(channels);
+_puts("\n");
+#endif
+                    break;
+                }
+                case PERIPH_TYPE_XCU:    // vci_xicu component
+                {
+                    // nothing to do 
+#if BOOT_DEBUG_PERI
+_puts("- XCU / channels = ");
+_putd(channels);
+_puts("\n");
+#endif
+                    break;
+                }
+                case PERIPH_TYPE_MMC:    // vci_memcache config
+                {
+                    // nothing to do
+#if BOOT_DEBUG_PERI
+_puts("- MMC / channels = ");
+_putd(channels);
+_puts("\n");
+#endif
+                    break;
+                }
                 case PERIPH_TYPE_TTY:    // vci_multi_tty component
                 {
 #if BOOT_DEBUG_PERI
-_puts("- TTY initialised\n");
+_puts("- TTY / channels = ");
+_putd(channels);
+_puts("\n");
 #endif
                     break;
@@ -1902,5 +2027,7 @@
                     }
 #if BOOT_DEBUG_PERI
-_puts("- IOB initialised\n");
+_puts("- IOB / channels = ");
+_putd(channels);
+_puts("\n");
 #endif
                     break;
@@ -1910,9 +2037,12 @@
 
 #if BOOT_DEBUG_PERI
-_puts("\n[BOOT DEBUG] ****** coprocessors initialisation in cluster ");
-_putd(cluster_id);
-_puts(" ******\n");
-#endif
-
+_puts("\n[BOOT DEBUG] ****** coprocessors initialisation in cluster[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts("] ******\n");
+#endif
+
+        // loop on coprocessors
         for ( coproc_id = cluster[cluster_id].coproc_offset;
               coproc_id < cluster[cluster_id].coproc_offset +
@@ -1939,8 +2069,8 @@
                 paddr_t mwmr_channel_pbase = vobj[vobj_id].paddr;
 
-                _mwmr_hw_init( cluster_id,
-                               cp_port_id, 
-                               cp_port[cp_port_id].direction, 
-                               mwmr_channel_pbase );
+                _mwr_hw_init( cluster_xy,
+                              cp_port_id, 
+                              cp_port[cp_port_id].direction, 
+                              mwmr_channel_pbase );
 #if BOOT_DEBUG_PERI
 _puts("     port direction: ");
@@ -1959,53 +2089,4 @@
 } // end boot_peripherals_init()
 
-
-//////////////////////////////////////////////////////////////////////////////
-// This function is executed by all processors to jump into kernel:
-// - Each processor initialises its CP0_SCHED register from the value
-//   contained in the _schedulers[] array (previously initialised
-//   by proc0 in the _schedulers_init() function).
-// - Each processor (but proc 0) initialise the CP2_PTPR register with
-//   the default value (i.e. PTPR corresponding to vspace_0 page table),
-//   and write into CP2 MODE register to activate their MMU.
-// - All processors jump to the kernel entry point (seg_kernel_init_base).
-//////////////////////////////////////////////////////////////////////////////
-void boot_to_kernel()
-{
-    // CP0 SCHED register initialisation
-    unsigned int procid = _get_procid();
-    _set_sched( (unsigned int)_schedulers[procid] );
-
-    // MMU Activation
-    if ( procid != 0 )
-    {
-        _set_mmu_ptpr( (unsigned int)(_ptabs_paddr[0]>>13) );
-        _set_mmu_mode( 0xF );
-
-        _tty_get_lock( 0 );
-        _puts("\n[BOOT] Proc ");
-        _putd( procid );
-        _puts(" MMU activation at cycle ");
-        _putd(_get_proctime());
-        _puts("\n");
-        _tty_release_lock( 0 );
-
-    }
-
-    // jump to kernel_init
-    unsigned int kernel_entry = (unsigned int)&seg_kernel_init_base;
-
-    _tty_get_lock( 0 );
-    _puts("\n[BOOT] Processor ");
-    _putd( procid );
-    _puts(" jumps to kernel (");
-    _putx( kernel_entry );
-    _puts(") at cycle ");
-    _putd( _get_proctime() );
-    _puts("\n");
-    _tty_release_lock( 0 );
-
-    asm volatile( "jr   %0" ::"r"(kernel_entry) );
-}
-
 /////////////////////////////////////////////////////////////////////////
 // This function is the entry point of the boot code for all processors.
@@ -2014,8 +2095,10 @@
 void boot_init() 
 {
-    mapping_header_t* header = (mapping_header_t *) & seg_boot_mapping_base;
-    unsigned int      procid = _get_procid();
+    mapping_header_t* header     = (mapping_header_t *) & seg_boot_mapping_base;
+    unsigned int      gpid       = _get_procid();
+    unsigned int      cluster_xy = gpid / NB_PROCS_MAX;
+    unsigned int      lpid       = gpid % NB_PROCS_MAX;
  
-    if ( procid == 0 )    // only Processor 0 does it
+    if ( gpid == 0 )    // only Processor 0 does it
     {
         _puts("\n[BOOT] boot_init start at cycle ");
@@ -2043,5 +2126,5 @@
         _set_mmu_mode( 0xF );
 
-        _puts("\n[BOOT] Processor 0 MMU activation at cycle ");
+        _puts("\n[BOOT] Processor[0,0,0] : MMU activation at cycle ");
         _putd(_get_proctime());
         _puts("\n");
@@ -2064,12 +2147,8 @@
         _set_sched( (unsigned int)_schedulers[0] );
 
-        _puts("\n[BOOT] Proc 0 CPO_SCHED register initialised at cycle ");
-        _putd(_get_proctime());
-        _puts("\n");
-
-        // Initializing external peripherals
+        // Initializing peripherals
         boot_peripherals_init();
 
-        _puts("\n[BOOT] External peripherals initialised at cycle ");
+        _puts("\n[BOOT] All peripherals initialised at cycle ");
         _putd(_get_proctime());
         _puts("\n");
@@ -2083,15 +2162,17 @@
 
         // P0 starts all other processors
-        unsigned int cluster_id;
-        unsigned int local_id;
-        for (cluster_id = 0; cluster_id < NB_CLUSTERS; cluster_id++) 
-        {
-            for(local_id = 0; local_id < NB_PROCS_MAX; local_id++) 
+        unsigned int x,y,p;
+        for (x = 0 ; x < X_SIZE ; x++) 
+        {
+            for (y = 0 ; y < Y_SIZE ; y++) 
             {
-                if ((cluster_id != 0) || (local_id != 0))
-                {
-                    _xcu_send_ipi( cluster_id,
-                                   local_id,
-                                   (unsigned int)boot_init );
+                for(p = 0; p < NB_PROCS_MAX; p++) 
+                {
+                    if ( (x != 0) || (y != 0) || (p != 0) )
+                    {
+                        _xcu_send_ipi( (x<<Y_WIDTH) + y, 
+                                       p,
+                                       (unsigned int)boot_init );
+                    }
                 }
             }
@@ -2104,8 +2185,8 @@
 
     // all processor initialise SCHED register
-    _set_sched( (unsigned int)_schedulers[procid] );
+    _set_sched( (unsigned int)_schedulers[gpid] );
 
     // all processors (but Proc 0) activate MMU
-    if ( procid != 0 )
+    if ( gpid != 0 )
     {
         _set_mmu_ptpr( (unsigned int)(_ptabs_paddr[0]>>13) );
@@ -2113,11 +2194,14 @@
 
         _tty_get_lock( 0 );
-        _puts("\n[BOOT] Processor ");
-        _putd( procid );
-        _puts(" MMU activation at cycle ");
+        _puts("\n[BOOT] Processor[");
+        _putd( cluster_xy >> Y_WIDTH );
+        _puts(",");
+        _putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+        _puts(",");
+        _putd( lpid );
+        _puts("] : MMU activation at cycle ");
         _putd(_get_proctime());
         _puts("\n");
         _tty_release_lock( 0 );
-
     }
 
@@ -2126,7 +2210,11 @@
 
     _tty_get_lock( 0 );
-    _puts("\n[BOOT] Processor ");
-    _putd( procid );
-    _puts(" enters kernel at cycle ");
+    _puts("\n[BOOT] Processor[");
+    _putd( cluster_xy >> Y_WIDTH );
+    _puts(",");
+    _putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+    _puts(",");
+    _putd( lpid );
+    _puts("] enters kernel at cycle ");
     _putd( _get_proctime() );
     _puts(" / kernel entry = ");
Index: /soft/giet_vm/giet_common/utils.c
===================================================================
--- /soft/giet_vm/giet_common/utils.c	(revision 262)
+++ /soft/giet_vm/giet_common/utils.c	(revision 263)
@@ -19,5 +19,5 @@
 
 // This global variable is allocated in the boot.c file or in kernel_init.c file
-extern static_scheduler_t* _schedulers[NB_CLUSTERS * NB_PROCS_MAX];
+extern static_scheduler_t* _schedulers[X_SIZE * Y_SIZE * NB_PROCS_MAX];
 
 ///////////////////////////////////////////////////////////////////////////////////
@@ -565,5 +565,5 @@
     return (mapping_pseg_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters);
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE);
 }
 /////////////////////////////////////////////////////////////////////////////
@@ -572,5 +572,5 @@
     return (mapping_vspace_t *)  ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
             MAPPING_PSEG_SIZE * header->psegs);
 }
@@ -580,5 +580,5 @@
     return (mapping_vseg_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces);
@@ -589,5 +589,5 @@
     return (mapping_vobj_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces +
@@ -599,5 +599,5 @@
     return (mapping_task_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces +
@@ -610,5 +610,5 @@
     return (mapping_proc_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces +
@@ -622,5 +622,5 @@
     return (mapping_irq_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces +
@@ -635,5 +635,5 @@
     return (mapping_coproc_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces +
@@ -649,5 +649,5 @@
     return (mapping_cp_port_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces +
@@ -664,5 +664,5 @@
     return (mapping_periph_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces +
Index: /soft/giet_vm/giet_config.h
===================================================================
--- /soft/giet_vm/giet_config.h	(revision 262)
+++ /soft/giet_vm/giet_config.h	(revision 263)
@@ -23,8 +23,10 @@
 
 #define GIET_DEBUG_INIT		     0			/* trace parallel kernel initialisation */
+
 #define GIET_DEBUG_FAT           0          /* trace fat accesses */ 
 #define GIET_DEBUG_SWITCH	     0			/* trace context switchs  */
 #define GIET_DEBUG_IOC_DRIVER    0          /* trace IOC accesses */
 #define GIET_DEBUG_DMA_DRIVER    0          /* trace DMA accesses */
+#define GIET_DEBUG_FBF_DRIVER    1          /* trace FBF accesses */
 
 #define CONFIG_SRL_VERBOSITY TRACE 
Index: /soft/giet_vm/giet_drivers/dma_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/dma_driver.c	(revision 262)
+++ /soft/giet_vm/giet_drivers/dma_driver.c	(revision 263)
@@ -12,5 +12,5 @@
 // 
 // There is  (NB_CLUSTERS * NB_DMA_CHANNELS) channels, indexed by a global index:
-//        dma_id = cluster_id * NB_DMA_CHANNELS + loc_id
+//        dma_id = cluster_xy * NB_DMA_CHANNELS + loc_id
 //
 // A DMA channel is a private ressource allocated to a given processor.
@@ -22,5 +22,5 @@
 // The virtual base address of the segment associated to a channel is:
 //
-//    seg_dma_base + cluster_id * vseg_cluster_increment + DMA_SPAN * channel_id
+//    seg_dma_base + cluster_xy * vseg_cluster_increment + DMA_SPAN * channel_id
 //
 ////////////////////////////////////////////////////////////////////////////////////
@@ -32,22 +32,22 @@
 #include <vmem.h>
 
-#if !defined(NB_CLUSTERS) 
-# error: You must define NB_CLUSTERS in the hard_config.h file
-#endif
-
-#if (NB_CLUSTERS > 256)
-# error: NB_CLUSTERS cannot be larger than 256!
-#endif
-
-#if !defined(NB_PROCS_MAX) 
-# error: You must define NB_PROCS_MAX in the hard_config.h file
-#endif
-
-#if (NB_PROCS_MAX > 8)
-# error: NB_PROCS_MAX cannot be larger than 8!
-#endif
-
-#if (NB_DMA_CHANNELS > 8)
-# error: NB_DMA_CHANNELS cannot be larger than 8!
+#if !defined(X_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(Y_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(X_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(Y_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(NB_DMA_CHANNELS) 
+# error: You must define NB_DMA_CHANNELS in the hard_config.h file
 #endif
 
@@ -60,15 +60,19 @@
 // Returns 0 if success, returns > 0 if error.
 //////////////////////////////////////////////////////////////////////////////////
-unsigned int _dma_init( unsigned int cluster_id,
+unsigned int _dma_init( unsigned int cluster_xy,
                         unsigned int channel_id )
 {
 #if NB_DMA_CHANNELS > 0
+
     // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)      return 1;
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                    return 1; 
+    if (y >= Y_SIZE)                    return 1; 
     if (channel_id >= NB_DMA_CHANNELS)  return 1; 
 
     // compute DMA base address
     unsigned int* dma_address = (unsigned int*) ((unsigned int)&seg_dma_base + 
-                                (cluster_id * (unsigned int)&vseg_cluster_increment));
+                                (cluster_xy * (unsigned int)&vseg_cluster_increment));
 
     // disable interrupt for selected channel
@@ -84,15 +88,19 @@
 // completion. It actually forces the channel to return in iDLE state.
 //////////////////////////////////////////////////////////////////////////////////
-unsigned int _dma_reset( unsigned int cluster_id, 
+unsigned int _dma_reset( unsigned int cluster_xy, 
                          unsigned int channel_id ) 
 {
 #if NB_DMA_CHANNELS > 0
+
     // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)      return 1;
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                    return 1; 
+    if (y >= Y_SIZE)                    return 1; 
     if (channel_id >= NB_DMA_CHANNELS)  return 1; 
 
     // compute DMA base address
     unsigned int* dma_address = (unsigned int*) ((unsigned int)&seg_dma_base + 
-                                (cluster_id * (unsigned int)&vseg_cluster_increment));
+                                (cluster_xy * (unsigned int)&vseg_cluster_increment));
 
     // reset selected channel
@@ -107,15 +115,19 @@
 // This function returns the status of a DMA channel in a given cluster
 //////////////////////////////////////////////////////////////////////////////////
-unsigned int _dma_get_status( unsigned int cluster_id, 
+unsigned int _dma_get_status( unsigned int cluster_xy, 
                               unsigned int channel_id ) 
 {
 #if NB_DMA_CHANNELS > 0
+
     // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)      return 1;
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                    return 1; 
+    if (y >= Y_SIZE)                    return 1; 
     if (channel_id >= NB_DMA_CHANNELS)  return 1;
 
     // compute DMA base address
     unsigned int * dma_address = (unsigned int *) ((unsigned int)&seg_dma_base + 
-                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
 
     // get selected channel status
@@ -131,5 +143,5 @@
 // and sets the transfer size to lauch the transfer.
 //////////////////////////////////////////////////////////////////////////////////
-unsigned int _dma_start_transfer( unsigned int       cluster_id,
+unsigned int _dma_start_transfer( unsigned int       cluster_xy,
                                   unsigned int       channel_id,
                                   unsigned long long dst_paddr,   // physical address
@@ -138,11 +150,15 @@
 {
 #if NB_DMA_CHANNELS > 0
+
     // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)      return 1;
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                    return 1; 
+    if (y >= Y_SIZE)                    return 1; 
     if (channel_id >= NB_DMA_CHANNELS)  return 1;
 
     // compute DMA base address
     unsigned int * dma_address = (unsigned int *) ((unsigned int)&seg_dma_base + 
-                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
 
     // selected channel configuration and lauching
@@ -179,5 +195,5 @@
 
     unsigned int procid    = _get_procid();
-    unsigned int cluster_id = procid/NB_PROCS_MAX;
+    unsigned int cluster_xy = procid/NB_PROCS_MAX;
     unsigned int channel_id = procid%NB_PROCS_MAX;
 
@@ -192,6 +208,6 @@
 _puts("\n - vspace_id  = ");
 _putx( vspace_id );
-_puts("\n - cluster_id = ");
-_putx( cluster_id );
+_puts("\n - cluster_xy = ");
+_putx( cluster_xy );
 _puts("\n - channel_id = ");
 _putx( channel_id );
@@ -263,5 +279,5 @@
 
     // dma channel configuration & lauching
-    ko = _dma_start_transfer(  cluster_id, channel_id, dst_paddr, src_paddr, size ); 
+    ko = _dma_start_transfer(  cluster_xy, channel_id, dst_paddr, src_paddr, size ); 
     if ( ko ) 
     {
@@ -273,10 +289,10 @@
 
     // scan dma channel status 
-    unsigned int status = _dma_get_status( cluster_id, channel_id );
+    unsigned int status = _dma_get_status( cluster_xy, channel_id );
     while( (status != DMA_SUCCESS) && 
            (status != DMA_READ_ERROR) &&
            (status != DMA_WRITE_ERROR) )
     {
-        status = _dma_get_status( cluster_id, channel_id );
+        status = _dma_get_status( cluster_xy, channel_id );
 
 #if GIET_DEBUG_DMA_DRIVER
@@ -299,5 +315,5 @@
     }
     // reset dma channel
-    _dma_reset( cluster_id, channel_id );
+    _dma_reset( cluster_xy, channel_id );
 
 #if GIET_DEBUG_DMA_DRIVER
Index: /soft/giet_vm/giet_drivers/dma_driver.h
===================================================================
--- /soft/giet_vm/giet_drivers/dma_driver.h	(revision 262)
+++ /soft/giet_vm/giet_drivers/dma_driver.h	(revision 263)
@@ -42,14 +42,14 @@
 
 // low level access functions
-extern unsigned int _dma_init( unsigned int cluster_id,
+extern unsigned int _dma_init( unsigned int cluster_xy,
                                unsigned int channel_id );
 
-extern unsigned int _dma_reset( unsigned int  cluster_id, 
+extern unsigned int _dma_reset( unsigned int  cluster_xy, 
                                 unsigned int  channel_id );
 
-extern unsigned int _dma_get_status( unsigned int  cluster_id, 
+extern unsigned int _dma_get_status( unsigned int  cluster_xy, 
                                      unsigned int  channel_id );
 
-extern unsigned int _dma_start_transfer( unsigned int       cluster_id,
+extern unsigned int _dma_start_transfer( unsigned int       cluster_xy,
                                          unsigned int       channel_id,
                                          unsigned long long dst_paddr,
Index: /soft/giet_vm/giet_drivers/fbf_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/fbf_driver.c	(revision 262)
+++ /soft/giet_vm/giet_drivers/fbf_driver.c	(revision 263)
@@ -96,7 +96,10 @@
 } fb_cma_channel_t;
 
+// array of FB_CMA channels descriptors (32 bytes per entry)
+// each entry contains one SRC and one DST chbuf descriptors.
 in_unckdata volatile fb_cma_channel_t 
 _fb_cma_channel[NB_CMA_CHANNELS] __attribute__((aligned(64)));
 
+// array of physical addresses for the FB_CMA channels descriptors
 in_unckdata volatile paddr_t          
 _fb_cma_desc_paddr[NB_CMA_CHANNELS];
@@ -105,12 +108,10 @@
 // _fb_cma_init()
 // This function uses the _fb_cma_channel[] and _fb_cma_desc_paddr[] arrays,
-// that are both indexed by the channel index.
-// where each entry contains one fb_cma_channel structure (defining two
-// SRC and DST chbuf descriptors), and does four things:
+// (that are both indexed by the channel index), and does four things:
 //
 // 1) computes the physical addresses for the two source user buffers, for 
 //    the destination frame buffer. It initialises the channel descriptor 
 //    _fb_cma_channel[i], containing the SRC chbuf descriptor (two buffers), 
-//    the DST chbuf descriptor (one single frame buffer), and the buffer length. 
+//    the DST chbuf descriptor (one single buffer), and the buffer length. 
 // 
 // 2) computes the physical address for the channel descriptor and register it
@@ -138,5 +139,5 @@
     unsigned int  flags;               // protection flags
     unsigned int  ppn;                 // physical page number
-    paddr_t       channel_pbase;       // physical address of channel descriptor
+    paddr_t       desc_paddr;          // physical address of channel descriptor
 
     // get CMA channel index
@@ -255,35 +256,36 @@
         return 1;
     } 
-    channel_pbase = (((paddr_t)ppn) << 12) | (vaddr & 0x00000FFF);
-    _fb_cma_desc_paddr[channel_id] = channel_pbase;
-
-#if GIET_DEBUG_CMA_DRIVER
+    _fb_cma_desc_paddr[channel_id] = (((paddr_t)ppn) << 12) | (vaddr & 0x00000FFF);
+
+    desc_paddr                     = (((paddr_t)ppn) << 12) | (vaddr & 0x00000FFF);
+    
+
+#if GIET_DEBUG_FBF_DRIVER
+_tty_get_lock( 0 );
+_puts("\n[CMA DEBUG] fb_cma_init()");
+_puts("\n - fbf       pbase = ");
+_putl( _fb_cma_channel[channel_id].fbf );
+_puts("\n - buf0      pbase = ");
+_putl( _fb_cma_channel[channel_id].buf0 );
+_puts("\n - buf1      pbase = ");
+_putl( _fb_cma_channel[channel_id].buf1 );
+_puts("\n - channel   pbase = ");
+_putl( _fb_cma_desc_paddr[channel_id] );
 _puts("\n");
-_puts("- fbf       pbase = ");
-_putl( _fb_cma_channel[channel_id].fbf );
-_puts("\n");
-_puts("- buf0      pbase = ");
-_putl( _fb_cma_channel[channel_id].buf0 );
-_puts("\n");
-_puts("- buf1      pbase = ");
-_putl( _fb_cma_channel[channel_id].buf1 );
-_puts("\n");
-_puts("- channel   pbase = ");
-_putl( channel_pbase );
-_puts("\n");
+_tty_release_lock( 0 );
 #endif
 
     // SYNC request for channel descriptor
-    _memc_sync( channel_pbase, 32 );
+    _memc_sync( desc_paddr, 32 );
 
     // CMA channel activation
     unsigned int* cma_vbase = (unsigned int *)&seg_cma_base;
-    unsigned int  offset     = channel_id * CHBUF_CHANNEL_SPAN;
-
-    cma_vbase[offset + CHBUF_SRC_DESC]  = (unsigned int)(channel_pbase & 0xFFFFFFFF);
-    cma_vbase[offset + CHBUF_SRC_EXT]   = (unsigned int)(channel_pbase >> 32);
+    unsigned int  offset    = channel_id * CHBUF_CHANNEL_SPAN;
+
+    cma_vbase[offset + CHBUF_SRC_DESC]  = (unsigned int)(desc_paddr & 0xFFFFFFFF);
+    cma_vbase[offset + CHBUF_SRC_EXT]   = (unsigned int)(desc_paddr >> 32);
     cma_vbase[offset + CHBUF_SRC_NBUFS] = 2;
-    cma_vbase[offset + CHBUF_DST_DESC]  = (unsigned int)(channel_pbase & 0xFFFFFFFF) + 16;
-    cma_vbase[offset + CHBUF_DST_EXT]   = (unsigned int)(channel_pbase >> 32);
+    cma_vbase[offset + CHBUF_DST_DESC]  = (unsigned int)(desc_paddr & 0xFFFFFFFF) + 16;
+    cma_vbase[offset + CHBUF_DST_EXT]   = (unsigned int)(desc_paddr >> 32);
     cma_vbase[offset + CHBUF_DST_NBUFS] = 1;
     cma_vbase[offset + CHBUF_BUF_SIZE]  = length;
@@ -302,29 +304,83 @@
 #endif
 }
-//////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
 // _fb_cma_write()
-// This function makes a SYNC request for the source user buffer.
-// Then it updates the status of the SRC and DST chbuf descriptors, to allow
-// the CMA component to transfer the source user buffer buffer to the destination 
-// frame buffer, and makes a SYNC request for the channel descriptor.
-//
-// - buffer_id : user buffer index (0 => buf0 / not 0 => buf1)
+//
+// It updates the status of the SRC and DST chbuf descriptors, to allow the CMA
+// component to transfer the source user buffer to the frame buffer.
+//
+// If the IO Bridge component is used:
+// 1) it makes an INVAL request for the channel descriptor, before testing the
+//    source buffer status, because it is modified in XRAM by the CMA component.
+// 2) it makes a SYNC request for the source user buffer before activating the CMA 
+//    transfer, because the data will be read from XRAM by the CMA component.
+// 3) it makes a SYNC request for the channel descriptor after modification 
+//    of the SRC and DST status, because these descriptors will be read from XRAM 
+//    by the CMA component.
+//
+// The buffer_id argument is the user buffer index (0 => buf0 / not 0 => buf1)
 // Returns 0 if success, > 0 if error 
-//////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
 unsigned int _fb_cma_write( unsigned int buffer_id )
 {
 #if NB_CMA_CHANNELS > 0
 
-    paddr_t         buf_paddr;
-    unsigned int    buf_length;
+    volatile paddr_t buf_paddr;
+    unsigned int     buf_length;
+    unsigned int     full = 1;
+
+    unsigned int     count = 0;
 
     // get CMA channel index 
     unsigned int channel_id = _get_context_slot(CTX_CMA_ID);
 
-    // SYNC request for the source user buffer
-    if ( buffer_id == 0 )  buf_paddr = _fb_cma_channel[channel_id].buf0;
-    else                   buf_paddr = _fb_cma_channel[channel_id].buf1;
-    buf_length = _fb_cma_channel[channel_id].length;
-    _memc_sync( buf_paddr, buf_length );
+#if GIET_DEBUG_FBF_DRIVER
+_tty_get_lock( 0 );
+_puts("\n[CMA DEBUG] fb_cma_write() for CMA channel ");
+_putd( channel_id );
+_puts(" / buf_id = ");
+_putd( buffer_id );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    // waiting buffer empty
+    while ( full )
+    {  
+        if ( USE_IOB )
+        {
+            // INVAL L2 cache for the channel descriptor,
+            _memc_inval( _fb_cma_desc_paddr[channel_id], 32 );
+
+            // INVAL L1 cache for the channel descriptor,
+            _dcache_buf_invalidate( &_fb_cma_channel[channel_id], 32 );
+        }
+
+        // read SRC buffer descriptor
+        if ( buffer_id == 0 ) buf_paddr = _fb_cma_channel[channel_id].buf0;
+        else                  buf_paddr = _fb_cma_channel[channel_id].buf1;
+        full = ( (unsigned int)(buf_paddr>>63) );
+
+        count++;
+        if ( count == 10 ) _exit();
+
+#if GIET_DEBUG_FBF_DRIVER
+_tty_get_lock( 0 );
+_puts(" - buffer descriptor = ");
+_putl( buf_paddr );
+_puts(" at cycle ");
+_putd( _get_proctime() );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    }
+
+    if ( USE_IOB )
+    {
+        // SYNC request for the user buffer because 
+        // this buffer will be read from XRAM by the CMA component
+        _memc_sync( buf_paddr, _fb_cma_channel[channel_id].length );
+    }
 
     // set SRC full 
@@ -338,8 +394,10 @@
                                        & 0x7FFFFFFFFFFFFFFFULL;
 
-    // SYNC request for the channel descriptor
-    buf_paddr  = _fb_cma_desc_paddr[channel_id];
-    buf_length = 32;
-    _memc_sync( buf_paddr, buf_length );
+    if ( USE_IOB )
+    {
+        // SYNC request for the channel descriptor, because
+        // it will be read in XRAM by the CMA component
+        _memc_sync( _fb_cma_desc_paddr[channel_id], 32 );
+    }
 
     return 0;
Index: /soft/giet_vm/giet_drivers/icu_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/icu_driver.c	(revision 262)
+++ /soft/giet_vm/giet_drivers/icu_driver.c	(revision 263)
@@ -16,5 +16,5 @@
 // The virtual base address of the segment associated to the component is:
 //
-//      seg_icu_base + cluster_id * vseg_cluster_increment 
+//      seg_icu_base + cluster_xy * vseg_cluster_increment 
 //
 // The seg_icu_base and vseg_cluster_increment values must be defined 
@@ -24,20 +24,25 @@
 #include <giet_config.h>
 #include <icu_driver.h>
+#include <tty_driver.h>
 #include <utils.h>
 
-#if !defined(NB_CLUSTERS) 
-# error: You must define NB_CLUSTERS in the hard_config.h file
+#if !defined(X_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
 #endif
 
-#if (NB_CLUSTERS > 256)
-# error: NB_CLUSTERS cannot be larger than 256!
+#if !defined(Y_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(X_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(Y_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
 #endif
 
 #if !defined(NB_PROCS_MAX) 
 # error: You must define NB_PROCS_MAX in the hard_config.h file
-#endif
-
-#if (NB_PROCS_MAX > 8)
-# error: NB_PROCS_MAX cannot be larger than 8!
 #endif
 
@@ -53,18 +58,21 @@
 // Returns 0 if success, > 0 if error.
 ////////////////////////////////////////////////////////////////////////////////
-unsigned int _icu_set_mask( unsigned int cluster_id,
+unsigned int _icu_set_mask( unsigned int cluster_xy,
                             unsigned int proc_id,
                             unsigned int value )
 {
     // parameters checking 
-    if (cluster_id >= NB_CLUSTERS) return 1; 
-    if (proc_id >= NB_PROCS_MAX)   return 1; 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+    if (proc_id >= NB_PROCS_MAX) return 1; 
 
 #if USE_XICU
-    _puts("[GIET ERROR] _icu_set_mask should not be used if USE_XICU is set\n");
+    _puts("[GIET ERROR] _icu_set_mask() should not be used if USE_XICU is set\n");
     return 1;
 #else
     unsigned int * icu_address = (unsigned int *) ((unsigned int)&seg_icu_base + 
-                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
     icu_address[proc_id * ICU_SPAN + ICU_MASK_SET] = value; 
     return 0;
@@ -78,18 +86,21 @@
 // Returns 0 if success, > 0 if error.
 ////////////////////////////////////////////////////////////////////////////////
-unsigned int _icu_get_index( unsigned int cluster_id, 
+unsigned int _icu_get_index( unsigned int cluster_xy, 
                              unsigned int proc_id, 
                              unsigned int * buffer) 
 {
     // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)  return 1;
-    if (proc_id >= NB_PROCS_MAX)    return 1;
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+    if (proc_id >= NB_PROCS_MAX) return 1;
 
 #if USE_XICU
-    _puts("[GIET ERROR] _icu_get_index should not be used if USE_XICU is set\n");
+    _puts("[GIET ERROR] _icu_get_index() should not be used if USE_XICU is set\n");
     return 1;
 #else
     unsigned int* icu_address = (unsigned int *) ((unsigned int)&seg_icu_base + 
-                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
     *buffer = icu_address[proc_id * ICU_SPAN + ICU_IT_VECTOR]; 
     return 0;
Index: /soft/giet_vm/giet_drivers/icu_driver.h
===================================================================
--- /soft/giet_vm/giet_drivers/icu_driver.h	(revision 262)
+++ /soft/giet_vm/giet_drivers/icu_driver.h	(revision 263)
@@ -29,9 +29,9 @@
 ///////////////////////////////////////////////////////////////////////////////////
 
-extern unsigned int _icu_get_index( unsigned int cluster_id, 
+extern unsigned int _icu_get_index( unsigned int cluster_xy, 
                                     unsigned int proc_id, 
                                     unsigned int * buffer );
 
-extern unsigned int _icu_set_mask( unsigned int cluster_id,
+extern unsigned int _icu_set_mask( unsigned int cluster_xy,
                                    unsigned int proc_id,
                                    unsigned int value );
Index: /soft/giet_vm/giet_drivers/ioc_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/ioc_driver.c	(revision 262)
+++ /soft/giet_vm/giet_drivers/ioc_driver.c	(revision 263)
@@ -285,5 +285,5 @@
 _puts("\n");
 _puts(" - lba       = ");
-_putd( lba );
+_putx( lba );
 _puts("\n");
 _tty_release_lock( 0 );
@@ -379,4 +379,6 @@
 _puts(" for processor ");
 _putd( _get_procid() );
+_puts(" : error = ");
+_putd( (unsigned int)error );
 _puts("\n");
 _tty_release_lock( 0 );
Index: /soft/giet_vm/giet_drivers/mmc_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/mmc_driver.c	(revision 262)
+++ /soft/giet_vm/giet_drivers/mmc_driver.c	(revision 263)
@@ -21,12 +21,21 @@
 #include <giet_config.h>
 #include <mmc_driver.h>
+#include <tty_driver.h>
 #include <utils.h>
 
-#if !defined(NB_CLUSTERS) 
-# error: You must define NB_CLUSTERS in the hard_config.h file
+#if !defined(X_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
 #endif
 
-#if (NB_CLUSTERS > 256)
-# error: NB_CLUSTERS cannot be larger than 256!
+#if !defined(Y_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(X_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(Y_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
 #endif
 
@@ -40,8 +49,27 @@
                   unsigned int buf_length )
 {
-    unsigned int cluster_id    = (unsigned int)((buf_paddr>>32)/(256/NB_CLUSTERS));
+    // compute cluster coordinates
+    unsigned int cluster_xy = (unsigned int)(buf_paddr>>(40-X_WIDTH-Y_WIDTH));
+    unsigned int x          = cluster_xy >> Y_WIDTH;
+    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
+
+    // parameters checking 
+    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
+    {
+        _puts("\n[GIET ERROR] in _memc_inval() : illegal cluster index[");
+        _putd( x );
+        _puts(",");
+        _putd( y );
+        _puts("]\n");
+        _puts("   - paddr      = ");
+        _putl( buf_paddr );
+        _puts("\n   - cluster_xy = ");
+        _putx( cluster_xy );
+        _puts("\n");
+        _exit();
+    }
 
     unsigned int* mmc_address = (unsigned int*)((unsigned int)&seg_mmc_base + 
-                                (cluster_id * (unsigned int)&vseg_cluster_increment));
+                                (cluster_xy * (unsigned int)&vseg_cluster_increment));
 
     // get the hard lock protecting exclusive access to MEMC
@@ -66,8 +94,27 @@
                  unsigned int buf_length )
 {
-    unsigned int cluster_id    = (unsigned int)((buf_paddr>>32)/(256/NB_CLUSTERS));
+    // compute cluster coordinates
+    unsigned int cluster_xy = (unsigned int)(buf_paddr>>(40-X_WIDTH-Y_WIDTH));
+    unsigned int x          = cluster_xy >> Y_WIDTH;
+    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
+
+    // parameters checking 
+    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
+    {
+        _puts("\n[GIET ERROR] in _memc_sync() : illegal cluster index[");
+        _putd( x );
+        _puts(",");
+        _putd( y );
+        _puts("]\n");
+        _puts("   - paddr      = ");
+        _putl( buf_paddr );
+        _puts("\n   - cluster_xy = ");
+        _putx( cluster_xy );
+        _puts("\n");
+        _exit();
+    }
 
     unsigned int * mmc_address = (unsigned int *) ((unsigned int)&seg_mmc_base + 
-                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
 
     // get the hard lock protecting exclusive access to MEMC
Index: /soft/giet_vm/giet_drivers/mwr_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/mwr_driver.c	(revision 262)
+++ /soft/giet_vm/giet_drivers/mwr_driver.c	(revision 263)
@@ -12,5 +12,5 @@
 // The (virtual) base address of the associated segment is:
 //
-//       seg_mwr_base + cluster_id * vseg_cluster_increment
+//       seg_mwr_base + cluster_xy * vseg_cluster_increment
 //
 // The seg_mwr_base and vseg_cluster_increment values must be defined 
@@ -22,17 +22,25 @@
 #include <utils.h>
 
-#if !defined(NB_CLUSTERS) 
-# error: You must define NB_CLUSTERS in the hard_config.h file
+#if !defined(X_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
 #endif
 
-#if (NB_CLUSTERS > 256)
-# error: NB_CLUSTERS cannot be larger than 256!
+#if !defined(Y_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(X_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(Y_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
 #endif
 
 //////////////////////////////////////////////////////////////////////////////////
-//    _mwmr_hw_init()
+//    _mwr_hw_init()
 // This function initializes one MWMR controller channel (i.e. one coprocessor
 // port) in a given cluster.
-// - cluster_id    : cluster index
+// - cluster_xy    : cluster index
 // _ port_id       : port index
 // - way           : direction (to_coproc/from_coproc)
@@ -40,23 +48,25 @@
 // TODO : The MWMR controler should be modified to support 40 bits addresses...
 //        Introduce a MWMR_CONFIG_PADDR_EXT register in the MWMR coprocessor
-//        To support addresses > 32 bits and remove this limitation...
 //////////////////////////////////////////////////////////////////////////////////
 // Returns 0 if success, returns > 0 if error.
 //////////////////////////////////////////////////////////////////////////////////
-unsigned int _mwmr_hw_init( unsigned int           cluster_id, 
-                            unsigned int           port_id, 
-                            unsigned int           from_coproc,
-                            paddr_t                channel_pbase ) 
+unsigned int _mwr_hw_init( unsigned int           cluster_xy, 
+                           unsigned int           port_id, 
+                           unsigned int           from_coproc,
+                           paddr_t                channel_pbase ) 
 {
-    _puts(" [GIET_ERROR] _mwmr_hw_init() function not implemented yet\n");
+    _puts(" [GIET_ERROR] _mwr_hw_init() function not supported yet\n");
     _exit();
 
 /*
     // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)      return 1;
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                    return 1; 
+    if (y >= Y_SIZE)                    return 1; 
 
-    // compute MWMR base address
-    unsigned int* mwmr_address = (unsigned int*) ((unsigned int)&seg_mwmr_base + 
-                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
+    // compute base address
+    unsigned int* mwr_address = (unsigned int*) ((unsigned int)&seg_mwr_base + 
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
 
     unsigned int lsb = (unsigned int)channel_pbase;
@@ -68,12 +78,12 @@
 
     // initializes and launches mwmr controler
-    mwmr_address[port_id * MWMR_SPAN + MWMR_CONFIG_FIFO_WAY]  = from_coproc;
-    mwmr_address[port_id * MWMR_SPAN + MWMR_CONFIG_FIFO_NO]   = port_id;
-    mwmr_address[port_id * MWMR_SPAN + MWMR_CONFIG_WIDTH]     = width;
-    mwmr_address[port_id * MWMR_SPAN + MWMR_CONFIG_DEPTH]     = depth;
-    mwmr_address[port_id * MWMR_SPAN + MWMR_CONFIG_STATUS]    = lsb;
-    mwmr_address[port_id * MWMR_SPAN + MWMR_CONFIG_DATA]      = lsb + 24;
-    mwmr_address[port_id * MWMR_SPAN + MWMR_CONFIG_EXT]       = msb;
-    mwmr_address[port_id * MWMR_SPAN + MWMR_CONFIG_RUNNING]   = 1;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_FIFO_WAY]  = from_coproc;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_FIFO_NO]   = port_id;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_WIDTH]     = width;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_DEPTH]     = depth;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_STATUS]    = lsb;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_DATA]      = lsb + 24;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_EXT]       = msb;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_RUNNING]   = 1;
 */
     return 0;
Index: /soft/giet_vm/giet_drivers/mwr_driver.h
===================================================================
--- /soft/giet_vm/giet_drivers/mwr_driver.h	(revision 262)
+++ /soft/giet_vm/giet_drivers/mwr_driver.h	(revision 263)
@@ -19,10 +19,13 @@
     MWMR_CONFIG_FIFO_WAY,
     MWMR_CONFIG_FIFO_NO,
-    MWMR_CONFIG_STATUS_ADDR,
+    MWMR_CONFIG_STATUS,
     MWMR_CONFIG_DEPTH,
     MWMR_CONFIG_BUFFER_ADDR,
     MWMR_CONFIG_RUNNING,
     MWMR_CONFIG_WIDTH,
-    MWMR_FIFO_FILL_STATUS,
+    MWMR_CONFIG_DATA,
+    MWMR_CONFIG_EXT,
+    /***/
+    MWMR_SPAN,
 };
 
@@ -37,8 +40,8 @@
 ///////////////////////////////////////////////////////////////////////////////////
 
-extern unsigned int _mwmr_hw_init( unsigned int           cluster_id, 
-                                   unsigned int           port_id, 
-                                   unsigned int           from_coproc,
-                                   unsigned long long     channel_pbase);
+extern unsigned int _mwr_hw_init( unsigned int           cluster_xy, 
+                                  unsigned int           port_id, 
+                                  unsigned int           from_coproc,
+                                  unsigned long long     channel_pbase);
 
 ///////////////////////////////////////////////////////////////////////////////////
Index: /soft/giet_vm/giet_drivers/tim_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/tim_driver.c	(revision 262)
+++ /soft/giet_vm/giet_drivers/tim_driver.c	(revision 263)
@@ -16,5 +16,5 @@
 // - "user" timers : requested by the task in the mapping_info data structure.
 //   For each user timer, the timer_id is stored in the context of the task.
-// The global index is cluster_id * (NB_PROCS_MAX + NB_TIM_CHANNELS) + local_id
+// The global index is cluster_xy * (NB_PROCS_MAX + NB_TIM_CHANNELS) + local_id
 //
 // The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in the
@@ -25,5 +25,5 @@
 // The virtual base address of the segment associated to a channel is:
 //
-//     seg_tim_base + cluster_id * vseg_cluster_increment + TIMER_SPAN * timer_id
+//     seg_tim_base + cluster_xy * vseg_cluster_increment + TIMER_SPAN * timer_id
 //
 // The seg_tim_base and vseg_cluster_increment values must be defined 
@@ -35,18 +35,22 @@
 #include <utils.h>
 
-#if !defined(NB_CLUSTERS) 
-# error: You must define NB_CLUSTERS in the hard_config.h file
+#if !defined(X_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
 #endif
 
-#if (NB_CLUSTERS > 256)
-# error: NB_CLUSTERS cannot be larger than 256!
+#if !defined(Y_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(X_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(Y_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
 #endif
 
 #if !defined(NB_PROCS_MAX) 
 # error: You must define NB_PROCS_MAX in the hard_config.h file
-#endif
-
-#if (NB_PROCS_MAX > 8)
-# error: NB_PROCS_MAX cannot be larger than 8!
 #endif
 
@@ -59,8 +63,4 @@
 #endif
 
-#if !defined( USE_XICU )
-# error: You must define USE_XICU in the hard_config.h file
-#endif
-
 ///////////////////  Timer global variables ////////////////////////////////////////
 
@@ -68,6 +68,6 @@
 
 #if (NB_TIM_CHANNELS > 0)
-in_unckdata volatile unsigned char _user_timer_event[NB_CLUSTERS * NB_TIM_CHANNELS] 
-                            = { [0 ... ((NB_CLUSTERS * NB_TIM_CHANNELS) - 1)] = 0 };
+in_unckdata volatile unsigned char _user_timer_event[X_SIZE*Y_SIZE*NB_TIM_CHANNELS] 
+                            = { [0 ... ((X_SIZE*Y_SIZE*NB_TIM_CHANNELS) - 1)] = 0 };
 #endif
 
@@ -80,14 +80,17 @@
 // Returns 0 if success, > 0 if error.
 //////////////////////////////////////////////////////////////////////////////
-unsigned int _timer_start( unsigned int cluster_id, 
+unsigned int _timer_start( unsigned int cluster_xy, 
                            unsigned int local_id, 
                            unsigned int period) 
 {
     // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)    return 1;
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                  return 1; 
+    if (y >= Y_SIZE)                  return 1; 
     if (local_id >= NB_TIM_CHANNELS)  return 1;
 
     unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + 
-                                  (cluster_id * (unsigned int)&vseg_cluster_increment));
+                                  (cluster_xy * (unsigned int)&vseg_cluster_increment));
 
     timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
@@ -102,13 +105,16 @@
 // Returns 0 if success, > 0 if error.
 //////////////////////////////////////////////////////////////////////////////
-unsigned int _timer_stop( unsigned int cluster_id, 
+unsigned int _timer_stop( unsigned int cluster_xy, 
                           unsigned int local_id) 
 {
     // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)    return 1;
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                  return 1; 
+    if (y >= Y_SIZE)                  return 1; 
     if (local_id >= NB_TIM_CHANNELS)  return 1;
 
     unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + 
-                                  (cluster_id * (unsigned int)&vseg_cluster_increment));
+                                  (cluster_xy * (unsigned int)&vseg_cluster_increment));
 
     timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0;
@@ -124,13 +130,16 @@
 // Returns 0 if success, > 0 if error.
 //////////////////////////////////////////////////////////////////////////////
-unsigned int _timer_reset_irq( unsigned int cluster_id, 
+unsigned int _timer_reset_irq( unsigned int cluster_xy, 
                                unsigned int local_id ) 
 {
     // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)    return 1;
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                  return 1; 
+    if (y >= Y_SIZE)                  return 1; 
     if (local_id >= NB_TIM_CHANNELS)  return 1;
 
     unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + 
-                                   (cluster_id * (unsigned int)&vseg_cluster_increment));
+                                   (cluster_xy * (unsigned int)&vseg_cluster_increment));
 
     timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0;
@@ -147,14 +156,17 @@
 // This function is called during a context switch (user or preemptive)
 //////////////////////////////////////////////////////////////////////i//////
-unsigned int _timer_reset_cpt( unsigned int cluster_id, 
+unsigned int _timer_reset_cpt( unsigned int cluster_xy, 
                                unsigned int local_id) 
 {
     // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)    return 1;
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                  return 1; 
+    if (y >= Y_SIZE)                  return 1; 
     if (local_id >= NB_TIM_CHANNELS)  return 1;
 
     // We suppose that the TIMER_MODE register value is 0x3
     unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + 
-                                   (cluster_id * (unsigned int)&vseg_cluster_increment));
+                                   (cluster_xy * (unsigned int)&vseg_cluster_increment));
 
     unsigned int period = timer_address[local_id * TIMER_SPAN + TIMER_PERIOD];
Index: /soft/giet_vm/giet_drivers/tim_driver.h
===================================================================
--- /soft/giet_vm/giet_drivers/tim_driver.h	(revision 262)
+++ /soft/giet_vm/giet_drivers/tim_driver.h	(revision 263)
@@ -29,15 +29,15 @@
 extern volatile unsigned char _timer_event[];
 
-extern unsigned int _timer_start( unsigned int cluster_id, 
+extern unsigned int _timer_start( unsigned int cluster_xy, 
                                   unsigned int local_id, 
                                   unsigned int period );
 
-extern unsigned int _timer_stop( unsigned int cluster_id,
+extern unsigned int _timer_stop( unsigned int cluster_xy,
                                  unsigned int local_id );
 
-extern unsigned int _timer_reset_irq( unsigned int cluster_id, 
+extern unsigned int _timer_reset_irq( unsigned int cluster_xy, 
                                       unsigned int local_id );
 
-extern unsigned int _timer_reset_cpt( unsigned int cluster_id, 
+extern unsigned int _timer_reset_cpt( unsigned int cluster_xy, 
                                       unsigned int local_id);
 
Index: /soft/giet_vm/giet_drivers/xcu_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/xcu_driver.c	(revision 262)
+++ /soft/giet_vm/giet_drivers/xcu_driver.c	(revision 263)
@@ -16,5 +16,5 @@
 // The virtual base address of the segment associated to the component is:
 //
-//      seg_xcu_base + cluster_id * vseg_cluster_increment
+//      seg_xcu_base + cluster_xy * vseg_cluster_increment
 //
 // The seg_xcu_base and vseg_cluster_increment values must be defined 
@@ -24,20 +24,26 @@
 #include <giet_config.h>
 #include <xcu_driver.h>
+#include <tty_driver.h>
+#include <mapping_info.h>
 #include <utils.h>
 
-#if !defined(NB_CLUSTERS) 
-# error: You must define NB_CLUSTERS in the hard_config.h file
-#endif
-
-#if (NB_CLUSTERS > 256)
-# error: NB_CLUSTERS cannot be larger than 256!
+#if !defined(X_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(Y_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(X_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(Y_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
 #endif
 
 #if !defined(NB_PROCS_MAX) 
 # error: You must define NB_PROCS_MAX in the hard_config.h file
-#endif
-
-#if (NB_PROCS_MAX > 8)
-# error: NB_PROCS_MAX cannot be larger than 8!
 #endif
 
@@ -53,19 +59,24 @@
 // Returns 0 if success, > 0 if error.
 ////////////////////////////////////////////////////////////////////////////////
-unsigned int _xcu_set_mask( unsigned int cluster_id, unsigned int proc_id,
+unsigned int _xcu_set_mask( unsigned int cluster_xy, 
+                            unsigned int proc_id,
                             unsigned int value,
-                            unsigned int is_PTI) 
-{
-    // parameters checking 
-    if (cluster_id >= NB_CLUSTERS) return 1; 
-    if (proc_id >= NB_PROCS_MAX)   return 1; 
+                            unsigned int irq_type ) 
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+    if (proc_id >= NB_PROCS_MAX) return 1; 
 
 #if USE_XICU
     unsigned int* xcu_address = (unsigned int *) ((unsigned int)&seg_xcu_base + 
-                                (cluster_id * (unsigned int)&vseg_cluster_increment));
-    if (is_PTI) 
-        xcu_address[XICU_REG(XICU_MSK_PTI_ENABLE, proc_id)] = value;
-    else 
-        xcu_address[XICU_REG(XICU_MSK_HWI_ENABLE, proc_id)] = value;
+                                (cluster_xy * (unsigned int)&vseg_cluster_increment));
+    unsigned int func;
+    if      (irq_type == IRQ_TYPE_PTI) func = XICU_MSK_PTI_ENABLE;
+    else if (irq_type == IRQ_TYPE_SWI) func = XICU_MSK_WTI_ENABLE;
+    else                               func = XICU_MSK_HWI_ENABLE;
+    xcu_address[XICU_REG(func,proc_id)] = value;
     return 0;
 #else
@@ -86,15 +97,18 @@
 // Returns 0 if success, > 0 if error.
 ////////////////////////////////////////////////////////////////////////////////
-unsigned int _xcu_get_index( unsigned int cluster_id, 
+unsigned int _xcu_get_index( unsigned int cluster_xy, 
                              unsigned int proc_id, 
                              unsigned int * buffer) 
 {
     // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)  return 1;
-    if (proc_id >= NB_PROCS_MAX)    return 1;
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+    if (proc_id >= NB_PROCS_MAX) return 1; 
 
 #if USE_XICU
     unsigned int* xcu_address = (unsigned int *) ((unsigned int)&seg_xcu_base + 
-                                (cluster_id * (unsigned int)&vseg_cluster_increment));
+                                (cluster_xy * (unsigned int)&vseg_cluster_increment));
 
     unsigned int prio = xcu_address[XICU_REG(XICU_PRIO, proc_id)];
@@ -125,15 +139,18 @@
 // Returns 0 if success, > 0 if error.
 ////////////////////////////////////////////////////////////////////////////////
-unsigned int _xcu_send_ipi( unsigned int cluster_id,
+unsigned int _xcu_send_ipi( unsigned int cluster_xy,
                             unsigned int proc_id,
                             unsigned int wdata )
 { 
     // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)  return 1;
-    if (proc_id >= NB_PROCS_MAX)    return 1;
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+    if (proc_id >= NB_PROCS_MAX) return 1; 
 
 #if USE_XICU
     unsigned int* xcu_address = (unsigned int *) ((unsigned int)&seg_xcu_base + 
-                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
     xcu_address[XICU_REG(XICU_WTI_REG, proc_id)] = wdata;
     return 0; 
@@ -152,16 +169,19 @@
 // Returns 0 if success, > 0 if error.
 ////////////////////////////////////////////////////////////////////////////////
-unsigned int _xcu_timer_start( unsigned int cluster_id,
-                               unsigned int local_id,
+unsigned int _xcu_timer_start( unsigned int cluster_xy,
+                               unsigned int proc_id,
                                unsigned int period )
 {
     // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)    return 1;
-    if (local_id >= NB_TIM_CHANNELS)  return 1;
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+    if (proc_id >= NB_PROCS_MAX) return 1; 
 
 #if USE_XICU
     unsigned int* xcu_address = (unsigned int *) ((unsigned int)&seg_xcu_base + 
-                                (cluster_id * (unsigned int)&vseg_cluster_increment));
-    xcu_address[XICU_REG(XICU_PTI_PER, local_id)] = period;
+                                (cluster_xy * (unsigned int)&vseg_cluster_increment));
+    xcu_address[XICU_REG(XICU_PTI_PER, proc_id)] = period;
     return 0;
 #else
@@ -179,15 +199,18 @@
 // Returns 0 if success, > 0 if error.
 //////////////////////////////////////////////////////////////////////////////
-unsigned int _xcu_timer_stop( unsigned int cluster_id, 
-                              unsigned int local_id) 
-{
-    // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)    return 1;
-    if (local_id >= NB_TIM_CHANNELS)  return 1;
+unsigned int _xcu_timer_stop( unsigned int cluster_xy, 
+                              unsigned int proc_id) 
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+    if (proc_id >= NB_PROCS_MAX) return 1; 
 
 #if USE_XICU
     unsigned int * xcu_address = (unsigned int *) ((unsigned int)&seg_xcu_base + 
-                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
-    xcu_address[XICU_REG(XICU_PTI_PER, local_id)] = 0;
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
+    xcu_address[XICU_REG(XICU_PTI_PER, proc_id)] = 0;
     return 0;
 #else
@@ -207,16 +230,19 @@
 // Returns 0 if success, > 0 if error.
 //////////////////////////////////////////////////////////////////////////////
-unsigned int _xcu_timer_reset_irq( unsigned int cluster_id, 
-                                   unsigned int local_id ) 
-{
-    // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)    return 1;
-    if (local_id >= NB_TIM_CHANNELS)  return 1;
+unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy, 
+                                   unsigned int proc_id ) 
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+    if (proc_id >= NB_PROCS_MAX) return 1; 
 
 #if USE_XICU
     unsigned int * xcu_address = (unsigned int *) ((unsigned int)&seg_xcu_base +
-                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
-
-    unsigned int bloup = xcu_address[XICU_REG(XICU_PTI_ACK, local_id)];
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    unsigned int bloup = xcu_address[XICU_REG(XICU_PTI_ACK, proc_id)];
     bloup++; // to avoid a warning 
     return 0;
@@ -238,21 +264,24 @@
 // This function is called during a context switch (user or preemptive)
 /////////////////////////////////////////////////////////////////////////////
-unsigned int _xcu_timer_reset_cpt( unsigned int cluster_id, 
-                                   unsigned int local_id ) 
-{
-    // parameters checking 
-    if (cluster_id >= NB_CLUSTERS)   return 1;
-    if (local_id >= NB_TIM_CHANNELS) return 1;
+unsigned int _xcu_timer_reset_cpt( unsigned int cluster_xy, 
+                                   unsigned int proc_id ) 
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+    if (proc_id >= NB_PROCS_MAX) return 1; 
 
 #if USE_XICU
     unsigned int * xcu_address = (unsigned int *) ((unsigned int) &seg_xcu_base + 
-                                 (cluster_id * (unsigned int)&vseg_cluster_increment));
-
-    unsigned int period = xcu_address[XICU_REG(XICU_PTI_PER, local_id)];
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    unsigned int period = xcu_address[XICU_REG(XICU_PTI_PER, proc_id)];
 
     // we write 0 first because if the timer is currently running, 
     // the corresponding timer counter is not reset
-    xcu_address[XICU_REG(XICU_PTI_PER, local_id)] = 0;
-    xcu_address[XICU_REG(XICU_PTI_PER, local_id)] = period;
+    xcu_address[XICU_REG(XICU_PTI_PER, proc_id)] = 0;
+    xcu_address[XICU_REG(XICU_PTI_PER, proc_id)] = period;
     return 0;
 #else
Index: /soft/giet_vm/giet_drivers/xcu_driver.h
===================================================================
--- /soft/giet_vm/giet_drivers/xcu_driver.h	(revision 262)
+++ /soft/giet_vm/giet_drivers/xcu_driver.h	(revision 263)
@@ -39,34 +39,34 @@
 
 #define XICU_REG(func, index) (((func)<<5)|(index))
-
+ 
 ///////////////////////////////////////////////////////////////////////////////////
 // XICU access functions 
 ///////////////////////////////////////////////////////////////////////////////////
 
-extern unsigned int _xcu_get_index( unsigned int cluster_id, 
+extern unsigned int _xcu_get_index( unsigned int cluster_xy, 
                                     unsigned int proc_id, 
                                     unsigned int * buffer );
 
-extern unsigned int _xcu_set_mask( unsigned int cluster_id,
+extern unsigned int _xcu_set_mask( unsigned int cluster_xy,
                                    unsigned int proc_id,
                                    unsigned int mask, 
                                    unsigned int is_timer );
 
-extern unsigned int _xcu_send_ipi( unsigned int cluster_id,
+extern unsigned int _xcu_send_ipi( unsigned int cluster_xy,
                                    unsigned int proc_id,
                                    unsigned int wdata );
 
-extern unsigned int _xcu_timer_start( unsigned int cluster_id, 
-                                      unsigned int local_id,
+extern unsigned int _xcu_timer_start( unsigned int cluster_xy, 
+                                      unsigned int proc_id,
                                       unsigned int period ); 
 
-extern unsigned int _xcu_timer_stop( unsigned int cluster_id, 
-                                     unsigned int local_id ); 
+extern unsigned int _xcu_timer_stop( unsigned int cluster_xy, 
+                                     unsigned int proc_id ); 
 
-extern unsigned int _xcu_timer_reset_irq( unsigned int cluster_id, 
-                                          unsigned int local_id );
+extern unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy, 
+                                          unsigned int proc_id );
 
-extern unsigned int _xcu_timer_reset_cpt( unsigned int cluster_id, 
-                                          unsigned int local_id ); 
+extern unsigned int _xcu_timer_reset_cpt( unsigned int cluster_xy, 
+                                          unsigned int proc_id ); 
 
 ///////////////////////////////////////////////////////////////////////////////////
Index: /soft/giet_vm/giet_fat32/fat32.c
===================================================================
--- /soft/giet_vm/giet_fat32/fat32.c	(revision 262)
+++ /soft/giet_vm/giet_fat32/fat32.c	(revision 263)
@@ -497,7 +497,7 @@
     fat.cache_lba = lba;
 
-//  #if GIET_DEBUG_FAT
-//  display_fat_cache();
-//  #endif
+    #if GIET_DEBUG_FAT
+    display_fat_cache();
+    #endif
 
     // in this loop we scan all names in directory identified by cluster: 
@@ -714,5 +714,5 @@
     if ( _ioc_read( mode,             // mode for IOC driver
                     0,                // sector index 
-                    fat.fat_cache,   // buffer address
+                    fat.fat_cache,    // buffer address
                     1 ) )             // one sector
     { 
@@ -760,5 +760,5 @@
 #if GIET_DEBUG_FAT
 _tty_get_lock( 0 );
-_puts("\n[FAT DEBUG] First Partition Sector Loaded\n");
+_puts("\n[FAT DEBUG] Partition First Sector Loaded\n");
 _tty_release_lock( 0 );
 #endif
@@ -839,5 +839,5 @@
 ///////////////////////////////////////////////////////////////////////////////
 // This function checks that the kernel FAT structure has been initialised,
-// and makes the FAT initialisation if required (first user _fat_open request). 
+// and makes the FAT initialisation if it is the first user open request. 
 // This function searches a file identified by the "pathname" argument.
 // It starts from root (cluster 2) to scan successively each subdirectory.
@@ -871,9 +871,8 @@
     if( fat.initialised != FAT_INITIALISED )
     {
-        _fat_init( IOC_KERNEL_MODE );  // we use KERNEL_MODE, because
-                                       // we need to write into FAT cache
+        _fat_init( IOC_BOOT_VA_MODE );
     }
  
-    // Scan the sub-directories, starting from the root directory (cluster 2)
+    // Scan the directories, starting from the root directory (cluster 2)
     // - The get_name_from_path() function extracts (successively) 
     //   each directory name from the pathname, and store it in name[] buffer
Index: /soft/giet_vm/giet_kernel/irq_handler.c
===================================================================
--- /soft/giet_vm/giet_kernel/irq_handler.c	(revision 262)
+++ /soft/giet_vm/giet_kernel/irq_handler.c	(revision 263)
@@ -29,5 +29,5 @@
 
 #if NB_TIM_CHANNELS
-extern volatile unsigned char _user_timer_event[NB_CLUSTERS * NB_TIM_CHANNELS] ;
+extern volatile unsigned char _user_timer_event[X_SIZE*Y_SIZE*NB_TIM_CHANNELS] ;
 #endif
 
Index: /soft/giet_vm/giet_kernel/kernel_init.c
===================================================================
--- /soft/giet_vm/giet_kernel/kernel_init.c	(revision 262)
+++ /soft/giet_vm/giet_kernel/kernel_init.c	(revision 263)
@@ -11,5 +11,5 @@
 // physicals addresses can have up to 40 bits, and use the  (unsigned long long) type.
 // It natively supports clusterised shared mmemory multi-processors architectures, 
-// where each processor is identified by a composite index (cluster_id, local_id),
+// where each processor is identified by a composite index (cluster_xy, local_id),
 // and where there is one physical memory bank per cluster.
 //
@@ -61,5 +61,5 @@
 
 __attribute__((section (".kdata"))) 
-static_scheduler_t* _schedulers[NB_CLUSTERS * NB_PROCS_MAX];   // virtual addresses
+static_scheduler_t* _schedulers[X_SIZE*Y_SIZE * NB_PROCS_MAX];   // virtual addresses
 
 ////////////////////////////////////////////////////////////////////////////////////
@@ -68,5 +68,5 @@
 
 __attribute__((section (".kdata"))) 
-unsigned int _idle_stack[NB_CLUSTERS * NB_PROCS_MAX * 128]; 
+unsigned int _idle_stack[X_SIZE*Y_SIZE * NB_PROCS_MAX * 128]; 
 
 ////////////////////////////////////////////////////////////////////////////////////
@@ -108,13 +108,19 @@
 {
     unsigned int global_pid = _get_procid();
+    unsigned int cluster_xy = global_pid / NB_PROCS_MAX;
+    unsigned int local_pid  = global_pid % NB_PROCS_MAX;
 
 #if 0
-// Debug feature : we can kill all processors but one
-if ( global_pid != 1 ) 
+////////////// Debug : we can kill all processors but one
+if ( global_pid != 0 ) 
 {
     _tty_get_lock( 0 );
-    _puts("\n[GIET] Processor ");
-    _putd( global_pid );
-    _puts(" suicide...\n");
+    _puts("\n[GIET] Processor[");
+    _putd( cluster_xy >> Y_WIDTH );
+    _puts(",");
+    _putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+    _puts(",");
+    _putd( local_pid );
+    _puts("] suicide...\n");
     _tty_release_lock( 0 );
     _exit();
@@ -125,6 +131,4 @@
     //          and contribute to initialise the _schedulers[] array
 
-    unsigned int        cluster_id = global_pid / NB_PROCS_MAX;
-    unsigned int        proc_id    = global_pid % NB_PROCS_MAX;
     static_scheduler_t* psched     = (static_scheduler_t*)_get_sched();
     unsigned int        tasks      = psched->tasks;
@@ -134,7 +138,11 @@
 #if GIET_DEBUG_INIT
 _tty_get_lock( 0 );
-_puts("\n[GIET DEBUG] Parallel init : step 1 for processor ");
-_putd(global_pid);
-_puts("\n - scheduler vbase = ");
+_puts("\n[GIET DEBUG] Parallel init : step 1 for processor[");
+_putd( cluster_xy >> Y_WIDTH );
+_puts(",");
+_putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+_puts(",");
+_putd( local_pid );
+_puts("]\n - scheduler vbase = ");
 _putx((unsigned int) psched);
 _puts("\n - tasks           = ");
@@ -173,7 +181,11 @@
 #if GIET_DEBUG_INIT
 _tty_get_lock( 0 );
-_puts("\n[GIET DEBUG] Parallel init : step 2 for processor ");
-_putd( global_pid );
-_puts(" / task ");
+_puts("\n[GIET DEBUG] Parallel init : step 2 for processor[");
+_putd( cluster_xy >> Y_WIDTH );
+_puts(",");
+_putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+_puts(",");
+_putd( local_pid );
+_puts("] / task ");
 _putd( ltid );
 _puts("\n - ctx_vsid  = ");
@@ -202,5 +214,5 @@
     //          there is at most 32 interrupts per processor
 
-    unsigned int isr_switch_channel = 0xFFFFFFFF;
+    unsigned int isr_switch_index = 0xFFFFFFFF;
     unsigned int irq_id;            // IN_IRQ index
     unsigned int hwi_mask = 0;
@@ -228,12 +240,16 @@
             _exit();
         }
-        if (isr == ISR_SWITCH) isr_switch_channel = irq_id;
+        if (isr == ISR_SWITCH) isr_switch_index = irq_id;
     }
 
 #if GIET_DEBUG_INIT
 _tty_get_lock( 0 );
-_puts("\n[GIET DEBUG] Parallel init : step 3 for processor ");
-_putd(global_pid);
-_puts("\n - ICU HWI_MASK = ");
+_puts("\n[GIET DEBUG] Parallel init : step 3 for processor[");
+_putd( cluster_xy >> Y_WIDTH );
+_puts(",");
+_putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+_puts(",");
+_putd( local_pid );
+_puts("]\n - ICU HWI_MASK = ");
 _putx(hwi_mask);
 _puts("\n - ICU SWI_MASK = ");
@@ -253,9 +269,9 @@
 
 #if USE_XICU
-    _xcu_set_mask(cluster_id, proc_id, hwi_mask, IRQ_TYPE_HWI); // set HWI_MASK
-    _xcu_set_mask(cluster_id, proc_id, swi_mask, IRQ_TYPE_SWI); // set SWI_MASK
-    _xcu_set_mask(cluster_id, proc_id, pti_mask, IRQ_TYPE_PTI); // set PTI_MASK
+    _xcu_set_mask(cluster_xy, local_pid, hwi_mask, IRQ_TYPE_HWI); // set HWI_MASK
+    _xcu_set_mask(cluster_xy, local_pid, swi_mask, IRQ_TYPE_SWI); // set SWI_MASK
+    _xcu_set_mask(cluster_xy, local_pid, pti_mask, IRQ_TYPE_PTI); // set PTI_MASK
 #else
-    _icu_set_mask(cluster_id, proc_id, (hwi_mask | pti_mask | swi_mask) );   
+    _icu_set_mask(cluster_xy, local_pid, (hwi_mask | pti_mask | swi_mask) );   
 #endif
 
@@ -264,9 +280,9 @@
     {
         // one ISR_SWITCH must be defined for each proc
-        if (isr_switch_channel == 0xFFFFFFFF) 
+        if (isr_switch_index == 0xFFFFFFFF) 
         {
             _tty_get_lock( 0 );
-            _puts("\n[GIET ERROR] ISR_SWITCH not found on proc ");
-            _putd(proc_id);
+            _puts("\n[GIET ERROR] ISR_SWITCH not found for processor ");
+            _putx(global_pid);
             _puts("\n");
             _tty_release_lock( 0 );
@@ -277,13 +293,13 @@
         unsigned int ko;
 #if USE_XICU
-        ko = _xcu_timer_start( cluster_id, isr_switch_channel, GIET_TICK_VALUE ); 
+        ko = _xcu_timer_start( cluster_xy, local_pid, GIET_TICK_VALUE ); 
 #else
-        ko = _timer_start( cluster_id, isr_switch_channel, GIET_TICK_VALUE ); 
+        ko = _timer_start( cluster_xy, local_pid, GIET_TICK_VALUE ); 
 #endif
         if ( ko )
         {
             _tty_get_lock( 0 );
-            _puts("\n[GIET ERROR] ISR_SWITCH start error for processor ");
-            _putd(proc_id);
+            _puts("\n[GIET ERROR] cannot start timer for processor ");
+            _putd(local_pid);
             _puts("\n");
             _tty_release_lock( 0 );
@@ -294,6 +310,11 @@
 #if GIET_DEBUG_INIT
 _tty_get_lock( 0 );
-_puts("\n[GIET DEBUG] Parallel init : step 4 for processor ");
-_putd(global_pid);
+_puts("\n[GIET DEBUG] Parallel init : step 4 for processor[");
+_putd( cluster_xy >> Y_WIDTH );
+_puts(",");
+_putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+_puts(",");
+_putd( local_pid );
+_puts("]");
 if ( tasks > 1 ) _puts("\n  context switch activated\n");
 else             _puts("\n  context switch  not activated\n");
@@ -315,7 +336,11 @@
 #if GIET_DEBUG_INIT
 _tty_get_lock( 0 );
-_puts("\n[GIET DEBUG] Parallel init : step 5 for processor ");
-_putd(global_pid);
-_puts("\n  idle task context set\n");
+_puts("\n[GIET DEBUG] Parallel init : step 5 for processor[");
+_putd( cluster_xy >> Y_WIDTH );
+_puts(",");
+_putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+_puts(",");
+_putd( local_pid );
+_puts("] : idle task context set\n");
 _tty_release_lock( 0 );
 #endif
@@ -333,5 +358,5 @@
         _tty_get_lock( 0 );
         _puts("\n[GIET WARNING] No task allocated to processor ");
-        _putd(global_pid);
+        _putx(global_pid);
         _puts(" => idle\n");
         _tty_release_lock ( 0 );
@@ -345,7 +370,11 @@
 #if GIET_DEBUG_INIT
 _tty_get_lock( 0 );
-_puts("\n[GIET DEBUG] Parallel init : step 6 for processor ");
-_putd(global_pid);
-_puts("\n - sp   = ");
+_puts("\n[GIET DEBUG] Parallel init : step 6 for processor[");
+_putd( cluster_xy >> Y_WIDTH );
+_puts(",");
+_putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+_puts(",");
+_putd( local_pid );
+_puts("]\n - sp   = ");
 _putx(sp_value);
 _puts("\n - sr   = ");
@@ -360,7 +389,11 @@
 
 _tty_get_lock( 0 );
-_puts("\n[GIET] Processor ");
-_putd( global_pid );
-_puts(" completes kernel init at cycle ");
+_puts("\n[GIET] Processor[");
+_putd( cluster_xy >> Y_WIDTH );
+_puts(",");
+_putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+_puts(",");
+_putd( local_pid );
+_puts("] completes kernel init at cycle ");
 _putd( _get_proctime() );
 _puts(" / task_entry_point = ");
Index: /soft/giet_vm/giet_kernel/switch.s
===================================================================
--- /soft/giet_vm/giet_kernel/switch.s	(revision 262)
+++ /soft/giet_vm/giet_kernel/switch.s	(revision 263)
@@ -2,4 +2,13 @@
 * This function receives two arguments that are the current task context 
 * (virtual) addresses and the next task context (virtual) address.
+*
+* TODO (AG) Il semble possible de limiter le nombre de registres Ã  sauver:
+* - s0 Ã  s8 ($16 Ã  $23 + $30)
+* - sp ($29)
+* - ra ($31)
+* - hi et lo
+* - sr
+* - epc
+* - ptpr
 ******************************************************************************/
 
Index: /soft/giet_vm/giet_kernel/sys_handler.c
===================================================================
--- /soft/giet_vm/giet_kernel/sys_handler.c	(revision 262)
+++ /soft/giet_vm/giet_kernel/sys_handler.c	(revision 263)
@@ -153,9 +153,11 @@
     mapping_cluster_t * cluster = _get_cluster_base(header);
 
-    if (cluster_id < header->clusters) {
+    if ( cluster_id < X_SIZE * Y_SIZE ) 
+    {
         *buffer = cluster[cluster_id].procs;
         return 0;
     }
-    else {
+    else 
+    {
         return 1;
     }
Index: /soft/giet_vm/giet_xml/mapping_info.h
===================================================================
--- /soft/giet_vm/giet_xml/mapping_info.h	(revision 262)
+++ /soft/giet_vm/giet_xml/mapping_info.h	(revision 263)
@@ -132,7 +132,8 @@
 {
     unsigned int signature;          // must contain MAPPING_SIGNATURE
-    unsigned int clusters;           // number of clusters
-    unsigned int cluster_x;          // number of cluster in a row
-    unsigned int cluster_y;          // number of cluster in a column
+    unsigned int x_size;             // actual number of clusters in a row
+    unsigned int y_size;             // actual number of clusters in a column
+    unsigned int x_width;            // number of bits to encode x coordinate 
+    unsigned int y_width;            // number of bits to encode y coordinate 
     unsigned int globals;            // number of vsegs mapped in all vspaces
     unsigned int vspaces;            // number of virtual spaces
@@ -183,4 +184,7 @@
 typedef struct __attribute__((packed))  mapping_cluster_s 
 {
+    unsigned int    x;               // x coordinate
+    unsigned int    y;               // y coordinate
+
     unsigned int    psegs;           // number of psegs in cluster
     unsigned int    pseg_offset;     // index of first pseg in pseg set
@@ -237,5 +241,5 @@
     paddr_t         length;          // size (bytes)
     unsigned int    type;            // RAM / PERI
-    unsigned int    cluster;         // index of cluster containing pseg
+    unsigned int    clusterid;       // linear index in array of clusters
     unsigned int    next_vseg;       // linked list of vsegs mapped on pseg
 } mapping_pseg_t;
@@ -246,5 +250,5 @@
 {
     char            name[32];        // task name (unique in vspace)
-    unsigned int    clusterid;       // physical cluster index
+    unsigned int    clusterid;       // linear index in array of clusters
     unsigned int    proclocid;       // processor local index (inside cluster)
     unsigned int    stack_vobjid;    // stack vobj index in vspace
Index: /soft/giet_vm/giet_xml/xml_driver.c
===================================================================
--- /soft/giet_vm/giet_xml/xml_driver.c	(revision 262)
+++ /soft/giet_vm/giet_xml/xml_driver.c	(revision 263)
@@ -133,10 +133,10 @@
     pseg = (mapping_pseg_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters);
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size);
 
     // computes the base adresss for vspaces array, 
     vspace = (mapping_vspace_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
             MAPPING_PSEG_SIZE * header->psegs);
 
@@ -144,5 +144,5 @@
     vseg = (mapping_vseg_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces);
@@ -151,5 +151,5 @@
     vobj = (mapping_vobj_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces +
@@ -159,5 +159,5 @@
     task = (mapping_task_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces +
@@ -168,5 +168,5 @@
     proc = (mapping_proc_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces +
@@ -178,5 +178,5 @@
     irq = (mapping_irq_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces +
@@ -189,5 +189,5 @@
     coproc = (mapping_coproc_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces +
@@ -201,5 +201,5 @@
     cp_port = (mapping_cp_port_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces +
@@ -214,5 +214,5 @@
     periph = (mapping_periph_t *) ((char *) header +
             MAPPING_HEADER_SIZE +
-            MAPPING_CLUSTER_SIZE * header->clusters +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
             MAPPING_PSEG_SIZE * header->psegs +
             MAPPING_VSPACE_SIZE * header->vspaces +
@@ -229,16 +229,23 @@
     fprintf(fpout, "<?xml version = \"1.0\"?>\n\n");
 
-    fprintf(fpout, "<mapping_info signature = \"0x%x\" ", header->signature);
-    fprintf(fpout, " name = \"%s\" ", header->name);
-    fprintf(fpout, " cluster_x = \"%d\" ", header->cluster_x);
-    fprintf(fpout, " cluster_y = \"%d\" ", header->cluster_y);
-    fprintf(fpout, " vspaces = \"%d\" >\n\n", header->vspaces);
+    fprintf(fpout, "<mapping_info signature = \"0x%x\" \n", header->signature);
+    fprintf(fpout, "              name      = \"%s\"   \n", header->name);
+    fprintf(fpout, "              x_size    = \"%d\"   \n", header->x_size);
+    fprintf(fpout, "              y_size    = \"%d\"   \n", header->y_size);
+    fprintf(fpout, "              x_width   = \"%d\"   \n", header->x_width);
+    fprintf(fpout, "              y_width   = \"%d\"   \n", header->y_width);
+    fprintf(fpout, "              vspaces   = \"%d\"   \n", header->vspaces);
+    fprintf(fpout, "              increment = \"%d\" >\n\n", header->vspaces);
 
     ///////////////////// clusters ///////////////////////////////////////////////
 
     fprintf( fpout, "    <clusterset>\n");
-    for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) 
-    {
-        fprintf(fpout, "        <cluster index  = \"%d\" >\n", cluster_id);
+    for (cluster_id = 0; cluster_id < (header->x_size * header->y_size); cluster_id++) 
+    {
+        fprintf(fpout, "        <cluster x = \"%d\" y = \"%d\" >\n", 
+                cluster[cluster_id].x, cluster[cluster_id].y );
+
+        ///////////////////// psegs   ////////////////////////////////////////////////
+
         for (pseg_id = cluster[cluster_id].pseg_offset;
              pseg_id < cluster[cluster_id].pseg_offset + cluster[cluster_id].psegs;
@@ -246,7 +253,7 @@
         {
             fprintf(fpout, "            <pseg name = \"%s\" ", pseg[pseg_id].name);
-            fprintf(fpout, " type = \"%s\" ", pseg_type[pseg[pseg_id].type]);
-            fprintf(fpout, " base = \"0x%llx\" ", pseg[pseg_id].base);
-            fprintf(fpout, " length = \"0x%llx\" />\n",   pseg[pseg_id].length);
+            fprintf(fpout, "type = \"%s\" ", pseg_type[pseg[pseg_id].type]);
+            fprintf(fpout, "base = \"0x%llx\" ", pseg[pseg_id].base);
+            fprintf(fpout, "length = \"0x%llx\" />\n",   pseg[pseg_id].length);
         }
 
@@ -316,5 +323,5 @@
         fprintf(fpout, "vbase = \"0x%x\" ", vseg[vseg_id].vbase);
         fprintf(fpout, "mode  = \"%s\" ", mode_str[vseg[vseg_id].mode]);
-        fprintf(fpout, "clusterid = \"%d\" ", pseg[pseg_id].cluster);
+        fprintf(fpout, "clusterid = \"%d\" ", pseg[pseg_id].clusterid);
         fprintf(fpout, "psegname = \"%s\" ", pseg[pseg_id].name);
         fprintf(fpout, "ident = \"%d\" >\n", vseg[vseg_id].ident);
@@ -343,14 +350,20 @@
         fprintf(fpout, " startname = \"%s\" >\n", vobj[func_id].name); 
 
+        //////////////////// vsegs //////////////////////////////////////////////
+
         for (vseg_id = vspace[vspace_id].vseg_offset;
              vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs);
              vseg_id++) 
         {
-            unsigned int pseg_id = vseg[vseg_id].psegid; 
+            unsigned int pseg_id    = vseg[vseg_id].psegid; 
+            unsigned int cluster_id = pseg[pseg_id].clusterid;
+            unsigned int x          = cluster_id >> header->y_width;
+            unsigned int y          = cluster_id & ((1<<header->y_width)-1);
 
             fprintf(fpout, "            <vseg name = \"%s\" ", vseg[vseg_id].name);
             fprintf(fpout, "vbase = \"0x%x\" ", vseg[vseg_id].vbase);
-            fprintf(fpout, "mode  = \"%s\" ", mode_str[vseg[vseg_id].mode]);
-            fprintf(fpout, "clusterid = \"%d\" ", pseg[pseg_id].cluster);
+            fprintf(fpout, "mode = \"%s\" ", mode_str[vseg[vseg_id].mode]);
+            fprintf(fpout, "x = \"%d\" ", x);
+            fprintf(fpout, "y = \"%d\" ", y);
             fprintf(fpout, "psegname = \"%s\" ", pseg[pseg_id].name);
             fprintf(fpout, "ident = \"%d\" >\n", vseg[vseg_id].ident);
@@ -369,4 +382,7 @@
             fprintf(fpout, "            </vseg>\n\n");
         }
+
+        //////////////////// tasks //////////////////////////////////////////////
+
         for (task_id = vspace[vspace_id].task_offset;
              task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
@@ -375,7 +391,11 @@
             unsigned int stack_vobj_id = task[task_id].stack_vobjid + vspace[vspace_id].vobj_offset; 
             unsigned int heap_vobj_id = task[task_id].heap_vobjid + vspace[vspace_id].vobj_offset; 
+            unsigned int cluster_id   = task[task_id].clusterid;
+            unsigned int x            = cluster_id >> header->y_width;
+            unsigned int y            = cluster_id & ((1<<header->y_width)-1);
 
             fprintf(fpout, "            <task name = \"%s\" ", task[task_id].name);
-            fprintf(fpout, "clusterid = \"%d\" ", task[task_id].clusterid);
+            fprintf(fpout, "x = \"%d\" ", x);
+            fprintf(fpout, "y = \"%d\" ", y);
             fprintf(fpout, "proclocid = \"%d\" ", task[task_id].proclocid);
             fprintf(fpout, "stackname = \"%s\" ", vobj[stack_vobj_id].name);
Index: /soft/giet_vm/giet_xml/xml_parser.c
===================================================================
--- /soft/giet_vm/giet_xml/xml_parser.c	(revision 262)
+++ /soft/giet_vm/giet_xml/xml_parser.c	(revision 263)
@@ -109,8 +109,6 @@
 ////////////////////////////////////////////////////////////////////
 
-unsigned int cluster_y        = 0; // number of clusters in a column
-unsigned int cluster_x        = 0; // number of clusters in a row
 unsigned int nb_proc_max      = 0; // max number of processors per cluster
-unsigned int nb_tasks_max     = 0; // max number of tasks (for all vspaces)
+unsigned int nb_tasks_max     = 0; // max number of tasks (in all vspaces)
 
 unsigned int tim_channels     = 0; // max number of user timers (per cluster)
@@ -132,5 +130,5 @@
 
 unsigned int periph_vbase_array[PERIPH_TYPE_MAX_VALUE] 
-         = { [0 ... (PERIPH_TYPE_MAX_VALUE - 1)] = 0xFFF00000 };
+         = { [0 ... (PERIPH_TYPE_MAX_VALUE - 1)] = 0xFFFFFFFF };
 
 //////////////////////////////////////////////////////////////////////
@@ -283,6 +281,6 @@
 // This function set the vbase address for all peripheral types. 
 // For replicated peripherals with the same type the virtual base address must be:
-//   vbase = seg_type_base & 0XFFF00000 + 
-//          (cluster_id * vbase_cluster_increment) & 0x000FFFFF
+//   vbase = seg_type_base & 0XFF000000 + 
+//          (cluster_id * vbase_cluster_increment) & 0x00FF0000
 ///////////////////////////////////////////////////////////////////////////////////
 void set_periph_vbase_array()
@@ -291,12 +289,12 @@
     unsigned int periph_id;    // periph global index
     unsigned int pseg_id;      // pseg global index
-    unsigned int cluster_id;   // cluster global index
+    unsigned int cluster_id;   // cluster linear index
+    unsigned int cluster_xy;   // cluster topological index
     unsigned int type;         // peripheral type 
 
-    unsigned int msb_mask = 0xFFF00000;
-    unsigned int lsb_mask = 0x000FFFFF;
-
-    // We are looking for any vseg matching a peripheral
-    // (i.e. they are associated to the same pseg)
+    unsigned int type_mask    = 0xFF000000;
+    unsigned int cluster_mask = 0x00FF0000;
+
+    // We are analysing all vsegs corresponding to a peripheral
 
     // scan all vsegs
@@ -306,8 +304,7 @@
         if ( vobj[vseg[vseg_id]->vobj_offset]->type == VOBJ_TYPE_PERI )
         {
-            pseg_id = vseg[vseg_id]->psegid; 
-            cluster_id = pseg[pseg_id]->cluster;
-
-            // scan all periphs 
+            pseg_id    = vseg[vseg_id]->psegid; 
+
+            // scan all periphs to retrieve peripheral type (same psegid)
             for ( periph_id = 0 ; periph_id < header->periphs ; periph_id++)
             {
@@ -315,26 +312,16 @@
                 {
                     type = periph[periph_id]->type;
-                    if ( periph_vbase_array[type] == 0xFFF00000 )  // vbase not set
+                    if ( periph_vbase_array[type] == 0xFFFFFFFF )  // vbase not set
                     {
-                        periph_vbase_array[type] = vseg[vseg_id]->vbase;    
+                        periph_vbase_array[type] = vseg[vseg_id]->vbase & type_mask;    
                     }
                     else                                 // vbase already set
                     {
-                        // checking 12 MSB bits for replicated peripherals
-                        if( (vseg[vseg_id]->vbase & msb_mask) != 
-                            (periph_vbase_array[type] & msb_mask) )
+                        // checking mask bits 
+                        if( (vseg[vseg_id]->vbase & type_mask) != 
+                            (periph_vbase_array[type]) )
                         {
                             printf("[XML ERROR] All peripherals with same type ");
-                            printf(" should share the same 12 MSB for vbase address\n");
-                            printf("periph index = %d / periph type = %d / vbase = %x\n",
-                                    periph_id, type, vseg[vseg_id]->vbase);
-                            exit(1);
-                        }
-                        // checking 20 LSB bits for replicated peripherals
-                        if( (vseg[vseg_id]->vbase & lsb_mask) != 
-                            (header->increment * cluster_id) )
-                        {
-                            printf("[XML ERROR] All peripherals with same type ");
-                            printf(" must have the 20 LSB bits = cluster_id * increment");
+                            printf(" should share the same 8 MSB bits in base address\n");
                             printf("periph index = %d / periph type = %d / vbase = %x\n",
                                     periph_id, type, vseg[vseg_id]->vbase);
@@ -342,4 +329,26 @@
                         }
                     }
+   
+                    // checking cluster bits for all replicated peripherals
+                    if ( (type == PERIPH_TYPE_DMA) ||
+                         (type == PERIPH_TYPE_MMC) ||
+                         (type == PERIPH_TYPE_ICU) ||
+                         (type == PERIPH_TYPE_XCU) ||
+                         (type == PERIPH_TYPE_TIM) ) 
+                    {
+                        cluster_id = pseg[pseg_id]->clusterid;
+                        cluster_xy = (cluster[cluster_id]->x << header->y_width) +
+                                      cluster[cluster_id]->y;
+
+                        if( (vseg[vseg_id]->vbase & cluster_mask) != 
+                            (header->increment * cluster_xy) )
+                        {
+                            printf("[XML ERROR] All replicated peripherals ");
+                            printf("must have cluster bits = cluster_id * increment");
+                            printf("periph index = %d / periph type = %d / vbase = %x\n",
+                                    periph_id, type, vseg[vseg_id]->vbase);
+                            exit(1);
+                        }
+                    } 
                 }
             }
@@ -348,7 +357,28 @@
 }  // end set_periph_vbase_array()
 
-////////////////////////////////////////////////////////
-int getPsegId(unsigned int cluster_id, char * pseg_name) 
-{
+///////////////////////////////////////////////////////////////
+int getClusterId( unsigned int x, unsigned int y )
+{
+    // associative search of cluster index
+    unsigned int cluster_id;
+
+    for( cluster_id = 0 ; cluster_id < (header->x_size * header->y_size) ; cluster_id++ )
+    {
+        if( (cluster[cluster_id]->x == x) && (cluster[cluster_id]->y == y) )
+        {
+            return cluster_id;
+        }
+    }
+    return -1;
+}  // end getClusterId()
+
+///////////////////////////////////////////////////////////////
+int getPsegId(unsigned int x, unsigned int y, char * pseg_name) 
+{
+    int cluster_id = getClusterId( x, y );
+
+    if ( cluster_id == -1 ) return -1;
+
+    // associative search for pseg index
     unsigned int pseg_id;
     unsigned int pseg_min = cluster[cluster_id]->pseg_offset;
@@ -363,5 +393,5 @@
     }
     return -1;
-}
+}  // end getPsegId()
 
 ///////////////////////////////////
@@ -399,4 +429,5 @@
     unsigned int ok;
     unsigned int value;
+    unsigned int x,y;
     char * str;
 
@@ -420,5 +451,5 @@
     {
 #if XML_PARSER_DEBUG
-printf("      name = %s\n", str);
+printf("      name      = %s\n", str);
 #endif
         strncpy( task[task_index]->name, str, 31 );
@@ -431,22 +462,40 @@
     }
 
-    ///////// get clusterid attribute
-    value = getIntValue(reader, "clusterid", &ok);
-    if (ok) 
-    {
-#if XML_PARSER_DEBUG
-printf("      clusterid = %x\n", value);
-#endif
-        if (value >= header->clusters) 
-        {
-            printf("[XML ERROR] <clusterid> too large for task (%d,%d)\n",
-                    vspace_index, task_loc_index);
-            exit(1);
-        }
-        task[task_index]->clusterid = value;
+    ///////// get x coordinate 
+     x = getIntValue(reader, "x", &ok);
+#if XML_PARSER_DEBUG
+printf("      x         = %d\n", x);
+#endif
+    if ( !(ok && (x < header->x_size)) ) 
+    {
+        printf("[XML ERROR] illegal or missing < x > attribute for task (%d,%d)\n",
+                vspace_index, task_loc_index);
+        exit(1);
     }  
-    else 
-    {
-        printf("[XML ERROR] illegal or missing <clusterid> attribute for task (%d,%d)\n",
+
+    ///////// get y coordinate 
+     y = getIntValue(reader, "y", &ok);
+#if XML_PARSER_DEBUG
+printf("      y         = %d\n", y);
+#endif
+    if ( !(ok && (y < header->y_size)) ) 
+    {
+        printf("[XML ERROR] illegal or missing < y > attribute for task (%d,%d)\n",
+                vspace_index, task_loc_index);
+        exit(1);
+    }  
+
+    ///////// set clusterid attribute
+    int index = getClusterId( x, y );
+#if XML_PARSER_DEBUG
+printf("      clusterid = %d\n", index);
+#endif
+    if( index >= 0 )
+    {
+        task[task_index]->clusterid = index;
+    }
+    else
+    {
+        printf("[XML ERROR] <clusterid> not found for task (%d,%d)\n",
                 vspace_index, task_loc_index);
         exit(1);
@@ -510,6 +559,6 @@
         {
 #if XML_PARSER_DEBUG
-printf("      heapname = %s\n", str);
-printf("      heapid   = %d\n", index);
+printf("      heapname  = %s\n", str);
+printf("      heapid    = %d\n", index);
 #endif
             task[task_index]->heap_vobjid = index;
@@ -527,5 +576,4 @@
     }
 
-
     ////////// get startid  attribute
     value = getIntValue(reader, "startid", &ok);
@@ -533,5 +581,5 @@
     {
 #if XML_PARSER_DEBUG
-printf("      startid = %x\n", value);
+printf("      startid   = %x\n", value);
 #endif
         task[task_index]->startid = value;
@@ -724,4 +772,5 @@
     unsigned int ok;
     unsigned int value;
+    unsigned int x,y;
     char * str;
 
@@ -760,5 +809,5 @@
     {
 #if XML_PARSER_DEBUG
-printf("      name = %s\n", str);
+printf("      name        = %s\n", str);
 #endif
         strncpy( vseg[vseg_index]->name, str, 31);
@@ -776,5 +825,5 @@
     {
 #if XML_PARSER_DEBUG
-printf("      ident = %d\n", value);
+printf("      ident       = %d\n", value);
 #endif
         vseg[vseg_index]->ident = value;
@@ -790,5 +839,5 @@
     {
 #if XML_PARSER_DEBUG
-printf("      vbase = 0x%x\n", value);
+printf("      vbase       = 0x%x\n", value);
 #endif
         vseg[vseg_index]->vbase = value;
@@ -801,13 +850,33 @@
     }
 
-    ////////// get clusterid and psegname attributes
-    value = getIntValue(reader, "clusterid", &ok);
-    if (ok == 0) 
-    {
-        printf("[XML ERROR] illegal or missing <clusterid> for vseg %d\n", 
+    ////////// get x coordinate
+    x = getIntValue(reader, "x", &ok);
+#if XML_PARSER_DEBUG
+printf("      x           = %d\n", x);
+#endif
+    if ( !(ok && (x < header->x_size)) ) 
+    {
+        printf("[XML ERROR] illegal or missing < x > attribute for vseg %d\n", 
                 vseg_loc_index);
         exit(1);
     }
+
+    ////////// get y coordinate
+    y = getIntValue(reader, "y", &ok);
+#if XML_PARSER_DEBUG
+printf("      y           = %d\n", y);
+#endif
+    if ( !(ok && (y < header->y_size)) ) 
+    {
+        printf("[XML ERROR] illegal or missing < y > attribute for vseg %d\n", 
+                vseg_loc_index);
+        exit(1);
+    }
+
+    ///////// get psegname attribute
     str = getStringValue(reader, "psegname", &ok);
+#if XML_PARSER_DEBUG
+printf("      psegname    = %s\n", str);
+#endif
     if (ok == 0) 
     {
@@ -818,18 +887,16 @@
 
     /////////// set psegid field
-    int index = getPsegId(value, str);
+    int psegid = getPsegId( x, y, str );
+#if XML_PARSER_DEBUG
+printf("      psegid      = %d\n", psegid);
+#endif
     if (index >= 0) 
     {
-#if XML_PARSER_DEBUG
-printf("      clusterid = %d\n", value);
-printf("      psegname  = %s\n", str);
-printf("      psegid    = %d\n", index);
-#endif
-        vseg[vseg_index]->psegid = index;
-    }
-    else 
-    {
-        printf("[XML ERROR] pseg not found for vseg %d / clusterid = %d / psegname = %s\n", 
-                vseg_loc_index, value, str );
+        vseg[vseg_index]->psegid = psegid;
+    }
+    else 
+    {
+        printf("[XML ERROR] pseg not found for vseg %d / x = %d / y = %d / psegname = %s\n", 
+                vseg_loc_index, x, y, str );
         exit(1);
     }  
@@ -838,5 +905,5 @@
     str = getStringValue(reader, "mode", &ok);
 #if XML_PARSER_DEBUG
-printf("      mode = %s\n", str);
+printf("      mode        = %s\n", str);
 #endif
     if      (ok && (strcmp(str, "CXWU") == 0)) { vseg[vseg_index]->mode = 0xF; }
@@ -955,8 +1022,10 @@
         const char * tag = (const char *) xmlTextReaderConstName(reader);
 
-        if (strcmp(tag, "vseg") == 0) {
+        if (strcmp(tag, "vseg") == 0) 
+        {
             vsegNode(reader);
         }
-        else if (strcmp(tag, "task") == 0) {
+        else if (strcmp(tag, "task") == 0) 
+        {
             taskNode(reader);
             nb_task_vspace++;
@@ -1144,5 +1213,5 @@
 
     /////////// set psegid attribute
-    int index = getPsegId(cluster_index, str);
+    int index = getPsegId( cluster[cluster_index]->x, cluster[cluster_index]->y, str);
     if (index >= 0) 
     {
@@ -1465,5 +1534,5 @@
 
     /////////// set psegid attribute
-    int index = getPsegId(cluster_index, str);
+    int index = getPsegId( cluster[cluster_index]->x, cluster[cluster_index]->y, str);
     if (index >= 0) 
     {
@@ -1786,5 +1855,5 @@
 
     //////// set cluster attribute
-    pseg[pseg_index]->cluster = cluster_index;
+    pseg[pseg_index]->clusterid = cluster_index;
 
     //////// set next_vseg attribute
@@ -1804,7 +1873,5 @@
     cluster[cluster_index] = (mapping_cluster_t *) malloc(sizeof(mapping_cluster_t));
 
-    //initialise all variables
-    //they will be incremented by *Node() functions
-    //FIXME: calloc?
+    //initialise variables that will be incremented by *Node() functions
     cluster[cluster_index]->psegs = 0;
     cluster[cluster_index]->procs = 0;
@@ -1812,7 +1879,5 @@
     cluster[cluster_index]->periphs = 0;
 
-
     //initialise global variables
-    //TODO: delete those three
     proc_loc_index = 0;
     coproc_loc_index = 0;
@@ -1830,21 +1895,36 @@
     }
 
-    // checking source file consistency
-    if (cluster_index >= header->clusters) 
-    {
-        printf("[XML ERROR] The cluster index is too large : %d\n", cluster_index);
-        exit(1);
-    }
-
-#if XML_PARSER_DEBUG
-    printf("  cluster %d\n", cluster_index);
-#endif
-
-
-    /////////// check cluster index attribute (optional)
-    value = getIntValue(reader, "index", &ok);
-    if (ok && (value != cluster_index)) 
-    {
-        printf("[XML ERROR] wrong cluster index / expected value is %d", 
+#if XML_PARSER_DEBUG
+printf("\n  cluster %d\n", cluster_index);
+#endif
+
+    /////////// get x coordinate
+    value = getIntValue(reader, "x", &ok);
+#if XML_PARSER_DEBUG
+printf("    x             = %d\n", value);
+#endif
+    if (ok && (value < header->x_size) ) 
+    {
+        cluster[cluster_index]->x = value;
+    }
+    else
+    {
+        printf("[XML ERROR] Illegal or missing < x > attribute for cluster %d", 
+                cluster_index);
+        exit(1);
+    }
+
+    /////////// get y coordinate
+    value = getIntValue(reader, "y", &ok);
+#if XML_PARSER_DEBUG
+printf("    y             = %d\n", value);
+#endif
+    if (ok && (value < header->y_size) ) 
+    {
+        cluster[cluster_index]->y = value;
+    }
+    else
+    {
+        printf("[XML ERROR] Illegal or missing < y > attribute for cluster %d", 
                 cluster_index);
         exit(1);
@@ -1858,8 +1938,8 @@
 
 #if XML_PARSER_DEBUG
-    printf("    pseg_offset   = %d\n", pseg_index);
-    printf("    proc_offset   = %d\n", proc_index);
-    printf("    coproc_offset = %d\n", coproc_index);
-    printf("    periph_offset = %d\n", coproc_index);
+printf("    pseg_offset   = %d\n", pseg_index);
+printf("    proc_offset   = %d\n", proc_index);
+printf("    coproc_offset = %d\n", coproc_index);
+printf("    periph_offset = %d\n", coproc_index);
 #endif
 
@@ -1899,9 +1979,9 @@
 
 #if XML_PARSER_DEBUG
-            printf("    psegs   = %d\n", cluster[cluster_index]->psegs);
-            printf("    procs   = %d\n", cluster[cluster_index]->procs);
-            printf("    coprocs = %d\n", cluster[cluster_index]->coprocs);
-            printf("    periphs = %d\n", cluster[cluster_index]->periphs);
-            printf("    end cluster %d\n", cluster_index);
+printf("    psegs   = %d\n", cluster[cluster_index]->psegs);
+printf("    procs   = %d\n", cluster[cluster_index]->procs);
+printf("    coprocs = %d\n", cluster[cluster_index]->coprocs);
+printf("    periphs = %d\n", cluster[cluster_index]->periphs);
+printf("    end cluster %d\n", cluster_index);
 #endif
             cluster_index++;
@@ -1919,5 +1999,5 @@
 
 #if XML_PARSER_DEBUG
-    printf("\n  clusters set\n");
+printf("\n  clusters set\n");
 #endif
 
@@ -1933,5 +2013,5 @@
         {
             // checking source file consistency
-            if (cluster_index != header->clusters) 
+            if ( cluster_index != (header->x_size * header->y_size) ) 
             {
                 printf("[XML ERROR] Wrong number of clusters\n");
@@ -2079,47 +2159,60 @@
     }
 
-    /////////// get cluster_x attribute
-    cluster_x = getIntValue(reader, "cluster_x", &ok);
-    if (ok) 
-    {
-#if XML_PARSER_DEBUG
-        printf("  cluster_x = %d\n", cluster_x);
-#endif
-        header->cluster_x = cluster_x;
-    }
-    else 
-    {
-        printf("[XML ERROR] illegal or missing <cluster_x> attribute in header\n");
-        exit(1);
-    }
-
-    /////////// get cluster_y attribute
-    cluster_y = getIntValue(reader, "cluster_y", &ok);
-    if (ok) 
-    {
-#if XML_PARSER_DEBUG
-        printf("  cluster_y = %d\n", cluster_y);
-#endif
-        header->cluster_y = cluster_y;
-    }
-    else 
-    {
-        printf("[XML ERROR] illegal or missing <cluster_y> attribute in header\n");
+    /////////// get x_width attribute
+    value = getIntValue(reader, "x_width", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("  x_width = %d\n", value);
+#endif
+        header->x_width = value;
+    }
+
+    /////////// get y_width attribute
+    value = getIntValue(reader, "y_width", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("  y_width = %d\n", value);
+#endif
+        header->y_width = value;
+    }
+
+    /////////// get x_size attribute
+    unsigned int x_size = getIntValue(reader, "x_size", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("  x_size  = %d\n", x_size);
+#endif
+        header->x_size = x_size;
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <x_size> attribute in header\n");
+        exit(1);
+    }
+
+    /////////// get y_size attribute
+    unsigned int y_size = getIntValue(reader, "y_size", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("  y_size  = %d\n", y_size);
+#endif
+        header->y_size = y_size;
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <y_size> attribute in header\n");
         exit(1);
     }
 
     //check the number of cluster
-    value = cluster_x * cluster_y;
-    if (value >= MAX_CLUSTERS) 
-    {
-        printf("[XML ERROR] The number of clusters is larger than %d\n", MAX_CLUSTERS);
-        exit(1);
-    }
-
-    header->clusters  = value;
-
-#if XML_PARSER_DEBUG
-    printf("  clusters = %d\n", value);
-#endif
+    if ( (x_size * y_size) >= MAX_CLUSTERS )
+    {
+        printf("[XML ERROR] Number of clusters cannot be larger than %d\n", MAX_CLUSTERS);
+        exit(1);
+    }
 
     ///////// get vspaces attribute
@@ -2281,5 +2374,8 @@
 printf("Building map.bin for %s\n", header->name);
 printf("signature = %x\n", header->signature);
-printf("clusters  = %d\n", header->clusters);
+printf("x_size    = %d\n", header->x_size);
+printf("y_size    = %d\n", header->y_size);
+printf("x_width   = %d\n", header->x_width);
+printf("y_width   = %d\n", header->y_width);
 printf("vspaces   = %d\n", header->vspaces);
 printf("psegs     = %d\n", header->psegs);
@@ -2406,7 +2502,11 @@
     file_write(fdout, ifdef);
 
-    def_int_write(fdout, "CLUSTER_X         ", cluster_x);
-    def_int_write(fdout, "CLUSTER_Y         ", cluster_y);
-    def_int_write(fdout, "NB_CLUSTERS       ", cluster_index);
+    def_int_write(fdout, "X_SIZE            ", header->x_size);
+    def_int_write(fdout, "Y_SIZE            ", header->y_size);
+    def_int_write(fdout, "X_WIDTH           ", header->x_width);
+    def_int_write(fdout, "Y_WIDTH           ", header->y_width);
+
+    file_write(fdout, "\n");
+
     def_int_write(fdout, "NB_PROCS_MAX      ", nb_proc_max);
     def_int_write(fdout, "NB_TASKS_MAX      ", nb_tasks_max);
Index: /soft/giet_vm/mappings/4c_1p_iob_four.xml
===================================================================
--- /soft/giet_vm/mappings/4c_1p_iob_four.xml	(revision 262)
+++ /soft/giet_vm/mappings/4c_1p_iob_four.xml	(revision 263)
@@ -3,6 +3,8 @@
 <mapping_info signature    = "0xdeadbeef" 
               name         = "4c_1p_iob_four" 
-              cluster_x    = "2" 
-              cluster_y    = "2" 
+              x_size       = "2" 
+              y_size       = "2" 
+              x_width      = "4"
+              y_width      = "4"
               vspaces      = "4"
               increment    = "0x10000" >
@@ -16,5 +18,5 @@
     <clusterset>
 
-        <cluster index = "0" >
+        <cluster x = "0" y = "0" >
             <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0000000000" length = "0x0010000000" />
             <pseg name = "PSEG_XCU"  type = "PERI" base = "0x00B0000000" length = "0x0000002000" />
@@ -79,9 +81,9 @@
         </cluster>
 
-        <cluster index = "1" >
-            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x4000000000" length = "0x0010000000" />
-            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x40B0000000" length = "0x0000002000" />
-            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x40B1000000" length = "0x0000008000" />
-            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x40B2000000" length = "0x0000001000" />
+        <cluster x = "0" y = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0100000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x01B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x10B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x01B2000000" length = "0x0000001000" />
 
             <proc index = "0" >
@@ -95,9 +97,9 @@
         </cluster>
 
-        <cluster index = "2" >
-            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x8000000000" length = "0x0010000000" />
-            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x80B0000000" length = "0x0000002000" />
-            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x80B1000000" length = "0x0000008000" />
-            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x80B2000000" length = "0x0000001000" />
+        <cluster x = "1" y = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1000000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x10B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x10B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x10B2000000" length = "0x0000001000" />
 
             <proc index = "0" >
@@ -111,9 +113,9 @@
         </cluster>
 
-        <cluster index = "3" >
-            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0xC000000000" length = "0x0010000000" />
-            <pseg name = "PSEG_XCU"  type = "PERI" base = "0xC0B0000000" length = "0x0000002000" />
-            <pseg name = "PSEG_DMA"  type = "PERI" base = "0xC0B1000000" length = "0x0000008000" />
-            <pseg name = "PSEG_MMC"  type = "PERI" base = "0xC0B2000000" length = "0x0000001000" />
+        <cluster x = "1" y = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1100000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x11B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x11B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x11B2000000" length = "0x0000001000" />
 
             <proc index = "0" >
@@ -136,17 +138,17 @@
 - seg_boot_buffer is used by the boot-loader. It can contain a complete .elf file. The content is not reused by the kernel.
 
-        <vseg name = "seg_boot_mapping"   vbase = "0x00000000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+        <vseg name = "seg_boot_mapping"   vbase = "0x00000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
             <vobj name = "boot_mapping"   type = "BLOB"   length = "0x00010000" binpath	= "map.bin" />
         </vseg>
-        <vseg name = "seg_boot_code"      vbase = "0x00010000" mode = "CXW_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+        <vseg name = "seg_boot_code"      vbase = "0x00010000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
             <vobj name = "boot_code"      type = "BUFFER" length = "0x00020000" />
         </vseg>
-        <vseg name = "seg_boot_data"      vbase = "0x00030000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+        <vseg name = "seg_boot_data"      vbase = "0x00030000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
             <vobj name = "boot_data"      type = "BUFFER" length = "0x00010000" />
         </vseg>
-        <vseg name = "seg_boot_buffer"    vbase = "0x00040000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+        <vseg name = "seg_boot_buffer"    vbase = "0x00040000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
             <vobj name = "boot_buffer"    type = "BUFFER" length = "0x00020000" />
         </vseg>
-        <vseg name = "seg_boot_stack"     vbase = "0x00060000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+        <vseg name = "seg_boot_stack"     vbase = "0x00060000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
             <vobj name = "boot_stack"     type = "BUFFER" length = "0x00090000" />
         </vseg>
@@ -154,101 +156,110 @@
 *** Segments used by the kernel / A[31:28] = 0x8 
   
-        <vseg name = "seg_kernel_code"    vbase = "0x80000000" mode = "CXW_" clusterid = "0" psegname = "PSEG_RAM" > 
+        <vseg name = "seg_kernel_code"    vbase = "0x80000000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > 
             <vobj name = "kernel_code"    type = "ELF" length = "0x00020000" binpath = "build/kernel/kernel.elf" />
         </vseg>
-        <vseg name = "seg_kernel_data"    vbase = "0x80020000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" > 
+        <vseg name = "seg_kernel_data"    vbase = "0x80020000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
             <vobj name = "kernel_data"    type = "ELF" length = "0x00060000" binpath = "build/kernel/kernel.elf" />
 		</vseg>
-        <vseg name = "seg_kernel_uncdata" vbase = "0x80080000" mode = "__W_" clusterid = "0" psegname = "PSEG_RAM" > 
+        <vseg name = "seg_kernel_uncdata" vbase = "0x80080000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
             <vobj name = "kernel_uncdata" type = "ELF" length = "0x00040000" binpath = "build/kernel/kernel.elf" />
         </vseg>
-        <vseg name = "seg_kernel_init"    vbase = "0x800C0000" mode = "CXW_" clusterid = "0" psegname = "PSEG_RAM" > 
+        <vseg name = "seg_kernel_init"    vbase = "0x800C0000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > 
             <vobj name = "kernel_init"    type = "ELF" length = "0x00010000" binpath = "build/kernel/kernel.elf" />
         </vseg>
 
 *** Segments for non replicated peripherals / A[31:28] = 0xB / Identity mapping
-
-        <vseg name = "seg_iob"            vbase = "0xBE000000" mode = "__W_" clusterid = "0" psegname = "PSEG_IOB" ident = "1" >
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+
+        <vseg name = "seg_iob"            vbase = "0xBE000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_IOB" ident = "1" >
             <vobj name = "iob"            type = "PERI" length  = "0x00001000" /> 
         </vseg>
-        <vseg name = "seg_ioc"            vbase = "0xB3000000" mode = "__W_" clusterid = "0" psegname = "PSEG_IOC" ident = "1" >
+        <vseg name = "seg_ioc"            vbase = "0xB3000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_IOC" ident = "1" >
             <vobj name = "ioc"            type = "PERI" length  = "0x00001000" /> 
         </vseg>
-        <vseg name = "seg_tty"            vbase = "0xB4000000" mode = "__W_" clusterid = "0" psegname = "PSEG_TTY" ident = "1" >
+        <vseg name = "seg_tty"            vbase = "0xB4000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_TTY" ident = "1" >
    			<vobj name = "tty"            type = "PERI" length  = "0x00001000" />
         </vseg>
-        <vseg name = "seg_nic"            vbase = "0xB5000000" mode = "__W_" clusterid = "0" psegname = "PSEG_NIC" ident = "1" >
+        <vseg name = "seg_nic"            vbase = "0xB5000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_NIC" ident = "1" >
             <vobj name = "nic"            type = "PERI" length  = "0x00080000" /> 
         </vseg>
-        <vseg name = "seg_cma"            vbase = "0xB6000000" mode = "__W_" clusterid = "0" psegname = "PSEG_CMA" ident = "1" >
+        <vseg name = "seg_cma"            vbase = "0xB6000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_CMA" ident = "1" >
             <vobj name = "cma"            type = "PERI" length  = "0x00008000" /> 
         </vseg>
-        <vseg name = "seg_fbf"            vbase = "0xB7000000" mode = "__W_" clusterid = "0" psegname = "PSEG_FBF" ident = "1" >
+        <vseg name = "seg_fbf"            vbase = "0xB7000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_FBF" ident = "1" >
             <vobj name = "fbf"            type = "PERI" length  = "0x00004000" /> 
         </vseg>
-        <vseg name = "seg_rom"            vbase = "0xBFC00000" mode = "CXW_" clusterid = "0" psegname = "PSEG_ROM" ident = "1" >
+        <vseg name = "seg_rom"            vbase = "0xBFC00000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_ROM" ident = "1" >
             <vobj name = "rom"            type = "PERI" length  = "0x00004000" /> 
         </vseg>
 
 *** Segments for replicated ICUS / A[31:24] = 0xB0 / Increment = 0x10000 / Identity mapping in cluster 0            
-
-        <vseg name = "seg_icu_0"          vbase = "0xB0000000" mode = "__W_" clusterid = "0" psegname = "PSEG_XCU" ident = "1" > 
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_icu_0"          vbase = "0xB0000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_XCU" ident = "1" > 
             <vobj name = "icu_0"          type = "PERI" length  = "0x00001000" /> 
         </vseg>
-        <vseg name = "seg_icu_1"          vbase = "0xB0010000" mode = "__W_" clusterid = "1" psegname = "PSEG_XCU" > 
+        <vseg name = "seg_icu_1"          vbase = "0xB0010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_XCU" > 
             <vobj name = "icu_1"          type = "PERI" length  = "0x00001000" /> 
         </vseg>
-        <vseg name = "seg_icu_2"          vbase = "0xB0020000" mode = "__W_" clusterid = "2" psegname = "PSEG_XCU" > 
+        <vseg name = "seg_icu_2"          vbase = "0xB0100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_XCU" > 
             <vobj name = "icu_2"          type = "PERI" length  = "0x00001000" /> 
         </vseg>
-        <vseg name = "seg_icu_3"          vbase = "0xB0030000" mode = "__W_" clusterid = "3" psegname = "PSEG_XCU" > 
+        <vseg name = "seg_icu_3"          vbase = "0xB0110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_XCU" > 
             <vobj name = "icu_3"          type = "PERI" length  = "0x00001000" /> 
         </vseg>
 
 *** segments for replicated DMAs / A[31:24] = 0xB1 / Increment = 0x10000 / Tdentity mapping in cluster 0
-
-        <vseg name = "seg_dma_0"          vbase = "0xB1000000" mode = "__W_" clusterid = "0" psegname = "PSEG_DMA" ident = "1" >
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_dma_0"          vbase = "0xB1000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_DMA" ident = "1" >
             <vobj name = "dma_0"          type = "PERI" length  = "0x00008000" />
         </vseg>
-        <vseg name = "seg_dma_1"          vbase = "0xB1010000" mode = "__W_" clusterid = "1" psegname = "PSEG_DMA" >
+        <vseg name = "seg_dma_1"          vbase = "0xB1010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_DMA" >
             <vobj name = "dma_1"          type = "PERI" length  = "0x00008000" />
         </vseg>
-        <vseg name = "seg_dma_2"          vbase = "0xB1020000" mode = "__W_" clusterid = "2" psegname = "PSEG_DMA" >
+        <vseg name = "seg_dma_2"          vbase = "0xB1100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_DMA" >
             <vobj name = "dma_2"          type = "PERI" length  = "0x00008000" />
         </vseg>
-        <vseg name = "seg_dma_3"          vbase = "0xB1030000" mode = "__W_" clusterid = "3" psegname = "PSEG_DMA" >
+        <vseg name = "seg_dma_3"          vbase = "0xB1110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_DMA" >
             <vobj name = "dma_3"          type = "PERI" length  = "0x00008000" />
         </vseg>
 
 *** segments for replicated MMC / A[31:24] = 0xB2 / Increment = 0x10000 / Identity mapping in cluster 0
-
-        <vseg name = "seg_memc_0"         vbase = "0xB2000000" mode = "__W_" clusterid = "0" psegname = "PSEG_MMC" ident = "1" >
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_memc_0"         vbase = "0xB2000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_MMC" ident = "1" >
             <vobj name = "memc_0"         type = "PERI" length  = "0x00001000" />
         </vseg>
-        <vseg name = "seg_memc_1"         vbase = "0xB2010000" mode = "__W_" clusterid = "1" psegname = "PSEG_MMC" >
+        <vseg name = "seg_memc_1"         vbase = "0xB2010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_MMC" >
             <vobj name = "memc_1"         type = "PERI" length  = "0x00001000" />
         </vseg>
-        <vseg name = "seg_memc_2"         vbase = "0xB2020000" mode = "__W_" clusterid = "2" psegname = "PSEG_MMC" >
+        <vseg name = "seg_memc_2"         vbase = "0xB2100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_MMC" >
             <vobj name = "memc_2"         type = "PERI" length  = "0x00001000" />
         </vseg>
-        <vseg name = "seg_memc_3"         vbase = "0xB2030000" mode = "__W_" clusterid = "3" psegname = "PSEG_MMC" >
+        <vseg name = "seg_memc_3"         vbase = "0xB2110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_MMC" >
             <vobj name = "memc_3"         type = "PERI" length  = "0x00001000" />
         </vseg>
 
 *** segments for replicated schedulers / A[31:28] = 0xF / Increment = 0x10000
-
-        <vseg name = "seg_sched_0"        vbase = "0xF0000000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" >
+*** The type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_sched_0"        vbase = "0xF0000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" >
             <vobj name = "sched_0"        type = "SCHED" length  = "0x00008000" />
         </vseg>
-        <vseg name = "seg_sched_1"        vbase = "0xF0010000" mode = "C_W_" clusterid = "1" psegname = "PSEG_RAM" >
+        <vseg name = "seg_sched_1"        vbase = "0xF0010000" mode = "C_W_" x = "0" y = "1" psegname = "PSEG_RAM" >
             <vobj name = "sched_1"        type = "SCHED" length  = "0x00008000" />
         </vseg>
-        <vseg name = "seg_sched_2"        vbase = "0xF0020000" mode = "C_W_" clusterid = "2" psegname = "PSEG_RAM" >
+        <vseg name = "seg_sched_2"        vbase = "0xF0100000" mode = "C_W_" x = "1" y = "0" psegname = "PSEG_RAM" >
             <vobj name = "sched_2"        type = "SCHED" length  = "0x00008000" />
         </vseg>
-        <vseg name = "seg_sched_3"        vbase = "0xF0030000" mode = "C_W_" clusterid = "3" psegname = "PSEG_RAM" >
+        <vseg name = "seg_sched_3"        vbase = "0xF0110000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" >
             <vobj name = "sched_3"        type = "SCHED" length  = "0x00008000" />
         </vseg>
-***
+
     </globalset> 
 
@@ -257,97 +268,97 @@
 *** For each vspace, the startname field is the name of the vobj containing the start_vector (entry point array)
 *** For each task, the startid field define the task entry point as an index in the start_vector
-*** For each task, the clusterid and proclocid arguments define the task static placement
+*** For each task, the x = "0" y and proclocid arguments define the task static placement
 *** For each task, the stackname field is the name of the vobj containing the task stack 
 *** For each task, the heapname field is the name of the vobj containing the task heap 
 
         <vspace name = "router" startname = "router_data" > 
-            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CXWU" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CXWU" x = "0" y = "0" psegname = "PSEG_RAM" > 
                 <vobj name = "router_code" type	 = "ELF" length = "0x00010000" binpath = "build/router/router.elf" /> 
             </vseg>
-            <vseg name = "seg_data"        vbase = "0x00500000" mode = "__WU" clusterid = "0" psegname = "PSEG_RAM" >
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "__WU" x = "0" y = "0" psegname = "PSEG_RAM" >
                 <vobj name = "router_data" type	 = "ELF" length = "0x00010000" binpath = "build/router/router.elf" />
             </vseg>
-            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
                 <vobj name = "ptab"        type	 = "PTAB" length  = "0x00020000" align   = "13" />
             </vseg>
-            <vseg name = "seg_stack_prod"  vbase = "0x00700000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" >
+            <vseg name = "seg_stack_prod"  vbase = "0x00700000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" >
                 <vobj name = "stack_prod"  type	 = "BUFFER" length = "0x00010000" /> 
                 <vobj name = "heap_prod"   type	 = "BUFFER" length = "0x00010000" /> 
             </vseg>
-            <vseg name = "seg_stack_cons"  vbase = "0x00800000" mode = "C_WU" clusterid = "1" psegname = "PSEG_RAM" > 
+            <vseg name = "seg_stack_cons"  vbase = "0x00800000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" > 
                 <vobj name = "stack_cons"  type	 = "BUFFER" length = "0x00010000" />
                 <vobj name = "heap_cons"   type	 = "BUFFER" length = "0x00010000" /> 
             </vseg>
-            <vseg name = "seg_stack_routA" vbase = "0x00900000" mode = "C_WU" clusterid = "2" psegname = "PSEG_RAM" > 
+            <vseg name = "seg_stack_routA" vbase = "0x00900000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" > 
                 <vobj name = "stack_routA" type	 = "BUFFER" length = "0x00010000" />
                 <vobj name = "heap_routA"  type	 = "BUFFER" length = "0x00010000" /> 
             </vseg>
-            <vseg name = "seg_stack_routB" vbase = "0x00A00000" mode = "C_WU" clusterid = "3" psegname = "PSEG_RAM" > 
+            <vseg name = "seg_stack_routB" vbase = "0x00A00000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" > 
                 <vobj name = "stack_routB" type	 = "BUFFER" length = "0x00010000" />
                 <vobj name = "heap_routB"  type	 = "BUFFER" length = "0x00010000" /> 
             </vseg>
-            <vseg name = "seg_mwmrs"       vbase = "0x00B00000" mode = "__WU" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vseg name = "seg_mwmrs"       vbase = "0x00B00000" mode = "__WU" x = "0" y = "0" psegname = "PSEG_RAM" > 
                 <vobj name = "mwmr_in"     type  = "MWMR" length = "0x00000020" init = "1" />
                 <vobj name = "mwmr_out"    type  = "MWMR" length = "0x00000020" init = "1" />
 		    </vseg>
 
-            <task name = "producer" clusterid = "0" proclocid = "0" stackname = "stack_prod"  heapname = "heap_prod"  startid = "0" usetty = "1" />
-            <task name = "consumer" clusterid = "1" proclocid = "0" stackname = "stack_cons"  heapname = "heap_cons"  startid = "1" usetty = "1" />
-            <task name = "router_A" clusterid = "2" proclocid = "0" stackname = "stack_routA" heapname = "heap_routA" startid = "2" usetty = "1" />
-            <task name = "router_B" clusterid = "3" proclocid = "0" stackname = "stack_routB" heapname = "heap_routB" startid = "2" usetty = "1" />
+            <task name = "producer" x = "0" y = "0" proclocid = "0" stackname = "stack_prod"  heapname = "heap_prod"  startid = "0" usetty = "1" />
+            <task name = "consumer" x = "0" y = "1" proclocid = "0" stackname = "stack_cons"  heapname = "heap_cons"  startid = "1" usetty = "1" />
+            <task name = "router_A" x = "1" y = "0" proclocid = "0" stackname = "stack_routA" heapname = "heap_routA" startid = "2" usetty = "1" />
+            <task name = "router_B" x = "1" y = "1" proclocid = "0" stackname = "stack_routB" heapname = "heap_routB" startid = "2" usetty = "1" />
         </vspace>
 
         <vspace name = "hello" startname = "hello_data" >
-            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CXWU" clusterid = "1" psegname = "PSEG_RAM" > 
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CXWU" x = "0" y = "1" psegname = "PSEG_RAM" > 
                 <vobj name = "hello_code"  type	 = "ELF" length = "0x00010000" binpath = "build/hello/hello.elf" />
             </vseg>
-            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" clusterid = "1" psegname = "PSEG_RAM" >
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" >
                 <vobj name = "hello_data"  type	 = "ELF" length = "0x00010000" binpath = "build/hello/hello.elf" />
             </vseg>
-            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C_W_" clusterid = "1" psegname = "PSEG_RAM" >
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C_W_" x = "0" y = "1" psegname = "PSEG_RAM" >
                 <vobj name = "ptab"        type	 = "PTAB" length = "0x00020000" align = "13" /> 
             </vseg>
-            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" clusterid = "1" psegname = "PSEG_RAM" >
+            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" >
                 <vobj name = "stack"       type	 = "BUFFER" length = "0x00010000" />
                 <vobj name = "heap"        type	 = "BUFFER" length = "0x00010000" />
             </vseg>
 
-            <task name = "main_hello" clusterid = "1" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+            <task name = "main_hello" x = "0" y = "1" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
         </vspace>
 
         <vspace name = "pgcd" startname = "pgcd_data" >
-            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CXWU" clusterid = "2" psegname = "PSEG_RAM" >
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CXWU" x = "1" y = "0" psegname = "PSEG_RAM" >
                 <vobj name = "pgcd_code"   type  = "ELF" length = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
             </vseg>
-            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" clusterid = "2" psegname = "PSEG_RAM" >
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" >
                 <vobj name	= "pgcd_data"  type	 = "ELF" length = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
             </vseg>
-            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C_W_" clusterid = "2" psegname = "PSEG_RAM" >
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C_W_" x = "1" y = "0" psegname = "PSEG_RAM" >
                 <vobj name = "ptab"        type	 = "PTAB" length = "0x00020000" align = "13" />
             </vseg>
-            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" clusterid = "2" psegname = "PSEG_RAM" >
+            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" >
                 <vobj name = "stack"       type  = "BUFFER" length = "0x00010000" /> 
                 <vobj name = "heap"        type  = "BUFFER" length = "0x00010000" /> 
             </vseg>
 
-            <task name = "main_pgcd" clusterid = "2" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+            <task name = "main_pgcd" x = "1" y = "0" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
         </vspace>
 
         <vspace name = "display" startname = "disp_data" >
-            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CXWU" clusterid = "3" psegname = "PSEG_RAM" >
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CXWU" x = "1" y = "1" psegname = "PSEG_RAM" >
                 <vobj name = "disp_code"   type	 = "ELF" length = "0x00010000" binpath = "build/display/display.elf" />
             </vseg>
-            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" clusterid = "3" psegname = "PSEG_RAM" >
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
                 <vobj name = "disp_data"   type	 = "ELF" length = "0x00010000" binpath = "build/display/display.elf" />
 			</vseg>
-            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C_W_" clusterid = "3" psegname = "PSEG_RAM" >
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" >
                 <vobj name = "ptab"        type	 = "PTAB" length  = "0x00020000" align   = "13" />
             </vseg>
-            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" clusterid = "3" psegname = "PSEG_RAM" >
+            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
                 <vobj name = "stack"       type	 = "BUFFER" length = "0x00010000" />
                 <vobj name = "heap"        type	 = "BUFFER" length = "0x00010000" />
             </vseg>
 
-            <task name = "main_display" clusterid = "3" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" usecma = "1" />
+            <task name = "main_display" x = "1" y = "1" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" usecma = "1" />
         </vspace>
     </vspaceset>
