Index: /soft/giet_vm/giet_drivers/bdv_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/bdv_driver.c	(revision 629)
+++ /soft/giet_vm/giet_drivers/bdv_driver.c	(revision 630)
@@ -23,4 +23,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////
+//      Extern variables
+///////////////////////////////////////////////////////////////////////////////
+
+// allocated in the boot.c or kernel_init.c files
+extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 
+ 
+///////////////////////////////////////////////////////////////////////////////
 //      Global variables
 ///////////////////////////////////////////////////////////////////////////////
@@ -162,6 +169,8 @@
         _it_disable( &save_sr ); 
 
-        // reset runnable 
-        _set_task_slot( x, y, p, ltid, CTX_RUN_ID, 0 );  
+        // Set NORUN_MASK_IOC bit 
+        static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
+        unsigned int*       ptr     = &psched->context[ltid][CTX_NORUN_ID];
+        _atomic_or( ptr , NORUN_MASK_IOC );
         
         // launch transfer
@@ -234,34 +243,31 @@
 
     // identify task waiting on BDV
-    unsigned int remote_procid  = _bdv_gtid>>16;
-    unsigned int ltid           = _bdv_gtid & 0xFFFF;
-    unsigned int remote_cluster = remote_procid >> P_WIDTH;
-    unsigned int remote_x       = remote_cluster >> Y_WIDTH;
-    unsigned int remote_y       = remote_cluster & ((1<<Y_WIDTH)-1);
-    unsigned int remote_p       = remote_procid & ((1<<P_WIDTH)-1);
-
-    // re-activates sleeping task
-    _set_task_slot( remote_x,
-                    remote_y,
-                    remote_p,
-                    ltid,        
-                    CTX_RUN_ID,  // CTX_RUN slot 
-                    1 );         // running value
+    unsigned int procid  = _bdv_gtid>>16;
+    unsigned int ltid    = _bdv_gtid & 0xFFFF;
+    unsigned int cluster = procid >> P_WIDTH;
+    unsigned int x       = cluster >> Y_WIDTH;
+    unsigned int y       = cluster & ((1<<Y_WIDTH)-1);
+    unsigned int p       = procid & ((1<<P_WIDTH)-1);
+
+    // Reset NORUN_MASK_IOC bit 
+    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
+    unsigned int*       ptr     = &psched->context[ltid][CTX_NORUN_ID];
+    _atomic_and( ptr , ~NORUN_MASK_IOC );
 
     // send a WAKUP WTI to processor running the sleeping task 
