Index: trunk/kernel/devices/dev_icu.c
===================================================================
--- trunk/kernel/devices/dev_icu.c	(revision 1)
+++ trunk/kernel/devices/dev_icu.c	(revision 3)
@@ -24,5 +24,5 @@
 #include <hal_types.h>
 #include <hal_special.h>
-#include <device.h>
+#include <chdev.h>
 #include <thread.h>
 #include <cluster.h>
@@ -37,172 +37,114 @@
 /////////////////////////////////////////////////////////////////////////////////////////
 
-extern devices_directory_t  devices_dir;         // allocated in kernel_init.c
-
-extern devices_input_irq_t  devices_input_irq;   // allocated in kernel_init.c
-
-
-///////////////////////////////////
-void dev_icu_init( xptr_t   dev_xp,
-                   uint32_t hwi_nr,
-                   uint32_t wti_nr,
-                   uint32_t pti_nr )
-{
-    // get ICU device cluster and local pointer
-    cxy_t      dev_cxy = GET_CXY( dev_xp );
-    device_t * dev_ptr = (device_t *)GET_PTR( dev_xp );
-
-    if( dev_cxy != local_cxy )
-    {
-        printk("\n[PANIC] %s for cluster %x must be local\n",
-               __FUNCTION__ , local_cxy );
-        hal_core_sleep();
-    }
-
-    // set ICU device extension fields
-    dev_ptr->ext.icu.hwi_nr     = hwi_nr;
-    dev_ptr->ext.icu.wti_nr     = wti_nr;
-    dev_ptr->ext.icu.pti_nr     = pti_nr;
-    dev_ptr->ext.icu.wti_bitmap = 0;
-    spinlock_init( &dev_ptr->ext.icu.wti_lock );
+extern chdev_directory_t  chdev_dir;         // allocated in kernel_init.c
+
+extern chdev_pic_input_t  chdev_pic_input;   // allocated in kernel_init.c
+
+/////////////////////////////////
+void dev_icu_init( chdev_t * icu,
+                   uint32_t  hwi_nr,
+                   uint32_t  wti_nr,
+                   uint32_t  pti_nr )
+{
+    // set ICU chdev extension fields
+    icu->ext.icu.hwi_nr     = hwi_nr;
+    icu->ext.icu.wti_nr     = wti_nr;
+    icu->ext.icu.pti_nr     = pti_nr;
+    icu->ext.icu.wti_bitmap = 0;
+    spinlock_init( &icu->ext.icu.wti_lock );
    
-    // get implementation index from ICU device descriptor
-    uint32_t impl = dev_ptr->impl;
-
-    // set field "name" in device descriptor
-    // and call the relevant driver init function
+    // get implementation
+    uint32_t impl = icu->impl;
+
+    // call the relevant driver init function
     if( impl == IMPL_ICU_XCU )
     {
-        memcpy( dev_ptr->name , "ICU_XCU" , 16 );
-
-        uint32_t     lid;
-        cluster_t  * cluster = LOCAL_CLUSTER;
-        for( lid = 0 ; lid < cluster->cores_nr ; lid++ )
+        uint32_t  lid;
+        for( lid = 0 ; lid < LOCAL_CLUSTER->cores_nr ; lid++ )
         {
-            soclib_xcu_init( dev_ptr , lid );
+            soclib_xcu_init( icu , lid );
         }
     }
     else
     {
-        printk("\n[PANIC] %s : undefined ICU implementation for cluste %x\n",
-               __FUNCTION__ , local_cxy );
-        hal_core_sleep();
+        assert( false , __FUNCTION__ , "undefined ICU implementation" );
     }
 } // end dev_icu_init()
 
 /////////////////////////////////////////////////////////////////////////////////////
-// This static function check the irq_type / irq_index arguments for a remote ICU.
+// This static function check the irq_type / irq_index arguments.
 // It is called by the dev_icu_enable_irq() & dev_icu_disable_irq() functions.
-// returns 0 if OK / returns non zero if invalid arguments
 /////////////////////////////////////////////////////////////////////////////////////
-static inline void dev_icu_check_irq( xptr_t     icu_xp,
+static inline void dev_icu_check_irq( chdev_t  * icu,
                                       uint32_t   irq_type,
                                       uint32_t   irq_index )
 {
-    // get cluster and local pointer on remote ICU
-    cxy_t      icu_cxy = GET_CXY( icu_xp );
-    device_t * icu_ptr = (device_t *)GET_PTR( icu_xp );
-
     if( irq_type == HWI_TYPE ) 
     {
-        if( irq_index >= hal_remote_lw( XPTR( icu_cxy , &icu_ptr->ext.icu.hwi_nr ) ) )
-        {
-            printk("\n[PANIC] in %s : illegal HWI index = %d for ICU in cluster %x\n",
-                   __FUNCTION__ , irq_index , icu_cxy );
-            hal_core_sleep();
-        }
+        assert( (irq_index < icu->ext.icu.hwi_nr) , __FUNCTION__ , "illegal HWI" );
     }
     if( irq_type == WTI_TYPE )
     {
-        if( irq_index >= hal_remote_lw( XPTR( icu_cxy , &icu_ptr->ext.icu.wti_nr ) ) )
-        {
-            printk("\n[PANIC] in %s : illegal WTI index = %d for ICU in cluster %x\n",
-                   __FUNCTION__ , irq_index , icu_cxy );
-            hal_core_sleep();
-        }
+        assert( (irq_index < icu->ext.icu.wti_nr) , __FUNCTION__ , "illegal WTI" );
     }
     if( irq_type == PTI_TYPE )
     {
-        if( irq_index >= hal_remote_lw( XPTR( icu_cxy , &icu_ptr->ext.icu.pti_nr ) ) )
-        {
-            printk("\n[PANIC] in %s : illegal PTI index = %d for ICU in cluster %x\n",
-                   __FUNCTION__ , irq_index , icu_cxy );
-            hal_core_sleep();
-        }
-    }
-}  // end dev_icu check irq()
-
-////////////////////////////////////////////
-void dev_icu_enable_irq( cxy_t      icu_cxy,
-                         lid_t      lid,
+        assert( (irq_index < icu->ext.icu.pti_nr) , __FUNCTION__ , "illegal PTI" );
+    }
+}  // end dev_icu_check_irq()
+
+////////////////////////////////////////
+void dev_icu_enable_irq( lid_t      lid,
                          uint32_t   irq_type,
                          uint32_t   irq_index,
-                         xptr_t     src_dev_xp )
-{
-    // get extended pointer & local pointer on remote ICU device
-    xptr_t     icu_xp  = devices_dir.icu[icu_cxy];
-    device_t * icu_ptr = (device_t *)GET_PTR( icu_xp );
+                         chdev_t  * src_chdev )
+{
+    // get local pointer on local ICU chdev
+    xptr_t    icu_xp = chdev_dir.icu[local_cxy];
+    chdev_t * icu    = (chdev_t *)GET_PTR( icu_xp );
 
     // check IRQ type and index
-    dev_icu_check_irq( icu_xp , irq_type , irq_index );
+    dev_icu_check_irq( icu , irq_type , irq_index );
 
     // (1) call implementation specific ICU driver to enable IRQ
-    if( icu_ptr->impl == IMPL_ICU_XCU ) 
-    {
-        soclib_xcu_enable_irq( icu_xp , 1<<irq_index , irq_type , lid );
-    }
-    else
-    {
-        printk("\n[PANIC] in %s : undefined ICU implementation" , __FUNCTION__ );
-        hal_core_sleep();
-    }
-
-    // (2) get selected remote core local pointer, and register
-    // source device xptr in relevant interrupt vector
-
-    core_t * core_ptr = hal_remote_lpt( XPTR( icu_cxy , &LOCAL_CLUSTER->core_tbl[lid] ) );
-    xptr_t   core_xp  = XPTR( icu_cxy , core_ptr );
-	core_set_irq_vector_entry( core_xp , irq_type , irq_index , src_dev_xp );
-
-    // (3) get extended pointer on source device, and 
-    // register IRQ type and index in source device descriptor
-
-    cxy_t      src_dev_cxy = GET_CXY( src_dev_xp );
-    device_t * src_dev_ptr = (device_t *)GET_PTR( src_dev_xp );
-
-    hal_remote_sw( XPTR( src_dev_cxy , &src_dev_ptr->irq_type ) , irq_type );
-    hal_remote_sw( XPTR( src_dev_cxy , &src_dev_ptr->irq_id   ) , irq_index );
+    if( icu->impl == IMPL_ICU_XCU ) 
+    {
+        soclib_xcu_enable_irq( icu , 1<<irq_index , irq_type , lid );
+    }
+
+    // (2) get selected core local pointer, and register
+    // source chdev pointer in relevant interrupt vector
+    core_t * core = &LOCAL_CLUSTER->core_tbl[lid];
+	core_set_irq_vector_entry( core , irq_type , irq_index , src_chdev );
+
+    // (3) register IRQ type and index in source chdev descriptor
+    src_chdev->irq_type = irq_type;
+    src_chdev->irq_id   = irq_index;
 
 }  // end dev_icu_enable_irq()
 
-/////////////////////////////////////////////
-void dev_icu_disable_irq( cxy_t      icu_cxy,
-                          lid_t      lid,
+/////////////////////////////////////////
+void dev_icu_disable_irq( lid_t      lid,
                           uint32_t   irq_type,
                           uint32_t   irq_index )
 {
-    // get extended pointer & local pointer on remote ICU device
-    xptr_t  icu_xp = devices_dir.icu[icu_cxy];
-    device_t * icu_ptr = (device_t *)GET_PTR( icu_xp );
+    // get local pointer on local ICU chdev
+    xptr_t    icu_xp = chdev_dir.icu[local_cxy];
+    chdev_t * icu    = (chdev_t *)GET_PTR( icu_xp );
 
     // check IRQ type and index
-    dev_icu_check_irq( icu_xp , irq_type , irq_index );
+    dev_icu_check_irq( icu , irq_type , irq_index );
 
     // (1) call the implementation specific ICU driver to disable IRQ 
-    if( icu_ptr->impl == IMPL_ICU_XCU ) 
-    {
-        soclib_xcu_disable_irq( icu_xp , 1<<irq_index , irq_type , lid );
-    }
-    else
-    {
-        printk("\n[PANIC] in %s : undefined ICU implementation" , __FUNCTION__ );
-        hal_core_sleep();
+    if( icu->impl == IMPL_ICU_XCU ) 
+    {
+        soclib_xcu_disable_irq( icu , 1<<irq_index , irq_type , lid );
     }
 
     // (2) get selected remote core local pointer, and remove
-    // the source device xptr from relevant interrupt vector
-
-    core_t * core_ptr = hal_remote_lpt( XPTR( icu_cxy , &LOCAL_CLUSTER->core_tbl[lid] ) );
-    xptr_t   core_xp  = XPTR( icu_cxy , core_ptr );
-	core_set_irq_vector_entry( core_xp , irq_type , irq_index , XPTR_NULL );
+    // the source chdev xptr from relevant interrupt vector
+
+    core_t * core = &LOCAL_CLUSTER->core_tbl[lid];
+	core_set_irq_vector_entry( core , irq_type , irq_index , NULL );
 
 } // end dev_icu_disable_irq()
@@ -212,14 +154,10 @@
                          uint32_t   period )
 {
-    // get pointer on local ICU device descriptor
-    core_t   * core = CURRENT_CORE;
-    device_t * icu  = core->icu;
+    // get local pointer on local ICU chdev
+    xptr_t    icu_xp = chdev_dir.icu[local_cxy];
+    chdev_t * icu    = (chdev_t *)GET_PTR( icu_xp );
 
     // check PTI index
-    if( pti_index >= icu->ext.icu.pti_nr ) 
-    {
-        printk("\n[PANIC] in %s : illegal PTI index = %d\n", __FUNCTION__ , pti_index );
-        hal_core_sleep();
-    }
+    assert( (pti_index < icu->ext.icu.pti_nr) , __FUNCTION__ , "illegal PTI index" ); 
 
     // call the implementation specific driver ICU to set period 
@@ -233,14 +171,10 @@
 void dev_icu_ack_timer( uint32_t pti_index )
 {
-    // get pointer on local ICU device descriptor
-    core_t   * core = CURRENT_CORE;
-    device_t * icu  = core->icu;
+    // get local pointer on local ICU chdev
+    xptr_t    icu_xp = chdev_dir.icu[local_cxy];
+    chdev_t * icu    = (chdev_t *)GET_PTR( icu_xp );
 
     // check PTI index
-    if( pti_index >= icu->ext.icu.pti_nr ) 
-    {
-        printk("\n[PANIC] in %s : illegal PTI index = %d\n", __FUNCTION__ , pti_index );
-        hal_core_sleep();
-    }
+    assert( (pti_index < icu->ext.icu.pti_nr) , __FUNCTION__ , "illegal PTI index" ); 
 
     // call the implementation specific driver ICU to acknowledge PTI IRQ
@@ -249,10 +183,4 @@
         soclib_xcu_ack_timer( icu , pti_index );
     }
-    else
-    {
-        printk("\n[PANIC] in %s : undefined ICU implementation" , __FUNCTION__ );
-        hal_core_sleep();
-    }
-
 }  // end dev_icu_ack_timer()
 
@@ -270,22 +198,17 @@
     uint32_t    y = cxy & ((1<<y_width)-1);
 
-    if( (x >= x_size) || (y >= y_size) )
-    {
-        hal_core_sleep("%s : illegal cluster identifier = %x\n", __FUNCTION__ , cxy );
-    } 
-    if( lid >= cores_nr )
-    {
-        hal_core_sleep("%s : illegal core local index = %d\n", __FUNCTION__ , lid );
-    } 
-
-    // get extended pointer on target ICU device
-    xptr_t icu_xp = devices_dir.icu[cxy];
+    assert( ((x < x_size) && (y < y_size)) , __FUNCTION__ , "illegal cluster identifier" );
+
+    assert( (lid < cores_nr) , __FUNCTION__ , "illegal core local index" );
+
+    // get extended pointer on target ICU chdev
+    xptr_t icu_xp = chdev_dir.icu[cxy];
 
      // get target ICU cluster and local pointer
-    cxy_t      cxy_icu = GET_CXY( icu_xp );
-    device_t * ptr_icu = (device_t *)GET_PTR( icu_xp );
-
-    // get driver implementation from target ICU device
-    uint32_t impl = hal_remote_lw( XPTR( cxy_icu , &ptr_icu->impl ) );   
+    cxy_t     icu_cxy = GET_CXY( icu_xp );
+    chdev_t * icu_ptr = (chdev_t *)GET_PTR( icu_xp );
+
+    // get implementation from remote ICU chdev
+    uint32_t impl = hal_remote_lw( XPTR( icu_cxy , &icu_ptr->impl ) );   
 
     // call the implementation specific ICU driver to send IPI
@@ -293,9 +216,4 @@
     {
         soclib_xcu_send_ipi( icu_xp , lid );
-    }
-    else
-    {
-        printk("\n[PANIC] in %s : undefined ICU implementation" , __FUNCTION__ );
-        hal_core_sleep();
     }
 }  // end dev_icu_send_ipi()
@@ -307,12 +225,12 @@
     uint32_t   wti_status;   // WTI index + 1  / no pending WTI if 0
     uint32_t   pti_status;   // PTI index + 1  / no pending PTI if 0
-    xptr_t     src_dev_xp;   // extended pointer on source device descriptor
-    cxy_t      src_dev_cxy;  // source device cluster
-    device_t * src_dev_ptr;  // source device local pointer
+    chdev_t  * src_chdev;    // pointer on source chdev descriptor
     uint32_t   index;        // IRQ index
 
-    // get pointer on local ICU device descriptor
     core_t   * core = CURRENT_CORE;
-    device_t * icu  = core->icu;
+
+    // get local pointer on local ICU chdev
+    xptr_t    icu_xp = chdev_dir.icu[local_cxy];
+    chdev_t * icu    = (chdev_t *)GET_PTR( icu_xp );
 
     // call the implementation specific ICU driver  
@@ -322,40 +240,39 @@
         soclib_xcu_get_status( icu , core->lid , &hwi_status , &wti_status , &pti_status );
     }
