Changeset 188 for trunk/kernel/kern


Ignore:
Timestamp:
Jul 12, 2017, 8:12:41 PM (7 years ago)
Author:
alain
Message:

Redefine the PIC device API.

Location:
trunk/kernel/kern
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/chdev.h

    r23 r188  
    120120    uint32_t             channel;     /*! channel index                                  */
    121121    bool_t               is_rx;       /*! relevant for NIC peripheral channels only      */
    122         xptr_t               base;        /*! extended pointer on channel segment paddr      */
     122        xptr_t               base;        /*! extended pointer on channel device segment     */
    123123    char                 name[16];    /*! name (required by DEVFS)                       */
    124124
     
    177177
    178178/******************************************************************************************
    179  * This structure defines the input IRQS for the PIC device, that is used by all external
    180  * peripherals (IOC, NIC, TXT, etc.) to signal completion of an I/O operation. It describes
    181  * the hardware wiring of IRQs between external peripherals and PIC, as each entry in this
    182  * structure contains the input IRQ index in PIC. Value is -1 for an unused input.
    183  * For a multi-channels peripheral, there is one chdev and one IRQ per channel.
    184  * This structure is replicated in each cluster. It is allocated as a global variable
    185  * in the kernel_init.c file, and is initialised during kernel init.
    186  *****************************************************************************************/
    187 
    188 typedef struct chdev_pic_input_s
    189 {
    190     uint32_t   txt[CONFIG_MAX_TXT_CHANNELS];
    191     uint32_t   ioc[CONFIG_MAX_IOC_CHANNELS];
    192     uint32_t   nic_rx[CONFIG_MAX_NIC_CHANNELS];
    193     uint32_t   nic_tx[CONFIG_MAX_NIC_CHANNELS];
    194 }
    195 chdev_pic_input_t;
    196 
    197 /******************************************************************************************
    198  * This structure defines the input IRQS for the ICU device, that is used by all internal
    199  * peripherals IRQS (DMA, MMC, etc.) to signal completion of an I/O operation. It describes
    200  * the hardware wiring of IRQs between internal peripherals and ICU, as each entry in this
    201  * structure contains the input IRQ index in ICU. Value is -1 for an unused input.
    202  * For a multi-channels peripheral, there is one chdev and one IRQ per channel.
    203  * This structure is replicated in each cluster. It is allocated as a global variable
    204  * in the kernel_init.c file, and is initialised during kernel init.
    205  *****************************************************************************************/
    206 
    207 typedef struct chdev_icu_input_s
    208 {
    209     uint32_t   dma[CONFIG_MAX_DMA_CHANNELS];
    210     uint32_t   mmc;                             // MMC is single channel
    211 }
    212 chdev_icu_input_t;
    213 
    214 /******************************************************************************************
    215179 * This function display relevant values for a chdev descriptor.
    216180 ******************************************************************************************
  • trunk/kernel/kern/cluster.h

    r101 r188  
    133133
    134134    pmgr_t            pmgr;            /*! embedded process manager                       */
     135
     136    void            * pic_extend;      /*! PIC implementation specific extension          */
    135137}
    136138cluster_t;
  • trunk/kernel/kern/core.c

    r126 r188  
    3030#include <thread.h>
    3131#include <chdev.h>
    32 #include <dev_icu.h>
     32#include <dev_pic.h>
    3333#include <rpc.h>
    3434#include <cluster.h>
     
    5050        core->usage             = 0;
    5151        core->spurious_irqs     = 0;
    52         core->rpc_threads       = 0;
    53 
    54         list_root_init( &core->rpc_free_list );
    55 
    56         core->thread_rpc        = NULL;
     52    core->rpc_threads       = 0;
    5753        core->thread_idle       = NULL;
    5854        core->fpu_owner         = NULL;
    5955        core->rand_last         = hal_time_stamp() & 0xFFF;
    6056
     57    // initialize scheduler
    6158        sched_init( core );
    6259}
     
    167164}
    168165
     166
     167/* deprecated [AG] july 20017
    169168///////////////////////////////////////////////////
    170169void core_set_irq_vector_entry( core_t   * core,
     
    177176        else                            core->pti_vector[irq_id] = chdev;
    178177}
     178*/
  • trunk/kernel/kern/core.h

    r101 r188  
    3636struct thread_s;
    3737struct chdev_s;
    38 
     38enum   pic_impl_e;
    3939
    4040/****************************************************************************************
    4141 * This structure defines the core descriptor.
    42  * - It contains an embedded private scheduler.
    43  * - It contains the three interrupt vectors, implemented as three arrays of pointers
    44  *   on the source channel devices, for all IRQs allocated to the core.
     42 * Besides the core identifiers (gid,lid), it contains an embedded private scheduler.
     43 * It contains an architecture specific extension to store the interrupt vector(s).
     44 * The core_init()function must allocate memory for this extension, depending on the
     45 * PIC device implementation type.
    4546 ***************************************************************************************/
    4647
     
    5556        uint32_t            usage;          /*! cumulated busy_percent (idle / total)      */
    5657        uint32_t            spurious_irqs;  /*! for instrumentation...                     */
     58    uint32_t            rpc_threads;    /*! current RPC threads number for this core   */
    5759        struct thread_s   * thread_rpc;     /*! pointer on current RPC thread descriptor   */
    5860        struct thread_s   * thread_idle;    /*! pointer on idle thread descriptor          */
    5961        struct thread_s   * fpu_owner;      /*! pointer on current FPU owner thread        */
    6062    uint32_t            rand_last;      /*! last computed random value                 */
    61         uint32_t            rpc_threads;    /*! total number of RPC threads for this core  */
    62         list_entry_t        rpc_free_list;  /*! root of the list of free RPC threads       */
    63 
    6463        scheduler_t         scheduler;      /*! embedded private scheduler                 */
    6564
    66     struct chdev_s    * hwi_vector[CONFIG_MAX_HWIS_PER_ICU];     /*! on source device  */
    67     struct chdev_s    * pti_vector[CONFIG_MAX_PTIS_PER_ICU];     /*! on source device  */
    68     struct chdev_s    * wti_vector[CONFIG_MAX_WTIS_PER_ICU];     /*! on source device  */
     65    void              * pic_extend;     /*! PIC implementation specific extension      */
    6966}
    7067core_t;
    7168
    72 /***************************************************************************************
     69/****************************************************************************************
    7370 * This macro returns a pointer on the calling core descriptor.
    74  **************************************************************************************/
     71 ***************************************************************************************/
    7572
    7673#define CURRENT_CORE  (CURRENT_THREAD->core)
    7774
    7875/***************************************************************************************
    79  * TODO this initialisation must be completed for the thread_idle field... [AG]
    80  * This function initializes a core descriptor from information found in arch_info.
     76 * This function initializes a core descriptor.
    8177 * It makes the association [gid] <=> [lid], as defined in arch_info, via the
    8278 * boot_info_t structure build by the bootloader in each cluster.
     79 * It allocates memory for the PIC infrastructure specific core extension.
     80 * It does NOT initialize the <thread_idle> and the <pic_extend> fields,
     81 * that must be completed later.
    8382 ***************************************************************************************
    8483 * @ core      : pointer on core descriptor to initialise.
    85  * @ lid       : local core index
    86  * @ gid       : global core identifier (hardware index)
     84 * @ lid       : local core index in cluster.
     85 * @ gid       : global core identifier (hardware index).
    8786 **************************************************************************************/
    88 void core_init( core_t   * core,
    89                 lid_t      lid,
    90                 gid_t      gid );
     87void core_init( core_t          * core,
     88                lid_t             lid,
     89                gid_t             gid );
    9190
    9291/***************************************************************************************
  • trunk/kernel/kern/do_interrupt.c

    r140 r188  
    3030void do_interrupt( thread_t * this )
    3131{
    32     // update user time
    33     thread_user_time_update( this );
    34 
    35     // access ICU device to call the relevant ISR
    36     dev_icu_irq_handler();
    37 
    38     // handle pending signals for interrupted thread
    39     thread_signals_handle( this );
    40 
    41     // update kernel time
    42     thread_kernel_time_update( this );
    4332}
  • trunk/kernel/kern/kernel_init.c

    r127 r188  
    8585cluster_t            cluster_manager                         CONFIG_CACHE_LINE_ALIGNED;
    8686
     87// This variable defines the TXT0 kernel terminal
     88__attribute__((section(".kdata")))
     89chdev_t              txt0_chdev                              CONFIG_CACHE_LINE_ALIGNED;
     90
    8791// This variables define the kernel process0 descriptor
    8892__attribute__((section(".kdata")))
     
    9397chdev_directory_t    chdev_dir                               CONFIG_CACHE_LINE_ALIGNED;
    9498
    95 // This variable contains the input IRQ indexes for the PIC device
     99// This variable contains the input IRQ indexes for the IOPIC controller
    96100__attribute__((section(".kdata")))
    97 chdev_pic_input_t    chdev_pic_input                         CONFIG_CACHE_LINE_ALIGNED;
    98 
    99 // This variable contains the input IRQ indexes for the ICU device
     101iopic_input_t         iopic_input                             CONFIG_CACHE_LINE_ALIGNED;
     102
     103// This variable contains the input IRQ indexes for the LAPIC controller
    100104__attribute__((section(".kdata")))
    101 chdev_icu_input_t    chdev_icu_input                         CONFIG_CACHE_LINE_ALIGNED;
     105lapic_input_t        lapic_input                             CONFIG_CACHE_LINE_ALIGNED;
    102106
    103107// This variable defines the local cluster identifier
    104108__attribute__((section(".kdata")))
    105109cxy_t                local_cxy                               CONFIG_CACHE_LINE_ALIGNED;
    106 
    107 // This variable defines the TXT0 chdev descriptor
    108 __attribute__((section(".kdata")))
    109 chdev_t              txt0_chdev                              CONFIG_CACHE_LINE_ALIGNED;
    110110
    111111// This variable is used for CP0 cores synchronisation in kernel_init()
     
    142142
    143143///////////////////////////////////////////////////////////////////////////////////////////
    144 // This static function initializes the TXT0 chdev descriptor, associated to the "kernel
    145 // terminal", and shared by all kernel instances for debug messages. It also registers it
    146 // in the chdev directory, containing extended pointers on all chdevs.
    147 // The global variable txt0_chdev is replicated in all clusters, but only the chdev
    148 // allocated in I/O cluster is used by ALMOS-MKH.
    149 // Therefore, this function must be called by a thread running in the I/O cluster.
     144// This function initializes the TXT0 chdev descriptor, that is the "kernel terminal",
     145// shared by all kernel instances for debug messages.
     146// It is a global variable (replicated in all clusters), because this terminal is used
     147// before the kmem allocator initialisation, but only the instance in cluster containing
     148// the calling core is registered in the "chdev_dir" directory.
    150149// As this TXT0 chdev supports only the TXT_SYNC_WRITE command, we don't create
    151150// a server thread, we don't allocate a WTI, and we don't initialize the waiting queue.
     
    158157    uint32_t        dev_nr;          // actual number of devices in this cluster
    159158    xptr_t          base;            // remote pointer on segment base
    160     uint32_t        type;            // peripheral type
    161159    uint32_t        func;            // device functional index
    162160    uint32_t        impl;            // device implementation index
     
    164162    uint32_t        x;               // X cluster coordinate
    165163    uint32_t        y;               // Y cluster coordinate
     164    uint32_t        channels;        // number of channels
    166165
    167166    // get number of peripherals and base of devices array from boot_info
     
    173172    {
    174173        base        = dev_tbl[i].base;
    175         type        = dev_tbl[i].type;
    176         func        = FUNC_FROM_TYPE( type );
    177         impl        = IMPL_FROM_TYPE( type );
     174        func        = FUNC_FROM_TYPE( dev_tbl[i].type );
     175        impl        = IMPL_FROM_TYPE( dev_tbl[i].type );
     176        channels    = dev_tbl[i].channels;
    178177
    179178        if (func == DEV_FUNC_TXT )
    180179        {
    181             // initialize basic fields
    182             txt0_chdev.func     = func;
    183             txt0_chdev.impl     = impl;
    184             txt0_chdev.channel  = 0;
    185             txt0_chdev.is_rx    = 0;
    186             txt0_chdev.base     = base;
    187 
    188             // initialize lock
     180            assert( (channels > 0) , __FUNCTION__ ,
     181                    "numner of TXT channels cannot be 0\n");
     182
     183            // initializes TXT0 basic fields
     184            txt0_chdev.func    = func;
     185            txt0_chdev.impl    = impl;
     186            txt0_chdev.channel = 0;
     187            txt0_chdev.base    = base;
     188            txt0_chdev.is_rx   = false;
     189
     190            // initializes lock
    189191            remote_spinlock_init( XPTR( local_cxy , &txt0_chdev.wait_lock ) );
    190 
    191             // TODO use generic device initialisation
    192             // hal_drivers_txt_init( &txt0_chdev );
    193 
    194             if( impl == IMPL_TXT_TTY )
    195             {
    196                 txt0_chdev.cmd = &soclib_tty_cmd;
    197                 txt0_chdev.isr = &soclib_tty_isr;
    198                 soclib_tty_init( &txt0_chdev );
    199             }
    200 
    201             // initialize the replicated chdev_dir[x][y] structures
     192           
     193            // TXT specific initialisation:
     194            // no server thread & no IRQ routing for channel 0
     195            dev_txt_init( &txt0_chdev );                 
     196
     197            // register the TXT0 in all chdev_dir[x][y] structures
    202198            for( x = 0 ; x < info->x_size ; x++ )
    203199            {
     
    210206            }
    211207
    212             kinit_dmsg("\n[INFO] %s : core[%x][0] created TXT0 chdev"
    213                        " / paddr = %l at cycle %d\n",
    214                        __FUNCTION__ , local_cxy , chdev_func_str( func ),
    215                        XPTR(local_cxy , &txt0_chdev) , hal_get_cycles() );
    216         }
    217     }
    218 }
    219 
    220 ///////////////////////////////////////////////////////////////////////////////////////////
    221 // This static function allocates memory for the chdev (channel_device) descriptors
    222 // associated to the internal peripherals contained in the local cluster. These internal
    223 // devices (ICU, MMC, DMA) chdev descriptors are placed in the local cluster.
    224 // It initialises these device descriptors as specified by the boot_info_t structure,
    225 // including the dynamic linking with the driver for the specified implementation.
    226 // Finally, all copies of the devices directory are initialised.
     208                    kinit_dmsg("\n[INFO] %s created TXT0 chdev in cluster %x at cycle %d\n",
     209                       __FUNCTION__ , local_cxy , (uint32_t)hal_time_stamp() );
     210        }
     211        } // end loop on devices
     212}  // end txt0_device_init()
     213
     214///////////////////////////////////////////////////////////////////////////////////////////
     215// This function allocates memory and initializes the chdev descriptors for the internal
     216// peripherals contained in the local cluster, other than the LAPIC, as specified by
     217// the boot_info, including the linking with the driver for the specified implementation.
     218// The relevant entries in all copies of the devices directory are initialised.
    227219///////////////////////////////////////////////////////////////////////////////////////////
    228220// @ info    : pointer on the local boot-info structure.
     
    230222static void internal_devices_init( boot_info_t * info )
    231223{
    232     boot_device_t * dev;             // pointer on boot_info device (ICU/MMC/DMA)
    233     uint32_t        x;               // X cluster coordinate
    234     uint32_t        y;               // Y cluster coordinate
    235     chdev_t       * chdev_ptr;       // local pointer on chdev descriptor
    236     xptr_t          chdev_xp;        // extended pointer on chdev descriptor
    237 
    238     ///////////  ICU   //////////
    239 
    240     dev = &info->dev_icu;
    241 
    242     assert( ((info->cores_nr == 0) || (dev->channels != 0)) , __FUNCTION__ ,
    243             "ICU device must exist in cluster containing cores" );
    244 
    245     assert( (dev->channels == 1) , __FUNCTION__ ,
    246             "channels number must be 1 for ICU device" );
    247 
    248     assert( (FUNC_FROM_TYPE( dev->type ) == DEV_FUNC_ICU ) , __FUNCTION__ ,
    249             " inconsistent ICU  device type");
    250 
    251     // create one chdev in local cluster
    252     chdev_ptr = chdev_create( FUNC_FROM_TYPE( dev->type ),
    253                               IMPL_FROM_TYPE( dev->type ),
    254                               0,                              // channel
    255                               false,                          // TX
    256                               dev->base );
    257 
    258     assert( (chdev_ptr != NULL) , __FUNCTION__ , "cannot allocate ICU chdev" );
    259 
    260     // get extended pointer on chdev descriptor
    261     chdev_xp = XPTR( local_cxy , chdev_ptr );
    262 
    263     // make ICU specific initialisation
    264     // TODO remove these three parameters
    265     dev_icu_init( chdev_ptr , dev->param0 , dev->param1 , dev->param2 );
    266 
    267     // initialize the ICU field in the chdev_dir[x][y] structures
    268     // replicated in all clusters, and containing extended pointers
    269     // on all remotely accessible devices
    270     for( x = 0 ; x < info->x_size ; x++ )
    271     {
    272         for( y = 0 ; y < info->y_size ; y++ )
    273         {
    274             cxy_t  cxy = (x<<info->y_width) + y;
    275             hal_remote_swd( XPTR( cxy , &chdev_dir.icu[local_cxy] ) , chdev_xp );
    276         }
    277     }
    278 
    279     // initialize the entries of the local chdev_icu_input structure
    280     // defining how internal peripherals are connected to ICU
    281     uint32_t   id;
    282     uint8_t    valid;
    283     uint32_t   src_type;
    284     uint8_t    src_ch;
    285     uint32_t   src_func;
    286     for( id = 0 ; id < CONFIG_MAX_HWIS_PER_ICU ; id++ )
    287     {
    288         valid    = dev->irq[id].valid;
    289         src_type = dev->irq[id].dev_type;
    290         src_ch   = dev->irq[id].channel;
    291         src_func = FUNC_FROM_TYPE( src_type );
    292 
    293         if( valid ) // only valid local IRQs are registered
    294         {
    295             if     ( src_func == DEV_FUNC_MMC ) chdev_icu_input.mmc = id;
    296             else if( src_func == DEV_FUNC_DMA ) chdev_icu_input.dma[src_ch] = id;
    297             else assert( false , __FUNCTION__ , "illegal source device for ICU input" );
    298         }
    299     }
    300 
    301     kinit_dmsg("\n[INFO] %s : core[%x][0] created ICU chdev at cycle %d\n",
    302                __FUNCTION__ , local_cxy , hal_get_cycles() );
    303 
    304     /////////// MMC internal chdev ///////////
    305 
    306     dev = &info->dev_mmc;
    307 
    308     if( dev->channels != 0 )   // MMC device is defined
    309     {
    310         assert( (dev->channels == 1) , __FUNCTION__ ,
    311             "channels number must be 1 for MMC device" );
    312 
    313         assert( (FUNC_FROM_TYPE( dev->type ) == DEV_FUNC_MMC ) , __FUNCTION__ ,
    314             " inconsistent MMC device type");
    315 
    316         // create one chdev in local cluster
    317         chdev_ptr = chdev_create( FUNC_FROM_TYPE( dev->type ),
    318                                   IMPL_FROM_TYPE( dev->type ),
    319                                   0,                              // channel
    320                                   false,                          // TX
    321                                   dev->base );
    322 
    323         assert( (chdev_ptr != NULL) , __FUNCTION__ , "cannot allocate MMC chdev" );
    324 
    325         // get extended pointer on chdev descriptor
    326         chdev_xp = XPTR( local_cxy , chdev_ptr );
    327 
    328         // make MMC specific initialisation
    329         dev_mmc_init( chdev_ptr );
    330 
    331         // initialize the MMC field in the chdev_dir[x][y] structures
    332         // replicated in all clusters, and containing extended pointers
    333         // on all remotely accessible devices
    334         for( x = 0 ; x < info->x_size ; x++ )
    335         {
    336             for( y = 0 ; y < info->y_size ; y++ )
     224    boot_device_t * dev_tbl;         // pointer on array of internaldevices in boot_info
     225        uint32_t        dev_nr;          // actual number of devices in this cluster
     226        xptr_t          base;            // remote pointer on segment base
     227    uint32_t        func;            // device functionnal index
     228    uint32_t        impl;            // device implementation index
     229        uint32_t        i;               // device index in dev_tbl
     230        uint32_t        x;               // X cluster coordinate
     231        uint32_t        y;               // Y cluster coordinate
     232        uint32_t        channels;        // number of channels
     233        uint32_t        channel;         // channel index
     234        chdev_t       * chdev_ptr;       // local pointer on created chdev
     235
     236    // get number of internal peripherals and base from boot_info
     237        dev_nr  = info->int_dev_nr;
     238    dev_tbl = info->int_dev;
     239
     240    // loop on internal peripherals
     241        for( i = 0 ; i < dev_nr ; i++ )
     242        {
     243        base        = dev_tbl[i].base;
     244        channels    = dev_tbl[i].channels;
     245        func        = FUNC_FROM_TYPE( dev_tbl[i].type );
     246        impl        = IMPL_FROM_TYPE( dev_tbl[i].type );
     247
     248        //////////////////////////
     249        if( func == DEV_FUNC_MMC ) 
     250        {
     251            assert( (channels == 1) , __FUNCTION__ ,
     252                    "MMC device must be single channel\n" );
     253
     254            // create chdev in local cluster
     255            chdev_ptr = chdev_create( func,
     256                                      impl,
     257                                      0,          // channel
     258                                      false,      // direction
     259                                      base );
     260
     261            assert( (chdev_ptr != NULL) , __FUNCTION__ ,
     262                    "cannot allocate memory for MMC chdev\n" );
     263           
     264            // make MMC specific initialisation
     265            dev_mmc_init( chdev_ptr );
     266
     267            // set the MMC field in all chdev_dir[x][y] structures
     268            for( x = 0 ; x < info->x_size ; x++ )
    337269            {
    338                 cxy_t  cxy = (x<<info->y_width) + y;
    339                 hal_remote_swd( XPTR( cxy , &chdev_dir.mmc[local_cxy] ) , chdev_xp );
     270                for( y = 0 ; y < info->y_size ; y++ )
     271                {
     272                    cxy_t  cxy = (x<<info->y_width) + y;
     273                    hal_remote_swd( XPTR( cxy , &chdev_dir.mmc[local_cxy] ),
     274                                    XPTR( local_cxy , chdev_ptr ) );
     275                }
    340276            }
    341         }
    342 
    343         kinit_dmsg("\n[INFO] %s : core[%x][0] created MMC chdev at cycle %d\n",
    344                    __FUNCTION__ , local_cxy , hal_get_cycles() );
    345     }
    346 
    347     /////////// DMA internal chdevs //////////
    348 
    349     dev = &info->dev_dma;
    350 
    351     if( dev->channels != 0 )   // DMA device is defined
    352     {
    353         assert( (FUNC_FROM_TYPE( dev->type ) == DEV_FUNC_DMA ) , __FUNCTION__ ,
    354                 " inconsistent DMA  device type");
    355 
    356         // create one chdev per channel in local cluster
    357         uint32_t channel;
    358         for( channel = 0 ; channel < dev->channels ; channel++ )
    359         {
    360             chdev_ptr = chdev_create( FUNC_FROM_TYPE( dev->type ),
    361                                       IMPL_FROM_TYPE( dev->type ),
    362                                       channel,                        // channel
    363                                       false,                          // TX
    364                                       dev->base );
    365 
    366             assert( (chdev_ptr != NULL) , __FUNCTION__ , "cannot allocate DMA chdev" );
    367 
    368             // get extended pointer on channel descriptor
    369             chdev_xp = XPTR( local_cxy , chdev_ptr );
    370 
    371             // make DMA specific initialisation
    372             dev_dma_init( chdev_ptr );
    373 
    374             // initialize only the DMA[channel] field in the local chdev_dir[x][y]
    375             // structure because the DMA device is not remotely accessible.
    376             chdev_dir.dma[channel] = chdev_xp;
    377 
    378             kinit_dmsg("\n[INFO] %s : core[%x][0] created DMA[%d] chdev at cycle %d\n",
    379                        __FUNCTION__ , local_cxy , channel , hal_get_cycles() );
     277
     278            if( local_cxy == 0 )
     279            kinit_dmsg("\n[INFO] %s created MMC chdev in cluster 0 at cycle %d\n",
     280                       __FUNCTION__ , local_cxy , (uint32_t)hal_time_stamp() );
     281        }
     282        ///////////////////////////////
     283        else if( func == DEV_FUNC_DMA )
     284        {
     285            // create one chdev per channel in local cluster
     286            for( channel = 0 ; channel < channels ; channel++ )
     287            {   
     288                // create chdev[channel] in local cluster
     289                chdev_ptr = chdev_create( func,
     290                                          impl,
     291                                          channel,
     292                                          false,     // direction
     293                                          base );
     294
     295                assert( (chdev_ptr != NULL) , __FUNCTION__ ,
     296                        "cannot allocate memory for DMA chdev" );
     297           
     298                // make DMA specific initialisation
     299                dev_dma_init( chdev_ptr );     
     300
     301                // initialize only the DMA[channel] field in the local chdev_dir[x][y]
     302                // structure because the DMA device is not remotely accessible.
     303                chdev_dir.dma[channel] = XPTR( local_cxy , chdev_ptr );
     304
     305                kinit_dmsg("\n[INFO] %s created DMA[%d] chdev in cluster 0 at cycle %d\n",
     306                           __FUNCTION__ , channel , (uint32_t)hal_time_stamp() );
     307            }
    380308        }
    381309    }
     
    383311
    384312///////////////////////////////////////////////////////////////////////////////////////////
    385 // This static function allocates memory for the chdev descriptors associated
    386 // to the external (shared) peripherals contained in the local cluster. These external
    387 // devices (IOB, IOC, TXT, NIC, etc ) are distributed on all clusters.
    388 // It initialises these device descriptors as specified by the boot_info_t structure,
     313// This function allocates memory and initializes the chdev descriptors for the 
     314// external (shared) peripherals other than the IOPIC, as specified by the boot_info,
    389315// including the dynamic linking with the driver for the specified implementation.
    390 // Finally, all copies of the devices directory are initialised.
    391 //
    392 // The number of channel_devices depends on the device functional type.
    393 // There are three nested loops to build the full set of external channel_devices:
    394 // - loop on external devices.
    395 // - loop on channels for multi-channels devices.
    396 // - loop on directions (RX/TX) for NIC device.
    397 // The set of channel_devices is indexed by the chdev_gid global index, that is used
    398 // to select the cluster containing a given chdev[func,channel,direction].
    399 // All clusters scan the full set of chdevs, but only the cluster matching
    400 // (chdev_gid % (x_size*y_size)) create the corresponding chdev.
    401 //
    402 // TODO check that cluster IO contains a PIC [AG]
    403 // TODO make a default initialisation for the chdev_dir structure (XPTR_NULL )  [AG]
     316// These chdev descriptors are distributed on all clusters, using a modulo on a global
     317// index, identically computed in all clusters: In each cluster, the local CP0 core
     318// computes the global index for all external chdevs, and creates only the chdevs that
     319// must be placed in the local cluster.
     320// The relevant entries in all copies of the devices directory are initialised.
    404321///////////////////////////////////////////////////////////////////////////////////////////
    405322// @ info    : pointer on the local boot-info structure.
     
    407324static void external_devices_init( boot_info_t * info )
    408325{
    409     boot_device_t * dev_tbl;         // pointer on array of devices in boot_info
    410     uint32_t        dev_nr;          // actual number of devices in this cluster
    411     xptr_t          base;            // remote pointer on segment base
    412     uint32_t        type;            // peripheral type
     326    boot_device_t * dev_tbl;         // pointer on array of external devices in boot_info
     327        uint32_t        dev_nr;          // actual number of external devices
     328        xptr_t          base;            // remote pointer on segment base
    413329    uint32_t        func;            // device functionnal index
    414330    uint32_t        impl;            // device implementation index
    415     uint32_t        i;               // device index in dev_tbl
    416     uint32_t        x;               // X cluster coordinate
    417     uint32_t        y;               // Y cluster coordinate
    418     uint32_t        channels_nr;     // number of channels
    419     uint32_t        channel;         // channel index
    420     uint32_t        directions_nr;   // number of directions
    421     uint32_t        direction;       // direction index
    422     uint32_t        p0;              // device parameter 0
    423     uint32_t        p1;              // device parameter 1
    424     uint32_t        p2;              // device parameter 2
    425     uint32_t        p3;              // device parameter 3
    426     uint32_t        first_channel;   // used in loop on channels
    427 
     331        uint32_t        i;               // device index in dev_tbl
     332        uint32_t        x;               // X cluster coordinate
     333        uint32_t        y;               // Y cluster coordinate
     334        uint32_t        channels;        // number of channels
     335        uint32_t        channel;         // channel index
     336        uint32_t        directions;      // number of directions (1 or 2)
     337        uint32_t        rx;              // direction index (0 or 1)
     338    uint32_t        first_channel;   // used in loop on channels for TXT
    428339    chdev_t       * chdev;           // local pointer on one channel_device descriptor
    429     xptr_t          chdev_xp;        // extended pointer on channel_device descriptor
    430     uint32_t        chdev_gid = 0;   // global index of channel_device descriptor
     340    uint32_t        ext_chdev_gid;   // global index of external chdev
    431341
    432342    // get number of peripherals and base of devices array from boot_info
     
    434344    dev_tbl     = info->ext_dev;
    435345
     346    // initializes global index (PIC is already placed in cluster 0
     347    ext_chdev_gid = 1;
     348
    436349    // loop on external peripherals
    437350    for( i = 0 ; i < dev_nr ; i++ )
    438351    {
    439         base        = dev_tbl[i].base;
    440         type        = dev_tbl[i].type;
    441         channels_nr = dev_tbl[i].channels;
    442         p0          = dev_tbl[i].param0;
    443         p1          = dev_tbl[i].param1;
    444         p2          = dev_tbl[i].param2;
    445         p3          = dev_tbl[i].param3;
    446 
    447         func     = FUNC_FROM_TYPE( type );
    448         impl     = IMPL_FROM_TYPE( type );
     352        base     = dev_tbl[i].base;
     353        channels = dev_tbl[i].channels;
     354        func     = FUNC_FROM_TYPE( dev_tbl[i].type );
     355        impl     = IMPL_FROM_TYPE( dev_tbl[i].type );
    449356
    450357        // There is one chdev per direction for NIC
    451         if (func == DEV_FUNC_NIC) directions_nr = 2;
    452         else                      directions_nr = 1;
     358        if (func == DEV_FUNC_NIC) directions = 2;
     359        else                      directions = 1;
    453360
    454361        // The TXT0 chdev has already been created
     
    456363        else                      first_channel = 0;
    457364
    458         // do nothing for ROM, that does not require a device descriptor.
     365        // do nothing for RO, that does not require a device descriptor.
    459366        if( func == DEV_FUNC_ROM ) continue;
    460367
    461         // check external device functional type
    462         if( (func != DEV_FUNC_IOB) &&
    463             (func != DEV_FUNC_PIC) &&
    464             (func != DEV_FUNC_IOC) &&
    465             (func != DEV_FUNC_TXT) &&
    466             (func != DEV_FUNC_NIC) &&
    467             (func != DEV_FUNC_FBF) )
    468         {
    469             assert( false , __FUNCTION__ , "undefined external peripheral type" );
    470         }
     368        // do nothing for PIC, that is already initialized
     369        if( func == DEV_FUNC_PIC ) continue;
     370
     371        // check PIC device initialized
     372        assert( (chdev_dir.pic != XPTR_NULL ) , __FUNCTION__ ,
     373              "PIC device must be initialized before other devices\n" );
     374
     375        // check external device functionnal type
     376        assert( ( (func == DEV_FUNC_IOB) ||
     377                  (func == DEV_FUNC_IOC) ||
     378                  (func == DEV_FUNC_TXT) ||
     379                  (func == DEV_FUNC_NIC) ||
     380                  (func == DEV_FUNC_FBF) ) , __FUNCTION__ ,
     381                  "undefined external peripheral type\n" );
    471382
    472383        // loops on channels
    473         for( channel = first_channel ; channel < channels_nr ; channel++ )
     384        for( channel = first_channel ; channel < channels ; channel++ )
    474385        {
    475386            // loop on directions
    476             for( direction = 0 ; direction < directions_nr ; direction++ )
     387            for( rx = 0 ; rx < directions ; rx++ )
    477388            {
    478                 // get target cluster for chdev[func,channel,direction]
    479                 uint32_t offset     = chdev_gid % ( info->x_size * info->y_size );
     389                // compute target cluster for chdev[func,channel,direction]
     390                uint32_t offset     = ext_chdev_gid % ( info->x_size * info->y_size );
    480391                uint32_t cx         = offset / info->y_size;
    481392                uint32_t cy         = offset % info->y_size;
     
    489400                                          impl,
    490401                                          channel,
    491                                           direction,
     402                                          rx,          // direction
    492403                                          base );
    493404
     
    495406                            "cannot allocate external device" );
    496407
    497                     // get extended pointer on chdev
    498                     chdev_xp = XPTR( local_cxy , chdev );
    499 
    500408                    // make device type specific initialisation
    501                     // the number of parameters depends on the device type
    502                     // TODO : remove the parameters that  must be provided by the drivers
    503409                    if     ( func == DEV_FUNC_IOB ) dev_iob_init( chdev );
    504410                    else if( func == DEV_FUNC_IOC ) dev_ioc_init( chdev );
    505411                    else if( func == DEV_FUNC_TXT ) dev_txt_init( chdev );
    506412                    else if( func == DEV_FUNC_NIC ) dev_nic_init( chdev );
    507                     else if( func == DEV_FUNC_PIC ) dev_pic_init( chdev , p0 );
    508                     else if( func == DEV_FUNC_FBF ) dev_fbf_init( chdev , p0 , p1 );
    509                     else
    510                     {
    511                         assert( false , __FUNCTION__ , "undefined device type" );
    512                     }
     413                    else if( func == DEV_FUNC_FBF ) dev_fbf_init( chdev );
    513414
    514415                    // all external (shared) devices are remotely accessible
     
    517418                    xptr_t * entry;
    518419
    519                     if( func == DEV_FUNC_IOB ) entry  = &chdev_dir.iob;
    520                     if( func == DEV_FUNC_PIC ) entry  = &chdev_dir.pic;
    521                     if( func == DEV_FUNC_TXT ) entry  = &chdev_dir.txt[channel];
    522                     if( func == DEV_FUNC_IOC ) entry  = &chdev_dir.ioc[channel];
    523                     if( func == DEV_FUNC_FBF ) entry  = &chdev_dir.fbf[channel];
    524                     if( func == DEV_FUNC_NIC ) entry  = &chdev_dir.nic_tx[channel];
     420                    if(func==DEV_FUNC_IOB            ) entry  = &chdev_dir.iob;
     421                    if(func==DEV_FUNC_IOC             ) entry  = &chdev_dir.ioc[channel];
     422                    if(func==DEV_FUNC_TXT            ) entry  = &chdev_dir.txt[channel];
     423                    if(func==DEV_FUNC_FBF             ) entry  = &chdev_dir.fbf[channel];
     424                    if((func==DEV_FUNC_NIC) && (rx==0)) entry  = &chdev_dir.nic_tx[channel];
     425                    if((func==DEV_FUNC_NIC) && (rx==1)) entry  = &chdev_dir.nic_rx[channel];
    525426
    526427                    for( x = 0 ; x < info->x_size ; x++ )
     
    529430                        {
    530431                            cxy_t  cxy = (x<<info->y_width) + y;
    531                             hal_remote_swd( XPTR( cxy , entry ) , chdev_xp );
     432                            hal_remote_swd( XPTR( cxy , entry ),
     433                                            XPTR( local_cxy , chdev ) );
    532434                        }
    533435                    }
    534436
    535                     kinit_dmsg("\n[INFO] %s : core[%x][0] create chdev %s[%d] at cycle %d\n",
    536                                __FUNCTION__ , local_cxy , chdev_func_str( func ),
    537                                channel , hal_get_cycles() );
     437                            kinit_dmsg("\n[INFO] %s create chdev %s[%d] in cluster %x at cycle %d\n",
     438                               __FUNCTION__ , chdev_func_str( func ), channel,
     439                               local_cxy , (uint32_t)hal_time_stamp() );
    538440
    539441                }  // end if match
    540442
    541443                // increment chdev global index (matching or not)
    542                 chdev_gid++;
     444                ext_chdev_gid++;
    543445
    544446            } // end loop on directions
    545 
    546447        }  // end loop on channels
    547 
    548         // initialize the entries of the local chdev_pic_input structure
    549         // defining how external peripherals are connected to PIC
     448        } // end loop on devices
     449}  // end external_devices_init()
     450
     451///////////////////////////////////////////////////////////////////////////////////////////
     452// This function is called by CP0 in cluster 0 to allocate memory and initialize the PIC
     453// device, namely the informations attached to the external IOPIC controller.
     454// This initialisation must be done before other devices initialisation because the IRQ
     455// routing infrastructure is required for internal and external devices initialisation.
     456///////////////////////////////////////////////////////////////////////////////////////////
     457// @ info    : pointer on the local boot-info structure.
     458///////////////////////////////////////////////////////////////////////////////////////////
     459static void iopic_init( boot_info_t * info )
     460{
     461    boot_device_t * dev_tbl;         // pointer on boot_info external devices array
     462        uint32_t        dev_nr;          // actual number of external devices
     463        xptr_t          base;            // remote pointer on segment base
     464    uint32_t        func;            // device functionnal index
     465    uint32_t        impl;            // device implementation index
     466        uint32_t        i;               // device index in dev_tbl
     467    uint32_t        x;               // cluster X coordinate
     468    uint32_t        y;               // cluster Y coordinate
     469    bool_t          found;           // IOPIC found
     470        chdev_t       * chdev;           // pointer on PIC chdev descriptor
     471
     472    // get number of external peripherals and base of array from boot_info
     473        dev_nr      = info->ext_dev_nr;
     474    dev_tbl     = info->ext_dev;
     475
     476    // loop on external peripherals to get the IOPIC 
     477        for( i = 0 , found = false ; i < dev_nr ; i++ )
     478        {
     479        func = FUNC_FROM_TYPE( dev_tbl[i].type );
     480
    550481        if( func == DEV_FUNC_PIC )
    551482        {
    552             uint32_t   id;
    553             uint8_t    valid;
    554             uint32_t   dev_type;
    555             uint8_t    channel;
    556             uint8_t    is_rx;
    557 
    558             // loop on PIC inputs
    559             for( id = 0 ; id < CONFIG_MAX_IRQS_PER_PIC ; id++ )
     483            base     = dev_tbl[i].base;
     484            impl     = IMPL_FROM_TYPE( dev_tbl[i].type );
     485            found    = true;
     486            break;
     487        }
     488    }
     489
     490    assert( found , __FUNCTION__ , "PIC device not found\n" );
     491
     492    // allocate and initialize the PIC chdev in local cluster
     493    chdev = chdev_create( func,
     494                          impl,
     495                          0,      // channel
     496                          0,      // direction,
     497                          base );
     498
     499    assert( (chdev != NULL), __FUNCTION__ , "no memory for PIC chdev\n" );
     500
     501    // make PIC device type specific initialisation
     502    dev_pic_init( chdev );
     503
     504    // register extended pointer on PIC chdev in "chdev_dir" array in all clusters
     505    xptr_t * entry = &chdev_dir.pic;   
     506               
     507    for( x = 0 ; x < info->x_size ; x++ )
     508    {
     509        for( y = 0 ; y < info->y_size ; y++ )
     510        {
     511            cxy_t  cxy = (x<<info->y_width) + y;
     512            hal_remote_swd( XPTR( cxy , entry ) ,
     513                            XPTR( local_cxy , chdev ) );
     514        }
     515    }
     516
     517    // initialize the "iopic_input" structure
     518    // defining how external IRQs are connected to IOPIC
     519    uint32_t   id;
     520    uint8_t    valid;
     521    uint32_t   type;
     522    uint8_t    channel;
     523    uint8_t    is_rx;
     524
     525    for( id = 0 ; id < CONFIG_MAX_EXTERNAL_IRQS ; id++ )
     526    {
     527        valid   = dev_tbl[i].irq[id].valid;
     528        type    = dev_tbl[i].irq[id].dev_type;
     529        channel = dev_tbl[i].irq[id].channel;
     530        is_rx   = dev_tbl[i].irq[id].is_rx;
     531
     532        if( valid )  // only valid inputs are registered
     533        {
     534            uint32_t * index;  // local pointer on one entry
     535            uint16_t func = FUNC_FROM_TYPE( type );
     536
     537            if     ( func == DEV_FUNC_TXT )
     538            index = &iopic_input.txt[channel];
     539            else if( func == DEV_FUNC_IOC )
     540            index = &iopic_input.ioc[channel];
     541            else if( (func == DEV_FUNC_NIC) && (is_rx == 0) )
     542            index = &iopic_input.nic_tx[channel];
     543            else if( (func == DEV_FUNC_NIC) && (is_rx != 0) )
     544            index = &iopic_input.nic_rx[channel];
     545            else if( func == DEV_FUNC_IOB )
     546            index = &iopic_input.iob;
     547            else
     548            assert( false , __FUNCTION__ , "illegal source device for IOPIC input" );
     549
     550            // set entry in local structure
     551            *index = id;
     552        }
     553    }
     554
     555    kinit_dmsg("\n[INFO] %s created IOPIC chdev in cluster %x at cycle %d\n",
     556               __FUNCTION__ , local_cxy , (uint32_t)hal_time_stamp() );
     557   
     558}  // end iopic_init()
     559
     560///////////////////////////////////////////////////////////////////////////////////////////
     561// This function is called by all CP0s in all cluster to complete the PIC device
     562// initialisation, namely the informations attached to the LAPIC controller.
     563// This initialisation must be done after the IOPIC initialisation, but before other
     564// devices initialisation because the IRQ routing infrastructure is required for both
     565// internal and external devices initialisation.
     566///////////////////////////////////////////////////////////////////////////////////////////
     567// @ info    : pointer on the local boot-info structure.
     568///////////////////////////////////////////////////////////////////////////////////////////
     569static void lapic_init( boot_info_t * info )
     570{
     571    boot_device_t * dev_tbl;      // pointer on boot_info internal devices array
     572    uint32_t        dev_nr;       // number of internal devices
     573    uint32_t        i;            // device index in dev_tbl
     574        xptr_t          base;         // remote pointer on segment base
     575    uint32_t        func;         // device functionnal type in boot_info
     576    bool_t          found;        // LAPIC found
     577
     578    // get number of internal peripherals and base
     579        dev_nr      = info->int_dev_nr;
     580    dev_tbl     = info->int_dev;
     581
     582    // loop on internal peripherals to get the lapic device
     583        for( i = 0 , found = false ; i < dev_nr ; i++ )
     584        {
     585        func = FUNC_FROM_TYPE( dev_tbl[i].type );
     586
     587        if( func == DEV_FUNC_ICU )
     588        {
     589            base     = dev_tbl[i].base;
     590            found    = true;
     591            break;
     592        }
     593    }
     594
     595    // if the LAPIC controller is not defined in the boot_info,
     596    // we simply don't initialize the PIC extensions in the kernel,
     597    // making the assumption that the LAPIC related informations
     598    // are hidden in the hardware specific PIC driver.
     599    if( found )
     600    {
     601        // initialise the PIC extensions for
     602        // the core descriptor and core manager extensions
     603        dev_pic_extend_init( (uint32_t *)GET_PTR( base ) );
     604
     605        // initialize the "lapic_input" structure
     606        // defining how internal IRQs are connected to LAPIC
     607        uint32_t        id;
     608        uint8_t         valid;
     609        uint8_t         channel;
     610        uint32_t        func;
     611
     612        for( id = 0 ; id < CONFIG_MAX_INTERNAL_IRQS ; id++ )
     613        {
     614            valid    = dev_tbl[i].irq[id].valid;
     615            func     = FUNC_FROM_TYPE( dev_tbl[i].irq[id].dev_type );
     616            channel  = dev_tbl[i].irq[id].channel;
     617
     618            if( valid ) // only valid local IRQs are registered
    560619            {
    561                 valid     = dev_tbl[i].irq[id].valid;
    562                 dev_type  = dev_tbl[i].irq[id].dev_type;
    563                 channel   = dev_tbl[i].irq[id].channel;
    564                 is_rx     = dev_tbl[i].irq[id].is_rx;
    565 
    566                 if( valid )  // only valid inputs are registered
    567                 {
    568                     uint32_t * index;  // local pointer on one entry
    569                     uint16_t dev_func = FUNC_FROM_TYPE( dev_type );
    570 
    571                     if( dev_func == DEV_FUNC_TXT )
    572                     {
    573                         index = &chdev_pic_input.txt[channel];
    574                     }
    575                     else if( dev_func == DEV_FUNC_IOC )
    576                     {
    577                         index = &chdev_pic_input.ioc[channel];
    578                     }
    579                     else if( (dev_func == DEV_FUNC_NIC) && (is_rx == 0) )
    580                     {
    581                         index = &chdev_pic_input.nic_tx[channel];
    582                     }
    583                     else if( (dev_func == DEV_FUNC_NIC) && (is_rx != 0) )
    584                     {
    585                         index = &chdev_pic_input.nic_rx[channel];
    586                     }
    587                     else
    588                     {
    589                         assert( false , __FUNCTION__ , "illegal source device for PIC input" );
    590                     }
    591 
    592                     // set entry in local structure
    593                     *index = id;
    594                 }
    595             } // end loop on PIC inputs
    596         } // end PIC
    597     } // end loop on devices
    598 }  // end external_devices_init()
    599 
     620                if     ( func == DEV_FUNC_MMC ) lapic_input.mmc = id;
     621                else if( func == DEV_FUNC_DMA ) lapic_input.dma[channel] = id;
     622                else assert( false , __FUNCTION__ , "illegal source device for LAPIC input" );
     623            }
     624        }
     625    }
     626}  // end lapic_init()
    600627
    601628///////////////////////////////////////////////////////////////////////////////////////////
     
    645672void kernel_init( boot_info_t * info )
    646673{
    647     lid_t        core_lid = -1;      // running core local index
    648     cxy_t        core_cxy = -1;      // running core cluster identifier
    649     gid_t        core_gid;           // running core hardware identifier
    650     cluster_t  * cluster;            // pointer on local cluster manager
    651     core_t     * core;               // pointer on running core descriptor
    652     thread_t   * thread;             // pointer on idle thread descriptor
     674    lid_t        core_lid = -1;        // running core local index
     675    cxy_t        core_cxy = -1;        // running core cluster identifier
     676    gid_t        core_gid;             // running core hardware identifier
     677    cluster_t  * cluster;              // pointer on local cluster manager
     678    core_t     * core;                 // pointer on running core descriptor
     679    thread_t   * thread;               // pointer on idle thread descriptor
     680    xptr_t       vfs_root_inode_xp;    // extended pointer on VFS root inode
     681//  xptr_t       devfs_root_inode_xp;  // extended pointer on DEVFS root inode
    653682    error_t      error;
    654683
    655     // all cores get and check core identifiers
     684    cxy_t        io_cxy = info->io_cxy;
     685
     686    /////////////////////////////////////////////////////////////////////////////////
     687    // STEP 0 : Each core get its core identifier from boot_info, and makes
     688    //          a partial initialisation of its private idle thread descriptor.
     689    //          CP0 initializes the "local_cxy" global variable.
     690    //          CP0 in cluster IO initializes the TXT0 chdev to print log messages.
     691    /////////////////////////////////////////////////////////////////////////////////
     692
    656693    error = get_core_identifiers( info,
    657694                                  &core_lid,
     
    668705    hal_set_current_thread( thread );
    669706
     707    // each core initializes the idle thread "locks_root" and "xlocks_root" fields
    670708    list_root_init( &thread->locks_root );
    671     xlist_root_init( XPTR( local_cxy, &thread->xlocks_root ) );
    672 
    673     // CP0 in I/O cluster initializes TXT0 chdev descriptor
    674     if( (core_lid == 0) && (core_cxy == info->io_cxy) ) txt0_device_init( info );
    675 
    676     /////////////////////////////////////////////////////////////////////////////////
    677     // global & local synchro to protect access to TXT0 terminal
    678     if( core_lid == 0 ) remote_barrier( XPTR( info->io_cxy , &global_barrier ),
     709    xlist_root_init( XPTR( local_cxy , &thread->xlocks_root ) );
     710
     711    // CP0 in I/O cluster initialises TXT0 chdev descriptor
     712    if( (core_lid == 0) && (core_cxy == io_cxy) ) txt0_device_init( info );
     713
     714    /////////////////////////////////////////////////////////////////////////////////
     715    if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
    679716                                        (info->x_size * info->y_size) );
    680717    barrier_wait( &local_barrier , info->cores_nr );
    681     /////////////////////////////////////////////////////////////////////////////////
    682 
    683     if( (core_lid ==  0) && (local_cxy == info->io_cxy) )
    684     {
    685         kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 0 at cycle %d\n",
    686                    __FUNCTION__ , core_cxy , core_lid , hal_get_cycles() );
    687     }
    688 
    689     // all cores check core identifiers
     718
     719    if( (core_lid ==  0) && (local_cxy == 0) )
     720    kinit_dmsg("\n[INFO] %s exit barrier 0 at cycle %d : TXT0 initialized\n",
     721               __FUNCTION__, (uint32_t)hal_time_stamp());
     722
     723    /////////////////////////////////////////////////////////////////////////////
     724    // STEP 1 : all cores check its core identifier.
     725    //          CP0 initializes the local cluster manager.
     726    //          This includes the memory allocators.
     727    /////////////////////////////////////////////////////////////////////////////
     728
     729    // all cores check identifiers
    690730    if( error )
    691731    {
     
    696736    }
    697737
    698     // CP0 initializes the local cluster manager (cores and memory allocators)
     738    // CP0 initializes cluster manager
    699739    if( core_lid == 0 )
    700740    {
     
    703743        if( error )
    704744        {
    705             nolock_printk("\n[PANIC] in %s : cannot initialise cluster manager in cluster %x",
     745            nolock_printk("\n[PANIC] in %s : cannot initialise cluster %x",
    706746                   __FUNCTION__ , local_cxy );
    707747            hal_core_sleep();
     
    710750
    711751    /////////////////////////////////////////////////////////////////////////////////
    712     // global & local synchro, to protect access to cluster manager
    713     if( core_lid == 0 ) remote_barrier( XPTR( info->io_cxy , &global_barrier ),
     752    if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
    714753                                        (info->x_size * info->y_size) );
    715754    barrier_wait( &local_barrier , info->cores_nr );
    716755    /////////////////////////////////////////////////////////////////////////////////
    717756
    718     if( (core_lid ==  0) && (local_cxy == info->io_cxy) )
    719     {
    720         kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 1 at cycle %d\n",
    721                    __FUNCTION__ , core_cxy , core_lid , hal_get_cycles() );
    722     }
    723 
    724     // all cores get pointer on local cluster manager and on core descriptor
     757    if( (core_lid ==  0) && (local_cxy == 0) )
     758    kinit_dmsg("\n[INFO] %s exit barrier 1 at cycle %d : clusters initialised\n",
     759               __FUNCTION__, (uint32_t)hal_time_stamp());
     760
     761    /////////////////////////////////////////////////////////////////////////////////
     762    // STEP 2 : all CP0s initialize the process_zero descriptor.
     763    //          CP0 in cluster 0 initialises the IOPIC device.
     764    //          all CP0s complete the distibuted LAPIC initialization.
     765    /////////////////////////////////////////////////////////////////////////////////
     766
     767    // all cores get pointer on local cluster manager & core descriptor
    725768    cluster = &cluster_manager;
    726769    core    = &cluster->core_tbl[core_lid];
    727770
    728     // CP0 initializes the process_zero descriptor
     771    // all CP0s initialize the process_zero descriptor
    729772    if( core_lid == 0 ) process_reference_init( &process_zero , 0 , XPTR_NULL );
    730773
    731 #ifdef __HAL_x86_64__
    732         return; /* XXX temporary */
    733 #endif
    734 
    735     // CP0 allocates and initializes the internal peripheral chdev descriptors.
    736     // Each CP0[cxy] scan the set of its internal (private) peripherals,
     774    // CP0 in cluster 0 initializes the PIC chdev,
     775    if( (core_lid == 0) && (local_cxy == 0) ) iopic_init( info );
     776   
     777    // all CP0s initialize their local LAPIC extension,
     778    if( core_lid == 0 ) lapic_init( info );
     779
     780    ////////////////////////////////////////////////////////////////////////////////
     781    if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
     782                                        (info->x_size * info->y_size) );
     783    barrier_wait( &local_barrier , info->cores_nr );
     784    ////////////////////////////////////////////////////////////////////////////////
     785
     786    if( (core_lid ==  0) && (local_cxy == 0) )
     787    kinit_dmsg("\n[INFO] %s exit barrier 2 at cycle %d : PIC initialised\n",
     788               __FUNCTION__, (uint32_t)hal_time_stamp());
     789
     790    ////////////////////////////////////////////////////////////////////////////////
     791    // STEP 3 : all CP0s initialize their local chdev descriptors
     792    //          (both internal devices and external devices).
     793    ////////////////////////////////////////////////////////////////////////////////
     794
     795    // CP0 scan the internal (private) peripherals,
    737796    // and allocates memory for the corresponding chdev descriptors.
    738797    if( core_lid == 0 ) internal_devices_init( info );
    739 
    740     // CP0 allocates one WTI mailbox per core for Inter Processor Interrupt
    741     // this must be done after ICU chdev initialisation, by CP0 only, and before
    742     // external devices initialisation to enforce the rule :
    743     // "The WTI index for the IPI routed to core[lid] is lid"
    744     if( core_lid == 1 )
    745     {
    746         uint32_t  wti_id;
    747         uint32_t  lid;
    748         for( lid = 0 ; lid < LOCAL_CLUSTER->cores_nr ; lid++ )
    749         {
    750             wti_id = dev_icu_wti_alloc();
    751 
    752             if( wti_id != lid )
    753             {
    754                 nolock_printk("\n[PANIC] in %s : WTI index for IPI = %d / core_lid = %d",
    755                               __FUNCTION__ , wti_id , lid );
    756                 hal_core_sleep();
    757             }
    758 
    759             dev_icu_enable_irq( lid , WTI_TYPE , wti_id , NULL );
    760         }
    761     }
     798       
    762799
    763800    // All CP0s contribute to initialise external peripheral chdev descriptors.
     
    765802    // and allocates memory for the chdev descriptors that must be placed
    766803    // on the (cxy) cluster according to the global index value.
     804
    767805    if( core_lid == 0 ) external_devices_init( info );
    768806
    769807    /////////////////////////////////////////////////////////////////////////////////
    770     // global &local synchro to protect access to peripherals
    771     if( core_lid == 0 ) remote_barrier( XPTR( info->io_cxy , &global_barrier ),
     808    if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
    772809                                        (info->x_size * info->y_size) );
    773810    barrier_wait( &local_barrier , info->cores_nr );
    774811    /////////////////////////////////////////////////////////////////////////////////
    775812
    776     if( (core_lid ==  0) && (local_cxy == info->io_cxy) )
    777     {
    778         kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 2 at cycle %d\n",
    779                    __FUNCTION__ , core_cxy , core_lid , hal_get_cycles() );
    780     }
    781 
     813    if( (core_lid ==  0) && (local_cxy == 0) )
     814    kinit_dmsg("\n[INFO] %s exit barrier 3 at cycle %d : all chdev initialised\n",
     815               __FUNCTION__, (uint32_t)hal_time_stamp());
     816
     817    /////////////////////////////////////////////////////////////////////////////////
     818    // STEP 4 : Alls cores initialize their private IDLE thread.
     819    //          Only CP0 in cluster 0 creates the VFS root inode.
     820    //          It access the boot device to initialize the file system context.
     821    /////////////////////////////////////////////////////////////////////////////////
     822
     823    // all cores create idle thread descriptor
    782824    error = thread_kernel_init( thread,
    783825                                THREAD_IDLE,
     
    792834    }
    793835
    794     // register idle thread in scheduler
     836    // all cores register idle thread in scheduler
    795837    core->scheduler.idle = thread;
    796838
    797     // activate the idle thread
     839    // all core activate the idle thread
    798840    thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL );
    799841
    800     if( (core_lid ==  0) && (local_cxy == info->io_cxy) )
    801     {
    802         kinit_dmsg("\n[INFO] %s : core[%x][%d] created idle thread %x at cycle %d\n",
    803                    __FUNCTION__ , core_cxy , core_lid , thread , hal_get_cycles());
    804     }
    805 
    806     // CP0 in all clusters initializes cooperatively VFS and DEVFS
    807     if( (core_lid == 0)  )
    808     {
    809         xptr_t  root_inode_xp;
    810 
    811         // initialize root File System (must be FATFS in this implementation)
     842    if( (core_lid ==  0) && (local_cxy == 0) )
     843    {
     844        kinit_dmsg("\n[INFO] %s : created idle thread %x at cycle %d\n",
     845                   __FUNCTION__ , thread , (uint32_t)hal_time_stamp());
     846    }
     847
     848    // CPO in cluster 0 creates the VFS root
     849    if( (core_lid ==  0) && (local_cxy == 0 ) )
     850    {
     851        vfs_root_inode_xp = XPTR_NULL;
     852
     853        // File System must be FATFS in this implementation,
     854        // but other File System can be introduced here
    812855        if( CONFIG_VFS_ROOT_IS_FATFS )
    813856        {
    814             root_inode_xp = fatfs_init();
     857            // 1. create FATFS context in cluster 0
     858            fatfs_ctx_t * fatfs_ctx = fatfs_ctx_alloc();
     859
     860            nolock_assert( (fatfs_ctx != NULL) , __FUNCTION__ ,
     861                           "cannot create FATFS context in cluster 0\n" );
     862
     863            // 2. access boot device to initialize FATFS context
     864            fatfs_ctx_init( fatfs_ctx );
     865 
     866            // 3. get various informations from FATFS context
     867            uint32_t root_dir_cluster = fatfs_ctx->root_dir_cluster;
     868            uint32_t cluster_size     = fatfs_ctx->bytes_per_sector *
     869                                        fatfs_ctx->sectors_per_cluster;
     870            uint32_t total_clusters   = fatfs_ctx->fat_sectors_count << 7;
     871 
     872            // 4. create VFS root inode in cluster 0
     873            error = vfs_inode_create( XPTR_NULL,                           // dentry_xp
     874                                      FS_TYPE_FATFS,                       // fs_type
     875                                      INODE_TYPE_DIR,                      // inode_type
     876                                      (void *)(intptr_t)root_dir_cluster,  // extend
     877                                      0,                                   // attr
     878                                      0,                                   // rights
     879                                      0,                                   // uid
     880                                      0,                                   // gid
     881                                      &vfs_root_inode_xp );                // return
     882
     883            nolock_assert( (error == 0) , __FUNCTION__ ,
     884                           "cannot create VFS root inode\n" );
     885
     886            // 5. initialize VFS context for FAT in cluster 0
     887            vfs_ctx_init( FS_TYPE_FATFS,                 // file system type
     888                          0,                             // attributes
     889                              total_clusters,               
     890                              cluster_size,
     891                              vfs_root_inode_xp,             // VFS root
     892                          fatfs_ctx );                   // extend
    815893        }
    816894        else
     
    820898        }
    821899
    822         if( root_inode_xp == XPTR_NULL )
    823         {
    824             nolock_printk("\n[PANIC] in %s : core[%x][%d] cannot initialize file system\n",
    825                    __FUNCTION__ , local_cxy , core_lid );
    826             hal_core_sleep();
    827         }
    828 
    829900        // register VFS root inode in process_zero
    830         process_zero.vfs_root_xp = root_inode_xp;
    831         process_zero.vfs_cwd_xp  = root_inode_xp;
    832 
    833         // mount the DEVFS File system
    834         devfs_mount( root_inode_xp , "dev" );
    835     }
    836 
    837 
    838     // CP0 in I/O cluster creates the process_init and print banner
    839     if( (core_lid ==  0) && (local_cxy == info->io_cxy) )
     901        process_zero.vfs_root_xp = vfs_root_inode_xp;
     902        process_zero.vfs_cwd_xp  = vfs_root_inode_xp;
     903    }
     904
     905    /////////////////////////////////////////////////////////////////////////////////
     906    if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
     907                                        (info->x_size * info->y_size) );
     908    barrier_wait( &local_barrier , info->cores_nr );
     909    /////////////////////////////////////////////////////////////////////////////////
     910
     911    if( (core_lid ==  0) && (local_cxy == 0) )
     912    kinit_dmsg("\n[INFO] %s exit barrier 4 at cycle %d : VFS OK in cluster 0\n",
     913               __FUNCTION__, (uint32_t)hal_time_stamp());
     914
     915    /////////////////////////////////////////////////////////////////////////////////
     916    // STEP 5 : Other CP0s allocate memory for the selected FS context,
     917    //          and initialise both the local FS context and the local VFS context
     918    //          from values stored in cluster 0.
     919    //          They get the VFS root inode extended pointer from cluster 0.
     920    /////////////////////////////////////////////////////////////////////////////////
     921
     922    if( (core_lid ==  0) && (local_cxy != 0) )
     923    {
     924        // File System must be FATFS in this implementation,
     925        // but other File System can be introduced here
     926        if( CONFIG_VFS_ROOT_IS_FATFS )
     927        {
     928            // allocate memory for FATFS context
     929            fatfs_ctx_t * fatfs_ctx = fatfs_ctx_alloc();
     930
     931            nolock_assert( (fatfs_ctx != NULL) , __FUNCTION__ ,
     932                           "cannot create FATFS context\n" );
     933
     934            // get local pointer on VFS context for FATFS
     935            vfs_ctx_t   * vfs_ctx = &fs_context[FS_TYPE_FATFS];
     936
     937            // copy VFS context from cluster 0 to local cluster
     938            hal_remote_memcpy( XPTR( local_cxy , vfs_ctx ),
     939                               XPTR( 0 , vfs_ctx ),
     940                               sizeof(vfs_ctx_t) );
     941
     942            // copy FATFS context from cluster 0 to local cluster
     943            hal_remote_memcpy( XPTR( local_cxy , fatfs_ctx ),
     944                               XPTR( 0 , fatfs_ctx ),
     945                               sizeof(fatfs_ctx_t) );
     946
     947            // update extend field in local copy of VFS context
     948            vfs_ctx->extend = fatfs_ctx;
     949        }
     950
     951        // get extended pointer on VFS root inode from cluster 0
     952        vfs_root_inode_xp = hal_remote_lwd( XPTR( 0 , process_zero.vfs_root_xp ) );
     953
     954        // update local process_zero descriptor
     955        process_zero.vfs_root_xp = vfs_root_inode_xp;
     956        process_zero.vfs_cwd_xp  = vfs_root_inode_xp;
     957    }
     958
     959    /////////////////////////////////////////////////////////////////////////////////
     960    // global &local synchro to protect File System initialisation
     961    if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
     962                                        (info->x_size * info->y_size) );
     963    barrier_wait( &local_barrier , info->cores_nr );
     964
     965    if( (core_lid ==  0) && (local_cxy == 0) )
     966    kinit_dmsg("\n[INFO] %s exit barrier 5 at cycle %d : VFS OK in all clusters\n",
     967               __FUNCTION__, (uint32_t)hal_time_stamp());
     968
     969
     970    /////////////////////////////////////////////////////////////////////////////////
     971    // STEP 6 : CP0 in cluster IO makes the global DEVFS tree initialisation:
     972    //          It creates the DEVFS root directory and the DEVFS "external"
     973    //          diretory in cluster IO and mount these inodes into VFS.
     974    /////////////////////////////////////////////////////////////////////////////////
     975
     976    if( (core_lid ==  0) && (local_cxy == io_cxy) )
     977    {
     978        xptr_t  devfs_root_inode_xp;       // extended pointer on DEVFS root directory
     979        xptr_t  devfs_external_inode_xp;   // extended pointer on DEVFS external directory   
     980
     981        // create "dev" and "external" directories.
     982        devfs_global_init( process_zero.vfs_root_xp,
     983                           &devfs_root_inode_xp,
     984                           &devfs_external_inode_xp );
     985
     986        // creates the DEVFS context in cluster IO
     987        devfs_ctx_t * devfs_ctx = devfs_ctx_alloc();
     988
     989        nolock_assert( (devfs_ctx != NULL) , __FUNCTION__ ,
     990                       "cannot create DEVFS context in cluster IO\n");
     991
     992        // register DEVFS root and external directories
     993        devfs_ctx_init( devfs_ctx, devfs_root_inode_xp, devfs_external_inode_xp );
     994    }   
     995
     996    /////////////////////////////////////////////////////////////////////////////////
     997    // global &local synchro to protect File System initialisation
     998    if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
     999                                        (info->x_size * info->y_size) );
     1000    barrier_wait( &local_barrier , info->cores_nr );
     1001
     1002    if( (core_lid ==  0) && (local_cxy == 0) )
     1003    kinit_dmsg("\n[INFO] %s exit barrier 6 at cycle %d : DEVFS OK in cluster IO\n",
     1004               __FUNCTION__, (uint32_t)hal_time_stamp());
     1005
     1006    /////////////////////////////////////////////////////////////////////////////////
     1007    // STEP 7 : All CP0s complete in parallel the DEVFS tree initialization.
     1008    //          Each CP0 get the "dev" and "external" extended pointers from
     1009    //          values storred in cluster IO. Then CP0 in cluster(i) creates the
     1010    //          DEVFS "internal directory, and creates the pseudo-files for all
     1011    //          chdevs contained in cluster (i).
     1012    /////////////////////////////////////////////////////////////////////////////////
     1013
     1014    if( core_lid == 0 )
     1015    {
     1016        xptr_t  root_inode_xp;       // extended pointer on DEVFS root directory
     1017        xptr_t  external_inode_xp;   // extended pointer on DEVFS external directory   
     1018
     1019        // get extended pointer on "extend" field of VFS context for DEVFS in cluster IO
     1020        xptr_t  extend_xp = XPTR( io_cxy , &fs_context[FS_TYPE_DEVFS].extend );
     1021
     1022        // get pointer on DEVFS context in cluster IO
     1023        devfs_ctx_t * devfs_ctx = hal_remote_lpt( extend_xp );
     1024       
     1025        root_inode_xp     = hal_remote_lwd( XPTR( io_cxy , &devfs_ctx->root_inode_xp ) );
     1026        external_inode_xp = hal_remote_lwd( XPTR( io_cxy , &devfs_ctx->external_inode_xp ) );
     1027
     1028        devfs_local_init( root_inode_xp,
     1029                          external_inode_xp );
     1030    }
     1031
     1032    /////////////////////////////////////////////////////////////////////////////////
     1033    // global &local synchro to protect File System initialisation
     1034    if( core_lid == 0 ) remote_barrier( XPTR( io_cxy , &global_barrier ),
     1035                                        (info->x_size * info->y_size) );
     1036    barrier_wait( &local_barrier , info->cores_nr );
     1037
     1038    if( (core_lid ==  0) && (local_cxy == 0) )
     1039    kinit_dmsg("\n[INFO] %s exit barrier 7 at cycle %d : DEVFS OK in all clusters\n",
     1040               __FUNCTION__, (uint32_t)hal_time_stamp());
     1041
     1042    /////////////////////////////////////////////////////////////////////////////////
     1043    // STEP 8 : CP0 in I/O cluster creates the process_init and print banner.
     1044    /////////////////////////////////////////////////////////////////////////////////
     1045
     1046    if( (core_lid ==  0) && (local_cxy == io_cxy) )
    8401047    {
    8411048        process_init_create();
    842 
     1049    }
     1050
     1051    /////////////////////////////////////////////////////////////////////////////////
     1052    // global syncho to protect access to File System
     1053    if( core_lid == 0 ) remote_barrier( XPTR( info->io_cxy , &global_barrier ),
     1054                                        (info->x_size * info->y_size) );
     1055    barrier_wait( &local_barrier , info->cores_nr );
     1056
     1057    if( (core_lid ==  0) && (local_cxy == 0) )
     1058    kinit_dmsg("\n[INFO] %s exit barrier 8 at cycle %d : process init created\n",
     1059               __FUNCTION__ , (uint32_t)hal_time_stamp() );
     1060
     1061    /////////////////////////////////////////////////////////////////////////////////
     1062    // STEP 9 : CP0 in cluster 0 print banner
     1063    /////////////////////////////////////////////////////////////////////////////////
     1064   
     1065    if( (core_lid ==  0) && (local_cxy == io_cxy) )
     1066    {
    8431067        print_banner( (info->x_size * info->y_size) , info->cores_nr );
    8441068
     
    8861110    }
    8871111
    888     /////////////////////////////////////////////////////////////////////////////////
    889     // global syncho to protect access to File System
    890     if( core_lid == 0 ) remote_barrier( XPTR( info->io_cxy , &global_barrier ),
    891                                         (info->x_size * info->y_size) );
    892     barrier_wait( &local_barrier , info->cores_nr );
    893     /////////////////////////////////////////////////////////////////////////////////
    894 
    895     if( (core_lid ==  0) && (local_cxy == info->io_cxy) )
    896     {
    897         kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 3 at cycle %d\n",
    898                    __FUNCTION__ , core_cxy , core_lid , hal_get_cycles() );
    899     }
    900 
    9011112    // each core activates its private PTI IRQ
    902     dev_icu_set_period( core_lid , CONFIG_SCHED_TICK_PERIOD );
    903     dev_icu_enable_irq( core_lid , PTI_TYPE , core_lid , NULL );
    904 
    905     // each core get its private IRQ masks values
    906     uint32_t hwi_mask;
    907     uint32_t wti_mask;
    908     uint32_t pti_mask;
    909     dev_icu_get_masks( core_lid , &hwi_mask , &wti_mask , &pti_mask );
    910 
    911     thread_dmsg("\n[INFO] %s : core[%x][%d] complete kernel init at cycle %d\n"
    912                 "   hwi_mask = %x / wti_mask = %x / pti_mask = %x\n",
    913                     __FUNCTION__ , local_cxy , core_lid , hal_get_cycles() ,
    914                     hwi_mask , wti_mask , pti_mask );
     1113    dev_pic_enable_timer( CONFIG_SCHED_TICK_PERIOD );
     1114
     1115    if( (core_lid ==  0) && (local_cxy == io_cxy) )
     1116    thread_dmsg("\n[INFO] %s complete kernel init in cluster 0 at cycle %d\n"
     1117                __FUNCTION__ , (uint32_t)hal_time_stamp() )
    9151118
    9161119    // each core jump to idle thread
  • trunk/kernel/kern/printk.c

    r103 r188  
    3535///////////////////////////////////////////////////////////////////////////////////
    3636
    37 extern chdev_t            txt0_chdev;        // allocated in kernel_init.c
     37extern chdev_directory_t  chdev_dir;  // defined in chdev.h / allocated in kernel_init.c
    3838
    3939/////////////////////////////////////
     
    369369    uint32_t      save_sr;
    370370
     371    // get pointers on TXT0 chdev
     372    xptr_t    txt0_xp  = chdev_dir.txt[0];
     373    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
     374    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
     375
    371376    // get extended pointer on remote TXT0 chdev lock
    372     xptr_t  txt0_lock_xp = XPTR( LOCAL_CLUSTER->io_cxy , &txt0_chdev.wait_lock );
     377    xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
    373378
    374379    // get TXT0 lock in busy waiting mode
    375     remote_spinlock_lock_busy( txt0_lock_xp , &save_sr );
     380    remote_spinlock_lock_busy( lock_xp , &save_sr );
    376381
    377382    // call kernel_printf on TXT0, in busy waiting mode
     
    381386
    382387    // release lock
    383     remote_spinlock_unlock_busy( txt0_lock_xp , save_sr );
     388    remote_spinlock_unlock_busy( lock_xp , save_sr );
    384389}
    385390
     
    406411    }
    407412}
     413
     414//////////////////////////////////////////////////
     415inline void nolock_assert( bool_t       condition,
     416                           const char * function_name,
     417                           char       * string )
     418{
     419    if( condition == false )
     420    {
     421        nolock_printk("\n[PANIC] in %s : %s\n" , function_name , string );
     422        hal_core_sleep();
     423    }
     424}
     425
    408426
    409427
  • trunk/kernel/kern/printk.h

    r103 r188  
    8383
    8484/**********************************************************************************
    85  * This function displaya "PANIC" message and force the calling core in
     85 * This function displays a "PANIC" message and force the calling core in
    8686 * sleeping mode if a Boolean condition is false.
    8787 * These functions are actually used to debug the kernel...
     
    9595                    char       * string );
    9696
     97/**********************************************************************************
     98 * This function displays a "PANIC" message and force the calling core in
     99 * sleeping mode if a Boolean condition is false,
     100 * without taking the the lock protecting exclusive access to TXT0 terminal.
     101 **********************************************************************************
     102 * @ condition     : condition that must be true.
     103 * @ function_name : name of the calling function.
     104 * @ string        : error message if condition is false.
     105 *********************************************************************************/
     106inline void nolock_assert( bool_t       condition,
     107                           const char * function_name,
     108                           char       * string );
     109
    97110///////////////////////////////////////////////////////////////////////////////////
    98111//       Conditionnal debug macros
     
    171184#endif
    172185
    173 #if CONFIG_ICU_DEBUG
    174 #define icu_dmsg(...)   printk(__VA_ARGS__)
    175 #else
    176 #define icu_dmsg(...)
    177 #endif
    178 
    179186#if CONFIG_IDLE_DEBUG
    180187#define idle_dmsg(...) printk(__VA_ARGS__)
     
    187194#else
    188195#define ioc_dmsg(...)
     196#endif
     197
     198#if CONFIG_IRQ_DEBUG
     199#define irq_dmsg(...)   printk(__VA_ARGS__)
     200#else
     201#define irq_dmsg(...)
    189202#endif
    190203
  • trunk/kernel/kern/process.c

    r186 r188  
    9999        assert( (pid == 0) , __FUNCTION__ , "process_zero must have PID = 0\n");
    100100
    101         parent_pid = 0;  // process_zero is its own parent...
     101        parent_cxy = 0;
     102        parent_ptr = NULL;
     103        parent_pid = 0;      // process_zero is its own parent...
    102104    }
    103105    else
  • trunk/kernel/kern/rpc.c

    r101 r188  
    537537                                  uint32_t       fs_type,    // in
    538538                                  uint32_t       inode_type, // in
     539                                  void         * extend,     // in
    539540                                  uint32_t       attr,       // in
    540541                                  uint32_t       rights,     // in
     
    560561    rpc.args[1] = (uint64_t)fs_type;
    561562    rpc.args[2] = (uint64_t)inode_type;
    562     rpc.args[3] = (uint64_t)attr;
    563     rpc.args[4] = (uint64_t)rights;
    564     rpc.args[5] = (uint64_t)uid;
    565     rpc.args[6] = (uint64_t)gid;
     563    rpc.args[3] = (uint64_t)(intptr_t)extend;
     564    rpc.args[4] = (uint64_t)attr;
     565    rpc.args[5] = (uint64_t)rights;
     566    rpc.args[6] = (uint64_t)uid;
     567    rpc.args[7] = (uint64_t)gid;
    566568
    567569    // register RPC request in remote RPC fifo (blocking function)
     
    569571
    570572    // get output values from RPC descriptor
    571     *inode_xp = (xptr_t)rpc.args[7];
    572     *error    = (error_t)rpc.args[8];
     573    *inode_xp = (xptr_t)rpc.args[8];
     574    *error    = (error_t)rpc.args[9];
    573575}
    574576
     
    579581    uint32_t         fs_type;
    580582    uint32_t         inode_type;
     583    void           * extend;
    581584    uint32_t         attr;
    582585    uint32_t         rights;
     
    591594
    592595    // get input arguments from client rpc descriptor
    593     dentry_xp  = (xptr_t)  hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
    594     fs_type    = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
    595     inode_type = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
    596     attr       = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) );
    597     rights     = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) );
    598     uid        = (uid_t)   hal_remote_lwd( XPTR( client_cxy , &desc->args[5] ) );
    599     gid        = (gid_t)   hal_remote_lwd( XPTR( client_cxy , &desc->args[6] ) );
     596    dentry_xp  = (xptr_t)          hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     597    fs_type    = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
     598    inode_type = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
     599    extend     = (void *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) );
     600    attr       = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) );
     601    rights     = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[5] ) );
     602    uid        = (uid_t)           hal_remote_lwd( XPTR( client_cxy , &desc->args[6] ) );
     603    gid        = (gid_t)           hal_remote_lwd( XPTR( client_cxy , &desc->args[7] ) );
    600604
    601605    // call local kernel function
     
    603607                              fs_type,
    604608                              inode_type,
     609                              extend,
    605610                              attr,
    606611                              rights,
     
    610615
    611616    // set output arguments
    612     hal_remote_swd( XPTR( client_cxy , &desc->args[7] ) , (uint64_t)inode_xp );
    613     hal_remote_swd( XPTR( client_cxy , &desc->args[8] ) , (uint64_t)error );
     617    hal_remote_swd( XPTR( client_cxy , &desc->args[8] ) , (uint64_t)inode_xp );
     618    hal_remote_swd( XPTR( client_cxy , &desc->args[9] ) , (uint64_t)error );
    614619}
    615620
     
    12901295                if( cores == 0 ) // no core in kernel mode in server
    12911296                {
    1292                     dev_icu_send_ipi( server_cxy , client_lid );
     1297                    dev_pic_send_ipi( server_cxy , client_lid );
    12931298
    12941299                    rpc_dmsg("\n[INFO] %s : core %d in cluster %x send IPI to core %d in cluster %x\n",
     
    14541459
    14551460        // update core descriptor counter 
    1456             core->rpc_threads++;
     1461            hal_atomic_add( &core->rpc_threads , 1 );
    14571462    }
    14581463
     
    15491554
    15501555            // update core descriptor counter
    1551                         this->core->rpc_threads--;
     1556                hal_atomic_add( &this->core->rpc_threads , -1 );
    15521557
    15531558            // suicide
  • trunk/kernel/kern/rpc.h

    r23 r188  
    325325 * @ fs_type    : [in]  file system type.
    326326 * @ inode_type : [in]  file system type.
     327 * @ extend     : [in]  fs_type_specific inode extension.
    327328 * @ attr       : [in]  inode attributes.
    328329 * @ rights     : [in]  access rights
     
    336337                                  uint32_t   fs_type,
    337338                                  uint32_t   inode_type,
     339                                  void     * extend,
    338340                                  uint32_t   attr,   
    339341                                  uint32_t   rights, 
  • trunk/kernel/kern/thread.c

    r185 r188  
    3434#include <process.h>
    3535#include <scheduler.h>
    36 #include <dev_icu.h>
     36#include <dev_pic.h>
    3737#include <core.h>
    3838#include <list.h>
     
    718718    thread_block( target , THREAD_BLOCKED_GLOBAL );
    719719
    720     // send an IPI to reschedule the target thread core.
    721     dev_icu_send_ipi( local_cxy , target->core->lid );
     720    // send an IPI to schedule the target thread core.
     721    dev_pic_send_ipi( local_cxy , target->core->lid );
    722722}
    723723
     
    739739        idle_dmsg("\n[INFO] %s : core[%x][%d] wake up at cycle %d\n",
    740740                    __FUNCTION__ , local_cxy , lid , hal_get_cycles() );
    741 
    742                 // acknowledge IRQ
    743         dev_icu_irq_handler();
    744741
    745742        // force scheduling
Note: See TracChangeset for help on using the changeset viewer.