Changeset 189 for soft/giet_vm/sys/ctx_handler.c
- Timestamp:
- Aug 7, 2012, 6:37:49 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/sys/ctx_handler.c
r167 r189 1 /////////////////////////////////////////////////////////////////////////////////// 1 /////////////////////////////////////////////////////////////////////////////////////// 2 2 // File : ctx_handler.c 3 3 // Date : 01/04/2012 4 4 // Authors : alain greiner & joel porquet 5 5 // Copyright (c) UPMC-LIP6 6 //////////////////////////////////////////////////////////////////////////////////// 7 // The ctx_handler.h and ctx_handler.c files are part of the GIET nano-kernel.6 /////////////////////////////////////////////////////////////////////////////////////// 7 // The ctx_handler.h and ctx_handler.c files are part of the GIET-VM nano-kernel. 8 8 // This code is used to support context switch when several tasks are executing 9 9 // in time multiplexing on a single processor. 10 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 // 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. 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]<- *** 33 ///////////////////////////////////////////////////////////////////////////////////// 11 // there is one private scheduler per processor. 12 // Each sheduler contains up to 15 task contexts. 13 /////////////////////////////////////////////////////////////////////////////////////// 34 14 35 15 #include <giet_config.h> … … 40 20 #include <sys_handler.h> 41 21 42 extern void _task_switch(unsigned int *, unsigned int *); 43 44 ///////////////////////////////////////////////////////////////////////////////// 45 // Global variables : array of schedulers (one scheduler per processor) 46 ///////////////////////////////////////////////////////////////////////////////// 47 48 __attribute__((section (".kdata"))) static_scheduler_t _scheduler[NB_CLUSTERS * NB_PROCS]; 22 /////////////////////////////////////////////////////////////////////////////////////// 23 // A task context is an array of 64 words = 256 bytes. 24 // It contains copies of processor registers (when the task is preempted), 25 // and some general informations associated to the task. 26 // 27 // - It contains GPR[i], generally stored in slot (i). $0, *26 & $27 are not saved. 28 // - It contains HI & LO registers. 29 // - It contains CP0 registers: EPC, SR, CR, SCHED 30 // - It contains CP2 registers : PTPR and MODE. 31 // - It contains TTY global index, the FBDMA global index, the virtual base 32 // address of the page table (PTAB), and the task global index (TASK). 33 // 34 // ctx[0]<- SR|ctx[8] <- $8 |ctx[16]<- $16|ctx[24]<- $24|ctx[32]<- EPC |ctx[40]<- TTY 35 // ctx[1]<- $1|ctx[9] <- $9 |ctx[17]<- $17|ctx[25]<- $25|ctx[33]<- CR |ctx[41]<- FBDMA 36 // ctx[2]<- $2|ctx[10]<- $10|ctx[18]<- $18|ctx[26]<- LO |ctx[34]<- *** |ctx[42]<- PTAB 37 // ctx[3]<- $3|ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- PTPR|ctx[43]<- TASK 38 // ctx[4]<- $4|ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- MODE|ctx[44]<- SCHED 39 // ctx[5]<- $5|ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- *** |ctx[45]<- TIMER 40 // ctx[6]<- $6|ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- *** |ctx[46]<- *** 41 // ctx[7]<- $7|ctx[15]<- $15|ctx[23]<- $23|ctx[31]<- RA |ctx[39]<- *** |ctx[47]<- *** 42 //////////////////////////////////////////////////////////////////////////////////////// 43 44 extern void _task_switch(unsigned int*, unsigned int*); 49 45 50 46 ///////////////////////////////////////////////////////////////////////////////// … … 52 48 // This function performs a context switch between the running task 53 49 // 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 50 // 51 // It desactivate the DTLB, to directly access the scheduler using 52 // the physical address stored in register CP0_SCHED. 53 // All the context switch procedure is executed with interrupts masked. 54 // 55 // The return address contained in $31 is saved in the current task context 57 56 // (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. 57 // contained in the ctx[31] slot of the next task context. 60 58 ///////////////////////////////////////////////////////////////////////////////// 61 59 void _ctx_switch() 62 60 { 63 unsigned char curr_task_id; 64 unsigned char next_task_id; 65 66 unsigned int *curr_context; 67 unsigned int *next_context; 68 69 unsigned int proc_id = _procid(); 70 unsigned int tasks = _scheduler[proc_id].tasks; 71 72 // return if only one task */ 73 if ( tasks <= 1) return; 74 75 // compute the task context base address for the current task 76 curr_task_id = _scheduler[proc_id].current; 77 curr_context = &(_scheduler[proc_id].context[curr_task_id][0]); 61 unsigned int tasks; 62 unsigned int curr_task_id; 63 unsigned int next_task_id; 64 unsigned int *curr_ctx_paddr; 65 unsigned int *next_ctx_paddr; 66 67 // get scheduler physical address 68 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 69 70 // get number of tasks allocated to scheduler 71 tasks = _get_tasks_number(); 72 73 // no switch if only one task 74 if ( tasks > 1) 75 { 76 // compute the context physical address for the current task 77 curr_task_id = _get_current_task_id(); 78 curr_ctx_paddr = &(psched->context[curr_task_id][0]); 78 79 79 // select the next task using a round-robin schedulingpolicy80 next_task_id = (curr_task_id + 1) % tasks;80 // select the next task using a round-robin policy 81 next_task_id = (curr_task_id + 1) % tasks; 81 82 82 // compute the task context base address for the next task 83 next_context = &(_scheduler[proc_id].context[next_task_id][0]); 83 // compute the context physical address for the next task 84 next_ctx_paddr = &(psched->context[next_task_id][0]); 85 86 // update the scheduler state 87 _set_current_task_id( next_task_id ); 84 88 85 89 #if GIET_DEBUG_SWITCH 86 90 _get_lock( &_tty_put_lock ); 87 91 _puts( "\n[GIET] Context switch for processor "); 88 _putw( proc_id);92 _putw( _procid() ); 89 93 _puts( " at cycle "); 90 94 _putw( _proctime() ); … … 102 106 #endif 103 107 104 // update the scheduler state, and makes the task switch 105 _scheduler[proc_id].current = next_task_id; 106 _task_switch( curr_context, next_context ); 107 108 // makes the task switch 109 _task_switch( curr_ctx_paddr, next_ctx_paddr ); 110 111 /* 112 asm volatile( "ori $27, $0, 0xB \n" 113 "mtc2 $27, $1 \n" // desactivate DTLB 114 115 "add $27, %0, $0 \n" // $27 <= &curr_ctx 116 117 "mfc0 $26, $12 \n" // $26 <= SR 118 "sw $26, 0*4($27) \n" // ctx[0] <= SR 119 ".set noat \n" 120 "sw $1, 1*4($27) \n" // ctx[1] <= $1 121 ".set at \n" 122 "sw $2, 2*4($27) \n" // ctx[2] <= $2 123 "sw $3, 3*4($27) \n" // ctx[3] <= $3 124 "sw $4, 4*4($27) \n" // ctx[4] <= $4 125 "sw $5, 5*4($27) \n" // ctx[5] <= $5 126 "sw $6, 6*4($27) \n" // ctx[6] <= $6 127 "sw $7, 7*4($27) \n" // ctx[7] <= $7 128 "sw $8, 8*4($27) \n" // ctx[8] <= $8 129 "sw $9, 9*4($27) \n" // ctx[9] <= $9 130 "sw $10, 10*4($27) \n" // ctx[10] <= $10 131 "sw $11, 11*4($27) \n" // ctx[11] <= $11 132 "sw $12, 12*4($27) \n" // ctx[12] <= $12 133 "sw $13, 13*4($27) \n" // ctx[13] <= $13 134 "sw $14, 14*4($27) \n" // ctx[14] <= $14 135 "sw $15, 15*4($27) \n" // ctx[15] <= $15 136 "sw $16, 16*4($27) \n" // ctx[16] <= $16 137 "sw $17, 17*4($27) \n" // ctx[17] <= $17 138 "sw $18, 18*4($27) \n" // ctx[18] <= $18 139 "sw $19, 19*4($27) \n" // ctx[19] <= $19 140 "sw $20, 20*4($27) \n" // ctx[20] <= $20 141 "sw $21, 21*4($27) \n" // ctx[21] <= $21 142 "sw $22, 22*4($27) \n" // ctx[22] <= $22 143 "sw $23, 23*4($27) \n" // ctx[23] <= $23 144 "sw $24, 24*4($27) \n" // ctx[24] <= $24 145 "sw $25, 25*4($27) \n" // ctx[25] <= $25 146 "mflo $26 \n" 147 "sw $26, 26*4($27) \n" // ctx[26] <= LO 148 "mfhi $26 \n" 149 "sw $26, 27*4($27) \n" // ctx[27] <= H1 150 "sw $28, 28*4($27) \n" // ctx[28] <= $28 151 "sw $29, 29*4($27) \n" // ctx[29] <= $29 152 "sw $30, 30*4($27) \n" // ctx[30] <= $30 153 "sw $31, 31*4($27) \n" // ctx[31] <= $31 154 "mfc0 $26, $14 \n" 155 "sw $26, 32*4($27) \n" // ctx[32] <= EPC 156 "mfc0 $26, $13 \n" 157 "sw $26, 33*4($27) \n" // ctx[33] <= CR 158 "mfc2 $26, $0 \n" 159 "sw $26, 35*4($27) \n" // ctx[35] <= PTPR 160 161 "add $27, %1, $0 \n" // $27<= &next_ctx 162 163 "lw $26, 35*4($27) \n" 164 "mtc2 $26, $0 \n" // restore PTPR 165 "lw $26, 0*4($27) \n" 166 "mtc0 $26, $12 \n" // restore SR 167 ".set noat \n" 168 "lw $1, 1*4($27) \n" // restore $1 169 ".set at \n" 170 "lw $2, 2*4($27) \n" // restore $2 171 "lw $3, 3*4($27) \n" // restore $3 172 "lw $4, 4*4($27) \n" // restore $4 173 "lw $5, 5*4($27) \n" // restore $5 174 "lw $6, 6*4($27) \n" // restore $6 175 "lw $7, 7*4($27) \n" // restore $7 176 "lw $8, 8*4($27) \n" // restore $8 177 "lw $9, 9*4($27) \n" // restore $9 178 "lw $10, 10*4($27) \n" // restore $10 179 "lw $11, 11*4($27) \n" // restore $11 180 "lw $12, 12*4($27) \n" // restore $12 181 "lw $13, 13*4($27) \n" // restore $13 182 "lw $14, 14*4($27) \n" // restore $14 183 "lw $15, 15*4($27) \n" // restore $15 184 "lw $16, 16*4($27) \n" // restore $16 185 "lw $17, 17*4($27) \n" // restore $17 186 "lw $18, 18*4($27) \n" // restore $18 187 "lw $19, 19*4($27) \n" // restore $19 188 "lw $20, 20*4($27) \n" // restore $20 189 "lw $21, 21*4($27) \n" // restore $21 190 "lw $22, 22*4($27) \n" // restore $22 191 "lw $23, 23*4($27) \n" // restore $23 192 "lw $24, 24*4($27) \n" // restore $24 193 "lw $25, 25*4($27) \n" // restore $25 194 "lw $26, 26*4($27) \n" 195 "mtlo $26 \n" // restore LO 196 "lw $26, 27*4($27) \n" 197 "mthi $26 \n" // restore HI 198 "lw $28, 28*4($27) \n" // restore $28 199 "lw $29, 29*4($27) \n" // restore $29 200 "lw $30, 30*4($27) \n" // restore $30 201 "lw $31, 31*4($27) \n" // restore $31 202 "lw $26, 32*4($27) \n" 203 "mtc0 $26, $14 \n" // restore EPC 204 "lw $26, 33*4($27) \n" 205 "mtc0 $26, $13 \n" // restore CR 206 207 "ori $27, $0, 0xF \n" 208 "mtc2 $27, $1 \n" // activate DTLB 209 : 210 : "r"(curr_ctx_paddr), "r"(next_ctx_paddr) 211 : "$1" , "$4" ,"$5" ,"$6" ,"$7" ,"$8" ,"$9" ,"$10", 212 "$11","$12","$13","$14","$15","$16","$17","$18","$19","$20", 213 "$21","$22","$23","$24","$25","$26","$27", "$29", 214 "$31" ); 215 */ 216 } 108 217 } // end _ctx_switch 109 218
Note: See TracChangeset
for help on using the changeset viewer.