Index: soft/giet_vm/giet_drivers/xcu_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/xcu_driver.c	(revision 281)
+++ soft/giet_vm/giet_drivers/xcu_driver.c	(revision 295)
@@ -5,20 +5,4 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The xcu_driver.c and xcu_driver.h files are part ot the GIET-VM nano-kernel.
-// This driver supports the SoCLib vci_xicu, that is a vectorised interrupt
-// controler supporting IPI (Inter Processor Interrupts) and integrated timers.
-//
-// It can exist several interrupt controller unit in the architecture 
-// (one per cluster), and each one can contain several channels.
-// The number of XICU channels is equal to NB_PROCS_MAX, because there is 
-// one private XICU channel per processor in a cluster.
-////////////////////////////////////////////////////////////////////////////////
-// The virtual base address of the segment associated to the component is:
-//
-//      seg_xcu_base + cluster_xy * vseg_cluster_increment
-//
-// The seg_xcu_base and vseg_cluster_increment values must be defined 
-// in giet_vsegs.ld file.
-////////////////////////////////////////////////////////////////////////////////
 
 #include <giet_config.h>
@@ -52,25 +36,23 @@
 #endif
 
-////////////////////////////////////////////////////////////////////////////////
-//     _xcu_set_mask()
-// This function set the mask register for the XICU channel identified by the
-// cluster index and the processor index multiplied by the number of IRQ per
-// processor.
+
+////////////////////////////////////////////////////////////////////////////////
+// This function set the mask register for the IRQ type defined by "irq_type",
+// and for the channel identified by the "cluster_xy" and "channel" arguments.
 // All '1' bits are set / all '0' bits are not modified.
