Ignore:
Timestamp:
Mar 12, 2019, 1:37:38 PM (3 years ago)
Author:
alain
Message:

Fix several bugs to use the instruction MMU in kernel mode
in replacement of the instruction address extension register,
and remove the "kentry" segment.

This version is running on the tsar_generic_iob" platform.

One interesting bug: the cp0_ebase defining the kernel entry point
(for interrupts, exceptions and syscalls) must be initialized
early in kernel_init(), because the VFS initialisation done by
kernel_ini() uses RPCs, and RPCs uses Inter-Processor-Interrup.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/boot/tsar_mips32/boot.c

    r623 r624  
    2525/****************************************************************************
    2626 * This file contains the ALMOS-MKH. boot-loader for the TSAR architecture. *
    27  *                                                                          *
    28  * It supports a clusterised, shared memory, multi-processor architecture,  *
     27 * that is a clusterised, shared memory, multi-processor architecture,      *
    2928 * where each processor core is identified by a composite index [cxy,lid]   *
    3029 * with one physical memory bank per cluster.                               *
     
    8685// the Boot Page Table contains two PTE1, and should be aligned on 8 Kbytes
    8786
    88 uint32_t                        boot_pt[2] __attribute__((aligned(2048)));
     87uint32_t                        boot_pt[2] __attribute__((aligned(0x2000)));
    8988
    9089// synchronization variables.
     
    101100uint32_t                        seg_kdata_base;   // kdata segment base address
    102101uint32_t                        seg_kdata_size;   // kdata segment size (bytes)
    103 uint32_t                        seg_kentry_base;  // kcode segment base address
    104 uint32_t                        seg_kentry_size;  // kcode segment size (bytes)
    105 
    106 uint32_t                        kernel_entry;    // kernel entry point
     102
     103uint32_t                        kernel_entry;     // kernel_init() function
    107104
    108105// Functions
     
    147144static void boot_archinfo_load( void )
    148145{
    149     archinfo_header_t* header = (archinfo_header_t*)ARCHINFO_BASE; 
     146    archinfo_header_t * header = (archinfo_header_t*)ARCHINFO_BASE; 
    150147   
    151148    // Load file into memory
    152149    if (boot_fat32_load(ARCHINFO_PATHNAME, ARCHINFO_BASE, ARCHINFO_MAX_SIZE))
    153150    {
    154         boot_printf("\n[BOOT ERROR]: boot_archinfo_load(): "
    155         "<%s> file not found\n",
    156         ARCHINFO_PATHNAME);
     151        boot_printf("\n[BOOT ERROR]in %s : <%s> file not found\n",
     152        __FUNCTION__, ARCHINFO_PATHNAME);
    157153        boot_exit();
    158154    }
     
    175171/**************************************************************************************
    176172 * This function loads the 'kernel.elf' file into the boot cluster memory buffer,
    177  * analyzes it, and places the three kcode, kentry, kdata segments at their final
    178  * physical adresses (defined the .elf file).       
    179  * It set the global variables defining the kernel layout.
     173 * analyzes it, and places the kcode and kdata segments at their final physical
     174 * adresses (defined the .elf file), and set the kernel layout global variables.
    180175 *************************************************************************************/
    181176static void boot_kernel_load( void )
     
    192187    bool_t       kcode_found;     // kcode segment found.
    193188    bool_t       kdata_found;     // kdata segment found.
    194     bool_t       kentry_found;    // kentry segment found.
    195189    uint32_t     seg_id;          // iterator for segments loop.
    196190
     
    233227    kcode_found  = false;
    234228    kdata_found  = false;
    235     kentry_found = false;
    236229    for (seg_id = 0; seg_id < segments_nb; seg_id++)
    237230    {
     
    265258
    266259            // Note: we suppose that the 'kernel.elf' file contains exactly
    267             // three loadable segments ktext, kentry, & kdata:
    268             // - the kcode segment is read-only and base == KCODE_BASE
    269             // - the kentry segment is read-only and base == KENTRY_BASE
    270 
    271             if( ((program_header[seg_id].p_flags & PF_W) == 0) &&
    272                  (program_header[seg_id].p_paddr == KCODE_BASE) )     // kcode segment
     260            // two loadable segments : kcode & kdata
     261
     262            if( program_header[seg_id].p_paddr == KCODE_BASE )     // kcode segment
    273263            {
    274264                if( kcode_found )
     
    283273                seg_kcode_base = seg_paddr;
    284274                seg_kcode_size = seg_memsz;
    285             }
    286             else if( program_header[seg_id].p_paddr == KENTRY_BASE ) // kentry segment
    287             {
    288                 if( kentry_found )
    289                 {
    290                     boot_printf("\n[BOOT_ERROR] in %s for file %s :\n"
    291                     "   two kentry segments found\n",
    292                     __FUNCTION__ , KERNEL_PATHNAME );
    293                     boot_exit();
    294                 }
    295 
    296                 kentry_found     = true;
    297                 seg_kentry_base = seg_paddr;
    298                 seg_kentry_size = seg_memsz;
    299275            }
    300276            else                                                    // kdata segment
     
    322298        boot_exit();
    323299    }
    324     if( kentry_found == false )
    325     {
    326         boot_printf("\n[BOOT_ERROR] in %s for file %s : seg_kentry not found\n",
    327         __FUNCTION__ , KERNEL_PATHNAME );
    328         boot_exit();
    329     }
    330300    if( kdata_found == false )
    331301    {
     
    336306
    337307    // check segments sizes
    338     if( seg_kentry_size > KENTRY_MAX_SIZE )
    339     {
    340         boot_printf("\n[BOOT_ERROR] in %s for file %s : seg_kentry too large\n",
    341         __FUNCTION__ , KERNEL_PATHNAME );
    342         boot_exit();
    343     }
    344 
    345308    if( (seg_kcode_size + seg_kdata_size) > KCODE_MAX_SIZE )
    346309    {
     
    386349    boot_device_t      * boot_dev;
    387350
    388     // get pointer on ARCHINFO header  and on the four arch_info arrays
     351 #if DEBUG_BOOT_INFO
     352boot_printf("\n[BOOT INFO] %s : enter at cycle %d\n",
     353__FUNCTION__ , boot_get_proctime() );
     354#endif
     355
     356   // get pointer on ARCHINFO header  and on the four arch_info arrays
    389357    header       = (archinfo_header_t*)ARCHINFO_BASE;
    390358    core_base    = archinfo_get_core_base   (header);
     
    406374    boot_info->kdata_base  = seg_kdata_base;
    407375    boot_info->kdata_size  = seg_kdata_size;
    408     boot_info->kentry_base = seg_kentry_base;
    409     boot_info->kentry_size = seg_kentry_size;
    410376
    411377    // loop on arch_info clusters to build cluster_info[][] array
     
    806772        if (cxy == 0)
    807773        {
    808             boot_printf("\n[BOOT] core[%x,%d] enters at cycle %d\n",
    809                         cxy , lid , boot_get_proctime() );
     774            boot_printf("\n[BOOT] core[%x,%d] active at cycle %d\n",
     775            cxy, lid, boot_get_proctime() );
    810776
    811777            // Initialize IOC driver
     
    858824            boot_check_core(boot_info, lid);
    859825
    860 // TO BE DONE
    861 // core[0][0] identity maps two big pages for the boot and kernel code,
    862 // boot_page_table_init( 0 );
    863 
    864 // TO BE DONE
    865 // core[0][0] activates the instruction MMU to use the local copy of boot code
    866 // boot_activate_ins_mmu( 0 );
     826            // identity maps two big pages for the boot and kernel code,
     827            boot_page_table_init( 0 );
     828
     829            // activate the instruction MMU to use the local copy of boot code
     830            boot_activate_ins_mmu( 0 );
    867831
    868832            // Activate other core[cxy][0] / get number of activated cores
     
    889853            // but all cores must access the code stored in cluster 0
    890854
    891             // Each CP0 copies the boot code (data and instructions)
     855#if DEBUG_BOOT_MULTI
     856boot_printf("\n[BOOT] core[%x,%d] active at cycle %d\n",
     857cxy, lid, boot_get_proctime() );
     858#endif
     859            // Each core[cxy][0] copies the boot code (data and instructions)
    892860            // from the cluster 0 to the local cluster.
    893861            boot_remote_memcpy( XPTR( cxy           , BOOT_BASE ),
     
    899867            cxy , lid , boot_get_proctime() );
    900868
    901 // TO BE DONE
    902 // Each core identity maps two big pages for the boot and kernel code,
    903 // boot_page_table_init( cxy );
    904 
    905 // Each core activates the instruction MMU to use the local copy of boot code
    906 // boot_activate_ins_mmu( cxy );
     869            // identity maps two big pages for the boot and kernel code,
     870            boot_page_table_init( cxy );
     871
     872            // activate the instruction MMU to use the local copy of boot code
     873            boot_activate_ins_mmu( cxy );
    907874
    908875            // Each CP0 copies the arch_info.bin into the local memory.
     
    914881            cxy , lid , boot_get_proctime() );
    915882
    916             // Each CP0 copies the kcode segment into local memory
     883            // copy the kcode segment into local memory
    917884            boot_remote_memcpy( XPTR( cxy           , seg_kcode_base ),
    918885                                XPTR( BOOT_CORE_CXY , seg_kcode_base ),
     
    924891                                seg_kdata_size );
    925892
    926             // [TO BE REMOVED<D-°>
    927             // Each CP0 copies the kentry segment into local memory
    928             boot_remote_memcpy( XPTR( cxy           , seg_kentry_base ),
    929                                 XPTR( BOOT_CORE_CXY , seg_kentry_base ),
    930                                 seg_kentry_size );
    931 
    932893            boot_printf("\n[BOOT] core[%x,%d] replicated kernel code at cycle %d\n",
    933894            cxy , lid , boot_get_proctime() );
     
    965926         **********************************************************************/
    966927
    967 // TO BE DONE
    968 // each core activate the instruction MMU to use the local copy of the boot code
    969 // boot_activate_ins_mmu( cxy );
     928#if DEBUG_BOOT_MULTI
     929boot_printf("\n[BOOT] core[%x,%d] active at cycle %d\n",
     930cxy, lid, boot_get_proctime() );
     931#endif
     932        // activate the instruction MMU to use the local copy of the boot code
     933        boot_activate_ins_mmu( cxy );
    970934
    971935        // Get local boot_info_t structure base address.
     
    979943    }
    980944
    981     // the "kernel_entry" global variable, set by boot_kernel_load() define
    982     // the adress of the kernel_init() function.
     945    // All cores enter the kernel_init() function. The address is contained in
     946    // the "kernel_entry" global variable, set by boot_kernel_load() function.
    983947    // Each core initialise the following registers before jumping to kernel:
    984948    // - gr_29    : stack pointer / kernel stack allocated in idle thread descriptor,
    985949    // - c0_sr    : status register / reset BEV bit
    986950    // - gr_04    : kernel_init() argument / pointer on boot_info structure
    987     // - c0_ebase : kentry_base
    988 
    989     // compute "sp" from base address of idle thread descriptors array and lid.
    990951    // The array of idle-thread descriptors is allocated in the kdata segment,
    991952    // just after the boot_info structure.
     953
     954#if DEBUG_BOOT_MULTI
     955boot_printf("\n[BOOT] core[%x,%d] jump to kernel_init = %x at cycle %d\n",
     956cxy, lid, __FUNCTION__, kernel_entry, boot_get_proctime() );
     957#endif
     958
    992959    uint32_t base;
    993960    uint32_t offset = sizeof( boot_info_t );
     
    998965    uint32_t sp = base + ((lid + 1) * CONFIG_THREAD_DESC_SIZE) - 16;
    999966
    1000     // get "ebase" from kerneL_info
    1001     uint32_t ebase = boot_info->kentry_base;
    1002 
    1003 // TO BE DONE
    1004 // The cp0_ebase will not be set by the assenbly code below
    1005 // when the kentry segment will be removed => done in kernel init
    1006 
    1007967    asm volatile( "mfc0  $27,  $12           \n"
    1008968                  "lui   $26,  0xFFBF        \n"
     
    1012972                  "move  $4,   %0            \n"
    1013973                  "move  $29,  %1            \n"
    1014                   "mtc0  %2,   $15,  1       \n"
    1015                   "jr    %3                  \n"
     974                  "jr    %2                  \n"
    1016975                  :
    1017976                  : "r"(boot_info) ,
    1018977                    "r"(sp) ,
    1019                     "r"(ebase) ,
    1020978                    "r"(kernel_entry)
    1021979                  : "$26" , "$27" , "$29" , "$4" );
Note: See TracChangeset for help on using the changeset viewer.