-    else
-    {
-        printk("\n[PANIC] in %s : undefined ICU implementation" , __FUNCTION__ );
-        hal_core_sleep();
-    }
 
     // analyse ICU status and handle up to 3 pending IRQ (one WTI, one HWI, one PTI)
 
-    if( wti_status )          // pending WTI TODO what about IPIs ???  [AG]
+    if( wti_status )          // pending WTI 
 	{
         index = wti_status - 1;
 
-        // get extended pointer on IRQ source device
-		src_dev_xp  = core->wti_vector[index];
-        src_dev_cxy = GET_CXY( src_dev_xp );
-        src_dev_ptr = (device_t *)GET_PTR( src_dev_xp );
-
-		if( src_dev_xp == XPTR_NULL )        // strange, but not fatal => disable IRQ
-		{
-            printk("\n[WARNING] in %s : no handler for WTI %d on core %d in cluster %x\n",
-                   __FUNCTION__ , index , core->lid , local_cxy );
-	        core->spurious_irqs ++;
-            dev_icu_disable_irq( local_cxy , core->lid , WTI_TYPE , index ); 
-		}
-        else if( src_dev_cxy != local_cxy )  // WTI must be handled in device cluster
+        if( index < LOCAL_CLUSTER->cores_nr )   // it is an IPI
         {
-            printk("\n[PANIC] in %s : non local WTI %d on core %d in cluster %x\n",
-                   __FUNCTION__ , index , core->lid , local_cxy );
-            hal_core_sleep();
+            assert( (index == core->lid) , __FUNCTION__ , "illegal IPI index" );
+
+            // TODO acknowledge WTI [AG]
+
+            // TODO force scheduling [AG]
         }
-        else                                 // call relevant ISR
+        else                                    // it is an external device
         {
-		    icu_dmsg("\n[INFO] %s received WTI : index = %d for cpu %d in cluster %d\n",
-                     __FUNCTION__ , index , core->lid , local_cxy );
-
-	        src_dev_ptr->isr( src_dev_ptr );
+            // get pointer on IRQ source chdev
+		    src_chdev = core->wti_vector[index];
+
+		    if( src_chdev == NULL )        // strange, but not fatal => disable IRQ
+		    {
+                printk("\n[WARNING] in %s : no handler for WTI %d on core %d in cluster %x\n",
+                       __FUNCTION__ , index , core->lid , local_cxy );
+	            core->spurious_irqs ++;
+                dev_icu_disable_irq( core->lid , WTI_TYPE , index ); 
+            }
+            else                                 // call relevant ISR
+            {
+		        icu_dmsg("\n[INFO] %s received WTI : index = %d for cpu %d in cluster %d\n",
+                         __FUNCTION__ , index , core->lid , local_cxy );
+
+                // call ISR
+	            src_chdev->isr( src_chdev );
+            }
         }
 	}
