Ignore:
Timestamp:
Mar 6, 2019, 4:37:15 PM (5 years ago)
Author:
alain
Message:

Introduce three new types of vsegs (KCODE,KDATA,KDEV)
to map the kernel vsegs in the process VSL and GPT.
This now used by both the TSAR and the I86 architectures.

File:
1 edited

Legend:

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

    r578 r623  
    33 *
    44 * Authors :   Vu Son  (2016)
    5  *             Alain Greiner (2016, 2017,2018)
     5 *             Alain Greiner (2016,2017,2018,2019)
    66 *
    77 * Copyright (c) UPMC Sorbonne Universites
     
    2626 * This file contains the ALMOS-MKH. boot-loader for the TSAR architecture. *
    2727 *                                                                          *
    28  * It supports clusterised shared memory multi-processor architectures,     *
     28 * It supports a clusterised, shared memory, multi-processor architecture,  *
    2929 * where each processor core is identified by a composite index [cxy,lid]   *
    3030 * with one physical memory bank per cluster.                               *
    3131 *                                                                          *
    3232 * The 'boot.elf' file (containing the boot-loader binary code) is stored   *
    33  * on disk and is loaded into memory by core[0,0] (cxy = 0 / lid = 0),      *
    34  * and is copied in each other cluter by the local CP0 (lid = 0].           *
     33 * on disk (not in the FAT file system), and must be loaded into memory by  *
     34 * the preloader running on the core[0][0] (cxy = 0 / lid = 0).             *
    3535 *                                                                          *
    36  * 1) The boot-loader first phase is executed by core[0,0], while           *
    37  *    all other cores are waiting in the preloader.                         *
    38  *    It does the following tasks:                                          *
    39  *      - load into the memory bank of cluster 0 the 'arch_info.bin'        *
    40  *        file (containing the hardware architecture description) and the   *
    41  *        'kernel.elf' file, at temporary locations,                        *   
    42  *      - initializes the 'boot_info_t' structure in cluster(0,0)           *
    43  *        (there is 1 'boot_info_t' per cluster), which contains both       *
    44  *        global and cluster specific information that will be used for     *
    45  *        kernel initialisation.                                            *
    46  *      - activate CP0s in all other clusters, using IPIs.                  *
    47  *      - wait completion reports from CP0s on a global barrier.            *
     36 * The main task of the boot-loader is to load in the first physical page   *
     37 * of each cluster a copy of the kernel code (segments "kcode" and "kdata") *
     38 * and to build - in each cluster - a cluster specific description of the   *
     39 * hardware archtecture, stored in the "kdata" segment as the boot_info_t   *
     40 * structure. The "kernel.elf" and "arch_info.bin" files are supposed to be *
     41 * stored on disk in a FAT32 file system.                                   *
    4842 *                                                                          *
    49  * 2) The boot-loader second phase is then executed in parallel by all      *
    50  *    CP0s (other than core[0,0]). Each CP0 performs the following tasks:   *
    51  *      - copies into the memory bank of the local cluster the 'boot.elf',  *
    52  *        the 'arch_info.bin' (at the same addresses as the 'boot.elf' and  *
    53  *        the 'arch_info.bin' in the memory bank of the cluster(0,0), and   *
    54  *        the kernel image (at address 0x0),                                *
    55  *      - initializes the 'boot_info_t' structure of the local cluster,     *
    56  *      - activate all other cores in the same cluster (CPi).               *
    57  *      - wait local CPi completion reports on a local barrier.             *
    58  *      - report completion  on the global barrier.                         *
     43 * All cores contribute to the boot procedure, but all cores are not        *
     44 * simultaneously active:                                                   *
     45 * - in a first phase, only core[0][0] is running (core 0 in cluster 0).    *
     46 * - in a second phase, only core[cxy][0] is running in each cluster.       *
     47 * - in last phase, all core[cxy][lid] are running.                         *
    5948 *                                                                          *
    60  * 3) The boot-loader third phase is executed in parallel by all cores.     *
    61  *    In each cluster (i) the CP0                                           *
    62  *      - activates the other cores of cluster(i),                          *
    63  *      - blocks on the local barrier waiting for all local CPi to report   *
    64  *        completion on the local barrier,                                  *
    65  *      - moves the local kernel image from the temporary location to the   *
    66  *        address 0x0, (erasing the preloader code).                        *
     49 * Finally, all cores jump to the kernel_init() function that makes the     *                 
     50 * actual kernel initialisation.                                            *
    6751 *                                                                          *
    68  * 4) All cores jump to kern_init() (maybe not at the same time).           *
     52 * Implementation note:                                                     *                      *                                                                          *
     53 * To allows each core to use the local copy of both the boot code and the  *
     54 * kernel code, the boot-loader builds a minimal and temporary BPT (Boot    *
     55 * Page Table) containing only two big pages: page[0] maps the kernel code, *
     56 * and page 1 maps the boot code.                                           *
    6957 ****************************************************************************/
    7058
     
    9684 ****************************************************************************/
    9785
     86// the Boot Page Table contains two PTE1, and should be aligned on 8 Kbytes
     87
     88uint32_t                        boot_pt[2] __attribute__((aligned(2048)));
     89
    9890// synchronization variables.
    9991
    100 volatile boot_remote_spinlock_t tty0_lock;       // protect TTY0 access
    101 volatile boot_remote_barrier_t  global_barrier;  // synchronize CP0 cores
    102 volatile boot_remote_barrier_t  local_barrier;   // synchronize cores in one cluster
    103 uint32_t                        active_cp0s_nr;  // number of expected CP0s
     92volatile boot_remote_spinlock_t tty0_lock;        // protect TTY0 access
     93volatile boot_remote_barrier_t  global_barrier;   // synchronize CP0 cores
     94volatile boot_remote_barrier_t  local_barrier;    // synchronize cores in one cluster
     95uint32_t                        active_cores_nr;  // number of expected CP0s
    10496 
    10597// kernel segments layout variables
     
    114106uint32_t                        kernel_entry;    // kernel entry point
    115107
    116 // Functions called by boot_entry.S
     108// Functions
    117109
    118110extern void boot_entry( void );    // boot_loader entry point
     
    738730
    739731/*********************************************************************************
    740  * This function is called by all CP0 to activate the other CPi cores.
     732 * This function is called by all CP0s to activate the other CPi cores.
    741733 * @ boot_info  : pointer to local 'boot_info_t' structure.
    742734 *********************************************************************************/
     
    761753} // boot_wake_local_cores()
    762754
     755/*********************************************************************************
     756 * This function is called by all core[cxy][0] to initialize the Boot Page Table:
     757 * map two local big pages for the boot code and kernel code.
     758 * @ cxy    : local cluster identifier.
     759 *********************************************************************************/
     760void boot_page_table_init( cxy_t  cxy )
     761{
     762    // set PTE1 in slot[0] for kernel code
     763    uint32_t kernel_attr  = 0x8A800000;                   // flagss : V,C,X,G
     764    uint32_t kernel_ppn1  = (cxy << 20) >> 9;             // big physical page index == 0
     765    boot_pt[0]            = kernel_attr | kernel_ppn1;
     766
     767    // set PTE1 in slot[1] for boot code (no global flag)
     768    uint32_t boot_attr    = 0x8A000000;                   // flags : V,C,X
     769    uint32_t boot_ppn1    = ((cxy << 20) + 512) >> 9;     // big physical page index == 1
     770    boot_pt[1]            = boot_attr | boot_ppn1;
     771}
     772
     773/*********************************************************************************
     774 * This function is called by all cores to activate the instruction MMU,
     775 * and use the local copy of boot code.
     776 *********************************************************************************/
     777void boot_activate_ins_mmu( cxy_t cxy )
     778{
     779    // set mmu_ptpr register
     780    uint32_t ptpr = ((uint32_t)boot_pt >> 13) | (cxy << 19);
     781    asm volatile ( "mtc2   %0,   $0         \n" : : "r" (ptpr) );
     782
     783    // set ITLB bit in mmu_mode
     784    asm volatile ( "mfc2   $26,  $1         \n"
     785                   "ori    $26,  $26,  0x8  \n"
     786                   "mtc2   $26,  $1         \n" );
     787}
    763788
    764789/*********************************************************************************
     
    776801    if (lid == 0)
    777802    {
    778         /****************************************************
    779          * PHASE A : only CP0 in boot cluster executes it
    780          ***************************************************/
    781         if (cxy == BOOT_CORE_CXY)
     803        /************************************i**********************
     804         * PHASE Sequencial : only core[0][0] executes it
     805         **********************************************************/
     806        if (cxy == 0)
    782807        {
    783808            boot_printf("\n[BOOT] core[%x,%d] enters at cycle %d\n",
     
    833858            boot_check_core(boot_info, lid);
    834859
    835             // Activate other CP0s / get number of active CP0s
    836             active_cp0s_nr = boot_wake_all_cp0s() + 1;
     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 );
     867
     868            // Activate other core[cxy][0] / get number of activated cores
     869            active_cores_nr = boot_wake_all_cp0s() + 1;
    837870
    838871            // Wait until all clusters (i.e all CP0s) ready to enter kernel.
    839872            boot_remote_barrier( XPTR( BOOT_CORE_CXY , &global_barrier ) ,
    840                                  active_cp0s_nr );
     873                                 active_cores_nr );
    841874
    842875            // activate other local cores
    843876            boot_wake_local_cores( boot_info );
    844 
    845 // display address extensions
    846 // uint32_t cp2_data_ext;
    847 // uint32_t cp2_ins_ext;
    848 // asm volatile( "mfc2   %0,  $24" : "=&r" (cp2_data_ext) );
    849 // asm volatile( "mfc2   %0,  $25" : "=&r" (cp2_ins_ext) );
    850 // boot_printf("\n[BOOT] core[%x,%d] CP2_DATA_EXT = %x / CP2_INS_EXT = %x\n",
    851 // cxy , lid , cp2_data_ext , cp2_ins_ext );
    852877
    853878            // Wait until all local cores in cluster ready
     
    855880                                 boot_info->cores_nr );
    856881        }
    857         /******************************************************************
    858          * PHASE B : all CP0s other than CP0 in boot cluster execute it
    859          *****************************************************************/
     882        /**************************************************************************
     883         * PHASE partially parallel : all core[cxy][0] with (cxy != 0) execute it
     884         **************************************************************************/
    860885        else
    861886        {
    862             // at this point, all INSTRUCTION address extension registers
    863             // point on cluster(0,0), but the DATA extension registers point
    864             // already on the local cluster to use the local stack.
    865             // To access the bootloader global variables we must first copy
    866             // the boot code (data and instructions) in the local cluster.
     887            // at this point, the DATA extension registers point
     888            // already on the local cluster cxy to use the local stack,
     889            // but all cores must access the code stored in cluster 0
     890
     891            // Each CP0 copies the boot code (data and instructions)
     892            // from the cluster 0 to the local cluster.
    867893            boot_remote_memcpy( XPTR( cxy           , BOOT_BASE ),
    868894                                XPTR( BOOT_CORE_CXY , BOOT_BASE ),
    869895                                BOOT_MAX_SIZE );
    870896
    871             // from now, it is safe to refer to the boot code global variables
     897            // from now, it is safe to refer to the boot global variables
    872898            boot_printf("\n[BOOT] core[%x,%d] replicated boot code at cycle %d\n",
    873899            cxy , lid , boot_get_proctime() );
    874900
    875                         // switch to the INSTRUCTION local memory space, to avoid contention.
    876             // asm volatile("mtc2  %0, $25" :: "r"(cxy));
    877 
    878             // Copy the arch_info.bin file into the local memory.
     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 );
     907
     908            // Each CP0 copies the arch_info.bin into the local memory.
    879909            boot_remote_memcpy(XPTR(cxy,           ARCHINFO_BASE),
    880910                               XPTR(BOOT_CORE_CXY, ARCHINFO_BASE),
     
    884914            cxy , lid , boot_get_proctime() );
    885915
    886             // Copy the kcode segment into local memory
     916            // Each CP0 copies the kcode segment into local memory
    887917            boot_remote_memcpy( XPTR( cxy           , seg_kcode_base ),
    888918                                XPTR( BOOT_CORE_CXY , seg_kcode_base ),
    889919                                seg_kcode_size );
    890920
    891             // Copy the kdata segment into local memory
     921            // Each CP0 copies the kdata segment into local memory
    892922            boot_remote_memcpy( XPTR( cxy           , seg_kdata_base ),
    893923                                XPTR( BOOT_CORE_CXY , seg_kdata_base ),
    894924                                seg_kdata_size );
    895925
    896             // Copy the kentry segment into local memory
     926            // [TO BE REMOVED<D-°>
     927            // Each CP0 copies the kentry segment into local memory
    897928            boot_remote_memcpy( XPTR( cxy           , seg_kentry_base ),
    898929                                XPTR( BOOT_CORE_CXY , seg_kentry_base ),
     
    902933            cxy , lid , boot_get_proctime() );
    903934
    904             // Get local boot_info_t structure base address.
     935            // Each CP0 get local boot_info_t structure base address.
    905936            boot_info = (boot_info_t*)seg_kdata_base;
    906937
    907             // Initialize local boot_info_t structure.
     938            // Each CP0 initializes local boot_info_t structure.
    908939            boot_info_init( boot_info , cxy );
    909940
     
    911942            cxy , lid , boot_get_proctime() );
    912943
    913             // Check core information.
     944            // Each CP0 checks core information.
    914945            boot_check_core( boot_info , lid );
    915946
    916             // get number of active clusters from BOOT_CORE cluster
    917             uint32_t count = boot_remote_lw( XPTR( BOOT_CORE_CXY , &active_cp0s_nr ) );
    918 
    919             // Wait until all clusters (i.e all CP0s) ready to enter kernel
     947            // Each CP0 get number of active clusters from BOOT_CORE cluster
     948            uint32_t count = boot_remote_lw( XPTR( 0 , &active_cores_nr ) );
     949
     950            // Wait until all clusters (i.e all CP0s) ready
    920951            boot_remote_barrier( XPTR( BOOT_CORE_CXY , &global_barrier ) , count );
    921952
    922953            // activate other local cores
    923954            boot_wake_local_cores( boot_info );
    924 
    925 // display address extensions
    926 // uint32_t cp2_data_ext;
    927 // uint32_t cp2_ins_ext;
    928 // asm volatile( "mfc2   %0,  $24" : "=&r" (cp2_data_ext) );
    929 // asm volatile( "mfc2   %0,  $25" : "=&r" (cp2_ins_ext) );
    930 // boot_printf("\n[BOOT] core[%x,%d] CP2_DATA_EXT = %x / CP2_INS_EXT = %x\n",
    931 // cxy , lid , cp2_data_ext , cp2_ins_ext );
    932955
    933956            // Wait until all local cores in cluster ready
     
    938961    else
    939962    {
    940         /***************************************************************
    941          * PHASE C: all non CP0 cores in all clusters execute it
    942          **************************************************************/
    943 
    944         // Switch to the INSTRUCTIONS local memory space
    945         // to avoid contention at the boot cluster.
    946         asm volatile("mtc2  %0, $25" :: "r"(cxy));
     963        /***********************************************************************
     964         * PHASE fully parallel : all cores[cxy][lid] with (lid! = 0) execute it
     965         **********************************************************************/
     966
     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 );
    947970
    948971        // Get local boot_info_t structure base address.
     
    952975        boot_check_core(boot_info, lid);
    953976
    954 // display address extensions
    955 // uint32_t cp2_data_ext;
    956 // uint32_t cp2_ins_ext;
    957 // asm volatile( "mfc2   %0,  $24" : "=&r" (cp2_data_ext) );
    958 // asm volatile( "mfc2   %0,  $25" : "=&r" (cp2_ins_ext) );
    959 // boot_printf("\n[BOOT] core[%x,%d] CP2_DATA_EXT = %x / CP2_INS_EXT = %x\n",
    960 // cxy , lid , cp2_data_ext , cp2_ins_ext );
    961 
    962977        // Wait until all local cores in cluster ready
    963978        boot_remote_barrier( XPTR( cxy , &local_barrier ) , boot_info->cores_nr );
    964979    }
    965980
     981    // the "kernel_entry" global variable, set by boot_kernel_load() define
     982    // the adress of the kernel_init() function.
    966983    // Each core initialise the following registers before jumping to kernel:
    967     // - sp_29    : stack pointer on idle thread,
    968     // - c0_sr    : reset BEV bit
    969     // - a0_04    : pointer on boot_info structure
    970     // - c0_ebase : kentry_base(and jump to kernel_entry.
    971 
     984    // - gr_29    : stack pointer / kernel stack allocated in idle thread descriptor,
     985    // - c0_sr    : status register / reset BEV bit
     986    // - 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.
    972990    // The array of idle-thread descriptors is allocated in the kdata segment,
    973     // just after the boot_info structure
    974     uint32_t sp;
     991    // just after the boot_info structure.
    975992    uint32_t base;
    976993    uint32_t offset = sizeof( boot_info_t );
    977994    uint32_t pmask  = CONFIG_PPM_PAGE_MASK;
    978995    uint32_t psize  = CONFIG_PPM_PAGE_SIZE;
    979 
    980     // compute base address of idle thread descriptors array
    981996    if( offset & pmask ) base = seg_kdata_base + (offset & ~pmask) + psize;
    982997    else                 base = seg_kdata_base + offset;
    983 
    984     // compute stack pointer
    985     sp = base + ((lid + 1) * CONFIG_THREAD_DESC_SIZE) - 16;
     998    uint32_t sp = base + ((lid + 1) * CONFIG_THREAD_DESC_SIZE) - 16;
     999
     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
    9861006
    9871007    asm volatile( "mfc0  $27,  $12           \n"
     
    9971017                  : "r"(boot_info) ,
    9981018                    "r"(sp) ,
    999                     "r"(boot_info->kentry_base) ,
     1019                    "r"(ebase) ,
    10001020                    "r"(kernel_entry)
    10011021                  : "$26" , "$27" , "$29" , "$4" );
Note: See TracChangeset for help on using the changeset viewer.