Index: /soft/giet_vm/giet_kernel/ctx_handler.h
===================================================================
--- /soft/giet_vm/giet_kernel/ctx_handler.h	(revision 555)
+++ /soft/giet_vm/giet_kernel/ctx_handler.h	(revision 556)
@@ -19,21 +19,21 @@
 // allocated to the task (private peripheral channel)
 /////////////////////////////////////////////////////////////////////////////////
-// ctx[0] <- ***   |ctx[8] <- $8     |ctx[16]<- $16   |ctx[24]<- $24
-// ctx[1] <- $1    |ctx[9] <- $9     |ctx[17]<- $17   |ctx[25]<- $25
-// ctx[2] <- $2    |ctx[10]<- $10    |ctx[18]<- $18   |ctx[26]<- LO
-// ctx[3] <- $3    |ctx[11]<- $11    |ctx[19]<- $19   |ctx[27]<- HI
-// ctx[4] <- $4    |ctx[12]<- $12    |ctx[20]<- $20   |ctx[28]<- $28
-// ctx[5] <- $5    |ctx[13]<- $13    |ctx[21]<- $21   |ctx[29]<- SP
-// ctx[6] <- $6    |ctx[14]<- $14    |ctx[22]<- $22   |ctx[30]<- $30
-// ctx[7] <- $7    |ctx[15]<- $15    |ctx[23]<- $23   |ctx[31]<- RA
+// ctx[0] <- ***   |ctx[8] <- $8     |ctx[16]<- $16    |ctx[24]<- $24
+// ctx[1] <- $1    |ctx[9] <- $9     |ctx[17]<- $17    |ctx[25]<- $25
+// ctx[2] <- $2    |ctx[10]<- $10    |ctx[18]<- $18    |ctx[26]<- LO
+// ctx[3] <- $3    |ctx[11]<- $11    |ctx[19]<- $19    |ctx[27]<- HI
+// ctx[4] <- $4    |ctx[12]<- $12    |ctx[20]<- $20    |ctx[28]<- $28
+// ctx[5] <- $5    |ctx[13]<- $13    |ctx[21]<- $21    |ctx[29]<- SP
+// ctx[6] <- $6    |ctx[14]<- $14    |ctx[22]<- $22    |ctx[30]<- $30
+// ctx[7] <- $7    |ctx[15]<- $15    |ctx[23]<- $23    |ctx[31]<- RA
 //
-// ctx[32]<- EPC   |ctx[40]<- TTY    |ctx[48]<- TRDID |ctx[56]<- ***
-// ctx[33]<- CR    |ctx[41]<- CMA_FB |ctx[49]<- GTID  |ctx[57]<- ***
-// ctx[34]<- SR    |ctx[42]<- CMA_RX |ctx[50]<- RUN   |ctx[58]<- ***
-// ctx[35]<- BVAR  |ctx[43]<- CMA_TX |ctx[51]<- ***   |ctx[59]<- ***
-// ctx[36]<- PTAB  |ctx[44]<- NIC_RX |ctx[52]<- ***   |ctx[60]<- ***
-// ctx[37]<- LTID  |ctx[45]<- NIC_TX |ctx[53]<- ***   |ctx[61]<- ***
-// ctx[38]<- VSID  |ctx[46]<- TIM    |ctx[54]<- ***   |ctx[62]<- ***
-// ctx[39]<- PTPR  |ctx[47]<- HBA    |ctx[55]<- ***   |ctx[63]<- ***
+// ctx[32]<- EPC   |ctx[40]<- TTY    |ctx[48]<- TRDID  |ctx[56]<- ***
+// ctx[33]<- CR    |ctx[41]<- CMA_FB |ctx[49]<- GTID   |ctx[57]<- ***
+// ctx[34]<- SR    |ctx[42]<- CMA_RX |ctx[50]<- RUN    |ctx[58]<- ***
+// ctx[35]<- BVAR  |ctx[43]<- CMA_TX |ctx[51]<- COPROC |ctx[59]<- ***
+// ctx[36]<- PTAB  |ctx[44]<- NIC_RX |ctx[52]<- ***    |ctx[60]<- ***
+// ctx[37]<- LTID  |ctx[45]<- NIC_TX |ctx[53]<- ***    |ctx[61]<- ***
+// ctx[38]<- VSID  |ctx[46]<- TIM    |ctx[54]<- ***    |ctx[62]<- ***
+// ctx[39]<- PTPR  |ctx[47]<- HBA    |ctx[55]<- ***    |ctx[63]<- ***
 /////////////////////////////////////////////////////////////////////////////////
 
