Index: soft/giet_vm/giet_drivers/tim_driver.c
===================================================================
--- soft/giet_vm/giet_drivers/tim_driver.c	(revision 426)
+++ soft/giet_vm/giet_drivers/tim_driver.c	(revision 437)
@@ -1,33 +1,12 @@
 //////////////////////////////////////////////////////////////////////////////////////
-// File     : timer_driver.c
+// File     : tim_driver.c
 // Date     : 23/05/2013
 // Author   : alain greiner
 // Copyright (c) UPMC-LIP6
 //////////////////////////////////////////////////////////////////////////////////////
-// The timer_driver.c and timer_driver.h files are part ot the GIET-VM nano-kernel.
-// This driver supports the SoCLib vci_multi_timer component.
-//
-// It can exist several multi_timers in the architecture (at most one per cluster),
-// and each one can contain several timers (called channels).
-//
-// 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.
-//   For each user timer, the timer_id is stored in the context of the task.
-// The global index is cluster_xy * (NB_PROCS_MAX + NB_TIM_CHANNELS) + local_id
-//
-// The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in hard_config.h file.
-//
-// The virtual base address of the segment associated to a channel is:
-//     SEG_TIM_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + TIMER_SPAN * timer_id
-//
-// The SEG_TIM_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h.
-/////////////////////////////////////////////////////////////////////////////////////
 
 #include <giet_config.h>
+#include <hard_config.h>
 #include <tim_driver.h>
-#include <xcu_driver.h>
-#include <tty_driver.h>
 #include <utils.h>
 
@@ -68,153 +47,109 @@
 #endif
 
-///////////////////  Timer global variables ////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+//                      global variables
+/////////////////////////////////////////////////////////////////////////////////
 
 #define in_unckdata __attribute__((section (".unckdata")))
 
 #if (NB_TIM_CHANNELS > 0)
-in_unckdata volatile unsigned char _user_timer_event[(1<<X_WIDTH)*(1<<Y_WIDTH)*NB_TIM_CHANNELS] 
-                        = { [0 ... (((1<<X_WIDTH)*(1<<Y_WIDTH)*NB_TIM_CHANNELS) - 1)] = 0 };
+in_unckdata volatile unsigned char _user_timer_event[NB_TIM_CHANNELS]
+                        = { [0 ... ((1<<NB_TIM_CHANNELS) - 1)] = 0 };
 #endif
 
-////////////////////////////////////////////////////////////////////////////////////
-// This function activates a timer in the vci_timer 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.
-///////////////////////////////////////////////////////////////////////////////////
-void _timer_start( unsigned int cluster_xy, 
-                   unsigned int local_id, 
-                   unsigned int period) 
+/////////////////////////////////////////////////////////////////////////////////
+//                      access functions
+/////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////
+unsigned int _timer_get_register( unsigned int channel,
+                                  unsigned int index )
+{
+    unsigned int* vaddr = (unsigned int*)SEG_TIM_BASE + channel*TIMER_SPAN + index;
+    return _io_extended_read( vaddr );
+}
+
+//////////////////////////////////////////////////////
+void _timer_set_register( unsigned int channel,
+                          unsigned int index,
+                          unsigned int value )
+{
+    unsigned int* vaddr = (unsigned int*)SEG_TIM_BASE + channel*TIMER_SPAN + index;
+    _io_extended_write( vaddr, value );
+}
+
+///////////////////////////////////////
+int _timer_start( unsigned int channel, 
+                  unsigned int period ) 
 {
 #if NB_TIM_CHANNELS
 
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
+    if ( channel >= NB_TIM_CHANNELS )
     {
-        _printf("[GIET ERROR] in _timer_start()\n");
-        _exit();
+        _puts("[GIET ERROR] in _timer_start()\n");
+        return -1;
     }
 
-    unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE +
-                                  (cluster_xy * PERI_CLUSTER_INCREMENT) );
-
-    timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
-    timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0x3;
+    _timer_set_register( channel, TIMER_PERIOD, period );
+    _timer_set_register( channel, TIMER_MODE  , 0x3 );
+    
+    return 0;
 
 #else
-    _printf("[GIET ERROR] _timer_start() should not be called when NB_TIM_CHANNELS is 0\n");
-    _exit();
+
+    _puts("[GIET ERROR] _timer_start() should not be called when NB_TIM_CHANNELS is 0\n");
+    return -1;
+
 #endif
 }
 
-//////////////////////////////////////////////////////////////////////////////
-// This function desactivates a timer in the vci_timer component
-// by writing in the proper register.
-// Returns 0 if success, > 0 if error.
-//////////////////////////////////////////////////////////////////////////////
-void _timer_stop( unsigned int cluster_xy, 
-                  unsigned int local_id) 
+///////////////////////////////////////
+int _timer_stop( unsigned int channel ) 
 {
 #if NB_TIM_CHANNELS
 
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
+    if ( channel >= NB_TIM_CHANNELS )
     {
-        _printf("[GIET ERROR] in _timer_stop()\n");
-        _exit();
+        _puts("[GIET ERROR] in _timer_stop()\n");
+        return -1;
     }
 
-    unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE +
-                                  (cluster_xy * PERI_CLUSTER_INCREMENT) );
+    _timer_set_register( channel, TIMER_MODE  , 0 );
 
