Index: soft/giet_vm/Makefile
===================================================================
--- soft/giet_vm/Makefile	(revision 202)
+++ soft/giet_vm/Makefile	(revision 203)
@@ -57,7 +57,7 @@
 
 ### mapping compilation
-map.bin: map.xml
+map.bin: 1c_4p_four.xml
 	$(MAKE) -C xml
-	xml/xml2bin map.xml map.bin
+	xml/xml2bin $< $@
 
 ### system compilation
Index: soft/giet_vm/boot/boot.ld
===================================================================
--- soft/giet_vm/boot/boot.ld	(revision 202)
+++ soft/giet_vm/boot/boot.ld	(revision 203)
@@ -1,42 +1,17 @@
-/****************************************************************************
-* Definition of the base address for all virtual segments
-*****************************************************************************/
 
-/* 
-The following (virtual) addresses are specific for the boot phase.
-They must respect identity mapping: physical address = virtual address 
-*/
+/****************************************************************************/
+/* Definition of the base addresses for all vsegs used by the GIET_VM       */
+/****************************************************************************/
 
-seg_boot_base         	= 0xBFC00000;	/* boot code */
+INCLUDE giet_vsegs.ld
 
-seg_boot_stack_base     = 0xBFC08000;	/* boot temporary stack */ 
-
-seg_mapping_base      	= 0xBFC0C000;	/* boot mapping_info */
-
-/* 
-The following (virtual) addresse are defined and used by the kernel.
-They are not constrained to respect identity mapping.  
-*/
-
-seg_kernel_init_base    = 0x80090000;	/* system init entry */ 
-
-seg_tty_base      	    = 0x90000000;   /* TTY device */
-seg_timer_base    	    = 0x91000000;   /* Timer device */
-seg_ioc_base      	    = 0x92000000;   /* Block device */
-seg_dma_base      	    = 0x93000000;   /* DMA device */
-seg_gcd_base      	    = 0x95000000;   /* GCD device */
-seg_fb_base       	    = 0x96000000;   /* FrameBuffer device */
-seg_iob_base      	    = 0x9E000000;   /* IO Bridge device */
-seg_icu_base      	    = 0x9F000000;   /* ICU or XICU device */
-
-/*
-Grouping sections into segments for boot code and data
-*/
+/****************************************************************************/
+/* Grouping sections into virtual segment for boot code and data             */
+/****************************************************************************/
 
 SECTIONS
 {
-    /* contain both data and code sections */
-    . = seg_boot_base;
-    seg_boot : 
+    . = seg_boot_code_base;
+    seg_boot_code : 
     {
         *(.boot)
@@ -55,2 +30,3 @@
     }
 }
+
Index: soft/giet_vm/boot/boot_init.c
===================================================================
--- soft/giet_vm/boot/boot_init.c	(revision 202)
+++ soft/giet_vm/boot/boot_init.c	(revision 203)
@@ -800,5 +800,5 @@
     }
 
-    // checking Rnumber of clusters
+    // checking number of clusters
     if ( header->clusters != NB_CLUSTERS )
     {
@@ -820,5 +820,5 @@
     }
 
-    // checking harware
+    // checking hardware
     unsigned int periph_id;
     unsigned int cluster_id;
@@ -851,7 +851,7 @@
                     boot_exit();
                 }
