Ignore:
Timestamp:
Oct 1, 2015, 4:20:46 PM (9 years ago)
Author:
alain
Message:

Major release: Change the task model to implement the POSIX threads API.

  • The shell "exec" and "kill" commands can be used to activate/de-activate the applications.
  • The "pause", "resume", and "context" commands can be used to stop, restart, a single thtead or to display the thread context.

This version has been tested on the following multi-threaded applications,
that have been modified to use the POSIX threads:

  • classif
  • convol
  • transpose
  • gameoflife
  • raycast
Location:
soft/giet_vm/giet_kernel
Files:
8 edited

Legend:

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

    r707 r709  
    99#include <sys_handler.h>
    1010#include <giet_config.h>
     11#include <fat32.h>
    1112#include <hard_config.h>
    1213#include <utils.h>
    1314#include <tty0.h>
    1415#include <xcu_driver.h>
     16#include <bdv_driver.h>
    1517
    1618/////////////////////////////////////////////////////////////////////////////////
     
    1921
    2022// defined in giet_kernel/switch.s file
    21 extern void _task_switch(unsigned int *, unsigned int *);
     23extern void _thread_switch( thread_context_t* , thread_context_t* );
    2224
    2325// allocated in boot.c or kernel_init.c files
    2426extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
    2527
    26 
    27 ///////////////////////////////////////////////
    28 static void _ctx_kill_task( unsigned int ltid )
     28// allocated in kernel_init.c file
     29extern fat_desc_t  _fat;
     30
     31//////////////////////////////////////////////////////////////////
     32// This function is called by the _ctx_switch() function.
     33// It desactivates a thread that received a KILL signal.
     34// We must release all ressources allocated to the thread
     35// before the actual desactivation, that uses NORUN_MASK_THREAD.
     36//////////////////////////////////////////////////////////////////
     37static void _ctx_kill_thread( unsigned int x,
     38                              unsigned int y,
     39                              unsigned int p,
     40                              unsigned int ltid )
    2941{
    3042    // get scheduler address
    31     static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
    32 
    33     // pretend the task to kill is scheduled (required for sys_handler calls)
    34     unsigned int cur_task = psched->current;
     43    static_scheduler_t* psched = _schedulers[x][y][p];
     44
     45    // pretend the thread to kill is the currently scheduled thread
     46    // (required by the _sys_***_release() calls)
     47    unsigned int cur_thread = psched->current;
    3548    psched->current = ltid;
    3649
     50    // release BDV lock if taken and reset BDV peripheral
     51    if ( psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_BDV )
     52    {
     53        _bdv_set_register( BLOCK_DEVICE_STATUS , 0 );
     54        _spin_lock_release( &_bdv_lock );
     55    }
     56
     57    // release FAT lock if taken
     58    if ( psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_FAT )
     59    {
     60        _spin_lock_release( &_fat.fat_lock );
     61    }
     62
    3763    // release private TTY terminal if required
    38     if ( psched->context[ltid][CTX_TTY_ID] < NB_TTY_CHANNELS )
    39     {
    40         _sys_tty_release();
    41         psched->context[ltid][CTX_TTY_ID] = -1;
    42     }
     64    if ( psched->context[ltid].slot[CTX_TTY_ID] < NB_TTY_CHANNELS )
     65        _sys_tty_release();
    4366
    4467    // release private TIM channel if required
    45     if ( psched->context[ltid][CTX_TIM_ID] < NB_TIM_CHANNELS )
     68
     69    if ( psched->context[ltid].slot[CTX_TIM_ID] < NB_TIM_CHANNELS )
    4670    {
    4771        _sys_tim_release();
    48         psched->context[ltid][CTX_TIM_ID] = -1;
    49     }
    50 
    51     // release private NIC_RX channel if required
    52     if ( psched->context[ltid][CTX_NIC_RX_ID] < NB_NIC_CHANNELS )
     72    }
     73
     74    // release private NIC_RX and CMA_RX channels if required
     75    if ( psched->context[ltid].slot[CTX_NIC_RX_ID] < NB_NIC_CHANNELS )
    5376    {
    5477        _sys_nic_release( 1 );
    55         psched->context[ltid][CTX_NIC_RX_ID] = -1;
    56     }
    57 
    58     // release private NIC_TX channel if required
    59     if ( psched->context[ltid][CTX_NIC_TX_ID] < NB_NIC_CHANNELS )
     78    }
     79
     80    // release private NIC_TX and CMA_TX channels if required
     81    if ( psched->context[ltid].slot[CTX_NIC_TX_ID] < NB_NIC_CHANNELS )
    6082    {
    6183        _sys_nic_release( 0 );
    62         psched->context[ltid][CTX_NIC_TX_ID] = -1;
    6384    }
    6485
    6586    // release private FBF_CMA channel if required
    66     if ( psched->context[ltid][CTX_CMA_FB_ID] < NB_CMA_CHANNELS )
     87    if ( psched->context[ltid].slot[CTX_CMA_FB_ID] < NB_CMA_CHANNELS )
    6788    {
    6889        _sys_fbf_cma_release();
    69         psched->context[ltid][CTX_CMA_FB_ID] = -1;
    70     }
    71 
    72     // restore scheduled task
    73     psched->current = cur_task;
    74 
    75     // set NORUN_MASK_TASK bit
    76     _atomic_or( &psched->context[ltid][CTX_NORUN_ID], NORUN_MASK_TASK );
    77 
    78 } // end _ctx_kill_task()
    79 
    80 
    81 //////////////////////////////////
    82 void _ctx_display( unsigned int x,
    83                    unsigned int y,
    84                    unsigned int p,
    85                    unsigned int ltid,
    86                    char*        string )
    87 {
    88     static_scheduler_t* psched = _schedulers[x][y][p];
    89     _printf("\n########## task[%d,%d,%d,%d] context\n"
    90             " - CTX_EPC   = %x\n"
    91             " - CTX_PTAB  = %x\n"
    92             " - CTX_PTPR  = %x\n"
    93             " - CTX_VSID  = %x\n"
    94             " - CTX_SR    = %x\n"
    95             " - CTX_RA    = %x\n"
    96             " - CTX_SP    = %x\n"
    97             " - CTX_NORUN = %x\n"
    98             " - CTX_SIG   = %x\n"
    99             "########## %s\n",
    100             x , y , p , ltid ,
    101             psched->context[ltid][CTX_EPC_ID],
    102             psched->context[ltid][CTX_PTAB_ID],
    103             psched->context[ltid][CTX_PTPR_ID],
    104             psched->context[ltid][CTX_VSID_ID],
    105             psched->context[ltid][CTX_SR_ID],
    106             psched->context[ltid][CTX_RA_ID],
    107             psched->context[ltid][CTX_SP_ID],
    108             psched->context[ltid][CTX_NORUN_ID],
    109             psched->context[ltid][CTX_SIG_ID],
    110             string );
    111 }  // _ctx_display()
     90    }
     91
     92    // restore scheduled thread index
     93    psched->current = cur_thread;
     94
     95    // set NORUN_MASK_THREAD bit to desactivate the target thread
     96    psched->context[ltid].slot[CTX_NORUN_ID] = NORUN_MASK_THREAD;
     97
     98} // end _ctx_kill_thread()
    11299
    113100
    114101//////////////////
    115102void _ctx_switch()
    116 {
    117     unsigned int gpid       = _get_procid();
    118     unsigned int cluster_xy = gpid >> P_WIDTH;
    119     unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
    120 
    121     // get scheduler address
    122     static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
    123 
    124     // get number of tasks allocated to scheduler
    125     unsigned int tasks = psched->tasks;
    126 
    127     // get current task index
    128     unsigned int curr_task_id = psched->current;
    129 
    130     // select the next task using a round-robin policy
    131     unsigned int next_task_id;
    132     unsigned int tid;
    133     unsigned int found = 0;
    134 
    135     for (tid = curr_task_id + 1; tid < curr_task_id + 1 + tasks; tid++)
    136     {
    137         next_task_id = tid % tasks;
    138 
    139         // this task needs to be killed
    140         if ( psched->context[next_task_id][CTX_SIG_ID] & SIG_MASK_KILL )
    141         {
    142             // acknowledge signal
    143             _atomic_and( &psched->context[next_task_id][CTX_SIG_ID], ~SIG_MASK_KILL );
    144 
    145             _ctx_kill_task( next_task_id );
    146         }
    147 
    148         // test if the task is runable
    149         if ( psched->context[next_task_id][CTX_NORUN_ID] == 0 )
    150         {
    151             found = 1;
    152             // TODO: don't break to process all pending signals.
    153             break;
    154         }
    155     }
    156 
    157     // launch "idle" task if no runable task
    158     if (found == 0) next_task_id = IDLE_TASK_INDEX;
    159 
    160 #if ( GIET_DEBUG_SWITCH & 0x1 )
    161 unsigned int x = cluster_xy >> Y_WIDTH;
    162 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
    163 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    164 _printf("\n[DEBUG SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n",
    165         curr_task_id, next_task_id, x, y , lpid, _get_proctime() );
    166 #endif
    167 
    168     if (curr_task_id != next_task_id)  // actual task switch required
    169     {
    170         unsigned int* curr_ctx_vaddr = &(psched->context[curr_task_id][0]);
    171         unsigned int* next_ctx_vaddr = &(psched->context[next_task_id][0]);
    172 
    173         // reset TICK timer counter.
    174         _xcu_timer_reset_cpt( cluster_xy, lpid );
    175 
    176         // set current task index
    177         psched->current = next_task_id;
    178 
    179         // makes context switch
    180         _task_switch( curr_ctx_vaddr , next_ctx_vaddr );
    181     }
    182 } //end _ctx_switch()
    183 
    184 
    185 /////////////////
    186 void _idle_task()
    187103{
    188104    unsigned int gpid       = _get_procid();
     
    192108    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
    193109
     110    unsigned int ltid;     // index for loops on threads in scheduler
     111
     112    // get calling thread scheduler address
     113    static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
     114
     115    // get number of threads allocated to scheduler
     116    unsigned int threads = psched->threads;
     117
     118    // get current thread ltid
     119    unsigned int curr_thread_id = psched->current;
     120
     121    // first loop on threads: handle all pending KILL signals
     122    for ( ltid = 0 ; ltid < threads ; ltid++ )
     123    {
     124        if ( psched->context[ltid].slot[CTX_SIGS_ID] & SIGS_MASK_KILL )
     125        {
     126            // acknowledge KILL signal
     127            _atomic_and( &psched->context[ltid].slot[CTX_SIGS_ID], ~SIGS_MASK_KILL );
     128
     129            // desactivate the killed thread
     130            _ctx_kill_thread( x , y , p , ltid );
     131        }
     132    }
     133
     134    // second loop: select next thread using a round-robin policy
     135    unsigned int next_thread_id;
     136    unsigned int found = 0;
     137    for ( ltid = curr_thread_id + 1 ; ltid < (curr_thread_id + 1 + threads) ; ltid++ )
     138    {
     139        next_thread_id = ltid % threads;
     140
     141        // test if the thread is runable
     142        if ( psched->context[next_thread_id].slot[CTX_NORUN_ID] == 0 )
     143        {
     144            found = 1;
     145            break;
     146        }
     147    }
     148
     149    // launch idle_thread if no runable thread
     150    if ( found == 0 ) next_thread_id = IDLE_THREAD_INDEX;
     151
     152    if ( curr_thread_id != next_thread_id )  // actual thread switch required
     153    {
     154
     155#if GIET_DEBUG_SWITCH
     156unsigned int x = cluster_xy >> Y_WIDTH;
     157unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     158if ( (_get_proctime() > GIET_DEBUG_SWITCH) && (x == 0) && (y == 0) && (p == 0) )
     159_printf("\n[DEBUG SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n",
     160        curr_thread_id, next_thread_id, x, y , p, _get_proctime() );
     161#endif
     162
     163        thread_context_t* curr_ctx_vaddr = &(psched->context[curr_thread_id]);
     164        thread_context_t* next_ctx_vaddr = &(psched->context[next_thread_id]);
     165
     166        // reset TICK timer counter.
     167        _xcu_timer_reset_cpt( cluster_xy, p );
     168
     169        // set current thread index
     170        psched->current = next_thread_id;
     171
     172        // makes context switch
     173        _thread_switch( curr_ctx_vaddr , next_ctx_vaddr );
     174    }
     175} //end _ctx_switch()
     176
     177
     178///////////////////
     179void _idle_thread()
     180{
     181    unsigned int gpid       = _get_procid();
     182    unsigned int cluster_xy = gpid >> P_WIDTH;
     183    unsigned int x          = cluster_xy >> Y_WIDTH;
     184    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
     185    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
     186
    194187    while(1)
    195188    {
    196189        // initialize counter
    197         unsigned int count = GIET_IDLE_TASK_PERIOD;
     190        unsigned int count = GIET_IDLE_THREAD_PERIOD;
    198191
    199192        // decounting loop
    200193        asm volatile(
    201194                "move   $3,   %0              \n"
    202                 "_idle_task_loop:             \n"
     195                "_idle_thread_loop:             \n"
    203196                "addi   $3,   $3,   -1        \n"
    204                 "bnez   $3,   _idle_task_loop \n"
     197                "bnez   $3,   _idle_thread_loop \n"
    205198                "nop                          \n"
    206199                :
  • soft/giet_vm/giet_kernel/ctx_handler.h

    r707 r709  
    66/////////////////////////////////////////////////////////////////////////////////
    77// The ctx_handler.h and ctx_handler.c files are part of the GIET-VM nano-kernel.
    8 // This code is used to support context switch when several tasks are executing
     8// This code is used to support context switch when several threads are executing
    99// in time multiplexing on a single processor.
    10 // The tasks are statically allocated to a processor in the boot phase, and
     10// The threads are statically allocated to a processor in the boot phase, and
    1111// there is one private scheduler per processor. Each sheduler occupies 8K bytes,
    12 // and contains up to 14 task contexts (task_id is from 0 to 13).
    13 // The task context [13] is reserved for the "idle" task that does nothing, and
    14 // is launched by the scheduler when there is no other runable task.
     12// and contains up to 14 thread contexts (thread_id is from 0 to 13).
     13// The thread context [13] is reserved for the "idle" thread that is
     14// launched by the scheduler when there is no other runable thread.
    1515/////////////////////////////////////////////////////////////////////////////////
    16 // A task context is an array of 64 uint32 words => 256 bytes.
    17 // It contains copies of processor registers (when the task is preempted)
    18 // and some general informations associated to a task, such as the private
    19 // peripheral channels allocated to the task, the vspace index, the various
    20 // task index (local / global / application), and the runnable status.
     16// A thread context is an array of 64 uint32 words => 256 bytes.
     17// It contains copies of processor registers (when the thread is preempted)
     18// and some general informations associated to a thread, such as the private
     19// peripheral channels allocated to the thread, the vspace index, the two
     20// thread index, and the runnable status.
    2121/////////////////////////////////////////////////////////////////////////////////
    2222// ctx[0] <- ***   |ctx[8] <- $8     |ctx[16]<- $16    |ctx[24]<- $24
     
    2424// ctx[2] <- $2    |ctx[10]<- $10    |ctx[18]<- $18    |ctx[26]<- LO
    2525// ctx[3] <- $3    |ctx[11]<- $11    |ctx[19]<- $19    |ctx[27]<- HI
    26 // ctx[4] <- $4    |ctx[12]<- $12    |ctx[20]<- $20    |ctx[28]<- $28
    27 // ctx[5] <- $5    |ctx[13]<- $13    |ctx[21]<- $21    |ctx[29]<- SP
    28 // ctx[6] <- $6    |ctx[14]<- $14    |ctx[22]<- $22    |ctx[30]<- $30
    29 // ctx[7] <- $7    |ctx[15]<- $15    |ctx[23]<- $23    |ctx[31]<- RA
     26// ctx[4] <- A0    |ctx[12]<- $12    |ctx[20]<- $20    |ctx[28]<- $28
     27// ctx[5] <- A1    |ctx[13]<- $13    |ctx[21]<- $21    |ctx[29]<- SP
     28// ctx[6] <- A2    |ctx[14]<- $14    |ctx[22]<- $22    |ctx[30]<- $30
     29// ctx[7] <- A3    |ctx[15]<- $15    |ctx[23]<- $23    |ctx[31]<- RA
    3030//
    3131// ctx[32]<- EPC   |ctx[40]<- TTY    |ctx[48]<- TRDID  |ctx[56]<- ***
    32 // ctx[33]<- CR    |ctx[41]<- CMA_FB |ctx[49]<- GTID   |ctx[57]<- ***
     32// ctx[33]<- CR    |ctx[41]<- CMA_FB |ctx[49]<- LTID   |ctx[57]<- ***
    3333// ctx[34]<- SR    |ctx[42]<- CMA_RX |ctx[50]<- NORUN  |ctx[58]<- ***
    3434// ctx[35]<- BVAR  |ctx[43]<- CMA_TX |ctx[51]<- COPROC |ctx[59]<- ***
    3535// ctx[36]<- PTAB  |ctx[44]<- NIC_RX |ctx[52]<- ENTRY  |ctx[60]<- ***
    36 // ctx[37]<- LTID  |ctx[45]<- NIC_TX |ctx[53]<- SIG    |ctx[61]<- ***
    37 // ctx[38]<- VSID  |ctx[46]<- TIM    |ctx[54]<- ***    |ctx[62]<- ***
    38 // ctx[39]<- PTPR  |ctx[47]<- HBA    |ctx[55]<- ***    |ctx[63]<- ***
     36// ctx[37]<- ***   |ctx[45]<- NIC_TX |ctx[53]<- SIGS   |ctx[61]<- ***
     37// ctx[38]<- ***   |ctx[46]<- TIM    |ctx[54]<- VSID   |ctx[62]<- ***
     38// ctx[39]<- PTPR  |ctx[47]<- HBA    |ctx[55]<- LOCKS  |ctx[63]<- ***
    3939/////////////////////////////////////////////////////////////////////////////////
    4040
     
    4545
    4646/////////////////////////////////////////////////////////////////////////////////
    47 //    Definition of the task context slots indexes
     47//    Definition of some thread context slots indexes
    4848/////////////////////////////////////////////////////////////////////////////////
     49
     50#define CTX_A0_ID        4     // Argument 0
     51#define CTX_A1_ID        5     // Argument 1
     52#define CTX_A2_ID        6     // Argument 2
     53#define CTX_A3_ID        7     // Argument 3
    4954
    5055#define CTX_SP_ID        29    // Stack Pointer
     
    5661#define CTX_BVAR_ID      35        // Bad Virtual Address Register (CP0)
    5762#define CTX_PTAB_ID      36    // Page Table Virtual address
    58 #define CTX_LTID_ID      37    // Local  Task Index (in scheduler)
    59 #define CTX_VSID_ID      38    // Vspace Index     
     63//                       37
     64//                       38
    6065#define CTX_PTPR_ID      39    // Page Table Pointer Register (PADDR>>13)
    6166
     
    6974#define CTX_HBA_ID       47    // private HBA channel index
    7075
    71 #define CTX_TRDID_ID     48    // Thread Task Index in vspace
    72 #define CTX_GTID_ID      49    // Global Task Index in all system
    73 #define CTX_NORUN_ID     50    // bit-vector : task runable if all zero
    74 #define CTX_COPROC_ID    51    // cluster_xy : coprocessor coordinates
    75 #define CTX_ENTRY_ID     52    // Virtual address of task entry point
    76 #define CTX_SIG_ID       53    // bit-vector : pending signals for task
     76#define CTX_TRDID_ID     48    // Global Thread Index ( x | y | p | ltid )
     77#define CTX_LTID_ID      49    // Local Thread Index in scheduler
     78#define CTX_NORUN_ID     50    // bit-vector : thread runable if all zero
     79#define CTX_COPROC_ID    51    // coprocessor coordinates (cluster_xy)
     80#define CTX_ENTRY_ID     52    // Virtual address of thread entry point
     81#define CTX_SIGS_ID      53    // bit-vector : pending signals
     82#define CTX_VSID_ID      54    // Vspace Index     
     83#define CTX_LOCKS_ID     55    // bit-vector : kernel locks taken
    7784
    7885/////////////////////////////////////////////////////////////////////////////////
     
    8087/////////////////////////////////////////////////////////////////////////////////
    8188
    82 #define NORUN_MASK_TASK       0x00000001   // Task not active 
     89#define NORUN_MASK_THREAD     0x00000001   // Task not active 
    8390#define NORUN_MASK_IOC        0x00000002   // Task blocked on IOC transfer
    8491#define NORUN_MASK_COPROC     0x00000004   // Task blocked on COPROC transfer
     92#define NORUN_MASK_TTY        0x00000008   // Task blocked on TTY_RX transfer
    8593
    8694/////////////////////////////////////////////////////////////////////////////////
    87 //    Definition of the SIG bit-vector masks
     95//    Definition of the SIGS bit-vector masks
    8896/////////////////////////////////////////////////////////////////////////////////
    8997
    90 #define SIG_MASK_KILL         0x00000001   // Task will be killed at next tick
     98#define SIGS_MASK_KILL        0x00000001   // Task desactivated at next tick
    9199
    92100/////////////////////////////////////////////////////////////////////////////////
    93 //    Definition of the scheduler structure
     101//    Definition of the LOCKS bit-vector masks
    94102/////////////////////////////////////////////////////////////////////////////////
    95103
    96 typedef struct static_scheduler_s
     104#define LOCKS_MASK_BDV        0x00000001   // BDV kernel lock taken
     105#define LOCKS_MASK_FAT        0x00000002   // FAT kernel lock taken
     106
     107/////////////////////////////////////////////////////////////////////////////////
     108//    Task context and  scheduler structures
     109/////////////////////////////////////////////////////////////////////////////////
     110
     111typedef struct thread_context_s             // 256 bytes
    97112{
    98     unsigned int context[14][64];      // at most 14 task (including idle_task)
    99     unsigned int tasks;                // actual number of tasks
    100     unsigned int current;              // current task index
    101     unsigned int hwi_vector[32];       // hardware interrupt vector
    102     unsigned int pti_vector[32];       // timer    interrupt vector
    103     unsigned int wti_vector[32];       // software interrupt vector
    104     unsigned int reserved[30];         // padding to 4 Kbytes
    105     unsigned int idle_stack[1024];     // private stack for idle stack (4Kbytes)
     113    unsigned int slot[64];     
     114} thread_context_t;
     115
     116
     117typedef struct static_scheduler_s           // 8 Kbytes
     118{
     119    thread_context_t  context[14];          // at most 14 threads (including idle_thread)
     120    unsigned int      threads;              // actual number of allocated threads
     121    unsigned int      current;              // current thread index
     122    unsigned int      hwi_vector[32];       // hardware interrupt vector
     123    unsigned int      pti_vector[32];       // timer    interrupt vector
     124    unsigned int      wti_vector[32];       // software interrupt vector
     125    unsigned int      reserved[30];         // padding to 4 Kbytes
     126    unsigned int      idle_stack[1024];     // private stack for idle stack (4Kbytes)
    106127} static_scheduler_t;
    107128
    108 #define IDLE_TASK_INDEX        13
     129#define IDLE_THREAD_INDEX        13
    109130
    110131
     
    114135
    115136/////////////////////////////////////////////////////////////////////////////////
    116 // This function performs a context switch between the running task
    117 // and  another task, using a round-robin sheduling policy between all
    118 // tasks allocated to a given processor (static allocation).
    119 // It selects the next runable task to resume execution.
    120 // If the only runable task is the current task, return without context switch.
    121 // If there is no runable task, the scheduler switch to the default "idle" task.
    122 // The return address contained in $31 is saved in the current task context
     137// This function performs a context switch between the running thread
     138// and  another thread, using a round-robin sheduling policy between all
     139// threads allocated to a given processor (static allocation).
     140// It selects the next runable thread to resume execution.
     141// If the only runable thread is the current thread, return without context switch.
     142// If there is no runable thread, the scheduler switch to the default "idle" thread.
     143// The return address contained in $31 is saved in the current thread context
    123144// (in the ctx[31] slot), and the function actually returns to the address
    124 // contained in the ctx[31] slot of the next task context.
     145// contained in the ctx[31] slot of the next thread context.
    125146/////////////////////////////////////////////////////////////////////////////////
    126147extern void _ctx_switch();
     
    128149/////////////////////////////////////////////////////////////////////////////////
    129150// The address of this function is used to initialise the return address
    130 // in the "idle" task context.
     151// in the "idle" thread context.
    131152/////////////////////////////////////////////////////////////////////////////////
    132153extern void _ctx_eret();
    133154
    134155/////////////////////////////////////////////////////////////////////////////////
    135 // This function is executed task when no other task can be executed.
     156// This function is executed thread when no other thread can be executed.
    136157/////////////////////////////////////////////////////////////////////////////////
    137 extern void _idle_task();
    138 
    139 /////////////////////////////////////////////////////////////////////////////////
    140 // This function displays the context of a task identified by the processor
    141 // coordinates (x,y,p), and by the local task index ltid.
    142 // The string argument can be used for debug.
    143 /////////////////////////////////////////////////////////////////////////////////
    144 extern void _ctx_display( unsigned int x,
    145                           unsigned int y,
    146                           unsigned int p,
    147                           unsigned int ltid,
    148                           char*        string );
     158extern void _idle_thread();
    149159
    150160#endif
  • soft/giet_vm/giet_kernel/exc_handler.c

    r629 r709  
    6161    unsigned int x          = cluster_xy >> Y_WIDTH;
    6262    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    63     unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
     63    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
     64    unsigned int trdid      = _get_thread_trdid();
     65    unsigned int ltid       = _get_thread_ltid();
    6466
    65     unsigned int task       = _get_context_slot(CTX_LTID_ID);
    66 
     67    static_scheduler_t*  psched = (static_scheduler_t*)_get_sched();
    6768
    6869    const char * mips32_exc_str[] = { "strange unknown cause  ",
     
    7475                                      "reserved instruction   ",
    7576                                      "illegal coproc access  ",
    76                                       "arithmetic overflow    "};
     77                                      "arithmetic overflow    " };
    7778
    78     _printf("\n[GIET] Exception for task %d on processor[%d,%d,%d] at cycle %d\n"
     79    _printf("\n[GIET] Exception for thread %x on processor[%d,%d,%d] at cycle %d\n"
    7980            " - type      : %s\n"
    8081            " - EPC       : %x\n"
    8182            " - BVAR      : %x\n"
    82             "...Task desactivated\n",
    83             task, x, y, lpid, _get_proctime(),
     83            "...Thread desactivated\n",
     84            trdid , x , y , p , _get_proctime(),
    8485            mips32_exc_str[type], _get_epc(), _get_bvar() );
    8586
    86     // goes to sleeping state
    87     _set_context_slot( CTX_NORUN_ID , 1 );
     87    // register KILL signal
     88    _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL );
    8889
    89     // deschedule
     90    // deschedule calling thread
    9091    unsigned int save_sr; 
    9192    _it_disable( &save_sr );
  • soft/giet_vm/giet_kernel/irq_handler.c

    r702 r709  
    2626#include <tty0.h>
    2727
     28////////////////////////////////////////////////////////////////////////////
     29//        Extern variables
     30////////////////////////////////////////////////////////////////////////////
     31
     32// allocated in sys_handler.c file
     33extern unsigned int _tty_channel_wti[NB_TTY_CHANNELS];
     34extern unsigned int _tim_channel_wti[NB_TIM_CHANNELS];
     35extern unsigned int _cma_channel_wti[NB_CMA_CHANNELS];
     36extern unsigned int _nic_rx_channel_wti[NB_NIC_CHANNELS];
     37extern unsigned int _nic_tx_channel_wti[NB_NIC_CHANNELS];
     38
    2839/////////////////////////////////////////////////////////////////////////
    2940//       Global variables
     
    4152__attribute__((section(".kdata")))
    4253unsigned char _wti_alloc_ter[X_SIZE][Y_SIZE][NB_PROCS_MAX];
     54
     55#define MAX_RETRY   10000
    4356
    4457/////////////////////////////////////////////////////////////////////////
     
    134147}  // end _ext_irq_init()
    135148
    136 ////////////////////////////////////////////
     149/////////////////////////////////////////////
    137150void _ext_irq_alloc( unsigned int   isr_type,
    138151                     unsigned int   isr_channel,
     
    143156    unsigned int wti_addr;      // WTI mailbox physical address (32 lsb bits)
    144157
    145     // check arguments
     158    unsigned int count = MAX_RETRY;
     159
     160    // check input arguments
    146161    if ( isr_type >= GIET_ISR_TYPE_MAX )
    147162    {
     
    163178
    164179    // allocate a WTI mailbox to proc[x,y,p] (blocking until success)
     180   
    165181    while ( 1 )
    166182    {
     183        if ( count == 0 )
     184        {
     185            unsigned int trdid = _get_context_slot( CTX_TRDID_ID );
     186            unsigned int vsid  = _get_context_slot( CTX_VSID_ID );
     187            _printf("\n[GIET WARNING] thread %x in vspace %d "
     188                    "running on P[%d,%d,%d] still waiting in _ext_irq_alloc()\n",
     189                    trdid, vsid, x, y, p );
     190            count = MAX_RETRY;
     191        }
     192
    167193        if ( _wti_alloc_one[x][y][p] == 0 )
    168194        {
     
    183209            break;
    184210        }
     211        count--;
    185212    }   
     213
    186214    *wti_index = wti_id;
    187215
     
    196224
    197225#if GIET_DEBUG_IRQS
     226if ( _get_proctime() > GIET_DEBUG_IRQS )
    198227_printf("\n[DEBUG IRQS] _ext_irq_alloc() for P[%d,%d,%d] at cycle %d\n"
    199228        "  wti_id = %d / isr_type = %s / channel = %d / pic_input = %d\n",
     
    204233}  // end ext_irq_alloc()
    205234
    206 ////////////////////////////////////////////
     235////////////////////////////////////////////////
    207236void _ext_irq_release( unsigned int isr_type,
    208                        unsigned int isr_channel )
    209 {
    210     unsigned int wti_id;        // allocated WTI mailbox index in XCU
    211     unsigned int irq_id;        // external IRQ index in PIC (input)
    212 
    213     // get processor coordinates [x,y,p]
    214     unsigned int gpid           = _get_procid();
    215     unsigned int cluster_xy     = gpid >> P_WIDTH;
    216     unsigned int x              = cluster_xy >> Y_WIDTH;
    217     unsigned int y              = cluster_xy & ((1<<Y_WIDTH)-1);
    218     unsigned int p              = gpid & ((1<<P_WIDTH)-1);
    219 
    220     // check arguments
     237                       unsigned int channel )
     238{
     239    // check input arguments
    221240    if ( isr_type >= GIET_ISR_TYPE_MAX )
    222241    {
    223         _printf("\n[GIET ERROR] in _ext_irq_release() illegal ISR type\n");
    224         _exit();
    225     }
    226     if ( isr_channel >= GIET_ISR_CHANNEL_MAX )
    227     {
    228         _printf("\n[GIET ERROR] in _ext_irq_release() : illegal ISR channel\n");
    229         _exit();
    230     }
    231 
    232     // find WTI index
    233     static_scheduler_t*  psched = (static_scheduler_t*)_get_sched();
    234     for ( wti_id = 0 ; wti_id < 32 ; wti_id++ )
    235     {
    236         if ( psched->wti_vector[wti_id] == (isr_channel<<16 | isr_type) )
    237             break;
    238     }
    239     if ( wti_id == 32 )
    240     {
    241         _printf("\n[GIET ERROR] in _ext_irq_release() : isr not found\n");
    242         return;
    243     }
    244 
     242        _printf("\n[GIET ERROR] in _ext_irq_release() : "
     243                "illegal ISR type %d\n", isr_type );
     244        _exit();
     245    }
     246    if ( channel >= GIET_ISR_CHANNEL_MAX )
     247    {
     248        _printf("\n[GIET ERROR] in _ext_irq_release() : "
     249                "illegal ISR channel %d\n", channel );
     250        _exit();
     251    }
     252
     253    // analyse ISR type to get WTI index (wti), and coordinates
     254    // of processor (x,y,p) that has been allocated the external IRQ
     255    unsigned int wti    = 0;
     256    unsigned int x      = 0;
     257    unsigned int y      = 0;
     258    unsigned int p      = 0;
     259
     260    if      ( (isr_type == ISR_TTY_RX) || (isr_type == ISR_TTY_TX) )
     261    {
     262        x       = (_tty_channel_wti[channel]>>24) & 0xFF;
     263        y       = (_tty_channel_wti[channel]>>16) & 0xFF;
     264        p       = (_tty_channel_wti[channel]>> 8) & 0xFF;
     265        wti     = (_tty_channel_wti[channel]    ) & 0xFF;
     266    }
     267#if NB_TIM_CHANNELS
     268    else if ( isr_type == ISR_TIMER )
     269    {
     270        x       = (_tim_channel_wti[channel]>>24) & 0xFF;
     271        y       = (_tim_channel_wti[channel]>>16) & 0xFF;
     272        p       = (_tim_channel_wti[channel]>> 8) & 0xFF;
     273        wti     = (_tim_channel_wti[channel]    ) & 0xFF;
     274    }
     275#endif
     276#if NB_CMA_CHANNELS
     277    else if ( isr_type == ISR_CMA )
     278    {
     279        x       = (_cma_channel_wti[channel]>>24) & 0xFF;
     280        y       = (_cma_channel_wti[channel]>>16) & 0xFF;
     281        p       = (_cma_channel_wti[channel]>> 8) & 0xFF;
     282        wti     = (_cma_channel_wti[channel]    ) & 0xFF;
     283    }
     284#endif
     285#if NB_NIC_CHANNELS
     286    else if ( isr_type == ISR_NIC_RX )
     287    {
     288        x       = (_nic_rx_channel_wti[channel]>>24) & 0xFF;
     289        y       = (_nic_rx_channel_wti[channel]>>16) & 0xFF;
     290        p       = (_nic_rx_channel_wti[channel]>> 8) & 0xFF;
     291        wti     = (_nic_rx_channel_wti[channel]    ) & 0xFF;
     292    }
     293    else if ( isr_type == ISR_NIC_TX )
     294    {
     295        x       = (_nic_tx_channel_wti[channel]>>24) & 0xFF;
     296        y       = (_nic_tx_channel_wti[channel]>>16) & 0xFF;
     297        p       = (_nic_tx_channel_wti[channel]>> 8) & 0xFF;
     298        wti     = (_nic_tx_channel_wti[channel]    ) & 0xFF;
     299    }
     300#endif
     301    else 
     302    {
     303        _printf("\n[GIET ERROR] in _ext_irq_release() : "
     304                "ISR type %s not supported / thread = %x\n",
     305                _isr_type_str[isr_type] , _get_thread_trdid() );
     306        _exit();
     307    }
     308   
    245309    // desactivates dynamically allocated PIC entry
    246     irq_id = _ext_irq_index[isr_type][isr_channel];
     310    unsigned int irq_id = _ext_irq_index[isr_type][channel];
    247311    _pic_set_register( irq_id , IOPIC_MASK , 0 );
    248312
    249313    // releases dynamically allocated WTI mailbox
    250     if      ( wti_id == p +   NB_PROCS_MAX ) _wti_alloc_one[x][y][p] = 0;
    251     else if ( wti_id == p + 2*NB_PROCS_MAX ) _wti_alloc_two[x][y][p] = 0;
    252     else if ( wti_id == p + 3*NB_PROCS_MAX ) _wti_alloc_ter[x][y][p] = 0;
     314    if      ( wti == p +   NB_PROCS_MAX ) _wti_alloc_one[x][y][p] = 0;
     315    else if ( wti == p + 2*NB_PROCS_MAX ) _wti_alloc_two[x][y][p] = 0;
     316    else if ( wti == p + 3*NB_PROCS_MAX ) _wti_alloc_ter[x][y][p] = 0;
    253317    else
    254318    {
    255         _printf("\n[GIET ERROR] in _ext_irq_release() : illegal WTI index\n");
     319        _printf("\n[GIET ERROR] in _ext_irq_release() : "
     320                "WTI = %d / X = %d / Y = %d / P = %d\n", wti , x, y , p );
    256321        _exit();
    257322    }
     
    294359
    295360#if GIET_DEBUG_IRQS    // we don't take the TTY lock to avoid deadlocks
     361if ( _get_proctime() > GIET_DEBUG_IRQS )
    296362_nolock_printf("\n[DEBUG IRQS] _irq_demux() Processor[%d,%d,%d] enters at cycle %d\n"
    297363               " irq_type = %s / irq_id = %d / isr_type = %s / channel = %d\n",
     
    360426
    361427    unsigned int value;     // WTI mailbox value
    362     unsigned int save_sr;   // save SR value in pre-empted task stack
    363 
    364     unsigned int ltid       = _get_current_task_id();
     428    unsigned int save_sr;   // save SR value in pre-empted thread stack
     429
     430    unsigned int ltid       = _get_thread_ltid();
    365431
    366432    if ( irq_type != IRQ_TYPE_WTI )
     
    375441    _xcu_get_wti_value( cluster_xy, irq_id, &value );
    376442
    377 #if GIET_DEBUG_SWITCH
    378 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] enters _isr_wakup() at cycle %d\n"
     443#if GIET_DEBUG_IRQS
     444if ( _get_proctime() > GIET_DEBUG_IRQS )
     445_printf("\n[DEBUG IRQS] P[%d,%d,%d] enters _isr_wakup() at cycle %d\n"
    379446        "  WTI index = %d / current ltid = %d / mailbox value = %x\n",
    380447        x , y , p , _get_proctime() , irq_id , ltid , value );
     
    382449
    383450    // enter critical section and swich context (if required)
    384     if ( (ltid == IDLE_TASK_INDEX) || (value != 0) )
     451    if ( (ltid == IDLE_THREAD_INDEX) || (value != 0) )
    385452    {
    386453        _it_disable( &save_sr );
     
    402469    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
    403470
    404     unsigned int save_sr;   // save SR value in pre-empted task stack
     471    unsigned int save_sr;   // save SR value in pre-empted thread stack
    405472
    406473    if ( irq_type != IRQ_TYPE_PTI )
     
    415482    _xcu_timer_reset_irq( cluster_xy, irq_id );
    416483
    417 #if (GIET_DEBUG_SWITCH & 0x1)
    418 unsigned int ltid  = _get_current_task_id();
    419 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    420 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] enters _isr_tick() at cycle %d\n"
     484#if GIET_DEBUG_IRQS
     485unsigned int ltid  = _get_thread_ltid();
     486if ( _get_proctime() > GIET_DEBUG_IRQS )
     487_printf("\n[DEBUG IRQS] P[%d,%d,%d] enters _isr_tick() at cycle %d\n"
    421488        "  WTI index = %d / current ltid = %d\n",
    422489        x , y , p , _get_proctime() , irq_id , ltid );
  • soft/giet_vm/giet_kernel/kernel_init.c

    r688 r709  
    2323#include <bdv_driver.h>
    2424#include <mmc_driver.h>
     25#include <tty_driver.h>
    2526#include <ctx_handler.h>
    2627#include <irq_handler.h>
     28#include <sys_handler.h>
    2729#include <mapping_info.h>
    2830#include <mips32_registers.h>
     
    6062#endif
    6163
    62 #if !defined(IDLE_TASK_INDEX)
    63 # error: You must define IDLE_TASK_INDEX in the ctx_handler.h file
     64#if !defined(IDLE_THREAD_INDEX)
     65# error: You must define IDLE_THREAD_INDEX in the ctx_handler.h file
    6466#endif
    6567
     
    109111volatile unsigned int _kernel_init_done = 0;
    110112
    111 // Kernel uses sqt_lock to protect TTY0       
     113// Kernel uses a sqt_lock to protect TTY0       
    112114__attribute__((section(".kdata")))
    113115unsigned int   _tty0_boot_mode = 0;
    114116
    115 // Kernel uses sqt_lock to protect command allocator in HBA       
     117// Kernel uses a sqt_lock to protect command allocator in HBA       
    116118__attribute__((section(".kdata")))
    117119unsigned int   _hba_boot_mode = 0;
     
    125127////////////////////////////////////////////////////////////////////////////////
    126128
    127 // this variable is defined in tty0.c file
     129// this variable is allocated in tty0.c file
    128130extern sqt_lock_t _tty0_sqt_lock;
    129131
    130 // this variable is allocated in mmc_kernel.c
     132// this variable is allocated in mmc_driver.c file
    131133extern unsigned int _mmc_boot_mode;
    132134
    133 ////////////////////////////////////////////////////////////////////////////////
    134 // This kernel_init() function completes the kernel initialisation in 6 steps:
     135// this variable is allocated in sys_handler.c file
     136extern unsigned int _tty_channel_alloc[NB_TTY_CHANNELS];
     137
     138////////////////////////////////////////////////////////////////////////////////
     139// This kernel_init() function completes the kernel initialisation in 5 steps:
    135140// Step 0 is done by processor[0,0,0]. Steps 1 to 4 are executed in parallel
    136141// by all processors.
     
    138143// - step 1 : Each processor initialises scheduler pointers array.
    139144// - step 2 : Each processor initialises PTAB pointers arrays.
    140 // - step 3 : Each processor initialise idle task and starts TICK timer.
     145// - step 3 : Each processor initialise idle thread and starts TICK timer.
    141146// - step 4 : Each processor set sp, sr, ptpr, epc registers values.
    142147////////////////////////////////////////////////////////////////////////////////
     
    165170_nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes kernel heap init\n", x, y, p );
    166171#endif
    167         //////  distributed lock for MMC
     172        //////  distributed locks for MMC
    168173        _mmc_boot_mode = 0;
    169174        _mmc_init_locks();
    170175
    171176#if GIET_DEBUG_INIT
    172 _nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes MMC distributed lock init\n", x , y , p );
     177_nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes MMC distributed locks init\n", x , y , p );
    173178#endif
    174179        //////  distributed lock for TTY0
    175180        _sqt_lock_init( &_tty0_sqt_lock );
     181        _tty_channel_alloc[0] = 1;
    176182
    177183#if GIET_DEBUG_INIT
     
    183189#if GIET_DEBUG_INIT
    184190_nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes barrier init\n", x , y , p );
     191#endif
     192
     193        //////  TTY fifos initialisation
     194        unsigned int tty_id;
     195        for ( tty_id = 0 ; tty_id < NB_TTY_CHANNELS ; tty_id++) _tty_init( tty_id );
     196
     197#if GIET_DEBUG_INIT
     198_nolock_printf("\n[DEBUG KINIT] P[%d,%d,%d] completes TTY fifos init\n", x , y , p );
    185199#endif
    186200
     
    245259
    246260    static_scheduler_t* psched     = (static_scheduler_t*)_get_sched();
    247     unsigned int        tasks      = psched->tasks;
     261    unsigned int        threads    = psched->threads;
    248262
    249263    _schedulers[x][y][p] = psched;
     
    252266_printf("\n[DEBUG KINIT] P[%d,%d,%d] initialises SCHED array\n"
    253267        " - scheduler vbase = %x\n"
    254         " - tasks           = %d\n",
    255         x, y, p, (unsigned int)psched, tasks );
     268        " - threads         = %d\n",
     269        x, y, p, (unsigned int)psched, threads );
    256270#endif
    257271
     
    261275
    262276    ////////////////////////////////////////////////////////////////////////////
    263     // step 2 : each processor that is allocated at least one task loops
    264     //          on its allocated tasks:
    265     //          - contributes to _ptabs_vaddr[][][] & _ptabs_ptprs[][][]
    266     //            initialisation, from values stored in the tasks contexts.
     277    // step 2 : each processor that is allocated at least one thread loops
     278    //          on its allocated threads:
     279    //          - contributes to _ptabs_vaddr & _ptabs_ptprs arrays
     280    //            initialisation, from values stored in the threads contexts.
    267281    //          - set CTX_RA slot  with the kernel _ctx_eret() virtual address.
    268     //          - set CTX_ENTRY slot that must contain the task entry point,
    269     //            and contain only at this point the virtual address of the
    270     //            memory word containing this entry point.
     282    //          - set CTX_ENTRY & CTX_EPC slots that must contain the thread
     283    //            entry point. The CTX_ENTRY slot contain only at this point
     284    //            a pointer on the memory word containing this entry point.
    271285    ////////////////////////////////////////////////////////////////////////////
    272286
    273287    unsigned int ltid;
    274288
    275     for (ltid = 0; ltid < tasks; ltid++)
     289    for (ltid = 0; ltid < threads; ltid++)
    276290    {
    277         unsigned int vsid = _get_task_slot( x, y, p, ltid , CTX_VSID_ID );
    278         unsigned int ptab = _get_task_slot( x, y, p, ltid , CTX_PTAB_ID );
    279         unsigned int ptpr = _get_task_slot( x, y, p, ltid , CTX_PTPR_ID );
     291        unsigned int vsid = _get_thread_slot( x, y, p, ltid , CTX_VSID_ID );
     292        unsigned int ptab = _get_thread_slot( x, y, p, ltid , CTX_PTAB_ID );
     293        unsigned int ptpr = _get_thread_slot( x, y, p, ltid , CTX_PTPR_ID );
    280294
    281295        // initialize PTABS arrays
     
    289303        // set CTX_RA slot
    290304        unsigned int ctx_ra = (unsigned int)(&_ctx_eret);
    291         _set_task_slot( x, y, p, ltid, CTX_RA_ID, ctx_ra );
    292 
    293         // set CTX_ENTRY slot
    294         unsigned int* ptr = (unsigned int*)_get_task_slot(x , y , p , ltid , CTX_ENTRY_ID);
     305        _set_thread_slot( x, y, p, ltid, CTX_RA_ID, ctx_ra );
     306
     307        // set CTX_ENTRY and CTX_EPC slots
     308        unsigned int* ptr = (unsigned int*)_get_thread_slot(x , y , p , ltid , CTX_ENTRY_ID);
    295309        unsigned int ctx_entry = *ptr;
    296         _set_task_slot( x , y , p , ltid , CTX_ENTRY_ID , ctx_entry );
     310        _set_thread_slot( x , y , p , ltid , CTX_ENTRY_ID , ctx_entry );
     311        _set_thread_slot( x , y , p , ltid , CTX_EPC_ID , ctx_entry );
    297312
    298313#if GIET_DEBUG_INIT
    299314_printf("\n[DEBUG KINIT] P[%d,%d,%d] initialises PTABS arrays"
    300         " and context for task %d \n"
     315        " and context for thread %d \n"
    301316        " - ptabs_vaddr[%d][%d][%d] = %x\n"
    302317        " - ptabs_paddr[%d][%d][%d] = %l\n"
     
    309324#endif
    310325
    311     }  // end for tasks
     326    }  // end for threads
    312327
    313328    /////////////////////////////////////////
     
    316331
    317332    ////////////////////////////////////////////////////////////////////////////
    318     // step 3 : - Each processor complete idle task context initialisation.
     333    // step 3 : - Each processor complete idle thread context initialisation.
    319334    //            Only CTX_SP, CTX_RA, CTX_EPC, CTX_ENTRY slots, because other
    320335    //            slots have been initialised in boot code)
    321336    //            The 4 Kbytes idle stack is implemented in the scheduler itself.
    322     //          - Each processor starts TICK timer, if at least one task.
     337    //          - Each processor starts TICK timer, if at least one thread.
    323338    //          - P[0,0,0] initialises FAT (not done before, because it must
    324339    //            be done after the _ptabs_vaddr[v][x][y] array initialisation,
     
    328343    unsigned int sp    = ((unsigned int)psched) + 0x2000;
    329344    unsigned int ra    = (unsigned int)(&_ctx_eret);
    330     unsigned int entry = (unsigned int)(&_idle_task);
    331 
    332     _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_SP_ID  , sp    );
    333     _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_RA_ID  , ra    );
    334     _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_EPC_ID , entry );
    335     _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_ENTRY_ID , entry );
    336 
    337     if (tasks > 0) _xcu_timer_start( cluster_xy, p, GIET_TICK_VALUE );
    338 
    339 #if GIET_DEBUG_INIT
    340 _printf("\n[DEBUG KINIT] P[%d,%d,%d] initializes idle_task and starts TICK\n", 
     345    unsigned int entry = (unsigned int)(&_idle_thread);
     346
     347    _set_thread_slot( x , y , p , IDLE_THREAD_INDEX , CTX_SP_ID  , sp    );
     348    _set_thread_slot( x , y , p , IDLE_THREAD_INDEX , CTX_RA_ID  , ra    );
     349    _set_thread_slot( x , y , p , IDLE_THREAD_INDEX , CTX_EPC_ID , entry );
     350    _set_thread_slot( x , y , p , IDLE_THREAD_INDEX , CTX_ENTRY_ID , entry );
     351
     352    if (threads > 0) _xcu_timer_start( cluster_xy, p, GIET_TICK_VALUE );
     353
     354#if GIET_DEBUG_INIT
     355_printf("\n[DEBUG KINIT] P[%d,%d,%d] initializes idle_thread and starts TICK\n", 
    341356        x, y, p );
    342357#endif
     
    358373
    359374    ////////////////////////////////////////////////////////////////////////////
    360     // step 4 : Each processor computes the task index (ltid), and the values
     375    // step 4 : Each processor computes the thread index (ltid), and the values
    361376    //          to initialize the SP, SR, PTPR, EPC registers.
    362     //          It jumps to a runable task if possible, and jumps to IDLE-TASK
    363     //          if no task allocated or no runable task.
    364     ////////////////////////////////////////////////////////////////////////////
    365 
    366     if (tasks == 0) _printf("\n[GIET WARNING] No task allocated to P[%d,%d,%d]\n",
     377    //          It jumps to a runable thread if possible,
     378    //          or jumps to IDLE-THREAD if no runable thread.
     379    ////////////////////////////////////////////////////////////////////////////
     380
     381    if (threads == 0) _printf("\n[GIET WARNING] No thread allocated to P[%d,%d,%d]\n",
    367382                            x, y, p );
    368383
    369384    // default value for ltid
    370     ltid = IDLE_TASK_INDEX;
    371 
    372     // scan allocated tasks to find a runable task
    373     unsigned int  task_id;
    374     for ( task_id = 0 ; task_id < tasks ; task_id++ )
     385    ltid = IDLE_THREAD_INDEX;
     386
     387    // scan allocated threads to find a runable thread
     388    unsigned int  thread_id;
     389    for ( thread_id = 0 ; thread_id < threads ; thread_id++ )
    375390    {
    376         if ( _get_task_slot( x, y, p, task_id, CTX_NORUN_ID ) == 0 )
     391        if ( _get_thread_slot( x, y, p, thread_id, CTX_NORUN_ID ) == 0 )
    377392        {
    378             ltid = task_id;
     393            ltid = thread_id;
    379394            break;
    380395        }
     
    384399    psched->current = ltid;
    385400
    386     // get values from selected task context
    387     unsigned int sp_value   = _get_task_slot( x, y, p, ltid, CTX_SP_ID);
    388     unsigned int sr_value   = _get_task_slot( x, y, p, ltid, CTX_SR_ID);
    389     unsigned int ptpr_value = _get_task_slot( x, y, p, ltid, CTX_PTPR_ID);
    390     unsigned int epc_value  = _get_task_slot( x, y, p, ltid, CTX_ENTRY_ID);
     401    // get values from selected thread context
     402    unsigned int sp_value   = _get_thread_slot( x, y, p, ltid, CTX_SP_ID);
     403    unsigned int sr_value   = _get_thread_slot( x, y, p, ltid, CTX_SR_ID);
     404    unsigned int ptpr_value = _get_thread_slot( x, y, p, ltid, CTX_PTPR_ID);
     405    unsigned int epc_value  = _get_thread_slot( x, y, p, ltid, CTX_ENTRY_ID);
    391406
    392407#if GIET_DEBUG_INIT
  • soft/giet_vm/giet_kernel/switch.s

    r301 r709  
    11/******************************************************************************
    2 * This function receives two arguments that are the current task context
    3 * (virtual) addresses and the next task context (virtual) address.
     2* This function receives two arguments that are the current thread context
     3* (virtual) addresses and the next thread context (virtual) address.
    44*
    55* This function should be called in a critical section
     
    1515******************************************************************************/
    1616
    17     .globl  _task_switch
    18     .func   _task_switch
    19     .type   _task_switch, %function
     17    .globl  _thread_switch
     18    .func   _thread_switch
     19    .type   _thread_switch, %function
    2020
    21 _task_switch:
     21_thread_switch:
    2222
    23     /* save _current task context */
    24     add     $27,    $4,     $0  /* $27 <= &context[curr_task_id] */
     23    /* first step : save current thread context */
     24    add     $27,    $4,     $0  /* $27 <= &context[current] */
    2525
    2626    .set noat
     
    7070    sw      $26,    39*4($27)   /* ctx[35] <= PTPR */
    7171
    72     /* restore next task context */
    73     add     $27,    $5,     $0  /* $27<= &context[next_task_id] */
     72    /* second step : restore next thread context */
     73    add     $27,    $5,     $0  /* $27<= &context[next] */
    7474
    7575    .set noat
     
    123123
    124124    .endfunc
    125     .size _task_switch, .-_task_switch
     125    .size _thread_switch, .-_thread_switch
    126126
  • soft/giet_vm/giet_kernel/sys_handler.c

    r707 r709  
    2626#include <io.h>
    2727
     28#if !defined(X_SIZE)
     29# error: You must define X_SIZE in the hard_config.h file
     30#endif
     31
     32#if !defined(Y_SIZE)
     33# error: You must define Y_SIZE in the hard_config.h file
     34#endif
     35
     36#if !defined(NB_PROCS_MAX)
     37# error: You must define NB_PROCS_MAX in the hard_config.h file
     38#endif
     39
    2840#if !defined(SEG_BOOT_MAPPING_BASE)
    2941# error: You must define SEG_BOOT_MAPPING_BASE in the hard_config.h file
     
    7587extern unsigned int   _coproc_mode[X_SIZE*Y_SIZE];
    7688extern unsigned int   _coproc_error[X_SIZE*Y_SIZE];
    77 extern unsigned int   _coproc_gtid[X_SIZE*Y_SIZE];
    78 
     89extern unsigned int   _coproc_trdid[X_SIZE*Y_SIZE];
    7990
    8091// allocated in tty_driver.c file.
    81 extern unsigned int _tty_rx_full[NB_TTY_CHANNELS];
    82 extern unsigned int _tty_rx_buf[NB_TTY_CHANNELS];
     92extern tty_fifo_t   _tty_rx_fifo[NB_TTY_CHANNELS];
    8393
    8494// allocated in kernel_init.c file
    8595extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
    8696
    87 ////////////////////////////////////////////////////////////////////////////
    88 //     Channel allocators for peripherals
    89 //     (TTY[0] is reserved for kernel)
    90 ////////////////////////////////////////////////////////////////////////////
    91 
     97////////////////////////////////////////////////////////////////////////////////
     98//     Channel allocators for multi-channels peripherals
     99// - The array _***_channel_allocator[channel] defines the number of user
     100//   threads for a dynamically allocated channel of peripheral ***.
     101// - The array _***_channel_wti[channel] defines the WTI index and the
     102//   processor coordinates for the processor receiving the channel WTI.
     103////////////////////////////////////////////////////////////////////////////////
     104
     105#if NB_TTY_CHANNELS
    92106__attribute__((section(".kdata")))
    93 unsigned int _tty_channel[NB_TTY_CHANNELS]  = {1};
     107unsigned int _tty_channel_alloc[NB_TTY_CHANNELS] = {0};
    94108
    95109__attribute__((section(".kdata")))
    96 unsigned int _tim_channel_allocator    = 0;
    97 
     110unsigned int _tty_channel_wti[NB_TTY_CHANNELS];
     111#endif
     112
     113#if NB_TIM_CHANNELS
    98114__attribute__((section(".kdata")))
    99 unsigned int _cma_channel[NB_CMA_CHANNELS] = {0};
     115unsigned int _tim_channel_alloc[NB_TIM_CHANNELS] = {0};
    100116
    101117__attribute__((section(".kdata")))
    102 unsigned int _nic_rx_channel_allocator = 0;
    103 
     118unsigned int _tim_channel_wti[NB_TIM_CHANNELS];
     119#endif
     120
     121#if NB_CMA_CHANNELS
    104122__attribute__((section(".kdata")))
    105 unsigned int _nic_tx_channel_allocator = 0;
     123unsigned int _cma_channel_alloc[NB_CMA_CHANNELS] = {0};
     124
     125__attribute__((section(".kdata")))
     126unsigned int _cma_channel_wti[NB_CMA_CHANNELS];
     127#endif
     128
     129#if NB_NIC_CHANNELS
     130__attribute__((section(".kdata")))
     131unsigned int _nic_rx_channel_alloc[NB_NIC_CHANNELS] = {0};
     132
     133__attribute__((section(".kdata")))
     134unsigned int _nic_rx_channel_wti[NB_NIC_CHANNELS];
     135
     136__attribute__((section(".kdata")))
     137unsigned int _nic_tx_channel_alloc[NB_NIC_CHANNELS] = {0};
     138
     139__attribute__((section(".kdata")))
     140unsigned int _nic_tx_channel_wti[NB_NIC_CHANNELS];
     141#endif
    106142
    107143////////////////////////////////////////////////////////////////////////////
     
    140176    &_sys_proc_xyp,                  /* 0x00 */
    141177    &_get_proctime,                  /* 0x01 */
    142     &_sys_tty_write,                 /* 0x02 */
    143     &_sys_tty_read,                  /* 0x03 */
    144     &_sys_tty_alloc,                 /* 0x04 */
    145     &_sys_tasks_status,              /* 0x05 */
     178    &_sys_procs_number,              /* 0x02 */
     179    &_sys_xy_from_ptr,               /* 0x03 */
     180    &_sys_ukn,                       /* 0x04 */
     181    &_sys_ukn,                       /* 0x05 */
    146182    &_sys_ukn,                       /* 0x06 */
    147183    &_sys_heap_info,                 /* 0x07 */
    148     &_sys_local_task_id,             /* 0x08 */
    149     &_sys_global_task_id,            /* 0x09 */
     184    &_sys_vseg_get_vbase,            /* 0x08 */
     185    &_sys_vseg_get_length,           /* 0x09 */
    150186    &_sys_fbf_cma_alloc,             /* 0x0A */
    151187    &_sys_fbf_cma_init_buf,          /* 0x0B */
     
    153189    &_sys_fbf_cma_display,           /* 0x0D */
    154190    &_sys_fbf_cma_stop,              /* 0x0E */
    155     &_sys_task_exit,                 /* 0x0F */
    156 
    157     &_sys_procs_number,              /* 0x10 */
     191    &_sys_ukn,                       /* 0x0F */
     192
     193    &_sys_applications_status,       /* 0x10 */
    158194    &_sys_fbf_sync_write,            /* 0x11 */
    159195    &_sys_fbf_sync_read,             /* 0x12 */
    160     &_sys_thread_id,                 /* 0x13 */
     196    &_sys_ukn,                       /* 0x13 */
    161197    &_sys_tim_alloc,                 /* 0x14 */
    162198    &_sys_tim_start,                 /* 0x15 */
     
    164200    &_sys_kill_application,          /* 0x17 */
    165201    &_sys_exec_application,          /* 0x18 */   
    166     &_sys_context_switch,            /* 0x19 */
    167     &_sys_vseg_get_vbase,            /* 0x1A */
    168     &_sys_vseg_get_length,           /* 0x1B */
    169     &_sys_xy_from_ptr,               /* 0x1C */
    170     &_sys_ukn,                       /* 0x1D */
    171     &_sys_ukn,                       /* 0x1E */
    172     &_sys_ukn,                       /* 0x1F */
     202    &_sys_ukn,                       /* 0x19 */
     203    &_sys_pthread_control,           /* 0x1A */
     204    &_sys_pthread_yield,             /* 0x1B */
     205    &_sys_pthread_kill,              /* 0x1C */
     206    &_sys_pthread_create,            /* 0x1D */
     207    &_sys_pthread_join,              /* 0x1E */
     208    &_sys_pthread_exit,              /* 0x1F */
    173209
    174210    &_fat_open,                      /* 0x20 */
    175     &_sys_fat_read,                  /* 0x21 */
     211    &_fat_read,                      /* 0x21 */
    176212    &_fat_write,                     /* 0x22 */
    177213    &_fat_lseek,                     /* 0x23 */
     
    195231    &_sys_nic_stats,                 /* 0x34 */
    196232    &_sys_nic_clear,                 /* 0x35 */
    197     &_sys_ukn,                       /* 0x36 */
    198     &_sys_ukn,                       /* 0x37 */
    199     &_sys_ukn,                       /* 0x38 */   
     233    &_sys_tty_write,                 /* 0x36 */
     234    &_sys_tty_read,                  /* 0x37 */
     235    &_sys_tty_alloc,                 /* 0x38 */
    200236    &_sys_ukn,                       /* 0x39 */
    201237    &_sys_ukn,                       /* 0x3A */
     
    207243};
    208244
     245
     246//////////////////////////////////////////////////////////////////////////////
     247//           Applications related syscall handlers
     248//////////////////////////////////////////////////////////////////////////////
     249
     250////////////////////////////////////////////////////////////////////////
     251// This function is called by the _sys_exec_application function
     252// to reload all data segments contained in an application.elf file.
    209253////////////////////////////////////////////////////////////////////////
    210254static unsigned int _load_writable_segments( mapping_vspace_t*  vspace )
    211255{
    212 #if GIET_DEBUG_SWITCH
     256
     257#if GIET_DEBUG_EXEC 
    213258unsigned int gpid       = _get_procid();
    214259unsigned int cluster_xy = gpid >> P_WIDTH;
     
    216261unsigned int x          = cluster_xy >> Y_WIDTH;
    217262unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    218 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    219 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : enters for %s\n",
    220         x , y , p , vspace->name );
     263if ( _get_proctime() > GIET_DEBUG_EXEC )
     264_printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] "
     265        "enters for %s\n", x , y , p , vspace->name );
    221266#endif
    222267
     
    224269    mapping_vseg_t*    vseg    = _get_vseg_base(header);
    225270
    226     // buffer to store one cluster
    227     char  buf[4096];
    228 
    229     // open the .elf file associated to vspace
    230     unsigned int      vseg_id;
    231     unsigned int      fd = 0;
    232 
     271    unsigned int vseg_id;        // vseg index in mapping
     272    char         buf[4096];      // buffer to store one cluster
     273    unsigned int fd = 0;         // file descriptor
     274
     275    // first scan on vsegs in vspace to find the .elf pathname
    233276    for (vseg_id = vspace->vseg_offset;
    234277         vseg_id < (vspace->vseg_offset + vspace->vsegs);
    235278         vseg_id++)
    236279    {
    237         if(vseg[vseg_id].type == VSEG_TYPE_ELF)
     280        if( vseg[vseg_id].type == VSEG_TYPE_ELF )
    238281        {
     282            // open the .elf file associated to vspace
    239283            fd = _fat_open( vseg[vseg_id].binpath , O_RDONLY );
    240 
    241 #if GIET_DEBUG_SWITCH
    242 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    243 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : open %s / fd = %d\n",
    244         x , y , p , vseg[vseg_id].binpath , fd );
    245 #endif
    246 
    247284            if ( fd < 0 ) return 1;
    248285            break;
     286
     287#if GIET_DEBUG_EXEC
     288if ( _get_proctime() > GIET_DEBUG_EXEC )
     289_printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] "
     290        "open %s / fd = %d\n", x , y , p , vseg[vseg_id].binpath , fd );
     291#endif
    249292        }
    250293    }
    251 
     294 
    252295    // load Elf-Header into buffer from .elf file
    253     if ( _fat_lseek( fd, 0, SEEK_SET ) < 0 ) return 1;
    254     if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 ) return 1;
    255 
    256 #if GIET_DEBUG_SWITCH
    257 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    258 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : load Elf-Header\n",
    259         x , y , p );
     296    if ( _fat_lseek( fd, 0, SEEK_SET ) < 0 )
     297    {
     298        _fat_close( fd );
     299        return 1;
     300    }
     301    if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 )
     302    {
     303        _fat_close( fd );
     304        return 1;
     305    }
     306
     307#if GIET_DEBUG_EXEC
     308if ( _get_proctime() > GIET_DEBUG_EXEC )
     309_printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] "
     310        "loaded Elf-Header\n", x , y , p );
    260311#endif
    261312
     
    266317
    267318    // load Program-Header-Table from .elf file
    268     if ( _fat_lseek( fd, offset, SEEK_SET ) < 0 ) return 1;
    269     if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 ) return 1;
    270 
    271 #if GIET_DEBUG_SWITCH
    272 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    273 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : "
    274         "load Program-Header-Table\n", x , y , p );
     319    if ( _fat_lseek( fd, offset, SEEK_SET ) < 0 )
     320    {
     321        _fat_close( fd );
     322        return 1;
     323    }
     324    if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 )
     325    {
     326        _fat_close( fd );
     327        return 1;
     328    }
     329
     330#if GIET_DEBUG_EXEC
     331if ( _get_proctime() > GIET_DEBUG_EXEC )
     332_printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] "
     333        "loaded Program-Header-Table\n", x , y , p );
    275334#endif
    276335
     
    278337    Elf32_Phdr*  elf_pht_ptr = (Elf32_Phdr*)buf;
    279338
    280     // scan segments to  load all loadable & writable segments
    281     unsigned int seg_id;
    282     for (seg_id = 0 ; seg_id < nsegments ; seg_id++)
    283     {
    284         if ( (elf_pht_ptr[seg_id].p_type == PT_LOAD) &&    // loadable
    285              (elf_pht_ptr[seg_id].p_flags & PF_W) )        // writable
     339    // second scan on vsegs in vspace to load the seg_data segments :
     340    // - type == VSEG_TYPE_ELF
     341    // - non eXecutable
     342    for (vseg_id = vspace->vseg_offset;
     343         vseg_id < (vspace->vseg_offset + vspace->vsegs);
     344         vseg_id++)
     345    {
     346        if( (vseg[vseg_id].type == VSEG_TYPE_ELF) &&   // type ELF
     347            ((vseg[vseg_id].mode & 0x4) == 0) )        // non executable
    286348        {
    287             // Get segment attributes
    288             paddr_t      seg_paddr  = vseg[vseg_id].pbase;
    289             unsigned int seg_offset = elf_pht_ptr[seg_id].p_offset;
    290             unsigned int seg_size   = elf_pht_ptr[seg_id].p_filesz;
    291 
    292             // load the segment
    293             if ( _fat_lseek( fd, seg_offset, SEEK_SET ) < 0 ) return 1;
    294             if ( _fat_read( fd, seg_paddr, seg_size, 1 ) < 0 ) return 1;
    295 
    296 #if GIET_DEBUG_SWITCH
    297 if ( _get_proctime() > GIET_DEBUG_SWITCH )
    298 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : load segment %x\n",
    299         x , y , p , seg_vaddr );
     349            // get vbase and pbase
     350            paddr_t      pbase = vseg[vseg_id].pbase;
     351            unsigned int vbase = vseg[vseg_id].vbase;
     352
     353            // scan segments in Progam-Header-Table to find match
     354            // No match checking as the segment was previously found
     355            unsigned int seg;
     356            for (seg = 0 ; seg < nsegments ; seg++)
     357            {
     358                if ( (elf_pht_ptr[seg].p_type == PT_LOAD) &&    // loadable
     359                     (elf_pht_ptr[seg].p_flags & PF_W)    &&    // writable
     360                     (elf_pht_ptr[seg].p_vaddr == vbase) )      // matching
     361                {
     362                    // Get segment offset and size in .elf file
     363                    unsigned int seg_offset = elf_pht_ptr[seg].p_offset;
     364                    unsigned int seg_size   = elf_pht_ptr[seg].p_filesz;
     365
     366                    // compute destination address and extension for _fat_read()
     367                    unsigned int dest   = (unsigned int)pbase;
     368                    unsigned int extend = (unsigned int)(pbase>>32) | 0xFFFF0000;
     369
     370                    // load the segment
     371                    if ( _fat_lseek( fd, seg_offset, SEEK_SET ) < 0 )
     372                    {
     373                        _fat_close( fd );
     374                        return 1;
     375                    }
     376                    if ( _fat_read( fd, dest, seg_size, extend ) < 0 )
     377                    {
     378                        _fat_close( fd );
     379                        return 1;
     380                    }
     381                }
     382            }
     383
     384#if GIET_DEBUG_EXEC
     385if ( _get_proctime() > GIET_DEBUG_EXEC )
     386_printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] "
     387        "loaded segment %x\n", x , y , p , vbase );
    300388#endif
    301389        }
     
    308396}  // end load_writable_segments()
    309397
    310 //////////////////////////////////////////////////////////////////////////////
    311 //           Applications related syscall handlers
    312 //////////////////////////////////////////////////////////////////////////////
     398
     399
     400///////////////////////////////////////
     401int _sys_exec_application( char* name )
     402{
     403    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     404    mapping_vspace_t * vspace  = _get_vspace_base(header);
     405    mapping_thread_t * thread  = _get_thread_base(header);
     406    mapping_vseg_t   * vseg    = _get_vseg_base(header);
     407
     408    unsigned int vspace_id;
     409    unsigned int thread_id;
     410
     411#if GIET_DEBUG_EXEC
     412unsigned int gpid       = _get_procid();
     413unsigned int cluster_xy = gpid >> P_WIDTH;
     414unsigned int p          = gpid & ((1<<P_WIDTH)-1);
     415unsigned int x          = cluster_xy >> Y_WIDTH;
     416unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
     417if ( _get_proctime() > GIET_DEBUG_EXEC )
     418_printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] "
     419        "enters for %s at cycle %d\n", x, y, p, name, _get_proctime() );
     420#endif
     421
     422    unsigned int y_size = header->y_size;
     423
     424    // scan vspaces to find matching vspace name
     425    for (vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++)
     426    {
     427        if ( _strcmp( vspace[vspace_id].name, name ) == 0 )  // vspace found
     428        {
     429
     430#if GIET_DEBUG_EXEC
     431if ( _get_proctime() > GIET_DEBUG_EXEC )
     432_printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] "
     433        "found vspace %s at cycle  %d\n", x, y, p, name, _get_proctime() );
     434#endif
     435            // reload writable segments
     436            if ( _load_writable_segments( &vspace[vspace_id] ) )
     437            {
     438                _printf("[GIET ERROR] _sys_exec_application() : "
     439                        "can't load data segment for vspace %s\n", name );
     440                return GIET_SYSCALL_CANNOT_LOAD_DATA_SEGMENT;
     441            }
     442 
     443#if GIET_DEBUG_EXEC
     444if ( _get_proctime() > GIET_DEBUG_EXEC )
     445_printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] "
     446        "load segments for vspace %s at cycle  %d\n", x, y, p, name, _get_proctime() );
     447#endif
     448            // scan threads in vspace with three goals :
     449            // - check all threads desactivated
     450            // - re-initialise all threads contexts
     451            // - find main thread
     452            unsigned int        main_found  = 0;
     453            unsigned int        main_ltid   = 0;
     454            static_scheduler_t* main_psched = NULL;
     455            unsigned int        min         = vspace[vspace_id].thread_offset;
     456            unsigned int        max         = min + vspace[vspace_id].threads;
     457            for ( thread_id = min ; thread_id < max ; thread_id++ )
     458            {
     459                // get thread identifiers : [x,y,p,ltid]
     460                unsigned int cid   = thread[thread_id].clusterid;
     461                unsigned int x     = cid / y_size;
     462                unsigned int y     = cid % y_size;
     463                unsigned int p     = thread[thread_id].proclocid;
     464                unsigned int ltid  = thread[thread_id].ltid;
     465                unsigned int vsid  = thread[thread_id].stack_vseg_id;
     466
     467                // get scheduler pointer
     468                static_scheduler_t* psched = _schedulers[x][y][p];
     469
     470                // check thread non active
     471                if ( psched->context[ltid].slot[CTX_NORUN_ID] == 0 )  // runnable !!!
     472                {
     473                    _printf("\n[GIET ERROR] in _sys_exec_application() : "
     474                            "thread %s already active in vspace %s\n",
     475                            thread[thread_id].name, name );
     476                    return GIET_SYSCALL_THREAD_ALREADY_ACTIVE;
     477                }
     478               
     479                // initialise thread context
     480                unsigned int ctx_epc = psched->context[ltid].slot[CTX_ENTRY_ID];
     481                unsigned int ctx_sp  = vseg[vsid].vbase + vseg[vsid].length;
     482                unsigned int ctx_ra  = (unsigned int)&_ctx_eret;
     483                unsigned int ctx_sr  = GIET_SR_INIT_VALUE;
     484
     485                psched->context[ltid].slot[CTX_EPC_ID] = ctx_epc;
     486                psched->context[ltid].slot[CTX_RA_ID]  = ctx_ra;
     487                psched->context[ltid].slot[CTX_SR_ID]  = ctx_sr;
     488                psched->context[ltid].slot[CTX_SP_ID]  = ctx_sp;
     489
     490                // register information required to activate main thread
     491                // actual activation done when threads initialisation is completed
     492                if ( thread[thread_id].is_main )
     493                {
     494                    main_psched = psched;
     495                    main_ltid   = ltid;
     496                    main_found  = 1;
     497                }
     498 
     499#if GIET_DEBUG_EXEC
     500if ( _get_proctime() > GIET_DEBUG_EXEC )
     501_printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] "
     502        "initialise thread %s at cycle  %d\n",
     503        x, y, p, thread[thread_id].name, _get_proctime() );
     504#endif
     505            }  // end loop on vspace threads
     506
     507            // activate main thread
     508            if ( main_found )
     509            {
     510                main_psched->context[main_ltid].slot[CTX_NORUN_ID] = 0;
     511            }
     512            else
     513            {
     514                _printf("\n[GIET ERROR] in _sys_exec_application() : "
     515                        "main not found in vspace %s\n", name );
     516                return GIET_SYSCALL_MAIN_NOT_FOUND;
     517            }
     518             
     519#if GIET_DEBUG_EXEC
     520if ( _get_proctime() > GIET_DEBUG_EXEC )
     521_printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] "
     522        "lauched %s at cycle %d\n", x, y, p, name, _get_proctime() );
     523#endif
     524            return GIET_SYSCALL_OK;
     525        }
     526    }  // end of loop on vspaces
     527
     528    // vspace not found
     529    _printf("\n[GIET ERROR] in _sys_exec_application() : "
     530            "vspace %s not found\n", name );
     531    return GIET_SYSCALL_VSPACE_NOT_FOUND;
     532
     533}  // end _sys_exec_application()
     534   
    313535
    314536///////////////////////////////////////
     
    317539    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    318540    mapping_vspace_t * vspace  = _get_vspace_base(header);
    319     mapping_task_t   * task    = _get_task_base(header);
     541    mapping_thread_t * thread  = _get_thread_base(header);
    320542
    321543    unsigned int vspace_id;
    322     unsigned int task_id;
    323     unsigned int y_size = header->y_size;
     544    unsigned int thread_id;
    324545
    325546#if GIET_DEBUG_EXEC
     547unsigned int gpid       = _get_procid();
     548unsigned int cluster_xy = gpid >> P_WIDTH;
     549unsigned int p          = gpid & ((1<<P_WIDTH)-1);
     550unsigned int x          = cluster_xy >> Y_WIDTH;
     551unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    326552if ( _get_proctime() > GIET_DEBUG_EXEC )
    327 _printf("\n[DEBUG EXEC] enters _sys_kill_application() for %s\n", name );
    328 #endif
    329 
    330     // scan vspaces
     553_printf("\n[DEBUG EXEC] _sys_kill_application() P[%d,%d,%d] "
     554        "enters at cycle %d for %s\n", x, y, p, _get_proctime() , name );
     555#endif
     556
     557    // shell cannot be killed
     558    if ( _strcmp( name , "shell" ) == 0 )
     559    {
     560        _printf("\n[GIET ERROR] in _sys_kill_application() : "
     561                "%s application cannot be killed\n", name );
     562        return GIET_SYSCALL_APPLI_CANNOT_BE_KILLED;
     563    }
     564
     565    // scan vspaces to find matching vspace name
    331566    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++)
    332567    {
    333568        if ( _strcmp( vspace[vspace_id].name, name ) == 0 )
    334569        {
    335             // check if application can be killed
    336             if ( vspace[vspace_id].active ) return -2;
    337 
    338             // scan tasks in vspace
    339             for (task_id = vspace[vspace_id].task_offset;
    340                  task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
    341                  task_id++)
     570            // scan threads to send KILL signal to all threads in vspace
     571            unsigned int y_size = header->y_size;
     572            unsigned int min    = vspace[vspace_id].thread_offset;
     573            unsigned int max    = min + vspace[vspace_id].threads;
     574            for ( thread_id = min ; thread_id < max ; thread_id++ )
    342575            {
    343                 unsigned int cid   = task[task_id].clusterid;
     576                unsigned int cid   = thread[thread_id].clusterid;
    344577                unsigned int x     = cid / y_size;
    345578                unsigned int y     = cid % y_size;
    346                 unsigned int p     = task[task_id].proclocid;
    347                 unsigned int ltid  = task[task_id].ltid;
    348 
    349                 // get scheduler pointer for processor running the task
     579                unsigned int p     = thread[thread_id].proclocid;
     580                unsigned int ltid  = thread[thread_id].ltid;
     581
     582                // get scheduler pointer for processor running the thread
    350583                static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    351584
    352585                // set KILL signal bit
    353                 _atomic_or( &psched->context[ltid][CTX_SIG_ID] , SIG_MASK_KILL );
     586                _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL );
    354587            }
    355588
    356589#if GIET_DEBUG_EXEC
    357590if ( _get_proctime() > GIET_DEBUG_EXEC )
    358 _printf("\n[DEBUG EXEC] exit _sys_kill_application() : %s will be killed\n", name );
    359 #endif
    360 
    361             return 0;
     591_printf("\n[DEBUG EXEC] _sys_kill_application() P[%d,%d,%d] "
     592        "kill %s at cycle %d\n", x, y, p, name, _get_proctime() );
     593#endif
     594
     595            return GIET_SYSCALL_OK;
    362596        }
    363     }
     597    }  // en loop on vspaces
     598
     599    _printf("\n[GIET ERROR] in _sys_kill_application() : "
     600            "application %s not found\n", name );
     601    return GIET_SYSCALL_VSPACE_NOT_FOUND;
     602
     603}  // end _sys_kill_application()
     604   
     605
     606
     607//////////////////////////////
     608int _sys_applications_status()
     609{
     610    mapping_header_t *  header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     611    mapping_thread_t *  thread  = _get_thread_base(header);
     612    mapping_vspace_t *  vspace  = _get_vspace_base(header);
     613    mapping_cluster_t * cluster = _get_cluster_base(header);
     614
     615    unsigned int thread_id;
     616    unsigned int vspace_id;
     617
     618    // scan all vspaces
     619    for( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
     620    {
     621        _user_printf("\n*** vspace %s\n", vspace[vspace_id].name );
     622
     623        // scan all threads in vspace
     624        unsigned int min = vspace[vspace_id].thread_offset ;
     625        unsigned int max = min + vspace[vspace_id].threads ;
     626        for ( thread_id = min ; thread_id < max ; thread_id++ )
     627        {
     628            unsigned int         clusterid = thread[thread_id].clusterid;
     629            unsigned int         p         = thread[thread_id].proclocid;
     630            unsigned int         x         = cluster[clusterid].x;
     631            unsigned int         y         = cluster[clusterid].y;
     632            unsigned int         ltid      = thread[thread_id].ltid;
     633            static_scheduler_t*  psched    = (static_scheduler_t*)_schedulers[x][y][p];
     634            unsigned int         norun     = psched->context[ltid].slot[CTX_NORUN_ID];
     635            unsigned int         tty       = psched->context[ltid].slot[CTX_TTY_ID];
     636            unsigned int         current   = psched->current;
     637
     638            if ( current == ltid )
     639            _user_printf(" - thread %s / P[%d,%d,%d] / ltid = %d / "
     640                         "TTY = %d / norun = %x : running\n",
     641                         thread[thread_id].name, x, y, p, ltid, tty, norun );
     642            else if ( norun == 0 )
     643            _user_printf(" - thread %s / P[%d,%d,%d] / ltid = %d / "
     644                         "TTY = %d / norun = %x : runable\n",
     645                         thread[thread_id].name, x, y, p, ltid, tty, norun);
     646            else
     647            _user_printf(" - thread %s / P[%d,%d,%d] / ltid = %d / "
     648                         "TTY = %d / norun = %x : blocked\n",
     649                         thread[thread_id].name, x, y, p, ltid, tty, norun);
     650        }
     651    }
     652    _user_printf("\n");
     653    return GIET_SYSCALL_OK;
     654}  // end _sys_applications_status()
     655
     656
     657
     658/////////////////////////////////////////////////////////////////////////////
     659//          Threads related syscall handlers
     660/////////////////////////////////////////////////////////////////////////////
     661
     662////////////////////////////////////////////////
     663int _sys_pthread_create( unsigned int*  buffer,
     664                         void*          attr,
     665                         void*          function,
     666                         void*          arg )
     667{
     668    // attr argument not supported
     669    if ( attr != NULL )
     670    {
     671        _printf("\n[GIET ERROR] in _sys_pthread_create() : "
     672                "attr argument not supported\n" );
     673       
     674        return GIET_SYSCALL_PTHREAD_ARGUMENT_NOT_SUPPORTED;
     675    }
     676
     677    // get pointers in mapping
     678    mapping_header_t*    header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     679    mapping_thread_t*    thread   = _get_thread_base(header);
     680    mapping_vspace_t*    vspace   = _get_vspace_base(header);
     681    mapping_cluster_t*   cluster  = _get_cluster_base(header);
     682
     683    // get scheduler for processor running the calling thread
     684    static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
     685
     686    // get calling thread local index in scheduler
     687    unsigned int  current = psched->current;
     688
     689    // get vspace index
     690    unsigned int  vspace_id = psched->context[current].slot[CTX_VSID_ID];
    364691
    365692#if GIET_DEBUG_EXEC
    366693if ( _get_proctime() > GIET_DEBUG_EXEC )
    367 _printf("\n[DEBUG EXEC] exit _sys_kill_application() : %s not found\n", name );
    368 #endif
    369 
    370     return -1;    // not found
    371 
    372 }  // end _sys_kill_application()
     694_printf("\n[DEBUG EXEC] _sys_pthread_create() : enters at cycle %d"
     695        " for vspace %s / entry = %x\n",
     696        _get_proctime() , vspace[vspace_id].name , (unsigned int)function );
     697#endif
     698
     699    unsigned int thread_id;        // searched thread : local index in mapping
     700    unsigned int clusterid;        // searched thread : cluster index
     701    unsigned int lpid;             // searched thread : processor local index
     702    unsigned int ltid;             // searched thread : scheduler thread index
     703    unsigned int cx;               // searched thread : X coordinate for searched thread
     704    unsigned int cy;               // searched thread : Y coordinate for searched thread
     705    unsigned int entry;            // searched thread : entry point
     706    unsigned int norun;            // searched thread : norun vector
     707    unsigned int trdid;            // searched thread : thread identifier
     708
     709    // scan threads in vspace to find an inactive thread matching function
     710    unsigned int min   = vspace[vspace_id].thread_offset;
     711    unsigned int max   = min + vspace[vspace_id].threads;
     712    unsigned int found = 0;
     713    for ( thread_id = min ; (thread_id < max) && (found == 0) ; thread_id++ )
     714    {
     715        // get thread coordinates [cx,cy,lpid] and ltid from mapping
     716        ltid       = thread[thread_id].ltid;
     717        clusterid  = thread[thread_id].clusterid;
     718        lpid       = thread[thread_id].proclocid;
     719        cx = cluster[clusterid].x;
     720        cy = cluster[clusterid].y;
     721
     722        // get thread scheduler pointer
     723        psched = _schedulers[cx][cy][lpid];
     724
     725        // get thread entry-point, norun-vector, and trdid from context
     726        entry = psched->context[ltid].slot[CTX_ENTRY_ID];
     727        norun = psched->context[ltid].slot[CTX_NORUN_ID];
     728        trdid = psched->context[ltid].slot[CTX_TRDID_ID];
     729
     730        // check matching
     731        if ( ((unsigned int)function == entry ) &&
     732             (norun & NORUN_MASK_THREAD)  ) found = 1;
     733
     734    }  // end loop on threads
     735
     736    if ( found )  // one matching inactive thread has been found
     737    {
     738        // set argument value in thread context
     739        if ( arg != NULL ) psched->context[ltid].slot[CTX_A0_ID] = (unsigned int)arg;
     740
     741        // activate thread
     742        psched->context[ltid].slot[CTX_NORUN_ID] = 0;
     743
     744        // return launched thead global identifier
     745        *buffer   = trdid;
     746               
     747#if GIET_DEBUG_EXEC
     748if ( _get_proctime() > GIET_DEBUG_EXEC )
     749_printf("\n[DEBUG EXEC] exit _sys_pthread_create() at cycle %d : thread %x launched\n",
     750        _get_proctime() , trdid);
     751#endif
     752        return GIET_SYSCALL_OK;
     753    }
     754    else         // no matching thread found
     755    {
     756        _printf("\n[GIET ERROR] in _sys_pthread_create() : "
     757                "no matching thread for entry = %x in vspace %s\n",
     758                (unsigned int)function , vspace[vspace_id].name );
     759       
     760        return GIET_SYSCALL_THREAD_NOT_FOUND;
     761    }
     762
     763} // end _sys_pthread_create()
     764
     765
     766///////////////////////////////////////////
     767int _sys_pthread_join( unsigned int  trdid,
     768                       void*         ptr )
     769{
     770    // ptr argument not supported
     771    if ( ptr != NULL )
     772    {
     773        _printf("\n[GIET ERROR] in _sys_pthread_join() : "
     774                "ptr argument not supported, must be NULL\n" );
     775       
     776        return GIET_SYSCALL_PTHREAD_ARGUMENT_NOT_SUPPORTED;
     777    }
     778
     779               
     780#if GIET_DEBUG_EXEC
     781if ( _get_proctime() > GIET_DEBUG_EXEC )
     782_printf("\n[DEBUG EXEC] enters _sys_pthread_join() at cycle %d for thread %x\n",
     783        _get_proctime() , trdid );
     784#endif
     785
     786    // get calling thread vspace
     787    unsigned int  caller_vspace = _get_context_slot( CTX_VSID_ID );
     788
     789    // get and check target thread indexes from trdid
     790    unsigned int cx   = (trdid>>24) & 0xFF;
     791    unsigned int cy   = (trdid>>16) & 0xFF;
     792    unsigned int lpid = (trdid>>8 ) & 0xFF;
     793    unsigned int ltid = (trdid    ) & 0xFF;
     794
     795    // get target thread scheduler, vspace and registered trdid
     796    static_scheduler_t*  psched   = _schedulers[cx][cy][lpid];
     797    unsigned int target_vspace    = psched->context[ltid].slot[CTX_VSID_ID];
     798    unsigned int registered_trdid = psched->context[ltid].slot[CTX_TRDID_ID];
     799
     800    // check trdid
     801    if ( trdid != registered_trdid )
     802    {
     803       _printf("\nerror in _sys_pthread_join() : "
     804               "trdid = %x / registered_trdid = %x\n",
     805               trdid , registered_trdid );
     806
     807       return GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT;
     808    }
     809   
     810    // check calling thread and target thread in same vspace
     811    if ( caller_vspace != target_vspace )
     812    {
     813       _printf("\n[GIET ERROR] in _sys_pthread_join() : "
     814               " calling thread and target thread not in same vspace\n");
     815
     816       return GIET_SYSCALL_NOT_IN_SAME_VSPACE;
     817    }
     818
     819    // get target thread state
     820    unsigned int* pnorun = &psched->context[ltid].slot[CTX_NORUN_ID];
     821
     822    asm volatile ( "2000:                      \n"                         
     823                   "move  $11,  %0             \n"   /* $11 <= ptr           */
     824                   "lw    $11,  0($11)         \n"   /* $11 <= M[ptr]        */
     825                   "andi  $11,  $11,    1      \n"   /* $11 <= norun & 0x1   */
     826                   "beqz  $11,  2000b          \n"   
     827                   :
     828                   : "r" (pnorun)
     829                   : "$11" );
     830
     831    return GIET_SYSCALL_OK;
     832
     833}  // end _sys_pthread_join()
     834                       
     835
     836////////////////////////////////////////
     837int _sys_pthread_kill( pthread_t  trdid,
     838                       int        signal )
     839{
     840    // get calling thread vspace
     841    unsigned int  caller_vspace = _get_context_slot( CTX_VSID_ID );
     842
     843    // get and check target thread indexes from trdid
     844    unsigned int cx   = (trdid>>24) & 0xFF;
     845    unsigned int cy   = (trdid>>16) & 0xFF;
     846    unsigned int lpid = (trdid>>8 ) & 0xFF;
     847    unsigned int ltid = (trdid    ) & 0xFF;
     848
     849    // get target thread scheduler, vspace and registered trdid
     850    static_scheduler_t*  psched       = _schedulers[cx][cy][lpid];
     851    unsigned int target_vspace        = psched->context[ltid].slot[CTX_VSID_ID];
     852    unsigned int registered_trdid = psched->context[ltid].slot[CTX_TRDID_ID];
     853
     854    // check trdid
     855    if ( trdid != registered_trdid )
     856    {
     857       _printf("\n[GIET ERROR] in _sys_pthread_kill() : trdid = %x"
     858               " / registered_trdid = %x\n", trdid , registered_trdid );
     859       return GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT;
     860    }
     861   
     862    // check calling thread and target thread in same vspace
     863    if ( caller_vspace != target_vspace )
     864    {
     865       _printf("\n[GIET ERROR] in _sys_pthread_kill() : not in same vspace\n");
     866       return GIET_SYSCALL_NOT_IN_SAME_VSPACE;
     867    }
     868
     869    // register KILL signal in target thread context if required
     870    if ( signal )
     871    {
     872        _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL );
     873    }
     874
     875    return GIET_SYSCALL_OK;
     876
     877}  // end _sys_pthread_kill()
     878
     879
     880/////////////////////////////////////
     881int _sys_pthread_exit( void* string )
     882{
     883    unsigned int date       = _get_proctime();
     884
     885    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     886    mapping_vspace_t * vspace  = _get_vspace_base(header);
     887
     888    unsigned int ltid       = _get_context_slot(CTX_LTID_ID);
     889    unsigned int trdid      = _get_context_slot(CTX_TRDID_ID);
     890    unsigned int vsid       = _get_context_slot(CTX_VSID_ID);
     891
     892    // print exit message
     893    if ( string == NULL )
     894    {
     895        _printf("\n[GIET WARNING] Exit thread %x in vspace %s at cycle %d\n",
     896                trdid , vspace[vsid].name , date );
     897    }
     898    else
     899    {
     900        _printf("\n[GIET WARNING] Exit thread %x in vspace %s at cycle %d\n"
     901                "               Cause : %s\n\n",
     902                trdid , vspace[vsid].name , date , (char*) string );
     903    }
    373904   
    374 ///////////////////////////////////////
    375 int _sys_exec_application( char* name )
    376 {
    377     mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    378     mapping_vseg_t   * vseg    = _get_vseg_base(header);
    379     mapping_vspace_t * vspace  = _get_vspace_base(header);
    380     mapping_task_t   * task    = _get_task_base(header);
    381 
    382     unsigned int vspace_id;
    383     unsigned int task_id;
    384     unsigned int y_size = header->y_size;
    385 
    386 #if GIET_DEBUG_EXEC
     905    // get scheduler pointer for calling thread
     906    static_scheduler_t*  psched = (static_scheduler_t*)_get_sched();
     907
     908    // register KILL signal in calling thread context (suicid request)
     909    _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL );
     910
     911    // deschedule calling thread
     912    unsigned int save_sr; 
     913    _it_disable( &save_sr );
     914
     915    _ctx_switch();
     916
     917    return GIET_SYSCALL_OK;
     918
     919}  // end _sys_pthread_exit()
     920
     921////////////////////////
     922int _sys_pthread_yield()
     923{
     924    unsigned int save_sr;
     925
     926    _it_disable( &save_sr );
     927    _ctx_switch();
     928    _it_restore( &save_sr );
     929
     930    return GIET_SYSCALL_OK;
     931}
     932
     933//////////////////////////////////////////////////
     934int _sys_pthread_control( unsigned  int  command,
     935                          char*     vspace_name,
     936                          char*     thread_name )
     937{
     938
     939#if GIET_DEBUG_EXEC
    387940if ( _get_proctime() > GIET_DEBUG_EXEC )
    388 _printf("\n[DEBUG EXEC] enters _sys_exec_application() at cycle %d for %s\n",
    389          _get_proctime() , name );
    390 #endif
    391 
    392     // find vspace
    393     for ( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
    394     {
    395         if ( _strcmp( vspace[vspace_id].name, name ) == 0 )
     941_printf("\n[DEBUG EXEC] _sys_pthread_control() at cycle %d : "
     942        "enter for vspace %s / thread %s / command = %d\n",
     943        _get_proctime() , vspace_name, thread_name, command );
     944#endif
     945
     946    // get pointers in mapping
     947    mapping_header_t*    header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     948    mapping_thread_t*    thread   = _get_thread_base(header);
     949    mapping_vspace_t*    vspace   = _get_vspace_base(header);
     950    mapping_cluster_t*   cluster  = _get_cluster_base(header);
     951
     952    unsigned int found;
     953
     954    // search vspace name to get vspace index: vsid
     955    found = 0;
     956    unsigned int   vsid;
     957    for( vsid = 0 ; vsid < header->vspaces ; vsid++ )
     958    {
     959        if ( _strcmp( vspace[vsid].name, vspace_name ) == 0 )
     960        {
     961            found = 1;
    396962            break;
    397     }
    398 
    399     if ( vspace_id == header->vspaces )
    400     {
    401         _printf("\n[GIET ERROR] _sys_exec_application() : %s not found\n", name );
    402         return -1;
    403     }
    404 
    405     // scan tasks in vspace
    406     for (task_id = vspace[vspace_id].task_offset;
    407          task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
    408          task_id++)
    409     {
    410         unsigned int cid   = task[task_id].clusterid;
    411         unsigned int x     = cid / y_size;
    412         unsigned int y     = cid % y_size;
    413         unsigned int p     = task[task_id].proclocid;
    414         unsigned int ltid  = task[task_id].ltid;
    415 
    416         // get scheduler pointer for processor running the task
    417         static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    418 
    419         // check if an application task is runnable
    420         if ( psched->context[ltid][CTX_NORUN_ID] == 0 )
     963        }
     964    }
     965
     966    if ( found == 0 ) return GIET_SYSCALL_VSPACE_NOT_FOUND;
     967
     968    // search thread name in vspace to get thread index: tid
     969    found = 0;
     970    unsigned int   tid;
     971    unsigned int   min = vspace[vsid].thread_offset;
     972    unsigned int   max = min + vspace[vsid].threads;
     973    for( tid = min ; tid < max ; tid++ )
     974    {
     975        if ( _strcmp( thread[tid].name, thread_name ) == 0 )
    421976        {
    422             _printf( "\n[GIET ERROR] _sys_exec_application() : %s already executed\n", name );
    423             return -2;
     977            found = 1;
     978            break;
    424979        }
    425980    }
    426981
    427     // reload writable segments
    428     if ( _load_writable_segments( &vspace[vspace_id] ) )
    429     {
    430          _printf("[GIET ERROR] _sys_exec_application() : can't load segments for %s\n", name );
    431          return -3;
    432     }
    433 
    434     // scan tasks in vspace
    435     for (task_id = vspace[vspace_id].task_offset;
    436          task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
    437          task_id++)
    438     {
    439         unsigned int cid   = task[task_id].clusterid;
    440         unsigned int x     = cid / y_size;
    441         unsigned int y     = cid % y_size;
    442         unsigned int p     = task[task_id].proclocid;
    443         unsigned int ltid  = task[task_id].ltid;
    444 
    445         // get scheduler pointer for processor running the task
    446         static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    447 
    448         // reset task context: RA / SR / SP / EPC / NORUN
    449         unsigned int vseg_id       = task[task_id].stack_vseg_id;
    450         unsigned int sp_value      = vseg[vseg_id].vbase + vseg[vseg_id].length;
    451 
    452         psched->context[ltid][CTX_RA_ID]     = (unsigned int)&_ctx_eret;
    453         psched->context[ltid][CTX_SR_ID]     = GIET_SR_INIT_VALUE;
    454         psched->context[ltid][CTX_SP_ID]     = sp_value;
    455         psched->context[ltid][CTX_EPC_ID]    = psched->context[ltid][CTX_ENTRY_ID];
    456         psched->context[ltid][CTX_NORUN_ID]  = 0;
    457     }
    458 
    459 #if GIET_DEBUG_EXEC
    460 if ( _get_proctime() > GIET_DEBUG_EXEC )
    461 _printf("\n[DEBUG EXEC] exit _sys_exec_application() at cycle %d : %s will be executed\n",
    462         _get_proctime() , name );
    463 #endif
    464 
    465     return 0;
    466 }  // end _sys_exec_application()
    467    
     982    if ( found == 0 ) return GIET_SYSCALL_THREAD_NOT_FOUND;
     983
     984    // get thread coordinates
     985    unsigned int cid  = thread[tid].clusterid;
     986    unsigned int x    = cluster[cid].x;
     987    unsigned int y    = cluster[cid].y;
     988    unsigned int p    = thread[tid].proclocid;
     989    unsigned int ltid = thread[tid].ltid;
     990
     991    static_scheduler_t* psched = _schedulers[x][y][p];
     992
     993    // check trdid and vsid
     994    unsigned int trdid = x<<24 | y<<16 | p<<8 | ltid;
     995    if ( (psched->context[ltid].slot[CTX_TRDID_ID] != trdid) ||
     996         (psched->context[ltid].slot[CTX_VSID_ID]  != vsid) )
     997        return GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT;
     998
     999    // execute command
     1000    if ( command == THREAD_CMD_PAUSE )
     1001    {
     1002        _atomic_or ( &psched->context[ltid].slot[CTX_NORUN_ID],  NORUN_MASK_THREAD );
     1003        return GIET_SYSCALL_OK;
     1004    }
     1005    else if ( command == THREAD_CMD_RESUME )
     1006    {
     1007        _atomic_and( &psched->context[ltid].slot[CTX_NORUN_ID], ~NORUN_MASK_THREAD );
     1008        return GIET_SYSCALL_OK;
     1009    }
     1010    else if ( command == THREAD_CMD_CONTEXT )
     1011    {
     1012        _user_printf( " - CTX_TRDID  = %x\n"
     1013                      " - CTX_VSID   = %x\n"
     1014                      " - CTX_EPC    = %x\n"
     1015                      " - CTX_PTAB   = %x\n"
     1016                      " - CTX_PTPR   = %x\n"
     1017                      " - CTX_SR     = %x\n"
     1018                      " - CTX_RA     = %x\n"
     1019                      " - CTX_SP     = %x\n"
     1020                      " - CTX_ENTRY  = %x\n"
     1021                      " - CTX_NORUN  = %x\n"
     1022                      " - CTX_SIGS   = %x\n"
     1023                      " - CTX_LOCKS  = %x\n"
     1024                      " - CTX_TTY    = %x\n"
     1025                      " - CTX_NIC_RX = %x\n"
     1026                      " - CTX_NIC_TX = %x\n"
     1027                      " - CTX_CMA_RX = %x\n"
     1028                      " - CTX_CMA_TX = %x\n"
     1029                      " - CTX_CMA_FB = %x\n",
     1030                      psched->context[ltid].slot[CTX_TRDID_ID],
     1031                      psched->context[ltid].slot[CTX_VSID_ID],
     1032                      psched->context[ltid].slot[CTX_EPC_ID],
     1033                      psched->context[ltid].slot[CTX_PTAB_ID],
     1034                      psched->context[ltid].slot[CTX_PTPR_ID],
     1035                      psched->context[ltid].slot[CTX_SR_ID],
     1036                      psched->context[ltid].slot[CTX_RA_ID],
     1037                      psched->context[ltid].slot[CTX_SP_ID],
     1038                      psched->context[ltid].slot[CTX_ENTRY_ID],
     1039                      psched->context[ltid].slot[CTX_NORUN_ID],
     1040                      psched->context[ltid].slot[CTX_SIGS_ID],
     1041                      psched->context[ltid].slot[CTX_LOCKS_ID],
     1042                      psched->context[ltid].slot[CTX_TTY_ID],
     1043                      psched->context[ltid].slot[CTX_NIC_RX_ID],
     1044                      psched->context[ltid].slot[CTX_NIC_TX_ID],
     1045                      psched->context[ltid].slot[CTX_CMA_RX_ID],
     1046                      psched->context[ltid].slot[CTX_CMA_TX_ID],
     1047                      psched->context[ltid].slot[CTX_CMA_FB_ID] );
     1048        return GIET_SYSCALL_OK;
     1049    }
     1050    else
     1051    {
     1052        return GIET_SYSCALL_ILLEGAL_THREAD_COMMAND_TYPE;
     1053    }
     1054
     1055} // end _sys_pthread_control()
     1056
     1057
     1058
    4681059
    4691060//////////////////////////////////////////////////////////////////////////////
     
    4761067{
    4771068    // In this implementation, the allocation policy is constrained:
    478     // the coprocessor must be in the same cluster as the calling task,
     1069    // the coprocessor must be in the same cluster as the calling thread,
    4791070    // and there is at most one coprocessor per cluster
    4801071
     
    5191110        *coproc_info = _coproc_info[cluster_id];
    5201111
    521         // register coprocessor coordinates in task context
     1112        // register coprocessor coordinates in thread context
    5221113        unsigned int cluster_xy = (x<<Y_WIDTH) + y;
    5231114        _set_context_slot( CTX_COPROC_ID , cluster_xy );
     
    5281119        x , y , *coproc_info , cluster_xy );
    5291120#endif
    530         return 0;
     1121        return GIET_SYSCALL_OK;
    5311122    }
    5321123    else
     
    5351126                 " with type %d available in cluster[%d,%d]\n",
    5361127                 coproc_type , x , y );
    537         return -1;
     1128        return GIET_SYSCALL_COPROCESSOR_NOT_FOUND;
    5381129    }
    5391130}  // end _sys_coproc_alloc()
     
    5531144    {
    5541145         _printf("\n[GIET_ERROR] in _sys_coproc_release(): "
    555                  "no coprocessor allocated to task running on P[%d,%d,%d]\n",
     1146                 "no coprocessor allocated to thread running on P[%d,%d,%d]\n",
    5561147                 x , y , p );
    557          return -1;
     1148         return GIET_SYSCALL_COPROCESSOR_NOT_FOUND;
    5581149    }
    5591150
     
    5731164    }
    5741165
    575     // deallocates coprocessor coordinates in task context
     1166    // deallocates coprocessor coordinates in thread context
    5761167    _set_context_slot( CTX_COPROC_ID , 0xFFFFFFFF );
    5771168
     
    5841175#endif
    5851176
    586     return 0;
     1177    return GIET_SYSCALL_OK;
    5871178}  // end _sys_coproc_release()
    5881179
     
    6021193    {
    6031194         _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): "
    604                  "no coprocessor allocated to task running on P[%d,%d,%d]\n",
     1195                 "no coprocessor allocated to thread running on P[%d,%d,%d]\n",
    6051196                 x , y , p );
    606          return -1;
     1197         return GIET_SYSCALL_COPROCESSOR_NOT_FOUND;
    6071198    }
    6081199
     
    6151206         _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): "
    6161207                 " illegal mode\n");
    617          return -1;
     1208         return GIET_SYSCALL_COPROCESSOR_ILLEGAL_MODE;
    6181209    }
    6191210
     
    6221213 
    6231214    // physical addresses
    624     paddr_t            buffer_paddr;
     1215    unsigned long long buffer_paddr;
    6251216    unsigned int       buffer_lsb;
    6261217    unsigned int       buffer_msb;
    627     paddr_t            mwmr_paddr = 0;
     1218    unsigned long long mwmr_paddr = 0;
    6281219    unsigned int       mwmr_lsb;
    6291220    unsigned int       mwmr_msb;
    630     paddr_t            lock_paddr = 0;
     1221    unsigned long long lock_paddr = 0;
    6311222    unsigned int       lock_lsb;
    6321223    unsigned int       lock_msb;
     
    6741265#endif
    6751266       
    676     return 0;
     1267    return GIET_SYSCALL_OK;
    6771268} // end _sys_coproc_channel_init()
    6781269
     
    6911282    {
    6921283         _printf("\n[GIET_ERROR] in _sys_coproc_run(): "
    693                  "no coprocessor allocated to task running on P[%d,%d,%d]\n",
     1284                 "no coprocessor allocated to thread running on P[%d,%d,%d]\n",
    6941285                 x , y , p );
    695          return -1;
     1286         return -1111;
    6961287    }
    6971288
     
    7191310            _printf("\n[GIET_ERROR] P[%d,%d,%d] in _sys_coproc_run() for coprocessor[%d,%d]\n"
    7201311                    "  all channels don't have the same mode\n", x , y , p , cx , cy );
    721             return -1;
     1312            return -1111;
    7221313        }
    7231314    }
     
    7451336#endif
    7461337
    747         return 0;
     1338        return GIET_SYSCALL_OK;
    7481339    }
    7491340    ///////////////////////////////////////////////////////////////////////////
    7501341    else                                // mode == MODE_DMA_IRQ => descheduling
    7511342    {
    752         // set _coproc_gtid
    753         unsigned int ltid = _get_current_task_id();
    754         _coproc_gtid[cluster_id] = (procid<<16) + ltid;
     1343        // set _coproc_trdid
     1344        unsigned int ltid = _get_thread_ltid();
     1345        _coproc_trdid[cluster_id] = (x<<24) + (y<<16) + (p<<8) + ltid;
    7551346
    7561347        // enters critical section
     
    7601351        // set NORUN_MASK_COPROC bit
    7611352        static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
    762         unsigned int*       ptr     = &psched->context[ltid][CTX_NORUN_ID];
     1353        unsigned int*       ptr     = &psched->context[ltid].slot[CTX_NORUN_ID];
    7631354        _atomic_or( ptr , NORUN_MASK_COPROC );
    7641355
     
    7711362#endif
    7721363
    773         // deschedule task
     1364        // deschedule thread
    7741365        _ctx_switch();
    7751366
     
    8021393    {
    8031394         _printf("\n[GIET_ERROR] in _sys_coproc_completed(): "
    804                  "no coprocessor allocated to task running on P[%d,%d,%d]\n",
     1395                 "no coprocessor allocated to thread running on P[%d,%d,%d]\n",
    8051396                 x , y , p );
    806          return -1;
     1397         return -1111;
    8071398    }
    8081399
     
    8791470int _sys_tty_alloc( unsigned int shared )
    8801471{
    881     unsigned int channel;
    882 
     1472    unsigned int channel;    // allocated TTY channel
     1473
     1474    // get trdid and vsid for the calling thread
     1475    unsigned int vsid  = _get_context_slot( CTX_VSID_ID );
     1476    unsigned int trdid = _get_thread_trdid();
     1477
     1478    // check no TTY already allocated to calling thread
    8831479    if ( _get_context_slot( CTX_TTY_ID ) < NB_TTY_CHANNELS )
    8841480    {
    885         _printf("\n[GIET_ERROR] in _sys_tty_alloc() : TTY channel already allocated\n");
    886         return 0;
    887     }
    888 
    889     // get a new TTY channel
     1481        _printf("\n[GIET_ERROR] in _sys_tty_alloc() : "
     1482                "TTY channel already allocated to thread %x\n", trdid );
     1483        return -1111;
     1484    }
     1485
     1486    mapping_header_t  *header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     1487    mapping_vspace_t  *vspace   = _get_vspace_base(header);
     1488    mapping_thread_t  *thread   = _get_thread_base(header);
     1489   
     1490    // compute number of users
     1491    unsigned int users;
     1492    if ( shared )  users = vspace[vsid].threads;
     1493    else           users = 1;
     1494
     1495    // get a TTY channel
    8901496    for ( channel = 0 ; channel < NB_TTY_CHANNELS ; channel++ )
    8911497    {
    892         if ( !_tty_channel[channel] )
    893         {
    894             _tty_channel[channel] = 1;
    895             break;
    896         }
     1498        unsigned int* palloc  = &_tty_channel_alloc[channel];
     1499
     1500        if ( _atomic_test_and_set( palloc , users ) == 0 ) break;
    8971501    }
    8981502    if ( channel >= NB_TTY_CHANNELS )
    8991503    {
    900         _printf("\n[GIET_ERROR] in _sys_tty_alloc() : no TTY channel available\n");
    901         return -1;
    902     }
    903 
    904     // reset kernel buffer for allocated TTY channel
    905     _tty_rx_full[channel] = 0;
     1504        _printf("\n[GIET_ERROR] in _sys_tty_alloc() : "
     1505                "no TTY channel available for thread %x\n", trdid );
     1506        return -1111;
     1507    }
     1508
     1509    // initialise allocated TTY channel
     1510    _tty_init( channel );
    9061511
    9071512    // allocate a WTI mailbox to the calling proc if external IRQ
    908     unsigned int unused;
    909     if ( USE_PIC ) _ext_irq_alloc( ISR_TTY_RX , channel , &unused );
     1513    unsigned int wti_id;
     1514    if ( USE_PIC ) _ext_irq_alloc( ISR_TTY_RX , channel , &wti_id );
     1515
     1516    // register wti_id and coordinates for processor receiving WTI
     1517    unsigned int procid = _get_procid();
     1518    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
     1519    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     1520    unsigned int p      = procid & ((1<<P_WIDTH)-1);
     1521    _tty_channel_wti[channel] = x<<24 | y<<16 | p<<8 | wti_id;
    9101522   
    9111523    // update CTX_TTY_ID
    912     if ( shared )         // for all tasks in the same vspace
    913     {
    914         unsigned int      vspace_id = _get_context_slot( CTX_VSID_ID );
    915         mapping_header_t  *header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    916         mapping_vspace_t  *vspace   = _get_vspace_base(header);
    917         mapping_task_t    *task     = _get_task_base(header);
    918 
    919         // scan tasks in vspace
    920         unsigned int task_id;
    921         for (task_id = vspace[vspace_id].task_offset;
    922              task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
    923              task_id++)
     1524    if ( shared )         // for all threads in vspace
     1525    {
     1526        // scan threads in vspace
     1527        unsigned int tid;
     1528        for (tid = vspace[vsid].thread_offset;
     1529             tid < (vspace[vsid].thread_offset + vspace[vsid].threads);
     1530             tid++)
    9241531        {
    9251532            unsigned int y_size        = header->y_size;
    926             unsigned int cid           = task[task_id].clusterid;
     1533            unsigned int cid           = thread[tid].clusterid;
    9271534            unsigned int x             = cid / y_size;
    9281535            unsigned int y             = cid % y_size;
    929             unsigned int p             = task[task_id].proclocid;
    930             unsigned int ltid          = task[task_id].ltid;
     1536            unsigned int p             = thread[tid].proclocid;
     1537            unsigned int ltid          = thread[tid].ltid;
    9311538            static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p];
    9321539
    933             // don't overwrite TTY_ID
    934             if ( psched->context[ltid][CTX_TTY_ID] >= NB_TTY_CHANNELS )
    935             {
    936                 psched->context[ltid][CTX_TTY_ID] = channel;
    937             }
     1540            psched->context[ltid].slot[CTX_TTY_ID] = channel;
    9381541        }
    9391542    }
    940     else                  // for calling task only
     1543    else                  // for calling thread only
    9411544    {
    9421545        _set_context_slot( CTX_TTY_ID, channel );
    9431546    }
    9441547
    945     return 0;
    946 }
    947 
    948 /////////////////////////////////////////
    949 // NOTE: not a syscall
    950 int _sys_tty_release()
     1548    return GIET_SYSCALL_OK;
     1549}  // end _sys_tty_alloc()
     1550
     1551//////////////////////
     1552int _sys_tty_release()     // NOTE: not a syscall
    9511553{
    9521554    unsigned int channel = _get_context_slot( CTX_TTY_ID );
     
    9541556    if ( channel == -1 )
    9551557    {
    956         _printf("\n[GIET_ERROR] in _sys_tty_release() : TTY channel already released\n");
    957         return -1;
    958     }
    959 
    960     // release WTI mailbox
    961     if ( USE_PIC ) _ext_irq_release( ISR_TTY_RX , channel );
    962 
    963     // reset CTX_TTY_ID for all tasks in vspace
    964     unsigned int      vspace_id = _get_context_slot( CTX_VSID_ID );
    965     mapping_header_t  *header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    966     mapping_vspace_t  *vspace   = _get_vspace_base(header);
    967     mapping_task_t    *task     = _get_task_base(header);
    968 
    969     unsigned int task_id;
    970     for (task_id = vspace[vspace_id].task_offset;
    971          task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
    972          task_id++)
    973     {
    974         unsigned int y_size        = header->y_size;
    975         unsigned int cid           = task[task_id].clusterid;
    976         unsigned int x             = cid / y_size;
    977         unsigned int y             = cid % y_size;
    978         unsigned int p             = task[task_id].proclocid;
    979         unsigned int ltid          = task[task_id].ltid;
    980         static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p];
    981 
    982         // only clear matching TTY_ID
    983         if ( psched->context[ltid][CTX_TTY_ID] == channel )
    984         {
    985             psched->context[ltid][CTX_TTY_ID] = -1;
    986         }
    987     }
    988 
    989     // release TTY channel
    990     _tty_channel[channel] = 0;
    991 
    992     return 0;
    993 }
    994 
    995 /////////////////////////////////////////////////
     1558        unsigned int trdid = _get_thread_trdid();
     1559        _printf("\n[GIET_ERROR] in _sys_tty_release() : "
     1560                "TTY channel already released for thread %x\n", trdid );
     1561        return -1111;
     1562    }
     1563
     1564    // reset CTX_TTY_ID for the calling thread
     1565    _set_context_slot( CTX_TTY_ID , 0xFFFFFFFF );
     1566
     1567    // atomically decrement the _tty_channel_allocator[] array
     1568    _atomic_increment( &_tty_channel_alloc[channel] , -1 );
     1569
     1570    // release WTI mailbox if TTY channel no more used
     1571    if ( USE_PIC  && (_tty_channel_alloc[channel] == 0) )
     1572    {
     1573        _ext_irq_release( ISR_TTY_RX , channel );
     1574    }
     1575
     1576    return GIET_SYSCALL_OK;
     1577}  // end sys_tty_release()
     1578
     1579////////////////////////////////////////
    9961580int _sys_tty_write( const char*  buffer,   
    9971581                    unsigned int length,    // number of characters
     
    10021586    // compute and check tty channel
    10031587    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
    1004     if( channel >= NB_TTY_CHANNELS ) return -1;
     1588    if( channel >= NB_TTY_CHANNELS ) return -1111;
    10051589
    10061590    // write string to TTY channel
     
    10211605}
    10221606
    1023 ////////////////////////////////////////////////
     1607///////////////////////////////////////
    10241608int _sys_tty_read( char*        buffer,
    10251609                   unsigned int length,    // unused
     
    10281612    // compute and check tty channel
    10291613    if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID);
    1030     if( channel >= NB_TTY_CHANNELS ) return -1;
    1031 
    1032     // read one character from TTY channel
    1033     if (_tty_rx_full[channel] == 0)
    1034     {
    1035         return 0;
    1036     }
    1037     else
    1038     {
    1039         *buffer = _tty_rx_buf[channel];
    1040         _tty_rx_full[channel] = 0;
    1041         return 1;
    1042     }
     1614    if( channel >= NB_TTY_CHANNELS ) return -1111;
     1615
     1616    unsigned int save_sr;
     1617    unsigned int found = 0;
     1618
     1619    // get pointer on TTY_RX FIFO
     1620    tty_fifo_t*  fifo = &_tty_rx_fifo[channel];
     1621
     1622    // try to read one character from FIFO
     1623    // blocked in while loop until success
     1624    while ( found == 0 )
     1625    {
     1626        if ( fifo->sts == 0)   // FIFO empty => deschedule
     1627        {
     1628            // enters critical section
     1629             _it_disable( &save_sr );
     1630
     1631            // set NORUN_MASK_TTY bit for calling thread
     1632            static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
     1633            unsigned int ltid = psched->current;
     1634            _atomic_or( &psched->context[ltid].slot[CTX_NORUN_ID] , NORUN_MASK_TTY );
     1635
     1636            // register descheduling thread trdid
     1637            fifo->trdid = _get_thread_trdid();
     1638
     1639             // deschedule calling thread
     1640            _ctx_switch();
     1641
     1642            // exit critical section
     1643            _it_restore( &save_sr );
     1644        }
     1645        else                             // FIFO not empty => get one character
     1646        {
     1647            *buffer   = fifo->data[fifo->ptr];
     1648            fifo->sts = fifo->sts - 1;
     1649            fifo->ptr = (fifo->ptr + 1) % TTY_FIFO_DEPTH;
     1650            found     = 1;
     1651        }
     1652    }
     1653
     1654    return 1;
    10431655}
    10441656
    1045 ///////////////////////////////////////////
    1046 int _sys_tty_get_lock( unsigned int   channel,       // unused
    1047                        unsigned int * save_sr_ptr )
    1048 {
    1049     // check tty channel
    1050     if( channel != 0 )  return 1;
    1051 
    1052     _it_disable( save_sr_ptr );
    1053     _sqt_lock_acquire( &_tty0_sqt_lock );
    1054     return 0;
    1055 }
    1056 
    1057 ///////////////////////////////////////////////
    1058 int _sys_tty_release_lock( unsigned int   channel,
    1059                            unsigned int * save_sr_ptr )
    1060 {
    1061     // check tty channel
    1062     if( channel != 0 )  return 1;
    1063 
    1064     _sqt_lock_release( &_tty0_sqt_lock );
    1065     _it_restore( save_sr_ptr );
    1066     return 0;
    1067 }
     1657
    10681658
    10691659//////////////////////////////////////////////////////////////////////////////
    1070 //             TIM related syscall handlers
     1660//             TIMER related syscall handlers
    10711661//////////////////////////////////////////////////////////////////////////////
    10721662
     
    10741664int _sys_tim_alloc()
    10751665{
    1076     // get a new timer index
    1077     unsigned int channel = _atomic_increment( &_tim_channel_allocator, 1 );
    1078 
     1666
     1667#if NB_TIM_CHANNELS
     1668
     1669    unsigned int channel;    // allocated TIMER channel
     1670
     1671    unsigned int trdid = _get_thread_trdid();
     1672
     1673    // check no TIMER already allocated to calling thread
     1674    if ( _get_context_slot( CTX_TIM_ID ) < NB_TIM_CHANNELS )
     1675    {
     1676        _printf("\n[GIET_ERROR] in _sys_tim_alloc() : "
     1677                "TIMER channel already allocated to thread %x\n", trdid );
     1678        return -1111;
     1679    }
     1680
     1681    // get a TIMER channel
     1682    for ( channel = 0 ; channel < NB_TIM_CHANNELS ; channel++ )
     1683    {
     1684        unsigned int* palloc  = &_tim_channel_alloc[channel];
     1685
     1686        if ( _atomic_test_and_set( palloc , 1 ) == 0 ) break;
     1687    }
    10791688    if ( channel >= NB_TIM_CHANNELS )
    10801689    {
    1081         _printf("\n[GIET_ERROR] in _sys_tim_alloc() : not enough TIM channels\n");
    1082         return -1;
    1083     }
    1084     else
    1085     {
    1086         _set_context_slot( CTX_TIM_ID, channel );
    1087         return 0;
    1088     }
    1089 }
    1090 
    1091 ////////////////////
    1092 // NOTE: not a syscall
    1093 int _sys_tim_release()
    1094 {
    1095     // release one timer
    1096     _atomic_increment( &_tim_channel_allocator, 0xFFFFFFFF );
    1097 
    1098     return 0;
    1099 }
     1690        _printf("\n[GIET_ERROR] in _sys_tim_alloc() : "
     1691                "no TIMER channel available for thread %x\n", trdid );
     1692        return -1111;
     1693    }
     1694
     1695    // allocate a WTI mailbox to the calling proc if external IRQ
     1696    unsigned int wti_id;
     1697    if ( USE_PIC ) _ext_irq_alloc( ISR_TIMER , channel , &wti_id );
     1698
     1699    // register wti_id and coordinates for processor receiving WTI
     1700    unsigned int procid = _get_procid();
     1701    unsigned int x      = procid >> (Y_WIDTH + P_WIDTH);
     1702    unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     1703    unsigned int p      = procid & ((1<<P_WIDTH)-1);
     1704    _tim_channel_wti[channel] = x<<24 | y<<16 | p<<8 | wti_id;
     1705   
     1706    // update CTX_TIM_ID in thread context
     1707    _set_context_slot( CTX_TIM_ID, channel );
     1708
     1709    return GIET_SYSCALL_OK;
     1710
     1711#else
     1712
     1713    _printf("\n[GIET ERROR] in _sys_tim_alloc() : NB_TIM_CHANNELS = 0\n");
     1714    return -1111;
     1715
     1716#endif
     1717}  // end _sys_tim_alloc()
     1718
     1719
     1720//////////////////////
     1721int _sys_tim_release()     // NOTE: not a syscall
     1722{
     1723
     1724#if NB_TIM_CHANNELS
     1725
     1726    unsigned int channel = _get_context_slot( CTX_TIM_ID );
     1727
     1728    if ( channel == -1 )
     1729    {
     1730        unsigned int trdid = _get_thread_trdid();
     1731        _printf("\n[GIET_ERROR] in _sys_tim_release() : "
     1732                "TIMER channel already released for thread %x\n", trdid );
     1733        return -1111;
     1734    }
     1735
     1736    // reset CTX_TIM_ID for the calling thread
     1737    _set_context_slot( CTX_TIM_ID , 0xFFFFFFFF );
     1738
     1739    // reset the _tim_channel_alloc[] array
     1740    _tim_channel_alloc[channel] = 0;
     1741
     1742    // release WTI mailbox if TTY channel no more used
     1743    if ( USE_PIC )
     1744    {
     1745        _ext_irq_release( PERIPH_TYPE_TIM , channel );
     1746    }
     1747
     1748    return GIET_SYSCALL_OK;
     1749
     1750#else
     1751
     1752    _printf("\n[GIET ERROR] in _sys_tim_release() : NB_TIM_CHANNELS = 0\n");
     1753    return -1111;
     1754
     1755#endif
     1756}  // end _sys_tim_release()
    11001757
    11011758/////////////////////////////////////////
    11021759int _sys_tim_start( unsigned int period )
    11031760{
     1761
     1762#if NB_TIM_CHANNELS
     1763
    11041764    // get timer index
    11051765    unsigned int channel = _get_context_slot( CTX_TIM_ID );
     
    11071767    {
    11081768        _printf("\n[GIET_ERROR] in _sys_tim_start() : not enough TIM channels\n");
    1109         return -1;
     1769        return -1111;
    11101770    }
    11111771
     
    11131773    _timer_start( channel, period );
    11141774
    1115     return 0;
     1775    return GIET_SYSCALL_OK;
     1776
     1777#else
     1778
     1779    _printf("\n[GIET ERROR] in _sys_tim_start() : NB_TIM_CHANNELS = 0\n");
     1780    return -1111;
     1781
     1782#endif
    11161783}
    11171784
     
    11191786int _sys_tim_stop()
    11201787{
     1788
     1789#if NB_TIM_CHANNELS
     1790
    11211791    // get timer index
    11221792    unsigned int channel = _get_context_slot( CTX_TIM_ID );
     
    11241794    {
    11251795        _printf("\n[GIET_ERROR] in _sys_tim_stop() : illegal timer index\n");
    1126         return -1;
     1796        return -1111;
    11271797    }
    11281798
     
    11301800    _timer_stop( channel );
    11311801
    1132     return 0;
     1802    return GIET_SYSCALL_OK;
     1803
     1804#else
     1805
     1806    _printf("\n[GIET ERROR] in _sys_tim_stop() : NB_TIM_CHANNELS = 0\n");
     1807    return -1111;
     1808
     1809#endif
    11331810}
     1811
    11341812
    11351813//////////////////////////////////////////////////////////////////////////////
     
    11381816
    11391817#define NIC_CONTAINER_SIZE 4096
     1818
     1819#if NB_NIC_CHANNELS
    11401820
    11411821////////////////////////////////////////
     
    11441824                    unsigned int ymax )
    11451825{
     1826    mapping_header_t  *header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     1827    mapping_vspace_t  *vspace   = _get_vspace_base(header);
     1828    mapping_thread_t  *thread   = _get_thread_base(header);
     1829
     1830    // get calling thread trdid, vspace index, and number of threads
     1831    unsigned int trdid = _get_thread_trdid();
     1832    unsigned int vsid  = _get_context_slot( CTX_VSID_ID );
     1833    unsigned int users = vspace[vsid].threads;
     1834
    11461835    // check xmax / ymax parameters
    1147     if ( xmax > X_SIZE )
    1148     {
    1149         _printf("\n[GIET_ERROR] in _sys_nic_alloc() xmax argument too large\n");
    1150         return -1;
    1151     }
    1152     if ( ymax > Y_SIZE )
    1153     {
    1154         _printf("\n[GIET_ERROR] in _sys_nic_alloc() ymax argument too large\n");
    1155         return -1;
     1836    if ( (xmax > X_SIZE) || (ymax > Y_SIZE) )
     1837    {
     1838        _printf("\n[GIET_ERROR] in _sys_nic_alloc() "
     1839                "xmax or ymax argument too large for thread %x\n", trdid );
     1840        return -1111;
    11561841    }
    11571842
     
    11601845    ////////////////////////////////////////////////////////
    11611846
    1162     // get a NIC_RX or NIC_TX channel index
    1163     unsigned int nic_channel;
    1164     unsigned int cma_channel;
    1165 
    1166     if ( is_rx ) nic_channel = _atomic_increment( &_nic_rx_channel_allocator, 1 );
    1167     else         nic_channel = _atomic_increment( &_nic_tx_channel_allocator, 1 );
    1168 
     1847    unsigned int   nic_channel;
     1848    unsigned int   cma_channel;
     1849    unsigned int*  palloc;
     1850
     1851    // get a NIC_RX or NIC_TX channel
     1852    for ( nic_channel = 0 ; nic_channel < NB_NIC_CHANNELS ; nic_channel++ )
     1853    {
     1854        if ( is_rx ) palloc = &_nic_rx_channel_alloc[nic_channel];
     1855        else         palloc = &_nic_tx_channel_alloc[nic_channel];
     1856
     1857        if ( _atomic_test_and_set( palloc , users ) == 0 ) break;
     1858    }
    11691859    if ( (nic_channel >= NB_NIC_CHANNELS) )
    11701860    {
    1171         _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough NIC channels\n");
    1172         return -1;
    1173     }
    1174 
    1175     // get a CMA channel index
     1861        _printf("\n[GIET_ERROR] in _sys_nic_alloc() : "
     1862                "no NIC channel available for thread %x\n", trdid );
     1863        return -1111;
     1864    }
     1865
     1866    // get a CMA channel
    11761867    for ( cma_channel = 0 ; cma_channel < NB_CMA_CHANNELS ; cma_channel++ )
    11771868    {
    1178         if ( !_cma_channel[cma_channel] )
     1869        palloc = &_cma_channel_alloc[cma_channel];
     1870
     1871        if ( _atomic_test_and_set( palloc , users ) == 0 ) break;
     1872    }
     1873    if ( cma_channel >= NB_CMA_CHANNELS )
     1874    {
     1875        _printf("\n[GIET_ERROR] in _sys_nic_alloc() : "
     1876                "no CMA channel available for thread %x\n", trdid );
     1877        if ( is_rx )  _nic_rx_channel_alloc[nic_channel] = 0;
     1878        else          _nic_tx_channel_alloc[nic_channel] = 0;
     1879        return -1111;
     1880    }
     1881
     1882#if GIET_DEBUG_NIC
     1883_printf("\n[GIET DEBUG NIC] Thread %d enters sys_nic_alloc() at cycle %d\n"
     1884        "  nic_channel = %d / cma_channel = %d\n",
     1885        trdid , _get_proctime() , nic_channel , cma_channel );
     1886#endif
     1887
     1888    // register nic_index and cma_index in all threads
     1889    // contexts that are in the same vspace
     1890    unsigned int tid;
     1891    for (tid = vspace[vsid].thread_offset;
     1892         tid < (vspace[vsid].thread_offset + vspace[vsid].threads);
     1893         tid++)
     1894    {
     1895        unsigned int y_size        = header->y_size;
     1896        unsigned int cid           = thread[tid].clusterid;
     1897        unsigned int x             = cid / y_size;
     1898        unsigned int y             = cid % y_size;
     1899        unsigned int p             = thread[tid].proclocid;
     1900        unsigned int ltid          = thread[tid].ltid;
     1901        static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p];
     1902
     1903        if ( is_rx )
    11791904        {
    1180             _cma_channel[cma_channel] = 1;
    1181             break;
     1905            if ( (psched->context[ltid].slot[CTX_NIC_RX_ID] < NB_NIC_CHANNELS) ||
     1906                 (psched->context[ltid].slot[CTX_CMA_RX_ID] < NB_CMA_CHANNELS) )
     1907            {
     1908                _printf("\n[GIET_ERROR] in _sys_nic_alloc() : "
     1909                        "NIC_RX or CMA_RX channel already allocated for thread %x\n", trdid );
     1910                _nic_rx_channel_alloc[nic_channel] = 0;
     1911                _cma_channel_alloc[cma_channel]    = 0;
     1912                return -1111;
     1913            }
     1914            else
     1915            {
     1916                psched->context[ltid].slot[CTX_NIC_RX_ID] = nic_channel;
     1917                psched->context[ltid].slot[CTX_CMA_RX_ID] = cma_channel;
     1918            }
    11821919        }
    1183     }
    1184 
    1185     if ( cma_channel >= NB_CMA_CHANNELS )
    1186     {
    1187         _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough CMA channels\n");
    1188         return -1;
    1189     }
    1190 
    1191 #if GIET_DEBUG_NIC
    1192 unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    1193 _printf("\n[GIET DEBUG NIC] Task %d enters sys_nic_alloc() at cycle %d\n"
    1194         "  nic_channel = %d / cma_channel = %d\n",
    1195         thread , _get_proctime() , nic_channel , cma_channel );
    1196 #endif
    1197 
    1198     // register nic_index and cma_index in task context
    1199     if ( is_rx )
    1200     {
    1201         _set_context_slot( CTX_NIC_RX_ID, nic_channel );
    1202         _set_context_slot( CTX_CMA_RX_ID, cma_channel );
    1203     }
    1204     else
    1205     {
    1206         _set_context_slot( CTX_NIC_TX_ID, nic_channel );
    1207         _set_context_slot( CTX_CMA_TX_ID, cma_channel );
    1208     }
     1920        else // is_tx
     1921        {
     1922            if ( (psched->context[ltid].slot[CTX_NIC_TX_ID] < NB_NIC_CHANNELS) ||
     1923                 (psched->context[ltid].slot[CTX_CMA_TX_ID] < NB_CMA_CHANNELS) )
     1924            {
     1925                _printf("\n[GIET_ERROR] in _sys_nic_alloc() : "
     1926                        "NIC_TX or CMA_TX channel already allocated for thread %x\n", trdid );
     1927                _nic_tx_channel_alloc[nic_channel] = 0;
     1928                _cma_channel_alloc[cma_channel]    = 0;
     1929                return -1111;
     1930            }
     1931            else
     1932            {
     1933                psched->context[ltid].slot[CTX_NIC_TX_ID] = nic_channel;
     1934                psched->context[ltid].slot[CTX_CMA_TX_ID] = cma_channel;
     1935            }
     1936        }
     1937    }  // end loop on threads
    12091938
    12101939    /////////////////////////////////////////////////////////////////////////////////
     
    12411970            if ( vaddr == 0 )  // not enough kernel heap memory in cluster[cx,cy]
    12421971            {
    1243                 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough kenel heap"
    1244                         " in cluster[%d,%d]\n", cx, cy );
    1245                 return -1;
     1972                _printf("\n[GIET_ERROR] in _sys_nic_alloc() : "
     1973                        "not enough kenel heap in cluster[%d,%d]\n", cx, cy );
     1974                return -1111;
    12461975            }
    12471976
     
    12521981            if ( cont_paddr & 0x3F )
    12531982            {
    1254                 _printf("\n[GIET ERROR] in _sys_nic_alloc() : container address of cluster[%d,%d] not aligned\n",
    1255                         cx, cy);
    1256                 return -1;
     1983                _printf("\n[GIET ERROR] in _sys_nic_alloc() : "
     1984                        "container address of cluster[%d,%d] not aligned\n", cx, cy);
     1985                return -1111;
    12571986            }
    12581987
     
    12701999            if ( vaddr == 0 )  // not enough kernel heap memory in cluster[cx,cy]
    12712000            {
    1272                 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough kenel heap"
    1273                         " in cluster[%d,%d]\n", cx, cy );
    1274                 return -1;
     2001                _printf("\n[GIET_ERROR] in _sys_nic_alloc() : "
     2002                        "not enough kernel heap in cluster[%d,%d]\n", cx, cy );
     2003                return -1111;
    12752004            }
    12762005
     
    12812010            if ( sts_paddr & 0x3F )
    12822011            {
    1283                 _printf("\n[GIET ERROR] in _sys_nic_alloc() : status address of cluster[%d,%d] not aligned\n",
    1284                         cx, cy);
    1285                 return -1;
     2012                _printf("\n[GIET ERROR] in _sys_nic_alloc() : "
     2013                        "status address of cluster[%d,%d] not aligned\n", cx, cy);
     2014                return -1111;
    12862015            }
    12872016
     
    13852114#endif
    13862115
    1387     return nic_channel;
     2116    return GIET_SYSCALL_OK;
    13882117} // end _sys_nic_alloc()
    13892118
    13902119
    1391 ////////////////////////////////////////
    1392 // NOTE: not a syscall
    1393 int _sys_nic_release( unsigned int is_rx )
    1394 {
    1395     if ( is_rx )
    1396         _atomic_increment( &_nic_rx_channel_allocator , 0xFFFFFFFF );
    1397     else
    1398         _atomic_increment( &_nic_tx_channel_allocator , 0xFFFFFFFF );
    1399 
    1400     return 0;
    1401 }
    1402 
    1403 
    1404 ////////////////////////////////////////
    1405 int _sys_nic_start( unsigned int is_rx,
    1406                     unsigned int channel )
    1407 {
     2120//////////////////////////////////////////
     2121int _sys_nic_release( unsigned int is_rx )     // NOTE: not a syscall
     2122{
     2123    unsigned int trdid = _get_thread_trdid();
     2124
    14082125    unsigned int nic_channel;
    14092126    unsigned int cma_channel;
    1410 
    1411     // get NIC channel index and CMA channel index from task context
     2127   
     2128    // update the kernel tables
    14122129    if ( is_rx )
    14132130    {
    14142131        nic_channel = _get_context_slot( CTX_NIC_RX_ID );
    14152132        cma_channel = _get_context_slot( CTX_CMA_RX_ID );
    1416     }
     2133
     2134        if ( (nic_channel >= NB_NIC_CHANNELS) )
     2135        {
     2136            _printf("\n[GIET ERROR] in _sys_nic_release() : "
     2137                    "NIC_RX channel already released for thread %x\n", trdid );
     2138            return -1111;
     2139        }
     2140        if ( (cma_channel >= NB_CMA_CHANNELS) )
     2141        {
     2142            _printf("\n[GIET ERROR] in _sys_nic_release() : "
     2143                    "CMA_RX channel already released for thread %x\n", trdid );
     2144            return -1111;
     2145        }
     2146
     2147        // atomically decrement the NIC and CMA channel allocators
     2148        _atomic_increment( &_nic_rx_channel_alloc[nic_channel] , -1 );
     2149        _atomic_increment( &_cma_channel_alloc[cma_channel] , -1 );
     2150   
     2151        // stop the NIC and CMA peripherals channels if no more users
     2152        if ( (_nic_rx_channel_alloc[nic_channel] == 0) &&
     2153             (_cma_channel_alloc[cma_channel] == 0) )  _sys_nic_stop( 1 );
     2154
     2155        // reset the calling thread context slots
     2156        _set_context_slot( CTX_NIC_RX_ID , 0xFFFFFFFF );
     2157        _set_context_slot( CTX_CMA_RX_ID , 0xFFFFFFFF );
     2158    }         
    14172159    else
    14182160    {
    14192161        nic_channel = _get_context_slot( CTX_NIC_TX_ID );
    14202162        cma_channel = _get_context_slot( CTX_CMA_TX_ID );
     2163
     2164        if ( (nic_channel >= NB_NIC_CHANNELS) )
     2165        {
     2166            _printf("\n[GIET ERROR] in _sys_nic_release() : "
     2167                    "NIC_TX channel already released for thread %x\n", trdid );
     2168            return -1111;
     2169        }
     2170        if ( (cma_channel >= NB_CMA_CHANNELS) )
     2171        {
     2172            _printf("\n[GIET ERROR] in _sys_nic_release() : "
     2173                    "CMA_TX channel already released for thread %x\n", trdid );
     2174            return -1111;
     2175        }
     2176
     2177        // atomically decrement the NIC and CMA channel allocators
     2178        _atomic_increment( &_nic_tx_channel_alloc[nic_channel] , -1 );
     2179        _atomic_increment( &_cma_channel_alloc[cma_channel] , -1 );
     2180   
     2181        // stop the NIC and CMA peripherals channels if no more users
     2182        if ( (_nic_tx_channel_alloc[nic_channel] == 0) &&
     2183             (_cma_channel_alloc[cma_channel] == 0) )  _sys_nic_stop( 0 );
     2184
     2185        // reset the calling thread context slots
     2186        _set_context_slot( CTX_NIC_TX_ID , 0xFFFFFFFF );
     2187        _set_context_slot( CTX_CMA_TX_ID , 0xFFFFFFFF );
     2188    }
     2189
     2190    return GIET_SYSCALL_OK;
     2191}  // end sys_nic_release()
     2192
     2193
     2194////////////////////////////////////////
     2195int _sys_nic_start( unsigned int is_rx )
     2196{
     2197    unsigned int trdid  = _get_context_slot( CTX_TRDID_ID );
     2198
     2199    unsigned int nic_channel;
     2200    unsigned int cma_channel;
     2201
     2202    // get NIC channel index and CMA channel index from thread context
     2203    if ( is_rx )
     2204    {
     2205        nic_channel = _get_context_slot( CTX_NIC_RX_ID );
     2206        cma_channel = _get_context_slot( CTX_CMA_RX_ID );
     2207    }
     2208    else
     2209    {
     2210        nic_channel = _get_context_slot( CTX_NIC_TX_ID );
     2211        cma_channel = _get_context_slot( CTX_CMA_TX_ID );
    14212212    }
    14222213
    14232214#if GIET_DEBUG_NIC
    1424 unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    1425 _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_start() at cycle %d\n"
     2215_printf("\n[GIET DEBUG NIC] Thread %x in _sys_nic_start() at cycle %d\n"
    14262216        "  get NIC channel = %d / CMA channel = %d\n",
    1427         thread, _get_proctime(), nic_channel, cma_channel );
     2217        trdid, _get_proctime(), nic_channel, cma_channel );
    14282218#endif
    14292219
    14302220    // check NIC and CMA channels index
    1431     if ( nic_channel != channel )
    1432     {
    1433         _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal NIC channel\n");
    1434         return -1;
     2221    if ( nic_channel >= NB_NIC_CHANNELS )
     2222    {
     2223        _printf("\n[GIET_ERROR] in _sys_nic_start() : "
     2224                "illegal NIC channel for thread %x\n", trdid );
     2225        return -1111;
    14352226    }
    14362227    if ( cma_channel >= NB_CMA_CHANNELS )
    14372228    {
    1438         _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal CMA channel\n");
    1439         return -1;
     2229        _printf("\n[GIET_ERROR] in _sys_nic_start() : "
     2230                "illegal CMA channel for thread %x\n", trdid );
     2231        return -1111;
    14402232    }
    14412233
     
    14502242#if GIET_DEBUG_NIC
    14512243    _printf("\n[GIET DEBUG NIC] Task %d exit _sys_nic_start() at cycle %d\n",
    1452             thread , _get_proctime() );
    1453 #endif
    1454 
    1455     return 0;
     2244            trdid , _get_proctime() );
     2245#endif
     2246
     2247    return GIET_SYSCALL_OK;
    14562248}  // end _sys_nic_start()
    14572249
     
    14592251//////////////////////////////////////
    14602252int _sys_nic_move( unsigned int is_rx,
    1461                    unsigned int channel,
    14622253                   void*        buffer )
    14632254{
     2255    unsigned int trdid  = _get_context_slot( CTX_TRDID_ID );
     2256
     2257    unsigned int channel;
    14642258
    14652259#if GIET_DEBUG_NIC
    1466 unsigned int thread  = _get_context_slot( CTX_TRDID_ID );
    14672260_printf("\n[GIET DEBUG NIC] Task %d enters _sys_nic_move() at cycle %d\n",
    1468         thread , _get_proctime() );
    1469 #endif
     2261        trdid , _get_proctime() );
     2262#endif
     2263
     2264    // get NIC channel index from thread context
     2265    if ( is_rx )  channel = _get_context_slot( CTX_NIC_RX_ID );
     2266    else          channel = _get_context_slot( CTX_NIC_TX_ID );
    14702267
    14712268    // check NIC channel index
    14722269    if ( channel >= NB_NIC_CHANNELS )
    14732270    {
    1474         _printf("\n[GIET_ERROR] in _sys_nic_move() : illegal NIC channel index\n");
    1475         return -1;
     2271        _printf("\n[GIET_ERROR] in _sys_nic_move() : "
     2272                "illegal NIC channel index for thread %x\n", trdid );
     2273        return -1111;
    14762274    }
    14772275
     
    14852283    unsigned int ymax = ker_chbuf->ymax;
    14862284
    1487     // get cluster coordinates for the processor running the calling task
     2285    // get cluster coordinates for the processor running the calling thread
    14882286    unsigned int  procid = _get_procid();
    14892287    unsigned int  cx     = procid >> (Y_WIDTH + P_WIDTH);
     
    14952293        _printf("\n[GIET_ERROR] in _sys_nic_move() : processor X coordinate = %d"
    14962294                " / xmax = %d\n", cx , xmax );
    1497         return -1;
     2295        return -1111;
    14982296    }
    14992297    if ( cy >= ymax )
     
    15012299        _printf("\n[GIET_ERROR] in _sys_nic_move() : processor Y coordinate = %d"
    15022300                " / ymax = %d\n", cy , ymax );
    1503         return -1;
     2301        return -1111;
    15042302    }
    15052303   
     
    15182316    {
    15192317        _printf("\n[GIET ERROR] in _sys_nic_tx_move() : illegal user buffer address\n");
    1520         return -1;
     2318        return -1111;
    15212319    }
    15222320
     
    16062404#endif
    16072405
    1608     return 0;
     2406    return GIET_SYSCALL_OK;
    16092407} // end _sys_nic_move()
    16102408
    16112409
    1612 ////////////////////////////////////////
    1613 int _sys_nic_stop( unsigned int is_rx,
    1614                    unsigned int channel )
    1615 {
     2410///////////////////////////////////////
     2411int _sys_nic_stop( unsigned int is_rx )
     2412{
     2413    unsigned int trdid  = _get_context_slot( CTX_TRDID_ID );
     2414
    16162415    unsigned int nic_channel;
    16172416    unsigned int cma_channel;
     
    16302429
    16312430    // check NIC and CMA channels index
    1632     if ( nic_channel != channel )
    1633     {
    1634         _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal NIC channel\n");
    1635         return -1;
     2431    if ( nic_channel >= NB_NIC_CHANNELS )
     2432    {
     2433        _printf("\n[GIET_ERROR] in _sys_nic_stop() : "
     2434                "illegal NIC channel for thread %x\n", trdid );
     2435        return -1111;
    16362436    }
    16372437    if ( cma_channel >= NB_CMA_CHANNELS )
    16382438    {
    1639         _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal CMA channel\n");
    1640         return -1;
    1641     }
     2439        _printf("\n[GIET_ERROR] in _sys_nic_stop() : "
     2440                "illegal CMA channel for thread %x\n", trdid );
     2441        return -1111;
     2442    }
     2443
     2444    // desactivates the CMA channel
     2445    _cma_set_register( cma_channel, CHBUF_RUN , 0 );
     2446
     2447    // wait until CMA channel IDLE
     2448    unsigned int volatile status;
     2449    do
     2450    {
     2451         status = _cma_get_register( cma_channel, CHBUF_STATUS );
     2452    } while ( status );
    16422453
    16432454    // desactivates the NIC channel
    16442455    _nic_channel_stop( nic_channel, is_rx );
    16452456
    1646     // desactivates the CMA channel
    1647     _cma_set_register( cma_channel, CHBUF_RUN , 0 );
    1648 
    1649     return 0;
     2457    return GIET_SYSCALL_OK;
    16502458}  // end _sys_nic_stop()
    16512459
    16522460////////////////////////////////////////
    1653 int _sys_nic_clear( unsigned int is_rx,
    1654                     unsigned int channel )
    1655 {
    1656     unsigned int nic_channel;
     2461int _sys_nic_clear( unsigned int is_rx )
     2462{
     2463    unsigned int trdid  = _get_context_slot( CTX_TRDID_ID );
     2464
     2465    unsigned int channel;
    16572466
    16582467    // get NIC channel
    1659     if ( is_rx )  nic_channel = _get_context_slot( CTX_NIC_RX_ID );
    1660     else          nic_channel = _get_context_slot( CTX_NIC_TX_ID );
    1661 
    1662     if ( nic_channel != channel )
    1663     {
    1664         _printf("\n[GIET_ERROR] in _sys_nic_clear(): illegal NIC channel\n");
    1665         return -1;
     2468    if ( is_rx )  channel = _get_context_slot( CTX_NIC_RX_ID );
     2469    else          channel = _get_context_slot( CTX_NIC_TX_ID );
     2470
     2471    if ( channel >= NB_NIC_CHANNELS )
     2472    {
     2473        _printf("\n[GIET_ERROR] in _sys_nic_clear() : "
     2474                "illegal NIC channel for thread %x\n", trdid );
     2475        return -1111;
    16662476    }
    16672477
     
    16882498        _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_BROADCAST , 0 );
    16892499    }
    1690     return 0;
     2500    return GIET_SYSCALL_OK;
    16912501}  // en _sys_nic_clear()
    16922502
    16932503////////////////////////////////////////
    1694 int _sys_nic_stats( unsigned int is_rx,
    1695                     unsigned int channel )
    1696 {
     2504int _sys_nic_stats( unsigned int is_rx )
     2505{
     2506    unsigned int trdid  = _get_context_slot( CTX_TRDID_ID );
     2507
    16972508    unsigned int nic_channel;
    16982509
     
    17012512    else          nic_channel = _get_context_slot( CTX_NIC_TX_ID );
    17022513
    1703     if ( nic_channel != channel )
    1704     {
    1705         _printf("\n[GIET_ERROR] in _sys_nic_stats(): illegal NIC channel\n");
    1706         return -1;
     2514    if ( nic_channel >= NB_NIC_CHANNELS )
     2515    {
     2516        _printf("\n[GIET_ERROR] in _sys_nic_stats() : "
     2517                "illegal NIC channel for thread %x\n", trdid );
     2518        return -1111;
    17072519    }
    17082520
     
    17592571                broadcast );
    17602572    }
    1761     return 0;
     2573    return GIET_SYSCALL_OK;
    17622574}  // end _sys_nic_stats()
     2575
     2576#endif
    17632577
    17642578/////////////////////////////////////////////////////////////////////////////////////////
     
    17742588    memcpy( fbf_address, buffer, length);
    17752589
    1776     return 0;
     2590    return GIET_SYSCALL_OK;
    17772591}
    17782592
     
    17852599    memcpy( buffer, fbf_address, length);
    17862600
    1787     return 0;
     2601    return GIET_SYSCALL_OK;
    17882602}
    17892603
     
    17912605int _sys_fbf_cma_alloc()
    17922606{
     2607    unsigned int trdid = _get_thread_trdid();
     2608
    17932609    if ( _get_context_slot( CTX_CMA_FB_ID ) < NB_CMA_CHANNELS )
    17942610    {
    1795         _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : CMA channel already allocated\n");
    1796         return 0;
    1797     }
    1798 
    1799     // get a new CMA channel index
     2611        _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : "
     2612                "CMA channel already allocated for thread %x\n", trdid );
     2613        return GIET_SYSCALL_OK;
     2614    }
     2615
     2616    // get a CMA channel
    18002617    unsigned int channel;
    1801 
    18022618    for ( channel = 0 ; channel < NB_CMA_CHANNELS ; channel++ )
    18032619    {
    1804         if ( !_cma_channel[channel] )
    1805         {
    1806             _cma_channel[channel] = 1;
    1807             break;
    1808         }
    1809     }
    1810 
     2620        unsigned int*  palloc = &_cma_channel_alloc[channel];
     2621        if ( _atomic_test_and_set( palloc , 1 ) == 0 ) break;
     2622    }
    18112623    if ( channel >= NB_CMA_CHANNELS )
    18122624    {
    18132625        _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : no CMA channel available\n");
    1814         return -1;
     2626        return -1111;
    18152627    }
    18162628    else
    18172629    {
    18182630        _set_context_slot( CTX_CMA_FB_ID, channel );
    1819         return 0;
     2631        return GIET_SYSCALL_OK;
    18202632    }
    18212633} // end sys_fbf_cma_alloc()
    18222634
    1823 ////////////////////////
    1824 // NOTE: not a syscall
    1825 int _sys_fbf_cma_release()
     2635//////////////////////////
     2636int _sys_fbf_cma_release()  // Not a syscall
    18262637{
    18272638    unsigned int channel = _get_context_slot( CTX_CMA_FB_ID );
     2639    unsigned int trdid   = _get_thread_trdid();
    18282640
    18292641    if ( channel >= NB_CMA_CHANNELS )
    18302642    {
    1831         _printf("\n[GIET_ERROR] in _sys_fbf_cma_release() : CMA channel already released\n");
    1832         return -1;
    1833     }
    1834 
    1835     // stop fb
     2643        _printf("\n[GIET_ERROR] in _sys_fbf_cma_release() : "
     2644                "CMA_FB channel already releasedifor thread %x\n", trdid );
     2645        return -1111;
     2646    }
     2647
     2648    // stop CMA transfer
    18362649    _sys_fbf_cma_stop();
    18372650
    1838     // reset CTX_CMA_FB_ID for task
    1839     _set_context_slot( CTX_CMA_FB_ID, -1 );
     2651    // reset CTX_CMA_FB_ID for thread
     2652    _set_context_slot( CTX_CMA_FB_ID, 0xFFFFFFFF );
    18402653
    18412654    // release CMA channel
    1842     _cma_channel[channel] = 0;
    1843 
    1844     return 0;
     2655    _cma_channel_alloc[channel] = 0;
     2656
     2657    return GIET_SYSCALL_OK;
    18452658}
    18462659
     
    18682681    {
    18692682        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : CMA channel index too large\n");
    1870         return -1;
     2683        return -1111;
    18712684    }
    18722685
     
    18902703    {
    18912704        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : user buffer not aligned\n");
    1892         return -1;
     2705        return -1111;
    18932706    }
    18942707
     
    18982711    {
    18992712        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : user status not aligned\n");
    1900         return -1;
     2713        return -1111;
    19012714    }
    19022715
     
    19172730    {
    19182731        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : buf0 not in user space\n");
    1919         return -1;
     2732        return -1111;
    19202733    }
    19212734
     
    19252738    {
    19262739        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : sts0 not in user space\n");
    1927         return -1;
     2740        return -1111;
    19282741    }
    19292742
     
    19382751    {
    19392752        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : buf1 not in user space\n");
    1940         return -1;
     2753        return -1111;
    19412754    }
    19422755
     
    19462759    {
    19472760        _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : sts1 not in user space\n");
    1948         return -1;
     2761        return -1111;
    19492762    }
    19502763
     
    19742787#endif
    19752788
    1976     return 0;
     2789    return GIET_SYSCALL_OK;
    19772790
    19782791#else
    19792792
    19802793    _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : NB_CMA_CHANNELS = 0\n");
    1981     return -1;
     2794    return -1111;
    19822795
    19832796#endif 
     
    19952808    {
    19962809        _printf("\n[GIET ERROR] in _fbf_cma_start() : CMA channel index too large\n");
    1997         return -1;
     2810        return -1111;
    19982811    }
    19992812
     
    20052818        _printf("\n[GIET ERROR] in _sys_fbf_cma_start() :\n"
    20062819                "Buffer initialization has not been done\n");
    2007         return -1;
     2820        return -1111;
    20082821    }
    20092822
     
    20342847    _cma_set_register( channel, CHBUF_RUN      , 1 );
    20352848
    2036     return 0;
     2849    return GIET_SYSCALL_OK;
    20372850
    20382851#else
    20392852
    20402853    _printf("\n[GIET ERROR] in _sys_fbf_cma_start() : NB_CMA_CHANNELS = 0\n");
    2041     return -1;
     2854    return -1111;
    20422855
    20432856#endif
     
    20582871        _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : "
    20592872                "CMA channel index too large\n");
    2060         return -1;
     2873        return -1111;
    20612874    }
    20622875
     
    21382951    _mmc_sync( fbf_sts_paddr, 4 );
    21392952
    2140     return 0;
     2953    return GIET_SYSCALL_OK;
    21412954
    21422955#else
    21432956
    21442957    _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : no CMA channel allocated\n");
    2145     return -1;
     2958    return -1111;
    21462959
    21472960#endif
     
    21592972    {
    21602973        _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : CMA channel index too large\n");
    2161         return -1;
     2974        return -1111;
    21622975    }
    21632976
     
    21652978    _cma_set_register( channel, CHBUF_RUN, 0 );
    21662979
    2167     return 0;
     2980    return GIET_SYSCALL_OK;
    21682981
    21692982#else
    21702983
    21712984    _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : no CMA channel allocated\n");
    2172     return -1;
     2985    return -1111;
    21732986
    21742987#endif
     
    21842997{
    21852998    _printf("\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() );
    2186     return -1;
     2999    return GIET_SYSCALL_UNDEFINED_SYSTEM_CALL;
    21873000}
    21883001
     
    21983011    *p = gpid & ((1<<P_WIDTH)-1);
    21993012
    2200     return 0;
    2201 }
    2202 
    2203 //////////////////////////////////
    2204 int _sys_task_exit( char* string )
    2205 {
    2206     unsigned int date       = _get_proctime();
    2207 
    2208     unsigned int gpid       = _get_procid();
    2209     unsigned int cluster_xy = gpid >> P_WIDTH;
    2210     unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    2211     unsigned int x          = cluster_xy >> Y_WIDTH;
    2212     unsigned int p          = gpid & ((1<<P_WIDTH)-1);
    2213 
    2214     unsigned int ltid       = _get_context_slot(CTX_LTID_ID);
    2215 
    2216     // print exit message
    2217     _printf("\n[GIET] Exit task %d on processor[%d,%d,%d] at cycle %d"
    2218             "\n       Cause : %s\n\n",
    2219             ltid, x, y, p, date, string );
    2220 
    2221     // set NORUN_MASK_TASK bit (non runnable state)
    2222     static_scheduler_t*  psched  = (static_scheduler_t*)_schedulers[x][y][p];
    2223     unsigned int*        ptr     = &psched->context[ltid][CTX_NORUN_ID];
    2224     _atomic_or( ptr , NORUN_MASK_TASK );
    2225 
    2226     // deschedule
    2227     _sys_context_switch();
    2228 
    2229     return 0;
    2230 }
    2231 
    2232 /////////////////////////
    2233 int _sys_context_switch()
    2234 {
    2235     unsigned int save_sr;
    2236 
    2237     _it_disable( &save_sr );
    2238     _ctx_switch();
    2239     _it_restore( &save_sr );
    2240 
    2241     return 0;
    2242 }
    2243 
    2244 ////////////////////////
    2245 int _sys_local_task_id()
    2246 {
    2247     return _get_context_slot(CTX_LTID_ID);
    2248 }
    2249 
    2250 /////////////////////////
    2251 int _sys_global_task_id()
    2252 {
    2253     return _get_context_slot(CTX_GTID_ID);
    2254 }
    2255 
    2256 ////////////////////
    2257 int _sys_thread_id()
    2258 {
    2259     return _get_context_slot(CTX_TRDID_ID);
     3013    return GIET_SYSCALL_OK;
    22603014}
    22613015
     
    23123066        *nprocs = 0;
    23133067    }
    2314     return 0;
     3068    return GIET_SYSCALL_OK;
    23153069}
    23163070
     
    23403094                {
    23413095                    *vbase = vseg[vseg_id].vbase;
    2342                     return 0;
     3096                    return GIET_SYSCALL_OK;
    23433097                }
    23443098            }
    23453099        }
    23463100    }
    2347     return -1;    // not found
     3101    return GIET_SYSCALL_VSEG_NOT_FOUND;
    23483102}
    23493103
     
    23733127                {
    23743128                    *length = vseg[vseg_id].length;
    2375                     return 0;
     3129                    return GIET_SYSCALL_OK;
    23763130                }
    23773131            }
    23783132        }
    23793133    }
    2380     return -1;    // not found
     3134    return GIET_SYSCALL_VSEG_NOT_FOUND;
    23813135}
    23823136
     
    23923146    *y = (paddr>>32) & 0xF;
    23933147
    2394     return 0;
     3148    return GIET_SYSCALL_OK;
    23953149}
    23963150
     
    24013155                    unsigned int  y )
    24023156{
     3157    // checking parameters
     3158    if ( (x >= X_SIZE) || (y >= Y_SIZE) ) 
     3159    {
     3160        *vaddr  = 0;
     3161        *length = 0;
     3162        _printf("\n[GIET ERROR] in _sys_heap_info() : "
     3163                "illegal (%d,%d) coordinates\n", x , y );
     3164        return GIET_SYSCALL_ILLEGAL_CLUSTER_COORDINATES;
     3165    }
     3166
    24033167    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    2404     mapping_task_t *   task    = _get_task_base(header);
     3168    mapping_thread_t * thread  = _get_thread_base(header);
    24053169    mapping_vseg_t *   vseg    = _get_vseg_base(header);
    24063170    mapping_vspace_t * vspace  = _get_vspace_base(header);
    24073171
    2408     unsigned int task_id;
     3172    unsigned int thread_id;
    24093173    unsigned int vspace_id;
    24103174    unsigned int vseg_id = 0xFFFFFFFF;
    24113175
    2412     // searching the heap vseg
    2413     if ( (x < X_SIZE) && (y < Y_SIZE) )  // searching a task in cluster(x,y)
    2414     {
    2415         // get vspace global index
    2416         vspace_id = _get_context_slot(CTX_VSID_ID);
    2417 
    2418         // scan all tasks in vspace
    2419         unsigned int min = vspace[vspace_id].task_offset ;
    2420         unsigned int max = min + vspace[vspace_id].tasks ;
    2421         for ( task_id = min ; task_id < max ; task_id++ )
     3176    // get calling thread vspace index
     3177    vspace_id = _get_context_slot(CTX_VSID_ID);
     3178
     3179    // scan all threads in vspace to find one in clyster[x,y]
     3180    unsigned int min = vspace[vspace_id].thread_offset ;
     3181    unsigned int max = min + vspace[vspace_id].threads ;
     3182    for ( thread_id = min ; thread_id < max ; thread_id++ )
     3183    {
     3184        if ( thread[thread_id].clusterid == (x * Y_SIZE + y) )
    24223185        {
    2423             if ( task[task_id].clusterid == (x * Y_SIZE + y) )
    2424             {
    2425                 vseg_id = task[task_id].heap_vseg_id;
    2426                 if ( vseg_id != 0xFFFFFFFF ) break;
    2427             }
     3186            vseg_id = thread[thread_id].heap_vseg_id;
     3187            break;
    24283188        }
    2429     }
    2430     else                                // searching in the calling task
    2431     {
    2432         task_id = _get_context_slot(CTX_GTID_ID);
    2433         vseg_id = task[task_id].heap_vseg_id;
    24343189    }
    24353190
     
    24393194        *vaddr  = vseg[vseg_id].vbase;
    24403195        *length = vseg[vseg_id].length;
    2441         return 0;
    24423196    }
    24433197    else
     
    24453199        *vaddr  = 0;
    24463200        *length = 0;
    2447         return -1;
    2448     }
     3201        _printf("error in _sys_heap_info() : no heap in cluster (%d,%d)\n", x , y );
     3202    }
     3203    return GIET_SYSCALL_OK;
    24493204}  // end _sys_heap_info()
    2450 
    2451 
    2452 ///////////////////////
    2453 int _sys_tasks_status()
    2454 {
    2455     mapping_header_t *  header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    2456     mapping_task_t *    task    = _get_task_base(header);
    2457     mapping_vspace_t *  vspace  = _get_vspace_base(header);
    2458     mapping_cluster_t * cluster = _get_cluster_base(header);
    2459 
    2460     unsigned int task_id;
    2461     unsigned int vspace_id;
    2462 
    2463     // scan all vspaces
    2464     for( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
    2465     {
    2466         _printf("\n*** vspace %s\n", vspace[vspace_id].name );
    2467 
    2468         // scan all tasks in vspace
    2469         unsigned int min = vspace[vspace_id].task_offset ;
    2470         unsigned int max = min + vspace[vspace_id].tasks ;
    2471         for ( task_id = min ; task_id < max ; task_id++ )
    2472         {
    2473             unsigned int         clusterid = task[task_id].clusterid;
    2474             unsigned int         p         = task[task_id].proclocid;
    2475             unsigned int         x         = cluster[clusterid].x;
    2476             unsigned int         y         = cluster[clusterid].y;
    2477             unsigned int         ltid      = task[task_id].ltid;
    2478             static_scheduler_t*  psched    = (static_scheduler_t*)_schedulers[x][y][p];
    2479             unsigned int         norun     = psched->context[ltid][CTX_NORUN_ID];
    2480             unsigned int         current   = psched->current;
    2481 
    2482             if ( current == ltid )
    2483             _printf(" - task %s on P[%d,%d,%d] : running\n", task[task_id].name, x, y, p );
    2484             else if ( norun == 0 )
    2485             _printf(" - task %s on P[%d,%d,%d] : runable\n", task[task_id].name, x, y, p );
    2486             else
    2487             _printf(" - task %s on P[%d,%d,%d] : blocked\n", task[task_id].name, x, y, p );
    2488         }
    2489     }
    2490     return 0;
    2491 }  // end _sys_tasks_status()
    2492 
    2493 int _sys_fat_read( unsigned int fd_id,
    2494                    unsigned int buffer,
    2495                    unsigned int count )
    2496 {
    2497     return _fat_read(fd_id, buffer, count, 0);
    2498 }
    2499 
    25003205
    25013206
  • soft/giet_vm/giet_kernel/sys_handler.h

    r707 r709  
    1616#include "kernel_locks.h"
    1717#include "stdio.h"
     18
     19///////////////////////////////////////////////////////////////////////////////
     20// Define the possible command values for the giet_pthread_control() syscall
     21///////////////////////////////////////////////////////////////////////////////
     22
     23#define THREAD_CMD_PAUSE        0
     24#define THREAD_CMD_RESUME       1
     25#define THREAD_CMD_CONTEXT      2
     26
     27///////////////////////////////////////////////////////////////////////////////
     28// Define the error codes for the thread related syscalls
     29///////////////////////////////////////////////////////////////////////////////
     30
     31#define GIET_SYSCALL_OK                               ( 0 )
     32#define GIET_SYSCALL_VSPACE_NOT_FOUND                 (-1 )
     33#define GIET_SYSCALL_THREAD_NOT_FOUND                 (-2 )
     34#define GIET_SYSCALL_NOT_IN_SAME_VSPACE               (-3 )
     35#define GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT        (-4 )
     36#define GIET_SYSCALL_ILLEGAL_THREAD_COMMAND_TYPE      (-5 )
     37#define GIET_SYSCALL_CANNOT_LOAD_DATA_SEGMENT         (-6 )
     38#define GIET_SYSCALL_THREAD_ALREADY_ACTIVE            (-7 )
     39#define GIET_SYSCALL_MAIN_NOT_FOUND                   (-8 )
     40#define GIET_SYSCALL_APPLI_CANNOT_BE_KILLED           (-9 )
     41#define GIET_SYSCALL_PTHREAD_ARGUMENT_NOT_SUPPORTED   (-10)
     42#define GIET_SYSCALL_ILLEGAL_CLUSTER_COORDINATES      (-11)
     43#define GIET_SYSCALL_VSEG_NOT_FOUND                   (-12)
     44#define GIET_SYSCALL_UNDEFINED_SYSTEM_CALL            (-13)
     45#define GIET_SYSCALL_COPROCESSOR_NOT_FOUND            (-14)
     46#define GIET_SYSCALL_COPROCESSOR_ILLEGAL_MODE         (-15)
    1847
    1948///////////////////////////////////////////////////////////////////////////////
     
    86115
    87116
    88 
    89 
    90 ///////////////////////////////////////////////////////////////////////////////
    91 //    Coprocessors related syscall handlers
    92 ///////////////////////////////////////////////////////////////////////////////
    93 
    94 int _sys_coproc_register_set( unsigned int cluster_xy,
    95                               unsigned int reg_index,
    96                               unsigned int value );
    97 
    98 int _sys_coproc_register_get( unsigned int  cluster_xy,
    99                               unsigned int  reg_index,
    100                               unsigned int* buffer );
    101 
    102 int _sys_coproc_alloc( unsigned int   coproc_type,
    103                        unsigned int*  coproc_info );
    104 
    105 int _sys_coproc_release( unsigned int coproc_reg_index );
    106 
    107 int _sys_coproc_channel_init( unsigned int            channel,
    108                               giet_coproc_channel_t*  desc );
    109 
    110 int _sys_coproc_run( unsigned int coproc_reg_index );
    111 
    112 int _sys_coproc_completed();
     117//////////////////////////////////////////////////////////////////////////////
     118//           Applications related syscall handlers
     119//////////////////////////////////////////////////////////////////////////////
     120
     121extern int _sys_kill_application( char* name );
     122
     123extern int _sys_exec_application( char* name );
     124
     125extern int _sys_applications_status();
     126
     127/////////////////////////////////////////////////////////////////////////////
     128//          Threads related syscall handlers
     129/////////////////////////////////////////////////////////////////////////////
     130
     131extern int _sys_pthread_create( unsigned int*  buffer,
     132                                void*          attr,
     133                                void*          function,
     134                                void*          arg );
     135
     136extern int _sys_pthread_join( unsigned int  trdid,
     137                              void*         ptr );
     138
     139extern int _sys_pthread_kill( unsigned int  trdid,
     140                              int           signal );
     141
     142extern int _sys_pthread_exit( void* string);
     143
     144extern int _sys_pthread_yield();
     145
     146extern int _sys_pthread_control( unsigned int  command,
     147                                 char*         vspace_name,
     148                                 char*         thread_name );
     149
     150///////////////////////////////////////////////////////////////////////////////
     151//          Coprocessors related syscall handlers
     152///////////////////////////////////////////////////////////////////////////////
     153
     154extern int _sys_coproc_alloc( unsigned int   coproc_type,
     155                              unsigned int*  coproc_info );
     156
     157extern int _sys_coproc_release( unsigned int coproc_reg_index );
     158
     159extern int _sys_coproc_channel_init( unsigned int            channel,
     160                                     giet_coproc_channel_t*  desc );
     161
     162extern int _sys_coproc_run( unsigned int coproc_reg_index );
     163
     164extern int _sys_coproc_completed();
    113165
    114166///////////////////////////////////////////////////////////////////////////////
     
    116168///////////////////////////////////////////////////////////////////////////////
    117169
    118 int _sys_tty_alloc( unsigned int shared );
    119 
    120 int _sys_tty_release();
    121 
    122 int _sys_tty_write( const char*  buffer,
     170extern int _sys_tty_alloc( unsigned int shared );
     171
     172extern int _sys_tty_release();
     173
     174extern int _sys_tty_write( const char*  buffer,
    123175                    unsigned int length,
    124176                    unsigned int channel );
    125177
    126 int _sys_tty_read(  char*        buffer,
     178extern int _sys_tty_read(  char*        buffer,
    127179                    unsigned int length,
    128180                    unsigned int channel );
     
    132184//////////////////////////////////////////////////////////////////////////////
    133185
    134 int _sys_tim_alloc();
    135 
    136 int _sys_tim_release();
    137 
    138 int _sys_tim_start( unsigned int period );
    139 
    140 int _sys_tim_stop();
     186extern int _sys_tim_alloc();
     187
     188extern int _sys_tim_release();
     189
     190extern int _sys_tim_start( unsigned int period );
     191
     192extern int _sys_tim_stop();
    141193
    142194//////////////////////////////////////////////////////////////////////////////
     
    144196//////////////////////////////////////////////////////////////////////////////
    145197
    146 int _sys_nic_alloc( unsigned int is_rx,
    147                     unsigned int xmax,
    148                     unsigned int ymax );
    149 
    150 int _sys_nic_release( unsigned int is_rx );
    151 
    152 int _sys_nic_start( unsigned int is_rx,
    153                     unsigned int channel );
    154 
    155 int _sys_nic_move( unsigned int is_rx,
    156                    unsigned int channel,
    157                    void*        buffer );
    158 
    159 int _sys_nic_stop( unsigned int is_rx,
    160                    unsigned int channel );
    161 
    162 int _sys_nic_clear( unsigned int is_rx,
    163                     unsigned int channel );
    164 
    165 int _sys_nic_stats( unsigned int is_rx,
    166                     unsigned int channel );
     198extern int _sys_nic_alloc( unsigned int is_rx,
     199                           unsigned int xmax,
     200                           unsigned int ymax );
     201
     202extern int _sys_nic_release( unsigned int is_rx );
     203
     204extern int _sys_nic_start( unsigned int is_rx );
     205
     206extern int _sys_nic_move( unsigned int is_rx,
     207                          void*        buffer );
     208
     209extern int _sys_nic_stop( unsigned int is_rx );
     210
     211extern int _sys_nic_clear( unsigned int is_rx );
     212
     213extern int _sys_nic_stats( unsigned int is_rx );
    167214
    168215//////////////////////////////////////////////////////////////////////////////
     
    170217//////////////////////////////////////////////////////////////////////////////
    171218
    172 int _sys_fbf_sync_write( unsigned int offset,
     219extern int _sys_fbf_sync_write( unsigned int offset,
    173220                         void*        buffer,
    174221                         unsigned int length );
    175222
    176 int _sys_fbf_sync_read(  unsigned int offset,
     223extern int _sys_fbf_sync_read(  unsigned int offset,
    177224                         void*        buffer,
    178225                         unsigned int length );
    179226
    180 int _sys_fbf_cma_alloc();
    181 
    182 int _sys_fbf_cma_release();
    183 
    184 int _sys_fbf_cma_init_buf(void*        buf0_vbase,
     227extern int _sys_fbf_cma_alloc();
     228
     229extern int _sys_fbf_cma_release();
     230
     231extern int _sys_fbf_cma_init_buf(void*        buf0_vbase,
    185232                          void*        buf1_vbase,
    186233                          void*        sts0_vaddr,
    187234                          void*        sts1_vaddr );
    188235
    189 int _sys_fbf_cma_start( unsigned int length );
    190 
    191 int _sys_fbf_cma_display( unsigned int buffer_index );
    192 
    193 int _sys_fbf_cma_stop();
     236extern int _sys_fbf_cma_start( unsigned int length );
     237
     238extern int _sys_fbf_cma_display( unsigned int buffer_index );
     239
     240extern int _sys_fbf_cma_stop();
    194241
    195242//////////////////////////////////////////////////////////////////////////////
     
    197244//////////////////////////////////////////////////////////////////////////////
    198245
    199 int _sys_ukn();
    200 
    201 int _sys_proc_xyp( unsigned int* x,
     246extern int _sys_ukn();
     247
     248extern int _sys_proc_xyp( unsigned int* x,
    202249                   unsigned int* y,
    203250                   unsigned int* p );
    204251
    205 int _sys_task_exit( char* string );
    206 
    207 int _sys_kill_application( char* name );
    208 
    209 int _sys_exec_application( char* name );
    210 
    211 int _sys_context_switch();
    212 
    213 int _sys_local_task_id();
    214 
    215 int _sys_global_task_id();
    216 
    217 int _sys_thread_id();
    218 
    219 int _sys_procs_number( unsigned int* x_size,
     252extern int _sys_procs_number( unsigned int* x_size,
    220253                       unsigned int* y_size,
    221254                       unsigned int* nprocs );
    222255
    223 int _sys_vseg_get_vbase( char*         vspace_name,
     256extern int _sys_vseg_get_vbase( char*         vspace_name,
    224257                         char*         vseg_name,
    225258                         unsigned int* vbase );
    226259
    227 int _sys_vseg_get_length( char*         vspace_name,
     260extern int _sys_vseg_get_length( char*         vspace_name,
    228261                          char*         vseg_name,
    229262                          unsigned int* length );
    230263
    231 int _sys_xy_from_ptr( void*          ptr,
     264extern int _sys_xy_from_ptr( void*          ptr,
    232265                      unsigned int*  x,
    233266                      unsigned int*  y );
    234267
    235 int _sys_heap_info( unsigned int* vaddr,
     268extern int _sys_heap_info( unsigned int* vaddr,
    236269                    unsigned int* length,
    237270                    unsigned int  x,
    238271                    unsigned int  y );
    239 
    240 int _sys_tasks_status();
    241 
    242 int _sys_fat_read( unsigned int fd_id,
    243                    unsigned int buffer,
    244                    unsigned int count );
    245272
    246273#endif
Note: See TracChangeset for help on using the changeset viewer.