Index: /soft/giet_vm/Makefile
===================================================================
--- /soft/giet_vm/Makefile	(revision 214)
+++ /soft/giet_vm/Makefile	(revision 215)
@@ -44,5 +44,5 @@
 TRASH= /dev/null||true
 
-all: soft.elf
+all: map.bin soft.elf
 	
 ## merge all *.elf and map.bin to soft.elf
@@ -53,5 +53,5 @@
           build/pgcd/pgcd.elf \
           build/hello/hello.elf \
-          map.bin
+          
 	$(MAKE) -C memo
 	memo/memo.x  map.bin 
@@ -61,5 +61,5 @@
 map.bin: $(MAP_XML)
 	$(MAKE) -C xml
-	xml/xml2bin $< $@
+	xml/xml2bin $< .
 
 ### system compilation
@@ -130,5 +130,5 @@
 ### clean 
 clean:
-	rm -f *.o *.elf *.bin *.txt core *~	2>$(TRASH)
+	rm -f *.o *.elf *.bin *.txt core  giet_vsegs.ld hard_config.h *~ 2>$(TRASH)
 	$(MAKE) -s clean -C xml	2>$(TRASH)
 	$(MAKE) -s clean -C memo 2>$(TRASH)
Index: /soft/giet_vm/boot/boot_init.c
===================================================================
--- /soft/giet_vm/boot/boot_init.c	(revision 214)
+++ /soft/giet_vm/boot/boot_init.c	(revision 215)
@@ -187,4 +187,35 @@
                    : "$26" );
 }
+
+//////////////////////////////////////////////////////////////////////////////
+// boot_scheduler_get_itvector()
+// This function get an interrupt vector slot in a scheduler, after a temporary
+// desactivation of the DTLB (because we use the scheduler physical address).
+// - gpid   : global processor/scheduler index
+// - slotid : context slot index
+// - return the content of the slot 
+//////////////////////////////////////////////////////////////////////////////
+unsigned int boot_scheduler_get_itvector( unsigned int gpid, 
+                                         unsigned int slotid)
+{
+    unsigned int value;
+
+    // get scheduler physical address
+    static_scheduler_t*     psched = boot_schedulers_paddr[gpid];
+    
+    // get slot physical address
+    unsigned int*           pslot  = &(psched->interrupt_vector[slotid]);
+
+    asm volatile ( "li      $26,    0xB     \n"
+                   "mtc2    $26,    $1      \n"     /* desactivate DTLB */
+                   "lw      %0,     0(%1)   \n"     /* *pslot <= value  */
+                   "li      $26,    0xF     \n" 
+                   "mtc2    $26,    $1      \n"     /* activate DTLB    */
+                   : "=r"(value) 
+                   : "r"(pslot) 
+                   : "$26" );
+    return value;
+}
+
 //////////////////////////////////////////////////////////////////////////////
 // boot_scheduler_get_tasks()