-                if ( periph[periph_id].channels > NB_TTYS )
-                {
-                    boot_puts("\n[BOOT ERROR] Too much TTY terminals in cluster ");
+                if ( periph[periph_id].channels != NB_TTYS )
+                {
+                    boot_puts("\n[BOOT ERROR] Wrong NB_TTYS in cluster ");
                     boot_putw( cluster_id );
                     boot_puts(" : ttys = ");
@@ -870,7 +870,7 @@
                     boot_exit();
                 }
-                if ( periph[periph_id].channels > NB_NICS )
-                {
-                    boot_puts("\n[BOOT ERROR] Too much NIC channels in cluster ");
+                if ( periph[periph_id].channels != NB_NICS )
+                {
+                    boot_puts("\n[BOOT ERROR] Wrong NB_NICS in cluster ");
                     boot_putw( cluster_id );
                     boot_puts(" : nics = ");
@@ -884,5 +884,5 @@
             if ( periph[periph_id].type == PERIPH_TYPE_TIM ) 
             {
-                if ( periph[periph_id].channels > NB_TIMERS_MAX )
+                if ( periph[periph_id].channels != (NB_PROCS_MAX + NB_TIMERS_MAX) )
                 {
                     boot_puts("\n[BOOT ERROR] Too much user timers in cluster ");
@@ -897,5 +897,5 @@
             if ( periph[periph_id].type == PERIPH_TYPE_DMA ) 
             {
-                if ( periph[periph_id].channels > NB_DMAS_MAX )
+                if ( periph[periph_id].channels != NB_DMAS_MAX )
                 {
                     boot_puts("\n[BOOT ERROR] Too much DMA channels in cluster ");
@@ -1198,7 +1198,5 @@
 ////////////////////////////////////////////////////////////////////////////////
 // This function intializes the periherals and coprocessors, as specified
-// tsuch as the IOB component
-// (I/O bridge, containing the IOMMU, the IOC (external disk controller), 
-// the NIC (external network controller), the FBDMA (frame buffer controller), 
+// in the mapping_info file.
 ////////////////////////////////////////////////////////////////////////////////
 void boot_peripherals_init()
@@ -1306,5 +1304,5 @@
 
         } // end for periphs
-
+/*
         for ( coproc_id = cluster[cluster_id].coproc_offset ;
               coproc_id < cluster[cluster_id].coproc_offset + cluster[cluster_id].coprocs ;
@@ -1358,5 +1356,5 @@
             }
         } // end for coprocs
-
+*/
     } // end for clusters
 } // end boot_peripherals_init()
Index: soft/giet_vm/giet_config.h
===================================================================
--- soft/giet_vm/giet_config.h	(revision 202)
+++ soft/giet_vm/giet_config.h	(revision 203)
@@ -17,5 +17,5 @@
 #define BOOT_DEBUG_SCHED 	0		/* display schedulers initialisation on TTY0 */
 
-#define GIET_DEBUG_INIT		1		/* display parallel kernel initialisation on TTY0 */
+#define GIET_DEBUG_INIT		0		/* display parallel kernel initialisation on TTY0 */
 #define GIET_DEBUG_SWITCH	0	    /* display context switchs on TTY0 */
 
@@ -39,5 +39,5 @@
 #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       0		/* Use the XICU interrupt controler */
+#define GIET_USE_XICU       1		/* Use the XICU interrupt controler */
 
 #endif
Index: soft/giet_vm/libs/stdio.c
===================================================================
--- soft/giet_vm/libs/stdio.c	(revision 202)
+++ soft/giet_vm/libs/stdio.c	(revision 203)
@@ -5,5 +5,5 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The stdio.c and stdio.h files are part of the GIET nano-kernel.
+// The stdio.c and stdio.h files are part of the GIET_VM nano-kernel.
 // This library contains all user-level functions that contain a system call
 // to access protected or shared ressources.
@@ -17,4 +17,6 @@
 #define SYSCALL_TTY_WRITE       0x02
 #define SYSCALL_TTY_READ        0x03
+#define SYSCALL_TIMER_START     0x04
+#define SYSCALL_TIMER_STOP      0x05
 #define SYSCALL_GCD_WRITE       0x06
 #define SYSCALL_GCD_READ        0x07
@@ -461,4 +463,31 @@
 }
 
+
+/////  TIMER related system calls ////// 
+
+//////////////////////////////////////////////////////////////////////////////////
+// giet_timer_start()
+//////////////////////////////////////////////////////////////////////////////////
+// This function activates the private user timer allocated to the calling task
+// in the boot phase.
+// - Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////////
+unsigned int giet_timer_start()
+{
+    return sys_call(SYSCALL_TIMER_START,
+                   0,0,0,0);
+}
+//////////////////////////////////////////////////////////////////////////////////
+// giet_timer_stop()
+//////////////////////////////////////////////////////////////////////////////////
+// This function activates the user timer allocated to the calling task.
+// - Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////////
+unsigned int giet_timer_stop()
+{
+    return sys_call(SYSCALL_TIMER_STOP,
+                   0,0,0,0);
+}
+
 /////  GCD (Greatest Common Divider) related system calls
 
Index: soft/giet_vm/sys/common.h
===================================================================
--- soft/giet_vm/sys/common.h	(revision 202)
+++ soft/giet_vm/sys/common.h	(revision 203)
@@ -19,9 +19,9 @@
 extern _ld_symbol_t seg_iob_base;
 extern _ld_symbol_t seg_icu_base;
-extern _ld_symbol_t seg_timer_base;
+extern _ld_symbol_t seg_tim_base;
 extern _ld_symbol_t seg_tty_base;
 extern _ld_symbol_t seg_gcd_base;
 extern _ld_symbol_t seg_dma_base;
-extern _ld_symbol_t seg_fb_base;
+extern _ld_symbol_t seg_fbf_base;
 extern _ld_symbol_t seg_ioc_base;
 extern _ld_symbol_t seg_mapping_base;
Index: soft/giet_vm/sys/drivers.c
===================================================================
--- soft/giet_vm/sys/drivers.c	(revision 202)
+++ soft/giet_vm/sys/drivers.c	(revision 203)
@@ -11,5 +11,5 @@
 // - vci_multi_dma
 // - vci_multi_icu
-// - vci_xicu
+// - vci_xicu & vci_multi_icu
 // - vci_gcd
 // - vci_frame_buffer
@@ -23,11 +23,11 @@
 // - NB_TTYS    
 //
-// The following base addresses must be defined in the sys.ld file:
+// The following virtual base addresses must be defined in the sys.ld file:
 // - seg_icu_base
-// - seg_timer_base
+// - seg_tim_base
 // - seg_tty_base
 // - seg_gcd_base
 // - seg_dma_base
-// - seg_fb_base
+// - seg_fbf_base
 // - seg_ioc_base
 ///////////////////////////////////////////////////////////////////////////////////
@@ -93,19 +93,17 @@
 #define in_unckdata __attribute__((section (".unckdata")))
 
-
 //////////////////////////////////////////////////////////////////////////////
-// 	VciMultiTimer driver
+// 	Timers driver
 //////////////////////////////////////////////////////////////////////////////
-// There is one multi_timer (or xicu) component per cluster.
-// The global index is cluster_id*(NB_PROCS_MAX+NB_TIMERS_MAX) + local_id
+// The timers can be implemented in a vci_timer component or in a vci_xicu 
+// component (depending on the GIET_USE_XICU parameter).
+// There is one timer (or xicu) component per cluster.
 // There is two types of timers: 
 // - "system" timers : one per processor, used for context switch.
 //   local_id in [0, NB_PROCS_MAX-1],
 // - "user" timers : requested by the task in the mapping_info data structure.
-//   local_id in [NB_PROC_MAX, NB_PROCS_MAX+NB_TIMERS_MAX-1],
-//   For each user timer, the tty_id is stored in the context of the task
-//   and must be explicitely defined in the boot code.
-// These timers can be implemented in a vci_multi_timer component 
-// or in a vci_xicu component (depending on the GIET_USE_XICU parameter).
+//   local_id in [NB_PROC_MAX, NB_PROCS_MAX + NB_TIMERS_MAX - 1]
+//   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_TIMERS_MAX) + local_id
 //////////////////////////////////////////////////////////////////////////////
 
@@ -118,99 +116,90 @@
 
 //////////////////////////////////////////////////////////////////////////////
-//     _timer_access()
-// This function is the only way to access a timer device.
-// It can be a multi-timer component or an xicu component.
-// It can be used by the kernel to initialise a "system" timer,
+//     _timer_start()
+// This function activates a timer in the vci_timer (or vci_xicu) component
+// by writing in the proper register the period value.
+// It can be used by both the kernel to initialise a "system" timer,
 // or by a task (through a system call) to configure an "user" timer.
 // Returns 0 if success, > 0 if error.
 //////////////////////////////////////////////////////////////////////////////
-unsigned int _timer_access( unsigned int	read,
-                            unsigned int	cluster_id,
-                            unsigned int	local_id,
-                            unsigned int	register_id, 
-                            unsigned int*	buffer )
+unsigned int _timer_start( unsigned int	cluster_id,
+                           unsigned int	local_id,
+                           unsigned int	period )
 {
     // parameters checking 
-    if ( register_id >= TIMER_SPAN)					return 1;
     if ( cluster_id >= NB_CLUSTERS)					return 1;
     if ( local_id >= NB_TIMERS_MAX + NB_PROCS_MAX ) return 1;
 
 #if GIET_USE_XICU
-
-    unsigned int* timer_address = //TODO
-
+    unsigned int* timer_address = (unsigned int*)&seg_icu_base +
+                                  (cluster_id * CLUSTER_SPAN);
+
+    timer_address[XICU_REG(XICU_PTI_PER, local_id)] = period;
 #else
-
-    unsigned int* timer_address = (unsigned int*)&seg_timer_base + 
-                                  (cluster_id * CLUSTER_SPAN)  +
-                                  (local_id * TIMER_SPAN);
-#endif
-
-    if (read)	*buffer = timer_address[register_id]; // read word 
-    else		timer_address[register_id] = *buffer; // write word
+    unsigned int* timer_address = (unsigned int*)&seg_tim_base + 
+                                  (cluster_id * CLUSTER_SPAN);
+
+    timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
+    timer_address[local_id * TIMER_SPAN + TIMER_MODE]   = 0x3;
+#endif
+
     return 0;
 }
 //////////////////////////////////////////////////////////////////////////////
-//     _timer_write()
-// This function implements a write access to a "user" timer register.
-// It gets the cluster_id and local_id from the global index stored in
-// the task context and use the timer_access() function to make the write.
+//     _timer_stop()
+// This function desactivates a timer in the vci_timer (or vci_xicu) component
+// by writing in the proper register.
 // Returns 0 if success, > 0 if error.
 //////////////////////////////////////////////////////////////////////////////
-unsigned int _timer_write( unsigned int register_id, 
-                           unsigned int value )
-{
-    unsigned int buffer     = value;
-    unsigned int task_id    = _get_current_task_id();
-    unsigned int timer_id   = _get_context_slot(task_id, CTX_TIMER_ID);
-    unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX);
-    unsigned int local_id   = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX);
-
-    // checking user timer
-    if ( local_id < NB_PROCS_MAX ) 
-    {
-        return 2;
-    }
-    else
-    {
-        return _timer_access ( 0,				// write access
-                               cluster_id,
-                               local_id,
-                               register_id,
-                               &buffer );
-    }
+unsigned int _timer_stop( unsigned int	cluster_id,
+                          unsigned int	local_id )
+{
+    // parameters checking 
+    if ( cluster_id >= NB_CLUSTERS)					return 1;
+    if ( local_id >= NB_TIMERS_MAX + NB_PROCS_MAX ) return 1;
+
+#if GIET_USE_XICU
+    unsigned int* timer_address = (unsigned int*)&seg_icu_base +
+                                  (cluster_id * CLUSTER_SPAN);
+
+    timer_address[XICU_REG(XICU_PTI_PER, local_id)] = 0;
+#else
+    unsigned int* timer_address = (unsigned int*)&seg_tim_base + 
+                                  (cluster_id * CLUSTER_SPAN);
+
+    timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0;
+#endif
+
+    return 0;
 }
 //////////////////////////////////////////////////////////////////////////////
-//     _timer_read()
-// This function implements a read access to a "user" timer register.
-// It gets the cluster_id and local_id from the global index stored in
-// the task context and use the timer_access() function to make the read.
+//     _timer_reset_irq()
+// This function acknowlegge a timer interrupt in the vci_timer (or vci_xicu) 
+// component by writing in the proper register the period value.
+// It can be used by both the isr_switch() for a "system" timer, 
+// or by the _isr_timer() for an "user" timer.
 // Returns 0 if success, > 0 if error.
 //////////////////////////////////////////////////////////////////////////////
-unsigned int _timer_read( unsigned int  register_id, 
-                          unsigned int* buffer )
-{
-    unsigned int task_id    = _get_current_task_id();
-    unsigned int timer_id   = _get_context_slot(task_id, CTX_TIMER_ID);
-    unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX);
-    unsigned int local_id   = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX);
-
-    // checking user timer
-    if ( local_id < NB_PROCS_MAX ) 
-    {
-        return 2;
-    }
-    else
-    {
-        return _timer_access ( 1,				// read access
-                               cluster_id,
-                               local_id,
-                               register_id,
-                               buffer );
-    }
-}
-/////////////////////////////////////////////////////////////////////////////////
-//     _timer_check()
-/////////////////////////////////////////////////////////////////////////////////
+unsigned int _timer_reset_irq( unsigned int	cluster_id,
+                               unsigned int	local_id )
+{
+    // parameters checking 
+    if ( cluster_id >= NB_CLUSTERS)					return 1;
+    if ( local_id >= NB_TIMERS_MAX + NB_PROCS_MAX ) return 1;
+
+#if GIET_USE_XICU
+    unsigned int* timer_address = (unsigned int*)&seg_icu_base +
+                                  (cluster_id * CLUSTER_SPAN);
+
+    unsigned int bloup = timer_address[XICU_REG(XICU_PTI_ACK, local_id)];
+#else
+    unsigned int* timer_address = (unsigned int*)&seg_tim_base + 
+                                  (cluster_id * CLUSTER_SPAN);
+
+    timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0;
+#endif
+
+    return 0;
+}
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -349,66 +338,70 @@
 // 	VciMultiIcu and VciXicu drivers
 ////////////////////////////////////////////////////////////////////////////////
