Index: /soft/giet_vm/giet_drivers/dma_driver.h
===================================================================
--- /soft/giet_vm/giet_drivers/dma_driver.h	(revision 517)
+++ /soft/giet_vm/giet_drivers/dma_driver.h	(revision 518)
@@ -1,8 +1,8 @@
-///////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 // File     : dma_driver.h
 // Date     : 01/11/2013
 // Author   : alain greiner
 // Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 // The dma_driver.c and dma_driver.h files are part ot the GIET-VM nano-kernel.
 // This driver supports the SoCLib vci_multi_dma component.
@@ -24,12 +24,12 @@
 //
 // The SEG_DMA_BASE virtual address mus be defined in the hard_config.h file.
-////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 
 #ifndef _GIET_DMA_DRIVER_H_
 #define _GIET_DMA_DRIVER_H_
 
-///////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 // Multi DMA registers offset
-///////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 
 enum DMA_registers 
@@ -57,7 +57,7 @@
 
 
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 //                  low-level access functions  
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 
 //////////////////////////////////////////////////////////////////////////////////
@@ -98,5 +98,5 @@
 //////////////////////////////////////////////////////////////////////////////////
 
-///////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 // This function copies a source memory buffer to a destination memory buffer,
 // using directly physical addresses.
@@ -108,5 +108,5 @@
 // In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error 
 // message is displayed on TTY0, and system crash.
-///////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 extern void _dma_physical_copy( unsigned int       cluster_xy,
                                 unsigned int       channel_id,
@@ -115,5 +115,5 @@
                                 unsigned int       size ); 
 
-///////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 // This function copies a source memory buffer to a destination memory buffer,
 // making virtual to physical address translation: the MMU should be activated. 
@@ -125,5 +125,5 @@
 // In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error 
 // message is displayed on TTY0, and system crash.
-///////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 extern void _dma_copy(  unsigned int cluster_xy,
                         unsigned int channel_id,