@@ -365,22 +282,14 @@
         index = hwi_status - 1;
 
-        // get pointer on IRQ source device
-		src_dev_xp  = core->wti_vector[index];
-        src_dev_cxy = GET_CXY( src_dev_xp );
-        src_dev_ptr = (device_t *)GET_PTR( src_dev_xp );
-
-		if( src_dev_xp == XPTR_NULL )        // strange, but not fatal => disable IRQ
+        // get pointer on IRQ source chdev
+		src_chdev = core->hwi_vector[index];
+
+		if( src_chdev == NULL )        // strange, but not fatal => disable IRQ
 		{
             printk("\n[WARNING] in %s : no handler for HWI %d on core %d in cluster %x\n",
                    __FUNCTION__ , index , core->lid , local_cxy );
 	        core->spurious_irqs ++;
-            dev_icu_disable_irq( local_cxy , core->lid , HWI_TYPE , index ); 
+            dev_icu_disable_irq( core->lid , HWI_TYPE , index ); 
 		}
-        else if( src_dev_cxy != local_cxy )  // HWI must be handled in device cluster
-        {
-            printk("\n[PANIC] in %s : non local HWI %d on core %d in cluster %x\n",
-                   __FUNCTION__ , index , core->lid , local_cxy );
-            hal_core_sleep();
-        }
         else                    // call relevant ISR
         {
@@ -388,5 +297,6 @@
                      __FUNCTION__ , index , core->lid , local_cxy );
 