-// Returns 0 if success, > 0 if error.
-////////////////////////////////////////////////////////////////////////////////
-unsigned int _xcu_set_mask( unsigned int cluster_xy, 
-                            unsigned int irq_index,
-                            unsigned int value,
-                            unsigned int irq_type ) 
-{
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if (x >= X_SIZE)                                     return 1; 
-    if (y >= Y_SIZE)                                     return 1; 
-    if (irq_index >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) return 1; 
-
-#if USE_XICU
+////////////////////////////////////////////////////////////////////////////////
+void _xcu_set_mask( unsigned int cluster_xy, 
+                    unsigned int channel,  
+                    unsigned int value,
+                    unsigned int irq_type ) 
+{
+#if USE_XICU
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                                   _exit(); 
+    if (y >= Y_SIZE)                                   _exit(); 
+    if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit(); 
+
     volatile unsigned int* xcu_address =
         (unsigned int *) ((unsigned int)&seg_xcu_base + 
@@ -79,83 +61,94 @@
     unsigned int func;
     if      (irq_type == IRQ_TYPE_PTI) func = XICU_MSK_PTI_ENABLE;
-    else if (irq_type == IRQ_TYPE_SWI) func = XICU_MSK_WTI_ENABLE;
-    else                               func = XICU_MSK_HWI_ENABLE;
-    xcu_address[XICU_REG(func,irq_index)] = value;
-    return 0;
-#else
-    _tty_get_lock( 0 );
-    _puts("[GIET ERROR] _xcu_set_mask should not be used if USE_XICU is not set\n");
-    _tty_release_lock( 0 );
-    return 1;
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//     _xcu_get_index()
-// This function returns the index of the highest priority (smaller index) 
-// - active HWI (Hardware Interrupt), or
-// - active PTI (Timer Interrupt), or
-// - active SWI (Software Interrupt).
-// The ICU channel is identified by the cluster index and the processor index
-// multiplied by the number of IRQ per processor.
-// Returns 0 if success, > 0 if error.
-////////////////////////////////////////////////////////////////////////////////
-unsigned int _xcu_get_index( unsigned int cluster_xy, 
-                             unsigned int irq_index, 
-                             unsigned int * buffer) 
-{
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if (x >= X_SIZE)                                     return 1; 
-    if (y >= Y_SIZE)                                     return 1; 
-    if (irq_index >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) return 1; 
-
-#if USE_XICU
-    volatile unsigned int* xcu_address =
-        (unsigned int *) ((unsigned int)&seg_xcu_base + 
-        (cluster_xy * (unsigned int)&vseg_cluster_increment));
-
-    unsigned int prio = xcu_address[XICU_REG(XICU_PRIO,irq_index)];
+    else if (irq_type == IRQ_TYPE_WTI) func = XICU_MSK_WTI_ENABLE;
+    else if (irq_type == IRQ_TYPE_HWI) func = XICU_MSK_HWI_ENABLE;
+    else
+    { 
+        _printf("[GIET ERROR] _xcu_set_mask() receives illegal IRQ type\n");
+        _exit();
+    }
+
+    xcu_address[XICU_REG(func,channel)] = value;
+
+#else
+    _printf("[GIET ERROR] _xcu_set_mask() should not be used if USE_XICU not set\n");
+    _exit();
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// This function returns the index and the type of the highest priority 
+// - active PTI (Timer Interrupt), then
+// - active HWI (Hardware Interrupt), then
+// - active WTI (Software Interrupt)
+// As the hardware can define more than one IRQ per processor, but the GIET
+// use only one, channel = lpid * IRQ_PER_PROCESSOR.
+////////////////////////////////////////////////////////////////////////////////
+void _xcu_get_index( unsigned int cluster_xy, 
+                     unsigned int channel,   
+                     unsigned int * index, 
+                     unsigned int * irq_type )
+{
+#if USE_XICU
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                                   _exit(); 
+    if (y >= Y_SIZE)                                   _exit(); 
+    if (channel >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) _exit(); 
+
+    volatile unsigned int* xcu_address =
+        (unsigned int *) ((unsigned int)&seg_xcu_base + 
+        (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    unsigned int prio = xcu_address[XICU_REG(XICU_PRIO,channel)];
     unsigned int pti_ok = (prio & 0x00000001);
     unsigned int hwi_ok = (prio & 0x00000002);
-    unsigned int swi_ok = (prio & 0x00000004);
+    unsigned int wti_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; 
-    return 0;
-#else
-    _tty_get_lock( 0 );
-    _puts("[GIET ERROR] _xcu_get_index should not be used if USE_XICU is not set\n");
-    _tty_release_lock( 0 );
-    return 1;
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//     _xcu_send_ipi()
-// This function can be used only in an architecture using  XICU components.
-// It writes the "wdata" value in the mailbox defined by the cluster index
-// and the processor index.
-// Giet-VM supports at most NB_PROCS_MAX mailboxes:
-// (0 <= wti_index <= NB_PROCS_MAX-1)
-// Returns 0 if success, > 0 if error.
-////////////////////////////////////////////////////////////////////////////////
-unsigned int _xcu_send_ipi( unsigned int cluster_xy,
-                            unsigned int wti_index,
-                            unsigned int wdata )
+    unsigned int wti_id = (prio & 0x1F000000) >> 24;
+    if      (pti_ok)
+    {
+        *index    = pti_id;
+        *irq_type = IRQ_TYPE_PTI;
+    }
+    else if (hwi_ok)
+    {
+        *index    = hwi_id;
+        *irq_type = IRQ_TYPE_HWI;
+    }
+    else if (wti_ok) 
+    {
+        *index    = wti_id;
+        *irq_type = IRQ_TYPE_WTI;
+    }
+    else 
+    {
+        *index = 32;
+    }
+ 
+#else
+    _printf("[GIET ERROR] _xcu_get_index should not be used if USE_XICU is not set\n");
+    _exit();
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// This function writes the "wdata" value in the mailbox defined 
+// by the "cluster_xy" and "wti_index" arguments.
+////////////////////////////////////////////////////////////////////////////////
+void _xcu_send_wti( unsigned int cluster_xy,
+                    unsigned int wti_index,
+                    unsigned int wdata )
 { 
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if (x >= X_SIZE)               return 1; 
-    if (y >= Y_SIZE)               return 1; 
-    if (wti_index >= NB_PROCS_MAX) return 1; 
-
-#if USE_XICU
+#if USE_XICU
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)               _exit(); 
+    if (y >= Y_SIZE)               _exit(); 
+    if (wti_index >= 32)           _exit(); 
+
     volatile unsigned int* xcu_address =
         (unsigned int *) ((unsigned int)&seg_xcu_base + 
@@ -163,30 +156,78 @@
 
     xcu_address[XICU_REG(XICU_WTI_REG,wti_index)] = wdata;
-    return 0; 
-#else
-    _tty_get_lock( 0 );
-    _puts("[GIET ERROR] _xcu_send_ipi should not be used if USE_XICU is not set\n");
-    _tty_release_lock( 0 );
-    return 1;
+
+#else
+    _printf("[GIET ERROR] _xcu_send_ipi should not be used if USE_XICU is not set\n");
+    _exit();
 #endif
 } 
 
 ////////////////////////////////////////////////////////////////////////////////
-//    _xcu_timer_start()
+// This function returns the value contained in a WTI mailbox defined by
+// the cluster_xy and "wti_index" arguments. This value is written in
+// the "value" argument, and the corresponding WTI is acknowledged.
+// returns 0 if success, > 0 if error.
+////////////////////////////////////////////////////////////////////////////////
+void _xcu_get_wti_value( unsigned int   cluster_xy,
+                         unsigned int   wti_index,
+                         unsigned int * value )
+{
+#if USE_XICU
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)               _exit(); 
+    if (y >= Y_SIZE)               _exit(); 
+    if (wti_index >= 32)           _exit(); 
+ 
+    volatile unsigned int* xcu_address =
+        (unsigned int *) ((unsigned int)&seg_xcu_base + 
+        (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    *value = xcu_address[XICU_REG(XICU_WTI_REG, wti_index)]; 
+
+#else
+    _printf("[GIET ERROR] in _xcu_get_wti_value() USE_XICU is not set\n");
+    _exit();
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// This function returns the address of a WTI mailbox defined by
+// the "wti_index" argument, in the unsigned int "address" argument.
+// It is used by the GIET to configurate the IOPIC component.
+// There is no access to a specific XCU component in a specific cluster.
+// returns 0 if success, > 0 if error.
+////////////////////////////////////////////////////////////////////////////////
+void _xcu_get_wti_address( unsigned int   wti_index,
+                           unsigned int * address )
+{
+#if USE_XICU
+    if (wti_index >= 32)           _exit(); 
+ 
+    unsigned int xcu_address = (unsigned int)&seg_xcu_base;
+    *address = xcu_address + (XICU_REG(XICU_WTI_REG, wti_index)<<2); 
+
+#else
+    _printf("[GIET ERROR] in _xcu_get_wti_address() USE_XICU is not set\n");
+    _exit();
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // This function activates a timer contained in XICU by writing in the
 // proper register the period value.
-// Returns 0 if success, > 0 if error.
-////////////////////////////////////////////////////////////////////////////////
-unsigned int _xcu_timer_start( unsigned int cluster_xy,
-                               unsigned int pti_index,
-                               unsigned int period )
-{
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if (x >= X_SIZE)             return 1; 
-    if (y >= Y_SIZE)             return 1; 
-
-#if USE_XICU
+////////////////////////////////////////////////////////////////////////////////
+void _xcu_timer_start( unsigned int cluster_xy,
+                       unsigned int pti_index,
+                       unsigned int period )
+{
+#if USE_XICU
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             _exit(); 
+    if (y >= Y_SIZE)             _exit(); 
+
     volatile unsigned int* xcu_address =
         (unsigned int *) ((unsigned int)&seg_xcu_base + 
@@ -194,29 +235,25 @@
 
     xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = period;
-    return 0;
-#else
-    _tty_get_lock( 0 );
-    _puts("[GIET ERROR] _xcu_timer_start should not be used if USE_XICU is not set\n");
-    _tty_release_lock( 0 );
-    return 1;
-#endif
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//     _xcu_timer_stop()
+
+#else
+    _printf("[GIET ERROR] in _xcu_timer_start() USE_XICU is not set\n");
+    _exit();
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////////
 // This function desactivates a timer in XICU component
 // by writing in the proper register.
-// Returns 0 if success, > 0 if error.
-//////////////////////////////////////////////////////////////////////////////
-unsigned int _xcu_timer_stop( unsigned int cluster_xy, 
-                              unsigned int pti_index) 
-{
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if (x >= X_SIZE)             return 1; 
-    if (y >= Y_SIZE)             return 1; 
-
-#if USE_XICU
+//////////////////////////////////////////////////////////////////////////////
+void _xcu_timer_stop( unsigned int cluster_xy, 
+                      unsigned int pti_index) 
+{
+#if USE_XICU
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             _exit(); 
+    if (y >= Y_SIZE)             _exit(); 
+
     volatile unsigned int * xcu_address =
         (unsigned int *) ((unsigned int)&seg_xcu_base + 
@@ -224,31 +261,27 @@
 
     xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = 0;
-    return 0;
-#else
-    _tty_get_lock( 0 );
-    _puts("[GIET ERROR] _xcu_timer_stop should not be used if USE_XICU is not set\n");
-    _tty_release_lock( 0 );
-    return 1;
-#endif
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//     _xcu_timer_reset_irq()
+
+#else
+    _printf("[GIET ERROR] in _xcu_timer_stop() USE_XICU is not set\n");
+    _exit();
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////////
 // This function acknowlegge a timer interrupt in XICU 
 // component by reading in the proper register.
 // 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 _xcu_timer_reset_irq( unsigned int cluster_xy, 
-                                   unsigned int pti_index ) 
-{
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if (x >= X_SIZE)             return 1; 
-    if (y >= Y_SIZE)             return 1; 
-
-#if USE_XICU
+//////////////////////////////////////////////////////////////////////////////
+void _xcu_timer_reset_irq( unsigned int cluster_xy, 
+                           unsigned int pti_index ) 
+{
+#if USE_XICU
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             _exit(); 
+    if (y >= Y_SIZE)             _exit(); 
+
     volatile unsigned int * xcu_address =
         (unsigned int *) ((unsigned int)&seg_xcu_base +
@@ -256,32 +289,29 @@
 
     xcu_address[XICU_REG(XICU_PTI_ACK, pti_index)];
-    return 0;
-#else
-    _tty_get_lock( 0 );
-    _puts("[GIET ERROR] _xcu_timer_reset_irq should not be used if USE_XICU is not set\n");
-    _tty_release_lock( 0 );
-    return 1;
-#endif
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//     _xcu_timer_reset_cpt()
+
+#else
+    _printf("[GIET ERROR] in _xcu_timer_reset_irq() USE_XICU is not set\n");
+    _exit();
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////////
 // This function resets a timer counter. To do so, we re-write the period
 // in the proper register, what causes the count to restart.
 // The period value is read from the same (TIMER_PERIOD) register,
 // this is why in appearance we do nothing useful (read a value
-// from a register and write this value in the same register)
+// from a register and write this value in the same register).
 // This function is called during a context switch (user or preemptive)
 /////////////////////////////////////////////////////////////////////////////
-unsigned int _xcu_timer_reset_cpt( unsigned int cluster_xy, 
-                                   unsigned int pti_index ) 
-{
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if (x >= X_SIZE)             return 1; 
-    if (y >= Y_SIZE)             return 1; 
-
-#if USE_XICU
+void _xcu_timer_reset_cpt( unsigned int cluster_xy, 
+                           unsigned int pti_index ) 
+{
+#if USE_XICU
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             _exit(); 
+    if (y >= Y_SIZE)             _exit(); 
+
     volatile unsigned int * xcu_address =
         (unsigned int *) ((unsigned int) &seg_xcu_base + 
@@ -294,10 +324,8 @@
     xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = 0;
     xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = period;
-    return 0;
-#else
-    _tty_get_lock( 0 );
-    _puts("[GIET ERROR] _xcu_timer_reset_irq should not be used if USE_XICU is not set\n");
-    _tty_release_lock( 0 );
-    return 1;
+
+#else
+    _printf("[GIET ERROR] in _xcu_timer_reset_cpt() USE_XICU is not set\n");
+    _exit();
 #endif
 }