@@ -71,4 +71,5 @@
 #define CTX_GTID_ID      49  // Global Task Index in all system
 #define CTX_RUN_ID       50  // Boolean: task runable
+#define CTX_COPROC_ID    51  // cluster_xy : coprocessor coordinates
 
 /////////////////////////////////////////////////////////////////////////////////
Index: /soft/giet_vm/giet_kernel/sys_handler.c
===================================================================
--- /soft/giet_vm/giet_kernel/sys_handler.c	(revision 555)
+++ /soft/giet_vm/giet_kernel/sys_handler.c	(revision 556)
@@ -70,5 +70,10 @@
 // allocated in mwr_driver.c file.
 extern simple_lock_t  _coproc_lock[X_SIZE*Y_SIZE];
-extern unsigned int   _coproc_done[X_SIZE*Y_SIZE];
+extern unsigned int   _coproc_type[X_SIZE*Y_SIZE];
+extern unsigned int   _coproc_info[X_SIZE*Y_SIZE];
+extern unsigned int   _coproc_mode[X_SIZE*Y_SIZE];
+extern unsigned int   _coproc_error[X_SIZE*Y_SIZE];
+extern unsigned int   _coproc_gtid[X_SIZE*Y_SIZE];
+
 
 // allocated in tty_driver.c file.
