Changeset 199 for soft/giet_vm/sys


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

Introducing the "idle" to improve the exit mechanism.

Location:
soft/giet_vm/sys
Files:
10 edited

Legend:

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

    r189 r199  
    324324    return _physical_read_access( &(psched->current) );
    325325}
     326////////////////////////////////////////////////////////////////////////////
     327//    _set_current_task_id()
     328// This function returns the index of the currently running task.
     329////////////////////////////////////////////////////////////////////////////
     330void _set_current_task_id( unsigned int value )
     331{
     332    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
     333    _physical_write_access( &(psched->current), value );
     334}
    326335///////////////////////////////////////////////////////////////////////////////
    327 //    _get_current_context_slot()
    328 // This function returns the global TTY index for the currently running task.
     336//    _get_context_slot()
     337// This function returns a slot content for the task defined by task_id.
    329338///////////////////////////////////////////////////////////////////////////////
    330 unsigned int _get_current_context_slot(unsigned int slot_id)
    331 {
    332     static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
    333     unsigned int                        current = _physical_read_access( &(psched->current) );
    334     return _physical_read_access( &(psched->context[current][slot_id]) );
    335 }
    336 /////////////////////////////////////////////i//////////////////////////////////
     339unsigned int _get_context_slot( unsigned int task_id,
     340                                unsigned int slot_id )
     341{
     342    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
     343    return _physical_read_access( &(psched->context[task_id][slot_id]) );
     344}
     345///////////////////////////////////////////////////////////////////////////////
     346//    _set_context_slot()
     347// This function returns a slot content for the task defined by task_id.
     348///////////////////////////////////////////////////////////////////////////////
     349void _set_context_slot( unsigned int task_id,
     350                        unsigned int slot_id,
     351                        unsigned int value )
     352{
     353    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
     354    _physical_write_access( &(psched->context[task_id][slot_id]), value );
     355}
     356////////////////////////////////////////////////////////////////////////////////
    337357//    _get_interrupt_vector_entry()
    338358// This function returns the interrupt_vector entry defined by argument index.
     
    342362    static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
    343363    return _physical_read_access( &(psched->interrupt_vector[index]) );
    344 }
    345 ////////////////////////////////////////////////////////////////////////////
    346 //    _set_current_task_id()
    347 // This function returns the index of the currently running task.
    348 ////////////////////////////////////////////////////////////////////////////
    349 void _set_current_task_id( unsigned int value )
    350 {
    351     static_scheduler_t*         psched = (static_scheduler_t*)_get_sched();
    352     _physical_write_access( &(psched->current), value );
    353364}
    354365
  • soft/giet_vm/sys/common.h

    r189 r199  
    3636void                            _putd(unsigned int val);
    3737
    38 unsigned int            _strncmp(const char* s1, const char* s2, unsigned int n);
     38unsigned int            _strncmp( const char* s1,
     39                              const char* s2,
     40                              unsigned int n );
    3941
    40 void                            _dcache_buf_invalidate(const void *buffer, unsigned int size);
    41 
    42 void                            _itoa_dec(unsigned int val, char* buf);
    43 void                            _itoa_hex(unsigned int val, char* buf);
     42void                            _dcache_buf_invalidate( const void *buffer,
     43                                            unsigned int size );
    4444
    4545void                            _dtlb_off(void);
     
    5555unsigned int            _get_sched(void);
    5656
    57 unsigned int            _get_current_context_slot(unsigned int index);
     57unsigned int            _get_context_slot( unsigned int task_id,
     58                                       unsigned int slot_id );
     59
     60void                            _set_context_slot( unsigned int task_id,
     61                                       unsigned int slot_id,
     62                                       unsigned int value );
     63
    5864unsigned int            _get_interrupt_vector_entry(unsigned int index);
    59 unsigned int            _get_current_task_id(void);
     65
     66unsigned int            _get_current_task_id( void );
     67void                            _set_current_task_id( unsigned int value );
     68
    6069unsigned int            _get_tasks_number(void);
    6170
    62 void                            _set_current_task_id( unsigned int value);
    6371
    6472void                            _get_lock(unsigned int* lock);
  • soft/giet_vm/sys/ctx_handler.c

    r189 r199  
    1 ///////////////////////////////////////////////////////////////////////////////////////
     1/////////////////////////////////////////////////////////////////////////////////////////
    22// File     : ctx_handler.c
    33// Date     : 01/04/2012
    44// Authors  : alain greiner & joel porquet
    55// Copyright (c) UPMC-LIP6
    6 ///////////////////////////////////////////////////////////////////////////////////////
     6/////////////////////////////////////////////////////////////////////////////////////////
    77// The ctx_handler.h and ctx_handler.c files are part of the GIET-VM nano-kernel.
    88// This code is used to support context switch when several tasks are executing
    99// in time multiplexing on a single processor.
    10 // The tasks must be statically allocated to a processor in the boot phase, and
    11 // there is one private scheduler per processor.
    12 // Each sheduler contains up to 15 task contexts.
    13 ///////////////////////////////////////////////////////////////////////////////////////
     10// The tasks are statically allocated to a processor in the boot phase, and
     11// there is one private scheduler per processor. Each sheduler occupies 4K bytes,
     12// and contains up to 14 task contexts (task_id is from 0 to 13).
     13// The task context [14] is reserved for the "idle" task that does nothing, and
     14// is launched by the scheduler when there is no other runable task.
     15/////////////////////////////////////////////////////////////////////////////////////////
    1416
    1517#include <giet_config.h>
     
    2022#include <sys_handler.h>
    2123
    22 ///////////////////////////////////////////////////////////////////////////////////////
     24/////////////////////////////////////////////////////////////////////////////////////////
    2325// A task context is an array of 64 words = 256 bytes.
    24 // It contains copies of processor registers (when the task is preempted),
    25 // and some general informations associated to the task.
     26// It contains copies of processor registers (when the task is preempted):
     27// - GPR[i], generally stored in slot (i). $0, *26 & $27 are not saved.
     28// - HI & LO registers
     29// - CP0 registers: EPC, SR, CR, BVAR
     30// - CP2 registers : PTPR
     31// It contains some general informations associated to the task:
     32// - TTY        : terminal global index
     33// - FBDMA      : DMA channel global index
     34// - NIC        : NIC channel global index
     35// - TIMER  : Timer global index
     36// - PTAB   : page table virtual base address
     37// - LTID       : Task local index (in scheduler)
     38// - VSID   : Virtual space index
     39// - RUN        : Task state (0 => sleeping / 1 => runable )
    2640//
    27 // - It contains GPR[i], generally stored in slot (i). $0, *26 & $27 are not saved.
    28 // - It contains HI & LO registers.
    29 // - It contains CP0 registers: EPC, SR, CR, SCHED
    30 // - It contains CP2 registers : PTPR and MODE.
    31 // - It contains TTY global index, the FBDMA global index, the virtual base
    32 //   address of the page table (PTAB), and the task global index (TASK).
    33 //
    34 // ctx[0]<- SR|ctx[8] <- $8 |ctx[16]<- $16|ctx[24]<- $24|ctx[32]<- EPC |ctx[40]<- TTY
    35 // ctx[1]<- $1|ctx[9] <- $9 |ctx[17]<- $17|ctx[25]<- $25|ctx[33]<- CR  |ctx[41]<- FBDMA
    36 // ctx[2]<- $2|ctx[10]<- $10|ctx[18]<- $18|ctx[26]<- LO |ctx[34]<- *** |ctx[42]<- PTAB
    37 // ctx[3]<- $3|ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- PTPR|ctx[43]<- TASK
    38 // ctx[4]<- $4|ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- MODE|ctx[44]<- SCHED
    39 // ctx[5]<- $5|ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- *** |ctx[45]<- TIMER
    40 // ctx[6]<- $6|ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- *** |ctx[46]<- ***
    41 // ctx[7]<- $7|ctx[15]<- $15|ctx[23]<- $23|ctx[31]<- RA |ctx[39]<- *** |ctx[47]<- ***
    42 ////////////////////////////////////////////////////////////////////////////////////////
     41// ctx[0]<- ***|ctx[8] <- $8 |ctx[16]<- $16|ctx[24]<- $24|ctx[32]<- EPC  |ctx[40]<- TTY
     42// ctx[1]<- $1 |ctx[9] <- $9 |ctx[17]<- $17|ctx[25]<- $25|ctx[33]<- CR   |ctx[41]<- FBDMA
     43// ctx[2]<- $2 |ctx[10]<- $10|ctx[18]<- $18|ctx[26]<- LO |ctx[34]<- SR   |ctx[42]<- NIC
     44// ctx[3]<- $3 |ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- BVAR |ctx[43]<- TIMER
     45// ctx[4]<- $4 |ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- ***  |ctx[44]<- PTAB
     46// ctx[5]<- $5 |ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- ***  |ctx[45]<- LTID
     47// ctx[6]<- $6 |ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- ***  |ctx[46]<- VSID
     48// ctx[7]<- $7 |ctx[15]<- $15|ctx[23]<- $23|ctx[31]<- RA |ctx[39]<- PTPR |ctx[47]<- RUN
     49//////////////////////////////////////////////////////////////////////////////////////////
    4350
    4451extern void _task_switch(unsigned int*, unsigned int*);
     
    4754//      _ctx_switch()
    4855// This function performs a context switch between the running task
    49 // and  another task, using a round-robin sheduling policy.
     56// and  another task, using a round-robin sheduling policy between all
     57// tasks allocated to a given processor (static allocation).
     58// It selects the next runable task to resume execution.
     59// If the only runable task is the current task, return without context switch.
     60// If there is no runable task, the scheduler switch to the default "idle" task.
    5061//
    51 // It desactivate the DTLB, to directly access the scheduler using
    52 // the physical address stored in register CP0_SCHED.
    53 // All the context switch procedure is executed with interrupts masked.
    54 //
    55 // The return address contained in $31 is saved in the current task context
    56 // (in the ctx[31] slot), and the function actually returns to the address
    57 // contained in the ctx[31] slot of the next task context.
     62// Implementation notes:
     63// - As we only have the scheduler physical address (in CP0_SCHED register),
     64//   this function must use specific assess functions to access the scheduler.
     65// - All the context switch procedure is executed with interrupts masked.
     66// - The return address contained in $31 is saved in the current task context
     67//   (in the ctx[31] slot), and the function actually returns to the address
     68//   contained in the ctx[31] slot of the next task context.
    5869/////////////////////////////////////////////////////////////////////////////////
    5970void _ctx_switch()
    6071{
    61     unsigned int                        tasks;
    62     unsigned int                        curr_task_id;
    63     unsigned int                        next_task_id;
    64     unsigned int                        *curr_ctx_paddr;
    65     unsigned int                        *next_ctx_paddr;
    66 
    6772    // get scheduler physical address
    6873    static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
    6974
    7075    // get number of tasks allocated to scheduler
    71     tasks = _get_tasks_number();
     76    unsigned int        tasks = _get_tasks_number();
    7277
    73     // no switch if only one task
    74     if ( tasks > 1)
     78    // get current task index
     79    unsigned int        curr_task_id = _get_current_task_id();
     80
     81    // select the next task using a round-robin policy
     82    unsigned int        next_task_id;
     83    unsigned int        tid;
     84    unsigned int        found = 0;
     85
     86    for ( tid = curr_task_id + 1 ;
     87          tid < curr_task_id + 1 + tasks ;
     88          tid++ )
    7589    {
    76         // compute the context physical address for the current task
    77         curr_task_id = _get_current_task_id();
    78         curr_ctx_paddr = &(psched->context[curr_task_id][0]);
    79    
    80         // select the next task using a round-robin policy
    81         next_task_id = (curr_task_id + 1) % tasks;
    82    
    83         // compute the context physical address for the next task
    84         next_ctx_paddr = &(psched->context[next_task_id][0]);
     90        next_task_id = tid % tasks;
    8591
    86         // update the scheduler state
     92        // test if the task is runable
     93        if ( _get_context_slot( next_task_id, CTX_RUN_ID ) )   
     94        {
     95            found = 1;
     96                break;
     97        }
     98    }
     99
     100    // launch "idle" task if no runable task
     101    if ( found == 0 )
     102    {
     103        next_task_id = IDLE_TASK_INDEX;
     104    }
     105
     106    // no switch if no change
     107    if ( curr_task_id != next_task_id )
     108    {
     109        unsigned int*   curr_ctx_paddr = &(psched->context[curr_task_id][0]);
     110        unsigned int*   next_ctx_paddr = &(psched->context[next_task_id][0]);
     111
    87112        _set_current_task_id( next_task_id );
     113        _task_switch( curr_ctx_paddr, next_ctx_paddr );
    88114
    89115#if GIET_DEBUG_SWITCH
    90116_get_lock( &_tty_put_lock );
    91 _puts( "\n[GIET] Context switch for processor ");
    92 _putw( _procid() );
     117_puts( "\n[GIET DEBUG] Context switch for processor ");
     118_putd( _procid() );
    93119_puts( " at cycle ");
    94 _putw( _proctime() );
     120_putd( _proctime() );
    95121_puts("\n");
    96122_puts( " - tasks        = ");
    97 _putw( tasks );
     123_putd( tasks );
    98124_puts("\n");
    99125_puts( " - curr_task_id = ");
    100 _putw( curr_task_id );
     126_putd( curr_task_id );
    101127_puts("\n");
    102128_puts( " - next_task_id = ");
    103 _putw( next_task_id );
     129_putd( next_task_id );
    104130_puts("\n");
    105131_release_lock( &_tty_put_lock );
    106132#endif
    107133
    108         // makes the task switch
    109         _task_switch( curr_ctx_paddr, next_ctx_paddr );
     134    }
     135} //end _ctx_switch()
    110136
    111 /*
    112         asm volatile( "ori              $27,    $0,             0xB     \n"
    113                       "mtc2             $27,    $1                      \n"             // desactivate DTLB
     137/////////////////////////////////////////////////////////////////////////////////////
     138// This function is executed as the"idle" task when no other task can be executed
     139/////////////////////////////////////////////////////////////////////////////////////
     140void _ctx_idle()
     141{
     142    unsigned int delay = 1000000;
    114143
    115                       "add      $27,    %0,     $0  \n"         // $27 <= &curr_ctx
     144    while(1)
     145    {
     146        asm volatile("move  $3,   %0            \n"
     147                     "loop:                                     \n"
     148                     "addi      $3, $3, -1              \n"
     149                     "bnez  $3, loop            \n"
     150                     "nop                                       \n"
     151                     :
     152                     : "r"(delay)
     153                     : "$3" );
    116154
    117                       "mfc0     $26,    $12         \n"         // $26 <= SR
    118                       "sw       $26,    0*4($27)    \n"         // ctx[0] <= SR
    119                       ".set noat                    \n"
    120                       "sw       $1,     1*4($27)    \n"         // ctx[1] <= $1
    121                       ".set at                      \n"
    122                       "sw       $2,     2*4($27)    \n"         // ctx[2] <= $2
    123                       "sw       $3,     3*4($27)    \n"         // ctx[3] <= $3
    124                       "sw       $4,     4*4($27)    \n"         // ctx[4] <= $4
    125                       "sw       $5,     5*4($27)    \n"         // ctx[5] <= $5
    126                       "sw       $6,     6*4($27)    \n"         // ctx[6] <= $6
    127                       "sw       $7,     7*4($27)    \n"         // ctx[7] <= $7
    128                       "sw       $8,     8*4($27)    \n"         // ctx[8] <= $8
    129                       "sw       $9,     9*4($27)    \n"         // ctx[9] <= $9
    130                       "sw       $10,    10*4($27)   \n"         // ctx[10] <= $10
    131                       "sw       $11,    11*4($27)   \n"         // ctx[11] <= $11
    132                       "sw       $12,    12*4($27)   \n"         // ctx[12] <= $12
    133                       "sw       $13,    13*4($27)   \n"         // ctx[13] <= $13
    134                       "sw       $14,    14*4($27)   \n"         // ctx[14] <= $14
    135                       "sw       $15,    15*4($27)   \n"         // ctx[15] <= $15
    136                       "sw       $16,    16*4($27)   \n"         // ctx[16] <= $16
    137                       "sw       $17,    17*4($27)   \n"         // ctx[17] <= $17
    138                       "sw       $18,    18*4($27)   \n"         // ctx[18] <= $18
    139                       "sw       $19,    19*4($27)   \n"         // ctx[19] <= $19
    140                       "sw       $20,    20*4($27)   \n"         // ctx[20] <= $20
    141                       "sw       $21,    21*4($27)   \n"         // ctx[21] <= $21
    142                       "sw       $22,    22*4($27)   \n"         // ctx[22] <= $22
    143                       "sw       $23,    23*4($27)   \n"         // ctx[23] <= $23
    144                       "sw       $24,    24*4($27)   \n"         // ctx[24] <= $24
    145                       "sw       $25,    25*4($27)   \n"         // ctx[25] <= $25
    146                       "mflo     $26                 \n"
    147                       "sw       $26,    26*4($27)   \n"         // ctx[26] <= LO
    148                       "mfhi     $26                 \n"
    149                       "sw       $26,    27*4($27)   \n"         // ctx[27] <= H1
    150                       "sw       $28,    28*4($27)   \n"         // ctx[28] <= $28
    151                       "sw       $29,    29*4($27)   \n"         // ctx[29] <= $29
    152                       "sw       $30,    30*4($27)   \n"         // ctx[30] <= $30
    153                       "sw       $31,    31*4($27)   \n"         // ctx[31] <= $31
    154                       "mfc0     $26,    $14         \n"
    155                       "sw       $26,    32*4($27)   \n"         // ctx[32] <= EPC
    156                       "mfc0     $26,    $13         \n"
    157                       "sw       $26,    33*4($27)   \n"         // ctx[33] <= CR
    158                       "mfc2     $26,    $0          \n"
    159                       "sw       $26,    35*4($27)   \n"         // ctx[35] <= PTPR
     155        _get_lock( &_tty_put_lock );
     156        _puts( "\n[GIET WARNING] Processor ");
     157        _putd( _procid() );
     158        _puts( " still idle at cycle ");
     159        _putd( _proctime() );
     160        _puts("\n");
     161        _release_lock( &_tty_put_lock );
     162   
     163    }
     164} // end ctx_idle()
    160165
    161                       "add      $27,    %1,     $0      \n"             // $27<= &next_ctx
     166/////////////////////////////////////////////////////////////////////////////////
     167// The address of this functionis used to initialise the return address
     168// in the "idle" task context.
     169/////////////////////////////////////////////////////////////////////////////////
     170void _ctx_eret()
     171{
     172    asm volatile("eret");
     173}
    162174
    163                       "lw       $26,    35*4($27)       \n"
    164                       "mtc2     $26,    $0          \n"         // restore PTPR
    165                       "lw       $26,    0*4($27)        \n"
    166                       "mtc0     $26,    $12                     \n"             // restore SR
    167                       ".set noat                    \n"
    168                       "lw       $1,     1*4($27)        \n"             // restore $1
    169                       ".set at                      \n"
    170                           "lw       $2,     2*4($27)    \n"             // restore $2
    171                       "lw       $3,     3*4($27)    \n"         // restore $3
    172                       "lw       $4,     4*4($27)    \n"         // restore $4
    173                       "lw       $5,     5*4($27)    \n"         // restore $5
    174                       "lw       $6,     6*4($27)    \n"         // restore $6
    175                       "lw       $7,     7*4($27)    \n"         // restore $7
    176                       "lw       $8,     8*4($27)    \n"         // restore $8
    177                       "lw       $9,     9*4($27)    \n"         // restore $9
    178                       "lw       $10,    10*4($27)   \n"         // restore $10
    179                       "lw       $11,    11*4($27)   \n"         // restore $11
    180                       "lw       $12,    12*4($27)   \n"         // restore $12
    181                       "lw       $13,    13*4($27)   \n"         // restore $13
    182                       "lw       $14,    14*4($27)   \n"         // restore $14
    183                       "lw       $15,    15*4($27)   \n"         // restore $15
    184                       "lw       $16,    16*4($27)   \n"         // restore $16
    185                       "lw       $17,    17*4($27)   \n"         // restore $17
    186                       "lw       $18,    18*4($27)   \n"         // restore $18
    187                       "lw       $19,    19*4($27)   \n"         // restore $19
    188                       "lw       $20,    20*4($27)   \n"         // restore $20
    189                       "lw       $21,    21*4($27)   \n"         // restore $21
    190                       "lw       $22,    22*4($27)   \n"         // restore $22
    191                       "lw       $23,    23*4($27)   \n"         // restore $23
    192                       "lw       $24,    24*4($27)   \n"         // restore $24
    193                       "lw       $25,    25*4($27)   \n"         // restore $25
    194                       "lw       $26,    26*4($27)   \n"
    195                       "mtlo     $26                 \n"         // restore LO
    196                       "lw       $26,    27*4($27)   \n"
    197                       "mthi     $26                 \n"         // restore HI
    198                       "lw       $28,    28*4($27)   \n"         // restore $28
    199                       "lw       $29,    29*4($27)   \n"         // restore $29
    200                       "lw       $30,    30*4($27)   \n"         // restore $30
    201                       "lw       $31,    31*4($27)   \n"         // restore $31
    202                       "lw       $26,    32*4($27)   \n"
    203                       "mtc0     $26,    $14         \n"         // restore EPC
    204                       "lw       $26,    33*4($27)   \n"
    205                       "mtc0     $26,    $13         \n"         // restore CR
    206175
    207                       "ori              $27,    $0,             0xF \n"
    208                       "mtc2             $27,    $1          \n"         // activate DTLB
    209                       :
    210                       : "r"(curr_ctx_paddr), "r"(next_ctx_paddr)
    211                       : "$1" ,            "$4" ,"$5" ,"$6" ,"$7" ,"$8" ,"$9" ,"$10",
    212                         "$11","$12","$13","$14","$15","$16","$17","$18","$19","$20",
    213                         "$21","$22","$23","$24","$25","$26","$27",      "$29",
    214                         "$31" );
    215 */
    216     }
    217 } // end _ctx_switch
    218 
  • soft/giet_vm/sys/ctx_handler.h

    r189 r199  
    1616} static_scheduler_t;
    1717
     18
     19/////////////////////////////////////////////////////////////////////////////////
     20//  "idle" task index definition
     21/////////////////////////////////////////////////////////////////////////////////
     22
     23#define IDLE_TASK_INDEX         14
     24
    1825/////////////////////////////////////////////////////////////////////////////////
    1926//      Definition of the task context slots indexes
    2027/////////////////////////////////////////////////////////////////////////////////
    2128
    22 #define CTX_SR_ID               0
    2329#define CTX_SP_ID               29
    2430#define CTX_RA_ID               31
     
    2632#define CTX_EPC_ID              32
    2733#define CTX_CR_ID               33
    28 #define CTX_PTPR_ID             35
    29 #define CTX_MODE_ID             36
     34#define CTX_SR_ID               34
     35#define CTX_BVAR_ID             35
     36
     37#define CTX_PTPR_ID             39
    3038
    3139#define CTX_TTY_ID              40
    3240#define CTX_FBDMA_ID    41
    33 #define CTX_PTAB_ID             42
    34 #define CTX_TASK_ID             43
    35 #define CTX_SCHED_ID    44
    36 #define CTX_TIMER_ID    45
     41#define CTX_NIC_ID              42
     42#define CTX_TIMER_ID    43
     43#define CTX_PTAB_ID             44
     44#define CTX_LTID_ID             45
     45#define CTX_VSID_ID             46
     46#define CTX_RUN_ID              47
    3747
    3848//////////////////////////////////////////////////////////////////////////////////
     
    4151
    4252extern void _ctx_switch();
     53extern void _ctx_eret();
     54extern void _ctx_idle();
    4355
    4456extern static_scheduler_t _scheduler[];
  • soft/giet_vm/sys/drivers.c

    r189 r199  
    162162{
    163163    unsigned int buffer     = value;
    164     unsigned int timer_id   = _get_current_context_slot(CTX_TIMER_ID);
     164    unsigned int task_id    = _get_current_task_id();
     165    unsigned int timer_id   = _get_context_slot(task_id, CTX_TIMER_ID);
    165166    unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX);
    166167    unsigned int local_id   = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX);
     
    190191                          unsigned int* buffer )
    191192{
    192     unsigned int timer_id   = _get_current_context_slot(CTX_TIMER_ID);
     193    unsigned int task_id    = _get_current_task_id();
     194    unsigned int timer_id   = _get_context_slot(task_id, CTX_TIMER_ID);
    193195    unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX);
    194196    unsigned int local_id   = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX);
     
    232234//      _tty_error()
    233235////////////////////////////////////////////////////////////////////////////////
    234 void _tty_error()
    235 {
    236     unsigned int task_id = _get_current_task_id();
     236void _tty_error( unsigned int task_id )
     237{
    237238    unsigned int proc_id = _procid();
    238239
     
    259260    unsigned int        nwritten;
    260261
    261     unsigned int        tty_id = _get_current_context_slot(CTX_TTY_ID);
     262    unsigned int task_id  = _get_current_task_id();
     263    unsigned int tty_id   = _get_context_slot(task_id, CTX_TTY_ID);
     264
    262265    if ( tty_id >= NB_TTYS )
    263266    {
    264         _tty_error();
     267        _tty_error( task_id );
    265268        return 0;
    266269    }
     
    291294                            unsigned int        length)
    292295{
    293     unsigned int        tty_id = _get_current_context_slot(CTX_TTY_ID);
     296    unsigned int task_id  = _get_current_task_id();
     297    unsigned int tty_id   = _get_context_slot(task_id, CTX_TTY_ID);
    294298
    295299    if ( tty_id >= NB_TTYS )
    296300    {
    297         _tty_error();
     301        _tty_error( task_id );
    298302        return 0;
    299303    }
     
    320324                        unsigned int    length)
    321325{
    322     unsigned int        tty_id = _get_current_context_slot(CTX_TTY_ID);
     326    unsigned int task_id  = _get_current_task_id();
     327    unsigned int tty_id   = _get_context_slot(task_id, CTX_TTY_ID);
     328
    323329    if ( tty_id >= NB_TTYS )
    324330    {
    325         _tty_error();
     331        _tty_error( task_id );
    326332        return 0;
    327333    }
     
    544550
    545551    // get user space page table virtual address
    546     unsigned int user_pt_vbase = _get_current_context_slot(CTX_PTAB_ID);
     552    unsigned int task_id       = _get_current_task_id();
     553    unsigned int user_pt_vbase = _get_context_slot( task_id, CTX_PTAB_ID );
    547554   
    548555    user_vpn_min = user_vaddr >> 12;
     
    815822
    816823    // get DMA channel and compute DMA vbase address
    817     unsigned int        dma_id     = _get_current_context_slot(CTX_FBDMA_ID);
     824    unsigned int        task_id    = _get_current_task_id();
     825    unsigned int        dma_id     = _get_context_slot( task_id, CTX_FBDMA_ID );
    818826    unsigned int    cluster_id = dma_id / NB_DMAS_MAX;
    819827    unsigned int    loc_id     = dma_id % NB_DMAS_MAX;
     
    830838
    831839    // get user space page table virtual address
    832     unsigned int        user_ptab = _get_current_context_slot(CTX_PTAB_ID);
     840    unsigned int        user_ptab = _get_context_slot( task_id, CTX_PTAB_ID );
    833841
    834842    // compute frame buffer pbase address
     
    985993unsigned int _fb_completed()
    986994{
    987     unsigned int dma_id = _get_current_context_slot(CTX_FBDMA_ID);
     995    unsigned int task_id = _get_current_task_id();
     996    unsigned int dma_id  = _get_context_slot( task_id, CTX_FBDMA_ID );
    988997
    989998    // busy waiting with a pseudo random delay between bus access
  • soft/giet_vm/sys/exc_handler.c

    r189 r199  
    1010
    1111#include <exc_handler.h>
     12#include <ctx_handler.h>
    1213#include <sys_handler.h>
    1314#include <drivers.h>
     
    5354};
    5455
    55 static const char *exc_message_causes[] = {
    56     "\n\nException : strange unknown cause\n",
    57     "\n\nException : illegal read address \n",
    58     "\n\nException : illegal write address\n",
    59     "\n\nException : inst bus error       \n",
    60     "\n\nException : data bus error       \n",
    61     "\n\nException : breakpoint           \n",
    62     "\n\nException : reserved instruction \n",
    63     "\n\nException : illegal coproc access\n"
    64     "\n\nException : arithmetic overflow  \n",
     56static const char* exc_type[] = {
     57    "strange unknown cause",
     58    "illegal read address",
     59    "illegal write address",
     60    "inst bus error",
     61    "data bus error",
     62    "breakpoint",
     63    "reserved instruction",
     64    "illegal coproc access"
     65    "arithmetic overflow",
    6566};
    6667
    67 static void _cause(unsigned int msg_cause)
     68static void _display_cause(unsigned int type)
    6869{
    69     _puts( (char*)(exc_message_causes[msg_cause]) );
    70     _puts("\n - Cycle     : ");
     70    _puts("\n[GIET] Exception for task ");
     71    _putd( _get_current_task_id() );
     72    _puts(" on processor ");
     73    _putd( _procid() );
     74    _puts(" at cycle ");
    7175    _putd( _proctime() );
    72     _puts("\n - Processor : ");
    73     _putd( _procid() );
    74     _puts("\n - Task      : ");
    75     _putd( _get_current_task_id() );
     76    _puts("\n - type      : ");
     77    _puts( (char*)exc_type[type] );
    7678    _puts("\n - EPC       : ");
    7779    _putw( _get_epc() );
     
    7981    _putw( _get_bvar() );
    8082    _puts("\n");
    81     _exit();
     83
     84    // goes to sleeping state
     85    unsigned int task_id = _get_current_task_id();
     86    _set_context_slot( task_id, CTX_RUN_ID, 0 );
     87   
     88    // deschedule
     89    _ctx_switch();
    8290}
    8391
    84 static void _cause_ukn()  { _cause(0); }
    85 static void _cause_adel() { _cause(1); }
    86 static void _cause_ades() { _cause(2); }
    87 static void _cause_ibe()  { _cause(3); }
    88 static void _cause_dbe()  { _cause(4); }
    89 static void _cause_bp()   { _cause(5); }
    90 static void _cause_ri()   { _cause(6); }
    91 static void _cause_cpu()  { _cause(7); }
    92 static void _cause_ovf()  { _cause(8); }
     92static void _cause_ukn()  { _display_cause(0); }
     93static void _cause_adel() { _display_cause(1); }
     94static void _cause_ades() { _display_cause(2); }
     95static void _cause_ibe()  { _display_cause(3); }
     96static void _cause_dbe()  { _display_cause(4); }
     97static void _cause_bp()   { _display_cause(5); }
     98static void _cause_ri()   { _display_cause(6); }
     99static void _cause_cpu()  { _display_cause(7); }
     100static void _cause_ovf()  { _display_cause(8); }
    93101
  • 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()
  • soft/giet_vm/sys/mips32_registers.h

    r189 r199  
    4747/* CP0 registers */
    4848
    49 #define CP0_BAR                 $8
     49#define CP0_BVAR                $8
    5050#define CP0_TIME                $9
    5151#define CP0_SR                  $12
  • soft/giet_vm/sys/switch.s

    r189 r199  
    22* This function receives two arguments that are the current task context
    33* physical addresses and the next task context physical address.
     4* The DTLB is temporary desactivated...
    45******************************************************************************/
    56
     
    1718    add     $27,    $4,     $0  /* $27 <= &context[curr_task_id] */
    1819
    19     mfc0    $26,    $12         /* $26 <= SR */
    20     sw      $26,    0*4($27)    /* ctx[0] <= SR */
    2120    .set noat
    2221    sw      $1,     1*4($27)    /* ctx[1] <= $1 */
     
    4746    sw      $25,    25*4($27)   /* ctx[25] <= $25 */
    4847    mflo    $26
    49     sw      $26,    26*4($27)   /* ctx[26] <= LO */
     48    sw      $26,    26*4($27)   /* ctx[26] <= LO  */
    5049    mfhi    $26
    51     sw      $26,    27*4($27)   /* ctx[27] <= H1 */
     50    sw      $26,    27*4($27)   /* ctx[27] <= H1  */
    5251    sw      $28,    28*4($27)   /* ctx[28] <= $28 */
    5352    sw      $29,    29*4($27)   /* ctx[29] <= $29 */
     
    5756    sw      $26,    32*4($27)   /* ctx[32] <= EPC */
    5857    mfc0    $26,    $13
    59     sw      $26,    33*4($27)   /* ctx[33] <= CR */
     58    sw      $26,    33*4($27)   /* ctx[33] <= CR  */
     59    mfc0    $26,    $12
     60    sw      $26,    34*4($27)   /* ctx[34] <= SR  */
     61    mfc0    $26,    $8
     62    sw      $26,    35*4($27)   /* ctx[34] <= BVAR */
    6063    mfc2    $26,    $0
    61     sw      $26,    35*4($27)   /* ctx[35] <= PTPR */
     64    sw      $26,    39*4($27)   /* ctx[35] <= PTPR */
    6265
    6366    /* restore next task context */
    6467    add     $27,    $5,     $0  /* $27<= &context[next_task_id] */
    6568
    66     lw      $26,    35*4($27)
    67     mtc2    $26,    $0          /* restore PTPR */
    68     lw      $26,    0*4($27)
    69     mtc0    $26,    $12         /* restore SR */
    7069    .set noat
    7170    lw      $1,     1*4($27)    /* restore $1 */
     
    107106    lw      $26,    33*4($27)
    108107    mtc0    $26,    $13         /* restore CR */
     108    lw      $26,    34*4($27)
     109    mtc0    $26,    $12         /* restore SR */
     110    lw      $26,    35*4($27)
     111    mtc0    $26,    $8          /* restore BVAR */
     112    lw      $26,    39*4($27)
     113    mtc2    $26,    $0          /* restore PTPR */
    109114
    110115    /* activate DTLB */
  • soft/giet_vm/sys/sys_handler.c

    r189 r199  
    7575void _exit()
    7676{
    77 /*
    7877    unsigned int date    = _proctime();
    79 
    8078    unsigned int proc_id = _procid();
    81 
    8279    unsigned int task_id = _get_current_task_id();
    8380
    8481     // print death message
    8582    _get_lock(&_tty_put_lock);
    86     _puts("\n\n!!! Exit task ");
    87     _putw( task_id );
     83    _puts("\n[GIET] Exit task ");
     84    _putd( task_id );
    8885    _puts(" on processor ");
    89     _putw( proc_id );
     86    _putd( proc_id );
    9087    _puts(" at cycle ");
    91     _putw( date );
     88    _putd( date );
    9289    _puts("\n\n");
    9390    _release_lock(&_tty_put_lock);
    94 */
    9591   
    96     /* infinite loop */
    97     while (1) asm volatile("nop");
     92    // goes to sleeping state
     93    _set_context_slot( task_id, CTX_RUN_ID, 0 );
     94   
     95    // deschedule
     96    _ctx_switch();
    9897}
    9998//////////////////////////////////////////////////////////////////////////////
Note: See TracChangeset for help on using the changeset viewer.