Ignore:
Timestamp:
May 3, 2017, 1:23:24 PM (7 years ago)
Author:
alain
Message:

Bugs fix.

File:
1 edited

Legend:

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

    r5 r14  
    33 *
    44 * Authors :  Alain Greiner  (2016)
     5 *            Mohamed Lamine Karaoui (2016)
    56 *
    67 * Copyright (c) Sorbonne Universites
     
    2223 */
    2324
    24 #include <almos_config.h>
     25#include <kernel_config.h>
    2526#include <errno.h>
    2627#include <hal_types.h>
    2728#include <hal_special.h>
    2829#include <hal_context.h>
     30#include <barrier.h>
    2931#include <remote_barrier.h>
    3032#include <core.h>
     
    3436#include <kmem.h>
    3537#include <cluster.h>
    36 #include <devfs.h>
    37 #include <sysfs.h>
    3838#include <string.h>
    3939#include <memcpy.h>
     
    5454#include <soclib_tty.h>
    5555
     56// TODO #include <devfs.h>
     57// TODO #include <sysfs.h>
    5658
    5759#define KERNEL_INIT_SYNCHRO  0xA5A5B5B5
     
    6062// All these global variables are replicated in all clusters.
    6163// They are initialised by the kernel_init() function.
     64//
     65// WARNING : The section names have been defined to control the base addresses of the
     66// boot_info structure and the idle thread descriptors, through the kernel.ld script:
     67// - the boot_info structure is build by the bootloader, and used by kernel_init.
     68//   it must be first object in the kdata segment.
     69// - the array of idle threads descriptors must be placed on the first page boundary after
     70//   the boot_info structure in the kdata segment.
    6271///////////////////////////////////////////////////////////////////////////////////////////
    6372
    6473// This variable defines the local boot_info structure
    6574__attribute__((section(".kinfo")))
    66 boot_info_t          boot_info          CACHELINE_ALIGNED;
     75boot_info_t          boot_info;
     76
     77// This variable defines the "idle" threads descriptors array
     78__attribute__((section(".kidle")))
     79char                  idle_threads[CONFIG_THREAD_DESC_SIZE *
     80                                   CONFIG_MAX_LOCAL_CORES]   CONFIG_PPM_PAGE_ALIGNED;
    6781
    6882// This variable defines the local cluster manager
    6983__attribute__((section(".kdata")))
    70 cluster_t            cluster_manager    CACHELINE_ALIGNED;
    71 
    72 // These variables define the kernel process0 descriptor and associated thread
     84cluster_t            cluster_manager                         CONFIG_CACHE_LINE_ALIGNED;
     85
     86// This variables define the kernel process0 descriptor
    7387__attribute__((section(".kdata")))
    74 process_t            process_zero       CACHELINE_ALIGNED;           
    75 thread_t             thread_zero        CACHELINE_ALIGNED;
    76 
    77 // This variable contains the extended pointers on the device descriptors
     88process_t            process_zero                            CONFIG_CACHE_LINE_ALIGNED;           
     89
     90// This variable defines extended pointers on the distributed chdevs
    7891__attribute__((section(".kdata")))
    79 chdev_directory_t    chdev_dir          CACHELINE_ALIGNED;
     92chdev_directory_t    chdev_dir                               CONFIG_CACHE_LINE_ALIGNED;
    8093
    8194// This variable contains the input IRQ indexes for the PIC device
    8295__attribute__((section(".kdata")))
    83 chdev_pic_input_t    chdev_pic_input    CACHELINE_ALIGNED;
     96chdev_pic_input_t    chdev_pic_input                         CONFIG_CACHE_LINE_ALIGNED;
    8497
    8598// This variable contains the input IRQ indexes for the ICU device
    8699__attribute__((section(".kdata")))
    87 chdev_icu_input_t    chdev_icu_input    CACHELINE_ALIGNED;
    88 
    89 // This variable synchronizes the local cores during kernel_init()
    90 __attribute__((section(".kdata")))
    91 volatile uint32_t    local_sync_init    CACHELINE_ALIGNED; 
     100chdev_icu_input_t    chdev_icu_input                         CONFIG_CACHE_LINE_ALIGNED;
    92101
    93102// This variable defines the local cluster identifier
    94103__attribute__((section(".kdata")))
    95 cxy_t                local_cxy          CACHELINE_ALIGNED;
    96 
    97 // This variable is the lock protecting the kernel TXT terminal (used by printk)
     104cxy_t                local_cxy                               CONFIG_CACHE_LINE_ALIGNED;
     105
     106// This variable defines the TXT0 chdev descriptor
    98107__attribute__((section(".kdata")))
    99 remote_spinlock_t    txt0_lock          CACHELINE_ALIGNED;
     108chdev_t              txt0_chdev                              CONFIG_CACHE_LINE_ALIGNED;
     109
     110// This variable is used for CP0 cores sychronisation in kernel_init()
     111__attribute__((section(".kdata")))
     112remote_barrier_t     global_barrier                          CONFIG_CACHE_LINE_ALIGNED;
     113
     114// This variable is used for local cores sychronisation in kernel_init()
     115__attribute__((section(".kdata")))
     116barrier_t            local_barrier                           CONFIG_CACHE_LINE_ALIGNED;
    100117
    101118///////////////////////////////////////////////////////////////////////////////////////////
     
    119136
    120137///////////////////////////////////////////////////////////////////////////////////////////
    121 // This static function allocates memory and initializes the TXT0 chdev descriptor,
    122 // associated to the kernel terminal, shared by all kernel instances for debug messages.
    123 // It should be called by a thread running in the I/O cluster, because the TXT0 chdev
    124 // is created in the I/O cluster.
     138// This static function initializes the TXT0 chdev descriptor, associated to the "kernel
     139// terminal", and shared by all kernel instances for debug messages. It also register it
     140// in the chdev directory, containing extended pointers on all chdevs.
     141// The global variable txt0_chdev is replicated in all clusters, but only the chdev
     142// allocated in I/O cluster is used by ALMOS-MKH.
     143// Therefore, this function must be called by a thread running in the I/O cluster.
     144// As this TXT0 chdev supports only the TXT_SYNC_WRITE command,  we don't create
     145// a server thread,  we don't allocate a WTI, and we don't initialize the waiting queue.
    125146///////////////////////////////////////////////////////////////////////////////////////////
    126147// @ info    : pointer on the local boot-info structure.
     
    131152        uint32_t        dev_nr;          // actual number of devices in this cluster
    132153        xptr_t          base;            // remote pointer on segment base
    133         uint32_t        size;            // channel size (bytes)
    134154    uint32_t        type;            // peripheral type
    135155    uint32_t        func;            // device functionnal index
     
    138158        uint32_t        x;               // X cluster coordinate
    139159        uint32_t        y;               // Y cluster coordinate
    140         chdev_t       * chdev;           // local pointer on created chdev
    141160
    142161    // get number of peripherals and base of devices array from boot_info
     
    144163    dev_tbl     = info->ext_dev;
    145164
    146     // loop on external peripherals to find TXT
     165    // loop on external peripherals to find TXT device
    147166        for( i = 0 ; i < dev_nr ; i++ )
    148167        {
    149         size        = dev_tbl[i].size;
    150168        base        = dev_tbl[i].base;
    151169        type        = dev_tbl[i].type;
     
    155173        if (func == DEV_FUNC_TXT )
    156174        {
    157             // allocate and initialize a local chdev for TXT0
    158             chdev = chdev_create( func,
    159                                   impl,
    160                                   0,        // channel
    161                                   0,        // direction
    162                                   base );
     175            // initialize basic fields
     176            txt0_chdev.func     = func;
     177            txt0_chdev.impl     = impl;
     178            txt0_chdev.channel  = 0;
     179            txt0_chdev.is_rx    = 0;
     180            txt0_chdev.base     = base;
     181
     182            // initialize lock
     183            remote_spinlock_init( XPTR( local_cxy , &txt0_chdev.wait_lock ) );
    163184
    164185            // Complete TXT specific initialisation
    165186            if( impl == IMPL_TXT_TTY )
    166187            {
    167                 chdev->cmd = &soclib_tty_cmd;
    168                 chdev->isr = &soclib_tty_isr;
    169                 soclib_tty_init( chdev );
     188                txt0_chdev.cmd = &soclib_tty_cmd;
     189                txt0_chdev.isr = &soclib_tty_isr;
     190                soclib_tty_init( &txt0_chdev );
    170191            }
    171192
     
    176197                {
    177198                    cxy_t  cxy = (x<<info->y_width) + y;
    178                     hal_remote_swd( XPTR( cxy , &chdev_dir.txt[0] ) , XPTR( local_cxy , chdev ) );
     199                    hal_remote_swd( XPTR( cxy , &chdev_dir.txt[0] ) ,
     200                                    XPTR( local_cxy , &txt0_chdev ) );
    179201                }
    180202            }
    181203
    182                     kinit_dmsg("\n[INFO] %s : core[%x][0] created TXT0 chdev / paddr = %l at cycle %d\n",
    183                        __FUNCTION__ , local_cxy , chdev_func_str( func ), chdev_xp , hal_time_stamp() );
     204                    kinit_dmsg("\n[INFO] %s : core[%x][0] created TXT0 chdev"
     205                       " / paddr = %l at cycle %d\n",
     206                       __FUNCTION__ , local_cxy , chdev_func_str( func ),
     207                       XPTR(local_cxy , &txt0_chdev) , hal_time_stamp() );
    184208        }
    185209
     
    200224static void internal_devices_init( boot_info_t * info )
    201225{
    202     boot_device_t * dev_tbl;         // pointer on array of devices in boot_info
    203         uint32_t        dev_nr;          // actual number of devices in this cluster
    204         xptr_t          base;            // remote pointer on segment base
    205         uint32_t        size;            // channel size (bytes)
    206     uint32_t        type;            // peripheral type
    207     uint32_t        func;            // device functionnal index
    208     uint32_t        impl;            // device implementation index
    209         uint32_t        i;               // device index in dev_tbl
     226    boot_device_t * dev;             // pointer on boot_info device (ICU/MMC/DMA)
    210227        uint32_t        x;               // X cluster coordinate
    211228        uint32_t        y;               // Y cluster coordinate
    212         uint32_t        channels_nr;     // number of channels in device
    213         uint32_t        channel;         // channel index
    214         uint32_t        p0;              // device parameter 0
    215         uint32_t        p1;              // device parameter 1
    216         uint32_t        p2;              // device parameter 2
    217         uint32_t        p3;              // device parameter 3
    218 
    219         chdev_t       * chdev;           // local pointer on one channel_device descriptor
    220     xptr_t          chdev_xp;        // extended pointer on channel_device descriptor
    221 
    222     // get number of internal devices and base of devices array from boot_info
    223         dev_nr      = info->int_dev_nr;
    224     dev_tbl     = info->int_dev;
    225 
    226     // loop on all internal devices in cluster
    227         for( i = 0 ; i < dev_nr ; i++ )
    228         {
    229         size        = dev_tbl[i].size;
    230         base        = dev_tbl[i].base;
    231         type        = dev_tbl[i].type;
    232         channels_nr = dev_tbl[i].channels;
    233         p0          = dev_tbl[i].param0;
    234         p1          = dev_tbl[i].param1;
    235         p2          = dev_tbl[i].param2;
    236         p3          = dev_tbl[i].param3;
    237 
    238         func     = FUNC_FROM_TYPE( type );
    239         impl     = IMPL_FROM_TYPE( type );
    240 
    241         // do nothing for RAM, that does not require a chdev descriptor.
    242         if( func == DEV_FUNC_RAM ) continue;
    243 
    244         // check internal device functional type
    245         if( (func != DEV_FUNC_MMC) &&
    246             (func != DEV_FUNC_ICU) &&
    247             (func != DEV_FUNC_DMA) )
    248         {
    249             assert( false , __FUNCTION__ , "illegal internal peripheral type" );
    250         }
    251 
    252         // loop on channels
    253         for( channel = 0 ; channel < channels_nr ; channel++ )
    254         {
    255             // create one chdev in local cluster
    256             chdev = chdev_create( func ,
    257                                   impl,
    258                                   channel,     
    259                                   false,           // TX
    260                                   base );
    261 
    262             assert( (chdev != NULL) , __FUNCTION__ , "cannot allocate internal chdev" );
     229        chdev_t       * chdev_ptr;       // local pointer on chdev descriptor
     230    xptr_t          chdev_xp;        // extended pointer on chdev descriptor
     231
     232    ///////////  ICU   //////////
     233
     234    dev = &info->dev_icu;
     235
     236    assert( ((info->cores_nr == 0) || (dev->channels != 0)) , __FUNCTION__ ,
     237            "ICU device must exist in cluster containing cores" );
     238       
     239    assert( (dev->channels == 1) , __FUNCTION__ ,
     240            "channels number must be 1 for ICU device" );
     241
     242    assert( (FUNC_FROM_TYPE( dev->type ) == DEV_FUNC_ICU ) , __FUNCTION__ ,
     243            " inconsistent ICU  device type");
     244
     245    // create one chdev in local cluster
     246    chdev_ptr = chdev_create( FUNC_FROM_TYPE( dev->type ),
     247                              IMPL_FROM_TYPE( dev->type ),
     248                              0,                              // channel
     249                              false,                          // TX
     250                              dev->base );
     251
     252    assert( (chdev_ptr != NULL) , __FUNCTION__ , "cannot allocate ICU chdev" );
     253           
     254    // get extended pointer on chdev descriptor
     255    chdev_xp = XPTR( local_cxy , chdev_ptr );
     256
     257    // make ICU specific initialisation
     258    // TODO remove these three parameters
     259    dev_icu_init( chdev_ptr , dev->param0 , dev->param1 , dev->param2 );     
     260
     261    // initialize the ICU field in the chdev_dir[x][y] structures
     262    // replicated in all clusters, and containing extended pointers
     263    // on all remotely accessible devices
     264    for( x = 0 ; x < info->x_size ; x++ )
     265    {
     266        for( y = 0 ; y < info->y_size ; y++ )
     267        {
     268            cxy_t  cxy = (x<<info->y_width) + y;
     269            hal_remote_swd( XPTR( cxy , &chdev_dir.icu[local_cxy] ) , chdev_xp );
     270        }
     271    }
     272
     273    // initialize the entries of the local chdev_icu_input structure
     274    // defining how internal peripherals are connected to ICU
     275    uint32_t   id;
     276    uint8_t    valid;
     277    uint32_t   src_type;
     278    uint8_t    src_ch;
     279    uint32_t   src_func;
     280    for( id = 0 ; id < CONFIG_MAX_HWIS_PER_ICU ; id++ )
     281    {
     282        valid    = dev->irq[id].valid;
     283        src_type = dev->irq[id].dev_type;
     284        src_ch   = dev->irq[id].channel;
     285        src_func = FUNC_FROM_TYPE( src_type );
     286
     287        if( valid ) // only valid local IRQs are registered
     288        {
     289            if     ( src_func == DEV_FUNC_MMC ) chdev_icu_input.mmc = id;
     290            else if( src_func == DEV_FUNC_DMA ) chdev_icu_input.dma[src_ch] = id;
     291            else assert( false , __FUNCTION__ , "illegal source device for ICU input" );
     292        }
     293    }
     294
     295    kinit_dmsg("\n[INFO] %s : core[%x][0] creates ICU chdev at cycle %d\n",
     296               __FUNCTION__ , local_cxy , hal_time_stamp() );
     297
     298    /////////// MMC internal chdev /////////// 
     299
     300    dev = &info->dev_mmc;
     301
     302    if( dev->channels != 0 )   // MMC device is defined
     303    {
     304        assert( (dev->channels == 1) , __FUNCTION__ ,
     305            "channels number must be 1 for MMC device" );
     306
     307        assert( (FUNC_FROM_TYPE( dev->type ) == DEV_FUNC_MMC ) , __FUNCTION__ ,
     308            " inconsistent MMC device type");
     309
     310        // create one chdev in local cluster
     311        chdev_ptr = chdev_create( FUNC_FROM_TYPE( dev->type ),
     312                                  IMPL_FROM_TYPE( dev->type ),
     313                                  0,                              // channel
     314                                  false,                          // TX
     315                                  dev->base );
     316
     317        assert( (chdev_ptr != NULL) , __FUNCTION__ , "cannot allocate MMC chdev" );
     318           
     319        // get extended pointer on chdev descriptor
     320        chdev_xp = XPTR( local_cxy , chdev_ptr );
     321
     322        // make MMC specific initialisation
     323        dev_mmc_init( chdev_ptr );     
     324
     325        // initialize the MMC field in the chdev_dir[x][y] structures
     326        // replicated in all clusters, and containing extended pointers
     327        // on all remotely accessible devices
     328        for( x = 0 ; x < info->x_size ; x++ )
     329        {
     330            for( y = 0 ; y < info->y_size ; y++ )
     331            {
     332                cxy_t  cxy = (x<<info->y_width) + y;
     333                hal_remote_swd( XPTR( cxy , &chdev_dir.mmc[local_cxy] ) , chdev_xp );
     334            }
     335        }
     336
     337        kinit_dmsg("\n[INFO] %s : core[%x][0] creates MMC chdev at cycle %d\n",
     338                   __FUNCTION__ , local_cxy , hal_time_stamp() );
     339    }
     340
     341    /////////// DMA internal chdevs //////////
     342
     343    dev = &info->dev_dma;
     344
     345    if( dev->channels != 0 )   // DMA device is defined
     346    {
     347        assert( (FUNC_FROM_TYPE( dev->type ) == DEV_FUNC_DMA ) , __FUNCTION__ ,
     348                " inconsistent DMA  device type");
     349
     350        // create one chdev per channel in local cluster
     351        uint32_t channel;
     352        for( channel = 0 ; channel < dev->channels ; channel++ )
     353        {
     354            chdev_ptr = chdev_create( FUNC_FROM_TYPE( dev->type ),
     355                                      IMPL_FROM_TYPE( dev->type ),
     356                                      channel,                        // channel
     357                                      false,                          // TX
     358                                      dev->base );
     359
     360            assert( (chdev_ptr != NULL) , __FUNCTION__ , "cannot allocate DMA chdev" );
    263361           
    264362            // get extended pointer on channel descriptor
    265             chdev_xp = XPTR( local_cxy , chdev );
    266 
    267             // TODO ??? AG
    268                     // devfs_register( dev );
    269 
    270             // make device type specific initialisation
    271             // the number of parameters depends on the device type
    272             // TODO : remove these parameters that  must be provided by the driver
    273             if     ( func == DEV_FUNC_ICU ) dev_icu_init( chdev , p0 , p1 , p2 );     
    274             else if( func == DEV_FUNC_MMC ) dev_mmc_init( chdev );
    275             else                            dev_dma_init( chdev );
    276 
    277             // initialize the replicated chdev_dir[x][y] structures
    278             // containing extended pointers on all devices descriptors
    279             xptr_t * entry;   
    280 
    281             if     ( func == DEV_FUNC_ICU ) entry  = &chdev_dir.icu[local_cxy];
    282             else if( func == DEV_FUNC_MMC ) entry  = &chdev_dir.mmc[local_cxy];
    283             else                            entry  = &chdev_dir.dma[channel];
    284  
    285             if( func != DEV_FUNC_DMA )  // ICU and MMC devices are remotely accessible
    286             {
    287                 for( x = 0 ; x < info->x_size ; x++ )
    288                 {
    289                     for( y = 0 ; y < info->y_size ; y++ )
    290                     {
    291                         cxy_t  cxy = (x<<info->y_width) + y;
    292                         hal_remote_swd( XPTR( cxy , entry ) , chdev_xp );
    293                     }
    294                 }
    295             }
    296             else                      // DMA devices are NOT remotely accessible
    297             {
    298                 *entry = chdev_xp;
    299             }
    300 
    301             kinit_dmsg("\n[INFO] %s :core[%x][0] created chdev %s / channel %d"
    302                        " / paddr = %l at cycle %d\n",
    303                        __FUNCTION__ , local_cxy , chdev_func_str( func ) ,
    304                        channel , chdev_xp , hal_time_stamp() );
    305 
    306         } // end loop on channels
    307 
    308         // initialize the entries of the local chdev_icu_input structure
    309         // defining how internal peripherals are connected to ICU
    310         if( func == DEV_FUNC_ICU ) 
    311         {
    312             uint32_t   id;
    313             uint8_t    valid;
    314             uint32_t   dev_type;
    315             uint8_t    channel;
    316 
    317             // loop on ICU inputs
    318             for( id = 0 ; id < CONFIG_MAX_HWIS_PER_ICU ; id++ )
    319             {
    320                 valid    = dev_tbl[i].irq[id].valid;
    321                 dev_type = dev_tbl[i].irq[id].dev_type;
    322                 channel  = dev_tbl[i].irq[id].channel;
    323 
    324                 if( valid ) // only valid local IRQs are registered
    325                 {
    326                     uint32_t * index;   // local pointer on the entry to be set
    327                     uint16_t   dev_func = FUNC_FROM_TYPE( dev_type );
    328                     if( dev_func == DEV_FUNC_MMC ) 
    329                         index = &chdev_icu_input.mmc;
    330                     else if( dev_func == DEV_FUNC_DMA ) 
    331                         index = &chdev_icu_input.dma[channel];
    332                     else
    333                     {
    334                         assert( false , __FUNCTION__ , "illegal source device for ICU input" );
    335                     }                   
    336 
    337                     // set entry in local structure
    338                     *index = id;
    339                 }
    340 
    341             }  // end loop on ICU inputs
    342         }  // end if ICU
    343         } // end loop on peripherals
     363            chdev_xp = XPTR( local_cxy , chdev_ptr );
     364
     365            // make DMA specific initialisation
     366            dev_dma_init( chdev_ptr );     
     367
     368            // initialize only the DMA[channel] field in the local chdev_dir[x][y]
     369            // structure because the DMA device is not remotely accessible.
     370            chdev_dir.dma[channel] = chdev_xp;
     371
     372            kinit_dmsg("\n[INFO] %s : core[%x][0] creates DMA[%d] chdev at cycle %d\n",
     373                       __FUNCTION__ , local_cxy , channel , hal_time_stamp() );
     374        }
     375    }
    344376}  // end internal_devices_init()
    345377
     
    353385//
    354386// The number of channel_devices depends on the device functionnal type.
    355 // There is three nested loops to scan the full set of external channel_devices:
     387// There is three nested loops to build the full set of external channel_devices:
    356388// - loop on external devices.
    357389// - loop on channels for multi-channels devices.
     
    371403        uint32_t        dev_nr;          // actual number of devices in this cluster
    372404        xptr_t          base;            // remote pointer on segment base
    373         uint32_t        size;            // channel size (bytes)
    374405    uint32_t        type;            // peripheral type
    375406    uint32_t        func;            // device functionnal index
     
    399430        for( i = 0 ; i < dev_nr ; i++ )
    400431        {
    401         size        = dev_tbl[i].size;
    402432        base        = dev_tbl[i].base;
    403433        type        = dev_tbl[i].type;
     
    496526                    }
    497527
    498                             kinit_dmsg("\n[INFO] %s : core[%x][0] created chdev %s / channel = %d"
    499                                " / paddr = %l at cycle %d\n",
     528                            kinit_dmsg("\n[INFO] %s : core[%x][0] create chdev %s[%d] at cycle %d\n",
    500529                               __FUNCTION__ , local_cxy , chdev_func_str( func ),
    501                                channel , chdev_xp , hal_time_stamp() );
     530                               channel , hal_time_stamp() );
    502531
    503532                }  // end if match
     
    564593
    565594///////////////////////////////////////////////////////////////////////////////////////////
     595// This static function returns the identifiers of the calling core.
     596///////////////////////////////////////////////////////////////////////////////////////////
     597// @ info    : pointer on boot_info structure.
     598// @ lid     : [out] core local index in cluster.
     599// @ cxy     : [out] cluster identifier.
     600// @ lid     : [out] core global identifier (hardware).
     601// @ return 0 if success / return EINVAL if not found.
     602///////////////////////////////////////////////////////////////////////////////////////////
     603static error_t core_get_identifiers( boot_info_t * info,
     604                                     uint32_t    * lid,
     605                                     cxy_t       * cxy,
     606                                     gid_t       * gid )
     607{
     608        uint32_t   i;
     609    gid_t      global_id;
     610   
     611    // get global identifier from hardware register
     612    global_id = hal_get_gid();
     613
     614    // makes an associative search in boot_info to get (cxy,lid) from global_id
     615    for( i = 0 ; i < info->cores_nr ; i++ )
     616    {
     617        if( global_id == info->core[i].gid )
     618        {
     619            *lid = info->core[i].lid;
     620            *cxy = info->core[i].cxy;
     621            *gid = global_id;
     622            return 0;
     623        }
     624    }
     625    return EINVAL;
     626}                     
     627
     628///////////////////////////////////////////////////////////////////////////////////////////
    566629// This function is the entry point for the kernel initialisation.
    567 // It is executed by all cores in all clusters, but only core[0] in each cluster
    568 // initialize the cluster manager, ant the local peripherals.
     630// It is executed by all cores in all clusters, but only core[0], called CP0,   
     631// initializes the shared resources such as the cluster manager, or the local peripherals.
    569632// To comply with the multi-kernels paradigm, it access only local cluster memory, using
    570633// only informations contained in the local boot_info_t structure, set by the bootloader.
     
    574637void kernel_init( boot_info_t * info )
    575638{
    576     uint32_t     core_lid;      // running core local index
    577     cxy_t        core_cxy;      // running core cluster identifier
    578     gid_t        core_gid;      // running core hardware identifier
    579     cluster_t  * cluster;       // pointer on local cluster manager
    580     core_t     * core;          // pointer on running core descriptor
    581     thread_t   * thread_idle;   // pointer on thread_idle 
    582 
    583         uint32_t     i;
    584     bool_t       found;
     639    uint32_t     core_lid = -1;      // running core local index
     640    cxy_t        core_cxy = -1;      // running core cluster identifier
     641    gid_t        core_gid;           // running core hardware identifier
     642    cluster_t  * cluster;            // pointer on local cluster manager
     643    core_t     * core;               // pointer on running core descriptor
     644    thread_t   * thread;             // pointer on idle thread descriptor
    585645    error_t      error;
    586646
    587     // initialise global cluster identifier
    588     local_cxy = info->cxy;
    589 
    590     // each core get its global index from hardware register
    591     core_gid = hal_get_gid();
    592 
    593     // Each core makes an associative search in boot_info
    594     // to get its (cxy,lid) composite index from its gid
    595     found    = false;
    596     core_cxy = 0;
    597     core_lid = 0;
    598     for( i = 0 ; i < info->cores_nr ; i++ )
    599     {
    600         if( core_gid == info->core[i].gid )
    601         {
    602             core_lid = info->core[i].lid;
    603             core_cxy = info->core[i].cxy;
    604             found = true;
    605             break;
    606         }
    607     }
    608          
    609     // suicide if not found
    610     if( (found == false) || (core_cxy != local_cxy) ) hal_core_sleep();
    611 
    612     //////////////////////////////////////////////////////////////
    613     // In first step, only CP0 initialises local resources
    614     //////////////////////////////////////////////////////////////
    615 
    616     if( core_lid == 0 )   
    617     {
    618         // initialize local cluster manager (cores and memory allocators)
     647    // all cores get core identifiers
     648    error = core_get_identifiers( info,
     649                                  &core_lid,
     650                                  &core_cxy,
     651                                  &core_gid );
     652
     653    // CP0 initialise cluster identifier
     654    if( core_lid == 0 ) local_cxy = info->cxy;
     655
     656    // CP0 in I/O cluster initialises TXT0 chdev descriptor
     657    if( (core_lid == 0) && (core_cxy == info->io_cxy) ) txt0_device_init( info );
     658
     659    /////////////////////////////////////////////////////////////////////////////////
     660    // global & local synchro to protect access to TXT0 terminal
     661    if( core_lid == 0 ) remote_barrier( XPTR( info->io_cxy , &global_barrier ),
     662                                        (info->x_size * info->y_size) );
     663    barrier_wait( &local_barrier , info->cores_nr );
     664    /////////////////////////////////////////////////////////////////////////////////
     665
     666    kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 0\n",
     667               __FUNCTION__ , core_cxy , core_lid );
     668
     669    // all cores check core identifiers
     670    if( error )
     671    {
     672        printk("\n[PANIC] in %s : illegal core identifiers"
     673               " gid = %x / cxy = %x / lid = %d\n",
     674               __FUNCTION__ , core_lid , core_cxy , core_lid );
     675        hal_core_sleep();
     676    }
     677    else
     678    {
     679        kinit_dmsg("\n[INFO] %s : core[%x][%d] enters at cycle %d / sp = %x\n",
     680                   __FUNCTION__ , core_cxy , core_lid , hal_time_stamp() , hal_get_stack() );
     681    }
     682
     683    // CP0 initialize local cluster manager (cores and memory allocators)
     684    if( core_lid == 0 )
     685    {
    619686        error = cluster_init( info );
    620  
    621         // suicide if failure
    622         if( error ) hal_core_sleep();
    623 
    624         // get pointer on local cluster manager and on core descriptor
    625         cluster = LOCAL_CLUSTER;
    626             core    = &cluster->core_tbl[core_lid];
    627 
    628         // initialize process_zero descriptor
    629                 process_zero_init( info );
    630 
    631         // CP0 initialize its private thread_zero descriptor
    632             memset( &thread_zero , 0 , sizeof(thread_t) );
    633             thread_zero.type     = THREAD_KERNEL;
    634             thread_zero.process  = &process_zero;
    635             hal_set_current_thread( &thread_zero );
    636 
    637         // CP0 in I/O cluster initialize the kernel TXT0 chdev descriptor.
    638         // this TXTO device is shared by the all kernel instances for debug messages:
    639         // the printk() function call the dev_txt_sync_write() function that call
    640         // directly the relevant TXT driver, without desheduling.
    641         if( core_cxy == info->io_cxy ) txt0_device_init( info );
    642 
    643         // synchronise all CP0s before using TXT0
    644         remote_barrier( XPTR( info->io_cxy , &cluster->barrier ) ,
    645                         (cluster->x_size * cluster->y_size) );
    646 
    647         // All CP0 initialise internal peripheral chdev descriptors.
    648         // Each CP0[cxy] scan the set of its internal (private) peripherals,
    649         // and allocate memory for the corresponding chdev descriptors.
    650         internal_devices_init( info );
     687
     688        if( error )
     689        {
     690            printk("\n[PANIC] in %s : cannot initialise cluster manager in cluster %x",
     691                   __FUNCTION__ , local_cxy );
     692            hal_core_sleep();
     693        }
     694        else
     695        {
     696            kinit_dmsg("\n[INFO] %s : core[%x][%d] initialised cluster at cycle %d\n",
     697                       __FUNCTION__ , core_cxy , core_lid , hal_time_stamp());
     698        }
     699    }
     700
     701    /////////////////////////////////////////////////////////////////////////////////
     702    // global & local synchro, to protect access to cluster manager
     703    if( core_lid == 0 ) remote_barrier( XPTR( info->io_cxy , &global_barrier ),
     704                                        (info->x_size * info->y_size) );
     705    barrier_wait( &local_barrier , info->cores_nr );
     706    /////////////////////////////////////////////////////////////////////////////////
     707
     708    kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 1\n",
     709               __FUNCTION__ , core_cxy , core_lid );
     710
     711    // all cores get pointer on local cluster manager and on core descriptor
     712    cluster = &cluster_manager;
     713        core    = &cluster->core_tbl[core_lid];
     714
     715    // CP0 initialize process_zero descriptor
     716    if( core_lid == 0 ) process_zero_init( info );
     717
     718    // CP0 allocate and initialise internal peripheral chdev descriptors.
     719    // Each CP0[cxy] scan the set of its internal (private) peripherals,
     720    // and allocate memory for the corresponding chdev descriptors.
     721    if( core_lid == 0 ) internal_devices_init( info );
    651722       
    652         // All CP0 contribute to initialise external peripheral chdev descriptors.
    653         // Each CP0[cxy] scan the set of external (shared) peripherals (but the TXT0),
    654         // and allocates memory for the chdev descriptors that must be placed
    655         // on the (cxy) cluster according to its global index. 
    656         external_devices_init( info );
    657 
    658         // TODO initialize devFS and sysFS
    659                 // devfs_root_init();
    660                 // sysfs_root_init();
    661 
    662         // TODO ??? [AG]
    663                 // clusters_sysfs_register();
    664 
    665         // TODO initialize virtual file system
     723    // CP0 allocates one WTI mailbbox per core for Inter Processor Interrupt
     724    // this must be done after ICU chdev initialisation, by CP0 only, and before
     725    // external devices initialisation to enforce the rule (wti_id == lid)
     726    if( core_lid == 0 )
     727    {
     728        uint32_t  wti_id;
     729        uint32_t  lid;
     730        for( lid = 0 ; lid < LOCAL_CLUSTER->cores_nr ; lid++ )
     731        {
     732            wti_id = dev_icu_wti_alloc();
     733
     734            if( wti_id != lid )
     735            {
     736                printk("\n[PANIC] in %s : WTI index for IPI = %d / core_lid = %d",
     737                       __FUNCTION__ , wti_id , lid );
     738                hal_core_sleep();
     739            }
     740
     741            dev_icu_enable_irq( lid , WTI_TYPE , wti_id , NULL );
     742        }
     743    }
     744
     745    // CP0 contribute to initialise external peripheral chdev descriptors.
     746    // Each CP0[cxy] scan the set of external (shared) peripherals (but the TXT0),
     747    // and allocates memory for the chdev descriptors that must be placed
     748    // on the (cxy) cluster according to the global index value. 
     749    if( core_lid == 0 ) external_devices_init( info );
     750
     751    /////////////////////////////////////////////////////////////////////////////////
     752    // global &local synchro to protect access to peripherals
     753    if( core_lid == 0 ) remote_barrier( XPTR( info->io_cxy , &global_barrier ),
     754                                        (info->x_size * info->y_size) );
     755    barrier_wait( &local_barrier , info->cores_nr );
     756    /////////////////////////////////////////////////////////////////////////////////
     757
     758    kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 2\n",
     759               __FUNCTION__ , core_cxy , core_lid );
     760
     761    // all cores initialize the private idle thread descriptor
     762        thread = (thread_t *)( idle_threads + (core_lid * CONFIG_THREAD_DESC_SIZE) );
     763
     764    error = thread_kernel_init( thread,
     765                                THREAD_IDLE,
     766                                &thread_idle_func,
     767                                NULL,
     768                                core_lid );
     769
     770    if( error )
     771    {
     772        printk("\n[PANIC] in %s : core[%x][%d] cannot initialize idle thread\n",
     773               __FUNCTION__ , local_cxy , core_lid );
     774        hal_core_sleep();
     775    }
     776    else
     777    {
     778        // register idle thread in scheduler
     779        core->scheduler.idle = thread;
     780
     781        // register idle thread pointer in core register
     782        hal_set_current_thread( thread );
     783   
     784        // activate the idle thread
     785        thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL );
     786
     787        kinit_dmsg("\n[INFO] %s : core[%x][%d] created idle thread %x at cycle %d\n",
     788                   __FUNCTION__ , core_cxy , core_lid , thread , hal_time_stamp());
     789    }
     790
     791    // TODO CP0 in IO cluster initialize VFS, devFS and sysFS
     792    {
     793            // devfs_root_init();
     794            // sysfs_root_init();
     795            // clusters_sysfs_register();
    666796        // vfs_init();
    667 
    668         // TODO ??? [AG]
    669                 // sysconf_init();
    670 
    671         // activate other cores in same cluster
    672                 local_sync_init = KERNEL_INIT_SYNCHRO;
    673                 hal_wbflush();
    674     }
    675     else   // other cores                                 
    676     {
    677         // other cores wait synchro from core[0]
    678                 while( local_sync_init != KERNEL_INIT_SYNCHRO )
    679         {
    680                    uint32_t retval = hal_time_stamp() + 1000;
    681                    while( hal_time_stamp() < retval )  asm volatile ("nop");
    682         }
    683 
    684         // get pointer on local cluster manager and on core descriptor
    685         cluster = LOCAL_CLUSTER;
    686             core    = &cluster->core_tbl[core_lid];
    687 
    688         // core initialise its private thread_zero descriptor
    689             memset( &thread_zero , 0 , sizeof(thread_t) );
    690             thread_zero.type     = THREAD_KERNEL;
    691             thread_zero.process  = &process_zero;
    692             hal_set_current_thread( &thread_zero );
    693     }
    694 
    695         // each core creates its private idle thread descriptor
    696         error = thread_kernel_create( &thread_idle,
    697                                   THREAD_IDLE,
    698                                   &thread_idle_func,
    699                                   NULL,
    700                                   core_lid );
    701 
    702     assert( (error == 0) , __FUNCTION__ , "cannot create idle thread" );
    703 
    704     // each core register thread_idle in scheduler
    705     core->scheduler.idle = thread_idle;
    706 
    707     // each core register thread pointer in core hardware register
    708     hal_set_current_thread( thread_idle );
    709 
    710     kinit_dmsg("\n[INFO] %s : thread idle created for core[%x][%d] at cycle %d\n",
    711                __FUNCTION__ , core_cxy , core_lid , hal_time_stamp());
    712 
    713     // global syncho for all core[0] in all clusters
    714     if( core_lid == 0 )
    715     {
    716         remote_barrier( XPTR( info->io_cxy , &cluster->barrier ) ,
    717                         (cluster->x_size * cluster->y_size) );
    718     }
    719 
    720     // local synchro for all cores in local cluster
    721     remote_barrier( XPTR( local_cxy , &cluster->barrier ) ,
    722                     cluster->cores_nr );
    723 
     797            // sysconf_init();
     798    }
     799
     800    // CP0 in I/O cluster print banner
    724801    if( (core_lid ==  0) && (local_cxy == info->io_cxy) )
    725802    {
     
    727804    }
    728805
    729     // load idle thread context on calling core
    730         hal_cpu_context_load( thread_idle );
     806    /////////////////////////////////////////////////////////////////////////////////
     807    // global syncho to protect access to File System
     808    if( core_lid == 0 ) remote_barrier( XPTR( info->io_cxy , &global_barrier ),
     809                                        (info->x_size * info->y_size) );
     810    barrier_wait( &local_barrier , info->cores_nr );
     811    /////////////////////////////////////////////////////////////////////////////////
     812
     813    kinit_dmsg("\n[INFO] %s : core[%x][%d] exit barrier 3\n",
     814               __FUNCTION__ , core_cxy , core_lid );
     815
     816    // each core activates its private PTI IRQ
     817    dev_icu_set_period( core_lid , CONFIG_SCHED_TICK_PERIOD );
     818    dev_icu_enable_irq( core_lid , PTI_TYPE , core_lid , NULL );
     819
     820    // each core get its private IRQ masks values and
     821    uint32_t hwi_mask;
     822    uint32_t wti_mask;
     823    uint32_t pti_mask;
     824    dev_icu_get_masks( core_lid , &hwi_mask , &wti_mask , &pti_mask );
     825
     826    thread_dmsg("\n[INFO] %s : core[%x][%d] activates scheduler at cycle %d\n"
     827                "   hwi_mask = %x / wti_mask = %x / pti_mask = %x\n",
     828                    __FUNCTION__ , local_cxy , core_lid , hal_time_stamp() ,
     829                    hwi_mask , wti_mask , pti_mask );
     830
     831    // each core jump to idle thread
     832    asm volatile( "j thread_idle_func\n" );
    731833
    732834} // end kernel_init()
Note: See TracChangeset for help on using the changeset viewer.