@@ -125,71 +130,71 @@
 const void * _syscall_vector[64] = 
 {
-    &_sys_proc_xyp,             /* 0x00 */
-    &_get_proctime,             /* 0x01 */
-    &_sys_tty_write,            /* 0x02 */
-    &_sys_tty_read,             /* 0x03 */
-    &_sys_tty_alloc,            /* 0x04 */
-    &_sys_tty_get_lock,         /* 0x05 */
-    &_sys_tty_release_lock,     /* 0x06 */
-    &_sys_heap_info,            /* 0x07 */
-    &_sys_local_task_id,        /* 0x08 */
-    &_sys_global_task_id,       /* 0x09 */ 
-    &_sys_fbf_cma_alloc,        /* 0x0A */
-    &_sys_fbf_cma_start,        /* 0x0B */
-    &_sys_fbf_cma_display,      /* 0x0C */
-    &_sys_fbf_cma_stop,         /* 0x0D */
-    &_sys_task_exit,            /* 0x0E */
-    &_sys_procs_number,         /* 0x0F */
-
-    &_sys_fbf_sync_write,       /* 0x10 */
-    &_sys_fbf_sync_read,        /* 0x11 */
-    &_sys_thread_id,            /* 0x12 */
-    &_sys_ukn,                  /* 0x13 */
-    &_sys_tim_alloc,            /* 0x14 */
-    &_sys_tim_start,            /* 0x15 */ 
-    &_sys_tim_stop,             /* 0x16 */
-    &_sys_ukn,                  /* 0x17 */
-    &_sys_ukn,                  /* 0x18 */   
-    &_sys_context_switch,       /* 0x19 */
-    &_sys_vseg_get_vbase,       /* 0x1A */
-    &_sys_vseg_get_length,      /* 0x1B */
-    &_sys_xy_from_ptr,          /* 0x1C */
-    &_sys_ukn,                  /* 0x1D */
-    &_sys_ukn,                  /* 0x1E */
-    &_sys_ukn,                  /* 0x1F */
-
-    &_fat_user_open,            /* 0x20 */
-    &_fat_user_read,            /* 0x21 */
-    &_fat_user_write,           /* 0x22 */
-    &_fat_user_lseek,           /* 0x23 */
-    &_fat_fstat,                /* 0x24 */
-    &_fat_close,                /* 0x25 */
-    &_sys_ukn,                  /* 0x26 */
-    &_sys_ukn,                  /* 0x27 */
-    &_sys_ukn,                  /* 0x28 */
-    &_sys_ukn,                  /* 0x29 */
-    &_sys_ukn,                  /* 0x2A */
-    &_sys_ukn,                  /* 0x2B */
-    &_sys_ukn,                  /* 0x2C */
-    &_sys_ukn,                  /* 0x2D */
-    &_sys_ukn,                  /* 0x2E */
-    &_sys_ukn,                  /* 0x2F */
-
-    &_sys_nic_alloc,            /* 0x30 */
-    &_sys_nic_start,            /* 0x31 */
-    &_sys_nic_move,             /* 0x32 */
-    &_sys_nic_stop,             /* 0x33 */
-    &_sys_nic_stats,            /* 0x34 */
-    &_sys_nic_clear,            /* 0x35 */ 
-    &_sys_ukn,                  /* 0x36 */
-    &_sys_ukn,                  /* 0x37 */
-    &_sys_coproc_register_get,  /* 0x38 */   
-    &_sys_coproc_register_set,  /* 0x39 */
-    &_sys_coproc_release,       /* 0x3A */
-    &_sys_coproc_completed,     /* 0x3B */
-    &_sys_coproc_alloc,         /* 0x3C */
-    &_sys_coproc_channel_init,  /* 0x3D */
-    &_sys_coproc_channel_start, /* 0x3E */
-    &_sys_coproc_channel_stop,  /* 0x3F */
+    &_sys_proc_xyp,                  /* 0x00 */
+    &_get_proctime,                  /* 0x01 */
+    &_sys_tty_write,                 /* 0x02 */
+    &_sys_tty_read,                  /* 0x03 */
+    &_sys_tty_alloc,                 /* 0x04 */
+    &_sys_tty_get_lock,              /* 0x05 */
+    &_sys_tty_release_lock,          /* 0x06 */
+    &_sys_heap_info,                 /* 0x07 */
+    &_sys_local_task_id,             /* 0x08 */
+    &_sys_global_task_id,            /* 0x09 */ 
+    &_sys_fbf_cma_alloc,             /* 0x0A */
+    &_sys_fbf_cma_start,             /* 0x0B */
+    &_sys_fbf_cma_display,           /* 0x0C */
+    &_sys_fbf_cma_stop,              /* 0x0D */
+    &_sys_task_exit,                 /* 0x0E */
+    &_sys_procs_number,              /* 0x0F */
+
+    &_sys_fbf_sync_write,            /* 0x10 */
+    &_sys_fbf_sync_read,             /* 0x11 */
+    &_sys_thread_id,                 /* 0x12 */
+    &_sys_ukn,                       /* 0x13 */
+    &_sys_tim_alloc,                 /* 0x14 */
+    &_sys_tim_start,                 /* 0x15 */ 
+    &_sys_tim_stop,                  /* 0x16 */
+    &_sys_ukn,                       /* 0x17 */
+    &_sys_ukn,                       /* 0x18 */   
+    &_sys_context_switch,            /* 0x19 */
+    &_sys_vseg_get_vbase,            /* 0x1A */
+    &_sys_vseg_get_length,           /* 0x1B */
+    &_sys_xy_from_ptr,               /* 0x1C */
+    &_sys_ukn,                       /* 0x1D */
+    &_sys_ukn,                       /* 0x1E */
+    &_sys_ukn,                       /* 0x1F */
+
+    &_fat_user_open,                 /* 0x20 */
+    &_fat_user_read,                 /* 0x21 */
+    &_fat_user_write,                /* 0x22 */
+    &_fat_user_lseek,                /* 0x23 */
+    &_fat_fstat,                     /* 0x24 */
+    &_fat_close,                     /* 0x25 */
+    &_sys_ukn,                       /* 0x26 */
+    &_sys_ukn,                       /* 0x27 */
+    &_sys_ukn,                       /* 0x28 */
+    &_sys_ukn,                       /* 0x29 */
+    &_sys_ukn,                       /* 0x2A */
+    &_sys_ukn,                       /* 0x2B */
+    &_sys_ukn,                       /* 0x2C */
+    &_sys_ukn,                       /* 0x2D */
+    &_sys_ukn,                       /* 0x2E */
+    &_sys_ukn,                       /* 0x2F */
+
+    &_sys_nic_alloc,                 /* 0x30 */
+    &_sys_nic_start,                 /* 0x31 */
+    &_sys_nic_move,                  /* 0x32 */
+    &_sys_nic_stop,                  /* 0x33 */
+    &_sys_nic_stats,                 /* 0x34 */
+    &_sys_nic_clear,                 /* 0x35 */ 
+    &_sys_ukn,                       /* 0x36 */
+    &_sys_ukn,                       /* 0x37 */
+    &_sys_ukn,                       /* 0x38 */   
+    &_sys_ukn,                       /* 0x39 */
+    &_sys_ukn,                       /* 0x3A */
+    &_sys_coproc_completed,          /* 0x3B */
+    &_sys_coproc_alloc,              /* 0x3C */
+    &_sys_coproc_channel_init,       /* 0x3D */
+    &_sys_coproc_run,                /* 0x3E */
+    &_sys_coproc_release,            /* 0x3F */
 };
 
