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

Redefine the PIC device API.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.