-    timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0;
+    return 0;
 
 #else
-    _printf("[GIET ERROR] _timer_stop() should not be called when NB_TIM_CHANNELS is 0\n");
-    _exit();
+
+    _puts("[GIET ERROR] _timer_stop() should not be called when NB_TIM_CHANNELS is 0\n");
+    return -1;
+
 #endif
 }
 
-//////////////////////////////////////////////////////////////////////////////
-// This function acknowlegge a timer interrupt in the vci_timer  
-// component by writing 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.
-//////////////////////////////////////////////////////////////////////////////
-void _timer_reset_irq( unsigned int cluster_xy, 
-                       unsigned int local_id ) 
+////////////////////////////////////////////
+int _timer_reset_cpt( unsigned int channel ) 
 {
 #if NB_TIM_CHANNELS
 
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
+    if ( channel >= NB_TIM_CHANNELS )
     {
-        _printf("[GIET ERROR] in _timer_reset_irq()\n");
-        _exit();
+        _puts("[GIET ERROR in _timer_reset_cpt()\n");
+        return -1;
     }
 
-    unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE +
-                                  (cluster_xy * PERI_CLUSTER_INCREMENT) );
+    unsigned int period = _timer_get_register( channel, TIMER_PERIOD );
+    _timer_set_register( channel, TIMER_PERIOD, period );
 
-    timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0;
+    return 0;
 
 #else
-    _printf("[GIET ERROR] _timer_reset_irq() should not be called when NB_TIM_CHANNELS is 0\n");
-    _exit();
+
+    _puts("[GIET ERROR] _timer_reset_cpt should not be called when NB_TIM_CHANNELS is 0\n");
+    return -1;
+
 #endif
 }
 
-/////////////////////////////////////////////////////////////////////////////
-// This function resets the 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)
-// This function is called during a context switch (user or preemptive)
-//////////////////////////////////////////////////////////////////////i//////
-void _timer_reset_cpt( unsigned int cluster_xy, 
-                       unsigned int local_id) 
-{
-#if NB_TIM_CHANNELS
-
-    // parameters checking 
-    unsigned int x = cluster_xy >> Y_WIDTH;
-    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
-    if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) )
-    {
-        _printf("[GIET ERROR in _timer_reset_cpt()\n");
-        _exit();
-    }
-
-    // We suppose that the TIMER_MODE register value is 0x3
-    unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE +
-                                  (cluster_xy * PERI_CLUSTER_INCREMENT) );
-
-    unsigned int period = timer_address[local_id * TIMER_SPAN + TIMER_PERIOD];
-    timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
-
-#else
-    _printf("[GIET ERROR] _timer_reset_cpt should not be called when NB_TIM_CHANNELS is 0\n");
-    _exit();
-#endif
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-// This ISR handles the IRQs generated by the "user" timers that are
-// replicated in all clusters.
-// The IRQs generated by the "system" timers should be handled by _isr_switch().
-// It can be a HWI or a PTI.
-// The channel argument is the user timer local index.
-//     timer_global_id = cluster_id*(NB_TIM_CHANNELS) + channel
-// The ISR acknowledges the IRQ and registers the event in the proper entry
-// of the _user_timer_event[] array, and a log message is displayed on TTY0.
-///////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////
 void _timer_isr( unsigned int irq_type,   // HWI / PTI
                  unsigned int irq_id,     // index returned by XCU
@@ -223,20 +158,19 @@
 #if NB_TIM_CHANNELS
 
-    unsigned int cluster_xy = _get_procid() >> P_WIDTH;
-
-    // acknowledge IRQ depending on type 
-    if   ( irq_type == IRQ_TYPE_HWI )  _timer_reset_irq( cluster_xy, channel );
-    else                               _xcu_timer_reset_irq( cluster_xy, irq_id );
+    // acknowledge IRQ
+    _timer_set_register( channel, TIMER_RESETIRQ, 0 ); 
 
     // register the event
-    _user_timer_event[cluster_xy * NB_TIM_CHANNELS + channel] = 1;
+    _user_timer_event[channel] = 1;
 
     // display a message on TTY 0 
-    _printf("\n[GIET WARNING] User Timer IRQ at cycle %d / cluster = %x / channel = %d\n",
-            _get_proctime(), cluster_xy, channel );
+    _puts("\n[GIET WARNING] User Timer IRQ at cycle %d for channel = %d\n",
+            _get_proctime(), channel );
 
 #else
-    _printf("[GIET ERROR] _timer_isr() should not be called when NB_TIM_CHANNELS == 0\n");
+
+    _puts("[GIET ERROR] _timer_isr() should not be called when NB_TIM_CHANNELS == 0\n");
     _exit();
+
 #endif
 }
