Changeset 5


Ignore:
Timestamp:
Apr 26, 2017, 2:11:56 PM (7 years ago)
Author:
alain
Message:

Introduce the chdev_t structure in place of the device_t structure.

Location:
trunk/kernel/kern
Files:
2 added
2 deleted
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/blkio.c

    r1 r5  
    2626#include <kmem.h>
    2727#include <thread.h>
    28 #include <device.h>
     28#include <chdev.h>
    2929#include <driver.h>
    3030#include <event.h>
  • trunk/kernel/kern/cluster.c

    r1 r5  
    4848///////////////////////////////////////////////////////////////////////////////////////////
    4949
    50 process_t process_zero;
     50process_t process_zero;     // allocated in kernel_init.c file
    5151
    5252
     
    7878    cluster->cores_in_kernel = info->cores_nr;   // all cpus start in kernel mode
    7979
    80     // initialize kcm lock
     80    // initialize the lock protectig the embedded kcm allocator
    8181        spinlock_init( &cluster->kcm_lock );
    82 
    83     // initialize txt0 lock
    84         remote_spinlock_init( XPTR( local_cxy , &cluster->txt0_lock ) );
    8582
    8683    // initialises DQDT
     
    10097 
    10198    // initialises embedded KCM
    102         kcm_init( &cluster->kcm , KMEM_KCM ); 
    103 
    104     // initialises cores
     99        kcm_init( &cluster->kcm , KMEM_KCM );
     100
     101    // initialises all cores descriptors
    105102        for( lid = 0 ; lid < cluster->cores_nr; lid++ )
    106103        {
  • trunk/kernel/kern/cluster.h

    r1 r5  
    9898        spinlock_t        kcm_lock;           /*! local, protect creation of KCM allocators   */
    9999    remote_barrier_t  barrier;            /*! used to synchronize kernel parallel init    */
    100     remote_spinlock_t txt0_lock;          /*! global, only cluster_io lock is used        */
    101100
    102101    // global parameters
     
    115114    uint32_t          cores_in_kernel;    /*! number of cores currently in kernel mode    */
    116115
    117         core_t            core_tbl[CONFIG_MAX_CORES_PER_CLUSTER];         /*! embedded cores  */
     116        core_t            core_tbl[CONFIG_MAX_LOCAL_CORES];         /*! embedded cores        */
    118117
    119118        ppm_t             ppm;                /*! embedded kernel page manager                */
     
    145144 * This global variable is allocated in the kernel_init.c file.
    146145 * There is one cluster_manager per cluster, with the same local address,
    147  * but different value, in all clusters containing a kernel instance.
     146 * but different content, in all clusters containing a kernel instance.
    148147 *****************************************************************************************/
    149148
  • trunk/kernel/kern/core.c

    r1 r5  
    3030#include <printk.h>
    3131#include <thread.h>
     32#include <chdev.h>
    3233#include <dev_icu.h>
    3334#include <rpc.h>
     
    4142/////////////////////////////////
    4243void core_init( core_t    * core,
    43                 uint32_t    lid,
    44                 uint32_t    gid )
     44                lid_t       lid,
     45                gid_t       gid )
    4546{
    4647        core->lid               = lid;
     
    6465
    6566        sched_init( core );
    66 
    67         core->icu               = NULL;          // TODO ??? [AG]
    6867}
    6968
     
    200199
    201200///////////////////////////////////////////////////
    202 void core_set_irq_vector_entry( xptr_t     core_xp,
     201void core_set_irq_vector_entry( core_t   * core,
    203202                                uint32_t   irq_type,
    204203                                uint32_t   irq_id,
    205                                 xptr_t     dev_xp )
    206 {
    207     // get core cluster and local pointer
    208     cxy_t    core_cxy = GET_CXY( core_xp );
    209     core_t * core_ptr = (core_t *)GET_PTR( core_xp );
    210 
    211     // compute xptr on relevant interrupt vector entry
    212     xptr_t   xp;
    213     if     ( irq_type == WTI_TYPE ) xp = XPTR( core_cxy , &core_ptr->wti_vector[irq_id] );
    214     else if( irq_type == HWI_TYPE ) xp = XPTR( core_cxy , &core_ptr->hwi_vector[irq_id] );
    215     else                            xp = XPTR( core_cxy , &core_ptr->pti_vector[irq_id] );
    216 
    217     // set relevant IRQ vector entry
    218     hal_remote_swd( xp , dev_xp );
    219 }
     204                                chdev_t  * chdev )
     205{
     206    if     ( irq_type == WTI_TYPE ) core->wti_vector[irq_id] = chdev;
     207    else if( irq_type == HWI_TYPE ) core->hwi_vector[irq_id] = chdev;
     208    else                            core->pti_vector[irq_id] = chdev;
     209}
  • trunk/kernel/kern/core.h

    r1 r5  
    3737
    3838struct thread_s;
    39 struct device_s;
     39struct chdev_s;
    4040
    4141
    4242/****************************************************************************************
    43  * This structure defines the core descriptor
     43 * This structure defines the core descriptor.
     44 * It contains the three interrupt vectors, that are implemented as array of pointers
     45 * on the source channel devices, for all IRQs allocated to a given core.
    4446 ***************************************************************************************/
    4547
     
    6264        rpc_fifo_t          rpc_fifo;       /*! embedded private RPC fifo (one per core)   */
    6365        scheduler_t         scheduler;      /*! embedded private scheduler                 */
    64     struct device_s   * icu;            /*! pointer on local ICU device descriptor     */
    6566
    66     xptr_t              hwi_vector[CONFIG_MAX_HWIS_PER_ICU];     /*! on source device  */
    67     xptr_t              pti_vector[CONFIG_MAX_PTIS_PER_ICU];     /*! on source device  */
    68     xptr_t              wti_vector[CONFIG_MAX_WTIS_PER_ICU];     /*! on source device  */
     67    struct chdev_s    * hwi_vector[CONFIG_MAX_HWIS_PER_ICU];     /*! on source device  */
     68    struct chdev_s    * pti_vector[CONFIG_MAX_PTIS_PER_ICU];     /*! on source device  */
     69    struct chdev_s    * wti_vector[CONFIG_MAX_WTIS_PER_ICU];     /*! on source device  */
    6970
    70         char                name[CONFIG_SYSFS_NAME_LEN];
    7171        sysfs_entry_t       node;
    7272}
     
    159159 * any thread in any cluster.
    160160 ***************************************************************************************
    161  * @ core_xp    : extended pointer on the core descriptor.
     161 * @ core       : local pointer on the core descriptor.
    162162 * @ irq_type   : type of IRQ (HWI/WTI/PTI).
    163163 * @ irq_id     : index in the IRQ vector.
    164  * @ dev_xp     : extended pointer on the "source" descriptor.
     164 * @ chdev      : local pointer on the "source" chdev descriptor.
    165165 **************************************************************************************/
    166 void core_set_irq_vector_entry( xptr_t     core_xp,
    167                                 uint32_t   irq_type,
    168                                 uint32_t   irq_id,
    169                                 xptr_t     dev_xp );
     166void core_set_irq_vector_entry( core_t          * core,
     167                                uint32_t          irq_type,
     168                                uint32_t          irq_id,
     169                                struct chdev_s  * chdev );
    170170
    171171
  • trunk/kernel/kern/do_interrupt.c

    r1 r5  
    2525#include <thread.h>
    2626#include <cpu-trace.h>
    27 #include <device.h>
     27#include <chdev.h>
    2828#include <system.h>
    2929#include <signal.h>
  • trunk/kernel/kern/dqdt.c

    r1 r5  
    263263    // analyse load for all children in non terminal node
    264264    load_min = 0xFFFFFFFF;
     265    select   = 0;
    265266    for( i = 0 ; i < 4 ; i++ )
    266267    {
  • trunk/kernel/kern/event.c

    r1 r5  
    2424#include <cpu.h>
    2525#include <cluster.h>
    26 #include <device.h>
     26#include <chdev.h>
    2727#include <pmm.h>
    2828#include <event.h>
  • trunk/kernel/kern/kernel_init.c

    r1 r5  
    4040#include <ppm.h>
    4141#include <page.h>
    42 #include <device.h>
     42#include <chdev.h>
    4343#include <boot_info.h>
    4444#include <dqdt.h>
    4545#include <dev_icu.h>
    4646#include <dev_mmc.h>
    47 #include <dev_mwr.h>
    48 #include <dev_iox.h>
     47#include <dev_dma.h>
     48#include <dev_iob.h>
    4949#include <dev_ioc.h>
     50#include <dev_txt.h>
    5051#include <dev_pic.h>
    5152#include <printk.h>
    5253#include <vfs.h>
    53 
    54 
    55 #define KERNEL_INIT_SYNCRO  0xA5A5B5B5
     54#include <soclib_tty.h>
     55
     56
     57#define KERNEL_INIT_SYNCHRO  0xA5A5B5B5
    5658
    5759///////////////////////////////////////////////////////////////////////////////////////////
     
    6062///////////////////////////////////////////////////////////////////////////////////////////
    6163
     64// This variable defines the local boot_info structure
     65__attribute__((section(".kinfo")))
     66boot_info_t          boot_info          CACHELINE_ALIGNED;
     67
    6268// This variable defines the local cluster manager
     69__attribute__((section(".kdata")))
    6370cluster_t            cluster_manager    CACHELINE_ALIGNED;
    6471
    65 // This variable defines the kernel process descriptor and associated thread
     72// These variables define the kernel process0 descriptor and associated thread
     73__attribute__((section(".kdata")))
    6674process_t            process_zero       CACHELINE_ALIGNED;           
    6775thread_t             thread_zero        CACHELINE_ALIGNED;
    6876
    6977// This variable contains the extended pointers on the device descriptors
    70 devices_directory_t  devices_dir        CACHELINE_ALIGNED;
    71 
    72 // This variable contains the input IRQ indexes for the PIC and ICU devices
    73 devices_input_irq_t  devices_input_irq   CACHELINE_ALIGNED;
    74 
    75 // This variable synchronizes the cores during kernel_init()
    76 volatile uint32_t    local_sync_init = 0; 
     78__attribute__((section(".kdata")))
     79chdev_directory_t    chdev_dir          CACHELINE_ALIGNED;
     80
     81// This variable contains the input IRQ indexes for the PIC device
     82__attribute__((section(".kdata")))
     83chdev_pic_input_t    chdev_pic_input    CACHELINE_ALIGNED;
     84
     85// This variable contains the input IRQ indexes for the ICU device
     86__attribute__((section(".kdata")))
     87chdev_icu_input_t    chdev_icu_input    CACHELINE_ALIGNED;
     88
     89// This variable synchronizes the local cores during kernel_init()
     90__attribute__((section(".kdata")))
     91volatile uint32_t    local_sync_init    CACHELINE_ALIGNED; 
    7792
    7893// This variable defines the local cluster identifier
    79 cxy_t                local_cxy;
    80 
    81 
    82 ///////////////////////////////////////////////////////////////////////////////////////////
    83 // This function displays the ALMOS_MKH.banner.
    84 ///////////////////////////////////////////////////////////////////////////////////////////
    85 static void print_boot_banner()
     94__attribute__((section(".kdata")))
     95cxy_t                local_cxy          CACHELINE_ALIGNED;
     96
     97// This variable is the lock protecting the kernel TXT terminal (used by printk)
     98__attribute__((section(".kdata")))
     99remote_spinlock_t    txt0_lock          CACHELINE_ALIGNED;
     100
     101///////////////////////////////////////////////////////////////////////////////////////////
     102// This function displays the ALMOS_MKH banner.
     103///////////////////////////////////////////////////////////////////////////////////////////
     104static void print_banner( uint32_t nclusters , uint32_t ncores )
    86105{
    87         printk("\n           ____        ___        ___       ___    _______    ________         ___       ___   ___     ___   \n");
    88         printk("          /    \\      |   |      |   \\     /   |  /  ___  \\  /  ____  |       |   \\     /   | |   |   /  / \n");
    89         printk("         /  __  \\      | |        |   \\___/   |  |  /   \\  | | /    |_/        |   \\___/   |   | |   /  /  \n");
    90         printk("        /  /  \\  \\     | |        |  _     _  |  | |     | | | |______   ___   |  _     _  |   | |__/  /     \n");
    91         printk("       /  /____\\  \\    | |        | | \\   / | |  | |     | | \\______  \\ |___|  | | \\   / | |   |  __  <  \n");
    92         printk("      /   ______   \\   | |     _  | |  \\_/  | |  | |     | |  _     | |        | |  \\_/  | |   | |  \\  \\  \n");
    93         printk("     /   /      \\   \\  | |____/ | | |       | |  |  \\___/  | | \\____/ |        | |       | |   | |   \\  \\\n");
    94         printk("    /_____/    \\_____\\|_________/|___|     |___|  \\_______/  |________/       |___|     |___| |___|   \\__\\\n");
    95 
    96 
    97         printk("\n\n\t\t\t\t Multi-Kernel Advanced Locality Management Operating System\n");
    98         printk("\t\t\t\t   %s \n\n\n", CONFIG_ALMOS_VERSION );
     106    printk("\n"
     107           "                    _        __    __     _____     ______         __    __    _   __   _     _   \n"
     108           "          /\\       | |      |  \\  /  |   / ___ \\   / _____|       |  \\  /  |  | | / /  | |   | |  \n"
     109           "         /  \\      | |      |   \\/   |  | /   \\ | | /             |   \\/   |  | |/ /   | |   | |  \n"
     110           "        / /\\ \\     | |      | |\\  /| |  | |   | | | |_____   ___  | |\\  /| |  |   /    | |___| |  \n"
     111           "       / /__\\ \\    | |      | | \\/ | |  | |   | | \\_____  \\ |___| | | \\/ | |  |   \\    |  ___  |  \n"
     112           "      / ______ \\   | |      | |    | |  | |   | |       | |       | |    | |  | |\\ \\   | |   | |  \n"
     113           "     / /      \\ \\  | |____  | |    | |  | \\___/ |  _____/ |       | |    | |  | | \\ \\  | |   | |  \n"
     114           "    /_/        \\_\\ |______| |_|    |_|   \\_____/  |______/        |_|    |_|  |_|  \\_\\ |_|   |_|  \n"
     115           "\n\n\t\t Advanced Locality Management Operating System / Multi Kernel Hybrid\n"
     116           "\n\n\t\t\t Version 0.0   :   %d clusters   /   %d cores per cluster\n\n", nclusters , ncores );
    99117}
    100118
    101119
    102120///////////////////////////////////////////////////////////////////////////////////////////
    103 // This static function allocates memory for all devices descriptors associated
    104 // to peripherals contained in the local cluster:
    105 // - the internal (replicated) devices are placed in the local cluster.
    106 // - the external devices are pseudo-randomly distributed on all clusters.
    107 // It initialises these device descriptors as specified by the boot_info_t structure,
    108 // including the dynamic linking with the driver for the specified implementation.
    109 // Finally, all copies of the devices directory are initialised.
    110 // TODO check that cluster IO contains a PIC and IOB [AG]
     121// This static function allocates memory and initializes the TXT0 chdev descriptor,
     122// associated to the kernel terminal, shared by all kernel instances for debug messages.
     123// It should be called by a thread running in the I/O cluster, because the TXT0 chdev
     124// is created in the I/O cluster.
    111125///////////////////////////////////////////////////////////////////////////////////////////
    112126// @ info    : pointer on the local boot-info structure.
    113127///////////////////////////////////////////////////////////////////////////////////////////
    114 static void devices_init( boot_info_t * info )
     128static void txt0_device_init( boot_info_t * info )
    115129{
    116130    boot_device_t * dev_tbl;         // pointer on array of devices in boot_info
    117131        uint32_t        dev_nr;          // actual number of devices in this cluster
    118         xptr_t          xp_dev;          // extended pointer on device descriptor
    119         xptr_t          xp_dev_bis;      // extended pointer on second device descriptor
    120132        xptr_t          base;            // remote pointer on segment base
    121133        uint32_t        size;            // channel size (bytes)
     
    126138        uint32_t        x;               // X cluster coordinate
    127139        uint32_t        y;               // Y cluster coordinate
    128         uint32_t        channels;        // number of channels
    129         uint32_t        chl;             // channel index
    130         uint32_t        p0;              // device parameter 0
    131         uint32_t        p1;              // device parameter 1
    132         uint32_t        p2;              // device parameter 2
    133         uint32_t        p3;              // device parameter 3
    134     bool_t          is_local;        // true for internal peripherals
    135 
    136     // get number of peripherals from boot_info
    137         dev_nr      = info->devices_nr;
    138     dev_tbl     = info->dev;
    139 
    140     // loop on all peripherals in cluster
     140        chdev_t       * chdev;           // local pointer on created chdev
     141
     142    // get number of peripherals and base of devices array from boot_info
     143        dev_nr      = info->ext_dev_nr;
     144    dev_tbl     = info->ext_dev;
     145
     146    // loop on external peripherals to find TXT
    141147        for( i = 0 ; i < dev_nr ; i++ )
    142148        {
    143         size     = dev_tbl[i].size;
    144         base     = dev_tbl[i].base;
    145         type     = dev_tbl[i].type;
    146         channels = dev_tbl[i].channels;
    147         p0       = dev_tbl[i].param0;
    148         p1       = dev_tbl[i].param1;
    149         p2       = dev_tbl[i].param2;
    150         p3       = dev_tbl[i].param3;
    151 
    152         func     = FUNC_FROM_TYPE( type );
    153         impl     = IMPL_FROM_TYPE( type );
    154 
    155         // do nothing for RAM and ROM functional types
    156         if( (type == DEV_FUNC_RAM) || (type == DEV_FUNC_ROM) ) continue;
    157 
    158         // loop on channels in peripheral
    159         for( chl = 0 ; chl < channels ; chl++ )
    160         {
    161             // target cluster is local for internal (replicated) peripherals
    162             if( (func == DEV_FUNC_ICU) ||
    163                 (func == DEV_FUNC_MMC) ||
    164                 (func == DEV_FUNC_MWR) )   is_local = true;
    165             else                           is_local = false;
    166 
    167             // allocate memory and initialize device descriptor
    168                     xp_dev = device_alloc( info , is_local );
    169 
    170             if( xp_dev == XPTR_NULL ) hal_core_sleep();
    171            
    172             device_init( xp_dev ,
    173                          func ,
    174                          impl,
    175                          chl,
    176                          false,                    // TX
    177                          base + size*chl,
    178                          size );
    179 
    180             // allocate memory and initialise another device descriptor if NIC,
    181             // ALMOS-MKH uses two separate devices descriptor for NIC_RX and NIC_TX
    182             if( func == DEV_FUNC_NIC )
     149        size        = dev_tbl[i].size;
     150        base        = dev_tbl[i].base;
     151        type        = dev_tbl[i].type;
     152        func        = FUNC_FROM_TYPE( type );
     153        impl        = IMPL_FROM_TYPE( type );
     154
     155        if (func == DEV_FUNC_TXT )
     156        {
     157            // allocate and initialize a local chdev for TXT0
     158            chdev = chdev_create( func,
     159                                  impl,
     160                                  0,        // channel
     161                                  0,        // direction
     162                                  base );
     163
     164            // Complete TXT specific initialisation
     165            if( impl == IMPL_TXT_TTY )
    183166            {
    184                 xp_dev_bis = device_alloc( info , is_local );
    185 
    186                 if( xp_dev_bis == XPTR_NULL ) hal_core_sleep();
    187 
    188                 device_init( xp_dev_bis ,
    189                              func ,
    190                              impl,
    191                              chl,
    192                              true,                // RX
    193                              (base + size*chl),
    194                              size );
    195              }
    196 
    197             // TODO ??? AG
    198                     // devfs_register( dev );
    199 
    200             // make device type specific initialisation
    201             // the number of parameters depends on the device type
    202             if     ( func == DEV_FUNC_ICU ) dev_icu_init( xp_dev , p0 , p1 , p2 );     
    203             else if( func == DEV_FUNC_MMC ) dev_mmc_init( xp_dev );
    204 // TODO     else if( func == DEV_FUNC_MWR ) dev_mwr_init( xp_dev , p0 , p1 , p2 , p3 );
    205             else if( func == DEV_FUNC_IOB ) dev_iox_init( xp_dev );
    206             else if( func == DEV_FUNC_IOC ) dev_ioc_init( xp_dev );
    207             else if( func == DEV_FUNC_TXT ) dev_txt_init( xp_dev );
    208             else if( func == DEV_FUNC_PIC ) dev_pic_init( xp_dev , p0 );
    209             else if( func == DEV_FUNC_NIC ) dev_nic_init( xp_dev );
    210             else                            hal_core_sleep();
    211 
    212            // initialize the replicated devices_dir[x][y] structures
    213            // defining the extended pointers on all devices descriptors
    214            xptr_t * ptr_dev;   
    215            xptr_t * ptr_dev_bis;   
    216 
    217            if( func == DEV_FUNC_ICU ) ptr_dev     = &devices_dir.icu[local_cxy];
    218            if( func == DEV_FUNC_MMC ) ptr_dev     = &devices_dir.mmc[local_cxy];
    219            if( func == DEV_FUNC_MWR ) ptr_dev     = &devices_dir.mwr[local_cxy];
    220 
    221            if( func == DEV_FUNC_TXT ) ptr_dev     = &devices_dir.txt[chl];
    222            if( func == DEV_FUNC_IOB ) ptr_dev     = &devices_dir.iob;
    223            if( func == DEV_FUNC_IOC ) ptr_dev     = &devices_dir.ioc;
    224            if( func == DEV_FUNC_PIC ) ptr_dev     = &devices_dir.pic;
    225            if( func == DEV_FUNC_NIC ) ptr_dev     = &devices_dir.nic_tx[chl];
    226            if( func == DEV_FUNC_NIC ) ptr_dev_bis = &devices_dir.nic_rx[chl];
    227  
     167                chdev->cmd = &soclib_tty_cmd;
     168                chdev->isr = &soclib_tty_isr;
     169                soclib_tty_init( chdev );
     170            }
     171
     172            // initialize the replicated chdev_dir[x][y] structures
    228173            for( x = 0 ; x < info->x_size ; x++ )
    229174            {
     
    231176                {
    232177                    cxy_t  cxy = (x<<info->y_width) + y;
    233                      
    234                     hal_remote_swd( XPTR( cxy , ptr_dev ) , xp_dev );
    235 
    236                     if( func == DEV_FUNC_NIC )
    237                     {
    238                        hal_remote_swd( XPTR( cxy , ptr_dev_bis ) , xp_dev_bis );
     178                    hal_remote_swd( XPTR( cxy , &chdev_dir.txt[0] ) , XPTR( local_cxy , chdev ) );
     179                }
     180            }
     181
     182                    kinit_dmsg("\n[INFO] %s : core[%x][0] created TXT0 chdev / paddr = %l at cycle %d\n",
     183                       __FUNCTION__ , local_cxy , chdev_func_str( func ), chdev_xp , hal_time_stamp() );
     184        }
     185
     186        } // end loop on devices
     187
     188}  // end txt0_device_init()
     189
     190///////////////////////////////////////////////////////////////////////////////////////////
     191// This static function allocates memory for the chdev (channel_device) descriptors
     192// associated to the internal peripherals contained in the local cluster. These internal
     193// devices (ICU, MMC, DMA) chdev descriptors are placed in the local cluster.
     194// It initialises these device descriptors as specified by the boot_info_t structure,
     195// including the dynamic linking with the driver for the specified implementation.
     196// Finally, all copies of the devices directory are initialised.
     197///////////////////////////////////////////////////////////////////////////////////////////
     198// @ info    : pointer on the local boot-info structure.
     199///////////////////////////////////////////////////////////////////////////////////////////
     200static void internal_devices_init( boot_info_t * info )
     201{
     202    boot_device_t * dev_tbl;         // pointer on array of devices in boot_info
     203        uint32_t        dev_nr;          // actual number of devices in this cluster
     204        xptr_t          base;            // remote pointer on segment base
     205        uint32_t        size;            // channel size (bytes)
     206    uint32_t        type;            // peripheral type
     207    uint32_t        func;            // device functionnal index
     208    uint32_t        impl;            // device implementation index
     209        uint32_t        i;               // device index in dev_tbl
     210        uint32_t        x;               // X cluster coordinate
     211        uint32_t        y;               // Y cluster coordinate
     212        uint32_t        channels_nr;     // number of channels in device
     213        uint32_t        channel;         // channel index
     214        uint32_t        p0;              // device parameter 0
     215        uint32_t        p1;              // device parameter 1
     216        uint32_t        p2;              // device parameter 2
     217        uint32_t        p3;              // device parameter 3
     218
     219        chdev_t       * chdev;           // local pointer on one channel_device descriptor
     220    xptr_t          chdev_xp;        // extended pointer on channel_device descriptor
     221
     222    // get number of internal devices and base of devices array from boot_info
     223        dev_nr      = info->int_dev_nr;
     224    dev_tbl     = info->int_dev;
     225
     226    // loop on all internal devices in cluster
     227        for( i = 0 ; i < dev_nr ; i++ )
     228        {
     229        size        = dev_tbl[i].size;
     230        base        = dev_tbl[i].base;
     231        type        = dev_tbl[i].type;
     232        channels_nr = dev_tbl[i].channels;
     233        p0          = dev_tbl[i].param0;
     234        p1          = dev_tbl[i].param1;
     235        p2          = dev_tbl[i].param2;
     236        p3          = dev_tbl[i].param3;
     237
     238        func     = FUNC_FROM_TYPE( type );
     239        impl     = IMPL_FROM_TYPE( type );
     240
     241        // do nothing for RAM, that does not require a chdev descriptor.
     242        if( func == DEV_FUNC_RAM ) continue;
     243
     244        // check internal device functional type
     245        if( (func != DEV_FUNC_MMC) &&
     246            (func != DEV_FUNC_ICU) &&
     247            (func != DEV_FUNC_DMA) )
     248        {
     249            assert( false , __FUNCTION__ , "illegal internal peripheral type" );
     250        }
     251
     252        // loop on channels
     253        for( channel = 0 ; channel < channels_nr ; channel++ )
     254        {
     255            // create one chdev in local cluster
     256            chdev = chdev_create( func ,
     257                                  impl,
     258                                  channel,     
     259                                  false,           // TX
     260                                  base );
     261
     262            assert( (chdev != NULL) , __FUNCTION__ , "cannot allocate internal chdev" );
     263           
     264            // get extended pointer on channel descriptor
     265            chdev_xp = XPTR( local_cxy , chdev );
     266
     267            // TODO ??? AG
     268                    // devfs_register( dev );
     269
     270            // make device type specific initialisation
     271            // the number of parameters depends on the device type
     272            // TODO : remove these parameters that  must be provided by the driver
     273            if     ( func == DEV_FUNC_ICU ) dev_icu_init( chdev , p0 , p1 , p2 );     
     274            else if( func == DEV_FUNC_MMC ) dev_mmc_init( chdev );
     275            else                            dev_dma_init( chdev );
     276
     277            // initialize the replicated chdev_dir[x][y] structures
     278            // containing extended pointers on all devices descriptors
     279            xptr_t * entry;   
     280
     281            if     ( func == DEV_FUNC_ICU ) entry  = &chdev_dir.icu[local_cxy];
     282            else if( func == DEV_FUNC_MMC ) entry  = &chdev_dir.mmc[local_cxy];
     283            else                            entry  = &chdev_dir.dma[channel];
     284 
     285            if( func != DEV_FUNC_DMA )  // ICU and MMC devices are remotely accessible
     286            {
     287                for( x = 0 ; x < info->x_size ; x++ )
     288                {
     289                    for( y = 0 ; y < info->y_size ; y++ )
     290                    {
     291                        cxy_t  cxy = (x<<info->y_width) + y;
     292                        hal_remote_swd( XPTR( cxy , entry ) , chdev_xp );
    239293                    }
    240294                }
    241295            }
    242            
    243                     kinit_dmsg("[INFO] %s created device %s / channel %d / in cluster %x\n",
    244                        __FUNCTION__ , device_func_str[func] , chl , dev_cxy );
     296            else                      // DMA devices are NOT remotely accessible
     297            {
     298                *entry = chdev_xp;
     299            }
     300
     301            kinit_dmsg("\n[INFO] %s :core[%x][0] created chdev %s / channel %d"
     302                       " / paddr = %l at cycle %d\n",
     303                       __FUNCTION__ , local_cxy , chdev_func_str( func ) ,
     304                       channel , chdev_xp , hal_time_stamp() );
    245305
    246306        } // end loop on channels
    247307
    248         // initialize the replicated devices_irq[x][y] structures
    249         // defining how peripherals are connected to PIC or ICU components
    250         uint32_t   id;
    251         uint8_t    valid;
    252         uint32_t   dev_type;
    253         uint8_t    channel;
    254         uint8_t    is_rx;
    255         uint32_t * ptr_irq;
    256 
    257         // default initiialization for devices_irq structure
    258        
    259         // only external peripherals can be connected to PIC
     308        // initialize the entries of the local chdev_icu_input structure
     309        // defining how internal peripherals are connected to ICU
     310        if( func == DEV_FUNC_ICU ) 
     311        {
     312            uint32_t   id;
     313            uint8_t    valid;
     314            uint32_t   dev_type;
     315            uint8_t    channel;
     316
     317            // loop on ICU inputs
     318            for( id = 0 ; id < CONFIG_MAX_HWIS_PER_ICU ; id++ )
     319            {
     320                valid    = dev_tbl[i].irq[id].valid;
     321                dev_type = dev_tbl[i].irq[id].dev_type;
     322                channel  = dev_tbl[i].irq[id].channel;
     323
     324                if( valid ) // only valid local IRQs are registered
     325                {
     326                    uint32_t * index;   // local pointer on the entry to be set
     327                    uint16_t   dev_func = FUNC_FROM_TYPE( dev_type );
     328                    if( dev_func == DEV_FUNC_MMC ) 
     329                        index = &chdev_icu_input.mmc;
     330                    else if( dev_func == DEV_FUNC_DMA ) 
     331                        index = &chdev_icu_input.dma[channel];
     332                    else
     333                    {
     334                        assert( false , __FUNCTION__ , "illegal source device for ICU input" );
     335                    }                   
     336
     337                    // set entry in local structure
     338                    *index = id;
     339                }
     340
     341            }  // end loop on ICU inputs
     342        }  // end if ICU
     343        } // end loop on peripherals
     344}  // end internal_devices_init()
     345
     346///////////////////////////////////////////////////////////////////////////////////////////
     347// This static function allocates memory for the chdev descriptors associated
     348// to the external (shared) peripherals contained in the local cluster. These external
     349// devices (IOB, IOC, TXT, NIC, etc ) are distributed on all clusters.
     350// It initialises these device descriptors as specified by the boot_info_t structure,
     351// including the dynamic linking with the driver for the specified implementation.
     352// Finally, all copies of the devices directory are initialised.
     353//
     354// The number of channel_devices depends on the device functionnal type.
     355// There is three nested loops to scan the full set of external channel_devices:
     356// - loop on external devices.
     357// - loop on channels for multi-channels devices.
     358// - loop on directions (RX/TX) for NIC device.
     359// The set of channel_devices is indexed by the chdev_gid global index, that is used
     360// to select the cluster containing a given chdev[func,channel,direction].
     361// All clusters scan the full set of chdevs, but only the cluster matching
     362// (chdev_gid % (x_size*y_size)) create the corresponding chdev.
     363//
     364// TODO check that cluster IO contains a PIC [AG]
     365///////////////////////////////////////////////////////////////////////////////////////////
     366// @ info    : pointer on the local boot-info structure.
     367///////////////////////////////////////////////////////////////////////////////////////////
     368static void external_devices_init( boot_info_t * info )
     369{
     370    boot_device_t * dev_tbl;         // pointer on array of devices in boot_info
     371        uint32_t        dev_nr;          // actual number of devices in this cluster
     372        xptr_t          base;            // remote pointer on segment base
     373        uint32_t        size;            // channel size (bytes)
     374    uint32_t        type;            // peripheral type
     375    uint32_t        func;            // device functionnal index
     376    uint32_t        impl;            // device implementation index
     377        uint32_t        i;               // device index in dev_tbl
     378        uint32_t        x;               // X cluster coordinate
     379        uint32_t        y;               // Y cluster coordinate
     380        uint32_t        channels_nr;     // number of channels
     381        uint32_t        channel;         // channel index
     382        uint32_t        directions_nr;   // number of directions
     383        uint32_t        direction;       // direction index
     384        uint32_t        p0;              // device parameter 0
     385        uint32_t        p1;              // device parameter 1
     386        uint32_t        p2;              // device parameter 2
     387        uint32_t        p3;              // device parameter 3
     388    uint32_t        first_channel;   // used in loop on channels
     389
     390        chdev_t       * chdev;           // local pointer on one channel_device descriptor
     391    xptr_t          chdev_xp;        // extended pointer on channel_device descriptor
     392    uint32_t        chdev_gid = 0;   // global index of channel_device descriptor
     393
     394    // get number of peripherals and base of devices array from boot_info
     395        dev_nr      = info->ext_dev_nr;
     396    dev_tbl     = info->ext_dev;
     397
     398    // loop on external peripherals
     399        for( i = 0 ; i < dev_nr ; i++ )
     400        {
     401        size        = dev_tbl[i].size;
     402        base        = dev_tbl[i].base;
     403        type        = dev_tbl[i].type;
     404        channels_nr = dev_tbl[i].channels;
     405        p0          = dev_tbl[i].param0;
     406        p1          = dev_tbl[i].param1;
     407        p2          = dev_tbl[i].param2;
     408        p3          = dev_tbl[i].param3;
     409
     410        func     = FUNC_FROM_TYPE( type );
     411        impl     = IMPL_FROM_TYPE( type );
     412
     413        // There is one chdev per direction for NIC
     414        if (func == DEV_FUNC_NIC) directions_nr = 2;
     415        else                      directions_nr = 1;
     416
     417        // The TXT0 chdev has already been created
     418        if (func == DEV_FUNC_TXT) first_channel = 1;
     419        else                      first_channel = 0;
     420
     421        // do nothing for ROM, that does not require a device descriptor.
     422        if( func == DEV_FUNC_ROM ) continue;
     423
     424        // check external device functionnal type
     425        if( (func != DEV_FUNC_IOB) &&
     426            (func != DEV_FUNC_PIC) &&
     427            (func != DEV_FUNC_IOC) &&
     428            (func != DEV_FUNC_TXT) &&
     429            (func != DEV_FUNC_NIC) &&
     430            (func != DEV_FUNC_FBF) )
     431        {
     432            assert( false , __FUNCTION__ , "undefined external peripheral type" );
     433        }
     434
     435        // loops on channels
     436        for( channel = first_channel ; channel < channels_nr ; channel++ )
     437        {
     438            // loop on directions
     439            for( direction = 0 ; direction < directions_nr ; direction++ )
     440            {
     441                // get target cluster for chdev[func,channel,direction]
     442                uint32_t offset     = chdev_gid % ( info->x_size * info->y_size );
     443                uint32_t cx         = offset / info->y_size;
     444                uint32_t cy         = offset % info->y_size;
     445                uint32_t target_cxy = (cx<<info->y_width) + cy;
     446
     447                // allocate and initialize a local chdev
     448                // if local cluster matches target cluster
     449                if( target_cxy == local_cxy )
     450                {
     451                    chdev = chdev_create( func,
     452                                          impl,
     453                                          channel,
     454                                          direction,
     455                                          base );
     456
     457                    assert( (chdev != NULL), __FUNCTION__ ,
     458                            "cannot allocate external device" );
     459
     460                    // get extended pointer on chdev
     461                    chdev_xp = XPTR( local_cxy , chdev );
     462
     463                    // make device type specific initialisation
     464                    // the number of parameters depends on the device type
     465                    // TODO : remove the parameters that  must be provided by the drivers
     466                    if     ( func == DEV_FUNC_IOB ) dev_iob_init( chdev );
     467                    else if( func == DEV_FUNC_IOC ) dev_ioc_init( chdev );
     468                    else if( func == DEV_FUNC_TXT ) dev_txt_init( chdev );
     469                    else if( func == DEV_FUNC_NIC ) dev_nic_init( chdev );
     470                    else if( func == DEV_FUNC_PIC ) dev_pic_init( chdev , p0 );
     471                    else if( func == DEV_FUNC_FBF ) dev_fbf_init( chdev , p0 , p1 );
     472                    else
     473                    {
     474                        assert( false , __FUNCTION__ , "undefined device type" );
     475                    }
     476
     477                    // all external (shared) devices are remotely accessible
     478                    // initialize the replicated chdev_dir[x][y] structures
     479                    // defining the extended pointers on chdev descriptors
     480                    xptr_t * entry;   
     481               
     482                    if( func == DEV_FUNC_IOB ) entry  = &chdev_dir.iob;
     483                    if( func == DEV_FUNC_PIC ) entry  = &chdev_dir.pic;
     484                    if( func == DEV_FUNC_TXT ) entry  = &chdev_dir.txt[channel];
     485                    if( func == DEV_FUNC_IOC ) entry  = &chdev_dir.ioc[channel];
     486                    if( func == DEV_FUNC_FBF ) entry  = &chdev_dir.fbf[channel];
     487                    if( func == DEV_FUNC_NIC ) entry  = &chdev_dir.nic_tx[channel];
     488 
     489                    for( x = 0 ; x < info->x_size ; x++ )
     490                    {
     491                        for( y = 0 ; y < info->y_size ; y++ )
     492                        {
     493                            cxy_t  cxy = (x<<info->y_width) + y;
     494                            hal_remote_swd( XPTR( cxy , entry ) , chdev_xp );
     495                        }
     496                    }
     497
     498                            kinit_dmsg("\n[INFO] %s : core[%x][0] created chdev %s / channel = %d"
     499                               " / paddr = %l at cycle %d\n",
     500                               __FUNCTION__ , local_cxy , chdev_func_str( func ),
     501                               channel , chdev_xp , hal_time_stamp() );
     502
     503                }  // end if match
     504
     505                // increment chdev global index (matching or not)           
     506                chdev_gid++;
     507
     508            } // end loop on directions
     509
     510        }  // end loop on channels
     511
     512        // initialize the entries of the local chdev_pic_input structure
     513        // defining how external peripherals are connected to PIC
    260514        if( func == DEV_FUNC_PIC ) 
    261515        {
     516            uint32_t   id;
     517            uint8_t    valid;
     518            uint32_t   dev_type;
     519            uint8_t    channel;
     520            uint8_t    is_rx;
     521
    262522            // loop on PIC inputs
    263523            for( id = 0 ; id < CONFIG_MAX_IRQS_PER_PIC ; id++ )
     
    268528                is_rx     = dev_tbl[i].irq[id].is_rx;
    269529
    270                 // only valid IRQs are registered in the devices_input_irq structure
    271                 // ptr_irq is a local pointer on the entry to be set in devices_irq
    272                 if( valid )
     530                if( valid )  // only valid inputs are registered
    273531                {
     532                    uint32_t * index;  // local pointer on one entry
    274533                    uint16_t dev_func = FUNC_FROM_TYPE( dev_type );
    275                     if( dev_func == DEV_FUNC_TXT )   
    276                         ptr_irq = &devices_input_irq.txt[channel];
    277                     if( dev_func == DEV_FUNC_IOC )                   
    278                         ptr_irq = &devices_input_irq.ioc;
    279                     if( (dev_func == DEV_FUNC_NIC) && (is_rx == 0) )
    280                         ptr_irq = &devices_input_irq.nic_tx[channel];
    281                     if( (dev_func == DEV_FUNC_NIC) && (is_rx != 0) )
    282                         ptr_irq = &devices_input_irq.nic_rx[channel];
    283                    
    284                     // all copies of devices_irq must be updated in all clusters
    285                     for( x = 0 ; x < info->x_size ; x++ )
    286                     {
    287                         for( y = 0 ; y < info->y_size ; y++ )
    288                         {
    289                             cxy_t  cxy = (x<<info->y_width) + y;
    290                             hal_remote_sw( XPTR( cxy , ptr_irq ) , id );
    291                         }       
     534
     535                    if( dev_func == DEV_FUNC_TXT )
     536                    {
     537                        index = &chdev_pic_input.txt[channel];
    292538                    }
     539                    else if( dev_func == DEV_FUNC_IOC )
     540                    {
     541                        index = &chdev_pic_input.ioc[channel];
     542                    }
     543                    else if( (dev_func == DEV_FUNC_NIC) && (is_rx == 0) )
     544                    {
     545                        index = &chdev_pic_input.nic_tx[channel];
     546                    }
     547                    else if( (dev_func == DEV_FUNC_NIC) && (is_rx != 0) )
     548                    {
     549                        index = &chdev_pic_input.nic_rx[channel];
     550                    }
     551                    else
     552                    {
     553                        assert( false , __FUNCTION__ , "illegal source device for PIC input" );
     554                    }                   
     555
     556                    // set entry in local structure
     557                    *index = id;
    293558                }
    294559            } // end loop on PIC inputs
    295560        } // end PIC
    296 
    297         // only internal peripherals can be connected to ICU
    298         if( func == DEV_FUNC_ICU ) 
    299         {
    300             // loop on ICU inputs
    301             for( id = 0 ; id < CONFIG_MAX_HWIS_PER_ICU ; id++ )
    302             {
    303                 valid    = dev_tbl[i].irq[id].valid;
    304                 dev_type = dev_tbl[i].irq[id].dev_type;
    305                 channel  = dev_tbl[i].irq[id].channel;
    306 
    307                 // only valid IRQs are registered in the devices_input_irq structure
    308                 // ptr_irq is a local pointer on the entry to be set in devices_irq
    309                 if( valid )
    310                 {
    311                     uint16_t dev_func = FUNC_FROM_TYPE( dev_type );
    312                     if( dev_func == DEV_FUNC_MMC ) 
    313                         ptr_irq = &devices_input_irq.mmc[local_cxy];
    314                     if( dev_func == DEV_FUNC_MWR ) 
    315                         ptr_irq = &devices_input_irq.mwr[local_cxy];
    316                    
    317                     // all copies of devices_irq must be updated in all clusters
    318                     for( x = 0 ; x < info->x_size ; x++ )
    319                     {
    320                         for( y = 0 ; y < info->y_size ; y++ )
    321                         {
    322                             cxy_t  cxy = (x<<info->y_width) + y;
    323                             hal_remote_sw( XPTR( cxy , ptr_irq ) , id );
    324                         }
    325                     }
    326                 }
    327             }  // end loop on ICU inputs
    328         }  // end ICU
    329         } // end loop on peripherals
    330 }  // end devices_init()
    331 
     561        } // end loop on devices
     562}  // end external_devices_init()
    332563
    333564
     
    335566// This function is the entry point for the kernel initialisation.
    336567// It is executed by all cores in all clusters, but only core[0] in each cluster
    337 // initialize the cluster manager, ant the other local shared resources.
    338 // To comply with the multi-kernels paradigm, it access only local cluster memory,
    339 // using only informations contained in the local boot_info_t structure,
    340 // that has been set by the bootloader.
    341 // All cores TODO ...
     568// initialize the cluster manager, ant the local peripherals.
     569// To comply with the multi-kernels paradigm, it access only local cluster memory, using
     570// only informations contained in the local boot_info_t structure, set by the bootloader.
    342571///////////////////////////////////////////////////////////////////////////////////////////
    343572// @ info    : pointer on the local boot-info structure.
     
    363592
    364593    // Each core makes an associative search in boot_info
    365     // to get its (cxy,lid) composite index
     594    // to get its (cxy,lid) composite index from its gid
    366595    found    = false;
    367596    core_cxy = 0;
     
    378607    }
    379608         
    380     if ( found == false )
    381     {
    382         printk("PANIC in %s : Core %d not registered in cluster %x\n",
    383                __FUNCTION__ , core_gid , local_cxy );
    384         hal_core_sleep();
    385     }
    386 
    387     if ( core_cxy != local_cxy)
    388     {
    389         printk("PANIC in %s : Core %d has wrong cxy in cluster %x\n",
    390                __FUNCTION__ , core_gid , local_cxy );
    391         hal_core_sleep();
    392     }
    393 
    394     // from this point, only core[0] initialises local resources
     609    // suicide if not found
     610    if( (found == false) || (core_cxy != local_cxy) ) hal_core_sleep();
     611
     612    //////////////////////////////////////////////////////////////
     613    // In first step, only CP0 initialises local resources
     614    //////////////////////////////////////////////////////////////
     615
    395616    if( core_lid == 0 )   
    396617    {
    397618        // initialize local cluster manager (cores and memory allocators)
    398619        error = cluster_init( info );
    399         if ( error == 0 )
    400         {
    401             printk("PANIC in %s : Failed to initialize cluster manager in cluster %x\n",
    402                    __FUNCTION__ , local_cxy );
    403             hal_core_sleep();
    404         }
     620 
     621        // suicide if failure
     622        if( error ) hal_core_sleep();
     623
     624        // get pointer on local cluster manager and on core descriptor
     625        cluster = LOCAL_CLUSTER;
     626            core    = &cluster->core_tbl[core_lid];
    405627
    406628        // initialize process_zero descriptor
    407629                process_zero_init( info );
    408630
    409         // initialize thread_zero descriptor
     631        // CP0 initialize its private thread_zero descriptor
    410632            memset( &thread_zero , 0 , sizeof(thread_t) );
    411633            thread_zero.type     = THREAD_KERNEL;
     
    413635            hal_set_current_thread( &thread_zero );
    414636
    415         // initialise local devices descriptors
    416         devices_init( info );
     637        // CP0 in I/O cluster initialize the kernel TXT0 chdev descriptor.
     638        // this TXTO device is shared by the all kernel instances for debug messages:
     639        // the printk() function call the dev_txt_sync_write() function that call
     640        // directly the relevant TXT driver, without desheduling.
     641        if( core_cxy == info->io_cxy ) txt0_device_init( info );
     642
     643        // synchronise all CP0s before using TXT0
     644        remote_barrier( XPTR( info->io_cxy , &cluster->barrier ) ,
     645                        (cluster->x_size * cluster->y_size) );
     646
     647        // All CP0 initialise internal peripheral chdev descriptors.
     648        // Each CP0[cxy] scan the set of its internal (private) peripherals,
     649        // and allocate memory for the corresponding chdev descriptors.
     650        internal_devices_init( info );
     651       
     652        // All CP0 contribute to initialise external peripheral chdev descriptors.
     653        // Each CP0[cxy] scan the set of external (shared) peripherals (but the TXT0),
     654        // and allocates memory for the chdev descriptors that must be placed
     655        // on the (cxy) cluster according to its global index. 
     656        external_devices_init( info );
    417657
    418658        // TODO initialize devFS and sysFS
     
    420660                // sysfs_root_init();
    421661
    422                 // TODO dire précisément ce qu'on fait ici [AG]
    423                 // hal_arch_init( info );
    424 
    425662        // TODO ??? [AG]
    426663                // clusters_sysfs_register();
    427664
    428         // initialize virtual file system
     665        // TODO initialize virtual file system
    429666        // vfs_init();
    430667
     
    433670
    434671        // activate other cores in same cluster
    435                 local_sync_init = KERNEL_INIT_SYNCRO;
     672                local_sync_init = KERNEL_INIT_SYNCHRO;
    436673                hal_wbflush();
    437674    }
     
    439676    {
    440677        // other cores wait synchro from core[0]
    441                 while( local_sync_init != KERNEL_INIT_SYNCRO )
     678                while( local_sync_init != KERNEL_INIT_SYNCHRO )
    442679        {
    443680                   uint32_t retval = hal_time_stamp() + 1000;
     
    445682        }
    446683
    447         // other cores initialise thread_zero descriptor
     684        // get pointer on local cluster manager and on core descriptor
     685        cluster = LOCAL_CLUSTER;
     686            core    = &cluster->core_tbl[core_lid];
     687
     688        // core initialise its private thread_zero descriptor
    448689            memset( &thread_zero , 0 , sizeof(thread_t) );
    449690            thread_zero.type     = THREAD_KERNEL;
     
    451692            hal_set_current_thread( &thread_zero );
    452693    }
    453 
    454 
    455     // each core get pointer on local cluster manager and on core descriptor
    456     cluster = LOCAL_CLUSTER;
    457         core    = &cluster->core_tbl[core_lid];
    458694
    459695        // each core creates its private idle thread descriptor
     
    463699                                  NULL,
    464700                                  core_lid );
    465     if( error )
    466         {
    467                 printk("ERROR in %s: failed to create idle thread for core %d in cluster %x\n",
    468                __FUNCTION__ , core_lid , core_cxy );
    469         hal_core_sleep();
    470     }
     701
     702    assert( (error == 0) , __FUNCTION__ , "cannot create idle thread" );
    471703
    472704    // each core register thread_idle in scheduler
     
    476708    hal_set_current_thread( thread_idle );
    477709
    478     kinit_dmsg("INFO %s  Created thread idle %x for core %d at cycle %d ]\n",
    479                thread, hal_get_gid(), hal_time_stamp());
     710    kinit_dmsg("\n[INFO] %s : thread idle created for core[%x][%d] at cycle %d\n",
     711               __FUNCTION__ , core_cxy , core_lid , hal_time_stamp());
    480712
    481713    // global syncho for all core[0] in all clusters
     
    490722                    cluster->cores_nr );
    491723
    492     if( core_lid ==  0 )
     724    if( (core_lid ==  0) && (local_cxy == info->io_cxy) )
    493725    {
    494         kinit_dmsg("INFO %s completed for cluster %x at cycle %d\n",
    495                    __FUNCTION__ , local_cxy , hal_time_stamp() );
    496 
    497         if( local_cxy == info->io_cxy ) print_boot_banner();
     726        print_banner( (info->x_size * info->y_size) , info->cores_nr );
    498727    }
    499728
    500     // load idle thread context in calling core
     729    // load idle thread context on calling core
    501730        hal_cpu_context_load( thread_idle );
    502731
  • trunk/kernel/kern/printk.c

    r1 r5  
    2424#include <hal_types.h>
    2525#include <hal_irqmask.h>
    26 #include <printk.h>
    27 #include <stdarg.h>
     26#include <hal_special.h>
    2827#include <dev_txt.h>
    2928#include <remote_spinlock.h>
    3029#include <cluster.h>
     30#include <printk.h>
    3131
    3232///////////////////////////////////////////////////////////////////////////////////
    33 // This static function is called by printk(), nolock_printk() and user_printk()
     33// This static function is called by kernel_printf() to display a string on the
     34// TXT channel defined by the <channel> argument.
     35// The access mode is defined by the <busy> argument:
     36// - if <busy> is true, it uses the dev_txt_sync_write() function, that takes the
     37//   TXT lock, and call directly the relevant TXT driver, without descheduling.
     38// - if <busy is false, it uses the dev_txt_write() function, that register the
     39//   write buffer in the relevant TXT chdev queue, and uses a descheduling policy.
    3440///////////////////////////////////////////////////////////////////////////////////
     41// @ channel  : TXT channel.
     42// @ busy     : TXT device acces mode.
     43// @ buf      : buffer containing the characters.
     44// @ nc       : number of characters.
     45// return 0 if success / return -1 if TTY0 busy after 10000 retries.
     46///////////////////////////////////////////////////////////////////////////////////
     47static error_t txt_write( uint32_t  channel,
     48                          uint32_t  busy,
     49                          char    * buffer,
     50                          uint32_t  count )
     51{
     52    if( busy ) return dev_txt_sync_write( channel , buffer , count );
     53    else       return dev_txt_write( channel , buffer , count );
     54
     55
     56//////////////////////////////////////////////////////////////////////////////////////
     57// This static function is called by printk() and user_printk() to build
     58// a formated string.
     59//////////////////////////////////////////////////////////////////////////////////////
     60// @ channel   : channel index.
     61// @ busy      : TXT device access mode.
     62// @ format    : printf like format.
     63// @ args      : format arguments.
     64//////////////////////////////////////////////////////////////////////////////////////
    3565static void kernel_printf( uint32_t   channel,
     66                           uint32_t   busy,
    3667                           char     * format,
    3768                           va_list  * args )
     
    4677        if (i)
    4778        {
    48             dev_txt_sync_write( channel, format, i );
     79            txt_write( channel, busy, format, i );
    4980            format += i;
    5081        }
     
    83114                {
    84115                    val = -val;
    85                     dev_txt_sync_write( channel, "-" , 1 );
     116                    txt_write( channel, busy, "-" , 1 );
    86117                }
    87118                for(i = 0; i < 10; i++)
     
    109140            {
    110141                uint32_t val = va_arg( *args , uint32_t );
    111                 dev_txt_sync_write( channel, "0x" , 2 );
     142                txt_write( channel, busy, "0x" , 2 );
    112143                for(i = 0; i < 8; i++)
    113144                {
    114                     buf[7 - i] = HexaTab[val % 16];
     145                    buf[7 - i] = HexaTab[val & 0xF];
    115146                    if (!(val = (val>>4)))  break;
    116147                }
     
    119150                break;
    120151            }
    121             case ('X'):             /* 32 bits hexadecimal unsigned  on 10 char*/
     152            case ('X'):             /* 32 bits hexadecimal unsigned  on 10 char */
    122153            {
    123154                uint32_t val = va_arg( *args , uint32_t );
    124                 dev_txt_sync_write( channel, "0x" , 2 );
     155                txt_write( channel, busy, "0x" , 2 );
    125156                for(i = 0; i < 8; i++)
    126157                {
    127                     buf[7 - i] = HexaTab[val % 16];
     158                    buf[7 - i] = HexaTab[val & 0xF];
    128159                    val = (val>>4);
    129160                }
     
    135166            {
    136167                uint64_t val = va_arg( *args , uint64_t );
    137                 dev_txt_sync_write( channel, "0x" , 2 );
     168                txt_write( channel, busy, "0x" , 2 );
    138169                for(i = 0; i < 16; i++)
    139170                {
    140                     buf[15 - i] = HexaTab[val % 16];
    141                     if (!(val /= 16))  break;
     171                    buf[15 - i] = HexaTab[val & 0xF];
     172                    if (!(val = (val>>4)))  break;
    142173                }
    143174                len =  i + 1;
    144175                pbuf = &buf[15 - i];
     176                break;
     177            }
     178            case ('L'):           /* 64 bits hexadecimal unsigned on 18 char */
     179            {
     180                uint64_t val = va_arg( *args , uint64_t );
     181                txt_write( channel, busy, "0x" , 2 );
     182                for(i = 0; i < 16; i++)
     183                {
     184                    buf[15 - i] = HexaTab[val & 0xF];
     185                    val = (val>>4);
     186                }
     187                len =  16;
     188                pbuf = buf;
    145189                break;
    146190            }
     
    157201            default:
    158202            {
    159                 dev_txt_sync_write( channel ,
    160                                     "\n[PANIC] in kernel_printf() : illegal format\n", 45 );
     203                txt_write( channel , busy,
     204                           "\n[PANIC] in kernel_printf() : illegal format\n", 45 );
    161205            }
    162206        }
    163207
    164         if( pbuf != NULL ) dev_txt_sync_write( channel, pbuf, len );
     208        if( pbuf != NULL ) txt_write( channel, busy, pbuf, len );
    165209       
    166210        goto printf_text;
     
    169213}  // end kernel_printf()
    170214
    171 ///////////////////////////////////////
    172 void nolock_printk( char* format, ...)
    173 {
    174     va_list   args;
     215////////////////////////////////
     216void printk( char * format, ...)
     217{
     218    va_list       args;
    175219
    176220    // call kernel_printf
    177221    va_start( args , format );
    178     kernel_printf( 0, format , &args );
     222    kernel_printf( 0 , 1 , format , &args );
    179223    va_end( args );
    180224}
    181225
    182 ////////////////////////////////
    183 void printk( char* format, ...)
    184 {
    185     va_list       args;
    186     uint32_t  save_sr;
    187 
    188     // disable IRQs
    189     hal_disable_irq( &save_sr );
    190 
    191     // get TXT0 lock
    192     cluster_t * cluster = LOCAL_CLUSTER;
    193     remote_spinlock_lock( XPTR( cluster->io_cxy , &cluster->txt0_lock ) );
     226/////////////////////////////////////
     227void user_printk( char* format, ...)
     228{
     229    va_list   args;
     230
     231    // get calling thread TXT channel TODO
     232    uint32_t channel = 0;
    194233
    195234    // call kernel_printf
    196235    va_start( args , format );
    197     kernel_printf( 0, format , &args );
    198     va_end( args );
    199 
    200     // release TXT0 lock
    201     remote_spinlock_unlock( XPTR( cluster->io_cxy , &cluster->txt0_lock ) );
    202 
    203     // restore IRQs
    204     hal_restore_irq( save_sr );
    205 }
    206 
    207 /////////////////////////////////////
    208 void user_printk( char* format, ...)
    209 {
    210     va_list   args;
    211 
    212     // get calling thread TXT channel TODO
    213     uint32_t channel = 0;
    214 
    215     // call kernel_printf
    216     va_start( args , format );
    217     kernel_printf( channel, format , &args );
     236    kernel_printf( channel, 0 , format , &args );
    218237    va_end( args );
    219238}
    220239
    221 
     240///////////////////////////////////////////
     241inline void assert( bool_t       condition,
     242                    const char * function_name,
     243                    char       * string )
     244{
     245    if( condition == false )
     246    {
     247        printk("\n[PANIC] in %s : %s\n" , function_name , string );
     248        hal_core_sleep();
     249    }
     250}
    222251
    223252// Local Variables:
  • trunk/kernel/kern/printk.h

    r1 r5  
    2424///////////////////////////////////////////////////////////////////////////////////
    2525// The printk.c and printk.h files define the functions used by the kernel
    26 // to display messages on the kernel text terminal, using a busy waiting
    27 // policy if required : these functions does not use the TXT kernel thread,
    28 // and does not deschedule if TXT peripheral is not available.
    29 // These functions use the generic TXT device to call the proper implementation
     26// to display messages on a text terminal.
     27// Two access modes are supported:
     28// - The printk() function displays kernel messages on the kernel terminal TXT0,
     29//   using a busy waiting policy: It calls directly the relevant TXT driver,
     30//   after taking the TXT0 chdev lock for exclusive access to the TXT0 terminal.
     31// - The user_printk() function displays messages on the calling thread private
     32//   terminal, using a descheduling policy: it register the request in the selected
     33//   TXT chdev waiting queue and deschedule. The calling thread is reactivated by
     34//   the IRQ signaling completion.
     35// Both functions use the generic TXT device to call the proper implementation
    3036// dependant TXT driver.
     37// Finally these files define a set of conditionnal trace <***_dmsg> for debug.
    3138///////////////////////////////////////////////////////////////////////////////////
    3239
     
    3441#define _PRINTK_H
    3542
    36 ///////////////////////////////////////////////////////////////////////////////////
    37 //       Access functions to kernel terminal TTY0
    38 ///////////////////////////////////////////////////////////////////////////////////
    39 
     43#include <hal_types.h>
     44#include <stdarg.h>
     45
     46
     47/**********************************************************************************
     48 * This function displays a formated string on the kernel terminal TXT0,
     49 * using a busy waiting policy: It calls directly the relevant TXT driver,
     50 * after taking the TXT0 chdev lock for exclusive access to the TXT0 terminal.
     51 **********************************************************************************
     52 * @ format     : formated string.
     53 *********************************************************************************/
    4054extern void         printk( char* format, ... );
    4155
    42 extern void         nolock_printk( char* format, ... );
    43 
     56/**********************************************************************************
     57 * Display a formated string on the calling thread private terminal, using a
     58 * descheduling policy: it register the request in the selected TXT chdev waiting
     59 * queue and deschedule. IT is reactivated by the IRQ signaling completion.
     60 * Not fully implemented yet ( use TXT0 in deschedling mode ).
     61 **********************************************************************************
     62 * @ format     : formated string.
     63 *********************************************************************************/
    4464extern void         user_printk( char* format, ... );
    4565
     66/**********************************************************************************
     67 * This function displaya "PANIC" message and force the calling core in
     68 * sleeping mode if a Boolean condition is false.
     69 * These functions are actually used to debug the kernel...
     70 **********************************************************************************
     71 * @ condition     : condition that must be true.
     72 * @ function_name : name of the calling function.
     73 * @ string        : error message if condition is false.
     74 *********************************************************************************/
     75inline void assert( bool_t       condition,
     76                    const char * function_name,
     77                    char       * string );
     78
    4679///////////////////////////////////////////////////////////////////////////////////
    4780//       Conditionnal debug macros
    4881///////////////////////////////////////////////////////////////////////////////////
    4982
     83#if CONFIG_CONTEXT_DEBUG
     84#define context_dmsg(...)   printk(__VA_ARGS__)
     85#else
     86#define context_dmsg(...)
     87#endif
     88
    5089#if CONFIG_CORE_DEBUG
    51 #define core_dmsg(...)   printk(__VA__ARGS__)
     90#define core_dmsg(...)   printk(__VA_ARGS__)
    5291#else
    5392#define core_dmsg(...)
     
    5594
    5695#if CONFIG_DQDT_DEBUG
    57 #define dqdt_dmsg(...)   printk(__VA__ARGS__)
     96#define dma_dmsg(...)   printk(__VA_ARGS__)
     97#else
     98#define dma_dmsg(...)
     99#endif
     100
     101#if CONFIG_DQDT_DEBUG
     102#define dqdt_dmsg(...)   printk(__VA_ARGS__)
    58103#else
    59104#define dqdt_dmsg(...)
     
    61106
    62107#if CONFIG_ELF_DEBUG
    63 #define elf_dmsg(...)   printk(__VA__ARGS__)
     108#define elf_dmsg(...)   printk(__VA_ARGS__)
    64109#else
    65110#define elf_dmsg(...)
    66111#endif
    67112
     113#if CONFIG_EXEC_DEBUG
     114#define exec_dmsg(...)   printk(__VA_ARGS__)
     115#else
     116#define exec_dmsg(...)
     117#endif
     118
     119#if CONFIG_FBF_DEBUG
     120#define fbf_dmsg(...)   printk(__VA_ARGS__)
     121#else
     122#define fbf_dmsg(...)
     123#endif
     124
    68125#if CONFIG_FORK_DEBUG
    69 #define fork_dmsg(...)   printk(__VA__ARGS__)
     126#define fork_dmsg(...)   printk(__VA_ARGS__)
    70127#else
    71128#define fork_dmsg(...)
    72129#endif
    73130
    74 #if CONFIG_EXEC_DEBUG
    75 #define exec_dmsg(...)   printk(__VA__ARGS__)
    76 #else
    77 #define exec_dmsg(...)
    78 #endif
    79 
    80131#if CONFIG_ICU_DEBUG
    81 #define icu_dmsg(...)   printk(__VA__ARGS__)
     132#define icu_dmsg(...)   printk(__VA_ARGS__)
    82133#else
    83134#define icu_dmsg(...)
     
    85136
    86137#if CONFIG_IOC_DEBUG
    87 #define ioc_dmsg(...)   printk(__VA__ARGS__)
     138#define ioc_dmsg(...)   printk(__VA_ARGS__)
    88139#else
    89140#define ioc_dmsg(...)
     141#endif
     142
     143#if CONFIG_KCM_DEBUG
     144#define kcm_dmsg(...) printk(__VA_ARGS__)
     145#else
     146#define kcm_dmsg(...)
     147#endif
     148
     149#if CONFIG_KHM_DEBUG
     150#define khm_dmsg(...) printk(__VA_ARGS__)
     151#else
     152#define khm_dmsg(...)
    90153#endif
    91154
     
    102165#endif
    103166
     167#if CONFIG_MAPPER_DEBUG
     168#define mapper_dmsg(...)   printk(__VA_ARGS__)
     169#else
     170#define mapper_dmsg(...)
     171#endif
     172
    104173#if CONFIG_MMC_DEBUG
    105 #define mmc_dmsg(...)   printk(__VA__ARGS__)
     174#define mmc_dmsg(...)   printk(__VA_ARGS__)
    106175#else
    107176#define mmc_dmsg(...)
     
    109178
    110179#if CONFIG_NIC_DEBUG
    111 #define nic_dmsg(...)   printk(__VA__ARGS__)
     180#define nic_dmsg(...)   printk(__VA_ARGS__)
    112181#else
    113182#define nic_dmsg(...)
     
    115184
    116185#if CONFIG_PIC_DEBUG
    117 #define pic_dmsg(...)   printk(__VA__ARGS__)
     186#define pic_dmsg(...)   printk(__VA_ARGS__)
    118187#else
    119188#define pic_dmsg(...)
    120189#endif
    121190
     191#if CONFIG_PPM_DEBUG
     192#define ppm_dmsg(...)   printk(__VA_ARGS__)
     193#else
     194#define ppm_dmsg(...)
     195#endif
     196
    122197#if CONFIG_PROCESS_DEBUG
    123 #define process_dmsg(...)   printk(__VA__ARGS__)
     198#define process_dmsg(...)   printk(__VA_ARGS__)
    124199#else
    125200#define process_dmsg(...)
     
    127202
    128203#if CONFIG_RPC_DEBUG
    129 #define rpc_dmsg(...)   printk(__VA__ARGS__)
     204#define rpc_dmsg(...)   printk(__VA_ARGS__)
    130205#else
    131206#define rpc_dmsg(...)
     
    133208
    134209#if CONFIG_SCHED_DEBUG
    135 #define sched_dmsg(...)   printk(__VA__ARGS__)
     210#define sched_dmsg(...)   printk(__VA_ARGS__)
    136211#else
    137212#define sched_dmsg(...)
     
    139214
    140215#if CONFIG_THREAD_DEBUG
    141 #define thread_dmsg(...)   printk(__VA__ARGS__)
     216#define thread_dmsg(...)   printk(__VA_ARGS__)
    142217#else
    143218#define thread_dmsg(...)
     
    145220
    146221#if CONFIG_TXT_DEBUG
    147 #define txt_dmsg(...)   printk(__VA__ARGS__)
     222#define txt_dmsg(...)   printk(__VA_ARGS__)
    148223#else
    149224#define txt_dmsg(...)
     
    151226
    152227#if CONFIG_VFS_DEBUG
    153 #define vfs_dmsg(...)   printk(__VA__ARGS__)
     228#define vfs_dmsg(...)   printk(__VA_ARGS__)
    154229#else
    155230#define vfs_dmsg(...)
     
    157232
    158233#if CONFIG_VMM_DEBUG
    159 #define vmm_dmsg(...)   printk(__VA__ARGS__)
     234#define vmm_dmsg(...)   printk(__VA_ARGS__)
    160235#else
    161236#define vmm_dmsg(...)
  • trunk/kernel/kern/process.c

    r1 r5  
    271271    spinlock_lock( &process->th_lock );
    272272
    273     // first loop on threads to send the THREAD_SIG_KILL signal to all peocess threads
     273    // first loop on threads to send the THREAD_SIG_KILL signal to all process threads
    274274    // we use both "ltid" and "count" indexes, because it can exist "holes" in th_tbl
    275275    for( ltid = 0 , count = 0  ;
  • trunk/kernel/kern/remote_sem.c

    r1 r5  
    101101    {
    102102        rpc_semaphore_alloc_client( ref_cxy , &sem_xp );
     103        sem_ptr = (remote_sem_t *)GET_PTR( sem_xp );
    103104    }
    104105
  • trunk/kernel/kern/rpc.c

    r1 r5  
    3333#include <core.h>
    3434#include <mapper.h>
    35 #include <device.h>
     35#include <chdev.h>
    3636#include <bits.h>
    3737#include <thread.h>
     
    5555    &rpc_thread_user_create_server,     // 4
    5656    &rpc_thread_kernel_create_server,   // 5
    57     &rpc_icu_wti_alloc_server,          // 6                       
    58     &rpc_device_alloc_server,           // 7
     57    &rpc_undefined,                     // 6                       
     58    &rpc_undefined,                     // 7
    5959    &rpc_undefined,                     // 8
    6060    &rpc_undefined,                     // 9
     
    10181018
    10191019/////////////////////////////////////////////////////////////////////////////////////////
    1020 //               Marshaling functions attached to RPC_ICU_WTI_ALLOC
    1021 /////////////////////////////////////////////////////////////////////////////////////////
    1022 
    1023 //////////////////////////////////////////////
    1024 void rpc_icu_wti_alloc_client( cxy_t      cxy,
    1025                                uint32_t * wti_id )    // out
    1026 {
    1027     // RPC must be remote
    1028     if( cxy == local_cxy )
    1029     {
    1030         printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
    1031         hal_core_sleep();
    1032     }
    1033 
    1034     // initialise RPC descriptor header
    1035     rpc_desc_t  rpc;
    1036     rpc.index    = RPC_ICU_WTI_ALLOC;
    1037     rpc.response = 1;
    1038 
    1039     // register RPC request in remote RPC fifo
    1040     rpc_send_sync( cxy , &rpc );
    1041 
    1042     // get output argument from rpc descriptor
    1043     *wti_id = (uint32_t)rpc.args[0];
    1044 }
    1045 
    1046 //////////////////////////////////////////
    1047 void rpc_icu_wti_alloc_server( xptr_t xp )
    1048 {
    1049     uint32_t      wti_id;
    1050 
    1051     // get client cluster identifier and pointer on RPC descriptor
    1052     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
    1053     rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
    1054 
    1055     // call icu_wti_alloc() function
    1056     wti_id = dev_icu_wti_alloc();
    1057 
    1058     // set output argument
    1059     hal_remote_swd( XPTR( client_cxy , &desc->args[0] ) , (uint64_t)wti_id);
    1060 }
    1061 
    1062 /////////////////////////////////////////////////////////////////////////////////////////
    1063 //               Marshaling functions attached to RPC_DEVICE_ALLOC
    1064 /////////////////////////////////////////////////////////////////////////////////////////
    1065 
    1066 /////////////////////////////////////////////
    1067 void rpc_device_alloc_client( cxy_t     cxy,
    1068                               xptr_t  * dev_xp,      // out
    1069                               error_t * error )      // out
    1070 {
    1071     // RPC must be remote
    1072     if( cxy == local_cxy )
    1073     {
    1074         printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
    1075         hal_core_sleep();
    1076     }
    1077 
    1078     // initialise RPC descriptor header
    1079     rpc_desc_t  rpc;
    1080     rpc.index    = RPC_DEVICE_ALLOC;
    1081     rpc.response = 1;
    1082 
    1083     // register RPC request in remote RPC fifo
    1084     rpc_send_sync( cxy , &rpc );
    1085 
    1086     // get output argument from rpc descriptor
    1087     *dev_xp = (xptr_t)rpc.args[0];
    1088     *error  = (error_t)rpc.args[1];
    1089 }   
    1090 
    1091 /////////////////////////////////////////
    1092 void rpc_device_alloc_server( xptr_t xp )
    1093 {
    1094     error_t      error;
    1095     kmem_req_t   req;
    1096     device_t   * dev_ptr; 
    1097     xptr_t       dev_xp;
    1098 
    1099     // get client cluster identifier and pointer on RPC descriptor
    1100     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
    1101     rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
    1102 
    1103     // allocate memory for a device descriptor
    1104     req.type   = KMEM_DEVICE;
    1105     req.flags  = AF_ZERO;
    1106     dev_ptr    = (device_t *)kmem_alloc( &req );
    1107 
    1108     // set output arguments
    1109     error  = ( dev_ptr == NULL );
    1110     dev_xp = XPTR( local_cxy , dev_ptr );
    1111     hal_remote_swd( XPTR( client_cxy , &desc->args[0] ) , (uint64_t)dev_xp );
    1112     hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
    1113 }
    1114 
    1115 
    1116 /////////////////////////////////////////////////////////////////////////////////////////
    11171020//               Marshaling functions attached to RPC_FATFS_GET_CLUSTER
    11181021/////////////////////////////////////////////////////////////////////////////////////////
     
    11901093    bool_t     first;
    11911094    reg_t      sr_save;
     1095
     1096printk("\n@@@ coucou 0\n");
    11921097
    11931098    // get client CPU and cluster coordinates
     
    12201125    while( error );
    12211126 
     1127printk("\n@@@ coucou 1\n");
     1128
    12221129    rpc_dmsg("\n[INFO] %s on core %d in cluster %x sent RPC %p to cluster %x\n",
    12231130              __FUNCTION__ , client_lid , client_cxy , rpc , server_cxy );
     
    12401147        }
    12411148
     1149printk("\n@@@ coucou 2\n");
     1150
    12421151        // activate preemption to allow incoming RPC and avoid deadlock
    12431152        if( this->type == THREAD_RPC ) hal_enable_irq( &sr_save );
     
    12481157        if( rpc->response == 0 ) break;
    12491158    }
     1159
     1160printk("\n@@@ coucou 3\n");
    12501161
    12511162    // restore preemption
     
    14251336    error_t      error;
    14261337
    1427     // do nothing if light lock already taken or FIFO empty 
     1338    // calling thread does nothing if light lock already taken or FIFO empty 
    14281339        if( (rpc_fifo->owner != 0) || (local_fifo_is_empty( &rpc_fifo->fifo )) )
    14291340    {
     
    14311342    }
    14321343
    1433         // The calling thread try to take the light lock,
    1434     // and activate an RPC thread if success
     1344        // calling thread tries to take the light lock,
     1345    // and activates an RPC thread if success
    14351346    if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) )
    14361347        {
     
    14521363        return false;
    14531364    }
    1454 } // end __rpc_check()
     1365} // end rpc_check()
    14551366
    14561367
  • trunk/kernel/kern/rpc.h

    r1 r5  
    6363    RPC_THREAD_USER_CREATE     = 4,
    6464    RPC_THREAD_KERNEL_CREATE   = 5,
    65         RPC_ICU_WTI_ALLOC          = 6,
    66     RPC_DEVICE_ALLOC           = 7,
    6765
    6866    RPC_VFS_INODE_CREATE       = 10,
     
    465463
    466464/***********************************************************************************
    467  * The RPC_ICU_WTI_ALLOC can be send by any thread running in a "client" cluster
    468  * to get a WTI mailbox from the ICU of a "server" cluster.
    469  * The WTI is allocated from the server ICU, but the WTI is not enabled,
    470  * and no target core is selected in remote cluster.
    471  * It returns wti_id == -1 if there is no free WTI in server cluster.
    472  ***********************************************************************************
    473  * @ cxy      : server cluster identifier.
    474  * @ wti_id   : [out] local pointer on WTI index in client cluster (-1 if error).
    475  **********************************************************************************/
    476 void rpc_icu_wti_alloc_client( cxy_t      cxy,
    477                                uint32_t * wti_id );   
    478 
    479 void rpc_icu_wti_alloc_server( xptr_t xp );
    480 
    481 /***********************************************************************************
    482  * The RPC_DEVICE_ALLOC can be send by any thread running in a "client" cluster
    483  * to create a device descriptor in a remote "server" cluster.
    484  * The WTI is allocated from the server ICU, but the WTI is not enabled,
    485  * and no target core is selected in remote cluster.
    486  * It returns wti_id == -1 if there is no free WTI in server cluster.
    487  ***********************************************************************************
    488  * @ cxy      : server cluster identifier.
    489  * @ dev_xp   : [out] buffer for extended pointer on device (in client cluster).
    490  * @ error    : [out] local pointer on buffer for error code (in client cluster).
    491  **********************************************************************************/
    492 void rpc_device_alloc_client( cxy_t     cxy,
    493                               xptr_t  * dev_xp,           
    494                               error_t * error );   
    495 
    496 void rpc_device_alloc_server( xptr_t xp );
    497 
    498 /***********************************************************************************
    499465 * The RPC_FATFS_GET_CLUSTER can be send by any thread running in a "client" cluster
    500466 * to scan the FAT mapper, stored in a remote "server" cluster, and get the FATFS
  • trunk/kernel/kern/signal.c

    r1 r5  
    22 * signal.c - signal-management related operations implementation
    33 *
    4  * Author  Ghassan Almaless (2008,2009,2010,2011,2012)
    5  *         Mohamed Lamine Karaoui (2015)
    6  *         Alain Greiner    (2016)
     4 * Author  Alain Greiner    (2016,2017)
    75 *
    86 * Copyright (c) UPMC Sorbonne Universites
     
    5553}
    5654
    57 ////////////////////////////////////////
    58 error_t signal_init( thread_t * thread )
    59 {
    60         thread->info.sig_state = 0;
    61         thread->info.sig_mask  = CURRENT_THREAD->info.sig_mask;
    62         return 0;
    63 }
    64 
    65 ////////////////////////////////////////////////////
    66 static error_t signal_rise_all( process_t * process,
    67                                 uint32_t    sig )
     55//////////////////////////////////////
     56void signal_rise( process_t * process,
     57                  uint32_t    sig )
    6858{
    6959        thread_t     * thread;
     
    8373                        __FUNCTION__, process->th_nr , process->pid );
    8474
    85         return 0;
    86 }
    87 
    88 ////////////////////////////////////////////////////
    89 static error_t signal_rise_one( process_t * process,
    90                                 uint32_t    sig )
    91 {
    92         thread_t * thread;
    93 
    94         spinlock_lock( &process->th_lock );
    95 
    96 //mdify to current_thread, not the one pointed by the sig_mgr ?
    97         if(process->sig_mgr.handler == NULL)
    98                 thread = list_first(&process->th_root, struct thread_s, rope);
    99         else
    100                 thread = process->sig_mgr.handler;
    101 
    102         spinlock_lock( &thread->lock );
    103         thread->info.sig_state |= (1 << sig);
    104         spinlock_unlock( &thread->lock );
    105 
    106         spinlock_unlock( &process->th_lock );
    107 
    108     sig_dmsg("\n[INFO] %s : Thread %u of process %u has received signal %u. sig_state = %x\n",        \
    109                         __FUNCTION__, thread_current_cpu(thread)->gid,                          \
    110                         process->pid, sig, thread->info.sig_state);
    111 
    112         return 0;
    113 }
    114 
     75}  // end signal_rise()
     76
     77///////////////////////////////////////////
    11578RPC_DECLARE( __signal_rise,                             \
    11679                RPC_RET( RPC_RET_PTR(error_t, err)),    \
     
    183146}
    184147
    185 //////////////////////////////////
    186 error_t signal_rise( pid_t    pid,
    187                      cxy_t    location,
    188                      uint32_t sig)
    189 {
    190         error_t err;
    191 
    192         /* Check location error */
    193         if ( location == CID_NULL )
    194         {
    195                 err = ESRCH;
    196                 printk(WARNING, "%s: there is no process with pid %u\n", \
    197                                 __FUNCTION__, pid);
    198                 return err;
    199         }
    200 
    201         err = EAGAIN;
    202         RCPC( location, RPC_PRIO_SIG_RISE, __signal_rise,       \
    203                         RPC_RECV( RPC_RECV_OBJ(err) ),          \
    204                         RPC_SEND( RPC_SEND_OBJ(pid),            \
    205                                   RPC_SEND_OBJ(sig))            \
    206             );
    207 
    208         return err;
     148///////////////////////////////
     149error_t sys_kill( pid_t    pid,
     150                  uint32_t sig)
     151{
     152    cxy_t       owner_cxy;    // process owner cluster
     153    lpid_t      owner_lpid;   // local process identifier
     154    xptr_t      root_xp;      // extended pointer on root of xlist of process copies
     155    xptr_t      lock_xp;      // extended pointer on remote_spinlock protecting this list
     156    xptr_t      iter_xp;      // iterator for process copies list
     157    xptr_t      process_xp;   // local pointer on process copy
     158    cxy_t       process_cxy;  // cluster of process copy
     159    process_t * process_ptr;  // local pointer on process copy
     160        error_t     error;
     161
     162    // get local pointer on local cluster manager
     163    cluster_t * cluster = LOCAL_CLUSTER;
     164
     165    // get owner process cluster and lpid
     166    owner_cxy  = CXY_FROM_PID( pid );
     167    owner_lpid = LPID_FROM_PID( pid );
     168
     169    // get extended pointers on copies root and lock
     170    root_xp = XPTR( owner_cxy , &cluster->copies_root[lpid] );
     171    lock_xp = XPTR( owner_cxy , &cluster->copies_lock[lpid] );
     172
     173    // take the lock protecting the copies
     174    remote_spinlock_lock( lock_xp );
     175
     176    // TODO the loop below sequencialize the RPCs
     177    // they could be pipelined...
     178 
     179    // traverse the list of copies
     180    XLIST_FOREACH( root_xp , iter_xp )
     181    {
     182        process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
     183        process_cxy = GET_CXY( process_xp );
     184        process_ptr = (process_t *)GET_PTR( process_xp );
     185
     186        if( process_xy == local_cxy )   // process copy is local
     187        {
     188            error = signal_rise( process_ptr , sig );
     189        }
     190        else                           // process copy is remote
     191        {
     192            rpc_signal_rise_client( process_cxy , process_ptr , sig );
     193        }
     194    }
     195
     196        return 0;
    209197}
    210198
  • trunk/kernel/kern/signal.h

    r1 r5  
    128128{
    129129        sa_handler_t        * sigactions[SIG_NR];
    130  ster   struct thread_s     * handler;
     130    struct thread_s     * handler;
    131131}
    132132sig_mgr_t;
     
    145145
    146146/*******************************************************************************************
    147  * This function TODO
     147 * This function register the signal <sig> in the bit_vector of all threads of a given
     148 * process identified by its <pid>, in all clusters containing threads for this process.
     149 * It can be executed by any thread running in any cluster, as this function uses
     150 * remote access to traverse the list of process copies, and the RPC_RISE_SIGNAL
     151 * to deliver the signal to all involved clusters.
     152 * The list of process copies is rooted in the owner cluster.
    148153 ******************************************************************************************/
    149154int sys_kill( pid_t    pid,
     
    156161
    157162/*******************************************************************************************
    158  * This function TODO
     163 * This function register the signal <sig> in the bit-vector of all threads of a given
     164 * process identified by its <pid>, in a given cluster.
     165 * It must be executed by a thread running in the same cluster as the target threads
     166 * (can be a local thread or a RPC thread).
    159167 ******************************************************************************************/
    160 error_t signal_init( struct thread_s * thread );
    161 
    162 /*******************************************************************************************
    163  * This function register the signal <sig> in the bit-vector of all threads of a given
    164  * process identified by its <pid>, on all clusters containing a thread .
    165  * It can be executed by any thread running in any cluster.
    166  ******************************************************************************************/
    167 error_t signal_rise( pid_t     pid,
    168                      uint32_t  sig );
     168error_t signal_rise( struct process_s * process,
     169                     uint32_t           sig );
    169170
    170171/*******************************************************************************************
  • trunk/kernel/kern/thread.c

    r1 r5  
    88 * Copyright (c) UPMC Sorbonne Universites
    99 *
    10  * This file is part of ALMOS-MKH..
     10 * This file is part of ALMOS-MKH.
    1111 *
    12  * ALMOS-MKH. is free software; you can redistribute it and/or modify it
     12 * ALMOS-MKH is free software; you can redistribute it and/or modify it
    1313 * under the terms of the GNU General Public License as published by
    1414 * the Free Software Foundation; version 2.0 of the License.
    1515 *
    16  * ALMOS-MKH. is distributed in the hope that it will be useful, but
     16 * ALMOS-MKH is distributed in the hope that it will be useful, but
    1717 * WITHOUT ANY WARRANTY; without even the implied warranty of
    1818 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     
    2020 *
    2121 * You should have received a copy of the GNU General Public License
    22  * along with ALMOS-MKH.; if not, write to the Free Software Foundation,
     22 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
    2323 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    2424 */
     
    6262};
    6363
     64//////////////////////////////////////////////////////////////////////////////////////
     65// This static function returns a printable string for the thread type.
     66//////////////////////////////////////////////////////////////////////////////////////
     67char * thread_type_str( uint32_t type )
     68{
     69    if     ( type == THREAD_USER   ) return "THREAD_USER";
     70    else if( type == THREAD_RPC    ) return "THREAD_RPC";
     71    else if( type == THREAD_DEV    ) return "THREAD_DEV";
     72    else if( type == THREAD_KERNEL ) return "THREAD_KERNEL";
     73    else if( type == THREAD_IDLE   ) return "THREAD_IDLE";
     74    else                             return "undefined";
     75}
     76
    6477/////////////////////////////////////////////////////////////////////////////////////
    6578// This static function makes the actual allocation and initialisation for a thread
     
    7689// @ core_lid   : target core local index.
    7790/////////////////////////////////////////////////////////////////////////////////////
    78 static error_t __thread_create( thread_t     ** new_thread,
    79                                 process_t     * process,
    80                                 thread_type_t   type,
    81                                 void          * func,
    82                                 void          * args,
    83                                 lid_t           core_lid,
    84                                 intptr_t        u_stack_base,
    85                                 uint32_t        u_stack_size )
     91static error_t thread_create( thread_t     ** new_thread,
     92                              process_t     * process,
     93                              thread_type_t   type,
     94                              void          * func,
     95                              void          * args,
     96                              lid_t           core_lid,
     97                              intptr_t        u_stack_base,
     98                              uint32_t        u_stack_size )
    8699{
    87100    error_t        error;
     
    171184    *new_thread = thread;
    172185        return 0;
    173 } // end __thread_create()
     186} // end thread_create()
    174187
    175188
     
    185198    lid_t          core_lid;     // selected core local index
    186199
     200    thread_dmsg("\n[INFO] %s : enters\n",
     201                __FUNCTION__ );
     202
    187203        cluster_t    * local_cluster = LOCAL_CLUSTER;
    188204
     
    199215
    200216    // make allocation / initialisation
    201     error = __thread_create( &thread,
    202                              process,
    203                              THREAD_USER,
    204                              attr->entry_func,
    205                              attr->entry_args,
    206                              core_lid,
    207                              u_stack_base,
    208                              u_stack_size );
     217    error = thread_create( &thread,
     218                           process,
     219                           THREAD_USER,
     220                           attr->entry_func,
     221                           attr->entry_args,
     222                           core_lid,
     223                           u_stack_base,
     224                           u_stack_size );
    209225    if( error ) return ENOMEM;
    210226
     
    220236    error = hal_fpu_context_create( thread );
    221237    if( error ) return ENOMEM;
    222 
    223     thread_dmsg("INFO : %s thread %x for process %x on core %d in cluster %x\n",
    224                  __FUNCTION__, thread->trdid, process->pid, core_lid, local_cluster->cxy );
     238 
     239    thread_dmsg("\n[INFO] %s : exit / trdid = %x / process %x / core = %d\n",
     240                __FUNCTION__ , thread->trdid , process->pid , core_lid );
    225241
    226242    *new_thread = thread;
     
    239255    lid_t          core_lid;     // selected core local index
    240256
     257    thread_dmsg("\n[INFO] %s : enters\n",
     258                __FUNCTION__ );
     259
    241260    // select a target core in local cluster
    242261    core_lid = cluster_select_local_core();
     
    246265
    247266    // make allocation / initialisation
    248     error = __thread_create( &new,
    249                              process,
    250                              THREAD_USER,
    251                              this->entry_func,
    252                              this->entry_args,
    253                              core_lid,
    254                              u_stack_base,
    255                              u_stack_size );
     267    error = thread_create( &new,
     268                           process,
     269                           THREAD_USER,
     270                           this->entry_func,
     271                           this->entry_args,
     272                           core_lid,
     273                           u_stack_base,
     274                           u_stack_size );
    256275    if( error ) return ENOMEM;
    257276
     
    268287
    269288    thread_dmsg("INFO : %s thread %x for process %x on core %d in cluster %x\n",
    270                  __FUNCTION__, new->trdid, process->pid, core_lid, local_cluster->cxy );
     289                 __FUNCTION__, new->trdid, process->pid, core_lid, local_cxy );
    271290
    272291    *new_thread = new;
    273292        return 0;
     293
    274294} // end thread_user_fork()
    275295
     
    286306        thread_t     * new;        // pointer on new thread descriptor
    287307
    288     cluster_t    * local_cluster = LOCAL_CLUSTER;
    289 
    290     // check type argument
    291     if( (type != THREAD_KERNEL) && (type != THREAD_RPC) &&
    292         (type != THREAD_IDLE) && (type != THREAD_DEV) )
    293     {
    294         printk("ERROR : %s received an illegal thread type\n", __FUNCTION__ );
    295         hal_core_sleep();
    296     }
    297 
    298     // check core local index
    299     if( core_lid >= local_cluster->cores_nr )
    300     {
    301         printk("ERROR : %s received an illegal core_lid\n", __FUNCTION__ );
    302         hal_core_sleep();
    303     }
     308    thread_dmsg("\n[INFO] %s : enters for %s in cluster %x\n",
     309                __FUNCTION__ , thread_type_str( type ) , local_cxy );
     310
     311    assert( ( (type == THREAD_KERNEL) || (type == THREAD_RPC) ||
     312              (type == THREAD_IDLE)   || (type == THREAD_DEV) ) ,
     313              __FUNCTION__ , "illegal thread type" );
     314
     315    assert( (core_lid < LOCAL_CLUSTER->cores_nr) ,
     316            __FUNCTION__ , "illegal core_lid" );
    304317
    305318    // make allocation / initialisation
    306     error = __thread_create( &new,
    307                              &process_zero,
    308                              type,
    309                              func,
    310                              args,
    311                              core_lid,
    312                              0 , 0 );  // no user stack for a kernel thread
     319    error = thread_create( &new,
     320                           &process_zero,
     321                           type,
     322                           func,
     323                           args,
     324                           core_lid,
     325                           0 , 0 );  // no user stack for a kernel thread
    313326    if( error )
    314327    {
    315         printk("ERROR : %s cannot create thread\n", __FUNCTION__ );
    316         hal_core_sleep();
     328        printk("\n[ERROR] in %s : cannot create thread\n", __FUNCTION__ );
     329        return ENOMEM;
    317330    }
    318331
     
    320333        hal_cpu_context_create( new );
    321334
    322     thread_dmsg("INFO : %s thread %x in cluster %x on core %d\n",
    323                  __FUNCTION__ , new->trdid , local_cluster->cxy , core_lid );
     335    thread_dmsg("\n[INFO] %s : sucessfully exit / trdid = %x / core = %d\n",
     336                 __FUNCTION__ , new->trdid , core_lid );
    324337
    325338    *new_thread = new;
    326339        return 0;
     340
    327341} // end thread_kernel_create()
    328342
     
    341355    core_t     * core       = thread->core;
    342356
    343     if( thread->children_nr )
    344     {
    345         printk("\n[PANIC] in %s : thread %x for process %x on core %d in cluster %x"
    346                " has still attached children\n",
    347                __FUNCTION__, thread->trdid, process->pid, core->lid, local_cxy );
    348         hal_core_sleep();
    349     }
    350 
    351     if( (thread->local_locks != 0) || (thread->remote_locks != 0) )
    352     {
    353         printk("\n[PANIC] in %s : thread %x for process %x on core %d in cluster %x"
    354                " did not released all locks\n",
    355                __FUNCTION__, thread->trdid, process->pid, core->lid, local_cxy );
    356         hal_core_sleep();
    357     }
     357    thread_dmsg("\n[INFO] %s : enters for thread %x in process %x / type = %s\n",
     358                __FUNCTION__ , thread->trdid , process->pid , thread_type_str( thread->type ) );
     359
     360    assert( (thread->children_nr == 0) , __FUNCTION__ , "still attached children" );
     361
     362    assert( (thread->local_locks == 0) , __FUNCTION__ , "all local locks not released" );
    358363   
     364    assert( (thread->remote_locks == 0) , __FUNCTION__ , "all remote locks not released" );
     365
    359366        tm_start = hal_time_stamp();
    360367
     
    402409        tm_end = hal_time_stamp();
    403410
    404         thread_dmsg("INFO : %s destroy thread %x for process %x on core %d in cluster %x\n"
    405                  " / duration = %d / page_faults = %d / ticks = %d\n",
    406                        __FUNCTION__, trdid , pid , core_lid , local_cxy ,
    407                        tm_end - tm_start , pgfaults , ticks );
     411        thread_dmsg("\n[INFO] %s : exit for thread %x in process %x / duration = %d\n",
     412                       __FUNCTION__, thread->trdid , process->pid , tm_end - tm_start );
    408413
    409414}  // end thread_destroy()
     
    592597    while( 1 )
    593598    {
    594         thread_dmsg("INFO : core %d in cluster %x goes to sleeping state at cycle\n",
    595                      core->lid , cluster->cxy, hal_time_stamp() );
     599        thread_dmsg("\n[INFO] %s : core %d in cluster %x goes to sleeping state at cycle\n",
     600                    __FUNCTION__ , core->lid , local_cxy , hal_time_stamp() );
    596601
    597602        // force core to sleeping state
    598603        hal_core_sleep();
    599604
    600         thread_dmsg("INFO : core %d in cluster %x wake up at cycle %d\n",
    601                      core->lid , cluster->cxy, hal_time_stamp() );
     605        thread_dmsg("\n[INFO] %s : core %d in cluster %x wake up at cycle %d\n",
     606                    __FUNCTION__ , core->lid , local_cxy , hal_time_stamp() );
    602607
    603608        // force scheduling at wake-up
  • trunk/kernel/kern/thread.h

    r1 r5  
    4040#include <dev_txt.h>
    4141#include <dev_mmc.h>
     42#include <dev_dma.h>
    4243
    4344/***************************************************************************************
     
    196197        txt_command_t   txt;             /*! TXT device generic command               */
    197198        nic_command_t   nic;             /*! NIC device generic command               */
    198         mmc_command_t   mmc;             /*! NIC device generic command               */
     199        mmc_command_t   mmc;             /*! MMC device generic command               */
     200        dma_command_t   dma;             /*! DMA device generic command               */
    199201    } 
    200     dev;
     202    command;
    201203   
    202204        cxy_t               rpc_client_cxy;  /*! client cluster index (for a RPC thread)  */
Note: See TracChangeset for help on using the changeset viewer.