@@ -199,34 +204,11 @@
 //////////////////////////////////////////////////////////////////////////////
 
-///////////////////////////////////////////////////////
-int _sys_coproc_register_set( unsigned int  cluster_xy,
-                              unsigned int  reg_index,
-                              unsigned int  value )
-{
-    // TODO checking coprocessor ownership...
-
-    _mwr_set_coproc_register( cluster_xy , reg_index , value );
-    return 0;
-}  
-
-///////////////////////////////////////////////////////
-int _sys_coproc_register_get( unsigned int   cluster_xy,
-                              unsigned int   reg_index,
-                              unsigned int*  buffer )
-{
-    // TODO checking coprocessor ownership...
-
-    *buffer = _mwr_get_coproc_register( cluster_xy , reg_index );
-    return 0;
-}  
-
 //////////////////////////////////////////////////
 int _sys_coproc_alloc( unsigned int   coproc_type,
-                       unsigned int*  coproc_info,
-                       unsigned int*  cluster_xy )
+                       unsigned int*  coproc_info )
 {
     // In this implementation, the allocation policy is constrained:
     // the coprocessor must be in the same cluster as the calling task,
-    // and ther is at most one coprocessor per cluster
+    // and there is at most one coprocessor per cluster
 
     mapping_header_t  * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
@@ -238,5 +220,5 @@
     unsigned int x          = procid >> (Y_WIDTH + P_WIDTH);
     unsigned int y          = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-    unsigned int cluster_id = x*Y_SIZE + y;
+    unsigned int cluster_id = x * Y_SIZE + y;
  
     // search coprocessor in cluster
@@ -259,16 +241,23 @@
         // get the lock (at most one coproc per cluster)
         _simple_lock_acquire( &_coproc_lock[cluster_id] );
- 
+
+        // register coproc characteristics in kernel arrays
+        _coproc_type[cluster_id] = coproc_type;
+        _coproc_info[cluster_id] = (found->arg0 & 0xFF)     |
+                                   (found->arg1 & 0xFF)<<8  |
+                                   (found->arg2 & 0xFF)<<16 |
+                                   (found->arg3 & 0xFF)<<24 ;
+
         // returns coprocessor info
-        *coproc_info = (found->arg0 & 0xFF)     |
-                       (found->arg1 & 0xFF)<<8  |
-                       (found->arg2 & 0xFF)<<16 |
-                       (found->arg3 & 0xFF)<<24 ;
-        *cluster_xy = (x<<Y_WIDTH) + y;
+        *coproc_info = _coproc_info[cluster_id];
+
+        // register coprocessor coordinates in task context
+        unsigned int cluster_xy = (x<<Y_WIDTH) + y;
+        _set_context_slot( CTX_COPROC_ID , cluster_xy );
 
 #if GIET_DEBUG_COPROC
 _printf("\n[GIET DEBUG COPROC] _sys_coproc_alloc() in cluster[%d,%d]\n"
         "  coproc_info = %x / cluster_xy = %x\n",
-        x , y , *coproc_info , *cluster_xy );
+        x , y , *coproc_info , cluster_xy );
 #endif
         return 0;
@@ -283,31 +272,47 @@
 }  // end _sys_coproc_alloc()
 
