Ignore:
Timestamp:
Aug 9, 2012, 2:38:06 PM (12 years ago)
Author:
alain
Message:

Introducing the "idle" to improve the exit mechanism.

File:
1 edited

Legend:

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

    r189 r199  
    88// It contains the kernel entry point for the last step of system initialisation.
    99// All procs in this phase have their MMU activated, and are running in parallel.
    10 // - each processor updates its own scheduler, to replace the ISR index
    11 //   by the actual ISR virtual address, and set its own entry in the
    12 //   kernel _schedulers_paddr[] array.
    13 // - each processor initialises the SP, SR, PTPR, EPC registers, and starts
    14 //   its private Timer, before jumping to the user code with an eret.
     10// Each processor perform the following actions:
     11// 1/ contributes to _schedulers_paddr[] initialisation
     12// 2/ contributes to _ptabs_paddr[] and _ptabs_vaddr arrays initialisation
     13// 3/ computes and set the ICU mask for its private ICU channel
     14// 4/ initialises its private TICK timer (if required)
     15// 5/ initialises the "idle" task context in its private scheduler
     16// 6/ initialises the SP, SR, PTPR, EPC registers
     17// 7/ jumps to the user code with an eret.
    1518////////////////////////////////////////////////////////////////////////////////////
    1619
     
    3437
    3538__attribute__((section (".kdata")))
    36 page_table_t* _ptabs_paddr[GIET_NB_VSPACE_MAX];
    37 
    38 __attribute__((section (".kdata")))
    39 page_table_t* _ptabs_vaddr[GIET_NB_VSPACE_MAX];
    40 
    41 __attribute__((section (".kdata")))
    42 static_scheduler_t*     _schedulers_paddr[NB_CLUSTERS*NB_PROCS_MAX];
     39unsigned int                    _ptabs_paddr[GIET_NB_VSPACE_MAX];
     40
     41__attribute__((section (".kdata")))
     42unsigned int                    _ptabs_vaddr[GIET_NB_VSPACE_MAX];
     43
     44__attribute__((section (".kdata")))
     45static_scheduler_t*             _schedulers_paddr[NB_CLUSTERS*NB_PROCS_MAX];
     46
     47__attribute__((section (".kdata")))
     48unsigned int                    _idle_stack[NB_CLUSTERS*NB_PROCS_MAX*64];
    4349
    4450//////////////////////////////////////////////////////////////////////////////////
     
    4753__attribute__((section (".kinit"))) void _kernel_init()
    4854{
    49     // values to be written in registers
    50     unsigned int        sp_value;
    51     unsigned int        sr_value;
    52     unsigned int        ptpr_value;
    53     unsigned int        epc_value;
    54 
     55    // compute cluster and local processor index
    5556    unsigned int        proc_id    = _procid();
    5657    unsigned int    cluster_id = proc_id / NB_PROCS_MAX;
     
    6667_get_lock(&_tty_put_lock);
    6768_puts("\n[GIET DEBUG] step 1 for processor ");
    68 _putw( proc_id );
    69 _puts("\n");
    70 _puts("- scheduler pbase = ");
     69_putd( proc_id );
     70_puts(" / scheduler pbase = ");
    7171_putw( (unsigned int)psched );
    7272_puts("\n");
     
    7474#endif
    7575
    76     // step 2 : compute and set ICU mask
     76
     77    // step 2 : initialise page table addresse arrays
     78    //          it scans all tasks contexts in the scheduler
     79    //          and get VSID, PTAB and PTPR values
     80
     81    unsigned int ltid;
     82    unsigned int tasks = _get_tasks_number();
     83
     84    for ( ltid = 0 ; ltid < tasks ; ltid++ )
     85    {
     86        unsigned int vspace_id  = _get_context_slot( ltid , CTX_VSID_ID );
     87        unsigned int ptab_vaddr = _get_context_slot( ltid , CTX_PTAB_ID );
     88        unsigned int ptab_paddr = _get_context_slot( ltid , CTX_PTPR_ID ) << 13;
     89        _ptabs_vaddr[vspace_id] = ptab_vaddr;
     90        _ptabs_paddr[vspace_id] = ptab_paddr;
     91
     92#if GIET_DEBUG_INIT
     93_get_lock(&_tty_put_lock);
     94_puts("\n[GIET DEBUG] step 2 for processor ");
     95_putd( proc_id );
     96_puts(" / vspace ");
     97_putd( vspace_id );
     98_puts("\n- ptab vbase = ");
     99_putw( ptab_vaddr );
     100_puts("\n- ptab pbase = ");
     101_putw( ptab_paddr );
     102_puts("\n");
     103_release_lock(&_tty_put_lock);
     104#endif
     105
     106    }
     107 
     108    // step 3 : compute and set ICU mask
    77109    unsigned int irq_id;
    78110    unsigned int mask = 0;
     
    89121#if GIET_DEBUG_INIT
    90122_get_lock(&_tty_put_lock);
    91 _puts("\n[GIET DEBUG] step 2 for processor ");
    92 _putw( proc_id );
    93 _puts("\n");
    94 _puts("- ICU mask = ");
     123_puts("\n[GIET DEBUG] step 3 for processor ");
     124_putd( proc_id );
     125_puts(" / ICU mask = ");
    95126_putw( mask );
    96127_puts("\n");
     
    99130
    100131
    101     // step 3 : TODO initialise page table addresse arrays
    102 
    103 
    104132    // step 4 : start TICK timer if more than one task
    105     unsigned int tasks = _get_tasks_number();
    106133    if ( tasks > 1 )
    107134    {
     
    122149_get_lock(&_tty_put_lock);
    123150_puts("\n[GIET DEBUG] Step 4 for processor ");
    124 _putw( proc_id );
    125 _puts("\n");
    126 _puts("- TICK period = ");
    127 _putd( period );
    128 _puts("\n");
     151_putd( proc_id );
     152_puts(" / TICK activated\n");
    129153_release_lock(&_tty_put_lock);
    130154#endif
     
    132156    }
    133157
    134     // step 5 : each processor initialises SP, SR, PTPR, EPC, registers
     158    // step 5 : initialise the "idle" task context
     159    //          the SR initialisation value is 0xFF03 because
     160    //          the task _ctx_idle() executes in kernel mode...
     161    //          it uses the page table of vspace[0]
     162 
     163    _set_context_slot( IDLE_TASK_INDEX, CTX_RUN_ID,  1 );
     164    _set_context_slot( IDLE_TASK_INDEX, CTX_SR_ID,   0xFF03 );
     165    _set_context_slot( IDLE_TASK_INDEX, CTX_SP_ID,   (unsigned int)&_idle_stack[proc_id] + 64 );
     166    _set_context_slot( IDLE_TASK_INDEX, CTX_RA_ID,   (unsigned int)&_ctx_eret );
     167    _set_context_slot( IDLE_TASK_INDEX, CTX_EPC_ID,  (unsigned int)&_ctx_idle );
     168    _set_context_slot( IDLE_TASK_INDEX, CTX_LTID_ID, IDLE_TASK_INDEX );
     169    _set_context_slot( IDLE_TASK_INDEX, CTX_PTPR_ID, _ptabs_paddr[0] >> 13 );
     170
     171#if GIET_DEBUG_INIT
     172_get_lock(&_tty_put_lock);
     173_puts("\n[GIET DEBUG] Step 5 for processor ");
     174_putd( proc_id );
     175_puts(" / idle task context set\n");
     176_release_lock(&_tty_put_lock);
     177#endif
     178   
     179    // step 6 : each processor initialises SP, SR, PTPR, EPC, registers
    135180    //          with the values corresponding to the first allocated task,
    136     //          It does nothing, and keep idle if no task allocated.
    137 
    138     if ( tasks )                // at leat one task allocated
    139     {
    140         // initialise registers
    141         sp_value   = _get_current_context_slot(CTX_SP_ID);
    142         sr_value   = _get_current_context_slot(CTX_SR_ID);
    143         ptpr_value = _get_current_context_slot(CTX_PTPR_ID);
    144         epc_value  = _get_current_context_slot(CTX_EPC_ID);
    145 
    146 #if GIET_DEBUG_INIT
    147 _get_lock(&_tty_put_lock);
    148 _puts("\n[GIET DEBUG] step 5 for processor ");
    149 _putw( proc_id );
    150 _puts("\n");
     181    //          and starts the "idle" task if there is no task allocated.
     182
     183    unsigned int task_id;
     184
     185    if ( tasks == 0 )
     186    {
     187        task_id = IDLE_TASK_INDEX;
     188
     189        _get_lock( &_tty_put_lock );
     190        _puts("\n [GIET WARNING] No task allocated to processor ");
     191        _putw( proc_id );
     192        _puts(" => idle\n");
     193        _release_lock ( &_tty_put_lock );
     194    }
     195    else
     196    {
     197        task_id = 0;
     198    }
     199       
     200    unsigned int    sp_value   = _get_context_slot( task_id, CTX_SP_ID );
     201    unsigned int    sr_value   = _get_context_slot( task_id, CTX_SR_ID );
     202    unsigned int    ptpr_value = _get_context_slot( task_id, CTX_PTPR_ID );
     203    unsigned int    epc_value  = _get_context_slot( task_id, CTX_EPC_ID );
     204
     205#if GIET_DEBUG_INIT
     206_get_lock(&_tty_put_lock);
     207_puts("\n[GIET DEBUG] step 6 for processor ");
     208_putd( proc_id );
     209_puts(" / registers initialised \n");
    151210_puts("- sp   = ");
    152211_putw( sp_value );
     
    163222_release_lock(&_tty_put_lock);
    164223#endif
    165     }
    166     else                                        // no task allocated
    167     {
    168         _get_lock( &_tty_put_lock );
    169         _puts("\n No task allocated to processor ");
    170         _putw( proc_id );
    171         _puts(" => keep idle\n");
    172         _release_lock ( &_tty_put_lock );
    173 
    174         // enable interrupts in kernel mode
    175         asm volatile ( "li         $26, 0xFF01  \n"
    176                        "mtc0   $26, $12     \n"
    177                        ::: "$26" );
    178 
    179                 // infinite loop in kernel mode
    180         while (1) asm volatile("nop");
    181     }
    182 
    183     // set critical registers and jump to user code
    184     asm volatile (
    185        "move    $29,    %0              \n"             /* SP <= ctx[CTX_SP_ID] */
    186        "mtc0    %1,             $12             \n"             /* SR <= ctx[CTX_SR_ID] */
    187        "mtc2    %2,             $0              \n"             /* PTPR <= ctx[CTX_PTPR_ID] */
    188        "mtc0    %3,             $14             \n"             /* EPC <= ctx[CTX_EPC_ID] */
    189        "eret                                    \n"             /* jump to user code */
    190        "nop                                             \n"
    191        :
    192        : "r"(sp_value), "r"(sr_value), "r"(ptpr_value), "r"(epc_value) );
     224
     225    // set  registers and jump to user code
     226    asm volatile ( "move        $29,    %0              \n"             /* SP <= ctx[CTX_SP_ID] */
     227                   "mtc0        %1,             $12             \n"             /* SR <= ctx[CTX_SR_ID] */
     228                   "mtc2        %2,             $0              \n"             /* PTPR <= ctx[CTX_PTPR_ID] */
     229                   "mtc0        %3,             $14             \n"             /* EPC <= ctx[CTX_EPC_ID] */
     230                   "eret                                        \n"             /* jump to user code */
     231                   "nop                                         \n"
     232                   :
     233                   : "r"(sp_value), "r"(sr_value), "r"(ptpr_value), "r"(epc_value) );
    193234
    194235} // end _kernel_init()
Note: See TracChangeset for help on using the changeset viewer.