source: soft/giet_vm/giet_kernel/ctx_handler.c @ 708

Last change on this file since 708 was 707, checked in by guerin, 9 years ago

fix kill/exec

  • introduce physical_memcpy for fat_read
  • don't defer task exec
  • load writable segments in exec syscall
  • Property svn:executable set to *
File size: 6.9 KB
RevLine 
[294]1//////////////////////////////////////////////////////////////////////////////////
[258]2// File     : ctx_handler.c
3// Date     : 01/04/2012
4// Authors  : alain greiner & joel porquet
5// Copyright (c) UPMC-LIP6
[294]6//////////////////////////////////////////////////////////////////////////////////
[258]7
[440]8#include <ctx_handler.h>
[695]9#include <sys_handler.h>
[258]10#include <giet_config.h>
[528]11#include <hard_config.h>
[440]12#include <utils.h>
[459]13#include <tty0.h>
[258]14#include <xcu_driver.h>
15
[528]16/////////////////////////////////////////////////////////////////////////////////
17//     Extern variables and functions
18/////////////////////////////////////////////////////////////////////////////////
19
20// defined in giet_kernel/switch.s file
[258]21extern void _task_switch(unsigned int *, unsigned int *);
22
[528]23// allocated in boot.c or kernel_init.c files
24extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
25
[702]26
27///////////////////////////////////////////////
[695]28static void _ctx_kill_task( unsigned int ltid )
29{
30    // get scheduler address
31    static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
32
[697]33    // pretend the task to kill is scheduled (required for sys_handler calls)
34    unsigned int cur_task = psched->current;
35    psched->current = ltid;
36
[695]37    // release private TTY terminal if required
38    if ( psched->context[ltid][CTX_TTY_ID] < NB_TTY_CHANNELS )
39    {
40        _sys_tty_release();
[697]41        psched->context[ltid][CTX_TTY_ID] = -1;
[695]42    }
43
44    // release private TIM channel if required
45    if ( psched->context[ltid][CTX_TIM_ID] < NB_TIM_CHANNELS )
46    {
47        _sys_tim_release();
[697]48        psched->context[ltid][CTX_TIM_ID] = -1;
[695]49    }
50
51    // release private NIC_RX channel if required
52    if ( psched->context[ltid][CTX_NIC_RX_ID] < NB_NIC_CHANNELS )
53    {
54        _sys_nic_release( 1 );
[697]55        psched->context[ltid][CTX_NIC_RX_ID] = -1;
[695]56    }
57
58    // release private NIC_TX channel if required
59    if ( psched->context[ltid][CTX_NIC_TX_ID] < NB_NIC_CHANNELS )
60    {
61        _sys_nic_release( 0 );
[697]62        psched->context[ltid][CTX_NIC_TX_ID] = -1;
[695]63    }
64
[700]65    // release private FBF_CMA channel if required
66    if ( psched->context[ltid][CTX_CMA_FB_ID] < NB_CMA_CHANNELS )
67    {
68        _sys_fbf_cma_release();
69        psched->context[ltid][CTX_CMA_FB_ID] = -1;
70    }
71
[697]72    // restore scheduled task
73    psched->current = cur_task;
74
[695]75    // set NORUN_MASK_TASK bit
76    _atomic_or( &psched->context[ltid][CTX_NORUN_ID], NORUN_MASK_TASK );
77
[702]78} // end _ctx_kill_task()
[695]79
[702]80
[528]81//////////////////////////////////
82void _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"
[629]97            " - CTX_NORUN = %x\n"
[695]98            " - CTX_SIG   = %x\n"
[528]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], 
[629]108            psched->context[ltid][CTX_NORUN_ID],
[695]109            psched->context[ltid][CTX_SIG_ID],
[528]110            string );
111}  // _ctx_display()
112
113
[440]114//////////////////
[258]115void _ctx_switch() 
116{
[294]117    unsigned int gpid       = _get_procid();
[428]118    unsigned int cluster_xy = gpid >> P_WIDTH;
119    unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
[294]120
[258]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;
[695]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 );
[706]144
145            _ctx_kill_task( next_task_id );
[696]146        }
[695]147
[258]148        // test if the task is runable
[629]149        if ( psched->context[next_task_id][CTX_NORUN_ID] == 0 ) 
[258]150        {
151            found = 1;
[695]152            // TODO: don't break to process all pending signals.
[258]153            break;
154        }
155    }
156
157    // launch "idle" task if no runable task
[528]158    if (found == 0) next_task_id = IDLE_TASK_INDEX;
[258]159
[702]160#if ( GIET_DEBUG_SWITCH & 0x1 )
[294]161unsigned int x = cluster_xy >> Y_WIDTH;
162unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[702]163if ( _get_proctime() > GIET_DEBUG_SWITCH )
[528]164_printf("\n[DEBUG SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n",
[294]165        curr_task_id, next_task_id, x, y , lpid, _get_proctime() );
[258]166#endif
167
[294]168    if (curr_task_id != next_task_id)  // actual task switch required
169    {
[275]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
[528]173        // reset TICK timer counter.
[294]174        _xcu_timer_reset_cpt( cluster_xy, lpid );
[275]175
176        // set current task index
177        psched->current = next_task_id;
178
179        // makes context switch
[528]180        _task_switch( curr_ctx_vaddr , next_ctx_vaddr );
[258]181    }
182} //end _ctx_switch()
183
[528]184
[440]185/////////////////
[258]186void _idle_task() 
187{
[391]188    unsigned int gpid       = _get_procid();
[428]189    unsigned int cluster_xy = gpid >> P_WIDTH;
[391]190    unsigned int x          = cluster_xy >> Y_WIDTH;
191    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
[440]192    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
[391]193
[258]194    while(1)
195    {
[391]196        // initialize counter
[294]197        unsigned int count = GIET_IDLE_TASK_PERIOD;
[275]198
[294]199        // decounting loop
[258]200        asm volatile(
201                "move   $3,   %0              \n"
202                "_idle_task_loop:             \n"
203                "addi   $3,   $3,   -1        \n"
204                "bnez   $3,   _idle_task_loop \n"
205                "nop                          \n"
206                :
207                : "r"(count)
208                : "$3" ); 
209
[294]210        // warning message
[528]211        _printf("\n[GIET WARNING] Processor[%d,%d,%d] still idle at cycle %d",
212                x , y , p , _get_proctime() );
[258]213    }
214} // end ctx_idle()
215
216
[440]217////////////////
[258]218void _ctx_eret() 
219{
220    asm volatile("eret");
221}
222
223
224// Local Variables:
225// tab-width: 4
226// c-basic-offset: 4
227// c-file-offsets:((innamespace . 0)(inline-open . 0))
228// indent-tabs-mode: nil
229// End:
230// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
231
Note: See TracBrowser for help on using the repository browser.