-//////////////////////////////////////////////////
-int _sys_coproc_release( unsigned int cluster_xy )
-{
-    // TODO checking coprocessor ownership...
-
-    // check cluster coordinates
-    unsigned int cx     = cluster_xy >> Y_WIDTH;
-    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
+////////////////////////////////////////////////////////
+int _sys_coproc_release( unsigned int coproc_reg_index )
+{
+    // processor coordinates
     unsigned int procid = _get_procid();
     unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
     unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-    if ( (x != cx) || (y != cy) )
-    {
-         _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): "
-                 "wrong cluster coordinates\n");
+    unsigned int p      = procid & ((1<<P_WIDTH)-1);
+    
+    // get coprocessor coordinates
+    unsigned int cluster_xy = _get_context_slot( CTX_COPROC_ID );
+    if ( cluster_xy > 0xFF )
+    {
+         _printf("\n[GIET_ERROR] in _sys_coproc_release(): "
+                 "no coprocessor allocated to task running on P[%d,%d,%d]\n",
+                 x , y , p ); 
          return -1;
     }
 
-    // compute coprocessor global index 
-    unsigned int coproc_id = x * Y_SIZE + y;
-
-    // release coprocessor
-    _simple_lock_release( &_coproc_lock[coproc_id] );
+    unsigned int cx         = cluster_xy >> Y_WIDTH;
+    unsigned int cy         = cluster_xy & ((1<<Y_WIDTH)-1);
+    unsigned int cluster_id = cx * Y_SIZE + cy;
+    unsigned int info       = _coproc_info[cluster_id];
+    unsigned int nb_to      = info & 0xFF;
+    unsigned int nb_from    = (info>>8) & 0xFF;
+    unsigned int channel;
+
+    // stops coprocessor and communication channels
+    _mwr_set_coproc_register( cluster_xy , coproc_reg_index , 0 );
+    for ( channel = 0 ; channel < (nb_from + nb_to) ; channel++ )
+    {
+        _mwr_set_channel_register( cluster_xy , channel , MWR_CHANNEL_RUNNING , 0 );
+    }
+
+    // deallocates coprocessor coordinates in task context
+    _set_context_slot( CTX_COPROC_ID , 0xFFFFFFFF );
+
+    // release coprocessor lock
+    _simple_lock_release( &_coproc_lock[cluster_id] );
 
 #if GIET_DEBUG_COPROC
 _printf("\n[GIET DEBUG COPROC] _sys_coproc_release() in cluster[%d,%d]\n",
-        x, y );
+        cx, cy );
 #endif
 
@@ -315,21 +320,21 @@
 }  // end _sys_coproc_release()
 
-/////////////////////////////////////////////////////////////////
-int _sys_coproc_channel_init( unsigned int            cluster_xy,
-                              unsigned int            channel,
+//////////////////////////////////////////////////////////////
+int _sys_coproc_channel_init( unsigned int            channel,
                               giet_coproc_channel_t*  desc )
 {
-    // TODO checking coprocessor ownership...
-
-    // check cluster coordinates
-    unsigned int cx     = cluster_xy >> Y_WIDTH;
-    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
+    // processor coordinates
     unsigned int procid = _get_procid();
     unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
     unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-    if ( (x != cx) || (y != cy) )
+    unsigned int p      = procid & ((1<<P_WIDTH)-1);
+    
+    // get coprocessor coordinates
+    unsigned int cluster_xy = _get_context_slot( CTX_COPROC_ID );
+    if ( cluster_xy > 0xFF )
     {
          _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): "
-                 "wrong cluster coordinates\n");
+                 "no coprocessor allocated to task running on P[%d,%d,%d]\n",
+                 x , y , p ); 
          return -1;
     }
@@ -341,5 +346,5 @@
          (mode != MODE_DMA_NO_IRQ) )
     {
-         _printf("\n[GIET_ERROR] in _sys_coproc_channel_init():"
+         _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): "
                  " illegal mode\n");
          return -1;
@@ -353,8 +358,8 @@
     unsigned int       buffer_lsb;
     unsigned int       buffer_msb;
-    unsigned long long mwmr_paddr;
+    unsigned long long mwmr_paddr = 0;
     unsigned int       mwmr_lsb;
     unsigned int       mwmr_msb;
-    unsigned long long lock_paddr;
+    unsigned long long lock_paddr = 0;
     unsigned int       lock_lsb;
     unsigned int       lock_msb;
@@ -368,8 +373,8 @@
 
     // call MWMR_DMA driver
-    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_MODE, mode ); 
-    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_SIZE, size ); 
-    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_BUFFER_LSB, buffer_lsb ); 
-    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_BUFFER_MSB, buffer_msb ); 
+    _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_MODE, mode ); 
+    _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_SIZE, size ); 
+    _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_BUFFER_LSB, buffer_lsb ); 
+    _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_BUFFER_MSB, buffer_msb ); 
                        
     if ( mode == MODE_MWMR )
@@ -381,6 +386,6 @@
 
         // call MWMR_DMA driver
-        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_MWMR_LSB, mwmr_lsb ); 
-        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_MWMR_MSB, mwmr_msb ); 
+        _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_MWMR_LSB, mwmr_lsb ); 
+        _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_MWMR_MSB, mwmr_msb ); 
 
         // compute lock physical address
@@ -390,10 +395,10 @@
 
         // call MWMR_DMA driver