@@ -133,8 +133,8 @@
                         unsigned int size ); 
 
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 // This ISR should not be used by the GIET_VM, because the DMA is only
 // used by the kernel in the boot phase, with a polling strategy.
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 extern void _dma_isr( unsigned int irq_type,
                       unsigned int irq_id,
Index: /soft/giet_vm/giet_drivers/mwr_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/mwr_driver.c	(revision 517)
+++ /soft/giet_vm/giet_drivers/mwr_driver.c	(revision 518)
@@ -1,24 +1,16 @@
 ///////////////////////////////////////////////////////////////////////////////////
 // File     : mwr_driver.c
-// Date     : 23/05/2013
+// Date     : 27/02/2015
 // Author   : alain greiner
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The mwmr_driver.c and mwmr_driver.h files are part ot the GIET-VM nano-kernel.
-// This driver supports the SoClib vci_mwmr_controller component.
-// 
-// This peripheral can be replicated (at most one component per cluster).
-//
-// The (virtual) base address of the associated segment is:
-//       SEG_MWR_BASE + cluster_xy * PERI_CLUSTER_INCREMENT
-//
-// SEG_MWR_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h
-////////////////////////////////////////////////////////////////////////////////
 
 #include <giet_config.h>
 #include <hard_config.h>
+#include <mapping_info.h>
 #include <mwr_driver.h>
 #include <utils.h>
 #include <tty0.h>
+#include <io.h>
 
 #if !defined(X_SIZE) 
@@ -46,55 +38,94 @@
 #endif
 
-//////////////////////////////////////////////////////////////////////////////////
-//    _mwr_hw_init()
-// This function initializes one MWMR controller channel (i.e. one coprocessor
-// port) in a given cluster.
-// - cluster_xy    : cluster index
-// _ port_id       : port index
-// - way           : direction (to_coproc/from_coproc)
-// - channel_pbase : physical base address of the MWMR channel 
-// TODO : The MWMR controler should be modified to support 40 bits addresses...
-//        Introduce a MWMR_CONFIG_PADDR_EXT register in the MWMR coprocessor
-//////////////////////////////////////////////////////////////////////////////////
-// Returns 0 if success, returns > 0 if error.
-//////////////////////////////////////////////////////////////////////////////////
-unsigned int _mwr_hw_init( unsigned int           cluster_xy, 
-                           unsigned int           port_id, 
-                           unsigned int           from_coproc,
-                           paddr_t                channel_pbase ) 
+extern unsigned int _coproc_done[X_SIZE*Y_SIZE];
+
+/////////////////////////////////////////////////////////////////////////////
+// This function returns the value contained in a private register 
+// of the coprocessor contained in cluster "cluster_xy".
+/////////////////////////////////////////////////////////////////////////////
+unsigned int _mwr_get_coproc_register( unsigned int cluster_xy, // cluster
+                                       unsigned int index )     // register 
 {
-    _puts(" [GIET_ERROR] _mwr_hw_init() function not supported yet\n");
-    _exit();
+    unsigned int vaddr =
+        SEG_MWR_BASE + 
+        (cluster_xy * PERI_CLUSTER_INCREMENT) + 
+        (index << 2);
 
-/*
-    // 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; 
+    return ioread32( (void*)vaddr );
+}
 
-    // compute base address
-    unsigned int* mwr_address = (unsigned int*) ( SEG_MWR_BASE + 
-                                 (cluster_xy * PERI_CLUSTER_INCREMENT) );
+/////////////////////////////////////////////////////////////////////////////
+// This function sets a new value in a private register 
+// of the coprocessor contained in cluster "clustenr_xy".
+/////////////////////////////////////////////////////////////////////////////
+void _mwr_set_coproc_register( unsigned int cluster_xy,   // cluster index
+                               unsigned int index,        // register index
+                               unsigned int value )       // writte value
+{
+    unsigned int vaddr =
+        SEG_MWR_BASE + 
+        (cluster_xy * PERI_CLUSTER_INCREMENT) +
+        (index << 2);
+        
+    iowrite32( (void*)vaddr, value );
+}
 
-    unsigned int lsb = (unsigned int)channel_pbase;
-    unsigned int msb = (unsigned int)(channel_pbase>>32);
+/////////////////////////////////////////////////////////////////////////////
+// This function returns the value contained in a channel register 
+// defined by the "index" and "channel" arguments, in the MWMR_DMA component
+// contained in cluster "cluster_xy".
+/////////////////////////////////////////////////////////////////////////////
+unsigned int _mwr_get_channel_register( unsigned int cluster_xy, // cluster 
+                                        unsigned int channel,    // channel 
+                                        unsigned int index )     // register
+{
+    unsigned int vaddr =
+        SEG_MWR_BASE + 
+        (cluster_xy * PERI_CLUSTER_INCREMENT) + 
+        ((channel + 1) * (CHANNEL_SPAN << 2)) +
+        (index << 2);
 
-    // get depth and width from channel itself
-    unsigned int depth = _physical_read( channel_pbase + 16 );
-    unsigned int width = _physical_read( channel_pbase + 20 );
+    return ioread32( (void*)vaddr );
+}
 
-    // initializes and launches mwmr controler
-    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_FIFO_WAY]  = from_coproc;
-    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_FIFO_NO]   = port_id;
-    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_WIDTH]     = width;
-    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_DEPTH]     = depth;
-    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_STATUS]    = lsb;
-    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_DATA]      = lsb + 24;
-    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_EXT]       = msb;
-    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_RUNNING]   = 1;
-*/
-    return 0;
+/////////////////////////////////////////////////////////////////////////////
+// This function sets a new value in a channel register
+// defined by the "index" and "channel") arguments, in the MWMR_DMA component
+// contained in cluster "cluster_xy".
+/////////////////////////////////////////////////////////////////////////////
+void _mwr_set_channel_register( unsigned int cluster_xy,  // cluster index
+                                unsigned int channel,     // channel index
+                                unsigned int index,       // register index
+                                unsigned int value )      // written value
+{
+    unsigned int vaddr =
+        SEG_MWR_BASE + 
+        (cluster_xy * PERI_CLUSTER_INCREMENT) +
+        ((channel + 1) * (CHANNEL_SPAN << 2)) +
+        (index << 2);
+        
+    iowrite32( (void*)vaddr, value );
 }
+
+///////////////////////////////////////////////////////
+void _mwr_isr( unsigned int irq_type,  // should be HWI 
+               unsigned int irq_id,    // index returned by XCU
+               unsigned int channel )  // MWMR_DMA channel
+{
+    unsigned int gpid       = _get_procid();
+    unsigned int cluster_xy = gpid >> P_WIDTH;
+    unsigned int x          = cluster_xy >> Y_WIDTH;
+    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
+
+    // acknowledge IRQ
+    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_RUNNING, 0 );
+
+    // compute coproc_id from cluster coordinates
+    unsigned int coproc_id = x * Y_SIZE + y;
+
+    // set synchronisation variable
+    _coproc_done[coproc_id] = 1;
+}
+
 
 
Index: /soft/giet_vm/giet_drivers/mwr_driver.h
===================================================================
--- /soft/giet_vm/giet_drivers/mwr_driver.h	(revision 517)
+++ /soft/giet_vm/giet_drivers/mwr_driver.h	(revision 518)
@@ -4,48 +4,79 @@
 // Author   : alain greiner
 // Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// The mwr_driver.c and mwr_driver.h files are part ot the GIET-VM OS.
+// This driver supports the SoCLib vci_mwmr_dma component.
+// 
+// It can exist several MWMR_DMA controlers in the architecture 
+// (one per cluster), and each controller can contain several ports. 
+// Each port defines a TO_COPROC or FROM_COPROC communication channel.
+// Each channel can be configured to run in one of three predefined modes
+// (MWMR / DMA_IRQ / DMA_NO_IRQ).
+// The MWMR_DMA controler is a private ressource, allocated to a given task.
+//
+// The virtual base address of the segment associated to the coprocessor
+// addressable registers is:
+//   SEG_MWR_BASE + cluster_xy*PERI_CLUSTER_INCREMENT
+//
+// The virtual base address of the segments associated to a channel is:
+//   SEG_MWR_BASE +
+//   cluster_xy * PERI_CLUSTER_INCREMENT +
+//   4 * CHANNEL_SPAN * (channel+1)
+//
+// The SEG_MWR_BASE virtual address mus be defined in the hard_config.h file.
+///////////////////////////////////////////////////////////////////////////////
 
 #ifndef _GIET_MWR_DRIVERS_H_
 #define _GIET_MWR_DRIVERS_H_
 
-///////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
 // MWMR controler registers offsets 
-///////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
 
-enum SoclibMwmrRegisters 
+enum MwmrDmaRegisters 
 {
-    MWMR_IOREG_MAX = 16,
-    MWMR_RESET = MWMR_IOREG_MAX,
-    MWMR_CONFIG_FIFO_WAY,
-    MWMR_CONFIG_FIFO_NO,
-    MWMR_CONFIG_STATUS,
-    MWMR_CONFIG_DEPTH,
-    MWMR_CONFIG_BUFFER_ADDR,
-    MWMR_CONFIG_RUNNING,
-    MWMR_CONFIG_WIDTH,
-    MWMR_CONFIG_DATA,
-    MWMR_CONFIG_EXT,
-    /***/
-    MWMR_SPAN,
+    CHANNEL_BUFFER_LSB   = 0,     // Data buffer paddr 32 LSB bits
+    CHANNEL_BUFFER_MSB   = 1,     // Data buffer paddr extension
+    CHANNEL_MWMR_LSB     = 2,     // MWMR descriptor paddr 32 LSB bits
+    CHANNEL_MWMR_MSB     = 3,     // MWMR descriptor paddr extension
+    CHANNEL_LOCK_LSB     = 4,     // MWMR lock paddr 32 LSB bits
+    CHANNEL_LOCK_MSB     = 5,     // MWMR lock paddr extension
+    CHANNEL_WAY          = 6,     // TO_COPROC / FROMCOPROC         (Read-only)
+    CHANNEL_MODE         = 7,     // MWMR / DMA / DMA_IRQ 
+    CHANNEL_SIZE         = 8,     // Data Buffer size (bytes)
+    CHANNEL_RUNNING      = 9,     // channel running   
+    CHANNEL_STATUS       = 10,    // channel FSM state              (Read-Only)
+    CHANNEL_INFO         = 11,    // STS | CFG | FROM | TO          (Read-Only)
+    //
+    CHANNEL_SPAN         = 16,
 };
 
-enum SoclibMwmrWay 
-{
-    MWMR_TO_COPROC,
-    MWMR_FROM_COPROC,
-};
+///////////////////////////////////////////////////////////////////////////////
+//           Low-level access functions
+///////////////////////////////////////////////////////////////////////////////
 
-///////////////////////////////////////////////////////////////////////////////////
-// MWMR controller access functions
-///////////////////////////////////////////////////////////////////////////////////
+extern void _mwr_set_channel_register( unsigned int cluster_xy,
+                                       unsigned int channel,
+                                       unsigned int index,
+                                       unsigned int value );
 
-extern unsigned int _mwr_hw_init( unsigned int           cluster_xy, 
-                                  unsigned int           port_id, 
-                                  unsigned int           from_coproc,
-                                  unsigned long long     channel_pbase);
+extern unsigned int _mwr_get_channel_register( unsigned int cluster_xy,
+                                               unsigned int channel,
+                                               unsigned int index );
 
-///////////////////////////////////////////////////////////////////////////////////
+extern void _mwr_set_coproc_register( unsigned int cluster_xy,
+                                      unsigned int index,
+                                      unsigned int value );
 
+extern unsigned int _mwr_get_coproc_register( unsigned int cluster_xy,
+                                              unsigned int index );
 
+///////////////////////////////////////////////////////////////////////////////
+//            Interrupt Service Routine
+///////////////////////////////////////////////////////////////////////////////
+
+extern void _mwr_isr( unsigned int irq_type,
+                      unsigned int irq_id,
+                      unsigned int channel ); 
 #endif
 
