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

Last change on this file since 166 was 165, checked in by alain, 12 years ago

Introducing various modifications in kernel initialisation

File size: 4.4 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.
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
[165]27// ctx[5] <- $5   ctx[13]<- $13   ctx[21]<- $21   ctx[29]<- $29   ctx[37]<- FBDMA
[158]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>
[160]33#include <drivers.h>
34#include <common.h>
[158]35#include <ctx_handler.h>
[160]36#include <mapping_info.h>
[158]37#include <sys_handler.h>
38
39extern void _task_switch(unsigned int *, unsigned int *);
40
41/////////////////////////////////////////////////////////////////////////////////
42//      Global variables
43/////////////////////////////////////////////////////////////////////////////////
44
45static_scheduler_t _scheduler[NB_CLUSTERS * NB_PROCS];
46
47/////////////////////////////////////////////////////////////////////////////////
48//      _ctx_switch()
49// This function performs a context switch between the running task
50// and  another task, using a round-robin sheduling policy.
51// It use the global variable scheduler[] : array indexed by the procid,
52// that contains NB_CLUSTERS * NB_PROCS entries.
53// The return address contained in $31 is saved in the _current task context
54// (in the ctx[31] slot), and the function actually returns to the address
55// contained in the ctx[31] slot of the new task context. To perform the
56// actual switch, it calls the _task_switch function written in assembly language.
57/////////////////////////////////////////////////////////////////////////////////
58void _ctx_switch()
59{
60    unsigned char curr_task_id;
61    unsigned char next_task_id;
62
63    unsigned int *curr_context;
64    unsigned int *next_context;
65
[165]66    unsigned int pid   = _procid();
67    unsigned int time  = _proctime();
68    unsigned int tasks = _scheduler[pid].tasks;
[158]69
70    // return if only one task  */
71    if ( tasks <= 1) return;
[160]72 
[158]73    // compute the task context base address for the current task
[165]74    curr_task_id = _scheduler[pid].current;
75    curr_context = &(_scheduler[pid].context[curr_task_id][0]);
[160]76   
[158]77    // select the next task using a round-robin scheduling policy
78    next_task_id = (curr_task_id + 1) % tasks;
79   
80    // compute the task context base address for the next task
[165]81    next_context = &(_scheduler[pid].context[next_task_id][0]);
[158]82
83#if GIET_DEBUG_SWITCH
[165]84_get_lock( &_tty_put_lock );
[164]85_puts( "\n[GIET] Context switch for processor ");
[165]86_putw( pid );
[164]87_puts( " at cycle ");
88_putw( time );
89_puts("\n");
90_puts( " - tasks        = ");
91_putw( tasks );
92_puts("\n");
93_puts( " - curr_task_id = ");
94_putw( curr_task_id );
95_puts("\n");
96_puts( " - next_task_id = ");
97_putw( next_task_id );
98_puts("\n");
[165]99_release_lock( &_tty_put_lock );
[158]100#endif
101
[165]102    //  update the scheduler state, and makes the task switch
103    _scheduler[pid].current = next_task_id;
104    _task_switch( curr_context, next_context );
105
[158]106} // end _ctx_switch
107
Note: See TracBrowser for help on using the repository browser.