-// There is in principle one vci_multi_icu (or vci_xicu) component per cluster, 
-// and the number of independant ICUs is equal to NB_PROCS_MAX, because there is 
-// one private interrupr controler per processor.
-////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////
-//     _icu_write()
-// Write a 32-bit word in a memory mapped register of the MULTI_ICU device,
-// identified by the cluster index, and a processor local index.
-// Returns 0 if success, > 0 if error.
-////////////////////////////////////////////////////////////////////////////////
-unsigned int _icu_write( unsigned int cluster_index,
-                         unsigned int proc_index,
-                         unsigned int register_index, 
-                         unsigned int value )
-{
+// There is one vci_multi_icu (or vci_xicu) component per cluster, 
+// and the number of independant ICUs is equal to NB_PROCS_MAX, 
+// because there is one private interrupr controler per processor.
+////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////
+//     _icu_set_mask()
+// This function can be used with both the vci_xicu & vci_multi_icu components.
+// It set the mask register for the ICU channel identified by the cluster index 
+// and the processor index: all '1' bits are set / all '0' bits are not modified.
+// Returns 0 if success, > 0 if error.
+////////////////////////////////////////////////////////////////////////////////
+unsigned int _icu_set_mask( unsigned int cluster_id,
+                            unsigned int proc_id,
+                            unsigned int value,
+                            unsigned int is_timer )
+{
+    // parameters checking 
+    if ( cluster_id >= NB_CLUSTERS)		return 1;
+    if ( proc_id    >= NB_PROCS_MAX )   return 1;
+
+    unsigned int* icu_address = (unsigned int*)&seg_icu_base + 
+                                (cluster_id * CLUSTER_SPAN);
 #if GIET_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;
 #else
-
+    icu_address[proc_id * ICU_SPAN + ICU_MASK_SET] = value; 
+#endif
+
+    return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+//     _icu_get_index()
+// This function can be used with both the vci_xicu & vci_multi_icu components.
+// It returns the index of the highest priority (smaller index) active HWI.
+// The ICU channel is identified by the cluster index and the processor index.
+// Returns 0 if success, > 0 if error.
+////////////////////////////////////////////////////////////////////////////////
+unsigned int _icu_get_index(  unsigned int cluster_id,
+                              unsigned int proc_id,
+                              unsigned int* buffer )
+{
     // parameters checking 
-    if ( register_index >= ICU_SPAN) 		return 1;
-    if ( cluster_index >= NB_CLUSTERS)		return 1;
-    if ( proc_index >= NB_PROCS_MAX )       return 1;
-
-    unsigned int *icu_address = (unsigned int*)&seg_icu_base + 
-                                (cluster_index * CLUSTER_SPAN)  +
-                                (proc_index * ICU_SPAN);
-
-    icu_address[register_index] = value;   // write word 
+    if ( cluster_id >= NB_CLUSTERS)		return 1;
+    if ( proc_id    >= NB_PROCS_MAX )   return 1;
+
+    unsigned int* icu_address = (unsigned int*)&seg_icu_base + 
+                                (cluster_id * CLUSTER_SPAN);
+#if GIET_USE_XICU
+    unsigned int prio   = icu_address[XICU_REG(XICU_PRIO, proc_id)];
+    unsigned int pti_ok = (prio & 0x00000001);
+    unsigned int hwi_ok = (prio & 0x00000002);
+    unsigned int swi_ok = (prio & 0x00000004);
+    unsigned int pti_id = (prio & 0x00001F00) >> 8;
+    unsigned int hwi_id = (prio & 0x001F0000) >> 16;
+    unsigned int swi_id = (prio & 0x1F000000) >> 24;
+    if      (pti_ok)	*buffer = pti_id;
+    else if (hwi_ok)	*buffer = hwi_id;
+    else if (swi_ok)	*buffer = swi_id;
+    else                *buffer = 32;
+#else
+    *buffer = icu_address[proc_id * ICU_SPAN + ICU_IT_VECTOR]; 
+#endif
+
     return 0;
-
-#endif
-}
-////////////////////////////////////////////////////////////////////////////////
-//     _icu_read()
-// Read a 32-bit word in a memory mapped register of the MULTI_ICU device,
-// identified by the cluster index and a processor local index.
-// Returns 0 if success, > 0 if error.
-////////////////////////////////////////////////////////////////////////////////
-unsigned int _icu_read(  unsigned int cluster_index,
-                         unsigned int proc_index,
-                         unsigned int register_index, 
-                         unsigned int* buffer )
-{
-#if GIET_USE_XICU
-
-#else
-
-    // parameters checking 
-    if ( register_index >= ICU_SPAN) 		return 1;
-    if ( cluster_index >= NB_CLUSTERS)		return 1;
-    if ( proc_index >= NB_PROCS_MAX )       return 1;
-
-    unsigned int *icu_address = (unsigned int*)&seg_icu_base + 
-                                (cluster_index * CLUSTER_SPAN)  +
-                                (proc_index * ICU_SPAN);
-
-    *buffer = icu_address[register_index]; // read word 
-    return 0;
-
-#endif
 }
 
@@ -763,5 +756,5 @@
     else
     {
-        unsigned char *fb_address = (unsigned char*)&seg_fb_base + offset;
+        unsigned char *fb_address = (unsigned char*)&seg_fbf_base + offset;
         memcpy((void*)fb_address, (void*)buffer, length);
         return 0;
@@ -789,5 +782,5 @@
     else
     {
-        unsigned char *fb_address = (unsigned char*)&seg_fb_base + offset;
+        unsigned char *fb_address = (unsigned char*)&seg_fbf_base + offset;
         memcpy((void*)buffer, (void*)fb_address, length);
         return 0;
@@ -833,5 +826,7 @@
     if ( (user_vaddr & 0x3) || (length & 0x3) )
     {
+        _get_lock(&_tty_put_lock);
         _puts("[GIET ERROR] in _fbdma_access() : user buffer not word aligned\n");
+        _release_lock(&_tty_put_lock);
         return 1;
     }
@@ -841,5 +836,5 @@
 
     // compute frame buffer pbase address
-    unsigned int fb_vaddr = (unsigned int)&seg_fb_base + offset;
+    unsigned int fb_vaddr = (unsigned int)&seg_fbf_base + offset;
 
     ko = _v2p_translate( (page_table_t*)user_ptab,
@@ -851,5 +846,7 @@
     if ( ko )
     {
+        _get_lock(&_tty_put_lock);
         _puts("[GIET ERROR] in _fbdma_access() : frame buffer unmapped\n");
+        _release_lock(&_tty_put_lock);
         return 2;
     }
@@ -864,15 +861,21 @@
     if ( ko )
     {
+        _get_lock(&_tty_put_lock);
         _puts("[GIET ERROR] in _fbdma_access() : user buffer unmapped\n");
+        _release_lock(&_tty_put_lock);
         return 3;
     } 
     if ( (flags & PTE_U) == 0 )
     {
+        _get_lock(&_tty_put_lock);
         _puts("[GIET ERROR] in _fbdma_access() : user buffer not in user space\n");
+        _release_lock(&_tty_put_lock);
         return 4; 
     }
     if ( ( (flags & PTE_W) == 0 ) && to_user ) 
     {
+        _get_lock(&_tty_put_lock);
         _puts("[GIET ERROR] in _fbdma_access() : user buffer not writable\n");
+        _release_lock(&_tty_put_lock);
         return 5;
     }
Index: soft/giet_vm/sys/drivers.h
===================================================================
--- soft/giet_vm/sys/drivers.h	(revision 202)
+++ soft/giet_vm/sys/drivers.h	(revision 203)
@@ -15,15 +15,14 @@
 extern volatile unsigned char _timer_event[];
 
-unsigned int _timer_access( unsigned int	read,		// reas if non 0
-                            unsigned int	cluster_id,
-                            unsigned int	local_id, 
-                            unsigned int	register_id, 
-                            unsigned int*	buffer);
+unsigned int _timer_start( unsigned int	cluster_id,
+                           unsigned int	local_id, 
+                           unsigned int	period );
 
-unsigned int _timer_read(   unsigned int	register_id, 
-                            unsigned int*	buffer);
+unsigned int _timer_stop(  unsigned int	cluster_id, 
+                           unsigned int local_id );
 
-unsigned int _timer_write(  unsigned int	register_id, 
-                            unsigned int	value);
+
+unsigned int _timer_reset_irq( unsigned int	cluster_id, 
+                               unsigned int local_id );
 
 ///////////////////////////////////////////////////////////////////////////////////
@@ -48,13 +47,12 @@
 ///////////////////////////////////////////////////////////////////////////////////
 
-unsigned int _icu_read(     unsigned int	cluster_id,
+unsigned int _icu_get_index(unsigned int	cluster_id,
                             unsigned int	proc_id, 
-                            unsigned int	register_id, 
-                            unsigned int*	buffer);
+                            unsigned int*	buffer );
 
-unsigned int _icu_write(	unsigned int	cluster_id,
+unsigned int _icu_set_mask( unsigned int	cluster_id,
 							unsigned int	proc_id,
-							unsigned int	register_id, 
-							unsigned int	value );
+							unsigned int	mask, 
+							unsigned int	is_timer );
 
 ///////////////////////////////////////////////////////////////////////////////////
Index: soft/giet_vm/sys/hwr_mapping.h
===================================================================
--- soft/giet_vm/sys/hwr_mapping.h	(revision 202)
+++ soft/giet_vm/sys/hwr_mapping.h	(revision 203)
@@ -65,5 +65,30 @@
     ICU_SPAN        = 8,
 };
+enum Xicu_registers {
+    XICU_WTI_REG = 0,
+    XICU_PTI_PER = 1,
+    XICU_PTI_VAL = 2,
+    XICU_PTI_ACK = 3,
 
+    XICU_MSK_PTI = 4,
+    XICU_MSK_PTI_ENABLE = 5,
+    XICU_MSK_PTI_DISABLE = 6,
+    XICU_PTI_ACTIVE = 6,
+
+    XICU_MSK_HWI = 8,
+    XICU_MSK_HWI_ENABLE = 9,
+    XICU_MSK_HWI_DISABLE = 10,
+    XICU_HWI_ACTIVE = 10,
+
+    XICU_MSK_WTI = 12,
+    XICU_MSK_WTI_ENABLE = 13,
+    XICU_MSK_WTI_DISABLE = 14,
+    XICU_WTI_ACTIVE = 14,
+
+    XICU_PRIO = 15,
+};
+
+#define XICU_REG(func, index) (((func)<<5)|(index))
+	
 /* TIMER */
 enum TIMER_registers {
Index: soft/giet_vm/sys/irq_handler.c
===================================================================
--- soft/giet_vm/sys/irq_handler.c	(revision 202)
+++ soft/giet_vm/sys/irq_handler.c	(revision 203)
@@ -42,19 +42,12 @@
 
     // get the highest priority active IRQ index 
-
-#if GIET_USE_XICU
-
-#else
-
-    if ( _icu_read( pid / NB_PROCS_MAX,
-                    pid % NB_PROCS_MAX,
-                    ICU_IT_VECTOR,
-                    &irq_id ) )
+    if ( _icu_get_index( pid / NB_PROCS_MAX,
+                         pid % NB_PROCS_MAX,
+                         &irq_id ) )
     {
-        _puts("\n[GIET ERROR] wrong _icu_read in _irq_demux() function\n");
-        _exit();
+        _get_lock(&_tty_put_lock);
+        _puts("\n[GIET ERROR] Strange... Wrong _icu_read in _irq_demux()\n");
+        _release_lock(&_tty_put_lock);
     }
-
-#endif
 
     if ( irq_id < 32 )	// do nothing if no interrupt active 
@@ -74,9 +67,13 @@
 // 	_isr_default()
 // The default ISR is called when no specific ISR has been installed in the
-// interrupt vector. It simply displays a message on kernel TTY[0].
+// interrupt vector. It simply displays an error message on kernel TTY[0].
 ///////////////////////////////////////////////////////////////////////////////////
 void _isr_default()
 {
-    _puts("\n\n!!! Strange... Default ISR activated !!!\n");
+    _get_lock(&_tty_put_lock);
+    _puts("\n[GIET ERROR] Strange... Default ISR activated for processor ");
+    _putd( _procid() );
+    _puts("\n");
+    _release_lock(&_tty_put_lock);
 }
 
@@ -122,52 +119,37 @@
     unsigned int* ioc_address = (unsigned int*)&seg_ioc_base;
 
-    _ioc_status = ioc_address[BLOCK_DEVICE_STATUS]; /* save status & reset IRQ */
-    _ioc_done   = 1;                                /* signals completion */
+    _ioc_status = ioc_address[BLOCK_DEVICE_STATUS]; // save status & reset IRQ 
+    _ioc_done   = 1;                                // signals completion 
 }
 
 ///////////////////////////////////////////////////////////////////////////////////
 // 	   _isr_timer()
-// This ISR handles the IRQs generated by the "user" timers (the IRQs
-// generated by the "system" timers should be handled by the _isr_switch().
+// This ISR handles the IRQs generated by the "user" timers (the IRQs generated
+// by the "system" timers should be handled by the _isr_switch().
 // These timers are distributed in all clusters, and can be implemented
 // in a vci_multi_timer component, or in a vci_xicu component.
-// The channel_id argument is the global channel index:
-//     channel_id = cluster_id*(NB_TIMERS_MAX+NB_PROCS_MAX) + loc_id 
+// The timer_id argument is a global index:
+//     timer_id = cluster_id*(NB_TIMERS_MAX+NB_PROCS_MAX) + local_id 
 // The user timer local index is (loc_id - NB_PROCS_MAX).
 //
 // The ISR acknowledges the IRQ and registers the event in the proper entry
-// of the _timer_event[] array.
-// A log message is displayed on the kernel terminal.
-///////////////////////////////////////////////////////////////////////////////////
-void _isr_timer(unsigned int channel_id)
-{
-
-    unsigned int cluster_id = channel_id / (NB_TIMERS_MAX + NB_PROCS_MAX);
-    unsigned int loc_id     = channel_id % (NB_TIMERS_MAX + NB_PROCS_MAX); 
-
-    if (loc_id < NB_PROCS_MAX )
+// of the _timer_event[] array, and a log message is displayed on kernel terminal.
+///////////////////////////////////////////////////////////////////////////////////
+void _isr_timer(unsigned int timer_id)
+{
+
+    unsigned int cluster_id = timer_id / (NB_TIMERS_MAX + NB_PROCS_MAX);
+    unsigned int local_id   = timer_id % (NB_TIMERS_MAX + NB_PROCS_MAX); 
+
+    // checking timer type
+    if (local_id < NB_PROCS_MAX )
     {
-        _puts("[GIET ERROR] Receiving a user timer IRQ for a system timer\n");
-        _puts("             cluster = ");
-        _putw(cluster_id);
-        _puts(" / local_id = ");
-        _putw(loc_id);
+        _get_lock(&_tty_put_lock);
+        _puts("[GIET ERROR] Strange... User timer ISR for a system timer\n");
+        _release_lock(&_tty_put_lock);
     }
 
-#if GIET_USE_XICU
-
-// TODO
-
-#else
-
-    // compute Timer address
-    unsigned int* timer_address = (unsigned int*)&seg_timer_base +
-                                  (loc_id * TIMER_SPAN) +
-                                  (cluster_id * CLUSTER_SPAN);
-
-    // reset IRQ 
-    timer_address[TIMER_RESETIRQ] = 0;
-
-#endif
+    // aknowledge IRQ 
+    _timer_reset_irq( cluster_id, local_id );
 
 #if NB_TIMERS_MAX
@@ -177,9 +159,11 @@
 
     // display a message on TTY 0 
-    _puts("[GIET] User Timer IRQ / cluster = ");
-    _putw(cluster_id);
-    _puts(" / timer = ");
-    _putw(loc_id - NB_PROCS_MAX);
+    _get_lock(&_tty_put_lock);
+    _puts("[GIET] User Timer IRQ at cycle ");
+    _putd( _proctime() );
+    _puts(" / index = ");
+    _putd(timer_id);
     _puts("\n");
+    _release_lock(&_tty_put_lock);
 }
 
@@ -219,26 +203,12 @@
     // get cluster index and proc local index
     unsigned int pid        = _procid();
-    unsigned int loc_id     = pid % NB_PROCS_MAX;
+    unsigned int local_id   = pid % NB_PROCS_MAX;
     unsigned int cluster_id = pid / NB_PROCS_MAX;
 
-#if GIET_USE_XICU
-
-    unsigned int* timer_address = // TODO
-
-#else
-
-    // compute Timer address
-    unsigned int* timer_address = (unsigned int*)&seg_timer_base +
-                                  (loc_id * TIMER_SPAN) +
-                                  (cluster_id * CLUSTER_SPAN);
-
-    // reset IRQ
-    timer_address[TIMER_RESETIRQ] = 0; 
-
-#endif
+    // acknowledge IRQ
+    _timer_reset_irq( cluster_id, local_id ); 
 
     // performs the context switch
     _ctx_switch();
-
-}
-
+}
+
Index: soft/giet_vm/sys/kernel_init.c
===================================================================
--- soft/giet_vm/sys/kernel_init.c	(revision 202)
+++ soft/giet_vm/sys/kernel_init.c	(revision 203)
@@ -76,6 +76,6 @@
 
     // step 2 : initialise page table addresse arrays
-    //          it scans all tasks contexts in the scheduler 
-    //          and get VSID, PTAB and PTPR values
+    //          each processor scans all tasks contexts in its
+    //          private scheduler and get VSID, PTAB and PTPR values
 
     unsigned int ltid;
@@ -87,4 +87,5 @@
         unsigned int ptab_vaddr = _get_context_slot( ltid , CTX_PTAB_ID ); 
         unsigned int ptab_paddr = _get_context_slot( ltid , CTX_PTPR_ID ) << 13; 
+
         _ptabs_vaddr[vspace_id] = ptab_vaddr;
         _ptabs_paddr[vspace_id] = ptab_paddr;
@@ -106,16 +107,28 @@
     }
  
-    // step 3 : compute and set ICU mask 
+    // step 3 : compute and set ICU masks
+    //          there is at most 32 interrupts per processor
+    //          software interrupts are not supported yet
+
     unsigned int irq_id;
-    unsigned int mask = 0;
+    unsigned int hwi_mask = 0;
+    unsigned int pti_mask = 0;
+
     for ( irq_id = 0 ; irq_id < 32 ; irq_id++ )
     {
-        unsigned int entry   = _get_interrupt_vector_entry(irq_id);
-        if ( entry ) mask = mask | 0x1<< irq_id;
-    }
-    _icu_write( cluster_id,
-                lpid,
-                ICU_MASK_SET,
-                mask );
+        unsigned int entry  = _get_interrupt_vector_entry(irq_id);
+        unsigned int isr    = entry & 0x000000FF;
+
+        if ( (isr == ISR_DMA) || (isr == ISR_IOC) || (isr == ISR_TTY) )
+        {
+             hwi_mask = hwi_mask | 0x1<< irq_id;
+        }
+        else if ( (isr == ISR_SWITCH) || (isr == ISR_TIMER) )
+        { 
+            pti_mask = pti_mask | 0x1<< irq_id;
+        }
+    }
+    _icu_set_mask( cluster_id, lpid, hwi_mask, 0 ); // set HWI_MASK
+    _icu_set_mask( cluster_id, lpid, pti_mask, 1 );	// set PTI_MASK
    
 #if GIET_DEBUG_INIT
@@ -123,6 +136,8 @@
 _puts("\n[GIET DEBUG] step 3 for processor ");
 _putd( proc_id );
-_puts(" / ICU mask = ");
-_putw( mask );
+_puts("\n - ICU HWI_MASK = ");
+_putw( hwi_mask );
+_puts("\n - ICU PTI_MASK = ");
+_putw( pti_mask );
 _puts("\n");
 _release_lock(&_tty_put_lock);
@@ -133,16 +148,7 @@
     if ( tasks > 1 )
     {
-        unsigned int period     = GIET_TICK_VALUE;
-        unsigned int mode       = 0x3;
-        _timer_access( 0,			// write access
-                       cluster_id, 
-                       proc_id, 
-                       TIMER_PERIOD, 
-                       &period );
-        _timer_access( 0,			// write access
-                       cluster_id, 
-                       proc_id, 
-                       TIMER_MODE, 
-                       &mode );
+        _timer_start( cluster_id, 
+                      proc_id, 
+                      GIET_TICK_VALUE );
         
 #if GIET_DEBUG_INIT
@@ -150,5 +156,5 @@
 _puts("\n[GIET DEBUG] Step 4 for processor ");
 _putd( proc_id );
-_puts(" / TICK activated\n");
+_puts(" / context switch activated\n");
 _release_lock(&_tty_put_lock);
 #endif
Index: soft/giet_vm/sys/sys.ld
===================================================================
--- soft/giet_vm/sys/sys.ld	(revision 202)
+++ soft/giet_vm/sys/sys.ld	(revision 203)
@@ -1,31 +1,12 @@
-/****************************************************************************
-* Definition of the base address for all virtual segments
-*****************************************************************************/
 
-/* The vsegs used by the system are mapped in all virtual spaces 
-   They can be identity mapping... or not */
+/******************************************************************************/
+/* Definition of the base addresses for all vsegs used by the GIET_VM         */
+/******************************************************************************/
 
-seg_kernel_code_base    = 0x80000000;	/* system code */
-seg_kernel_data_base    = 0x80010000;	/* system cacheable data */
-seg_kernel_uncdata_base = 0x80080000;	/* system uncacheable data */
-seg_kernel_init_base    = 0x80090000;	/* system page table */ 
-seg_mapping_base  	    = 0xBFC0C000;	/* boot mapping_info */
+INCLUDE giet_vsegs.ld
 
-
-/* The peripherals base addresses are referenced by the software drivers and    \
-   must be defined, even if the peripherals are not used in the architecture */
-
-seg_tty_base      	    = 0x90000000;   /* TTY device */
-seg_timer_base    	    = 0x91000000;   /* Timer device */
-seg_ioc_base      	    = 0x92000000;   /* Block device */
-seg_dma_base      	    = 0x93000000;   /* DMA device */
-seg_gcd_base      	    = 0x95000000;   /* GCD device */
-seg_fb_base       	    = 0x96000000;   /* FrameBuffer device */
-seg_iob_base      	    = 0x9E000000;   /* IOB device */
-seg_icu_base      	    = 0x9F000000;   /* ICU or XICU device */
-
-/*
- * Grouping sections into segments for system code and data
- */
+/******************************************************************************/
+/* Grouping sections into virtual segments for system code and data           */
+/******************************************************************************/
 
 SECTIONS
@@ -37,4 +18,5 @@
         *(.text)
     }
+
     . = seg_kernel_data_base;
     seg_kernel_data : 
@@ -53,4 +35,5 @@
         *(.scommon)
     }
