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

Last change on this file since 159 was 158, checked in by alain, 12 years ago

Introducing the giet_vm and some example applications

File size: 4.4 KB
Line 
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.
17// - It contains GPR[i], generally stored in slot (i). $0, *26 & $27 are not saved.
18// - It contains HI & LO registers.
19// - It contains CP0 registers: EPC, SR, CR.
20// - It contains CP2 registers : PTPR and MODE.
21// - It contains the TTY index for the terminal allocated to the task.
22// ctx[0] <- SR   ctx[8] <- $8    ctx[16]<- $16   ctx[24]<- $24   ctx[32]<- EPC
23// ctx[1] <- $1   ctx[9] <- $9    ctx[17]<- $17   ctx[25]<- $25   ctx[33]<- CR
24// ctx[2] <- $2   ctx[10]<- $10   ctx[18]<- $18   ctx[26]<- LO    ctx[34]<- TTY
25// ctx[3] <- $3   ctx[11]<- $11   ctx[19]<- $19   ctx[27]<- HI    ctx[35]<- PTPR
26// ctx[4] <- $4   ctx[12]<- $12   ctx[20]<- $20   ctx[28]<- $28   ctx[36]<- MODE
27// ctx[5] <- $5   ctx[13]<- $13   ctx[21]<- $21   ctx[29]<- $29   ctx[37]<- reserved
28// ctx[6] <- $6   ctx[14]<- $14   ctx[22]<- $22   ctx[30]<- $30   ctx[38]<- reserved
29// ctx[7] <- $7   ctx[15]<- $15   ctx[23]<- $23   ctx[31]<- $31   ctx[39]<- reserved
30/////////////////////////////////////////////////////////////////////////////////////
31
32#include <giet_config.h>
33#include <ctx_handler.h>
34#include <sys_handler.h>
35#include <drivers.h>
36#include <common.h>
37
38extern void _task_switch(unsigned int *, unsigned int *);
39
40/////////////////////////////////////////////////////////////////////////////////
41//      Global variables
42/////////////////////////////////////////////////////////////////////////////////
43
44static_scheduler_t _scheduler[NB_CLUSTERS * NB_PROCS];
45
46/////////////////////////////////////////////////////////////////////////////////
47//      _ctx_switch()
48// This function performs a context switch between the running task
49// and  another task, using a round-robin sheduling policy.
50// It use the global variable scheduler[] : array indexed by the procid,
51// that contains NB_CLUSTERS * NB_PROCS entries.
52// The return address contained in $31 is saved in the _current task context
53// (in the ctx[31] slot), and the function actually returns to the address
54// contained in the ctx[31] slot of the new task context. To perform the
55// actual switch, it calls the _task_switch function written in assembly language.
56/////////////////////////////////////////////////////////////////////////////////
57void _ctx_switch()
58{
59    unsigned char curr_task_id;
60    unsigned char next_task_id;
61
62    unsigned int *curr_context;
63    unsigned int *next_context;
64
65    unsigned int tasks;
66    unsigned int proc_id;
67
68    proc_id = _procid();
69    tasks   = _scheduler[proc_id].tasks;
70
71    // return if only one task  */
72    if ( tasks <= 1) return;
73
74    // compute the task context base address for the current task
75    curr_task_id = _scheduler[proc_id].current;
76    curr_context = &(_scheduler[proc_id].context[curr_task_id][0]);
77
78    // select the next task using a round-robin scheduling policy
79    next_task_id = (curr_task_id + 1) % tasks;
80   
81    // compute the task context base address for the next task
82    next_context = &(_scheduler[proc_id].context[next_task_id][0]);
83
84    //  update the scheduler state, and makes the task switch
85    _scheduler[proc_id].current = next_task_id;
86    _task_switch( curr_context, next_context );
87
88#if GIET_DEBUG_SWITCH
89unsigned int time = _proctime();
90_tty_puts( "\n[GIET] Context switch for processor ");
91_tty_putw( proc_id );
92_tty_puts( " at cycle ");
93_tty_putw( time );
94_tty_puts("\n");
95_tty_puts( " - tasks        = ");
96_tty_putw( tasks );
97_tty_puts("\n");
98_tty_puts( " - curr_task_id = ");
99_tty_putw( curr_task_id );
100_tty_puts("\n");
101_tty_puts( " - next_task_id = ");
102_tty_putw( next_task_id );
103_tty_puts("\n");
104#endif
105
106} // end _ctx_switch
107
Note: See TracBrowser for help on using the repository browser.