source: soft/giet_vm/sys/ctx_handler.c @ 185

Last change on this file since 185 was 167, checked in by alain, 12 years ago

Fix several bugs to use the vci_block_device with MMU activated

File size: 4.6 KB
RevLine 
[158]1///////////////////////////////////////////////////////////////////////////////////
2// File     : ctx_handler.c
3// Date     : 01/04/2012
4// Authors  : alain greiner & joel porquet
5// Copyright (c) UPMC-LIP6
6////////////////////////////////////////////////////////////////////////////////////
7// The ctx_handler.h and ctx_handler.c files are part of the GIET nano-kernel.
8// This code is used to support context switch when several tasks are executing
9// in time multiplexing on a single processor.
10// The tasks must be statically allocated to a processor in the boot phase, and
11// there is one private scheduler per processor:  NB_CLUSTERS * NB_PROCS
12// Each sheduler contains up to NB_TASKS_MAX contexts.
13////////////////////////////////////////////////////////////////////////////////////
14// A task context is an array of 64 words = 256 bytes.
15// It contains copies of processor registers, when the task is not running,
16// and some general informations associated to the task.
[167]17//
[158]18// - It contains GPR[i], generally stored in slot (i). $0, *26 & $27 are not saved.
19// - It contains HI & LO registers.
20// - It contains CP0 registers: EPC, SR, CR.
21// - It contains CP2 registers : PTPR and MODE.
[167]22// - It contains the TTY global index, the FBDMA global index, the virtual base
23//   address of the page table (PTAB), and the task global index (TASK).
24//
25// ctx[0]<- SR|ctx[8] <- $8 |ctx[16]<- $16|ctx[24]<- $24|ctx[32]<- EPC |ctx[40]<- TTY
26// ctx[1]<- $1|ctx[9] <- $9 |ctx[17]<- $17|ctx[25]<- $25|ctx[33]<- CR  |ctx[41]<- FBDMA
27// ctx[2]<- $2|ctx[10]<- $10|ctx[18]<- $18|ctx[26]<- LO |ctx[34]<- *** |ctx[42]<- PTAB
28// ctx[3]<- $3|ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- PTPR|ctx[43]<- TASK
29// ctx[4]<- $4|ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- MODE|ctx[44]<- ***
30// ctx[5]<- $5|ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- *** |ctx[45]<- ***
31// ctx[6]<- $6|ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- *** |ctx[46]<- ***
32// ctx[7]<- $7|ctx[15]<- $15|ctx[23]<- $23|ctx[31]<- RA |ctx[39]<- *** |ctx[47]<- ***
[158]33/////////////////////////////////////////////////////////////////////////////////////
34
35#include <giet_config.h>
[160]36#include <drivers.h>
37#include <common.h>
[158]38#include <ctx_handler.h>
[160]39#include <mapping_info.h>
[158]40#include <sys_handler.h>
41
42extern void _task_switch(unsigned int *, unsigned int *);
43
44/////////////////////////////////////////////////////////////////////////////////
[167]45//      Global variables : array of schedulers (one scheduler per processor)
[158]46/////////////////////////////////////////////////////////////////////////////////
47
[167]48__attribute__((section (".kdata"))) static_scheduler_t _scheduler[NB_CLUSTERS * NB_PROCS];
[158]49
50/////////////////////////////////////////////////////////////////////////////////
51//      _ctx_switch()
52// This function performs a context switch between the running task
53// and  another task, using a round-robin sheduling policy.
54// It use the global variable scheduler[] : array indexed by the procid,
55// that contains NB_CLUSTERS * NB_PROCS entries.
56// The return address contained in $31 is saved in the _current task context
57// (in the ctx[31] slot), and the function actually returns to the address
58// contained in the ctx[31] slot of the new task context. To perform the
59// actual switch, it calls the _task_switch function written in assembly language.
60/////////////////////////////////////////////////////////////////////////////////
61void _ctx_switch()
62{
63    unsigned char curr_task_id;
64    unsigned char next_task_id;
65
66    unsigned int *curr_context;
67    unsigned int *next_context;
68
[167]69    unsigned int proc_id   = _procid();
70    unsigned int tasks     = _scheduler[proc_id].tasks;
[158]71
72    // return if only one task  */
73    if ( tasks <= 1) return;
[160]74 
[158]75    // compute the task context base address for the current task
[167]76    curr_task_id = _scheduler[proc_id].current;
77    curr_context = &(_scheduler[proc_id].context[curr_task_id][0]);
[160]78   
[158]79    // select the next task using a round-robin scheduling policy
80    next_task_id = (curr_task_id + 1) % tasks;
81   
82    // compute the task context base address for the next task
[167]83    next_context = &(_scheduler[proc_id].context[next_task_id][0]);
[158]84
85#if GIET_DEBUG_SWITCH
[165]86_get_lock( &_tty_put_lock );
[164]87_puts( "\n[GIET] Context switch for processor ");
[167]88_putw( proc_id );
[164]89_puts( " at cycle ");
[167]90_putw( _proctime() );
[164]91_puts("\n");
92_puts( " - tasks        = ");
93_putw( tasks );
94_puts("\n");
95_puts( " - curr_task_id = ");
96_putw( curr_task_id );
97_puts("\n");
98_puts( " - next_task_id = ");
99_putw( next_task_id );
100_puts("\n");
[165]101_release_lock( &_tty_put_lock );
[158]102#endif
103
[165]104    //  update the scheduler state, and makes the task switch
[167]105    _scheduler[proc_id].current = next_task_id;
[165]106    _task_switch( curr_context, next_context );
107
[158]108} // end _ctx_switch
109
Note: See TracBrowser for help on using the repository browser.