Index: soft/giet_vm/giet_kernel/sys_handler.c
===================================================================
--- soft/giet_vm/giet_kernel/sys_handler.c	(revision 725)
+++ soft/giet_vm/giet_kernel/sys_handler.c	(revision 733)
@@ -313,7 +313,5 @@
     if ( found == 0 )
     {
-
-_printf("@@@ _load_writable_segments() : .elf not found\n");
-
+        _printf("\n[GIET ERROR] _load_writable_segments() : .elf not found\n");
         return 1;
     }
@@ -322,16 +320,11 @@
     if ( _fat_lseek( fd, 0, SEEK_SET ) < 0 )
     {
-
-_printf("@@@ _load_writable_segments() : cannot seek\n");
-
+        _printf("\n[GIET ERROR] _load_writable_segments() : cannot seek\n");
         _fat_close( fd );
         return 1;
-
     }
     if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 )
     {
-
-_printf("@@@ _load_writable_segments() : cannot read\n");
-
+        _printf("\n[GIET ERROR] _load_writable_segments() : cannot read\n");
         _fat_close( fd );
         return 1;
@@ -1146,19 +1139,15 @@
 
 //////////////////////////////////////////////////
-int _sys_coproc_alloc( unsigned int   coproc_type,
-                       unsigned int*  coproc_info )
-{
-    // In this implementation, the allocation policy is constrained:
-    // the coprocessor must be in the same cluster as the calling thread,
-    // and there is at most one coprocessor per cluster
-
+int _sys_coproc_alloc( unsigned int   cluster_xy,
+                       unsigned int   coproc_type,
+                       unsigned int*  return_info )
+{
     mapping_header_t  * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     mapping_cluster_t * cluster = _get_cluster_base(header);
     mapping_periph_t  * periph  = _get_periph_base(header);
 
-    // get cluster coordinates and cluster global index 
-    unsigned int procid     = _get_procid();
-    unsigned int x          = procid >> (Y_WIDTH + P_WIDTH);
-    unsigned int y          = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+    // compute cluster coordinates and cluster index in mapping
+    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
+    unsigned int x          = (cluster_xy>>Y_WIDTH) & ((1<<X_WIDTH)-1);
     unsigned int cluster_id = x * Y_SIZE + y;
  
@@ -1180,5 +1169,5 @@
     if ( found != NULL )
     {
-        // get the lock (at most one coproc per cluster)
+        // get the lock 
         _simple_lock_acquire( &_coproc_lock[cluster_id] );
 
@@ -1191,14 +1180,10 @@
 
         // returns coprocessor info
-        *coproc_info = _coproc_info[cluster_id];
-
-        // register coprocessor coordinates in thread context
-        unsigned int cluster_xy = (x<<Y_WIDTH) + y;
-        _set_context_slot( CTX_COPROC_ID , cluster_xy );
+        *return_info = _coproc_info[cluster_id];
 
 #if GIET_DEBUG_COPROC
 _printf("\n[DEBUG COPROC] _sys_coproc_alloc() at cycle %d\n"
-        "coproc_info = %x / cluster_xy = %x\n",
-        _get_proctime() , *coproc_info , cluster_xy );
+        "type = %d in cluster[%d,%d] / coproc_info = %x\n",
+        _get_proctime() , coproc_type, x , y , *return_info );
 #endif
         return SYSCALL_OK;
@@ -1215,23 +1200,22 @@
 
 ////////////////////////////////////////////////////////
-int _sys_coproc_release( unsigned int coproc_reg_index )
-{
-    // get thread trdid
-    unsigned int trdid = _get_thread_trdid();
-
-    // get coprocessor coordinates
-    unsigned int cluster_xy = _get_context_slot( CTX_COPROC_ID );
-
-    if ( cluster_xy > 0xFF )
+int _sys_coproc_release( unsigned int cluster_xy,
+                         unsigned int coproc_type )
+{
+    // compute cluster coordinates and cluster index 
+    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
+    unsigned int x          = (cluster_xy>>Y_WIDTH) & ((1<<X_WIDTH)-1);
+    unsigned int cluster_id = x * Y_SIZE + y;
+
+    // check coprocessor type
+    if ( _coproc_type[cluster_id] != coproc_type )
     {
          _printf("\n[GIET_ERROR] in _sys_coproc_release(): "
-                 "no coprocessor allocated to thread %x\n", trdid );
+                 "no coprocessor of type %d allocated in cluster[%d,%d]\n", 
+                 coproc_type, x , y );
 
          return SYSCALL_COPROCESSOR_NON_ALLOCATED;
     }
 
-    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;
@@ -1240,12 +1224,9 @@
 
     // stops coprocessor and communication channels
-    _mwr_set_coproc_register( cluster_xy , coproc_reg_index , 0 );
+    _mwr_set_coproc_register( cluster_xy , 0 , 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 thread context
-    _set_context_slot( CTX_COPROC_ID , 0xFFFFFFFF );
 
     // release coprocessor lock
@@ -1254,5 +1235,6 @@
 #if GIET_DEBUG_COPROC
 _printf("\n[DEBUG COPROC] _sys_coproc_release() at cycle %d\n"
-        "thread %x release coprocessor in cluster[%d,%d]\n", cx, cy );
+        "type = %d in cluster[%d,%d]\n",
+        _get_proctime() , coproc_type , x , y );
 #endif
 
@@ -1260,18 +1242,21 @@
 }  // end _sys_coproc_release()
 
-//////////////////////////////////////////////////////////////
-int _sys_coproc_channel_init( unsigned int            channel,
+////////////////////////////////////////////////////////////////
+int _sys_coproc_channel_init( unsigned int            cluster_xy,
+                              unsigned int            coproc_type,
+                              unsigned int            channel,
                               giet_coproc_channel_t*  desc )
 {
-    // get thread trdid
-    unsigned int trdid = _get_thread_trdid();
-
-    // 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(): "
-                 "no coprocessor allocated to thread %x\n", trdid );
+    // compute cluster coordinates and cluster index 
+    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
+    unsigned int x          = (cluster_xy>>Y_WIDTH) & ((1<<X_WIDTH)-1);
+    unsigned int cluster_id = x * Y_SIZE + y;
+
+    // check coprocessor type
+    if ( _coproc_type[cluster_id] != coproc_type )
+    {
+         _printf("\n[GIET_ERROR] in _sys_coproc_release(): "
+                 "no coprocessor of type %d allocated in cluster[%d,%d]\n", 
+                 coproc_type, x , y );
 
          return SYSCALL_COPROCESSOR_NON_ALLOCATED;
@@ -1297,7 +1282,7 @@
     unsigned int       buffer_lsb;
     unsigned int       buffer_msb;
-    unsigned long long mwmr_paddr = 0;
-    unsigned int       mwmr_lsb;
-    unsigned int       mwmr_msb;
+    unsigned long long status_paddr = 0;
+    unsigned int       status_lsb;
+    unsigned int       status_msb;
     unsigned long long lock_paddr = 0;
     unsigned int       lock_lsb;
@@ -1320,11 +1305,11 @@
     {
         // compute MWMR descriptor physical address
-        mwmr_paddr = _v2p_translate( desc->mwmr_vaddr , &flags );
-        mwmr_lsb = (unsigned int)mwmr_paddr;
-        mwmr_msb = (unsigned int)(mwmr_paddr>>32); 
+        status_paddr = _v2p_translate( desc->status_vaddr , &flags );
+        status_lsb = (unsigned int)status_paddr;
+        status_msb = (unsigned int)(status_paddr>>32); 
 
         // call MWMR_DMA driver
-        _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 ); 
+        _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_MWMR_LSB, status_lsb ); 
+        _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_MWMR_MSB, status_msb ); 
 
         // compute lock physical address
@@ -1341,7 +1326,9 @@
 _printf("\n[DEBUG COPROC] _sys_coproc_channel_init() at cycle %d\n"
         "cluster[%d,%d] / channel = %d / mode = %d / buffer_size = %d\n"
-        " buffer_paddr = %l / mwmr_paddr = %l / lock_paddr = %l\n",
+        "buffer_vaddr = %x / status_vaddr = %x / lock_vaddr = %x\n"
+        "buffer_paddr = %l / status_paddr = %l / lock_paddr = %l\n",
         _get_proctime() , x , y , channel , mode , size ,
-        buffer_paddr, mwmr_paddr, lock_paddr );
+        desc->buffer_vaddr, desc->status_vaddr, desc->lock_vaddr,
+        buffer_paddr, status_paddr, lock_paddr );
 #endif
         
@@ -1349,24 +1336,23 @@
 } // end _sys_coproc_channel_init()
 
-////////////////////////////////////////////////////
-int _sys_coproc_run( unsigned int coproc_reg_index )
-{
-    // get thread trdid
-    unsigned int trdid = _get_thread_trdid();
-
-    // 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 thread %d\n", trdid );
+//////////////////////////////////////////////
+int _sys_coproc_run( unsigned int  cluster_xy,
+                     unsigned int  coproc_type )
+{
+    // compute cluster coordinates and cluster index 
+    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
+    unsigned int x          = (cluster_xy>>Y_WIDTH) & ((1<<X_WIDTH)-1);
+    unsigned int cluster_id = x * Y_SIZE + y;
+
+    // check coprocessor type
+    if ( _coproc_type[cluster_id] != coproc_type )
+    {
+         _printf("\n[GIET_ERROR] in _sys_coproc_release(): "
+                 "no coprocessor of type %d allocated in cluster[%d,%d]\n", 
+                 coproc_type, x , y );
 
          return SYSCALL_COPROCESSOR_NON_ALLOCATED;
     }
 
-    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;
@@ -1375,5 +1361,5 @@
     unsigned int channel;
 
-    // register coprocessor running mode 
+    // check channels modes, and register coprocessor running mode 
     for ( channel = 0 ; channel < (nb_from + nb_to) ; channel++ )
     {
@@ -1388,5 +1374,5 @@
         {
             _printf("\n[GIET_ERROR] in _sys_coproc_run(): "
-                    "channels don't have same mode in coprocessor[%d,%d]\n", cx , cy );
+                    "channels don't have same mode in coprocessor[%d,%d]\n", x , y );
 
             return SYSCALL_COPROCESSOR_ILLEGAL_MODE;
@@ -1405,15 +1391,15 @@
     {
         // start coprocessor
-        _mwr_set_coproc_register( cluster_xy , coproc_reg_index , 1 );
+        _mwr_set_coproc_register( cluster_xy , 0 , 1 );
 
 #if GIET_DEBUG_COPROC
 if ( mode == MODE_MWMR )
 _printf("\n[DEBUG COPROC] _sys_coproc_run() at cycle %d\n"
-        "thread %x starts coprocessor[%d,%d] in  MODE_MWMR\n", 
-        _get_proctime() , trdid , cx , cy );
+        "type = %d / cluster[%d,%d] / MODE_MWMR\n", 
+        _get_proctime() , coproc_type , x , y );
 else
 _printf("\n[DEBUG COPROC] _sys_coproc_run() at cycle %d\n"
-        "thread %x starts coprocessor[%d,%d] in  MODE_DMA_NO_IRQ\n", 
-        _get_proctime() , trdid , cx , cy );
+        "type = %d / cluster[%d,%d] / MODE_DMA_NO_IRQ\n", 
+        _get_proctime() , coproc_type , x , y );
 #endif
 
@@ -1423,11 +1409,7 @@
     else                                // mode == MODE_DMA_IRQ => descheduling
     {
-        // set _coproc_trdid
-        unsigned int gpid         = _get_procid();
-        unsigned int x            = gpid >> (Y_WIDTH+P_WIDTH);
-        unsigned int y            = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-        unsigned int p            = gpid & ((1<<P_WIDTH)-1);
-        unsigned int ltid         = _get_thread_ltid();
-        _coproc_trdid[cluster_id] = (x<<24) + (y<<16) + (p<<8) + ltid;
+        // register calling thread trdid
+        unsigned int trdid = _get_thread_trdid();
+        _coproc_trdid[cluster_id] = trdid;
 
         // enters critical section
@@ -1436,15 +1418,16 @@
 
         // set NORUN_MASK_COPROC bit
-        static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
+        static_scheduler_t* psched  = _get_sched();
+        unsigned int        ltid    = _get_thread_ltid();
         unsigned int*       ptr     = &psched->context[ltid].slot[CTX_NORUN_ID];
         _atomic_or( ptr , NORUN_MASK_COPROC );
 
         // start coprocessor
-        _mwr_set_coproc_register( cluster_xy , coproc_reg_index , 1 );
+        _mwr_set_coproc_register( cluster_xy , 0 , 1 );
 
 #if GIET_DEBUG_COPROC
 _printf("\n[DEBUG COPROC] _sys_coproc_run() at cycle %d\n"
-        "thread %x starts coprocessor[%d,%d] in  MODE_DMA_IRQ\n", 
-        _get_proctime() , trdid , cx , cy );
+        "thread %x starts coprocessor / type = %d / cluster[%d,%d] / MODE_DMA_IRQ\n", 
+        _get_proctime() , trdid , coproc_type , x , y );
 #endif
 
@@ -1455,5 +1438,5 @@
 _printf("\n[DEBUG COPROC] _sys_coproc_run() at cycle %d\n"
         "thread %x resume after coprocessor[%d,%d] completion\n", 
-        _get_proctime() , trdid , cx , cy );
+        _get_proctime() , trdid , x , y );
 #endif
 
@@ -1466,25 +1449,24 @@
 } // end _sys_coproc_run()
 
-///////////////////////////
-int _sys_coproc_completed()
-{
-    // get thread trdid
-    unsigned int trdid = _get_thread_trdid();
-
-    // 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 thread %x\n", trdid );
+////////////////////////////////////////////////////
+int _sys_coproc_completed( unsigned int  cluster_xy,
+                           unsigned int  coproc_type )
+{
+    // compute cluster coordinates and cluster index 
+    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
+    unsigned int x          = (cluster_xy>>Y_WIDTH) & ((1<<X_WIDTH)-1);
+    unsigned int cluster_id = x * Y_SIZE + y;
+
+    // check coprocessor type
+    if ( _coproc_type[cluster_id] != coproc_type )
+    {
+         _printf("\n[GIET_ERROR] in _sys_coproc_release(): "
+                 "no coprocessor of type %d allocated in cluster[%d,%d]\n", 
+                 coproc_type, x , y );
 
          return SYSCALL_COPROCESSOR_NON_ALLOCATED;
     }
 
-    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];
+    unsigned int mode = _coproc_mode[cluster_id];
 
     // analyse possible errors
@@ -1527,6 +1509,5 @@
 
             // reset channel
-            _mwr_set_channel_register( cluster_xy, channel,
-                                       MWR_CHANNEL_RUNNING , 0 ); 
+            _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_RUNNING , 0 ); 
 
         }  // end for channels