+
     . = seg_kernel_uncdata_base;
     seg_kernel_uncdata : 
Index: soft/giet_vm/sys/sys_handler.c
===================================================================
--- soft/giet_vm/sys/sys_handler.c	(revision 202)
+++ soft/giet_vm/sys/sys_handler.c	(revision 203)
@@ -5,5 +5,5 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The sys_handler.c and sys_handler.h files are part of the GIET nano-kernel.
+// The sys_handler.c and sys_handler.h files are part of the GIET-VM nano-kernel.
 // It define the syscall_vector[] (at the end of this file), as well as the 
 // associated syscall handlers that are not related to peripherals.
@@ -26,6 +26,6 @@
     &_tty_write,        /* 0x02 */
     &_tty_read,         /* 0x03 */
-    &_timer_write,      /* 0x04 */
-    &_timer_read,       /* 0x05 */
+    &_timer_start,      /* 0x04 */
+    &_timer_stop,       /* 0x05 */
     &_gcd_write,        /* 0x06 */
     &_gcd_read,         /* 0x07 */
Index: soft/giet_vm/xml/xml_parser.c
===================================================================
--- soft/giet_vm/xml/xml_parser.c	(revision 202)
+++ soft/giet_vm/xml/xml_parser.c	(revision 203)
@@ -1078,4 +1078,18 @@
     }
 