-    _xcu_send_wti( remote_cluster,   
-                   remote_p, 
+    _xcu_send_wti( cluster,   
+                   p, 
                    0 );          // don't force context switch 
 
 #if GIET_DEBUG_IOC  
-unsigned int procid  = _get_procid();
-unsigned int x       = procid >> (Y_WIDTH + P_WIDTH);
-unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
-unsigned int p       = procid & ((1<<P_WIDTH)-1);
+unsigned int pid  = _get_procid();
+unsigned int c_x  = pid >> (Y_WIDTH + P_WIDTH);
+unsigned int c_y  = (pid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
+unsigned int c_p  = pid & ((1<<P_WIDTH)-1);
 if ( _get_proctime() > GIET_DEBUG_IOC )
 _printf("\n[BDV DEBUG] Processor[%d,%d,%d] enters _bdv_isr() at cycle %d\n"
         "  for task %d running on P[%d,%d,%d] / bdv_status = %x\n",
-        x , y , p , _get_proctime() ,
-        ltid , remote_x , remote_y , remote_p , status );
+        c_x , c_y , c_p , _get_proctime() ,
+        ltid , x , y , p , status );
 #endif
 
Index: /soft/giet_vm/giet_drivers/hba_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/hba_driver.c	(revision 629)
+++ /soft/giet_vm/giet_drivers/hba_driver.c	(revision 630)
@@ -23,13 +23,18 @@
 #include <vmem.h>
 
-///////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+//      Extern variables
+//////////////////////////////////////////////////////////////////////////////////
+
+// allocated in the boot.c or kernel_init.c files
+extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 
+
+//////////////////////////////////////////////////////////////////////////////////
 //               Global variables
-///////////////////////////////////////////////////////////////////////////////////
-
 //////////////////////////////////////////////////////////////////////////////////
 // The global variable hba_boot_mode defines the way the HBA component is used
 // and must be defined in both kernel_init.c and boot.c files.
-// - during the boot phase, only one processor has access to the HBA in synchronous
-//   mode, there is no need for the allocator to use a lock
+// - during the boot phase, only one processor access the HBA in synchronous
+//   mode. There is no need for the allocator to use a lock.
 // - after the boot phase, the HBA device can be used by several processors. The
 //   allocator is protected by a sqt_lock.
@@ -278,5 +283,5 @@
     // in descheduling mode, we deschedule the task
     // and use an interrupt to reschedule the task.
-    // We need a critical section, because we must reset the RUN bit
+    // We need a critical section, because we must set the NORUN bit
 	// before to launch the transfer, and we don't want to be 
     // descheduled between these two operations. 
@@ -303,7 +308,9 @@
         _it_disable( &save_sr ); 
 
-        // reset runnable 
-        _set_task_slot( x, y, p, ltid, CTX_RUN_ID, 0 );  
-
+        // Set NORUN_MASK_IOC bit 
+        static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
+        unsigned int*       ptr     = &psched->context[ltid][CTX_NORUN_ID];
+        _atomic_or( ptr , NORUN_MASK_IOC );
+      
         // start HBA transfer
         _hba_set_register( HBA_PXCI, (1<<cmd_id) );
@@ -432,22 +439,19 @@
 
             // identify waiting task 
-            unsigned int remote_procid  = _hba_gtid[cmd_id]>>16;
-            unsigned int ltid           = _hba_gtid[cmd_id] & 0xFFFF;
-            unsigned int remote_cluster = remote_procid >> P_WIDTH;
-            unsigned int remote_x       = remote_cluster >> Y_WIDTH;
-            unsigned int remote_y       = remote_cluster & ((1<<Y_WIDTH)-1);
-            unsigned int remote_p       = remote_procid & ((1<<P_WIDTH)-1);
+            unsigned int procid  = _hba_gtid[cmd_id]>>16;
+            unsigned int ltid    = _hba_gtid[cmd_id] & 0xFFFF;
+            unsigned int cluster = procid >> P_WIDTH;
+            unsigned int x       = cluster >> Y_WIDTH;
+            unsigned int y       = cluster & ((1<<Y_WIDTH)-1);
+            unsigned int p       = procid & ((1<<P_WIDTH)-1);
  
-            // re-activates waiting task
-            _set_task_slot( remote_x,
-                            remote_y,
-                            remote_p,
-                            ltid,
-                            CTX_RUN_ID,
-                            1 );
+            // Reset NORUN_MASK_IOC bit 
+            static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
+            unsigned int*       ptr     = &psched->context[ltid][CTX_NORUN_ID];
+            _atomic_and( ptr , ~NORUN_MASK_IOC );
 
             // send a WAKUP WTI to processor running the waiting task 
-            _xcu_send_wti( remote_cluster , 
-                           remote_p , 
+            _xcu_send_wti( cluster , 
+                           p , 
                            0 );          // don't force context switch
 
@@ -457,5 +461,5 @@
         "  resume task %d running on P[%d,%d,%d]\n",
         cmd_id , _get_proctime() ,
-        ltid , remote_x , remote_y , remote_p );
+        ltid , x , y , p );
 #endif 
         }
Index: /soft/giet_vm/giet_drivers/mmc_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/mmc_driver.c	(revision 629)
+++ /soft/giet_vm/giet_drivers/mmc_driver.c	(revision 630)
@@ -39,16 +39,19 @@
 
 ///////////////////////////////////////////////////////////////////////////////
-// Locks protecting MMC components (one per cluster)
-// There are two kinds of lock: the _mmc_lock table contains all the locks and
-// and is stored in the kernel data segment, whereas the _mmc_distributed_lock
-// contains the addresses of locks which are distributed in every cluster (each
-// cluster contains the lock which protects its own mmc_component).
+//     Global variables
+///////////////////////////////////////////////////////////////////////////////
+// Two kinds of locks protecting the MMC components (one per cluster):
+// - the _mmc_lock array contains spin_locks allocated in cluster[0,0].
+//   They must be used by the boot code because the kernel heap is not set.
+// - the _mmc_distributed_locks array contains pointers on distributed
+//   spin_loks allocated in the distributed heap in each cluster. 
+//   Each cluster contains the lock protecting its own mmc_component.
+//   They can be used by the kernel code. 
 // The global variable mmc_boot_mode define the type of lock which is used,
 // and must be defined in both kernel_init.c and boot.c files.