-		    src_dev_ptr->isr( src_dev_ptr );
+            // call ISR
+		    src_chdev->isr( src_chdev );
         }
 	}
@@ -402,5 +312,5 @@
         dev_icu_ack_timer( index );
 
-        // execute all actions related to TICK event
+        // TODO execute all actions related to TICK event
         core_clock( core );
 	}
@@ -410,10 +320,10 @@
 uint32_t dev_icu_wti_alloc()
 {
-    // get pointer on local ICU device descriptor
-    core_t   * core = CURRENT_CORE;
-    device_t * icu  = core->icu;
-
-    // get bitmap pointer, lock, and size
-    bitmap_t   * bitmap = &icu->ext.icu.wti_bitmap;
+    // get local pointer on local ICU chdev
+    xptr_t    icu_xp = chdev_dir.icu[local_cxy];
+    chdev_t * icu    = (chdev_t *)GET_PTR( icu_xp );
+
+    // get bitmap pointer, lock pointer, and size
+    uint32_t   * bitmap = &icu->ext.icu.wti_bitmap;
     spinlock_t * lock   = &icu->ext.icu.wti_lock;
     uint32_t     size   =  icu->ext.icu.wti_nr;
@@ -437,20 +347,15 @@
 void dev_icu_wti_release( uint32_t index )
 {
-    // get pointer on local ICU device descriptor
-    core_t   * core = CURRENT_CORE;
-    device_t * icu  = core->icu;
+    // get pointer on local ICU chdev descriptor
+    xptr_t    icu_xp  = chdev_dir.icu[local_cxy];
+    chdev_t * icu_ptr = (chdev_t *)GET_PTR( icu_xp );
 
     // get bitmap pointer, lock, and size
-    bitmap_t   * bitmap = &icu->ext.icu.wti_bitmap;
-    spinlock_t * lock   = &icu->ext.icu.wti_lock;
-    uint32_t     size   =  icu->ext.icu.wti_nr;
+    bitmap_t   * bitmap = &icu_ptr->ext.icu.wti_bitmap;
+    spinlock_t * lock   = &icu_ptr->ext.icu.wti_lock;
+    uint32_t     size   =  icu_ptr->ext.icu.wti_nr;
 
     // check index
-    if( index >= size )
-    {
-        printk("\n[PANIC] in %s : illegal WTI index = %d on core %d in cluster %x\n",
-               __FUNCTION__ , index , core->lid , local_cxy );
-        hal_core_sleep();
-    }
+    assert( (index < size) , __FUNCTION__ , "illegal WTI index" );
 
     // get lock protecting WTI allocator
@@ -462,30 +367,23 @@
     // release lock
     spinlock_unlock( lock );
+
 }  // end dev_icu_wti_release()
 
-///////////////////////////////////////
-xptr_t dev_icu_wti_xptr( cxy_t     cxy,
-                         uint32_t  wti_id )
-{
-    uint32_t * ptr = NULL;    // local pointer on mailbox
-    
-    // get pointer on local ICU device descriptor
-    core_t   * core = CURRENT_CORE;
-    device_t * icu  = core->icu;
+//////////////////////////////////////////////
+uint32_t * dev_icu_wti_ptr( uint32_t  wti_id )
+{
+    uint32_t *  wti_ptr = NULL;
+
+    // get pointer on local ICU chdev descriptor
+    xptr_t    icu_xp  = chdev_dir.icu[local_cxy];
+    chdev_t * icu     = (chdev_t *)GET_PTR( icu_xp );
 
     // call implementation specific ICU driver
     if( icu->impl == IMPL_ICU_XCU )
     {
-        ptr = soclib_xcu_wti_ptr( icu , wti_id );   
-    }
-    else
-    {
-        printk("\n[PANIC] in %s : undefined ICU implementation" , __FUNCTION__ );
-        hal_core_sleep();
-    }
-
-    // return extended pointer on mailbox
-    return XPTR( cxy , ptr );
-
+        wti_ptr = soclib_xcu_wti_ptr( icu , wti_id );   
+    }
+
+    return wti_ptr;
 }   // end dev_icu_wti_xptr()
 
