Ignore:
Timestamp:
Feb 8, 2015, 12:50:23 PM (10 years ago)
Author:
alain
Message:

Introduce a fully parallel procedure for the kernel initialisation.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_kernel/kernel_init.c

    r478 r494  
    1313#include <tty0.h>
    1414#include <kernel_malloc.h>
     15#include <kernel_locks.h>
     16#include <kernel_barriers.h>
    1517#include <fat32.h>
    1618#include <xcu_driver.h>
     
    7274
    7375
     76// Distributed kernel heap descriptors array
     77// __attribute__((section(".kdata")))
     78// kernel_heap_t  kernel_heap[X_SIZE][Y_SIZE];
     79
     80// FAT internal representation for kernel code
     81__attribute__((section(".kdata")))
     82fat32_fs_t     fat      __attribute__((aligned(512)));
     83
     84// array of page tables virtual addresses
     85__attribute__((section(".kdata")))
     86volatile unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX];
     87
     88// array of page tables PTPR values (physical addresses >> 13)
     89__attribute__((section(".kdata")))
     90volatile unsigned int _ptabs_ptprs[GIET_NB_VSPACE_MAX];
     91
     92// Array of pointers on the schedulers
     93__attribute__((section(".kdata")))
     94volatile static_scheduler_t*    _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
     95
     96// Synchonisation before entering parallel execution
     97__attribute__((section(".kdata")))
     98volatile unsigned int _kernel_init_done = 0;
     99
     100// Kernel uses sqt_lock to protect TTY0       
     101__attribute__((section(".kdata")))
     102unsigned int   _tty0_boot_mode = 0;
     103
     104// Distributed synchronisation barrier for parallel init by all processors     
     105__attribute__((section(".kdata")))
     106sqt_barrier_t  _all_procs_barrier  __attribute__((aligned(64)));
     107
     108
     109
     110// this variable is defined in tty0.c file
     111extern sqt_lock_t _tty0_sqt_lock;
     112
     113
     114
    74115///////////////////////////////////////////////////////////////////////////////////
    75 // Ditributed kernel heap descriptors array (for dynamic memory allocation)
    76 ///////////////////////////////////////////////////////////////////////////////////
    77 
    78 kernel_heap_t  kernel_heap[X_SIZE][Y_SIZE];
    79 
    80 ///////////////////////////////////////////////////////////////////////////////////
    81 // FAT internal representation for kernel code
    82 ///////////////////////////////////////////////////////////////////////////////////
    83 
    84 fat32_fs_t     fat      __attribute__((aligned(512)));
    85 
    86 ///////////////////////////////////////////////////////////////////////////////////
    87 // array of pointers on the page tables (virtual addresses)
    88 ///////////////////////////////////////////////////////////////////////////////////
    89 
    90 volatile unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX];    // virtual addresses
    91 volatile unsigned int _ptabs_ptprs[GIET_NB_VSPACE_MAX];    // physical addresses >> 13
    92 
    93 ///////////////////////////////////////////////////////////////////////////////////
    94 // Array of pointers on the schedulers (physical addresses)
    95 ///////////////////////////////////////////////////////////////////////////////////
    96 
    97 volatile static_scheduler_t*    _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
    98 
    99 ////////////////////////////////////////////////////////////////////////////////////
    100 // Synchonisation barrier before jumping to user code
    101 ////////////////////////////////////////////////////////////////////////////////////
    102 
    103 volatile unsigned int kernel_init_barrier = 0;
    104 
    105 ////////////////////////////////////////////////////////////////////////////////////
    106 // Global variables for TTY/kernel communications
    107 ////////////////////////////////////////////////////////////////////////////////////
    108 
    109 unsigned int   _tty_rx_buf[NB_TTY_CHANNELS];
    110 unsigned int   _tty_rx_full[NB_TTY_CHANNELS];
    111 
    112 ////////////////////////////////////////////////////////////////////////////////////
    113 // Distributed locks protecting TTY terminals       
    114 ////////////////////////////////////////////////////////////////////////////////////
    115 
    116 sbt_lock_t     _tty_tx_lock[NB_TTY_CHANNELS]  __attribute__((aligned(64)));
    117 
    118 ///////////////////////////////////////////////////////////////////////////////////
    119 // This kernel_init() function completes the kernel initialisation in 7 steps:
    120 // All processors execute this code, but this is done sequencially.
    121 // - step 0 : Initialise fat, heap descriptors, and tty locks
    122 // - step 1 : Initialise scheduler pointers array
    123 // - step 2 : Initialise PTAB pointers arrays
    124 // - step 3 : Initialise private XCU masks
    125 // - step 4 :
    126 // - step 5 :
    127 // - step 6 :
     116// This kernel_init() function completes the kernel initialisation in 7 steps.
     117// Step 0 is done by processor[0,0,0]. Steps 1 to 6 are executed in parallel
     118// by all procesors.
     119// - step 0 : P[0,0,0] Initialise fat, heap descriptors, barrier and TTY0 lock.
     120// - step 1 : Each processor initialises scheduler pointers array.
     121// - step 2 : Each processor initialises PTAB pointers arrays.
     122// - step 3 : Each processor initialises its private XCU masks.
     123// - step 4 : Each processor starts its private TICK timer.
     124// - step 5 : Each processor initialises its private idle task context.
     125// - step 6 : Each processor set sp, sr, ptpr, epc registers values.
    128126///////////////////////////////////////////////////////////////////////////////////
    129127__attribute__((section (".kinit"))) void kernel_init()
    130128{
    131     // gpid : hardware processor index (fixed format: X_WIDTH|Y_WIDTH|P_WIDTH)
    132     // p    : local processor id in a cluster ( p < NB_PROCS_MAX)
    133     // cpid : continuous processor index = (((x * Y_SIZE + y) * NB_PROCS_MAX) + p
     129    // gpid  : hardware processor index (fixed format: X_WIDTH|Y_WIDTH|P_WIDTH)
     130    // x,y,p : processor coordinates ( x<X_SIZE / y<Y_SIZE / p<NB_PROCS_MAX )
    134131
    135132    unsigned int gpid       = _get_procid();
     
    138135    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    139136    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
    140     unsigned int cpid       = ((( x * Y_SIZE) + y) * NB_PROCS_MAX) + p;
    141 
    142     // This initialisation is done sequencially by each processor
    143     while( cpid != kernel_init_barrier ) asm volatile ( "nop" );
    144 
    145     // Step 0 : P[0,0,0] initialises various complex structures
    146     //          - kernel FAT
    147     //          - distributed kernel heaps
    148     //          - distributed locks protecting TTY channels
    149     //          - distributed locks protecting MMC components
     137
     138    ////////////////////////////////////////////////////////////////////////////
     139    // Step 0 : P[0,0,0] initialises various structures
     140
    150141    if ( gpid == 0 )
    151142    {
     143        // distributed kernel heaps
    152144        _heap_init();
    153145       
     
    155147_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel HEAP init\n", x, y, p );
    156148#endif
    157         unsigned int channel;
    158         for ( channel = 0 ; channel < NB_TTY_CHANNELS ; channel++ )
    159         {
    160             _sbt_lock_init( &_tty_tx_lock[channel] );
    161 
    162 #if GIET_DEBUG_INIT
    163 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes TTY[%d] lock init\n",
    164                x , y , p , channel );
    165 #endif
    166         }
    167 
    168 /*
    169         unsigned int cx, cy;
    170         for ( cx = 0 ; cx < X_SIZE ; cx++ )
    171         {
    172             for ( cy = 0 ; cy < X_SIZE ; cy++ )
    173             {
    174                 _sbt_lock_init( &_mmc_lock[cx][cy] );
    175 
    176 #if GIET_DEBUG_INIT
    177 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes MMC[%d][%d] lock init\n",
    178                x , y , p , cx , cy );
    179 #endif
    180             }
    181         }
    182 */
     149        // kernel FAT
    183150        _fat_init( IOC_BOOT_MODE );
    184151
     
    186153_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel FAT init\n", x, y, p );
    187154#endif
    188 
    189     }
    190 
    191     // Step 1 : each processor get its scheduler virtual address from CP0_SCHED register
    192     //          and contributes to _schedulers[] array initialisation
     155        // distributed lock for TTY0
     156        _sqt_lock_init( &_tty0_sqt_lock );
     157
     158#if GIET_DEBUG_INIT
     159_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes TTY0 lock init\n",
     160               x , y , p );
     161#endif
     162        // distributed kernel barrier between all processors
     163        _sqt_barrier_init( &_all_procs_barrier );
     164
     165#if GIET_DEBUG_INIT
     166_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes barrier init\n",
     167               x , y , p );
     168#endif
     169
     170        // release other processors
     171        _kernel_init_done = 1;
     172    }
     173    else
     174    {
     175        while( _kernel_init_done == 0 )  asm volatile ( "nop" );
     176    }
     177
     178    ///////////////////////////////////////////////////////////////////
     179    // Step 1 : each processor get its scheduler vaddr from CP0_SCHED,
     180    //          contributes to _schedulers[] array initialisation,
     181    //          and wait completion of array initialisation.
    193182
    194183    static_scheduler_t* psched     = (static_scheduler_t*)_get_sched();
     
    198187
    199188#if GIET_DEBUG_INIT
    200 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises SCHED array\n"
    201                " - scheduler vbase = %x\n"
    202                " - tasks           = %d\n",
    203                x, y, p, (unsigned int)psched, tasks );
    204 #endif
    205 
     189_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises SCHED array\n"
     190        " - scheduler vbase = %x\n"
     191        " - tasks           = %d\n",
     192        x, y, p, (unsigned int)psched, tasks );
     193#endif
     194
     195    _sqt_barrier_wait( &_all_procs_barrier );   
     196
     197    ////////////////////////////////////////////////////////////////////////////
    206198    // step 2 : each processor that is allocated at least one task loops
    207199    //          on all allocated tasks:
     
    225217
    226218#if GIET_DEBUG_INIT
    227 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises PTABS arrays\n"
     219_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises PTABS arrays\n"
    228220        " - ptabs_vaddr[%d] = %x / ptpr_paddr[%d] = %l\n",
    229221        x, y, p, 
     
    244236
    245237#if GIET_DEBUG_INIT
    246 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] updates context for task %d\n"
    247                " - ctx_epc   = %x\n"
    248                " - ctx_ra    = %x\n",
    249                x, y, p, ltid,
    250                _get_task_slot( x, y, p, ltid, CTX_EPC_ID ),
    251                _get_task_slot( x, y, p, ltid, CTX_RA_ID ) );
     238_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] updates context for task %d\n"
     239        " - ctx_epc   = %x\n"
     240        " - ctx_ra    = %x\n",
     241        x, y, p, ltid,
     242        _get_task_slot( x, y, p, ltid, CTX_EPC_ID ),
     243        _get_task_slot( x, y, p, ltid, CTX_RA_ID ) );
    252244#endif
    253245
    254246    }  // end for tasks
    255247
    256     // step 3 : compute and set XCU masks
     248    _sqt_barrier_wait( &_all_procs_barrier );   
     249
     250    ////////////////////////////////////////////////////////////////////////////
     251    // step 3 : compute and set XCU masks for HWI / PTI / WTI interrupts
    257252
    258253    unsigned int isr_switch_index = 0xFFFFFFFF;
     
    279274
    280275#if GIET_DEBUG_INIT
    281 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] sets XCU masks\n"
    282                " - XCU HWI_MASK = %x\n"
    283                " - XCU WTI_MASK = %x\n"
    284                " - XCU PTI_MASK = %x\n",
    285                x, y, p, hwi_mask, wti_mask, pti_mask );
     276_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] sets XCU masks\n"
     277        " - ISR_TICK_INDEX = %d\n"
     278        " - XCU HWI_MASK   = %x\n"
     279        " - XCU WTI_MASK   = %x\n"
     280        " - XCU PTI_MASK   = %x\n",
     281        x, y, p,
     282        isr_switch_index,
     283        hwi_mask, wti_mask, pti_mask );
    286284#endif
    287285
     
    292290    _xcu_set_mask( cluster_xy, channel, pti_mask, IRQ_TYPE_PTI );
    293291
    294     // step 4 : start TICK timer if at least one task
     292    ////////////////////////////////////////////////////////////////////////////
     293    // step 4 : Each processor start TICK timer if at least one task
     294
    295295    if (tasks > 0)
    296296    {
     
    298298        if (isr_switch_index == 0xFFFFFFFF)
    299299        {
    300             _nolock_printf("\n[GIET ERROR] ISR_TICK not found for processor[%d,%d,%d]\n",
     300            _printf("\n[GIET ERROR] ISR_TICK not found for processor[%d,%d,%d]\n",
    301301                           x, y, p );
    302302            _exit();
     
    309309
    310310#if GIET_DEBUG_INIT
    311 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] starts TICK timer\n",
    312                x, y, p );
    313 #endif
    314 
     311_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] starts TICK timer\n",
     312        x, y, p );
     313#endif
     314
     315    ////////////////////////////////////////////////////////////////////////////
    315316    // step 5 : each processor updates the idle_task context:
    316317    //          (CTX_SP, CTX_RA, CTX_EPC).
     
    326327
    327328#if GIET_DEBUG_INIT
    328 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes IDLE task\n"
    329                " - stack_base = %x\n"
    330                " - stack_size = 0x1000\n",
    331                x, y, p, pstack - 0x1000 );
    332 #endif
    333 
    334     // step 6 : when all processors reach the synchronisation barrier,
    335     //          each processor set registers SP, SR, PTPR, EPC,
    336     //          with the values corresponding to the first allocated task,
    337     //          or to the idle_task if there is no task allocated,
    338     //          and jump to user code
    339 
    340     if (tasks == 0)
     329_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes IDLE task\n"
     330        " - stack_base = %x\n"
     331        " - stack_size = 0x1000\n",
     332        x, y, p, pstack - 0x1000 );
     333#endif
     334
     335    _sqt_barrier_wait( &_all_procs_barrier );   
     336
     337    ////////////////////////////////////////////////////////////////////////////
     338    // step 6 : Each processor compute values for registers SP, SR, PTPR, EPC,
     339    //          corresponding to the first allocated task (can be idle task)
     340    //          and jump to user code when barrier is reached
     341
     342    if (tasks == 0)
    341343    {
    342344        ltid = IDLE_TASK_INDEX;
    343 
    344         _nolock_printf("\n[GIET WARNING] No task allocated to processor[%d,%d,%d]\n",
    345                        x, y, p );
     345        _printf("\n[GIET WARNING] No task allocated to processor[%d,%d,%d]\n",
     346                x, y, p );
    346347    }
    347348    else
     
    355356    unsigned int epc_value  = _get_task_slot( x, y, p, ltid, CTX_EPC_ID);
    356357
    357 #if GIET_DEBUG_INIT
    358 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] reach barrier at cycle %d\n",
    359                x, y, p, _get_proctime() );
    360 #endif
    361 
    362     // increment barrier counter
    363     kernel_init_barrier++;
    364 
    365     // busy waiting until all processors synchronized
    366     while ( kernel_init_barrier != NB_TOTAL_PROCS );
    367 
    368 #if GIET_DEBUG_INIT
    369 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes registers at cycle %d\n"
    370         " - sp   = %x\n"
    371         " - sr   = %x\n"
    372         " - ptpr = %x\n"
    373         " - epc  = %x\n",
     358    _sqt_barrier_wait( &_all_procs_barrier );
     359
     360#if GIET_DEBUG_INIT
     361_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] jumps to user code at cycle %d\n"
     362        "  sp = %x / sr = %x / ptpr = %x / epc = %x\n",
    374363        x, y, p, _get_proctime(),
    375364        sp_value, sr_value, ptpr_value, epc_value );
Note: See TracChangeset for help on using the changeset viewer.