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

Introduce the chdev_t structure in place of the device_t structure.

File:
1 edited

Legend:

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

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