-        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_LOCK_LSB, lock_lsb ); 
-        _mwr_set_channel_register( cluster_xy, channel, CHANNEL_LOCK_MSB, lock_msb ); 
+        _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_LOCK_LSB, lock_lsb ); 
+        _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_LOCK_MSB, lock_msb ); 
     }
 
 #if GIET_DEBUG_COPROC
-_printf("\n[GIET DEBUG COPROC] _sys_coproc_channel_init() in cluster[%d,%d]\n"
+_printf("\n[GIET DEBUG COPROC] _sys_coproc_channel_init() for coproc[%d,%d]\n"
         " channel =  %d / mode = %d / buffer_size = %d\n"
         " buffer_paddr = %l / mwmr_paddr = %l / lock_paddr = %l\n",
@@ -405,97 +410,194 @@
 } // end _sys_coproc_channel_init()
 
-////////////////////////////////////////////////////////
-int _sys_coproc_channel_start( unsigned int  cluster_xy,
-                               unsigned int  channel )
-{
-    // TODO checking coprocessor ownership...
-
-    // check cluster coordinates
-    unsigned int cx     = cluster_xy >> Y_WIDTH;
-    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
+////////////////////////////////////////////////////
+int _sys_coproc_run( unsigned int coproc_reg_index )
+{
+    // processor coordinates
     unsigned int procid = _get_procid();
     unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
     unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-    if ( (x != cx) || (y != cy) )
-    {
-         _printf("\n[GIET_ERROR] in _sys_coproc_channel_start():"
-                 " wrong coordinates\n");
+    unsigned int p      = procid & ((1<<P_WIDTH)-1);
+    
+    // get coprocessor coordinates
+    unsigned int cluster_xy = _get_context_slot( CTX_COPROC_ID );
+    if ( cluster_xy > 0xFF )
+    {
+         _printf("\n[GIET_ERROR] in _sys_coproc_run(): "
+                 "no coprocessor allocated to task running on P[%d,%d,%d]\n",
+                 x , y , p ); 
          return -1;
     }
- 
-    // reset synchronisation variable
-    unsigned int coproc_id = (x * Y_SIZE) + y;
-    _coproc_done[coproc_id] = 0;
-
-    // call MWMR_DMA driver
-    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_RUNNING, 1 ); 
+
+    unsigned int cx         = cluster_xy >> Y_WIDTH;
+    unsigned int cy         = cluster_xy & ((1<<Y_WIDTH)-1);
+    unsigned int cluster_id = cx * Y_SIZE + cy;
+    unsigned int info       = _coproc_info[cluster_id];
+    unsigned int nb_to      = info & 0xFF;
+    unsigned int nb_from    = (info>>8) & 0xFF;
+    unsigned int mode       = 0xFFFFFFFF;
+    unsigned int channel;
+
+    // register coprocessor running mode 
+    for ( channel = 0 ; channel < (nb_from + nb_to) ; channel++ )
+    {
+        unsigned int temp;
+        temp = _mwr_get_channel_register( cluster_xy , channel , MWR_CHANNEL_MODE );
+
+        if ( mode == 0xFFFFFFFF ) 
+        {
+            mode = temp;
+        }
+        else if ( temp != mode )
+        {
+            _printf("\n[GIET_ERROR] P[%d,%d,%d] in _sys_coproc_run() for coprocessor[%d,%d]\n"
+                    "  all channels don't have the same mode\n", x , y , p , cx , cy );
+            return -1;
+        }
+    }
+    _coproc_mode[cluster_id] = mode;
+
+    // start all communication channels
+    for ( channel = 0 ; channel < (nb_from + nb_to) ; channel++ )
+    {
+        _mwr_set_channel_register( cluster_xy , channel , MWR_CHANNEL_RUNNING , 1 );
+    }
+
+    //////////////////////////////////////////////////////////////////////////
+    if ( (mode == MODE_MWMR) || (mode == MODE_DMA_NO_IRQ) )  // no descheduling
+    {
+        // start coprocessor
+        _mwr_set_coproc_register( cluster_xy , coproc_reg_index , 1 );
 
 #if GIET_DEBUG_COPROC
-_printf("\n[GIET DEBUG COPROC] _sys_coproc_channel_start() in cluster[%d,%d]"
-        " / channel = %d\n", x , y , channel );
-#endif
-
-    return 0;
-} // end _sys_coproc_channel_start()
-
-///////////////////////////////////////////////////////
-int _sys_coproc_channel_stop( unsigned int  cluster_xy,
-                              unsigned int  channel )
-{
-    // TODO checking coprocessor ownership...
-
-    // check cluster coordinates
-    unsigned int cx     = cluster_xy >> Y_WIDTH;
-    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
+if ( mode == MODE_MWMR )
+_printf("\n[GIET DEBUG COPROC] _sys_coproc_run() P[%d,%d,%d] starts coprocessor[%d,%d]\n"
+        "   MODE_MWMR at cycle %d\n", x , y , p , cx , cy , _get_proctime() );
+else
+_printf("\n[GIET DEBUG COPROC] _sys_coproc_run() P[%d,%d,%d] starts coprocessor[%d,%d]\n"
+        "   MODE_DMA_NO_IRQ at cycle %d\n", x , y , p , cx , cy , _get_proctime() );
+#endif
+
+        return 0;
+    }
+    ///////////////////////////////////////////////////////////////////////////
+    else                                // mode == MODE_DMA_IRQ => descheduling
+    {
+        // set _coproc_gtid 
+        unsigned int ltid = _get_current_task_id();
+        _coproc_gtid[cluster_id] = (procid<<16) + ltid;
+
+        // enters critical section
+        unsigned int save_sr;
+        _it_disable( &save_sr ); 
+
+        // reset runnable 
+        _set_task_slot( x, y, p, ltid, CTX_RUN_ID, 0 );  
+
+        // start coprocessor
+        _mwr_set_coproc_register( cluster_xy , coproc_reg_index , 1 );
+
+#if GIET_DEBUG_COPROC
+_printf("\n[GIET DEBUG COPROC] _sys_coproc_run() P[%d,%d,%d] starts coprocessor[%d,%d]\n"
+        "   MODE_DMA_IRQ at cycle %d\n", x , y , p , cx , cy , _get_proctime() );
+#endif
+
+        // deschedule task
+        _ctx_switch(); 
+
+#if GIET_DEBUG_COPROC
+_printf("\n[GIET DEBUG COPROC] _sys_coproc_run() P[%d,%d,%d] resume\n"
+        "  coprocessor[%d,%d] completion at cycle %d\n", 
+        x , y , p , cx , cy , _get_proctime() );
+#endif
+
+        // restore SR
+        _it_restore( &save_sr );
+
+        // return error computed by mwr_isr()
+        return _coproc_error[cluster_id];
+    } 
+} // end _sys_coproc_run()
+
+///////////////////////////
+int _sys_coproc_completed()
+{
+    // processor coordinates
     unsigned int procid = _get_procid();
     unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
     unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-    if ( (x != cx) || (y != cy) )
-    {
-         _printf("\n[GIET_ERROR] in _sys_coproc_channel_stop(): wrong coordinates\n");
+    unsigned int p      = procid & ((1<<P_WIDTH)-1);
+    
+    // get coprocessor coordinates
+    unsigned int cluster_xy = _get_context_slot( CTX_COPROC_ID );
+    if ( cluster_xy > 0xFF )
+    {
+         _printf("\n[GIET_ERROR] in _sys_coproc_completed(): "
+                 "no coprocessor allocated to task running on P[%d,%d,%d]\n",
+                 x , y , p ); 
          return -1;
     }
- 
-    // call MWMR_DMA driver
-    _mwr_set_channel_register( cluster_xy, channel, CHANNEL_RUNNING, 0 );
+
+    unsigned int cx         = cluster_xy >> Y_WIDTH;
+    unsigned int cy         = cluster_xy & ((1<<Y_WIDTH)-1);
+    unsigned int cluster_id = cx * Y_SIZE + cy;
+    unsigned int mode       = _coproc_mode[cluster_id];
+
+    // analyse possible errors
+    if ( mode == MODE_DMA_NO_IRQ )
+    {
+        unsigned int info       = _coproc_info[cluster_id];
+        unsigned int nb_to      = info & 0xFF;
+        unsigned int nb_from    = (info>>8) & 0xFF;
+        unsigned int error      = 0;
+        unsigned int channel;
+        unsigned int status;
+
+        // get status for all channels, and signal all reported errors
+        for ( channel = 0 ; channel < (nb_to +nb_from) ; channel++ )
+        {
+            do
+            {
+                status = _mwr_get_channel_register( cluster_xy , channel , MWR_CHANNEL_STATUS );
+                if ( status == MWR_CHANNEL_ERROR_DATA )
+                {
+                    _printf("\n[GIET_ERROR] in _sys_coproc_completed()"
+                            " / channel %d / DATA_ERROR\n", channel );
+                    error = 1;
+                    break;
+                }
+                else if ( status == MWR_CHANNEL_ERROR_LOCK )
+                {
+                    _printf("\n[GIET_ERROR] in _sys_coproc_completed()"
+                            " / channel %d / LOCK_ERROR\n", channel );
+                    error = 1;
+                    break;
+                }
+                else if ( status == MWR_CHANNEL_ERROR_DESC )
+                {
+                    _printf("\n[GIET_ERROR] in _sys_coproc_completed()"
+                            " / channel %d / DESC_ERROR\n", channel );
+                    error = 1;
+                    break;
+                }
+            } while ( status == MWR_CHANNEL_BUSY );
+
+            // reset channel
+            _mwr_set_channel_register( cluster_xy , channel , MWR_CHANNEL_RUNNING , 0 ); 
+
+        }  // end for channels
 
 #if GIET_DEBUG_COPROC
-_printf("\n[GIET DEBUG COPROC] _sys_coproc_channel_stop() in cluster[%d,%d]"
-        " / channel = %d\n", x , y , channel );
-#endif
-
-    return 0;
-} // end _sys_coproc_channel_stop()
-
-/////////////////////////////////////////////////////
-int _sys_coproc_completed( unsigned int  cluster_xy )
-{
-    // TODO checking coprocessor ownership...
-
-    // check cluster coordinates
-    unsigned int cx     = cluster_xy >> Y_WIDTH;
-    unsigned int cy     = cluster_xy & ((1<<Y_WIDTH)-1);
-    unsigned int procid = _get_procid();
-    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
-    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-    if ( (x != cx) || (y != cy) )
-    {
-         _printf("\n[GIET_ERROR] in _sys_coproc_completed(): "
-                 "wrong cluster coordinates\n");
-         return -1;
-    }
- 
-    // polling the synchronisation variable
-    unsigned int coproc_id = (x * Y_SIZE) + y;
-    while ( ioread32( &_coproc_done[coproc_id]) == 0 ) asm volatile("nop");
-
-    _coproc_done[coproc_id] = 0;
-
-#if GIET_DEBUG_COPROC
-_printf("\n[GIET DEBUG COPROC] _sys_coproc_completed() in cluster[%d,%d]\n", 
-        x, y );
-#endif
-
-    return 0;
+_printf("\n[GIET DEBUG COPROC] _sys_coproc_completed() for coprocessor[%d,%d] error = %d\n", 
+        cx , cy , error );
+#endif
+
+        return error;
+    }
+    else  // mode == MODE_MWMR or MODE_DMA_IRQ
+    {
+        _printf("\n[GIET ERROR] sys_coproc_completed() should not be called for "
+                "coprocessor[%d,%d] running in MODE_MWMR or MODE_DMA_IRQ\n", cx , cy );
+        return 1;
+    }
 } // end _sys_coproc_completed()
 
Index: /soft/giet_vm/giet_kernel/sys_handler.h
===================================================================
--- /soft/giet_vm/giet_kernel/sys_handler.h	(revision 555)
+++ /soft/giet_vm/giet_kernel/sys_handler.h	(revision 556)
@@ -83,20 +83,14 @@
 
 int _sys_coproc_alloc( unsigned int   coproc_type,
-                       unsigned int*  coproc_info,
-                       unsigned int*  cluster_xy );
-
-int _sys_coproc_release( unsigned int cluster_xy );
-
-int _sys_coproc_channel_init( unsigned int            cluster_xy,
-                              unsigned int            channel,
+                       unsigned int*  coproc_info );
+
+int _sys_coproc_release( unsigned int coproc_reg_index );
+
+int _sys_coproc_channel_init( unsigned int            channel,
                               giet_coproc_channel_t*  desc );
 
-int _sys_coproc_channel_start( unsigned int  cluster_xy,
-                               unsigned int  channel );
-
-int _sys_coproc_channel_stop( unsigned int  cluster_xy,
-                              unsigned int  channel );
-
-int _sys_coproc_completed( unsigned int cluster_xy );
+int _sys_coproc_run( unsigned int coproc_reg_index );
+
+int _sys_coproc_completed();
 
 ///////////////////////////////////////////////////////////////////////////////
