Changeset 199 for soft/giet_vm/sys
- Timestamp:
- Aug 9, 2012, 2:38:06 PM (12 years ago)
- Location:
- soft/giet_vm/sys
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/sys/common.c
r189 r199 324 324 return _physical_read_access( &(psched->current) ); 325 325 } 326 //////////////////////////////////////////////////////////////////////////// 327 // _set_current_task_id() 328 // This function returns the index of the currently running task. 329 //////////////////////////////////////////////////////////////////////////// 330 void _set_current_task_id( unsigned int value ) 331 { 332 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 333 _physical_write_access( &(psched->current), value ); 334 } 326 335 /////////////////////////////////////////////////////////////////////////////// 327 // _get_c urrent_context_slot()328 // This function returns the global TTY index for the currently running task.336 // _get_context_slot() 337 // This function returns a slot content for the task defined by task_id. 329 338 /////////////////////////////////////////////////////////////////////////////// 330 unsigned int _get_current_context_slot(unsigned int slot_id) 331 { 332 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 333 unsigned int current = _physical_read_access( &(psched->current) ); 334 return _physical_read_access( &(psched->context[current][slot_id]) ); 335 } 336 /////////////////////////////////////////////i////////////////////////////////// 339 unsigned int _get_context_slot( unsigned int task_id, 340 unsigned int slot_id ) 341 { 342 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 343 return _physical_read_access( &(psched->context[task_id][slot_id]) ); 344 } 345 /////////////////////////////////////////////////////////////////////////////// 346 // _set_context_slot() 347 // This function returns a slot content for the task defined by task_id. 348 /////////////////////////////////////////////////////////////////////////////// 349 void _set_context_slot( unsigned int task_id, 350 unsigned int slot_id, 351 unsigned int value ) 352 { 353 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 354 _physical_write_access( &(psched->context[task_id][slot_id]), value ); 355 } 356 //////////////////////////////////////////////////////////////////////////////// 337 357 // _get_interrupt_vector_entry() 338 358 // This function returns the interrupt_vector entry defined by argument index. … … 342 362 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 343 363 return _physical_read_access( &(psched->interrupt_vector[index]) ); 344 }345 ////////////////////////////////////////////////////////////////////////////346 // _set_current_task_id()347 // This function returns the index of the currently running task.348 ////////////////////////////////////////////////////////////////////////////349 void _set_current_task_id( unsigned int value )350 {351 static_scheduler_t* psched = (static_scheduler_t*)_get_sched();352 _physical_write_access( &(psched->current), value );353 364 } 354 365 -
soft/giet_vm/sys/common.h
r189 r199 36 36 void _putd(unsigned int val); 37 37 38 unsigned int _strncmp(const char* s1, const char* s2, unsigned int n); 38 unsigned int _strncmp( const char* s1, 39 const char* s2, 40 unsigned int n ); 39 41 40 void _dcache_buf_invalidate(const void *buffer, unsigned int size); 41 42 void _itoa_dec(unsigned int val, char* buf); 43 void _itoa_hex(unsigned int val, char* buf); 42 void _dcache_buf_invalidate( const void *buffer, 43 unsigned int size ); 44 44 45 45 void _dtlb_off(void); … … 55 55 unsigned int _get_sched(void); 56 56 57 unsigned int _get_current_context_slot(unsigned int index); 57 unsigned int _get_context_slot( unsigned int task_id, 58 unsigned int slot_id ); 59 60 void _set_context_slot( unsigned int task_id, 61 unsigned int slot_id, 62 unsigned int value ); 63 58 64 unsigned int _get_interrupt_vector_entry(unsigned int index); 59 unsigned int _get_current_task_id(void); 65 66 unsigned int _get_current_task_id( void ); 67 void _set_current_task_id( unsigned int value ); 68 60 69 unsigned int _get_tasks_number(void); 61 70 62 void _set_current_task_id( unsigned int value);63 71 64 72 void _get_lock(unsigned int* lock); -
soft/giet_vm/sys/ctx_handler.c
r189 r199 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 /////////////////////////////////////////////////////////////////////////////////////// 6 ///////////////////////////////////////////////////////////////////////////////////////// 7 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 // The tasks must be statically allocated to a processor in the boot phase, and 11 // there is one private scheduler per processor. 12 // Each sheduler contains up to 15 task contexts. 13 /////////////////////////////////////////////////////////////////////////////////////// 10 // The tasks are statically allocated to a processor in the boot phase, and 11 // there is one private scheduler per processor. Each sheduler occupies 4K bytes, 12 // and contains up to 14 task contexts (task_id is from 0 to 13). 13 // The task context [14] is reserved for the "idle" task that does nothing, and 14 // is launched by the scheduler when there is no other runable task. 15 ///////////////////////////////////////////////////////////////////////////////////////// 14 16 15 17 #include <giet_config.h> … … 20 22 #include <sys_handler.h> 21 23 22 /////////////////////////////////////////////////////////////////////////////////////// 24 ///////////////////////////////////////////////////////////////////////////////////////// 23 25 // 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 // It contains copies of processor registers (when the task is preempted): 27 // - GPR[i], generally stored in slot (i). $0, *26 & $27 are not saved. 28 // - HI & LO registers 29 // - CP0 registers: EPC, SR, CR, BVAR 30 // - CP2 registers : PTPR 31 // It contains some general informations associated to the task: 32 // - TTY : terminal global index 33 // - FBDMA : DMA channel global index 34 // - NIC : NIC channel global index 35 // - TIMER : Timer global index 36 // - PTAB : page table virtual base address 37 // - LTID : Task local index (in scheduler) 38 // - VSID : Virtual space index 39 // - RUN : Task state (0 => sleeping / 1 => runable ) 26 40 // 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 //////////////////////////////////////////////////////////////////////////////////////// 41 // ctx[0]<- ***|ctx[8] <- $8 |ctx[16]<- $16|ctx[24]<- $24|ctx[32]<- EPC |ctx[40]<- TTY 42 // ctx[1]<- $1 |ctx[9] <- $9 |ctx[17]<- $17|ctx[25]<- $25|ctx[33]<- CR |ctx[41]<- FBDMA 43 // ctx[2]<- $2 |ctx[10]<- $10|ctx[18]<- $18|ctx[26]<- LO |ctx[34]<- SR |ctx[42]<- NIC 44 // ctx[3]<- $3 |ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- BVAR |ctx[43]<- TIMER 45 // ctx[4]<- $4 |ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- *** |ctx[44]<- PTAB 46 // ctx[5]<- $5 |ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- *** |ctx[45]<- LTID 47 // ctx[6]<- $6 |ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- *** |ctx[46]<- VSID 48 // ctx[7]<- $7 |ctx[15]<- $15|ctx[23]<- $23|ctx[31]<- RA |ctx[39]<- PTPR |ctx[47]<- RUN 49 ////////////////////////////////////////////////////////////////////////////////////////// 43 50 44 51 extern void _task_switch(unsigned int*, unsigned int*); … … 47 54 // _ctx_switch() 48 55 // This function performs a context switch between the running task 49 // and another task, using a round-robin sheduling policy. 56 // and another task, using a round-robin sheduling policy between all 57 // tasks allocated to a given processor (static allocation). 58 // It selects the next runable task to resume execution. 59 // If the only runable task is the current task, return without context switch. 60 // If there is no runable task, the scheduler switch to the default "idle" task. 50 61 // 51 // I t desactivate the DTLB, to directly access the scheduler using52 // 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 context56 // (in the ctx[31] slot), and the function actually returns to the address57 // contained in the ctx[31] slot of the next task context.62 // Implementation notes: 63 // - As we only have the scheduler physical address (in CP0_SCHED register), 64 // this function must use specific assess functions to access the scheduler. 65 // - All the context switch procedure is executed with interrupts masked. 66 // - The return address contained in $31 is saved in the current task context 67 // (in the ctx[31] slot), and the function actually returns to the address 68 // contained in the ctx[31] slot of the next task context. 58 69 ///////////////////////////////////////////////////////////////////////////////// 59 70 void _ctx_switch() 60 71 { 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 72 // get scheduler physical address 68 73 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 69 74 70 75 // get number of tasks allocated to scheduler 71 tasks = _get_tasks_number();76 unsigned int tasks = _get_tasks_number(); 72 77 73 // no switch if only one task 74 if ( tasks > 1) 78 // get current task index 79 unsigned int curr_task_id = _get_current_task_id(); 80 81 // select the next task using a round-robin policy 82 unsigned int next_task_id; 83 unsigned int tid; 84 unsigned int found = 0; 85 86 for ( tid = curr_task_id + 1 ; 87 tid < curr_task_id + 1 + tasks ; 88 tid++ ) 75 89 { 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]); 79 80 // select the next task using a round-robin policy 81 next_task_id = (curr_task_id + 1) % tasks; 82 83 // compute the context physical address for the next task 84 next_ctx_paddr = &(psched->context[next_task_id][0]); 90 next_task_id = tid % tasks; 85 91 86 // update the scheduler state 92 // test if the task is runable 93 if ( _get_context_slot( next_task_id, CTX_RUN_ID ) ) 94 { 95 found = 1; 96 break; 97 } 98 } 99 100 // launch "idle" task if no runable task 101 if ( found == 0 ) 102 { 103 next_task_id = IDLE_TASK_INDEX; 104 } 105 106 // no switch if no change 107 if ( curr_task_id != next_task_id ) 108 { 109 unsigned int* curr_ctx_paddr = &(psched->context[curr_task_id][0]); 110 unsigned int* next_ctx_paddr = &(psched->context[next_task_id][0]); 111 87 112 _set_current_task_id( next_task_id ); 113 _task_switch( curr_ctx_paddr, next_ctx_paddr ); 88 114 89 115 #if GIET_DEBUG_SWITCH 90 116 _get_lock( &_tty_put_lock ); 91 _puts( "\n[GIET ] Context switch for processor ");92 _put w( _procid() );117 _puts( "\n[GIET DEBUG] Context switch for processor "); 118 _putd( _procid() ); 93 119 _puts( " at cycle "); 94 _put w( _proctime() );120 _putd( _proctime() ); 95 121 _puts("\n"); 96 122 _puts( " - tasks = "); 97 _put w( tasks );123 _putd( tasks ); 98 124 _puts("\n"); 99 125 _puts( " - curr_task_id = "); 100 _put w( curr_task_id );126 _putd( curr_task_id ); 101 127 _puts("\n"); 102 128 _puts( " - next_task_id = "); 103 _put w( next_task_id );129 _putd( next_task_id ); 104 130 _puts("\n"); 105 131 _release_lock( &_tty_put_lock ); 106 132 #endif 107 133 108 // makes the task switch109 _task_switch( curr_ctx_paddr, next_ctx_paddr ); 134 } 135 } //end _ctx_switch() 110 136 111 /* 112 asm volatile( "ori $27, $0, 0xB \n" 113 "mtc2 $27, $1 \n" // desactivate DTLB 137 ///////////////////////////////////////////////////////////////////////////////////// 138 // This function is executed as the"idle" task when no other task can be executed 139 ///////////////////////////////////////////////////////////////////////////////////// 140 void _ctx_idle() 141 { 142 unsigned int delay = 1000000; 114 143 115 "add $27, %0, $0 \n" // $27 <= &curr_ctx 144 while(1) 145 { 146 asm volatile("move $3, %0 \n" 147 "loop: \n" 148 "addi $3, $3, -1 \n" 149 "bnez $3, loop \n" 150 "nop \n" 151 : 152 : "r"(delay) 153 : "$3" ); 116 154 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 155 _get_lock( &_tty_put_lock ); 156 _puts( "\n[GIET WARNING] Processor "); 157 _putd( _procid() ); 158 _puts( " still idle at cycle "); 159 _putd( _proctime() ); 160 _puts("\n"); 161 _release_lock( &_tty_put_lock ); 162 163 } 164 } // end ctx_idle() 160 165 161 "add $27, %1, $0 \n" // $27<= &next_ctx 166 ///////////////////////////////////////////////////////////////////////////////// 167 // The address of this functionis used to initialise the return address 168 // in the "idle" task context. 169 ///////////////////////////////////////////////////////////////////////////////// 170 void _ctx_eret() 171 { 172 asm volatile("eret"); 173 } 162 174 163 "lw $26, 35*4($27) \n"164 "mtc2 $26, $0 \n" // restore PTPR165 "lw $26, 0*4($27) \n"166 "mtc0 $26, $12 \n" // restore SR167 ".set noat \n"168 "lw $1, 1*4($27) \n" // restore $1169 ".set at \n"170 "lw $2, 2*4($27) \n" // restore $2171 "lw $3, 3*4($27) \n" // restore $3172 "lw $4, 4*4($27) \n" // restore $4173 "lw $5, 5*4($27) \n" // restore $5174 "lw $6, 6*4($27) \n" // restore $6175 "lw $7, 7*4($27) \n" // restore $7176 "lw $8, 8*4($27) \n" // restore $8177 "lw $9, 9*4($27) \n" // restore $9178 "lw $10, 10*4($27) \n" // restore $10179 "lw $11, 11*4($27) \n" // restore $11180 "lw $12, 12*4($27) \n" // restore $12181 "lw $13, 13*4($27) \n" // restore $13182 "lw $14, 14*4($27) \n" // restore $14183 "lw $15, 15*4($27) \n" // restore $15184 "lw $16, 16*4($27) \n" // restore $16185 "lw $17, 17*4($27) \n" // restore $17186 "lw $18, 18*4($27) \n" // restore $18187 "lw $19, 19*4($27) \n" // restore $19188 "lw $20, 20*4($27) \n" // restore $20189 "lw $21, 21*4($27) \n" // restore $21190 "lw $22, 22*4($27) \n" // restore $22191 "lw $23, 23*4($27) \n" // restore $23192 "lw $24, 24*4($27) \n" // restore $24193 "lw $25, 25*4($27) \n" // restore $25194 "lw $26, 26*4($27) \n"195 "mtlo $26 \n" // restore LO196 "lw $26, 27*4($27) \n"197 "mthi $26 \n" // restore HI198 "lw $28, 28*4($27) \n" // restore $28199 "lw $29, 29*4($27) \n" // restore $29200 "lw $30, 30*4($27) \n" // restore $30201 "lw $31, 31*4($27) \n" // restore $31202 "lw $26, 32*4($27) \n"203 "mtc0 $26, $14 \n" // restore EPC204 "lw $26, 33*4($27) \n"205 "mtc0 $26, $13 \n" // restore CR206 175 207 "ori $27, $0, 0xF \n"208 "mtc2 $27, $1 \n" // activate DTLB209 :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 }217 } // end _ctx_switch218 -
soft/giet_vm/sys/ctx_handler.h
r189 r199 16 16 } static_scheduler_t; 17 17 18 19 ///////////////////////////////////////////////////////////////////////////////// 20 // "idle" task index definition 21 ///////////////////////////////////////////////////////////////////////////////// 22 23 #define IDLE_TASK_INDEX 14 24 18 25 ///////////////////////////////////////////////////////////////////////////////// 19 26 // Definition of the task context slots indexes 20 27 ///////////////////////////////////////////////////////////////////////////////// 21 28 22 #define CTX_SR_ID 023 29 #define CTX_SP_ID 29 24 30 #define CTX_RA_ID 31 … … 26 32 #define CTX_EPC_ID 32 27 33 #define CTX_CR_ID 33 28 #define CTX_PTPR_ID 35 29 #define CTX_MODE_ID 36 34 #define CTX_SR_ID 34 35 #define CTX_BVAR_ID 35 36 37 #define CTX_PTPR_ID 39 30 38 31 39 #define CTX_TTY_ID 40 32 40 #define CTX_FBDMA_ID 41 33 #define CTX_PTAB_ID 42 34 #define CTX_TASK_ID 43 35 #define CTX_SCHED_ID 44 36 #define CTX_TIMER_ID 45 41 #define CTX_NIC_ID 42 42 #define CTX_TIMER_ID 43 43 #define CTX_PTAB_ID 44 44 #define CTX_LTID_ID 45 45 #define CTX_VSID_ID 46 46 #define CTX_RUN_ID 47 37 47 38 48 ////////////////////////////////////////////////////////////////////////////////// … … 41 51 42 52 extern void _ctx_switch(); 53 extern void _ctx_eret(); 54 extern void _ctx_idle(); 43 55 44 56 extern static_scheduler_t _scheduler[]; -
soft/giet_vm/sys/drivers.c
r189 r199 162 162 { 163 163 unsigned int buffer = value; 164 unsigned int timer_id = _get_current_context_slot(CTX_TIMER_ID); 164 unsigned int task_id = _get_current_task_id(); 165 unsigned int timer_id = _get_context_slot(task_id, CTX_TIMER_ID); 165 166 unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX); 166 167 unsigned int local_id = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX); … … 190 191 unsigned int* buffer ) 191 192 { 192 unsigned int timer_id = _get_current_context_slot(CTX_TIMER_ID); 193 unsigned int task_id = _get_current_task_id(); 194 unsigned int timer_id = _get_context_slot(task_id, CTX_TIMER_ID); 193 195 unsigned int cluster_id = timer_id / (NB_PROCS_MAX + NB_TIMERS_MAX); 194 196 unsigned int local_id = timer_id % (NB_PROCS_MAX + NB_TIMERS_MAX); … … 232 234 // _tty_error() 233 235 //////////////////////////////////////////////////////////////////////////////// 234 void _tty_error() 235 { 236 unsigned int task_id = _get_current_task_id(); 236 void _tty_error( unsigned int task_id ) 237 { 237 238 unsigned int proc_id = _procid(); 238 239 … … 259 260 unsigned int nwritten; 260 261 261 unsigned int tty_id = _get_current_context_slot(CTX_TTY_ID); 262 unsigned int task_id = _get_current_task_id(); 263 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 264 262 265 if ( tty_id >= NB_TTYS ) 263 266 { 264 _tty_error( );267 _tty_error( task_id ); 265 268 return 0; 266 269 } … … 291 294 unsigned int length) 292 295 { 293 unsigned int tty_id = _get_current_context_slot(CTX_TTY_ID); 296 unsigned int task_id = _get_current_task_id(); 297 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 294 298 295 299 if ( tty_id >= NB_TTYS ) 296 300 { 297 _tty_error( );301 _tty_error( task_id ); 298 302 return 0; 299 303 } … … 320 324 unsigned int length) 321 325 { 322 unsigned int tty_id = _get_current_context_slot(CTX_TTY_ID); 326 unsigned int task_id = _get_current_task_id(); 327 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 328 323 329 if ( tty_id >= NB_TTYS ) 324 330 { 325 _tty_error( );331 _tty_error( task_id ); 326 332 return 0; 327 333 } … … 544 550 545 551 // get user space page table virtual address 546 unsigned int user_pt_vbase = _get_current_context_slot(CTX_PTAB_ID); 552 unsigned int task_id = _get_current_task_id(); 553 unsigned int user_pt_vbase = _get_context_slot( task_id, CTX_PTAB_ID ); 547 554 548 555 user_vpn_min = user_vaddr >> 12; … … 815 822 816 823 // get DMA channel and compute DMA vbase address 817 unsigned int dma_id = _get_current_context_slot(CTX_FBDMA_ID); 824 unsigned int task_id = _get_current_task_id(); 825 unsigned int dma_id = _get_context_slot( task_id, CTX_FBDMA_ID ); 818 826 unsigned int cluster_id = dma_id / NB_DMAS_MAX; 819 827 unsigned int loc_id = dma_id % NB_DMAS_MAX; … … 830 838 831 839 // get user space page table virtual address 832 unsigned int user_ptab = _get_c urrent_context_slot(CTX_PTAB_ID);840 unsigned int user_ptab = _get_context_slot( task_id, CTX_PTAB_ID ); 833 841 834 842 // compute frame buffer pbase address … … 985 993 unsigned int _fb_completed() 986 994 { 987 unsigned int dma_id = _get_current_context_slot(CTX_FBDMA_ID); 995 unsigned int task_id = _get_current_task_id(); 996 unsigned int dma_id = _get_context_slot( task_id, CTX_FBDMA_ID ); 988 997 989 998 // busy waiting with a pseudo random delay between bus access -
soft/giet_vm/sys/exc_handler.c
r189 r199 10 10 11 11 #include <exc_handler.h> 12 #include <ctx_handler.h> 12 13 #include <sys_handler.h> 13 14 #include <drivers.h> … … 53 54 }; 54 55 55 static const char *exc_message_causes[] = {56 " \n\nException : strange unknown cause\n",57 " \n\nException : illegal read address \n",58 " \n\nException : illegal write address\n",59 " \n\nException : inst bus error \n",60 " \n\nException : data bus error \n",61 " \n\nException : breakpoint \n",62 " \n\nException : reserved instruction \n",63 " \n\nException : illegal coproc access\n"64 " \n\nException : arithmetic overflow \n",56 static const char* exc_type[] = { 57 "strange unknown cause", 58 "illegal read address", 59 "illegal write address", 60 "inst bus error", 61 "data bus error", 62 "breakpoint", 63 "reserved instruction", 64 "illegal coproc access" 65 "arithmetic overflow", 65 66 }; 66 67 67 static void _ cause(unsigned int msg_cause)68 static void _display_cause(unsigned int type) 68 69 { 69 _puts( (char*)(exc_message_causes[msg_cause]) ); 70 _puts("\n - Cycle : "); 70 _puts("\n[GIET] Exception for task "); 71 _putd( _get_current_task_id() ); 72 _puts(" on processor "); 73 _putd( _procid() ); 74 _puts(" at cycle "); 71 75 _putd( _proctime() ); 72 _puts("\n - Processor : "); 73 _putd( _procid() ); 74 _puts("\n - Task : "); 75 _putd( _get_current_task_id() ); 76 _puts("\n - type : "); 77 _puts( (char*)exc_type[type] ); 76 78 _puts("\n - EPC : "); 77 79 _putw( _get_epc() ); … … 79 81 _putw( _get_bvar() ); 80 82 _puts("\n"); 81 _exit(); 83 84 // goes to sleeping state 85 unsigned int task_id = _get_current_task_id(); 86 _set_context_slot( task_id, CTX_RUN_ID, 0 ); 87 88 // deschedule 89 _ctx_switch(); 82 90 } 83 91 84 static void _cause_ukn() { _ cause(0); }85 static void _cause_adel() { _ cause(1); }86 static void _cause_ades() { _ cause(2); }87 static void _cause_ibe() { _ cause(3); }88 static void _cause_dbe() { _ cause(4); }89 static void _cause_bp() { _ cause(5); }90 static void _cause_ri() { _ cause(6); }91 static void _cause_cpu() { _ cause(7); }92 static void _cause_ovf() { _ cause(8); }92 static void _cause_ukn() { _display_cause(0); } 93 static void _cause_adel() { _display_cause(1); } 94 static void _cause_ades() { _display_cause(2); } 95 static void _cause_ibe() { _display_cause(3); } 96 static void _cause_dbe() { _display_cause(4); } 97 static void _cause_bp() { _display_cause(5); } 98 static void _cause_ri() { _display_cause(6); } 99 static void _cause_cpu() { _display_cause(7); } 100 static void _cause_ovf() { _display_cause(8); } 93 101 -
soft/giet_vm/sys/kernel_init.c
r189 r199 8 8 // It contains the kernel entry point for the last step of system initialisation. 9 9 // All procs in this phase have their MMU activated, and are running in parallel. 10 // - each processor updates its own scheduler, to replace the ISR index 11 // by the actual ISR virtual address, and set its own entry in the 12 // kernel _schedulers_paddr[] array. 13 // - each processor initialises the SP, SR, PTPR, EPC registers, and starts 14 // its private Timer, before jumping to the user code with an eret. 10 // Each processor perform the following actions: 11 // 1/ contributes to _schedulers_paddr[] initialisation 12 // 2/ contributes to _ptabs_paddr[] and _ptabs_vaddr arrays initialisation 13 // 3/ computes and set the ICU mask for its private ICU channel 14 // 4/ initialises its private TICK timer (if required) 15 // 5/ initialises the "idle" task context in its private scheduler 16 // 6/ initialises the SP, SR, PTPR, EPC registers 17 // 7/ jumps to the user code with an eret. 15 18 //////////////////////////////////////////////////////////////////////////////////// 16 19 … … 34 37 35 38 __attribute__((section (".kdata"))) 36 page_table_t* _ptabs_paddr[GIET_NB_VSPACE_MAX]; 37 38 __attribute__((section (".kdata"))) 39 page_table_t* _ptabs_vaddr[GIET_NB_VSPACE_MAX]; 40 41 __attribute__((section (".kdata"))) 42 static_scheduler_t* _schedulers_paddr[NB_CLUSTERS*NB_PROCS_MAX]; 39 unsigned int _ptabs_paddr[GIET_NB_VSPACE_MAX]; 40 41 __attribute__((section (".kdata"))) 42 unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX]; 43 44 __attribute__((section (".kdata"))) 45 static_scheduler_t* _schedulers_paddr[NB_CLUSTERS*NB_PROCS_MAX]; 46 47 __attribute__((section (".kdata"))) 48 unsigned int _idle_stack[NB_CLUSTERS*NB_PROCS_MAX*64]; 43 49 44 50 ////////////////////////////////////////////////////////////////////////////////// … … 47 53 __attribute__((section (".kinit"))) void _kernel_init() 48 54 { 49 // values to be written in registers 50 unsigned int sp_value; 51 unsigned int sr_value; 52 unsigned int ptpr_value; 53 unsigned int epc_value; 54 55 // compute cluster and local processor index 55 56 unsigned int proc_id = _procid(); 56 57 unsigned int cluster_id = proc_id / NB_PROCS_MAX; … … 66 67 _get_lock(&_tty_put_lock); 67 68 _puts("\n[GIET DEBUG] step 1 for processor "); 68 _putw( proc_id ); 69 _puts("\n"); 70 _puts("- scheduler pbase = "); 69 _putd( proc_id ); 70 _puts(" / scheduler pbase = "); 71 71 _putw( (unsigned int)psched ); 72 72 _puts("\n"); … … 74 74 #endif 75 75 76 // step 2 : compute and set ICU mask 76 77 // step 2 : initialise page table addresse arrays 78 // it scans all tasks contexts in the scheduler 79 // and get VSID, PTAB and PTPR values 80 81 unsigned int ltid; 82 unsigned int tasks = _get_tasks_number(); 83 84 for ( ltid = 0 ; ltid < tasks ; ltid++ ) 85 { 86 unsigned int vspace_id = _get_context_slot( ltid , CTX_VSID_ID ); 87 unsigned int ptab_vaddr = _get_context_slot( ltid , CTX_PTAB_ID ); 88 unsigned int ptab_paddr = _get_context_slot( ltid , CTX_PTPR_ID ) << 13; 89 _ptabs_vaddr[vspace_id] = ptab_vaddr; 90 _ptabs_paddr[vspace_id] = ptab_paddr; 91 92 #if GIET_DEBUG_INIT 93 _get_lock(&_tty_put_lock); 94 _puts("\n[GIET DEBUG] step 2 for processor "); 95 _putd( proc_id ); 96 _puts(" / vspace "); 97 _putd( vspace_id ); 98 _puts("\n- ptab vbase = "); 99 _putw( ptab_vaddr ); 100 _puts("\n- ptab pbase = "); 101 _putw( ptab_paddr ); 102 _puts("\n"); 103 _release_lock(&_tty_put_lock); 104 #endif 105 106 } 107 108 // step 3 : compute and set ICU mask 77 109 unsigned int irq_id; 78 110 unsigned int mask = 0; … … 89 121 #if GIET_DEBUG_INIT 90 122 _get_lock(&_tty_put_lock); 91 _puts("\n[GIET DEBUG] step 2 for processor "); 92 _putw( proc_id ); 93 _puts("\n"); 94 _puts("- ICU mask = "); 123 _puts("\n[GIET DEBUG] step 3 for processor "); 124 _putd( proc_id ); 125 _puts(" / ICU mask = "); 95 126 _putw( mask ); 96 127 _puts("\n"); … … 99 130 100 131 101 // step 3 : TODO initialise page table addresse arrays102 103 104 132 // step 4 : start TICK timer if more than one task 105 unsigned int tasks = _get_tasks_number();106 133 if ( tasks > 1 ) 107 134 { … … 122 149 _get_lock(&_tty_put_lock); 123 150 _puts("\n[GIET DEBUG] Step 4 for processor "); 124 _putw( proc_id ); 125 _puts("\n"); 126 _puts("- TICK period = "); 127 _putd( period ); 128 _puts("\n"); 151 _putd( proc_id ); 152 _puts(" / TICK activated\n"); 129 153 _release_lock(&_tty_put_lock); 130 154 #endif … … 132 156 } 133 157 134 // step 5 : each processor initialises SP, SR, PTPR, EPC, registers 158 // step 5 : initialise the "idle" task context 159 // the SR initialisation value is 0xFF03 because 160 // the task _ctx_idle() executes in kernel mode... 161 // it uses the page table of vspace[0] 162 163 _set_context_slot( IDLE_TASK_INDEX, CTX_RUN_ID, 1 ); 164 _set_context_slot( IDLE_TASK_INDEX, CTX_SR_ID, 0xFF03 ); 165 _set_context_slot( IDLE_TASK_INDEX, CTX_SP_ID, (unsigned int)&_idle_stack[proc_id] + 64 ); 166 _set_context_slot( IDLE_TASK_INDEX, CTX_RA_ID, (unsigned int)&_ctx_eret ); 167 _set_context_slot( IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int)&_ctx_idle ); 168 _set_context_slot( IDLE_TASK_INDEX, CTX_LTID_ID, IDLE_TASK_INDEX ); 169 _set_context_slot( IDLE_TASK_INDEX, CTX_PTPR_ID, _ptabs_paddr[0] >> 13 ); 170 171 #if GIET_DEBUG_INIT 172 _get_lock(&_tty_put_lock); 173 _puts("\n[GIET DEBUG] Step 5 for processor "); 174 _putd( proc_id ); 175 _puts(" / idle task context set\n"); 176 _release_lock(&_tty_put_lock); 177 #endif 178 179 // step 6 : each processor initialises SP, SR, PTPR, EPC, registers 135 180 // with the values corresponding to the first allocated task, 136 // It does nothing, and keep idle if no task allocated. 137 138 if ( tasks ) // at leat one task allocated 139 { 140 // initialise registers 141 sp_value = _get_current_context_slot(CTX_SP_ID); 142 sr_value = _get_current_context_slot(CTX_SR_ID); 143 ptpr_value = _get_current_context_slot(CTX_PTPR_ID); 144 epc_value = _get_current_context_slot(CTX_EPC_ID); 145 146 #if GIET_DEBUG_INIT 147 _get_lock(&_tty_put_lock); 148 _puts("\n[GIET DEBUG] step 5 for processor "); 149 _putw( proc_id ); 150 _puts("\n"); 181 // and starts the "idle" task if there is no task allocated. 182 183 unsigned int task_id; 184 185 if ( tasks == 0 ) 186 { 187 task_id = IDLE_TASK_INDEX; 188 189 _get_lock( &_tty_put_lock ); 190 _puts("\n [GIET WARNING] No task allocated to processor "); 191 _putw( proc_id ); 192 _puts(" => idle\n"); 193 _release_lock ( &_tty_put_lock ); 194 } 195 else 196 { 197 task_id = 0; 198 } 199 200 unsigned int sp_value = _get_context_slot( task_id, CTX_SP_ID ); 201 unsigned int sr_value = _get_context_slot( task_id, CTX_SR_ID ); 202 unsigned int ptpr_value = _get_context_slot( task_id, CTX_PTPR_ID ); 203 unsigned int epc_value = _get_context_slot( task_id, CTX_EPC_ID ); 204 205 #if GIET_DEBUG_INIT 206 _get_lock(&_tty_put_lock); 207 _puts("\n[GIET DEBUG] step 6 for processor "); 208 _putd( proc_id ); 209 _puts(" / registers initialised \n"); 151 210 _puts("- sp = "); 152 211 _putw( sp_value ); … … 163 222 _release_lock(&_tty_put_lock); 164 223 #endif 165 } 166 else // no task allocated 167 { 168 _get_lock( &_tty_put_lock ); 169 _puts("\n No task allocated to processor "); 170 _putw( proc_id ); 171 _puts(" => keep idle\n"); 172 _release_lock ( &_tty_put_lock ); 173 174 // enable interrupts in kernel mode 175 asm volatile ( "li $26, 0xFF01 \n" 176 "mtc0 $26, $12 \n" 177 ::: "$26" ); 178 179 // infinite loop in kernel mode 180 while (1) asm volatile("nop"); 181 } 182 183 // set critical registers and jump to user code 184 asm volatile ( 185 "move $29, %0 \n" /* SP <= ctx[CTX_SP_ID] */ 186 "mtc0 %1, $12 \n" /* SR <= ctx[CTX_SR_ID] */ 187 "mtc2 %2, $0 \n" /* PTPR <= ctx[CTX_PTPR_ID] */ 188 "mtc0 %3, $14 \n" /* EPC <= ctx[CTX_EPC_ID] */ 189 "eret \n" /* jump to user code */ 190 "nop \n" 191 : 192 : "r"(sp_value), "r"(sr_value), "r"(ptpr_value), "r"(epc_value) ); 224 225 // set registers and jump to user code 226 asm volatile ( "move $29, %0 \n" /* SP <= ctx[CTX_SP_ID] */ 227 "mtc0 %1, $12 \n" /* SR <= ctx[CTX_SR_ID] */ 228 "mtc2 %2, $0 \n" /* PTPR <= ctx[CTX_PTPR_ID] */ 229 "mtc0 %3, $14 \n" /* EPC <= ctx[CTX_EPC_ID] */ 230 "eret \n" /* jump to user code */ 231 "nop \n" 232 : 233 : "r"(sp_value), "r"(sr_value), "r"(ptpr_value), "r"(epc_value) ); 193 234 194 235 } // end _kernel_init() -
soft/giet_vm/sys/mips32_registers.h
r189 r199 47 47 /* CP0 registers */ 48 48 49 #define CP0_B AR$849 #define CP0_BVAR $8 50 50 #define CP0_TIME $9 51 51 #define CP0_SR $12 -
soft/giet_vm/sys/switch.s
r189 r199 2 2 * This function receives two arguments that are the current task context 3 3 * physical addresses and the next task context physical address. 4 * The DTLB is temporary desactivated... 4 5 ******************************************************************************/ 5 6 … … 17 18 add $27, $4, $0 /* $27 <= &context[curr_task_id] */ 18 19 19 mfc0 $26, $12 /* $26 <= SR */20 sw $26, 0*4($27) /* ctx[0] <= SR */21 20 .set noat 22 21 sw $1, 1*4($27) /* ctx[1] <= $1 */ … … 47 46 sw $25, 25*4($27) /* ctx[25] <= $25 */ 48 47 mflo $26 49 sw $26, 26*4($27) /* ctx[26] <= LO */48 sw $26, 26*4($27) /* ctx[26] <= LO */ 50 49 mfhi $26 51 sw $26, 27*4($27) /* ctx[27] <= H1 */50 sw $26, 27*4($27) /* ctx[27] <= H1 */ 52 51 sw $28, 28*4($27) /* ctx[28] <= $28 */ 53 52 sw $29, 29*4($27) /* ctx[29] <= $29 */ … … 57 56 sw $26, 32*4($27) /* ctx[32] <= EPC */ 58 57 mfc0 $26, $13 59 sw $26, 33*4($27) /* ctx[33] <= CR */ 58 sw $26, 33*4($27) /* ctx[33] <= CR */ 59 mfc0 $26, $12 60 sw $26, 34*4($27) /* ctx[34] <= SR */ 61 mfc0 $26, $8 62 sw $26, 35*4($27) /* ctx[34] <= BVAR */ 60 63 mfc2 $26, $0 61 sw $26, 3 5*4($27) /* ctx[35] <= PTPR */64 sw $26, 39*4($27) /* ctx[35] <= PTPR */ 62 65 63 66 /* restore next task context */ 64 67 add $27, $5, $0 /* $27<= &context[next_task_id] */ 65 68 66 lw $26, 35*4($27)67 mtc2 $26, $0 /* restore PTPR */68 lw $26, 0*4($27)69 mtc0 $26, $12 /* restore SR */70 69 .set noat 71 70 lw $1, 1*4($27) /* restore $1 */ … … 107 106 lw $26, 33*4($27) 108 107 mtc0 $26, $13 /* restore CR */ 108 lw $26, 34*4($27) 109 mtc0 $26, $12 /* restore SR */ 110 lw $26, 35*4($27) 111 mtc0 $26, $8 /* restore BVAR */ 112 lw $26, 39*4($27) 113 mtc2 $26, $0 /* restore PTPR */ 109 114 110 115 /* activate DTLB */ -
soft/giet_vm/sys/sys_handler.c
r189 r199 75 75 void _exit() 76 76 { 77 /*78 77 unsigned int date = _proctime(); 79 80 78 unsigned int proc_id = _procid(); 81 82 79 unsigned int task_id = _get_current_task_id(); 83 80 84 81 // print death message 85 82 _get_lock(&_tty_put_lock); 86 _puts("\n \n!!!Exit task ");87 _put w( task_id );83 _puts("\n[GIET] Exit task "); 84 _putd( task_id ); 88 85 _puts(" on processor "); 89 _put w( proc_id );86 _putd( proc_id ); 90 87 _puts(" at cycle "); 91 _put w( date );88 _putd( date ); 92 89 _puts("\n\n"); 93 90 _release_lock(&_tty_put_lock); 94 */95 91 96 /* infinite loop */ 97 while (1) asm volatile("nop"); 92 // goes to sleeping state 93 _set_context_slot( task_id, CTX_RUN_ID, 0 ); 94 95 // deschedule 96 _ctx_switch(); 98 97 } 99 98 //////////////////////////////////////////////////////////////////////////////
Note: See TracChangeset
for help on using the changeset viewer.