@@ -1541,6 +1522,6 @@
 #if GIET_DEBUG_COPROC
 _printf("\n[DEBUG COPROC] _sys_coproc_completed() at cycle %d\n"
-        "coprocessor[%d,%d] successfully completes operation for thread %d\n", 
-        cx , cy , trdid );
+        "coprocessor type = %d / cluster[%d,%d] completes operation for thread %d\n", 
+        _get_proctime() , coproc_type , x , y , _get_thread_trdid() );
 #endif
             return SYSCALL_OK;
@@ -1550,5 +1531,5 @@
     {
         _printf("\n[GIET ERROR] in sys_coproc_completed(): "
-                "coprocessor[%d,%d] is not running in MODE_DMA_NO_IRQ\n", cx , cy );
+                "coprocessor[%d,%d] is not running in MODE_DMA_NO_IRQ\n", x , y );
 
         return SYSCALL_COPROCESSOR_ILLEGAL_MODE;
@@ -3146,5 +3127,5 @@
     _cma_set_register( channel, CHBUF_DST_NBUFS, 1 );
     _cma_set_register( channel, CHBUF_BUF_SIZE , FBUF_X_SIZE*FBUF_Y_SIZE );
-    _cma_set_register( channel, CHBUF_PERIOD   , 300 );
+    _cma_set_register( channel, CHBUF_PERIOD   , 1000 );
     _cma_set_register( channel, CHBUF_RUN      , MODE_NO_DST_SYNC );
 