-// - the boot code must use a spin_lock because the kernel heap is not set.
-// - the kernel code can use a sqt_lock when the kernel heap is set.
-///////////////////////////////////////////////////////////////////////////////
-
-extern unsigned int  _mmc_boot_mode;
+///////////////////////////////////////////////////////////////////////////////
+
+__attribute__((section(".kdata")))
+unsigned int  _mmc_boot_mode;
 
 __attribute__((section(".kdata")))
@@ -64,13 +67,20 @@
 void _mmc_init_locks()
 {
-    unsigned int cx;    // cluster X coordinate
-    unsigned int cy;    // cluster Y coordinate
+    unsigned int x;    // cluster X coordinate
+    unsigned int y;    // cluster Y coordinate
     
-    for ( cx = 0 ; cx < X_SIZE ; cx++ )
-    {
-        for ( cy = 0 ; cy < Y_SIZE ; cy++ )
+    for ( x = 0 ; x < X_SIZE ; x++ )
+    {
+        for ( y = 0 ; y < Y_SIZE ; y++ )
         {
-            _mmc_distributed_lock[cx][cy] = _remote_malloc( sizeof(spin_lock_t), cx, cy );
-            _spin_lock_init( _mmc_distributed_lock[cx][cy] );
+            if ( _mmc_boot_mode )
+            {
+                _spin_lock_init( &_mmc_lock[x][y] );
+            }
+            else
+            {
+                _mmc_distributed_lock[x][y] = _remote_malloc( sizeof(spin_lock_t), x, y );
+                _spin_lock_init( _mmc_distributed_lock[x][y] );
+            }
         }
     }
Index: /soft/giet_vm/giet_drivers/mwr_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/mwr_driver.c	(revision 629)
+++ /soft/giet_vm/giet_drivers/mwr_driver.c	(revision 630)
@@ -41,7 +41,15 @@
 #endif
 
-
-/////////////////////////////////////////////////////////////////////////////
-//      Global variables (all arrays are indexed by the cluster index)
+/////////////////////////////////////////////////////////////////////////////
+//      Extern variables
+/////////////////////////////////////////////////////////////////////////////
+
+// allocated in the boot.c or kernel_init.c files
+extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 
+
+/////////////////////////////////////////////////////////////////////////////
+//      Global variables 
+/////////////////////////////////////////////////////////////////////////////
+// All arrays are indexed by the cluster index.
 /////////////////////////////////////////////////////////////////////////////
 
@@ -150,6 +158,5 @@
 {
     // get coprocessor coordinates and characteristics
-    // the processor executing the ISR an the coprocessor
-    // are in the same cluster
+    // processor executing ISR and coprocessor are in the same cluster
     unsigned int gpid       = _get_procid();
     unsigned int cluster_xy = gpid >> P_WIDTH;
@@ -160,9 +167,10 @@
     unsigned int nb_to      = info & 0xFF;
     unsigned int nb_from    = (info>>8) & 0xFF;
+
     unsigned int channel;
     unsigned int status;
     unsigned int error = 0;
 
-    // check status, report errors and reset all channels
+    // check status, report errors and reset for all channels
     for ( channel = 0 ; channel < (nb_to + nb_from) ; channel++ )
     {
@@ -199,23 +207,20 @@
     // identify task waiting on coprocessor completion
     // this task can run in a remote cluster 
-    unsigned int gtid           = _coproc_gtid[cluster_id];
-    unsigned int remote_procid  = gtid>>16;
-    unsigned int ltid           = gtid & 0xFFFF;
-    unsigned int remote_cluster = remote_procid >> P_WIDTH;
-    unsigned int remote_x       = remote_cluster >> Y_WIDTH;
-    unsigned int remote_y       = remote_cluster & ((1<<Y_WIDTH)-1);
-    unsigned int remote_p       = remote_procid & ((1<<P_WIDTH)-1);
-
-    // re-activates sleeping task
-    _set_task_slot( remote_x,
-                    remote_y,
-                    remote_p,
-                    ltid,        
-                    CTX_RUN_ID,  // CTX_RUN slot 
-                    1 );         // running value
+    unsigned int r_gtid    = _coproc_gtid[cluster_id];
+    unsigned int r_procid  = r_gtid>>16;
+    unsigned int r_ltid    = r_gtid & 0xFFFF;
+    unsigned int r_cluster = r_procid >> P_WIDTH;
+    unsigned int r_x       = r_cluster >> Y_WIDTH;
+    unsigned int r_y       = r_cluster & ((1<<Y_WIDTH)-1);
+    unsigned int r_p       = r_procid & ((1<<P_WIDTH)-1);
+
+    // Reset NORUN_MASK_IOC bit 
+    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[r_x][r_y][r_p];
+    unsigned int*       ptr     = &psched->context[r_ltid][CTX_NORUN_ID];
+    _atomic_and( ptr , ~NORUN_MASK_IOC );
 
     // send a WAKUP WTI to processor running the sleeping task 
-    _xcu_send_wti( remote_cluster,   
-                   remote_p, 
+    _xcu_send_wti( r_cluster,   
+                   r_p, 
                    0 );          // don't force context switch 
 
@@ -224,7 +229,7 @@
 _printf("\n[GIET DEBUG COPROC] P[%d,%d,%d] executes _mwr_isr() at cycle %d\n"
         "  for task %d running on P[%d,%d,%d] / error = %d\n",
-        x , y , p , _get_proctime() , ltid , remote_x , remote_y , remote_p , error );
-#endif
-}
+        x , y , p , _get_proctime() , ltid , r_x , r_y , r_p , error );
+#endif
+}  // end _mwr_isr()
 
 
Index: /soft/giet_vm/giet_drivers/sdc_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/sdc_driver.c	(revision 629)
+++ /soft/giet_vm/giet_drivers/sdc_driver.c	(revision 630)
@@ -20,4 +20,11 @@
 
 #define  SDC_POLLING_TIMEOUT  1000000   // number of retries for polling PXCI 
+
+//////////////////////////////////////////////////////////////////////////////////
+//      Extern variables
+//////////////////////////////////////////////////////////////////////////////////
+
+// allocated in the boot.c or kernel_init.c files
+extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 
 
 ///////////////////////////////////////////////////////////////////////////////////
@@ -401,5 +408,5 @@
     // in descheduling mode, we deschedule the task
     // and use an interrupt to reschedule the task.
-    // We need a critical section, because we must reset the RUN bit
+    // We need a critical section, because we must set the NORUN bit
 	// before to launch the transfer, and we don't want to be 
     // descheduled between these two operations. 
@@ -426,7 +433,9 @@
         _it_disable( &save_sr ); 
 
-        // reset runnable 
-        _set_task_slot( x, y, p, ltid, CTX_RUN_ID, 0 );  
-
+        // Set NORUN_MASK_IOC bit 
+        static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
+        unsigned int*       ptr     = &psched->context[ltid][CTX_NORUN_ID];
+        _atomic_or( ptr , NORUN_MASK_IOC );
+        
         // start transfer
         _sdc_set_register( AHCI_PXCI, (1<<ptw) );
@@ -489,22 +498,19 @@
  
             // identify waiting task 
-            unsigned int remote_procid  = _ahci_gtid[ptr]>>16;
-            unsigned int ltid           = _ahci_gtid[ptr] & 0xFFFF;
-            unsigned int remote_cluster = remote_procid >> P_WIDTH;
-            unsigned int remote_x       = remote_cluster >> Y_WIDTH;
-            unsigned int remote_y       = remote_cluster & ((1<<Y_WIDTH)-1);
-            unsigned int remote_p       = remote_procid & ((1<<P_WIDTH)-1);
+            unsigned int procid  = _ahci_gtid[ptr]>>16;
+            unsigned int ltid    = _ahci_gtid[ptr] & 0xFFFF;
+            unsigned int cluster = procid >> P_WIDTH;
+            unsigned int x       = cluster >> Y_WIDTH;
+            unsigned int y       = cluster & ((1<<Y_WIDTH)-1);
+            unsigned int p       = procid & ((1<<P_WIDTH)-1);
  
-            // re-activates waiting task
-            _set_task_slot( remote_x,
-                            remote_y,
-                            remote_p,
-                            ltid,
-                            CTX_RUN_ID,
-                            1 );
+            // Reset NORUN_MASK_IOC bit 
+            static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
+            unsigned int*       ptr     = &psched->context[ltid][CTX_NORUN_ID];
+            _atomic_and( ptr , ~NORUN_MASK_IOC );
 
             // send a WAKUP WTI to processor running the waiting task 
-            _xcu_send_wti( remote_cluster , 
-                           remote_p , 
+            _xcu_send_wti( cluster , 
+                           p , 
                            0 );          // don't force context switch
 
@@ -514,5 +520,5 @@
         "  resume task %d running on P[%d,%d,%d] / status = %x\n",
         ptr , _get_proctime() ,
-        ltid , remote_x , remote_y , remote_p , _ahci_status[ptr] );
+        ltid , x , y , p , _ahci_status[ptr] );
 #endif
         }
@@ -521,5 +527,5 @@
             break;
         }
-    }
+    }  // end for completed commands
 }  // end _sdc_isr()
 