@@ -286,6 +317,5 @@
 void boot_puts(const char *buffer) 
 {
-    unsigned int* tty_address = (unsigned int*)( (char*)&seg_tty_base +
-                                (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
+    unsigned int* tty_address = (unsigned int*) &seg_tty_base;
     unsigned int n;
 
@@ -915,5 +945,5 @@
             if ( periph[periph_id].type == PERIPH_TYPE_TIM ) 
             {
-                if ( periph[periph_id].channels != (NB_PROCS_MAX + NB_TIMERS_MAX) )
+                if ( periph[periph_id].channels > NB_TIMERS_MAX )
                 {
                     boot_puts("\n[BOOT ERROR] Too much user timers in cluster ");
@@ -1312,5 +1342,5 @@
 
             //////// vci_io_bridge component
-            else if ( (type == PERIPH_TYPE_IOB) && GIET_IOMMU_ACTIVE )
+            else if ( (type == PERIPH_TYPE_IOB) && IOMMU_ACTIVE )
             {
                 // get the iommu page table physical address
@@ -1435,5 +1465,5 @@
     {
         alloc_fbdma_channel[cluster_id] = 0;
-        alloc_timer_channel[cluster_id] = NB_PROCS_MAX;
+        alloc_timer_channel[cluster_id] = 0;
     }
                 
@@ -1560,4 +1590,8 @@
             unsigned int ctx_ptpr = (unsigned int)boot_ptabs_paddr[vspace_id] >> 13;
 
+            // compute gpid = global processor index
+            unsigned int gpid = task[task_id].clusterid*NB_PROCS_MAX + 
+                                task[task_id].proclocid;
+
             // ctx_ptab : page_table virtual base address
             unsigned int ctx_ptab = (unsigned int)boot_ptabs_vaddr[vspace_id];
@@ -1602,5 +1636,7 @@
             {
                 unsigned int cluster_id = task[task_id].clusterid;
-                if ( alloc_timer_channel[cluster_id] >= NB_TIMERS_MAX )
+                unsigned int allocated = alloc_timer_channel[cluster_id];
+
+                if ( allocated >= NB_TIMERS_MAX )
                 {
                     boot_puts("\n[BOOT ERROR] local TIMER index too large for task ");
@@ -1611,6 +1647,33 @@
                     boot_exit();
                 }
-                ctx_timer = cluster_id*NB_TIMERS_MAX + alloc_timer_channel[cluster_id];
-                alloc_timer_channel[cluster_id]++;
+                
+                //assert(allocated >= 0);
+                char found = 0;
+                for( irq_id = 0; irq_id < 32; irq_id++)//look at the isr_timer isr channel
+                {
+                    unsigned int isr = boot_scheduler_get_itvector(gpid, irq_id) && 0x000000FF;
+                    if(isr == ISR_TIMER)
+                    {
+                        if(allocated == 0)
+                        {
+                            found = 1;
+                            alloc_timer_channel[cluster_id]++;
+                            ctx_timer = cluster_id*NB_TIMERS_MAX + alloc_timer_channel[cluster_id];
+                            break;
+                        }else
+                            allocated--;
+                    }
+                }
+
+                if(!found)
+                {
+                    boot_puts("\n[BOOT ERROR] No user timer available for task ");
+                    boot_puts( task[task_id].name );
+                    boot_puts(" in vspace ");
+                    boot_puts( vspace[vspace_id].name );
+                    boot_puts("\n");
+                    boot_exit();
+                }
+
             }
 
@@ -1642,8 +1705,4 @@
             unsigned int vobj_id = task[task_id].vobjlocid + vspace[vspace_id].vobj_offset;
             unsigned int ctx_sp = vobj[vobj_id].vaddr + vobj[vobj_id].length;
-
-            // compute gpid = global processor index
-            unsigned int gpid = task[task_id].clusterid*NB_PROCS_MAX + 
-                                task[task_id].proclocid;
 
             // In the code below, we access the scheduler with specific access 
Index: /soft/giet_vm/giet_config.h
===================================================================
--- /soft/giet_vm/giet_config.h	(revision 214)
+++ /soft/giet_vm/giet_config.h	(revision 215)
@@ -10,4 +10,8 @@
 #define _CONFIG_H
 
+/* hardware parameters */
+#include "hard_config.h"
+
+
 /* Debug parameters */
 
@@ -15,31 +19,15 @@
 #define BOOT_DEBUG_PT		0			/* trace page tables initialisation on TTY0 */
 #define BOOT_DEBUG_VOBJS	0			/* trace vobjs initialisation on TTY0 */
-#define BOOT_DEBUG_SCHED 	0			/* trace schedulers initialisation on TTY0 */
+#define BOOT_DEBUG_SCHED 	1			/* trace schedulers initialisation on TTY0 */
 
 #define GIET_DEBUG_INIT		0			/* trace parallel kernel initialisation on TTY0 */
 #define GIET_DEBUG_SWITCH	0			/* trace context switchs on TTY0 */
 
-
 #define CONFIG_SRL_VERBOSITY TRACE 
-
-/* hardware parameters */
-
-#define NB_CLUSTERS 		4			/* number of clusters */
-#define CLUSTER_SIZE		0x40000000	/* address increment between clusters */
-#define CLUSTER_IO_ID       2			/* cluster containing non replicated peripherals */
-	
-#define NB_PROCS_MAX	    1			/* max number of processors per cluster */
-#define NB_TIMERS_MAX		0			/* max number of user timers per cluster */
-#define NB_DMAS_MAX			1			/* max number of DMA channels per cluster*/
-#define NB_TTYS				8			/* total number of TTY channels */
-#define NB_IOCS				1			/* total number of IOC channels */
-#define NB_NICS				8			/* total number of NIC channels */
 
 /* software parameters */
 
-#define GIET_NB_VSPACE_MAX	4			/* max number of virtual spaces */
+#define GIET_NB_VSPACE_MAX	64			/* max number of virtual spaces */
 #define GIET_TICK_VALUE	    0x4000		/* context switch period (number of cycles) */
-#define GIET_IOMMU_ACTIVE   0			/* The IOMMU vspace is defined */
-#define GIET_USE_XICU       1			/* Use the XICU interrupt controler */
 
 #endif
Index: ft/giet_vm/giet_vsegs.ld
===================================================================
--- /soft/giet_vm/giet_vsegs.ld	(revision 214)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/****************************************************************************/
-/* Definition of the base addresses for all vsegs used by the GIET_VM       */
-/****************************************************************************/
-
-/****************************************************************************/
-/* The following (virtual) addresses are used by the boot code.             */
-/* They must respect identity mapping, because MMU is not activated.        */
-/*   (identity mapping <=> physical address == virtual address              */
-/****************************************************************************/
-
-seg_boot_code_base      = 0xBFC00000;   /* boot code */
-seg_boot_stack_base     = 0xBFC08000;	/* boot temporary stack */ 
-seg_mapping_base      	= 0xBFC0C000;	/* mapping_info blob */
-
-/****************************************************************************/
-/* The following (virtual) addresse are defined and used by the kernel.     */
-/* They are not constrained to respect identity mapping.                    */
-/****************************************************************************/
-
-seg_kernel_code_base    = 0x80000000;	/* kernel code */
-seg_kernel_data_base    = 0x80010000;	/* system cacheable data */
-seg_kernel_uncdata_base = 0x80080000;	/* system uncacheable data */
-seg_kernel_init_base    = 0x80090000;	/* system init entry */ 
-
-/****************************************************************************/
-/* The following (virtual) peripherals base addresses are used by both      */
-/* the boot code to initialise the peripherals, and by the kernel drivers.  */
-/* For sake of simplicity, they partially respect identity mapping.         */
-/* As some components are replicated in all clusters (ICU, DMA), the 8 MSB  */
-/* must be completed by the OS depending on the cluster index:              */
-/*       virtual address = base_address + cluster_id * CLUSTER_SIZE         */
-/*       ( with CLUSTER_SIZE = 4Gbytes / NB_CLUSTERS )                      */
-/****************************************************************************/
-
-seg_fbf_base       	    = 0x00D00000;   /* FrameBuffer device */
-
-seg_icu_base      	    = 0x00F00000;   /* ICU or XICU device */
-seg_ioc_base      	    = 0x00F10000;   /* Block device */
-seg_tty_base      	    = 0x00F20000;   /* TTY device */
-seg_dma_base      	    = 0x00F30000;   /* DMA device */
-seg_tim_base    	    = 0x00F40000;   /* Timer device */
-seg_gcd_base      	    = 0x00F50000;   /* GCD device */
-seg_iob_base      	    = 0x00FF0000;   /* IOB device */
-
Index: /soft/giet_vm/libs/libsrl/srl_args.h
===================================================================
--- /soft/giet_vm/libs/libsrl/srl_args.h	(revision 214)
+++ /soft/giet_vm/libs/libsrl/srl_args.h	(revision 215)
@@ -11,17 +11,17 @@
 
 
-# define SRL_GET_VBASE(task_name, port, type)                                                         \
-({                                                                                                  \
+# define SRL_GET_VBASE(task_name, port, type)                                                      \
+({                                                                                                 \
     unsigned int  vbase;                                                                           \
-    if( giet_vobj_get_vbase( APP_NAME , alias_##task_name.port, type, &vbase ) )                    \
-    {                                                                                               \
-        srl_log_printf( NONE, "\n[ERROR] in "#task_name" task :\n");                                \
-        srl_log_printf( NONE, "          undefined port <"#port"> for channel(%s): %d\n",           \
-                                                                alias_##task_name.port,vbase);      \
-        srl_log_printf( TRACE, "*** &"#port" = %x\n\n", vbase );                                    \
-        srl_exit();                                                                                 \
-    }else                                                                                           \
-        srl_log_printf( TRACE, "%s:%d: arg of %s for %s,from %s; &"#port" = %x\n\n",                \
-                            __FILE__, __LINE__, APP_NAME, #task_name,#port, vbase );                \
+    if( giet_vobj_get_vbase( APP_NAME , alias_##task_name.port, type, &vbase ) )                   \
+    {                                                                                              \
+        srl_log_printf( NONE, "\n[ERROR] in "#task_name" task :\n");                               \
+        srl_log_printf( NONE, "          undefined port <"#port"> for channel(%s): %d\n",          \
+                                                                alias_##task_name.port,vbase);     \
+        srl_log_printf( TRACE, "*** &"#port" = %x\n\n", vbase );                                   \
+        srl_exit();                                                                                \
+    }else                                                                                          \
+        srl_log_printf( TRACE, "%s:%d: arg of %s for %s,from %s; &"#port" = %x\n\n",               \
+                            __FILE__, __LINE__, APP_NAME, #task_name,#port, vbase );               \
     vbase;\
 })
Index: /soft/giet_vm/mappings/1c_4p_four.xml
===================================================================
--- /soft/giet_vm/mappings/1c_4p_four.xml	(revision 214)
+++ /soft/giet_vm/mappings/1c_4p_four.xml	(revision 215)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
 
-<mapping_info   signature = "0xdeadbeef" name = "1c_4p_four" clusters = "1" vspaces  = "4" >
+<mapping_info   signature = "0xdeadbeef" name = "1c_4p_four" cluster_x = "1" cluster_y = "1" vspaces  = "4" >
 
 *** This section describes an instance of the "caba_vgsb_xicu_mmu" generic architecture
@@ -71,4 +71,6 @@
             <periph type = "TTY" psegname = "PSEG_TTY" channels  = "8" /> 
             <periph type = "DMA" psegname = "PSEG_DMA" channels  = "1" /> 
+            <periph type = "TIM" psegname = "PSEG_TIM" channels  = "4" /> 
+            <periph type = "XICU" psegname = "PSEG_ICU" channels  = "5" /> 
             <periph type = "FBF" psegname = "PSEG_FBF" /> 
 
Index: /soft/giet_vm/mappings/4c_1p_four.xml
===================================================================
--- /soft/giet_vm/mappings/4c_1p_four.xml	(revision 214)
+++ /soft/giet_vm/mappings/4c_1p_four.xml	(revision 215)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
 
-<mapping_info signature = "0xdeadbeef" name = "C4_P1_FOUR" clusters = "4" vspaces = "4" >
+<mapping_info signature = "0xdeadbeef" name = "C4_P1_FOUR" cluster_x = "2" cluster_y = "2" vspaces = "4" >
 
     <clusterset>
@@ -8,5 +8,5 @@
 
             <pseg name = "PSEG_RAM" type = "RAM"  base = "0x00000000" length = "0x00C00000" />
-            <pseg name = "PSEG_ICU" type = "PERI" base = "0x00F00000" length = "0x00001000" />
+            <pseg name = "PSEG_XICU" type = "PERI" base = "0x00F00000" length = "0x00002000" />
             <pseg name = "PSEG_DMA" type = "PERI" base = "0x00F30000" length = "0x00008000" />
 
@@ -17,4 +17,5 @@
 
             <periph type = "DMA" psegname = "PSEG_DMA" channels = "1" />
+            <periph type = "XICU" psegname = "PSEG_XICU" channels = "2" />
 
         </cluster>
@@ -22,5 +23,5 @@
 
             <pseg name = "PSEG_RAM" type = "RAM"  base = "0x40000000" length = "0x00C00000" />
-            <pseg name = "PSEG_ICU" type = "PERI" base = "0x40F00000" length = "0x00001000" />
+            <pseg name = "PSEG_XICU" type = "PERI" base = "0x40F00000" length = "0x00002000" />
             <pseg name = "PSEG_DMA" type = "PERI" base = "0x40F30000" length = "0x00008000" />
 
@@ -31,4 +32,5 @@
 
             <periph type = "DMA" psegname = "PSEG_DMA" channels = "1" />
+            <periph type = "XICU" psegname = "PSEG_XICU" channels = "2" />
 
         </cluster>
@@ -36,5 +38,5 @@
 
             <pseg name = "PSEG_RAM" type = "RAM"  base = "0x80000000" length = "0x00C00000" /> 
-            <pseg name = "PSEG_ICU" type = "PERI" base = "0x80F00000" length = "0x00001000" />
+            <pseg name = "PSEG_XICU" type = "PERI" base = "0x80F00000" length = "0x00002000" />
             <pseg name = "PSEG_DMA" type = "PERI" base = "0x80F30000" length = "0x00008000" />
 
@@ -69,4 +71,5 @@
 
             <periph type = "DMA" psegname = "PSEG_DMA" channels = "1" /> 
+            <periph type = "XICU" psegname = "PSEG_XICU" channels = "18" />
             <periph type = "IOC" psegname = "PSEG_IOC" channels = "1" /> 
             <periph type = "TTY" psegname = "PSEG_TTY" channels = "8" /> 
@@ -78,5 +81,5 @@
 
             <pseg name = "PSEG_RAM" type = "RAM"  base = "0xC0000000" length = "0x00C00000" />
-            <pseg name = "PSEG_ICU" type = "PERI" base = "0xC0F00000" length = "0x00001000" />
+            <pseg name = "PSEG_XICU" type = "PERI" base = "0xC0F00000" length = "0x00001000" />
             <pseg name = "PSEG_DMA" type = "PERI" base = "0xC0F30000" length = "0x00008000" />
 
@@ -87,4 +90,5 @@
 
             <periph  type = "DMA" psegname  = "PSEG_DMA" channels = "1" />
+            <periph type = "XICU" psegname = "PSEG_XICU" channels = "2" />
         </cluster>
     </clusterset>
@@ -135,14 +139,14 @@
 *** On peut aussi dÃ©finir un vseg factorisÃ© en introduisant le CLUSTER_SIZE...
 
-        <vseg name = "seg_icu_0"          vbase = "0x00F00000" mode = "__W_" clusterid = "0" psegname = "PSEG_ICU" > 
+        <vseg name = "seg_icu_0"          vbase = "0x00F00000" mode = "__W_" clusterid = "0" psegname = "PSEG_XICU" > 
             <vobj name = "icu_0"          type = "PERI" length  = "0x00001000" /> 
         </vseg>
-        <vseg name = "seg_icu_1"          vbase = "0x40F00000" mode = "__W_" clusterid = "1" psegname = "PSEG_ICU" > 
+        <vseg name = "seg_icu_1"          vbase = "0x40F00000" mode = "__W_" clusterid = "1" psegname = "PSEG_XICU" > 
             <vobj name = "icu_1"          type = "PERI" length  = "0x00001000" /> 
         </vseg>
-        <vseg name = "seg_icu_2"          vbase = "0x80F00000" mode = "__W_" clusterid = "2" psegname = "PSEG_ICU" > 
+        <vseg name = "seg_icu_2"          vbase = "0x80F00000" mode = "__W_" clusterid = "2" psegname = "PSEG_XICU" > 
             <vobj name = "icu_2"          type = "PERI" length  = "0x00001000" /> 
         </vseg>
-        <vseg name = "seg_icu_3"          vbase = "0xC0F00000" mode = "__W_" clusterid = "3" psegname = "PSEG_ICU" > 
+        <vseg name = "seg_icu_3"          vbase = "0xC0F00000" mode = "__W_" clusterid = "3" psegname = "PSEG_XICU" > 
             <vobj name = "icu_3"          type = "PERI" length  = "0x00001000" /> 
         </vseg>
Index: /soft/giet_vm/mappings/exemple.xml
===================================================================
--- /soft/giet_vm/mappings/exemple.xml	(revision 214)
+++ /soft/giet_vm/mappings/exemple.xml	(revision 215)
@@ -3,6 +3,7 @@
 <mapping_info   signature = "0xdeadbeef" 
                 name     = "1C_4P_FOUR"
-                clusters = "1"
-                vspaces  = "4" >
+                vspaces  = "4" 
+                cluster_x = "1"
+                cluster_y = "1" >
 
         <clusterset>
@@ -212,4 +213,8 @@
                                   channels  = "8" />
 
+                         <periph  type      = "ICU"
+                                  psegname  = "PSEG_ICU"
+                                  channels  = "8" />
+
                          <periph  type      = "FBF"
                                   psegname  = "PSEG_FBF" />
Index: /soft/giet_vm/memo/src/memo.cpp
===================================================================
--- /soft/giet_vm/memo/src/memo.cpp	(revision 214)
+++ /soft/giet_vm/memo/src/memo.cpp	(revision 215)
@@ -39,5 +39,5 @@
 #include "memo.h"
 
-//#define MOVER_DEBUG 
+//#define MOVER_DEBUG
 
 MeMo::MeMo( const std::string &filename, 
@@ -258,5 +258,5 @@
     std::cout << std::hex << "mapping_info" << std::dec << std::endl
               << " + signature = " << header->signature << std::endl
-              << " + name      = " << header->name      << std::endl
+              << " + name      = " << (char*)header->name      << std::endl
               << " + clusters  = " << header->clusters  << std::endl
               << " + psegs     = " << header->psegs     << std::endl
@@ -279,4 +279,5 @@
     {
         std::cout << std::endl;
+        //std::cout << vseg[vseg_id].psegid << std::endl;
         std::cout << "global vseg "   << vseg[vseg_id].name << std::hex << std::endl 
                   << " + vbase    = " << vseg[vseg_id].vbase << std::endl 
Index: /soft/giet_vm/sys/common.c
===================================================================
--- /soft/giet_vm/sys/common.c	(revision 214)
+++ /soft/giet_vm/sys/common.c	(revision 215)
@@ -158,6 +158,5 @@
 void _puts(char* buffer) 
 {
-    unsigned int* tty_address = (unsigned int*)( (char*)&seg_tty_base +
-                                (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) ); 
+    unsigned int* tty_address = (unsigned int*) &seg_tty_base;
     unsigned int n;
 
Index: /soft/giet_vm/sys/drivers.c
===================================================================
--- /soft/giet_vm/sys/drivers.c	(revision 214)
+++ /soft/giet_vm/sys/drivers.c	(revision 215)
@@ -17,5 +17,4 @@
 //
 // The following global parameters must be defined in the giet_config.h file:
-// - CLUSTER_IO_ID
 // - CLUSTER_SIZE
 // - NB_CLUSTERS   
@@ -48,9 +47,9 @@
 
 #if !defined(NB_CLUSTERS) 
-# error: You must define NB_CLUSTERS in 'giet_config.h' file
+# error: You must define NB_CLUSTERS in the configs file
 #endif
 
 #if !defined(NB_PROCS_MAX) 
-# error: You must define NB_PROCS_MAX in 'giet_config.h' file
+# error: You must define NB_PROCS_MAX in the configs file
 #endif
 
@@ -60,9 +59,9 @@
 
 #if !defined(CLUSTER_SIZE) 
-# error: You must define CLUSTER_SIZE in 'giet_config.h' file
+# error: You must define CLUSTER_SIZE in the configs file
 #endif
 
 #if !defined(NB_TTYS)
-# error: You must define NB_TTYS in 'giet_config.h' file
+# error: You must define NB_TTYS in the configs file
 #endif
 
@@ -84,9 +83,17 @@
 
 #if !defined(NB_IOCS)
-# error: You must define NB_IOCS in 'giet_config.h' file 
+# error: You must define NB_IOCS in the configs file 
 #endif
 
 #if ( NB_IOCS > 1 )
 # error: NB_IOCS cannot be larger than 1
+#endif
+
+#if !defined( USE_XICU )
+# error: You must define USE_XICU in the configs file
+#endif
+
+#if !defined( IOMMU_ACTIVE )
+# error: You must define IOMMU_ACTIVE in the configs file
 #endif
 
@@ -98,5 +105,5 @@
 //////////////////////////////////////////////////////////////////////////////
 // The timers can be implemented in a vci_timer component or in a vci_xicu 
-// component (depending on the GIET_USE_XICU parameter).
+// component (depending on the USE_XICU parameter).
 // There is one timer (or xicu) component per cluster.
 // There is two types of timers: 
@@ -132,5 +139,5 @@
     if ( local_id >= NB_TIMERS_MAX + NB_PROCS_MAX ) return 1;
 
-#if GIET_USE_XICU
+#if USE_XICU
     unsigned int* timer_address = (unsigned int*)((char*)&seg_icu_base +
                                   (cluster_id * CLUSTER_SIZE) );
@@ -160,5 +167,5 @@
     if ( local_id >= NB_TIMERS_MAX + NB_PROCS_MAX ) return 1;
 
-#if GIET_USE_XICU
+#if USE_XICU
     unsigned int* timer_address = (unsigned int*)((char*)&seg_icu_base +
                                   (cluster_id * CLUSTER_SIZE) );
@@ -189,5 +196,5 @@
     if ( local_id >= NB_TIMERS_MAX + NB_PROCS_MAX ) return 1;
 
-#if GIET_USE_XICU
+#if USE_XICU
     unsigned int* timer_address = (unsigned int*)((char*)&seg_icu_base +
                                   (cluster_id * (unsigned)CLUSTER_SIZE) );
@@ -260,6 +267,5 @@
     }
 
-    unsigned int*	tty_address = (unsigned int*)( (char*)&seg_tty_base + 
-                                  (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) ); 
+    unsigned int*	tty_address = (unsigned int*) &seg_tty_base;
 
     for (nwritten = 0; nwritten < length; nwritten++)
@@ -322,6 +328,5 @@
 
     // compute terminal base address 
-    unsigned int *tty_address = (unsigned int*)( (char*)&seg_tty_base + 
-                                (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
+    unsigned int *tty_address = (unsigned int*) &seg_tty_base; 
 
     *buffer = (unsigned char)tty_address[tty_id*TTY_SPAN + TTY_READ];
@@ -355,5 +360,5 @@
     unsigned int* icu_address = (unsigned int*)( (char*)&seg_icu_base + 
                                 (cluster_id * (unsigned)CLUSTER_SIZE) );
-#if GIET_USE_XICU
+#if USE_XICU
     if ( is_timer ) icu_address[XICU_REG(XICU_MSK_PTI_ENABLE, proc_id)] = value;
     else            icu_address[XICU_REG(XICU_MSK_HWI_ENABLE, proc_id)] = value;
@@ -381,5 +386,5 @@
     unsigned int* icu_address = (unsigned int*)( (char*)&seg_icu_base + 
                                 (cluster_id * (unsigned)CLUSTER_SIZE) );
-#if GIET_USE_XICU
+#if USE_XICU
     unsigned int prio   = icu_address[XICU_REG(XICU_PRIO, proc_id)];
     unsigned int pti_ok = (prio & 0x00000001);
@@ -420,6 +425,5 @@
         return 1;
 
-    unsigned int* gcd_address = (unsigned int*)( (char*)&seg_gcd_base +
-                                (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
+    unsigned int* gcd_address = (unsigned int*) &seg_gcd_base;
 
     gcd_address[register_index] = value; // write word
@@ -438,6 +442,5 @@
         return 1;
 
-    unsigned int* gcd_address = (unsigned int*)( (char*)&seg_gcd_base +
-                                (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
+    unsigned int* gcd_address = (unsigned int*) &seg_gcd_base;
 
     *buffer = gcd_address[register_index]; // read word
@@ -530,6 +533,5 @@
     if ( (unsigned int)user_vaddr & 0x3 ) return 1;
 
-    unsigned int*	ioc_address = (unsigned int*)( (char*)&seg_ioc_base +
-                                  (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
+    unsigned int*	ioc_address = (unsigned int*) &seg_ioc_base ;
 
     unsigned int	block_size   = ioc_address[BLOCK_DEVICE_BLOCK_SIZE];
@@ -561,5 +563,5 @@
         if ( ix2 == 0 ) ppn_first = ppn;
 
-        if ( GIET_IOMMU_ACTIVE )    // the user buffer must be remapped in the I/0 space
+        if ( IOMMU_ACTIVE )    // the user buffer must be remapped in the I/0 space
         {
             // check buffer length < 2 Mbytes
@@ -588,5 +590,5 @@
 
     // compute buffer base address for IOC depending on IOMMU activation
-    if ( GIET_IOMMU_ACTIVE ) addr = (_ioc_iommu_ix1) << 21 | (user_vaddr & 0xFFF);
+    if ( IOMMU_ACTIVE ) addr = (_ioc_iommu_ix1) << 21 | (user_vaddr & 0xFFF);
     else                     addr = (ppn_first << 12) | (user_vaddr & 0xFFF);
 
@@ -622,8 +624,7 @@
 
     // unmap the buffer from IOMMU page table if IOMMU is activated
-    if ( GIET_IOMMU_ACTIVE )
-    {
-        unsigned int* iob_address = (unsigned int*)( (char*)&seg_iob_base +
-                                    (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
+    if ( IOMMU_ACTIVE )
+    {
+        unsigned int* iob_address = (unsigned int*) &seg_iob_base;
 
         for ( ix2 = 0 ; ix2 < _ioc_iommu_npages ; ix2++ )
@@ -691,6 +692,5 @@
 {
     // get IOC base address
-    unsigned int* ioc_address = (unsigned int*)( (char*)&seg_ioc_base +
-                                (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
+    unsigned int* ioc_address = (unsigned int*) &seg_ioc_base;
 
     *status = ioc_address[BLOCK_DEVICE_STATUS]; // read status & reset IRQ 
@@ -891,6 +891,5 @@
 
     // compute frame buffer pbase address
-    unsigned int fb_vaddr = (unsigned int)&seg_fbf_base + 
-                            (CLUSTER_IO_ID * (unsigned int)CLUSTER_SIZE) + offset;
+    unsigned int fb_vaddr = (unsigned int)&seg_fbf_base + offset;
 
     ko = _v2p_translate( (page_table_t*)user_ptab,
@@ -962,5 +961,5 @@
         if ( ix2 == 0 ) ppn_first = ppn;
 
-        if ( GIET_IOMMU_ACTIVE )    // the user buffer must be remapped in the I/0 space
+        if ( IOMMU_ACTIVE )    // the user buffer must be remapped in the I/0 space
         {
             // check buffer length < 2 Mbytes
@@ -1071,8 +1070,7 @@
     
     // unmap the buffer from IOMMU page table if IOMMU is activated
-    if ( GIET_IOMMU_ACTIVE )
-    {
-        unsigned int* iob_address = (unsigned int*)( (char*)&seg_iob_base +
-                                    (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) );
+    if ( IOMMU_ACTIVE )
+    {
+        unsigned int* iob_address = (unsigned int*) &seg_iob_base;
 
         unsigned int  ix1         = _dma_iommu_ix1 + dma_id;
Index: /soft/giet_vm/sys/irq_handler.c
===================================================================
--- /soft/giet_vm/sys/irq_handler.c	(revision 214)
+++ /soft/giet_vm/sys/irq_handler.c	(revision 215)
@@ -18,4 +18,8 @@
 #include <ctx_handler.h>
 #include <hwr_mapping.h>
+
+#if NB_TIMERS_MAX
+extern volatile unsigned char _user_timer_event[NB_CLUSTERS*NB_TIMERS_MAX] ;
+#endif
 
 ///////////////////////////////////////////////////////////////////////////////////
Index: /soft/giet_vm/sys/kernel_init.c
===================================================================
--- /soft/giet_vm/sys/kernel_init.c	(revision 214)
+++ /soft/giet_vm/sys/kernel_init.c	(revision 215)
@@ -48,4 +48,9 @@
 unsigned int			_idle_stack[NB_CLUSTERS*NB_PROCS_MAX*64]; 
 
+void _sys_exit()
+{
+    while(1);
+}
+
 //////////////////////////////////////////////////////////////////////////////////
 // This function is the entry point for the last step of the boot sequence.
@@ -127,4 +132,6 @@
     unsigned int pti_mask = 0;
 
+    unsigned int isr_switch_channel = 0xFFFFFFFF;
+
     for ( irq_id = 0 ; irq_id < 32 ; irq_id++ )
     {
@@ -136,6 +143,11 @@
              hwi_mask = hwi_mask | 0x1<< irq_id;
         }
-        else if ( (isr == ISR_SWITCH) || (isr == ISR_TIMER) )
+        else if ( (isr == ISR_SWITCH) )
         { 
+            pti_mask = pti_mask | 0x1<< irq_id;
+            isr_switch_channel = irq_id;
+        }
+        else if ( (isr == ISR_TIMER) )
+        {
             pti_mask = pti_mask | 0x1<< irq_id;
         }
@@ -159,6 +171,13 @@
     if ( tasks > 1 )
     {
+        if(isr_switch_channel == 0xFFFFFFFF)
+        {
+            _puts("\n[GIET ERROR] ISR_SWITCH not found on proc ");
+            _putd( proc_id);
+            _puts("\n");
+            _sys_exit();
+        }
         _timer_start( cluster_id, 
-                      proc_id, 
+                      isr_switch_channel, 
                       GIET_TICK_VALUE );
         
Index: /soft/giet_vm/sys/sys_handler.c
===================================================================
--- /soft/giet_vm/sys/sys_handler.c	(revision 214)
+++ /soft/giet_vm/sys/sys_handler.c	(revision 215)
@@ -139,15 +139,5 @@
 }
 
-/////////////////////////////////////////////////////////////////////////////
-// _vobj_get_vbase()
-// This function writes in vobj_buffer the virtual base address of a vobj 
-// identified by the (vspace_name / vobj_name ) couple.
-// The vobj_type argument is redundant, and for checking purpose.
-// returns 0: success, else: failed.
-/////////////////////////////////////////////////////////////////////////////
-unsigned int _vobj_get_vbase( char*			vspace_name, 
-                              char*			vobj_name,
-                              unsigned int	vobj_type, 
-                              unsigned int* vobj_vaddr )
+int _get_vobj( char* vspace_name, char* vobj_name, unsigned int vobj_type, mapping_vobj_t** res_vobj)
 {
     mapping_header_t* header = (mapping_header_t*)&seg_mapping_base;
@@ -175,5 +165,6 @@
                         return -1;							//wrong type
 
-                    *vobj_vaddr = (unsigned int)vobj[vobj_id].vaddr;
+                    *res_vobj = &vobj[vobj_id];
+
                     return 0;
                 }
@@ -182,4 +173,52 @@
     } 
     return -2;		//not found 
-}
-
+
+}
+/////////////////////////////////////////////////////////////////////////////
+// _vobj_get_vbase()
+// This function writes in vobj_vaddr the virtual base address of a vobj 
+// identified by the (vspace_name / vobj_name ) couple.
+// The vobj_type argument is here only for the purpose of checking .
+// returns 0: success, else: failed.
+/////////////////////////////////////////////////////////////////////////////
+unsigned int _vobj_get_vbase( char*			vspace_name, 
+                              char*			vobj_name,
+                              unsigned int	vobj_type, 
+                              unsigned int* vobj_vaddr )
+{
+    mapping_vobj_t*   res_vobj;
+    unsigned int ret;
+    if( (ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj)) )
+    {
+        return ret;
+    }
+    
+    *vobj_vaddr = res_vobj->vaddr;
+
+    return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// _vobj_get_length()
+// This function writes in vobj_length the virtual base address of a vobj 
+// identified by the (vspace_name / vobj_name ) couple.
+// The vobj_type argument is here only for the purpose of checking .
+// returns 0: success, else: failed.
+/////////////////////////////////////////////////////////////////////////////
+unsigned int _vobj_get_length(char*			vspace_name, 
+                              char*			vobj_name,
+                              unsigned int	vobj_type, 
+                              unsigned int* vobj_length )
+{
+
+    mapping_vobj_t*   res_vobj;
+    unsigned int ret;
+    if( (ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj)) )
+    {
+        return ret;
+    }
+    
+    *vobj_length = res_vobj->length;
+
+    return 0;
+}
Index: /soft/giet_vm/xml/mapping_info.h
===================================================================
--- /soft/giet_vm/xml/mapping_info.h	(revision 214)
+++ /soft/giet_vm/xml/mapping_info.h	(revision 215)
@@ -71,11 +71,13 @@
 enum periphType
 {
-    PERIPH_TYPE_IOC   = 0,
-    PERIPH_TYPE_TTY   = 1,
-    PERIPH_TYPE_TIM   = 2,
+    PERIPH_TYPE_ICU   = 0,
+    PERIPH_TYPE_TIM   = 1,
+    PERIPH_TYPE_XICU  = 2,
     PERIPH_TYPE_DMA   = 3,
-    PERIPH_TYPE_FBF   = 4,
-    PERIPH_TYPE_NIC   = 5,
-    PERIPH_TYPE_IOB   = 6,
+    PERIPH_TYPE_IOC   = 4,
+    PERIPH_TYPE_TTY   = 5,
+    PERIPH_TYPE_FBF   = 6,
+    PERIPH_TYPE_NIC   = 7,
+    PERIPH_TYPE_IOB   = 8,
 };
 
@@ -92,4 +94,6 @@
     unsigned int    signature;      // must contain MAPPING_SIGNATURE
 	unsigned int	clusters;	    // number of clusters
+	unsigned int	cluster_x;	    // number of cluster on the abcsisse axe
+	unsigned int	cluster_y;	    // number of cluster on the ordinate axe
 	unsigned int	globals;		// number of vsegs mapped in all vspaces
 	unsigned int	vspaces;		// number of virtual spaces
Index: /soft/giet_vm/xml/xml_driver.c
===================================================================
--- /soft/giet_vm/xml/xml_driver.c	(revision 214)
+++ /soft/giet_vm/xml/xml_driver.c	(revision 215)
@@ -57,8 +57,10 @@
     const char* periph_type[] =
     {
+        "ICU",
+        "TIM",
+        "XICU",
+        "DMA",
         "IOC",
         "TTY",
-        "TIM",
-        "DMA",
         "FBF",
         "NIC",
@@ -220,5 +222,6 @@
     fprintf( fpout, "<mapping_info signature = \"0x%x\" ", header->signature);
     fprintf( fpout, " name = \"%s\" ", header->name);
-    fprintf( fpout, " clusters = \"%d\" ", header->clusters);
+    fprintf( fpout, " cluster_x = \"%d\" ", header->cluster_x);
+    fprintf( fpout, " cluster_y = \"%d\" ", header->cluster_y);
     fprintf( fpout, " vspaces = \"%d\" >\n\n", header->vspaces);
 
@@ -241,9 +244,10 @@
     ///////////////////// processors /////////////////////////////////////////////
 
+        unsigned int proc_index = 0;
         for ( proc_id = cluster[cluster_id].proc_offset ; 
               proc_id < cluster[cluster_id].proc_offset + cluster[cluster_id].procs ;
               proc_id++ )
         {
-            fprintf( fpout, "            <proc index = \"%d\" >\n", proc_id);
+            fprintf( fpout, "            <proc index = \"%d\" >\n", proc_index);
             for ( irq_id = proc[proc_id].irq_offset ; 
                   irq_id < proc[proc_id].irq_offset + proc[proc_id].irqs ; 
Index: /soft/giet_vm/xml/xml_parser.c
===================================================================
--- /soft/giet_vm/xml/xml_parser.c	(revision 214)
+++ /soft/giet_vm/xml/xml_parser.c	(revision 215)
@@ -86,10 +86,60 @@
 unsigned int		vobj_count     = 0;
 
-///////////////////////////////////////////////////////////////////////
+
+/////////////////////////
+// found peripheral
+/////////////////////////
+char found_timer = 0;
+char found_icu = 0;
+char found_xicu = 0;
+char found_dma = 0;
+
+
+//////////////////////////////////
+//needed to generate map_config.ld
+//////////////////////////////////
+unsigned int cluster_y              = 0;
+unsigned int cluster_x              = 0; 
+unsigned int nb_proc_max            = 0; // max number of processors per cluster 
+unsigned int nb_timer_channel_max   = 0; // max number of user timer
+unsigned int nb_dma_channel_max     = 0;
+unsigned int nb_tty_channel         = 0;
+unsigned int nb_ioc_channel         = 0;
+unsigned int nb_nic_channel         = 0;
+unsigned int io_mmu_active          = 0;
+unsigned int use_xicu               = 0xFFFFFFFF;
+
+
+//////////////////////////////////
+//needed to generate giet_vseg.ld
+//////////////////////////////////
+
+//kernel and boot code
+unsigned int kernel_code_base    = 0x80000000;	/* kernel code */
+unsigned int kernel_data_base    = 0x80010000;	/* system cacheable data */
+unsigned int kernel_uncdata_base = 0x80080000;	/* system uncacheable data */
+unsigned int kernel_init_base    = 0x80090000;	/* system init entry */ 
+
+unsigned int boot_code_base      = 0xBFC00000;   /* boot code */
+unsigned int boot_stack_base     = 0xBFC08000;	/* boot temporary stack */ 
+unsigned int boot_mapping_base   = 0xBFC0C000;	/* mapping_info blob */
+
+//periphs
+unsigned int tim_base_offset = 0xFFFFFFFF;
+unsigned int tty_base_offset = 0xFFFFFFFF;
+unsigned int dma_base_offset = 0xFFFFFFFF;
+unsigned int ioc_base_offset = 0xFFFFFFFF;
+unsigned int fbf_base_offset = 0xFFFFFFFF;
+unsigned int icu_base_offset = 0xFFFFFFFF;
+unsigned int gcd_base_offset = 0xFFFFFFFF;
+unsigned int iob_base_offset = 0xFFFFFFFF;
+
+
+//////////////////////////////////////////////////////////////////////
 // This arrray is useful to build a temporary list of vobj references. 
 // The struct vobj_ref_s is formed by a vspace_name and a vobj_name.
 // This array is used to set the attribute vobj_id of a cp_port
 // once all the vspace have been parsed.
-
+/////////////////////////////////////////////////////////////////////
 typedef struct vobj_ref_s
 {
@@ -159,4 +209,5 @@
     char* string = (char*)xmlTextReaderGetAttribute(reader, (const xmlChar*)attributeName);
 
+    
     if ( string == NULL )  // missing argument
     {
@@ -166,4 +217,11 @@
     else
     {
+        //we read only string smaller than 32 byte
+        if(strlen(string) > 32)
+        {
+            printf("[XML ERROR] all strings must be less than 32 bytes\n");
+            exit(1);
+        }
+
         *ok = 1;
         return string;
@@ -181,5 +239,8 @@
     for ( pseg_id = pseg_min ; pseg_id < pseg_max ; pseg_id++ )
     {
-        if ( strcmp(pseg[pseg_id]->name, pseg_name) == 0 ) return pseg_id;
+        if ( strcmp(pseg[pseg_id]->name, pseg_name) == 0 ) 
+        {
+            return pseg_id;
+        }
     }
     return -1;
@@ -219,492 +280,4 @@
     return -1;
 }
-
-///////////////////////////////////////////
-void cpPortNode ( xmlTextReaderPtr reader )
-///////////////////////////////////////////
-{
-    char*           str;
-    unsigned int    ok;
-
-    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
-
-    if ( cp_port_index >= MAX_CP_PORTS )
-    {
-        printf("[XML ERROR] The number of ports (for coprocs) is larger than %d\n", MAX_CP_PORTS);
-    }
-
-#if XML_PARSER_DEBUG
-printf("\n  port %d\n", cp_port_index);
-#endif
-
-    cp_port[cp_port_index] = (mapping_cp_port_t*)malloc(sizeof(mapping_cp_port_t));
-    cp_port_vobj_ref[cp_port_index] = (vobj_ref_t*)malloc(sizeof(vobj_ref_t));
-
-
-    
-    ///////// get direction attribute
-    str = getStringValue( reader, "direction", &ok );
-    if ( ok )
-    {
-#if XML_PARSER_DEBUG
-printf("      direction = %s\n", str);
-#endif
-        if      ( strcmp(str, "TO_COPROC")   ==  0 ) cp_port[cp_port_index]->direction = PORT_TO_COPROC;
-        else if ( strcmp(str, "FROM_COPROC") ==  0 ) cp_port[cp_port_index]->direction = PORT_FROM_COPROC;
-        else
-        {
-            printf("[XML ERROR] illegal <direction> for cp_port %d in cluster %d\n",
-                   cp_port_index, cluster_index);
-            exit(1);
-        }
-    }  
-    else
-    {
-        printf("[XML ERROR] missing <direction> for cp_port %d in cluster %d\n",
-               cp_port_index, cluster_index);
-        exit(1);
-    }
-    
-    /////////// get vspacename attribute 
-    str = getStringValue( reader, "vspacename", &ok );
-#if XML_PARSER_DEBUG
-printf("      vspacename = %s\n", str);
-#endif
-    if ( ok ) 
-    {
-        strncpy(cp_port_vobj_ref[cp_port_index]->vspace_name, str, 31);
-    }
-    else
-    {
-        printf("[XML ERROR] missing <vspacename> for cp_port %d in cluster %d\n",
-               cp_port_index, cluster_index);
-        exit(1);
-    }
-
-    /////////// get vobjname attribute 
-    str = getStringValue( reader, "vobjname", &ok );
-#if XML_PARSER_DEBUG
-printf("      vobjname = %s\n", str);
-#endif
-    if ( ok ) 
-    {
-        strncpy(cp_port_vobj_ref[cp_port_index]->vobj_name, str, 31);
-    }
-    else
-    {
-        printf("[XML ERROR] missing <vobjname> for cp_port %d in cluster %d\n",
-               cp_port_index, cluster_index);
-        exit(1);
-    }
-    
-    cp_port_index++;
-    cp_port_loc_index++;
-
-} // end cpPortNode()
-
-///////////////////////////////////////////
-void periphNode ( xmlTextReaderPtr reader )
-///////////////////////////////////////////
-{
-    char*           str;
-    unsigned int    value;
-    unsigned int 	ok;
-
-    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
-
-    if ( periph_index >= MAX_PERIPHS )
-    {
-        printf("[XML ERROR] The number of periphs is larger than %d\n", MAX_PERIPHS);
-    }
-
-#if XML_PARSER_DEBUG
-printf("\n  periph %d\n", periph_index);
-#endif
-
-    periph[periph_index] = (mapping_periph_t*)malloc(sizeof(mapping_periph_t));
-
-    /////////// get type attribute 
-    str = getStringValue( reader, "type", &ok );
-    if ( ok ) 
-    {
-#if XML_PARSER_DEBUG
-printf("      type     = %s\n", str);
-#endif
-        unsigned int error = 0;
-  
-        // The TTY, IOC, NIC, FBF and IOB peripherals cannot be replicated
-        if      ( strcmp( str, "IOC" ) == 0 ) 
-        {
-            periph[periph_index]->type = PERIPH_TYPE_IOC;
-            if ( header->ioc_clusterid == 0xFFFFFFFF) header->ioc_clusterid = cluster_index;
-            else  error = 1;
-        } 
-        else if ( strcmp( str, "TTY" ) == 0 )
-        {
-            periph[periph_index]->type = PERIPH_TYPE_TTY;
-            if ( header->ioc_clusterid == 0xFFFFFFFF) header->ioc_clusterid = cluster_index;
-            else  error = 1;
-        }
-        else if ( strcmp( str, "FBF" ) == 0 ) 
-        {
-            periph[periph_index]->type = PERIPH_TYPE_FBF;
-            if ( header->ioc_clusterid == 0xFFFFFFFF) header->ioc_clusterid = cluster_index;
-            else  error = 1;
-        }
-        else if ( strcmp( str, "NIC" ) == 0 ) 
-        {
-            periph[periph_index]->type = PERIPH_TYPE_NIC;
-            if ( header->ioc_clusterid == 0xFFFFFFFF) header->ioc_clusterid = cluster_index;
-            else  error = 1;
-        }
-        // The TIM, DMA and IOB peripherals can be replicated in several clusters
-        else if ( strcmp( str, "TIM" ) == 0 ) 
-        {
-            periph[periph_index]->type = PERIPH_TYPE_TIM;
-        }
-        else if ( strcmp( str, "DMA" ) == 0 ) 
-        {
-            periph[periph_index]->type = PERIPH_TYPE_DMA;
-        }
-        else if ( strcmp( str, "IOB" ) == 0 ) 
-        {
-            periph[periph_index]->type = PERIPH_TYPE_IOB;
-        }
-        else
-        {
-            printf("[XML ERROR] illegal <type> for peripheral %d in cluster %d\n",
-                   periph_loc_index, cluster_index);
-            exit(1);
-        }
-    }
-    else
-    {
-        printf("[XML ERROR] missing <type> for peripheral  %d in cluster %d\n",
-               periph_loc_index, cluster_index);
-        exit(1);
-    }
-
-    ///////// get channels attribute (optionnal : 1 if missing)
-    value = getIntValue( reader, "channels", &ok );
-    if ( ok )
-    {
-#if XML_PARSER_DEBUG
-printf("      channels = %d\n", value);
-#endif
-        periph[periph_index]->channels = value;
-    }
-    else
-    {
-        periph[periph_index]->channels = 1;
-    }
-
-    /////////// get psegname attribute 
-    str = getStringValue(reader,"psegname", &ok);
-    if ( ok == 0 )
-    {
-        printf("[XML ERROR] illegal or missing <psegname> for coproc %d in cluster %d\n", 
-                 coproc_index, cluster_index);
-        exit(1);
-    }
-
-    /////////// set psegid attribute
-    int index = getPsegId( cluster_index, str );
-    if ( index >= 0 ) 
-    {
-#if XML_PARSER_DEBUG
-printf("      clusterid = %d\n", cluster_index);
-printf("      psegname  = %s\n", str);
-printf("      psegid    = %d\n", index);
-#endif
-        periph[periph_index]->psegid = index;
-        assert(pseg[index]->type == PSEG_TYPE_PERI && 
-        "peripheral psegname attribute must refer to a pseg of type PERI" );
-    }
-    else              
-    {
-        printf("[XML ERROR] pseg not found for periph %d / clusterid = %d / psegname = %s\n", 
-                   periph_loc_index, cluster_index, str );
-        exit(1);
-    }  
-    
-    periph_index++;
-    periph_loc_index++;
-
-} // end periphNode
-
-/////////////////////////////////////////
-void coprocNode ( xmlTextReaderPtr reader )
-/////////////////////////////////////////
-{
-    char*           str;
-    unsigned int 	ok;
-
-    cp_port_loc_index = 0;
-
-    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
-
-    if ( coproc_index >= MAX_COPROCS )
-    {
-        printf("[XML ERROR] The number of coprocs is larger than %d\n", MAX_COPROCS);
-    }
-
-#if XML_PARSER_DEBUG
-printf("\n  coproc %d\n", coproc_index);
-#endif
-
-    coproc[coproc_index] = (mapping_coproc_t*)malloc(sizeof(mapping_coproc_t));
-
-    /////////// get name attribute 
-    str = getStringValue( reader, "name", &ok );
-    if ( ok ) 
-    {
-#if XML_PARSER_DEBUG
-printf("      name = %s\n", str);
-#endif
-        strncpy(coproc[coproc_index]->name, str, 31);
-    }
-    else
-    {
-        printf("[XML ERROR] illegal or missing <name> for coproc %d in cluster %d\n",
-               coproc_index, cluster_index);
-        exit(1);
-    }
-
-    /////////// get psegname attribute 
-    str = getStringValue(reader,"psegname", &ok);
-    if ( ok == 0 )
-    {
-        printf("[XML ERROR] illegal or missing <psegname> for coproc %d in cluster %d\n", 
-                 coproc_index, cluster_index);
-        exit(1);
-    }
-
-    /////////// set psegid attribute
-    int index = getPsegId( cluster_index, str );
-    if ( index >= 0 ) 
-    {
-#if XML_PARSER_DEBUG
-printf("      clusterid = %d\n", cluster_index);
-printf("      psegname  = %s\n", str);
-printf("      psegid    = %d\n", index);
-#endif
-        coproc[coproc_index]->psegid = index;
-        assert(pseg[index]->type == PSEG_TYPE_PERI && "coproc psegname attribute must refer to a pseg of type PERI" );
-    }
-    else              
-    {
-        printf("[XML ERROR] pseg not found for coproc %d / clusterid = %d / psegname = %s\n", 
-                   coproc_index, cluster_index, str );
-        exit(1);
-    }  
-
-    ////////// set port_offset 
-    coproc[coproc_index]->port_offset = cp_port_index;
-
-#if XML_PARSER_DEBUG
-printf("      port_offset = %d\n", cp_port_index);
-#endif
-
-    int status = xmlTextReaderRead(reader);
-    while ( status == 1 ) 
-    {
-        const char* tag = (const char*)xmlTextReaderConstName(reader);
-
-        if      ( strcmp(tag, "port")     == 0 ) cpPortNode(reader);
-        else if ( strcmp(tag, "#text")    == 0 ) { }
-        else if ( strcmp(tag, "#comment") == 0 ) { }
-        else if ( strcmp(tag, "coproc")   == 0 ) 
-        {
-            coproc[coproc_index]->ports = cp_port_loc_index;
-            coproc_loc_index++;
-            coproc_index++;
-            return;
-        }
-        else 
-        {
-            printf("[XML ERROR] Unknown tag %s",tag);
-            exit(1);
-        }
-        status = xmlTextReaderRead ( reader );
-    }
-} // end coprocNode()
-
-///////////////////////////////////////
-void irqNode( xmlTextReaderPtr reader )
-///////////////////////////////////////
-{
-    unsigned int 	ok;
-    unsigned int 	value;
-    char*    		str;
-
-    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
-
-    if ( irq_index >= MAX_IRQS )
-    {
-        printf("[XML ERROR] The number of irqs is larger than %d\n", MAX_IRQS);
-    }
-
-#if XML_PARSER_DEBUG
-printf("     irq %d\n", irq_loc_index);
-#endif
-
-    irq[irq_index] = (mapping_irq_t*)malloc(sizeof(mapping_irq_t));
-
-    ///////// get type attribute
-    str = getStringValue(reader,"type", &ok);
-    if ( ok )
-    {
-#if XML_PARSER_DEBUG
-printf("        type    = %s\n", str);
-#endif
-        if      ( strcmp(str, "HARD") == 0 ) irq[irq_index]->type = 0;
-        else if ( strcmp(str, "SOFT") == 0 ) irq[irq_index]->type = 1;
-        else
-        {
-            printf("[XML ERROR] undefined IRQ  <type> for processor %d in cluster %d\n",
-                   cluster_index, proc_loc_index );
-            exit(1);
-        }
-    }  
-    else
-    {
-        printf("[XML ERROR] missing IRQ <type> for processor %d in cluster %d\n",
-               cluster_index, proc_loc_index );
-        exit(1);
-    }
-
-    ///////// get icuid attribute
-    value = getIntValue(reader, "icuid", &ok);
-    if ( ok )
-    {
-#if XML_PARSER_DEBUG
-printf("        icuid   = %d\n", value);
-#endif
-        irq[irq_index]->icuid = value;
-        if ( value >= 32 )
-        {
-            printf("[XML ERROR] IRQ <icuid> too large for processor %d in cluster %d\n",
-                   cluster_index, proc_loc_index );
-            exit(1);
-        }
-    }
-    else
-    {
-        printf("[XML ERROR] missing IRQ <icuid> for processor %d in cluster %d\n",
-               cluster_index, proc_loc_index );
-        exit(1);
-    }
-
-    ///////// get isr attribute
-    str = getStringValue(reader,"isr", &ok);
-    if ( ok )
-    {
-#if XML_PARSER_DEBUG
-printf("        isr     = %s\n", str);
-#endif
-        if      ( strcmp(str, "ISR_SWITCH" ) == 0 ) irq[irq_index]->isr = ISR_SWITCH;
-        else if ( strcmp(str, "ISR_IOC"    ) == 0 ) irq[irq_index]->isr = ISR_IOC;
-        else if ( strcmp(str, "ISR_DMA"    ) == 0 ) irq[irq_index]->isr = ISR_DMA;
-        else if ( strcmp(str, "ISR_TTY"    ) == 0 ) irq[irq_index]->isr = ISR_TTY;
-        else if ( strcmp(str, "ISR_TIMER"  ) == 0 ) irq[irq_index]->isr = ISR_TIMER;
-        else
-        {
-            printf("[XML ERROR] illegal IRQ <isr> for processor %d in cluster %d\n",
-                   cluster_index, proc_loc_index );
-            exit(1);
-        }
-#if XML_PARSER_DEBUG
-printf("        isrnum  = %d\n", irq[irq_index]->isr);
-#endif
-    }  
-    else
-    {
-        printf("[XML ERROR] missing IRQ <isr> for processor %d in cluster %d\n",
-               cluster_index, proc_loc_index );
-        exit(1);
-    }
-
-    ///////// get channel attribute (optionnal : 0 if missing)
-    value = getIntValue(reader, "channel", &ok);
-    if ( ok )
-    {
-#if XML_PARSER_DEBUG
-printf("        channel = %d\n", value);
-#endif
-        irq[irq_index]->channel = value;
-    }
-    else
-    {
-        irq[irq_index]->channel = 0;
-    }
-
-    irq_index++;
-    irq_loc_index++;
-
-} // end irqNode
-
-/////////////////////////////////////////
-void procNode ( xmlTextReaderPtr reader )
-/////////////////////////////////////////
-{
-    unsigned int 	ok;
-    unsigned int    value;
-
-    irq_loc_index = 0;
-
-    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
-
-    if ( proc_index >= MAX_PROCS )
-    {
-        printf("[XML ERROR] The number of procs is larger than %d\n", MAX_PROCS);
-    }
-
-#if XML_PARSER_DEBUG
-printf("\n  proc %d\n", proc_index);
-#endif
-
-    proc[proc_index] = (mapping_proc_t*)malloc(sizeof(mapping_proc_t));
-
-
-    /////////// get index attribute (optional)
-    value = getIntValue(reader,"index",&ok);
-    if ( ok && (value != proc_loc_index) )
-    {
-            printf("[XML ERROR] wrong proc index / expected value is %d", 
-                proc_loc_index);
-            exit(1);
-    }
-
-    ////////// set irq_offset attribute
-    proc[proc_index]->irq_offset = irq_index;
-
-#if XML_PARSER_DEBUG
-printf("    irq_offset = %d\n", irq_index);
-#endif
-
-    int status = xmlTextReaderRead(reader);
-    while ( status == 1 ) 
-    {
-        const char* tag = (const char*)xmlTextReaderConstName(reader);
-
-        if      ( strcmp(tag, "irq")      == 0 ) irqNode(reader);
-        else if ( strcmp(tag, "#text")    == 0 ) { }
-        else if ( strcmp(tag, "#comment") == 0 ) { }
-        else if ( strcmp(tag, "proc")     == 0 ) 
-        {
-            proc[proc_index]->irqs = irq_loc_index;
-            proc_loc_index++;
-            proc_index++;
-            return;
-        }
-        else 
-        {
-            printf("[XML ERROR] Unknown tag %s",tag);
-            exit(1);
-        }
-        status = xmlTextReaderRead ( reader );
-    }
-} // end procNode()
-
 
 /////////////////////////////////////////
@@ -1321,4 +894,556 @@
 } // end vspaceNode()
 
+///////////////////////////////////////////
+void cpPortNode ( xmlTextReaderPtr reader )
+///////////////////////////////////////////
+{
+    char*           str;
+    unsigned int    ok;
+
+    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
+
+    if ( cp_port_index >= MAX_CP_PORTS )
+    {
+        printf("[XML ERROR] The number of ports (for coprocs) is larger than %d\n", MAX_CP_PORTS);
+    }
+
+#if XML_PARSER_DEBUG
+printf("\n  port %d\n", cp_port_index);
+#endif
+
+    cp_port[cp_port_index] = (mapping_cp_port_t*)malloc(sizeof(mapping_cp_port_t));
+    cp_port_vobj_ref[cp_port_index] = (vobj_ref_t*)malloc(sizeof(vobj_ref_t));
+
+
+    
+    ///////// get direction attribute
+    str = getStringValue( reader, "direction", &ok );
+    if ( ok )
+    {
+#if XML_PARSER_DEBUG
+printf("      direction = %s\n", str);
+#endif
+        if      ( strcmp(str, "TO_COPROC")   ==  0 ) cp_port[cp_port_index]->direction = PORT_TO_COPROC;
+        else if ( strcmp(str, "FROM_COPROC") ==  0 ) cp_port[cp_port_index]->direction = PORT_FROM_COPROC;
+        else
+        {
+            printf("[XML ERROR] illegal <direction> for cp_port %d in cluster %d\n",
+                   cp_port_index, cluster_index);
+            exit(1);
+        }
+    }  
+    else
+    {
+        printf("[XML ERROR] missing <direction> for cp_port %d in cluster %d\n",
+               cp_port_index, cluster_index);
+        exit(1);
+    }
+    
+    /////////// get vspacename attribute 
+    str = getStringValue( reader, "vspacename", &ok );
+#if XML_PARSER_DEBUG
+printf("      vspacename = %s\n", str);
+#endif
+    if ( ok ) 
+    {
+        strncpy(cp_port_vobj_ref[cp_port_index]->vspace_name, str, 31);
+    }
+    else
+    {
+        printf("[XML ERROR] missing <vspacename> for cp_port %d in cluster %d\n",
+               cp_port_index, cluster_index);
+        exit(1);
+    }
+
+    /////////// get vobjname attribute 
+    str = getStringValue( reader, "vobjname", &ok );
+#if XML_PARSER_DEBUG
+printf("      vobjname = %s\n", str);
+#endif
+    if ( ok ) 
+    {
+        strncpy(cp_port_vobj_ref[cp_port_index]->vobj_name, str, 31);
+    }
+    else
+    {
+        printf("[XML ERROR] missing <vobjname> for cp_port %d in cluster %d\n",
+               cp_port_index, cluster_index);
+        exit(1);
+    }
+    
+    cp_port_index++;
+    cp_port_loc_index++;
+
+} // end cpPortNode()
+
+///////////////////////////////////////////
+void periphNode ( xmlTextReaderPtr reader )
+///////////////////////////////////////////
+{
+    char*           str;
+    unsigned int    value;
+    unsigned int 	ok;
+
+    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
+
+    if ( periph_index >= MAX_PERIPHS )
+    {
+        printf("[XML ERROR] The number of periphs is larger than %d\n", MAX_PERIPHS);
+    }
+
+#if XML_PARSER_DEBUG
+printf("\n  periph %d\n", periph_index);
+#endif
+
+    periph[periph_index] = (mapping_periph_t*)malloc(sizeof(mapping_periph_t));
+
+
+    ///////// get channels attribute (optionnal : 1 if missing)
+    value = getIntValue( reader, "channels", &ok );
+    if ( ok )
+    {
+#if XML_PARSER_DEBUG
+printf("      channels = %d\n", value);
+#endif
+        periph[periph_index]->channels = value;
+    }
+    else
+    {
+        periph[periph_index]->channels = 1;
+    }
+
+    /////////// get psegname attribute 
+    str = getStringValue(reader,"psegname", &ok);
+    if ( ok == 0 )
+    {
+        printf("[XML ERROR] illegal or missing <psegname> for coproc %d in cluster %d\n", 
+                 coproc_index, cluster_index);
+        exit(1);
+    }
+
+    /////////// set psegid attribute
+    int index = getPsegId( cluster_index, str );
+    if ( index >= 0 ) 
+    {
+#if XML_PARSER_DEBUG
+printf("      clusterid = %d\n", cluster_index);
+printf("      psegname  = %s\n", str);
+printf("      psegid    = %d\n", index);
+#endif
+        periph[periph_index]->psegid = index;
+        assert(pseg[index]->type == PSEG_TYPE_PERI && 
+        "peripheral psegname attribute must refer to a pseg of type PERI" );
+    }
+    else              
+    {
+        printf("[XML ERROR] pseg not found for periph %d / clusterid = %d / psegname = %s\n", 
+                   periph_loc_index, cluster_index, str );
+        exit(1);
+    }  
+
+
+    /////////// get type attribute 
+    str = getStringValue( reader, "type", &ok );
+    if ( ok ) 
+    {
+#if XML_PARSER_DEBUG
+printf("      type     = %s\n", str);
+#endif
+        unsigned int error = 0;
+  
+        // The TTY, IOC, NIC, FBF and IOB peripherals cannot be replicated
+        // one per architecture
+        if      ( strcmp( str, "IOC" ) == 0 ) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_IOC;
+            if ( header->ioc_clusterid == 0xFFFFFFFF) header->ioc_clusterid = cluster_index;
+            else  error = 1;
+
+            ioc_base_offset = pseg[ periph[periph_index]->psegid ]->base;
+            nb_ioc_channel = periph[periph_index]->channels;
+        } 
+        else if ( strcmp( str, "TTY" ) == 0 )
+        {
+            periph[periph_index]->type = PERIPH_TYPE_TTY;
+            if ( header->tty_clusterid == 0xFFFFFFFF) header->tty_clusterid = cluster_index;
+            else  error = 1;
+
+            tty_base_offset = pseg[ periph[periph_index]->psegid ]->base;
+            nb_tty_channel = periph[periph_index]->channels;
+        }
+        else if ( strcmp( str, "FBF" ) == 0 ) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_FBF;
+            if ( header->fbf_clusterid == 0xFFFFFFFF) header->fbf_clusterid = cluster_index;
+            else  error = 1;
+
+            fbf_base_offset = pseg[ periph[periph_index]->psegid ]->base;
+        }
+        else if ( strcmp( str, "NIC" ) == 0 ) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_NIC;
+            if ( header->nic_clusterid == 0xFFFFFFFF) header->nic_clusterid = cluster_index;
+            else  error = 1;
+
+            //nic_base_offset = pseg[ periph[periph_index]->psegid ]->base;
+            nb_nic_channel = periph[periph_index]->channels;
+        }
+        else if ( strcmp( str, "IOB" ) == 0 ) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_IOB;
+            iob_base_offset = pseg[ periph[periph_index]->psegid ]->base;
+
+            if(io_mmu_active) error = 1;
+            io_mmu_active = 1;
+        }
+        // The TIM, ICU, XICU, DMA and IOB peripherals can be replicated in several clusters
+        // one per cluster
+        else if ( strcmp( str, "TIM" ) == 0 ) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_TIM;
+            if(found_timer) error = 1;
+            found_timer = 1;
+
+            if(tim_base_offset == 0xFFFFFFFF)
+                tim_base_offset = pseg[ periph[periph_index]->psegid ]->base;
+
+            if(nb_timer_channel_max < periph[periph_index]->channels)
+                nb_timer_channel_max = periph[periph_index]->channels;
+        }
+        else if ( strcmp( str, "ICU" ) == 0 ) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_ICU;
+            if(found_icu) error = 1;
+            found_icu = 1;
+
+            if(icu_base_offset == 0xFFFFFFFF)
+                icu_base_offset = pseg[ periph[periph_index]->psegid ]->base;
+        }
+        else if ( strcmp( str, "XICU" ) == 0 ) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_XICU;
+            if(found_xicu) error = 1;
+            found_xicu = 1;
+
+            //'icu' since we can't have both xicu and icu in an arch
+            if(icu_base_offset == 0xFFFFFFFF)
+                icu_base_offset = pseg[ periph[periph_index]->psegid ]->base;
+        }
+        else if ( strcmp( str, "DMA" ) == 0 ) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_DMA;
+            if(found_dma) error = 1;
+            found_dma = 1;
+
+            if(dma_base_offset == 0xFFFFFFFF)
+                dma_base_offset = pseg[ periph[periph_index]->psegid ]->base;
+            if(nb_dma_channel_max < periph[periph_index]->channels)
+                nb_dma_channel_max = periph[periph_index]->channels;
+        }
+        else
+        {
+            printf("[XML ERROR] illegal <type> for peripheral %d in cluster %d\n",
+                   periph_loc_index, cluster_index);
+            exit(1);
+        }
+
+        if(error)
+        {
+            printf("[XML ERROR] illegal <type> for peripheral %d in cluster %d\n",
+                   periph_loc_index, cluster_index);
+            exit(1);
+        }
+    }
+    else
+    {
+        printf("[XML ERROR] missing <type> for peripheral  %d in cluster %d\n",
+               periph_loc_index, cluster_index);
+        exit(1);
+    }
+
+    
+    periph_index++;
+    periph_loc_index++;
+    cluster[cluster_index]->periphs++;
+
+} // end periphNode
+
+/////////////////////////////////////////
+void coprocNode ( xmlTextReaderPtr reader )
+/////////////////////////////////////////
+{
+    char*           str;
+    unsigned int 	ok;
+
+    cp_port_loc_index = 0;
+
+    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
+
+    if ( coproc_index >= MAX_COPROCS )
+    {
+        printf("[XML ERROR] The number of coprocs is larger than %d\n", MAX_COPROCS);
+    }
+
+#if XML_PARSER_DEBUG
+printf("\n  coproc %d\n", coproc_index);
+#endif
+
+    coproc[coproc_index] = (mapping_coproc_t*)malloc(sizeof(mapping_coproc_t));
+
+    /////////// get name attribute 
+    str = getStringValue( reader, "name", &ok );
+    if ( ok ) 
+    {
+#if XML_PARSER_DEBUG
+printf("      name = %s\n", str);
+#endif
+        strncpy(coproc[coproc_index]->name, str, 31);
+    }
+    else
+    {
+        printf("[XML ERROR] illegal or missing <name> for coproc %d in cluster %d\n",
+               coproc_index, cluster_index);
+        exit(1);
+    }
+
+    /////////// get psegname attribute 
+    str = getStringValue(reader,"psegname", &ok);
+    if ( ok == 0 )
+    {
+        printf("[XML ERROR] illegal or missing <psegname> for coproc %d in cluster %d\n", 
+                 coproc_index, cluster_index);
+        exit(1);
+    }
+
+    /////////// set psegid attribute
+    int index = getPsegId( cluster_index, str );
+    if ( index >= 0 ) 
+    {
+#if XML_PARSER_DEBUG
+printf("      clusterid = %d\n", cluster_index);
+printf("      psegname  = %s\n", str);
+printf("      psegid    = %d\n", index);
+#endif
+        coproc[coproc_index]->psegid = index;
+        assert(pseg[index]->type == PSEG_TYPE_PERI && "coproc psegname attribute must refer to a pseg of type PERI" );
+    }
+    else              
+    {
+        printf("[XML ERROR] pseg not found for coproc %d / clusterid = %d / psegname = %s\n", 
+                   coproc_index, cluster_index, str );
+        exit(1);
+    }  
+
+    ////////// set port_offset 
+    coproc[coproc_index]->port_offset = cp_port_index;
+
+#if XML_PARSER_DEBUG
+printf("      port_offset = %d\n", cp_port_index);
+#endif
+
+    int status = xmlTextReaderRead(reader);
+    while ( status == 1 ) 
+    {
+        const char* tag = (const char*)xmlTextReaderConstName(reader);
+
+        if      ( strcmp(tag, "port")     == 0 ) cpPortNode(reader);
+        else if ( strcmp(tag, "#text")    == 0 ) { }
+        else if ( strcmp(tag, "#comment") == 0 ) { }
+        else if ( strcmp(tag, "coproc")   == 0 ) 
+        {
+            coproc[coproc_index]->ports = cp_port_loc_index;
+            cluster[cluster_index]->coprocs++;
+            coproc_loc_index++;
+            coproc_index++;
+            return;
+        }
+        else 
+        {
+            printf("[XML ERROR] Unknown tag %s",tag);
+            exit(1);
+        }
+        status = xmlTextReaderRead ( reader );
+    }
+} // end coprocNode()
+
+///////////////////////////////////////
+void irqNode( xmlTextReaderPtr reader )
+///////////////////////////////////////
+{
+    unsigned int 	ok;
+    unsigned int 	value;
+    char*    		str;
+
+    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
+
+    if ( irq_index >= MAX_IRQS )
+    {
+        printf("[XML ERROR] The number of irqs is larger than %d\n", MAX_IRQS);
+    }
+
+#if XML_PARSER_DEBUG
+printf("     irq %d\n", irq_loc_index);
+#endif
+
+    irq[irq_index] = (mapping_irq_t*)malloc(sizeof(mapping_irq_t));
+
+    ///////// get type attribute
+    str = getStringValue(reader,"type", &ok);
+    if ( ok )
+    {
+#if XML_PARSER_DEBUG
+printf("        type    = %s\n", str);
+#endif
+        if      ( strcmp(str, "HARD") == 0 ) irq[irq_index]->type = 0;
+        else if ( strcmp(str, "SOFT") == 0 ) irq[irq_index]->type = 1;
+        else
+        {
+            printf("[XML ERROR] undefined IRQ  <type> for processor %d in cluster %d\n",
+                   cluster_index, proc_loc_index );
+            exit(1);
+        }
+    }  
+    else
+    {
+        printf("[XML ERROR] missing IRQ <type> for processor %d in cluster %d\n",
+               cluster_index, proc_loc_index );
+        exit(1);
+    }
+
+    ///////// get icuid attribute
+    value = getIntValue(reader, "icuid", &ok);
+    if ( ok )
+    {
+#if XML_PARSER_DEBUG
+printf("        icuid   = %d\n", value);
+#endif
+        irq[irq_index]->icuid = value;
+        if ( value >= 32 )
+        {
+            printf("[XML ERROR] IRQ <icuid> too large for processor %d in cluster %d\n",
+                   cluster_index, proc_loc_index );
+            exit(1);
+        }
+    }
+    else
+    {
+        printf("[XML ERROR] missing IRQ <icuid> for processor %d in cluster %d\n",
+               cluster_index, proc_loc_index );
+        exit(1);
+    }
+
+    ///////// get isr attribute
+    str = getStringValue(reader,"isr", &ok);
+    if ( ok )
+    {
+#if XML_PARSER_DEBUG
+printf("        isr     = %s\n", str);
+#endif
+        if      ( strcmp(str, "ISR_SWITCH" ) == 0 ) irq[irq_index]->isr = ISR_SWITCH;
+        else if ( strcmp(str, "ISR_IOC"    ) == 0 ) irq[irq_index]->isr = ISR_IOC;
+        else if ( strcmp(str, "ISR_DMA"    ) == 0 ) irq[irq_index]->isr = ISR_DMA;
+        else if ( strcmp(str, "ISR_TTY"    ) == 0 ) irq[irq_index]->isr = ISR_TTY;
+        else if ( strcmp(str, "ISR_TIMER"  ) == 0 ) irq[irq_index]->isr = ISR_TIMER;
+        else
+        {
+            printf("[XML ERROR] illegal IRQ <isr> for processor %d in cluster %d\n",
+                   cluster_index, proc_loc_index );
+            exit(1);
+        }
+#if XML_PARSER_DEBUG
+printf("        isrnum  = %d\n", irq[irq_index]->isr);
+#endif
+    }  
+    else
+    {
+        printf("[XML ERROR] missing IRQ <isr> for processor %d in cluster %d\n",
+               cluster_index, proc_loc_index );
+        exit(1);
+    }
+
+    ///////// get channel attribute (optionnal : 0 if missing)
+    value = getIntValue(reader, "channel", &ok);
+    if ( ok )
+    {
+#if XML_PARSER_DEBUG
+printf("        channel = %d\n", value);
+#endif
+        irq[irq_index]->channel = value;
+    }
+    else
+    {
+        irq[irq_index]->channel = 0;
+    }
+
+    irq_index++;
+    irq_loc_index++;
+
+} // end irqNode
+
+/////////////////////////////////////////
+void procNode ( xmlTextReaderPtr reader )
+/////////////////////////////////////////
+{
+    unsigned int 	ok;
+    unsigned int    value;
+
+    irq_loc_index = 0;
+
+    if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
+
+    if ( proc_index >= MAX_PROCS )
+    {
+        printf("[XML ERROR] The number of procs is larger than %d\n", MAX_PROCS);
+    }
+
+#if XML_PARSER_DEBUG
+printf("\n  proc %d\n", proc_index);
+#endif
+
+    proc[proc_index] = (mapping_proc_t*)malloc(sizeof(mapping_proc_t));
+
+
+    /////////// get index attribute (optional)
+    value = getIntValue(reader,"index",&ok);
+    if ( ok && (value != proc_loc_index) )
+    {
+            printf("[XML ERROR] wrong proc index / expected value is %d", 
+                proc_loc_index);
+            exit(1);
+    }
+
+    ////////// set irq_offset attribute
+    proc[proc_index]->irq_offset = irq_index;
+
+#if XML_PARSER_DEBUG
+printf("    irq_offset = %d\n", irq_index);
+#endif
+
+    int status = xmlTextReaderRead(reader);
+    while ( status == 1 ) 
+    {
+        const char* tag = (const char*)xmlTextReaderConstName(reader);
+
+        if      ( strcmp(tag, "irq")      == 0 ) irqNode(reader);
+        else if ( strcmp(tag, "#text")    == 0 ) { }
+        else if ( strcmp(tag, "#comment") == 0 ) { }
+        else if ( strcmp(tag, "proc")     == 0 ) 
+        {
+            proc[proc_index]->irqs = irq_loc_index;
+            cluster[cluster_index]->procs++;
+            proc_loc_index++;
+            proc_index++;
+            return;
+        }
+        else 
+        {
+            printf("[XML ERROR] Unknown tag %s",tag);
+            exit(1);
+        }
+        status = xmlTextReaderRead ( reader );
+    }
+} // end procNode()
+
+
 //////////////////////////////////////////
 void  psegNode ( xmlTextReaderPtr reader )
@@ -1420,8 +1545,27 @@
     unsigned int value;
 
+    cluster[cluster_index] = (mapping_cluster_t*)malloc(sizeof(mapping_cluster_t));
+    
+    //initialise all variables
+    //they will be incremented by *Node() functions
+    //FIXME: calloc?
+    cluster[cluster_index]->psegs = 0;
+    cluster[cluster_index]->procs = 0;
+    cluster[cluster_index]->coprocs = 0;
+    cluster[cluster_index]->periphs = 0;
+
+
+    //initialise global variables
+    //TODO: delete those three
     proc_loc_index = 0;
     coproc_loc_index = 0;
     periph_loc_index = 0;
 
+    // for replicated periph
+    found_timer = 0;
+    found_icu = 0;
+    found_xicu = 0;
+    found_dma = 0;
+
     if ( xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT ) return;
 
@@ -1437,9 +1581,4 @@
 #endif
 
-    cluster[cluster_index] = (mapping_cluster_t*)malloc(sizeof(mapping_cluster_t));
-    
-    //initialise the number of pseg 
-    //it will be incremented by PsegNode
-    cluster[cluster_index]->psegs = 0;
 
     /////////// check cluster index attribute (optional)
@@ -1480,10 +1619,36 @@
         else if ( strcmp(tag, "cluster")  == 0 ) 
         {
-            cluster[cluster_index]->procs   = proc_loc_index;
-            cluster[cluster_index]->coprocs = coproc_loc_index;
-            cluster[cluster_index]->periphs = periph_loc_index;
-
-            // cluster[cluster_index]psegs update is done in psegNode(),
-            // because the coprocNode() call to getPsegId() need it
+
+            if(use_xicu == 0xFFFFFFFF)
+                use_xicu = found_xicu;
+
+            ////////////////// peripherals checks ////////////////////
+            if( (found_timer  && use_xicu) || (!found_timer  && !use_xicu) )
+            {
+                printf("[XML ERROR] illegal or missing timer peripheral in cluster %d\n", cluster_index);
+                exit(1);
+            }
+
+            if( (found_icu  && use_xicu) || (!found_icu  && !use_xicu) )
+            {
+                printf("[XML ERROR] illegal or missing icu peripheral in cluster %d\n", cluster_index);
+                exit(1);
+            }
+
+            if( !found_xicu && use_xicu)
+            {
+                printf("[XML ERROR] illegal or missing dma peripheral in cluster %d\n", cluster_index);
+                exit(1);
+            }
+
+            if(!found_dma)
+            {
+                printf("[XML ERROR] illegal or missing dma peripheral in cluster %d\n", cluster_index);
+                exit(1);
+            }
+
+               
+            if(nb_proc_max < cluster[cluster_index]->procs)
+                nb_proc_max = cluster[cluster_index]->procs;
 
 #if XML_PARSER_DEBUG
@@ -1492,5 +1657,5 @@
 printf("    coprocs = %d\n", cluster[cluster_index]->coprocs);
 printf("    periphs = %d\n", cluster[cluster_index]->periphs);
-printf("  end cluster %d\n", cluster_index);
+printf("    end cluster %d\n", cluster_index);
 #endif
             cluster_index++;
@@ -1527,16 +1692,20 @@
                 exit(1);
             }
-            else
+
+            if(header->tty_clusterid == 0xFFFFFFFF)
             {
+                printf("[XML ERROR] illegal or missing tty peripheral");
+                exit(1);
+            }
+
 #if XML_PARSER_DEBUG
 printf("  end cluster set\n\n");
 #endif
-                header->psegs    = pseg_index;
-                header->procs    = proc_index;
-                header->irqs     = irq_index;
-                header->coprocs  = coproc_index;
-                header->cp_ports = cp_port_index;
-                return;
-            }
+            header->psegs    = pseg_index;
+            header->procs    = proc_index;
+            header->irqs     = irq_index;
+            header->coprocs  = coproc_index;
+            header->cp_ports = cp_port_index;
+            return;
         }
         else 
@@ -1659,23 +1828,47 @@
     }
 
-    /////////// get clusters attribute
-    value = getIntValue(reader, "clusters", &ok);
-    if ( ok )
-    {
-        if ( value >= MAX_CLUSTERS )
-        {
-            printf("[XML ERROR] The number of clusters is larger than %d\n", MAX_CLUSTERS);
-            exit(1);
-        }
+    /////////// 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");
+        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
-	header->clusters  = value;
-    }
-    else
-    {
-        printf("[XML ERROR] illegal or missing <clusters> attribute in header\n");
-        exit(1);
-    }
 
     ///////// get vspaces attribute
@@ -1743,38 +1936,55 @@
 {
     unsigned int i;
-    unsigned int length;
     // write element
     for ( i = 0 ; i < nb_elem ; i++ )
     {
-        length = write(fdout, table[i], elem_size);
-    
+        if(elem_size != write(fdout, table[i], elem_size))
+        {
+            printf("function %s: %s(%d) write  error \n", __FUNCTION__, type, i);
+            exit(1);
+        }
+
 #if XML_PARSER_DEBUG
 printf("Building binary: writing %s %d\n", type, i);
 #endif
-
-        if ( length != elem_size )
-        {
-            printf("type: %s\n", type);
-            perror("error writing");
-            exit(1);
-        }
     }
 }
 
+int open_file(const char* file_path)
+{
+
+    //open file
+    int fdout = open( file_path, (O_CREAT | O_RDWR), (S_IWUSR | S_IRUSR) );
+    if ( fdout < 0)
+    {
+        perror("open");
+        exit(1);
+    }
+
+    //reinitialise the file
+    if( ftruncate(fdout, 0) )
+    {
+        perror("truncate");
+        exit(1);
+    }
+
+//#if XML_PARSER_DEBUG
+    printf("%s\n",file_path);
+//#endif
+
+    return fdout;
+}
+
+
 ///////////////////////////
-void  buildBin( int fdout )
+void  buildBin( const char* file_path )
 ///////////////////////////
 {
-    unsigned int    vspace_id;
-    unsigned int    vobj_id;
     unsigned int    length;
+
+    int fdout = open_file(file_path);
 
     // write header to binary file
     length = write(fdout, (char*)header, sizeof(mapping_header_t));
-    
-#if XML_PARSER_DEBUG
-printf("\n*** write header\n");
-#endif
-
     if ( length != sizeof(mapping_header_t) )
     {
@@ -1785,49 +1995,12 @@
     // write clusters
     BuildTable(fdout, "cluster", cluster_index, sizeof(mapping_cluster_t), (char**) cluster);
-
     // write psegs
     BuildTable(fdout, "pseg", pseg_index, sizeof(mapping_pseg_t), (char**) pseg);
-
     // write vspaces
-    for ( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
-    {
-        length = write(fdout, (char*)vspace[vspace_id], sizeof(mapping_vspace_t));
-    
-#if XML_PARSER_DEBUG
-printf("write vspace %d\n", vspace_id);
-printf("vspace->vobj_offset: %d\n", vspace[vspace_id]->vobj_offset);
-printf("vspace->vobjs: %d\n", vspace[vspace_id]->vobjs);
-printf("header->vobjs: %d\n", header->vobjs);
-#endif
-
-        if ( length != sizeof(mapping_vspace_t) )
-        {
-            perror("write vspace");
-            exit(1);
-        }
-    }
-
+    BuildTable(fdout, "vspace", vspace_index, sizeof(mapping_vspace_t), (char**) vspace);
     // write vsegs
     BuildTable(fdout, "vseg", vseg_index, sizeof(mapping_vseg_t), (char**) vseg);
-    
     // write vobjs
-    for ( vobj_id = 0 ; vobj_id < header->vobjs ; vobj_id++ )
-    {
-        length = write(fdout, (char*)vobj[vobj_id], sizeof(mapping_vobj_t));
-    
-#if XML_PARSER_DEBUG
-printf("write vobj %d\n", vobj_id);
-printf("write vobj name %s\n", vobj[vobj_id]->name);
-printf("write vobj length %x\n", vobj[vobj_id]->length);
-printf("write vobj type %d\n", vobj[vobj_id]->type);
-#endif
-
-        if ( length != sizeof(mapping_vobj_t) )
-        {
-            perror("write vobj");
-            exit(1);
-        }
-    }
-
+    BuildTable(fdout, "vobj", vobj_index, sizeof(mapping_vobj_t), (char**) vobj);
     // write tasks array
     BuildTable(fdout, "task", task_index, sizeof(mapping_task_t), (char**) task);
@@ -1842,4 +2015,6 @@
     //building periphs array
     BuildTable(fdout, "periph", periph_index, sizeof(mapping_periph_t), (char**)periph);
+    
+    close(fdout);
 
 } // end buildBin()
@@ -1889,4 +2064,110 @@
 }
 
+
+void file_write(int fdout, char* towrite)
+{
+    unsigned int size = strlen(towrite);
+    if(size != write(fdout, towrite, size))
+    {
+        printf("file_write error");
+        exit(1);
+    }
+}
+
+void def_int_write(int fdout, char* def, int num)
+{
+    char  buf[64];
+    sprintf(buf, "#define\t %s  %d\n", def, num);
+    file_write(fdout, buf);
+
+}
+
+void def_hex_write(int fdout, char* def, int num)
+{
+    char  buf[64];
+    sprintf(buf, "#define\t %s  0x%x\n", def, num);
+    file_write(fdout, buf);
+}
+
+///////////////////////////
+void  genHd( const char* file_path )
+///////////////////////////
+{
+    int fdout = open_file(file_path);
+
+    char* prol = " /* AUTO GENRATED FILE */\n\n#ifndef _HD_CONFIG_H\n#define _HD_CONFIG_H\n\n";
+    file_write(fdout, prol);
+
+    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_hex_write(fdout, "CLUSTER_SIZE"    , ( ((unsigned long)1) << 32)/cluster_index);
+    def_int_write(fdout, "NB_PROCS_MAX"     , nb_proc_max);
+    def_int_write(fdout, "NB_TIMERS_MAX"   , nb_timer_channel_max);
+    def_int_write(fdout, "NB_DMAS_MAX"     , nb_dma_channel_max);
+    def_int_write(fdout, "NB_TTYS"         , nb_tty_channel);
+    def_int_write(fdout, "NB_IOCS"         , nb_ioc_channel);
+    def_int_write(fdout, "NB_NICS"         , nb_nic_channel);
+    
+    file_write(fdout, "\n");
+    def_int_write(fdout, "USE_XICU"         , use_xicu);
+    def_int_write(fdout, "IOMMU_ACTIVE "    , io_mmu_active);
+
+    char* epil = "\n#endif //_HD_CONFIG_H";
+    file_write(fdout, epil);
+
+    close(fdout);
+}
+
+void ld_write(int fdout, char* seg, unsigned int addr)
+{
+    char  buf[64];
+    sprintf(buf, "%s = 0x%x;\n", seg, addr);
+    file_write(fdout, buf);
+
+}
+
+///////////////////////////
+void  genLd( const char* file_path )
+///////////////////////////
+{
+    int fdout = open_file(file_path);
+
+    char* prol = "/* AUTO GENRATED FILE */\n\n";
+    file_write(fdout, prol);
+
+    //boot
+    ld_write(fdout, "seg_boot_code_base"           , boot_code_base);
+    ld_write(fdout, "seg_boot_stack_base"          , boot_stack_base);
+    ld_write(fdout, "seg_mapping_base"        , boot_mapping_base );
+
+    //kernel
+    ld_write(fdout, "\nseg_kernel_code_base"         , kernel_code_base);
+    ld_write(fdout, "seg_kernel_data_base"         , kernel_data_base);
+    ld_write(fdout, "seg_kernel_uncdata_base"      , kernel_uncdata_base);
+    ld_write(fdout, "seg_kernel_init_base"         , kernel_init_base);
+
+    //peripherals
+    ld_write(fdout, "\nseg_fbf_base" ,  fbf_base_offset);
+    ld_write(fdout, "seg_icu_base" ,  icu_base_offset);
+    ld_write(fdout, "seg_ioc_base" ,  ioc_base_offset);
+    ld_write(fdout, "seg_tty_base" ,  tty_base_offset);
+    ld_write(fdout, "seg_dma_base" ,  dma_base_offset);
+    ld_write(fdout, "seg_tim_base" ,  tim_base_offset);
+    ld_write(fdout, "seg_gcd_base" ,  gcd_base_offset);
+    ld_write(fdout, "seg_iob_base" ,  iob_base_offset);
+
+    close(fdout);
+}
+
+char* buildPath(const char* path, const char*name)
+{
+    char *res = calloc(strlen(path) + strlen(name) + 1, 1);
+    strcat(res, path);
+    strcat(res, "/");
+    strcat(res, name);
+    return res; 
+}
+
 /////////////////////////////////////
 int  main ( int argc, char* argv[] )
@@ -1895,15 +2176,26 @@
     if ( argc < 3 ) 
     {
-        printf("Usage: xml2bin <input_file_path> <output_file_path>\n");
+        printf("Usage: xml2bin <input_file_path> <output_path>\n");
         return 1;
     }
 
-    int fdout = open( argv[2], (O_CREAT | O_RDWR), S_IRWXU );
-    if ( fdout < 0)
-    {
-        perror("open");
-        exit(1);
-    }
+    struct stat dir_st;
+    if(stat( argv[2], &dir_st ))
+    {
+        perror("bad path");
+        exit(1);
+    }
+
+    if((dir_st.st_mode & S_IFDIR) == 0)
+    {
+        printf("path is not a dir: %s", argv[2] );
+        exit(1);
+    }
+
     
+    char *map_path = buildPath(argv[2], "map.bin"); 
+    char *ld_path = buildPath(argv[2],  "giet_vsegs.ld"); 
+    char *hd_path = buildPath(argv[2],  "hard_config.h"); 
+
     LIBXML_TEST_VERSION;
 
@@ -1922,5 +2214,7 @@
                 headerNode( reader );
                 prepareBuild();
-                buildBin( fdout );
+                buildBin( map_path );
+                genHd(hd_path);
+                genLd(ld_path);
             }
             else
