Ignore:
Timestamp:
Apr 26, 2017, 2:14:33 PM (5 years ago)
Author:
alain
Message:

Modify the boot_info_t struct to describe external peripherals in all clusters.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/bootloader_tsar/boot.c

    r1 r6  
     1/*
     2 * boot.c - TSAR bootloader implementation.
     3 *
     4 * Authors :   Alain Greiner / Vu Son  (2016)
     5 *
     6 * Copyright (c) UPMC Sorbonne Universites
     7 *
     8 * This file is part of ALMOS-MKH.
     9 *
     10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
     11 * under the terms of the GNU General Public License as published by
     12 * the Free Software Foundation; version 2.0 of the License.
     13 *
     14 * ALMOS-MKH is distributed in the hope that it will be useful, but
     15 * WITHOUT ANY WARRANTY; without even the implied warranty of
     16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     17 * General Public License for more details.
     18 *
     19 * You should have received a copy of the GNU General Public License
     20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
     21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
     22 */
     23
    124/****************************************************************************
    2  * This file contains the ALMOS-MKH. boot-loader for the TSAR architecture.  *
     25 * This file contains the ALMOS-MKH. boot-loader for the TSAR architecture. *
    326 *                                                                          *
    427 * It supports clusterised shared memory multi-processor architectures,     *
     
    4770
    4871#include <elf-types.h>
     72#include <hal_types.h>
    4973
    5074#include <almos_config.h>
     
    5377#include <arch_info.h>
    5478#include <boot_info.h>
    55 
    56 #include <hal_types.h>
    5779
    5880#include <boot_utils.h>
     
    6284#include <boot_tty_driver.h>
    6385
    64 /****************************************************************************
    65  *                                 Macros.                                  *
     86/*****************************************************************************
     87 *                                 Macros.                             
    6688 ****************************************************************************/
    6789
     
    7092                            (~(PPM_PAGE_SIZE-1)))
    7193
    72 /****************************************************************************
    73  *                             Global variables.                            *
     94/*****************************************************************************
     95 *                             Global variables.                           
    7496 ****************************************************************************/
    7597
    7698// synchronization variables.
    77 volatile boot_barrier_t global_barrier;     /* Used by bscpu to synchronize
    78                                                with other CP0s cores.       */
    79 
    80 volatile uint32_t   global_count;           /* Number of cores expected in
    81                                                global barrier.              */
    82 
    83 volatile uint32_t   local_barrier;          /* Used by CP0 to synchronize
    84                                                with local CPi.              */
    85 
    86 volatile uint32_t   boot_cluster_ready;     /* Modified by bscpu to report
    87                                                that the boot cluster is
    88                                                ready.                       */
    89 
    90 // kernel image memory layout.
    91 uint32_t ktext_base;                        /* ktext segment base address.  */
    92 uint32_t ktext_end;                         /* ktext segment end address.   */
    93 uint32_t kdata_base;                        /* kdata segment base address.  */
    94 uint32_t kdata_end;                         /* kdata segment end address.   */
    95 
    96 uint32_t kernel_entry;                      /* Kernel entry point.          */
    97 
    98 // Extern variables.
    99 extern void boot_entry();                   /* boot_loader() function       */
    100 
    101 /****************************************************************************
    102  *                           Internal functions.                            *
    103  ****************************************************************************/
    104 
     99
     100volatile boot_remote_spinlock_t tty0_lock;       // protect TTY0 access
     101volatile boot_remote_barrier_t  global_barrier;  // synchronize CP0 cores
     102volatile boot_remote_barrier_t  local_barrier;   // synchronize cores in one cluster
     103uint32_t                        active_cp0s_nr;  // number of expected CP0s
     104 
     105// kernel segments layout variables
     106
     107uint32_t                        seg_kcode_base;  // kcode segment base address
     108uint32_t                        seg_kcode_size;  // kcode segment size (bytes)
     109uint32_t                        seg_kdata_base;  // kdata segment base address
     110uint32_t                        seg_kdata_size;  // kdata segment size (bytes)
     111uint32_t                        kernel_entry;    // kernel entry point
     112
     113// address used by the WTI to activate remote CP0s
     114
     115extern void                     boot_entry();    // boot_loader entry point
     116
     117/*********************************************************************************
     118 * This function returns the printable string for each device type
     119 ********************************************************************************/
    105120char * device_type_str( uint32_t dev_type )
    106121{
    107     if     ( dev_type == DEV_TYPE_RAM     ) return "RAM";
    108     else if( dev_type == DEV_TYPE_DMA     ) return "DMA";
    109     else if( dev_type == DEV_TYPE_FBF     ) return "FBF";
    110     else if( dev_type == DEV_TYPE_IOB     ) return "IOB";
     122    if     ( dev_type == DEV_TYPE_RAM_SCL ) return "RAM_SCL";
     123    else if( dev_type == DEV_TYPE_ROM_SCL ) return "ROM_SCL";
     124    else if( dev_type == DEV_TYPE_FBF_SCL ) return "FBF_SCL";
     125    else if( dev_type == DEV_TYPE_IOB_TSR ) return "IOB_TSR";
    111126    else if( dev_type == DEV_TYPE_IOC_BDV ) return "IOC_BDV";
    112127    else if( dev_type == DEV_TYPE_IOC_HBA ) return "IOC_HBA";
     
    114129    else if( dev_type == DEV_TYPE_IOC_SPI ) return "IOC_SPI";
    115130    else if( dev_type == DEV_TYPE_IOC_RDK ) return "IOC_RDK";
    116     else if( dev_type == DEV_TYPE_MMC     ) return "MMC";
    117     else if( dev_type == DEV_TYPE_MWR_CPY ) return "MWR_CPY";
    118     else if( dev_type == DEV_TYPE_MWR_GCD ) return "MWR_GCD";
    119     else if( dev_type == DEV_TYPE_MWR_DCT ) return "MWR_DCT";
    120     else if( dev_type == DEV_TYPE_NIC     ) return "NIC";
    121     else if( dev_type == DEV_TYPE_ROM     ) return "ROM";
    122     else if( dev_type == DEV_TYPE_SIM     ) return "SIM";
    123     else if( dev_type == DEV_TYPE_TIM     ) return "TIM";
    124     else if( dev_type == DEV_TYPE_TTY     ) return "TTY";
    125     else if( dev_type == DEV_TYPE_XCU     ) return "XCU";
    126     else if( dev_type == DEV_TYPE_PIC     ) return "PIC";
    127     else if( dev_type == DEV_TYPE_CMA     ) return "CMA";
    128     else                                    return "UNDEFINED";
     131    else if( dev_type == DEV_TYPE_MMC_TSR ) return "MMC_TSR";
     132    else if( dev_type == DEV_TYPE_DMA_SCL ) return "DMA_SCL";
     133    else if( dev_type == DEV_TYPE_NIC_CBF ) return "NIC_CBF";
     134    else if( dev_type == DEV_TYPE_TIM_SCL ) return "TIM_SCL";
     135    else if( dev_type == DEV_TYPE_TXT_TTY ) return "TXT_TTY";
     136    else if( dev_type == DEV_TYPE_ICU_XCU ) return "ICU_XCU";
     137    else if( dev_type == DEV_TYPE_PIC_TSR ) return "PIC_TSR";
     138    else                                    return "undefined";
    129139}
    130140
    131 /****************************************************************************
     141/************************************************************************************
    132142 * This function loads the arch_info.bin file into the boot cluster memory.
    133  ****************************************************************************/
     143 ***********************************************************************************/
    134144static void boot_archinfo_load()
    135145{
     
    154164
    155165#if DEBUG_BOOT_INFO
    156 boot_printf("\n[BOOT] file %s loaded at %l\n",
    157             ARCHINFO_PATHNAME , ARCHINFO_BASE );
     166boot_printf("\n[BOOT INFO] in %s : file %s loaded at address = %x\n",
     167            __FUNCTION__ , ARCHINFO_PATHNAME , ARCHINFO_BASE );
    158168#endif
    159169
    160170} // boot_archinfo_load()
    161171
    162 /****************************************************************************
    163  * This function loads the 'kernel.elf' file into the boot cluster memory   *
    164  * bank, analyzes it then places the kernel image at the temporary physical *
    165  * memory address KERN_IMG_TMP_BASE since other processors are still        *
    166  * executing the preloader code (which means that the kernel image cannot   *
    167  * be placed now at its final memory location starting at address 0x0.      *
    168  ****************************************************************************/
     172/**************************************************************************************
     173 * This function loads the 'kernel.elf' file into the boot cluster memory buffer,
     174 * analyzes it, and places the the two seg_kcode & seg_kdata segments at their final
     175 * physical adresses (just after the preloader zone).       
     176 * It set the global variables defining the kernel layout.
     177 *************************************************************************************/
    169178static void boot_kernel_load()
    170179{
    171     Elf32_Ehdr* elf_header;         /* Pointer on 'kernel.elf' header.      */
    172     Elf32_Phdr* program_header;     /* Pointer on 'kernel.elf' program
    173                                        header.                              */
    174     uint32_t    phdr_offset;        /* Program header offset in
    175                                        'kernel.elf' file.                   */
    176     uint32_t    segments_nb;        /* Total number of segments in
    177                                        'kernel.elf' file.                   */
    178 
    179     uint32_t    seg_src_addr;       /* Segment address in 'kernel.elf'
    180                                        file (source).                       */
    181     uint32_t    seg_paddr;          /* Physical address at which the
    182                                        first byte of the segment resides
    183                                        in memory.                           */
    184     uint32_t    seg_offset;         /* Offset from the beginning of
    185                                        'kernel.elf' file to the segment's
    186                                        first byte.                          */
    187     uint32_t    seg_filesz;         /* Segment's number of bytes in
    188                                        'kernel.elf' file.                   */
    189     uint32_t    seg_memsz;          /* Segment's number of bytes in the
    190                                        memory image.                        */
    191 
    192     uint32_t    seg_id;             /* Iterator for program header scanning
    193                                        loop.                                */
    194 
    195     /* Loading file into memory. */
    196     if (boot_fat32_load(KERNEL_PATHNAME, KERN_BASE, KERN_MAX_SIZE))
    197     {
    198         boot_printf("\n[BOOT ERROR]: boot_kernel_load(): "
    199                     "<%s> file not found\n",
     180    Elf32_Ehdr * elf_header;      // pointer on kernel.elf header. 
     181    Elf32_Phdr * program_header;  // pointer on kernel.elf program header.
     182    uint32_t     phdr_offset;     // program header offset in kernel.elf file.
     183    uint32_t     segments_nb;     // number of segments in kernel.elf file.
     184    uint32_t     seg_src_addr;    // segment address in kernel.elf file (source).
     185    uint32_t     seg_paddr;       // segment local physical address of segment
     186    uint32_t     seg_offset;      // segment offset in kernel.elf file
     187    uint32_t     seg_filesz;      // segment size (bytes) in kernel.elf file
     188    uint32_t     seg_memsz;       // segment size (bytes) in memory image.
     189    bool_t       kcode_found;     // kcode segment found.
     190    bool_t       kdata_found;     // kdata segment found.
     191    uint32_t     seg_id;          // iterator for segments loop.
     192
     193#if DEBUG_BOOT_ELF
     194boot_printf("\n[BOOT INFO] %s enters for file %s at cycle %d\n",
     195            __FUNCTION__ , KERNEL_PATHNAME , boot_get_proctime() );
     196#endif
     197
     198    // Load kernel.elf file into memory buffer
     199    if ( boot_fat32_load(KERNEL_PATHNAME, KERN_BASE, KERN_MAX_SIZE) )
     200    {
     201        boot_printf("\n[BOOT ERROR] in %s : <%s> file not found\n",
    200202                    KERNEL_PATHNAME);
    201203        boot_exit();
    202204    }
    203205
    204     /*
    205      * Initializing pointer to header which is the first element of the
    206      * .elf file.
    207      */
     206    // get pointer to kernel.elf header 
    208207    elf_header = (Elf32_Ehdr*)KERN_BASE;
    209208
    210     /* Signature problem, abort program !!! */
     209    // check signature
    211210    if ((elf_header->e_ident[EI_MAG0] != ELFMAG0)   ||
    212211        (elf_header->e_ident[EI_MAG1] != ELFMAG1)   ||
     
    220219    }
    221220
    222     /* Getting the program header table offset and the number of segments. */
     221    // Get program header table offset and number of segments
    223222    phdr_offset     = elf_header->e_phoff;
    224223    segments_nb     = elf_header->e_phnum;
    225224
    226     /* Getting the program header table pointer. */
     225    // Get program header table pointer
    227226    program_header  = (Elf32_Phdr*)(KERN_BASE + phdr_offset);
    228227
    229     /* Looking for loadable segments. */
     228    // loop on segments
     229    kcode_found = false;
     230    kdata_found = false;
    230231    for (seg_id = 0; seg_id < segments_nb; seg_id++)
    231232    {
    232         // Found one:
    233         if (program_header[seg_id].p_type == PT_LOAD)
     233        if (program_header[seg_id].p_type == PT_LOAD)   // Found one loadable segment
    234234        {
    235             // Getting its attributes.
     235            // Get segment attributes.
    236236            seg_paddr    = program_header[seg_id].p_paddr;   
    237237            seg_offset   = program_header[seg_id].p_offset;
     
    239239            seg_memsz    = program_header[seg_id].p_memsz;
    240240
    241             // Load it to its appropriate physical memory address.
     241            // get segment base address in buffer
    242242            seg_src_addr = (uint32_t)KERN_BASE + seg_offset;
    243             boot_memcpy((void*)(KERN_IMG_TMP_BASE + seg_paddr),
    244                         (void*)seg_src_addr,
    245                                seg_filesz);
     243
     244            // Load segment to its final physical memory address
     245            boot_memcpy( (void*)seg_paddr,
     246                         (void*)seg_src_addr,
     247                         seg_filesz );
     248
     249#if DEBUG_BOOT_ELF
     250boot_printf("\n[BOOT INFO] in %s for file %s : found loadable segment\n"
     251            "   base = %x / size = %x\n",
     252            __FUNCTION__ , KERNEL_PATHNAME , seg_paddr , seg_memsz );
     253#endif
    246254
    247255            // Fill remaining memory with zero if (filesz < memsz).
    248             boot_memset((void*)(KERN_IMG_TMP_BASE + seg_paddr + seg_filesz),
    249                                 0,
    250                                 seg_memsz - seg_filesz);
    251            
    252             /*
    253              * Note: we suppose that the 'kernel.elf' file contains only 2
    254              * loadable segments ktext + kdata and that the main
    255              * difference between these two is the WRITE permission: ktext
    256              * contains read-only instructions and read_only data,
    257              * while kdata contains writable data.
    258              */
    259 
    260             // Get ktext segment base and end addresses.
    261             if ((program_header[seg_id].p_flags & PF_W) == 0)
    262             {
    263                 ktext_base = seg_paddr;
    264                 ktext_end  = seg_paddr + seg_memsz;
    265             }
    266 
    267             // Get kdata segment base and end addresses.
    268             else
    269             {
    270                 kdata_base = seg_paddr;
    271                 kdata_end  = seg_paddr + seg_memsz;
     256            if( seg_memsz < seg_filesz )
     257            {
     258                boot_memset( (void*)(seg_paddr + seg_filesz), 0, seg_memsz - seg_filesz);
     259            }
     260
     261            // Note: we suppose that the 'kernel.elf' file contains only 2
     262            // loadable segments ktext & kdata and that the main
     263            // difference between these two is the WRITE permission: ktext
     264            // contains read-only instructions and read_only data,
     265            // while kdata contains writable data.
     266
     267            if ((program_header[seg_id].p_flags & PF_W) == 0)  // kcode segment
     268            {
     269                if( kcode_found )
     270                {
     271                    boot_printf("\n[BOOT_ERROR] in %s for file %s :\n"
     272                                "   two loadable kcode segments found\n",
     273                                __FUNCTION__ , KERNEL_PATHNAME );
     274                    boot_exit();
     275                }
     276
     277                kcode_found     = true;
     278                seg_kcode_base = seg_paddr;
     279                seg_kcode_size = seg_memsz;
     280            }
     281            else                                               // kdata segment
     282            {
     283                if( kdata_found )
     284                {
     285                    boot_printf("\n[BOOT_ERROR] in %s for file %s :\n"
     286                                "   two loadable kdata segments found\n",
     287                                __FUNCTION__ , KERNEL_PATHNAME );
     288                    boot_exit();
     289                }
     290
     291                kdata_found     = true;
     292                seg_kdata_base = seg_paddr;
     293                seg_kdata_size = seg_memsz;
    272294            }
    273295        }
    274296    }
    275297
    276     // Get the entry point for kernel code.
     298    // check kcode & kdata segments found
     299    if( kcode_found == false )
     300    {
     301        boot_printf("\n[BOOT_ERROR] in %s for file %s :\n"
     302                    "   kcode segment not found\n",
     303                    __FUNCTION__ , KERNEL_PATHNAME );
     304        boot_exit();
     305    }
     306    if( kdata_found == false )
     307    {
     308        boot_printf("\n[BOOT_ERROR] in %s for file %s :\n"
     309                    "   kdata segment not found\n",
     310                    __FUNCTION__ , KERNEL_PATHNAME );
     311        boot_exit();
     312    }
     313
     314    // set entry point
    277315    kernel_entry = (uint32_t)elf_header->e_entry;
    278316
     317#if DEBUG_BOOT_ELF
     318boot_printf("\n[BOOT INFO] %s successfully completed for file %s at cycle %d\n",
     319            __FUNCTION__ , KERNEL_PATHNAME , boot_get_proctime() );
     320#endif
     321
    279322} // boot_kernel_load()
    280323
    281 /****************************************************************************
    282  * This function initializes the local 'boot_info_t' structure.             *
    283  * @ boot_info  : pointer to local boot_info_t structure                    *
    284  * @ cxy        : cluster identifier                                        *
    285  ****************************************************************************/
     324/*************************************************************************************
     325 * This function initializes the  boot_info_t structure for a given cluster.
     326 * @ boot_info  : pointer to local boot_info_t structure 
     327 * @ cxy        : cluster identifier                   
     328 ************************************************************************************/
    286329static void boot_info_init( boot_info_t * boot_info,
    287330                            cxy_t         cxy )
    288331{
    289     archinfo_header_t  * header;       
     332    archinfo_header_t  * header;
    290333    archinfo_core_t    * core_base;     
    291334    archinfo_cluster_t * cluster_base;
     
    294337
    295338    archinfo_cluster_t * cluster;
     339    archinfo_cluster_t * my_cluster = NULL;   // target cluster
     340    archinfo_cluster_t * io_cluster = NULL;   // cluster containing ext. peripherals
     341
    296342    archinfo_core_t    * core;
    297343    uint32_t             core_id;
     
    303349    boot_device_t      * boot_dev;
    304350
    305     // get pointer on ARCHINFO header
    306     header = (archinfo_header_t*)ARCHINFO_BASE;
     351#if DEBUG_BOOT_INFO
     352boot_printf("\n[BOOT INFO] %s : enter for cluster %x at cycle %d\n",
     353            __FUNCTION__ , cxy , boot_get_proctime() );
     354#endif
     355
     356    // get pointer on ARCHINFO header  and on the four arch_info arrays
     357    header       = (archinfo_header_t*)ARCHINFO_BASE;
     358    core_base    = archinfo_get_core_base   (header);
     359    cluster_base = archinfo_get_cluster_base(header);
     360    device_base  = archinfo_get_device_base (header);
     361    irq_base     = archinfo_get_irq_base    (header);
    307362
    308363    // Initialize global platform parameters
     
    315370
    316371    // Initialize kernel segments
    317     boot_info->kernel_code_start = ktext_base;
    318     boot_info->kernel_code_end   = ktext_end;
    319     boot_info->kernel_data_start = kdata_base;
    320     boot_info->kernel_data_end   = kdata_end;
    321 
    322     // Initialize specific cluster parameter
    323     core_base    = archinfo_get_core_base   (header);
    324     cluster_base = archinfo_get_cluster_base(header);
    325     device_base  = archinfo_get_device_base (header);
    326     irq_base     = archinfo_get_irq_base    (header);
    327 
    328     // lopp on the clusters to find local cluster descriptor
     372    boot_info->kernel_code_start = seg_kcode_base;
     373    boot_info->kernel_code_end   = seg_kcode_base + seg_kcode_size;
     374    boot_info->kernel_data_start = seg_kdata_base;
     375    boot_info->kernel_data_end   = seg_kdata_base + seg_kdata_size;
     376
     377    // loop on arch_info clusters to get relevant pointers
    329378    for (cluster =  cluster_base;
    330379         cluster < &cluster_base[header->x_size * header->y_size];
    331380         cluster++)
    332381    {
    333         if (cluster->cxy != cxy) continue;
    334 
    335         boot_info->cxy          = cluster->cxy;
    336         boot_info->cores_nr     = cluster->cores;
    337         boot_info->devices_nr   = cluster->devices;
    338 
    339 #if DEBUG_BOOT_INFO
    340 boot_printf("\n[BOOT] build boot_info for cluster %x : %d cores / %d devices\n",
    341             cluster->cxy , cluster->cores , cluster->devices );
    342 #endif
    343         // Initialize array of core descriptors
    344         for (core = &core_base[cluster->core_offset], core_id = 0;
    345              core < &core_base[cluster->core_offset + cluster->cores];
    346              core++, core_id++)
     382        if( cluster->cxy  == cxy )            my_cluster = cluster;
     383        if( cluster->cxy  == header->io_cxy ) io_cluster = cluster;
     384    }
     385
     386    if( my_cluster == NULL )
     387    {
     388        boot_printf("\n[ERROR] in %s : cannot found cluster %x in arch_info\n",
     389                    __FUNCTION__ , cxy );
     390        boot_exit();
     391    }
     392
     393    if( io_cluster == NULL )
     394    {
     395        boot_printf("\n[ERROR] in %s : cannot found io_cluster %x in arch_info\n",
     396                    __FUNCTION__ , header->io_cxy );
     397        boot_exit();
     398    }
     399
     400    // loop on all arch-info peripherals in IO_cluster,
     401    // to initialize the boot_info array of external peripherals
     402
     403#if DEBUG_BOOT_INFO
     404boot_printf("\n[BOOT INFO] %s : External peripherals\n", __FUNCTION__ );
     405#endif
     406
     407    device_id = 0;
     408    for (device = &device_base[io_cluster->device_offset];
     409         device < &device_base[io_cluster->device_offset + io_cluster->devices];
     410         device++ )
     411    {
     412        // initialise one entry for each external peripheral
     413        if( (device->type != DEV_TYPE_RAM_SCL) &&
     414            (device->type != DEV_TYPE_ICU_XCU) &&
     415            (device->type != DEV_TYPE_MMC_TSR) &&
     416            (device->type != DEV_TYPE_DMA_SCL) )
    347417        {
    348             boot_info->core[core_id].gid = (gid_t)core->gid;
    349             boot_info->core[core_id].lid = (lid_t)core->lid;
    350             boot_info->core[core_id].cxy = (cxy_t)core->cxy;
    351 
    352 #if DEBUG_BOOT_INFO
    353 boot_printf("  - core %x : cxy = %x / lid = %d\n",
    354             core->gid , core->cxy , core->lid );
    355 #endif
    356 
     418            boot_dev = &boot_info->ext_dev[device_id];
     419
     420            boot_dev->type     = device->type;
     421            boot_dev->base     = device->base;
     422            boot_dev->size     = device->size;
     423            boot_dev->channels = device->channels;
     424            boot_dev->param0   = device->arg0;   
     425            boot_dev->param1   = device->arg1;   
     426            boot_dev->param2   = device->arg2;   
     427            boot_dev->param3   = device->arg3;   
     428            boot_dev->irqs     = device->irqs;   
     429
     430            device_id++;
    357431        }
    358432
    359         // Initialize array of device descriptors
    360         for (device = &device_base[cluster->device_offset], device_id = 0;
    361              device < &device_base[cluster->device_offset + cluster->devices];
    362              device++, device_id++)
    363         {
    364             boot_dev = &boot_info->dev[device_id];
    365 
    366             boot_dev->type       =         device->type;
    367             boot_dev->base       = (xptr_t)device->base;
    368             boot_dev->size       =         device->size;
    369             boot_dev->channels   =         device->channels;
    370             boot_dev->param0     =         device->arg0;   
    371             boot_dev->param1     =         device->arg1;   
    372             boot_dev->param2     =         device->arg2;   
    373             boot_dev->param3     =         device->arg3;   
    374             boot_dev->irqs       =         device->irqs;   
    375 
    376 #if DEBUG_BOOT_INFO
    377 boot_printf("  - device %s : base = %l / size = %d / channels = %d / irqs = %d\n",
     433#if DEBUG_BOOT_INFO
     434boot_printf("  - %s : base = %l / size = %l / channels = %d / irqs = %d\n",
    378435            device_type_str( device->type ) , device->base , device->size ,
    379436            device->channels , device->irqs );   
    380437#endif
    381 
    382             // Initialize information about physical memory in cluster
    383             if (device->type == DEV_TYPE_RAM)
    384             {
    385                 // Compute total number of physical memory pages in cluster
    386                 boot_info->pages_nr = device->size >> CONFIG_PPM_PAGE_SHIFT;
    387 
    388                 // Get the last address allocated for the kernel segments
    389                 uint32_t end = (ktext_end < kdata_end) ? kdata_end : ktext_end;
    390 
    391                 // Computing the number of pages allocated for the kernel.
    392                 if( (end & CONFIG_PPM_PAGE_MASK) == 0 )
    393                 {
    394                     boot_info->pages_offset = end >> CONFIG_PPM_PAGE_SHIFT;
    395                 }
    396                 else
    397                 {
    398                     boot_info->pages_offset = (end >> CONFIG_PPM_PAGE_SHIFT) + 1;
    399                 }
    400             }
    401            
    402             // Initialize array of irq descriptors for XCU
    403             if (device->type == DEV_TYPE_XCU)
    404             {
    405                 for (irq_id = 0; irq_id < CONFIG_MAX_HWIS_PER_ICU; irq_id++)
    406                 {
    407                     boot_dev->irq[irq_id].valid  = 0;
    408                 }
    409 
    410                 for (irq = &irq_base[device->irq_offset];
    411                      irq < &irq_base[device->irq_offset + device->irqs];
    412                      irq++)
    413                 {
    414                     boot_dev->irq[irq->port].valid    = 1;
    415                     boot_dev->irq[irq->port].dev_type = irq->dev_type;
    416                     boot_dev->irq[irq->port].channel  = irq->channel;
    417                     boot_dev->irq[irq->port].is_rx    = irq->is_rx;
     438   
     439        // Initialize array of irq descriptors for PIC
     440        if (device->type == DEV_TYPE_PIC_TSR)
     441        {
     442            for (irq_id = 0; irq_id < CONFIG_MAX_IRQS_PER_PIC; irq_id++)
     443            {
     444                boot_dev->irq[irq_id].valid  = 0;
     445            }
     446
     447            for (irq = &irq_base[device->irq_offset];
     448                 irq < &irq_base[device->irq_offset + device->irqs];
     449                 irq++)
     450            {
     451                boot_dev->irq[irq->port].valid    = 1;
     452                boot_dev->irq[irq->port].dev_type = irq->dev_type;
     453                boot_dev->irq[irq->port].channel  = irq->channel;
     454                boot_dev->irq[irq->port].is_rx    = irq->is_rx;
    418455
    419456#if DEBUG_BOOT_INFO
     
    421458            irq->port , device_type_str( irq->dev_type ) , irq->channel , irq->is_rx );
    422459#endif
    423 
    424                 }
    425             }
    426 
    427             // Initialize array of irq descriptors for PIC
    428             if (device->type == DEV_TYPE_PIC)
    429             {
    430                 for (irq_id = 0; irq_id < CONFIG_MAX_IRQS_PER_PIC; irq_id++)
    431                 {
    432                     boot_dev->irq[irq_id].valid  = 0;
    433                 }
    434 
    435                 for (irq = &irq_base[device->irq_offset];
    436                      irq < &irq_base[device->irq_offset + device->irqs];
    437                      irq++)
    438                 {
    439                     boot_dev->irq[irq->port].valid    = 1;
    440                     boot_dev->irq[irq->port].dev_type = irq->dev_type;
    441                     boot_dev->irq[irq->port].channel  = irq->channel;
    442                     boot_dev->irq[irq->port].is_rx    = irq->is_rx;
     460            }
     461        }
     462    }
     463
     464    // initialize number of external peripherals
     465    boot_info->ext_dev_nr = device_id;
     466
     467    // Initialize cluster specific resources
     468    boot_info->cxy  = my_cluster->cxy;
     469
     470#if DEBUG_BOOT_INFO
     471boot_printf("\n[BOOT INFO] %s : cores in cluster %x\n", __FUNCTION__ );
     472#endif
     473
     474    // Initialize array of core descriptors
     475    core_id = 0;
     476    for (core = &core_base[my_cluster->core_offset];
     477         core < &core_base[my_cluster->core_offset + my_cluster->cores];
     478         core++ )
     479    {
     480        boot_info->core[core_id].gid = (gid_t)core->gid;
     481        boot_info->core[core_id].lid = (lid_t)core->lid;
     482        boot_info->core[core_id].cxy = (cxy_t)core->cxy;
     483
     484#if DEBUG_BOOT_INFO
     485boot_printf("  - core_gid = %x : cxy = %x / lid = %d\n",
     486            core->gid , core->cxy , core->lid );
     487#endif
     488        core_id++;
     489    }
     490
     491    // Initialize number of cores in my_cluster
     492    boot_info->cores_nr = core_id;
     493
     494    // loop on all peripherals in my_cluster to initialise
     495    // boot_info array of internal peripherals in my_cluster
     496
     497#if DEBUG_BOOT_INFO
     498boot_printf("\n[BOOT INFO] %s : internal peripherals in cluster %x\n", __FUNCTION__ );
     499#endif
     500
     501    device_id = 0;
     502    for (device = &device_base[my_cluster->device_offset];
     503         device < &device_base[my_cluster->device_offset + my_cluster->devices];
     504         device++ )
     505    {
     506        // initialise one entry for each internal peripheral
     507        if( (device->type == DEV_TYPE_RAM_SCL) ||
     508            (device->type == DEV_TYPE_ICU_XCU) ||
     509            (device->type == DEV_TYPE_MMC_TSR) ||
     510            (device->type == DEV_TYPE_DMA_SCL) )
     511        {
     512            boot_dev = &boot_info->int_dev[device_id];
     513
     514            boot_dev->type     = device->type;
     515            boot_dev->base     = device->base;
     516            boot_dev->size     = device->size;
     517            boot_dev->channels = device->channels;
     518            boot_dev->param0   = device->arg0;   
     519            boot_dev->param1   = device->arg1;   
     520            boot_dev->param2   = device->arg2;   
     521            boot_dev->param3   = device->arg3;   
     522            boot_dev->irqs     = device->irqs;
     523   
     524            device_id++;
     525        }
     526
     527#if DEBUG_BOOT_INFO
     528boot_printf("  - %s : base = %l / size = %l / channels = %d / irqs = %d\n",
     529            device_type_str( device->type ) , device->base , device->size ,
     530            device->channels , device->irqs );   
     531#endif
     532
     533        // Initialize information about physical memory in cluster
     534        if (device->type == DEV_TYPE_RAM_SCL)
     535        {
     536            // Compute total number of physical memory pages in cluster
     537            boot_info->pages_nr = device->size >> CONFIG_PPM_PAGE_SHIFT;
     538
     539            // Get the last address allocated for the kernel segments
     540            uint32_t end;
     541            if( boot_info->kernel_code_end > boot_info->kernel_data_end )
     542            {
     543                end = boot_info->kernel_code_end;
     544            }
     545            else
     546            {
     547                end = boot_info->kernel_data_end;
     548            }
     549               
     550            // Compute the number of pages allocated for the kernel.
     551            if( (end & CONFIG_PPM_PAGE_MASK) == 0 )
     552            {
     553                boot_info->pages_offset = end >> CONFIG_PPM_PAGE_SHIFT;
     554            }
     555            else
     556            {
     557                boot_info->pages_offset = (end >> CONFIG_PPM_PAGE_SHIFT) + 1;
     558            }
     559
     560#if DEBUG_BOOT_INFO
     561boot_printf("    . physical memory : %x pages / first free page = %x\n",
     562            boot_info->pages_nr , boot_info->pages_offset );
     563#endif
     564        }
     565           
     566        // Initialize array of irq descriptors for XCU
     567        if (device->type == DEV_TYPE_ICU_XCU)
     568        {
     569            for (irq_id = 0; irq_id < CONFIG_MAX_HWIS_PER_ICU; irq_id++)
     570            {
     571                boot_dev->irq[irq_id].valid  = 0;
     572            }
     573
     574            for (irq = &irq_base[device->irq_offset];
     575                 irq < &irq_base[device->irq_offset + device->irqs];
     576                 irq++)
     577            {
     578                boot_dev->irq[irq->port].valid    = 1;
     579                boot_dev->irq[irq->port].dev_type = irq->dev_type;
     580                boot_dev->irq[irq->port].channel  = irq->channel;
     581                boot_dev->irq[irq->port].is_rx    = irq->is_rx;
    443582
    444583#if DEBUG_BOOT_INFO
     
    447586#endif
    448587
    449                 }
    450588            }
    451589        }
    452 
    453 #if DEBUG_BOOT_INFO
    454 boot_printf("  - ram : number of pages = %x / first free page = %x\n",
    455             boot_info->pages_nr , boot_info->pages_offset );
    456 #endif
    457 
    458     }
     590    }
     591
     592    // initialize number of internal peripherals in my_cluster
     593    boot_info->int_dev_nr = device_id;
     594
     595    // set boot_info signature
     596    boot_info->signature = BOOT_INFO_SIGNATURE;
     597
    459598} // boot_info_init()
    460599
    461 /****************************************************************************
    462  * This function is executed by all cores in order to check their           *
    463  * local boot_info_t structure.                                             *
    464  * @ boot_info  : pointer to local 'boot_info_t' structure to be checked.   *
    465  * @ lid        : core local identifier, index the core descriptor table.   *
    466  ****************************************************************************/
     600/***********************************************************************************
     601 * This function check the local boot_info_t structure for a given core.
     602 * @ boot_info  : pointer to local 'boot_info_t' structure to be checked.
     603 * @ lid        : core local identifier, index the core descriptor table.
     604 **********************************************************************************/
    467605static void boot_check_core( boot_info_t * boot_info,
    468606                             lid_t         lid)
     
    490628} // boot_check_core()
    491629
    492 /****************************************************************************
    493  * This function is called by the bscpu to activate all other CP0s.         *
     630/*********************************************************************************
     631 * This function is called by CP0 in cluster(0,0) to activate all other CP0s.
    494632 * It returns the number of CP0s actually activated.
    495  ****************************************************************************/
    496 static uint32_t boot_wake_cp0()
     633 ********************************************************************************/
     634static uint32_t boot_wake_all_cp0s()
    497635{
    498     archinfo_header_t*  header;         /* Pointer on ARCHINFO header.      */
    499     archinfo_cluster_t* cluster_base;   /* Pointer on ARCHINFO cluster
    500                                            base.                            */
    501     archinfo_cluster_t* cluster;        /* Iterator for waking CP0 loop.    */
    502     archinfo_device_t*  device_base;    /* Pointer on ARCHINFO peripheral
    503                                            device base.                     */
    504     archinfo_device_t*  device;         /* Iterator for finding XICU device
    505                                            loop.                            */
    506 
    507     uint32_t            cp0_nb = 0;     /* Number of CP0 woken up.          */
     636    archinfo_header_t*  header;         // Pointer on ARCHINFO header
     637    archinfo_cluster_t* cluster_base;   // Pointer on ARCHINFO clusters base
     638    archinfo_cluster_t* cluster;        // Iterator for loop on clusters
     639    archinfo_device_t*  device_base;    // Pointer on ARCHINFO devices base
     640    archinfo_device_t*  device;         // Iterator for loop on devices
     641    uint32_t            cp0_nb = 0;     // CP0s counter
    508642
    509643    header       = (archinfo_header_t*)ARCHINFO_BASE;
     
    528662            continue;
    529663
    530         // Look for the XICU device associated to the CP0 of this cluster
    531         // then send an WTI to it in order to wake it up.
     664        // search XICU device associated to CP0, and send a WTI to activate it
    532665        for (device = &device_base[cluster->device_offset];
    533666             device < &device_base[cluster->device_offset + cluster->devices];
    534667             device++)
    535668        {
    536             if (device->type == DEV_TYPE_XCU)
    537             {
     669            if (device->type == DEV_TYPE_ICU_XCU)
     670            {
     671
     672#if DEBUG_BOOT_WAKUP
     673boot_printf("\n[BOOT] core[%x][0] activated at cycle %d\n",
     674            cluster->cxy , boot_get_proctime );
     675#endif
     676
    538677                boot_remote_sw((xptr_t)device->base, (uint32_t)boot_entry);
    539678                cp0_nb++;
     
    545684} // boot_wake_cp0()
    546685
    547 /****************************************************************************
    548  * This function is called by all CP0 to activate all local CPi cores.      *
    549  * @ boot_info  : pointer to local 'boot_info_t' structure, used to find    *
    550  *                the XICU device associated with local CPi base addresses. *
    551  ****************************************************************************/
    552 static void boot_wake_local_cores(boot_info_t* boot_info)
     686/*********************************************************************************
     687 * This function is called by all CP0 to activate all local CPi cores.
     688 * @ boot_info  : pointer to local 'boot_info_t' structure, used to find
     689 *                the XICU device associated with local CPi base addresses.
     690 *********************************************************************************/
     691static void boot_wake_local_cores(boot_info_t * boot_info)
    553692{
    554     boot_device_t*  device;         // Iterator on devices
    555     unsigned int    core_id;        // Iterator on cores
     693    boot_device_t *  device;         // Iterator on devices
     694    unsigned int     core_id;        // Iterator on cores
    556695
    557696    // loop on devices to find XCU
    558     for (device = &boot_info->dev[0];
    559          device < &boot_info->dev[boot_info->devices_nr];
     697    for (device = &boot_info->int_dev[0];
     698         device < &boot_info->int_dev[boot_info->int_dev_nr];
    560699         device++)
    561700    {
    562         if (device->type == DEV_TYPE_XCU)
     701        if (device->type == DEV_TYPE_ICU_XCU)
    563702        {
    564703            // loop on cores
    565704            for (core_id = 1; core_id < boot_info->cores_nr; core_id++)
     705            {
     706
     707#if DEBUG_BOOT_WAKUP
     708boot_printf("\n[BOOT] core[%x][%d] activated at cycle %d\n",
     709             boot_info->cxy , core_id , boot_get_proctime() );
     710#endif
    566711                boot_remote_sw((xptr_t) (device->base + (core_id << 2)),
    567712                               (uint32_t)boot_entry);
     713            }
    568714        }
    569715    }
    570716} // boot_wake_local_cores()
    571717
    572 /****************************************************************************
    573  *                               API functions.                             *
    574  ****************************************************************************/
    575 
    576 /****************************************************************************
     718
     719/*********************************************************************************
    577720 * This main function of the boot-loader is called by the  boot_entry() 
    578721 * function, and executed by all cores.
    579722 * The arguments values are computed by the boot_entry code.
    580  * @ lid    : core local identifier in its cluster,
     723 * @ lid    : core local identifier,
    581724 * @ cxy    : cluster identifier,
    582  ****************************************************************************/
     725 *********************************************************************************/
    583726void boot_loader( lid_t lid,
    584727                  cxy_t cxy )
    585728{
    586     boot_info_t * boot_info;   // Pointer on local boot_info_t structure
    587     uint32_t     local_count;  // Number of cores expected in local barrier                                  */
     729    boot_info_t * boot_info;       // pointer on local boot_info_t structure
    588730
    589731    if (lid == 0)
    590732    {
    591         /**************************************
    592          * PHASE ONE: only bscpu executes it. *
    593          **************************************/
     733        /****************************************************
     734         * PHASE A : only CP0 in boot cluster executes it
     735         ***************************************************/
    594736        if (cxy == BOOT_CORE_CXY)
    595737        {
    596             boot_printf("\n[BOOT] Starting on core[%d] in cluster %x at cycle %d\n",
    597                         lid, cxy, boot_get_proctime());
     738            boot_printf("\n[BOOT] core[%x][%d] enters at cycle %d\n",
     739                        cxy , lid , boot_get_proctime() );
    598740
    599741            // Initialize IOC driver
    600742            if      (USE_IOC_BDV) boot_bdv_init();
    601743            else if (USE_IOC_HBA) boot_hba_init();
    602             /*
    603             else if (USE_IOC_SDC) boot_sdc_init();
    604             else if (USE_IOC_SPI) boot_spi_init();
    605             */
     744            // else if (USE_IOC_SDC) boot_sdc_init();
     745            // else if (USE_IOC_SPI) boot_spi_init();
    606746            else if (!USE_IOC_RDK)
    607747            {
    608                 boot_printf("\n[BOOT ERROR] boot_loader(): "
    609                             "No IOC driver\n"
    610                            );
     748                boot_printf("\n[BOOT ERROR] in %s : no IOC driver\n");
    611749                boot_exit();
    612750            }
    613751
    614             // Initialize simplified version of FAT32.
     752            // Initialize FAT32.
    615753            boot_fat32_init();
     754
     755            // Load the 'kernel.elf' file into memory from IOC, and set   
     756            // the global variables defining the kernel layout     
     757            boot_kernel_load();
     758
     759            boot_printf("\n[BOOT] core[%x][%d] loaded kernel at cycle %d\n",
     760                        cxy , lid , boot_get_proctime() );
    616761
    617762            // Load the arch_info.bin file into memory.
    618763            boot_archinfo_load();
    619764
    620             // Load the 'kernel.elf' file into memory.
    621             boot_kernel_load();
    622 
    623             // Get local 'boot_info_t' structure base address.
     765            // Get local boot_info_t structure base address.
    624766            // It is the first structure in the .kdata segment.
    625             boot_info = (boot_info_t*)(KERN_IMG_TMP_BASE + kdata_base);
    626 
    627             // Signature problem, abort program !!!
     767            boot_info = (boot_info_t *)seg_kdata_base;
     768
     769            // Initialize local boot_info_t structure.
     770            boot_info_init( boot_info , cxy );
     771
     772            // check boot_info signature
    628773            if (boot_info->signature != BOOT_INFO_SIGNATURE)
    629774            {
    630                 boot_printf("\n[BOOT] boot_loader(): "
    631                             "boot_info signature should be %x\n",
    632                             BOOT_INFO_SIGNATURE);
     775                boot_printf("\n[BOOT ERROR] in %s reported by core[%x][%d]\n"
     776                            "  illegal boot_info signature / should be %x\n",
     777                            __FUNCTION__ , cxy , lid , BOOT_INFO_SIGNATURE );
    633778                boot_exit();
    634779            }
    635780
    636             // Initialize local 'boot_info_t' structure.
    637             boot_printf("\n[BOOT] boot_loader(): "
    638                         "Initializing the local boot_info_t structure "
    639                         "at cycle %d\n",
    640                         boot_get_proctime());
    641 
    642             boot_info_init(boot_info, cxy);
     781            boot_printf("\n[BOOT] core[%x][%d] loaded boot_info at cycle %d\n",
     782                        cxy , lid , boot_get_proctime() );
    643783
    644784            // Check core information.
    645785            boot_check_core(boot_info, lid);
    646786
    647             // Set the barrier.
    648             boot_cluster_ready = 0;
    649 
    650             // Activate other CP0s
    651             boot_printf("\n[BOOT] boot_loader(): "
    652                         "Waking other CP0 up at cycle %d\n",
    653                         boot_get_proctime());
    654 
    655             global_count = boot_wake_cp0();
    656 
    657             // Wait until all CP0s ready to enter kernel.
    658             boot_printf("\n[BOOT] boot_loader(): "
    659                         "Waiting for other %d CP0 at cycle %d\n",
    660                         global_count, boot_get_proctime());
    661 
    662             boot_barrier(XPTR(BOOT_CORE_CXY, &global_barrier),
    663                          global_count);
    664 
    665             // activate other local cores of the boot cluster.
    666             local_barrier = 0;
    667             boot_printf("\n[BOOT] boot_loader(): "
    668                         "Waking other CPi up at cycle %d\n",
    669                         boot_get_proctime());
    670 
    671             boot_wake_local_cores(boot_info);
    672 
    673             // Wait until all other local cores are ready
    674             boot_printf("\n[BOOT] boot_loader(): "
    675                         "Waiting for other %d CPi at cycle %d\n",
    676                         boot_info->cores_nr - 1, boot_get_proctime());
    677 
    678             local_count = boot_info->cores_nr - 1;
    679             while (local_barrier != local_count);
    680 
    681             // Move the local kernel image at address 0x0 (erase preloader code).
    682             boot_printf("\n[BOOT] boot_loader(): "
    683                         "Moving the kernel image and erasing the preloader"
    684                         "at cycle %d\n",
    685                         boot_get_proctime());
    686 
    687             // ktext segment.
    688             boot_memcpy((void*)ktext_base,
    689                         (void*)(KERN_IMG_TMP_BASE + ktext_base),
    690                         ktext_end - ktext_base);
    691 
    692             // kdata segment.
    693             boot_memcpy((void*)kdata_base,
    694                         (void*)(KERN_IMG_TMP_BASE + kdata_base),
    695                         kdata_end - kdata_base);
    696            
    697             // activate other local cores.
    698             boot_cluster_ready = 1;
    699             boot_printf("\n[BOOT] boot_loader(): "
    700                         "Everything is set, jumping to the kernel "
    701                         "at cycle %d\n",
    702                         boot_get_proctime());
     787            // Activate other CP0s / get number of active CP0s
     788            active_cp0s_nr = boot_wake_all_cp0s() + 1;
     789
     790            // Wait until all clusters (i.e all CP0s) ready to enter kernel.
     791            boot_remote_barrier( XPTR( BOOT_CORE_CXY , &global_barrier ) ,
     792                                 active_cp0s_nr );
     793
     794            // activate other local cores
     795            boot_wake_local_cores( boot_info );
     796
     797            // Wait until all local cores in cluster ready
     798            boot_remote_barrier( XPTR( cxy , &local_barrier ) ,
     799                                 boot_info->cores_nr );
    703800        }
    704         /****************************************************
    705          * PHASE TWO: all CP0s other than bscpu execute it. *
    706          ****************************************************/
     801        /******************************************************************
     802         * PHASE B : all CP0s other than CP0 in boot cluster execute it
     803         *****************************************************************/
    707804        else
    708805        {
    709             /*
    710              * Note: at this point, we cannot access the global variables of
    711              * this boot code since all the address extension registers for
    712              * DATA are pointing to their local cluster in order to have
    713              * access to the local stack and execute this C code.
    714              * However, all the address extension registers for INSTRUCTIONS
    715              * are still pointing to the boot cluster, thus we can access
    716              * and call functions defined in the boot code, for example
    717              * boot_remote_memcpy().
    718              */
    719 
    720             // Copy the boot-loader binary code 'boot.elf' into the local memory
    721             boot_remote_memcpy(XPTR(cxy,           BOOT_BASE),
    722                                XPTR(BOOT_CORE_CXY, BOOT_BASE),
    723                                (unsigned int)BOOT_MAX_SIZE);
    724 
    725             /*
    726              * Note: from now on, it is safe to refer to the boot code global variables
    727              * such as the base address and size of the kernel segments.
    728              */
    729 
    730             // switch to the INSTRUCTION local memory space, 
    731             // to avoid contention at the boot cluster.
     806            // at this point, all INSTRUCTION address extension registers
     807            // point on cluster(0,0), but the DATA extension registers point
     808            // already on the local cluster to use the local stack.
     809            // To access the bootloader global variables we must first copy
     810            // the boot code (data and instructions) in the local cluster.
     811            boot_remote_memcpy( XPTR( cxy           , BOOT_BASE ),
     812                                XPTR( BOOT_CORE_CXY , BOOT_BASE ),
     813                                BOOT_MAX_SIZE );
     814
     815            // from now, it is safe to refer to the boot code global variables
     816            boot_printf("\n[BOOT] core[%x][%d] replicated boot code at cycle %d\n",
     817                        cxy , lid , boot_get_proctime() );
     818
     819            // switch to the INSTRUCTION local memory space, to avoid contention.
    732820            asm volatile("mtc2  %0, $25" :: "r"(cxy));
    733821
    734             // Copy the 'arch_info.bin' file into the local memory.
     822            // Copy the arch_info.bin file into the local memory.
    735823            boot_remote_memcpy(XPTR(cxy,           ARCHINFO_BASE),
    736824                               XPTR(BOOT_CORE_CXY, ARCHINFO_BASE),
    737                                (unsigned int)ARCHINFO_MAX_SIZE);
    738 
    739             // Copy the kernel image into local memory at address 0x0.
    740             // ktext segment.
    741             boot_remote_memcpy(XPTR(cxy, ktext_base),
    742                                XPTR(BOOT_CORE_CXY, KERN_IMG_TMP_BASE + ktext_base),
    743                                ktext_end - ktext_base);
    744             // kdata segment.
    745             boot_remote_memcpy(XPTR(cxy, kdata_base),
    746                                XPTR(BOOT_CORE_CXY, KERN_IMG_TMP_BASE + kdata_base),
    747                                kdata_end - kdata_base);
    748 
    749             // Get local 'boot_info_t' structure base address.
    750             // This is the first structure in the kdata segment.
    751             boot_info = (boot_info_t*)kdata_base;
     825                               ARCHINFO_MAX_SIZE );
     826
     827            boot_printf("\n[BOOT] core[%x][%d] replicated arch_info at cycle %d\n",
     828                        cxy , lid , boot_get_proctime() );
     829
     830            // Copy the kcode segment into local memory
     831            boot_remote_memcpy( XPTR( cxy           , seg_kcode_base ),
     832                                XPTR( BOOT_CORE_CXY , seg_kcode_base ),
     833                                seg_kcode_size );
     834
     835            // Copy the kdata segment into local memory
     836            boot_remote_memcpy( XPTR( cxy           , seg_kdata_base ),
     837                                XPTR( BOOT_CORE_CXY , seg_kdata_base ),
     838                                seg_kdata_size );
     839
     840            boot_printf("\n[BOOT] core[%x][%d] replicated kernel code at cycle %d\n",
     841                        cxy , lid , boot_get_proctime() );
     842
     843            // Get local boot_info_t structure base address.
     844            boot_info = (boot_info_t*)seg_kdata_base;
    752845
    753846            // Initialize local boot_info_t structure.
    754             boot_info_init(boot_info, cxy);
     847            boot_info_init( boot_info , cxy );
    755848
    756849            // Check core information.
    757             boot_check_core(boot_info, lid);
    758 
    759             // Activateall other local CPi cores in this cluster.
    760             local_barrier = 0;
    761             boot_wake_local_cores(boot_info);
    762 
    763             // Waiting until all other local cores ready
    764             local_count = boot_info->cores_nr - 1;
    765             while (local_barrier != local_count);
    766 
    767             // All cores in this cluster are ready to enter kernel.
    768             boot_barrier(XPTR(BOOT_CORE_CXY, &global_barrier),
    769                          global_count);
     850            boot_check_core( boot_info , lid );
     851
     852            // get number of active clusters from BOOT_CORE cluster
     853            uint32_t count = boot_remote_lw( XPTR( BOOT_CORE_CXY , &active_cp0s_nr ) );
     854
     855            // Wait until all clusters (i.e all CP0s) ready to enter kernel
     856            boot_remote_barrier( XPTR( BOOT_CORE_CXY , &global_barrier ) , count );
     857
     858            // activate other local cores
     859            boot_wake_local_cores( boot_info );
     860
     861            // Wait until all local cores in cluster ready
     862            boot_remote_barrier( XPTR( cxy , &local_barrier ) ,
     863                                 boot_info->cores_nr );
    770864        }
    771865    }
     
    773867    {
    774868        /***************************************************************
    775          * PHASE THREE: all non CP0 cores in all clusters execute it.  *
     869         * PHASE C: all non CP0 cores in all clusters execute it
    776870         **************************************************************/
    777871
    778         if (cxy == BOOT_CORE_CXY)  // boot cluster only
    779         {
    780             // Report to the local CP0 that CPi is ready
    781             boot_atomic_add((int32_t*)&local_barrier, 1);
    782 
    783             // wait completion of kernel image move in  boot cluster
    784             while (boot_cluster_ready != 1);
    785 
    786             // Check core information
    787             boot_info = (boot_info_t*)kdata_base;
    788             boot_check_core(boot_info, lid);
    789         }
    790         else                      // other clusters
    791         {
    792             // Switch to the INSTRUCTIONS local memory space
    793             // to avoid contention at the boot cluster.
    794             asm volatile("mtc2  %0, $25" :: "r"(cxy));
    795 
    796             // Report to the local CP0 that CPi is ready
    797             boot_atomic_add((int32_t*)&local_barrier, 1);
    798 
    799             // Check core information
    800             boot_info = (boot_info_t*)kdata_base;
    801             boot_check_core(boot_info, lid);
    802         }
    803     }
    804 
    805     // Jump to the kernel code.
    806     asm volatile("jr   %0" :: "r"(kernel_entry));
     872        // Switch to the INSTRUCTIONS local memory space
     873        // to avoid contention at the boot cluster.
     874        asm volatile("mtc2  %0, $25" :: "r"(cxy));
     875
     876        // Get local boot_info_t structure base address.
     877        boot_info = (boot_info_t *)seg_kdata_base;
     878
     879        // Check core information
     880        boot_check_core(boot_info, lid);
     881
     882        // Wait until all local cores in cluster ready
     883        boot_remote_barrier( XPTR( cxy , &local_barrier ) , boot_info->cores_nr );
     884    }
     885
     886    // Each core compute address of a temporary kernel stack
     887    // in the upper part of the local cluster memory...
     888    uint32_t stack_ptr = ((boot_info->pages_nr - lid) << 12) - 16;
     889
     890    // All cores initialise stack pointer,
     891    // reset the BEV bit in status register,
     892    // register "boot_info" argument in a0,
     893    // and jump to kernel_entry.
     894    asm volatile( "mfc0  $27,  $12           \n"
     895                  "lui   $26,  0xFFBF        \n"
     896                  "ori   $26,  $26,  0xFFFF  \n"
     897                  "and   $27,  $27,  $26     \n"
     898                  "mtc0  $27,  $12           \n"
     899                  "move  $4,   %0            \n"
     900                  "move  $29,  %1            \n"
     901                  "jr    %2                  \n"
     902                  :: "r"(boot_info) , "r"(stack_ptr) , "r"(kernel_entry) );
    807903
    808904} // boot_loader()
Note: See TracChangeset for help on using the changeset viewer.