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

Last change on this file since 574 was 528, checked in by alain, 10 years ago

1) Introducing support for external IRQs dynamic routing.
2) Simplifying the _v2p_translate() function.
3) Removing the generic IOC driver (integrated in the FAT library).

  • Property svn:executable set to *
File size: 4.8 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>
[258]9#include <giet_config.h>
[528]10#include <hard_config.h>
[440]11#include <utils.h>
[459]12#include <tty0.h>
[258]13#include <xcu_driver.h>
14
[528]15/////////////////////////////////////////////////////////////////////////////////
16//     Extern variables and functions
17/////////////////////////////////////////////////////////////////////////////////
18
19// defined in giet_kernel/switch.s file
[258]20extern void _task_switch(unsigned int *, unsigned int *);
21
[528]22// allocated in boot.c or kernel_init.c files
23extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];
24
25//////////////////////////////////
26void _ctx_display( unsigned int x,
27                   unsigned int y,
28                   unsigned int p,
29                   unsigned int ltid,
30                   char*        string )
31{
32    static_scheduler_t* psched = _schedulers[x][y][p];
33    _printf("\n########## task[%d,%d,%d,%d] context\n"
34            " - CTX_EPC   = %x\n"
35            " - CTX_PTAB  = %x\n"
36            " - CTX_PTPR  = %x\n"
37            " - CTX_VSID  = %x\n"
38            " - CTX_SR    = %x\n"
39            " - CTX_RA    = %x\n"
40            " - CTX_SP    = %x\n"
41            " - CTX_RUN   = %x\n"
42            "########## %s\n",
43            x , y , p , ltid ,
44            psched->context[ltid][CTX_EPC_ID], 
45            psched->context[ltid][CTX_PTAB_ID], 
46            psched->context[ltid][CTX_PTPR_ID], 
47            psched->context[ltid][CTX_VSID_ID], 
48            psched->context[ltid][CTX_SR_ID], 
49            psched->context[ltid][CTX_RA_ID], 
50            psched->context[ltid][CTX_SP_ID], 
51            psched->context[ltid][CTX_RUN_ID],
52            string );
53}  // _ctx_display()
54
55
[440]56//////////////////
[258]57void _ctx_switch() 
58{
[294]59    unsigned int gpid       = _get_procid();
[428]60    unsigned int cluster_xy = gpid >> P_WIDTH;
61    unsigned int lpid       = gpid & ((1<<P_WIDTH)-1);
[294]62
[258]63    // get scheduler address
64    static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
65
66    // get number of tasks allocated to scheduler
67    unsigned int tasks = psched->tasks;
68
69    // get current task index
70    unsigned int curr_task_id = psched->current;
71
72    // select the next task using a round-robin policy
73    unsigned int next_task_id;
74    unsigned int tid;
75    unsigned int found = 0;
76
77    for (tid = curr_task_id + 1; tid < curr_task_id + 1 + tasks; tid++) 
78    {
79        next_task_id = tid % tasks;
80        // test if the task is runable
81        if ( psched->context[next_task_id][CTX_RUN_ID] ) 
82        {
83            found = 1;
84            break;
85        }
86    }
87
88    // launch "idle" task if no runable task
[528]89    if (found == 0) next_task_id = IDLE_TASK_INDEX;
[258]90
91#if GIET_DEBUG_SWITCH
[294]92unsigned int x = cluster_xy >> Y_WIDTH;
93unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
[528]94_printf("\n[DEBUG SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n",
[294]95        curr_task_id, next_task_id, x, y , lpid, _get_proctime() );
[258]96#endif
97
[294]98    if (curr_task_id != next_task_id)  // actual task switch required
99    {
[275]100        unsigned int* curr_ctx_vaddr = &(psched->context[curr_task_id][0]);
101        unsigned int* next_ctx_vaddr = &(psched->context[next_task_id][0]);
102
[528]103        // reset TICK timer counter.
[294]104        _xcu_timer_reset_cpt( cluster_xy, lpid );
[275]105
106        // set current task index
107        psched->current = next_task_id;
108
109        // makes context switch
[528]110        _task_switch( curr_ctx_vaddr , next_ctx_vaddr );
111
[258]112    }
113} //end _ctx_switch()
114
[528]115
[440]116/////////////////
[258]117void _idle_task() 
118{
[391]119    unsigned int gpid       = _get_procid();
[428]120    unsigned int cluster_xy = gpid >> P_WIDTH;
[391]121    unsigned int x          = cluster_xy >> Y_WIDTH;
122    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
[440]123    unsigned int p          = gpid & ((1<<P_WIDTH)-1);
[391]124
[258]125    while(1)
126    {
[391]127        // initialize counter
[294]128        unsigned int count = GIET_IDLE_TASK_PERIOD;
[275]129
[294]130        // decounting loop
[258]131        asm volatile(
132                "move   $3,   %0              \n"
133                "_idle_task_loop:             \n"
134                "addi   $3,   $3,   -1        \n"
135                "bnez   $3,   _idle_task_loop \n"
136                "nop                          \n"
137                :
138                : "r"(count)
139                : "$3" ); 
140
[294]141        // warning message
[528]142        _printf("\n[GIET WARNING] Processor[%d,%d,%d] still idle at cycle %d",
143                x , y , p , _get_proctime() );
[258]144    }
145} // end ctx_idle()
146
147
[440]148////////////////
[258]149void _ctx_eret() 
150{
151    asm volatile("eret");
152}
153
154
155// Local Variables:
156// tab-width: 4
157// c-basic-offset: 4
158// c-file-offsets:((innamespace . 0)(inline-open . 0))
159// indent-tabs-mode: nil
160// End:
161// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
162
Note: See TracBrowser for help on using the repository browser.