+    ////////// get ident attribute (optional : 0 if missing)
+    value = getIntValue(reader,"ident", &ok);
+    if ( ok )
+    {
+#if XML_PARSER_DEBUG
+printf("      ident = %d\n", value);
+#endif
+        vseg[vseg_index]->ident = value;
+    }  
+    else
+    {
+        vseg[vseg_index]->ident = 0;
+    }
+
     /////////// get vbase attribute
     value = getIntValue(reader,"vbase", &ok);
@@ -1127,18 +1141,4 @@
         exit(1);
     }  
-
-    ////////// get ident attribute (optional : 0 if missing)
-    value = getIntValue(reader,"ident", &ok);
-    if ( ok )
-    {
-#if XML_PARSER_DEBUG
-printf("      ident = %d\n", value);
-#endif
-        vseg[vseg_index]->ident = value;
-    }  
-    else
-    {
-        vseg[vseg_index]->ident = 0;
-    }
 
     //////// get mode attribute
@@ -1257,6 +1257,6 @@
     else
     {
-        printf("[XML ERROR] illegal or missing <startname> attribute for vspace %d\n", 
-                 vspace_index);
+        printf("[XML ERROR] illegal or missing <startname> attribute for vspace %s\n", 
+                 vspace[vspace_index]->name);
         exit(1);
     }
@@ -1281,5 +1281,6 @@
             if(index == -1)
             {
-                printf("[XML ERROR] vobj containing the start vector not found %s\n",str);
+                printf("[XML ERROR] vobj containing start vector not found in vspace %s\n",
+                        vspace[vspace_index]->name);
                 exit(-1);
             }
