Changeset 528 for soft/giet_vm/giet_kernel/kernel_init.c
- Timestamp:
- Mar 27, 2015, 11:43:48 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_kernel/kernel_init.c
r494 r528 11 11 #include <hard_config.h> 12 12 #include <utils.h> 13 #include <vmem.h> 13 14 #include <tty0.h> 14 15 #include <kernel_malloc.h> … … 52 53 #endif 53 54 55 #if !defined(USE_PIC) 56 # error: You must define USE_PIC in the hard_config.h file 57 #endif 58 54 59 #if !defined(IDLE_TASK_INDEX) 55 60 # error: You must define IDLE_TASK_INDEX in the ctx_handler.h file … … 72 77 #endif 73 78 74 75 76 // Distributed kernel heap descriptors array 77 // __attribute__((section(".kdata"))) 78 // kernel_heap_t kernel_heap[X_SIZE][Y_SIZE]; 79 #if !defined(GIET_ISR_TYPE_MAX) 80 # error: You must define GIET_ISR_TYPE_MAX in the giet_config.h file 81 #endif 82 83 #if !defined(GIET_ISR_CHANNEL_MAX) 84 # error: You must define GIET_ISR_CHANNEL_MAX in the giet_config.h file 85 #endif 86 87 88 //////////////////////////////////////////////////////////////////////////////// 89 // Global variables 90 //////////////////////////////////////////////////////////////////////////////// 79 91 80 92 // FAT internal representation for kernel code 81 93 __attribute__((section(".kdata"))) 82 fat32_fs_t fat __attribute__((aligned(512)));94 fat32_fs_t _fat __attribute__((aligned(512))); 83 95 84 96 // array of page tables virtual addresses 85 97 __attribute__((section(".kdata"))) 86 volatile unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX] ;98 volatile unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE]; 87 99 88 100 // array of page tables PTPR values (physical addresses >> 13) 89 101 __attribute__((section(".kdata"))) 90 volatile unsigned int _ptabs_ptprs[GIET_NB_VSPACE_MAX] ;102 volatile unsigned int _ptabs_ptprs[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE]; 91 103 92 104 // Array of pointers on the schedulers 93 105 __attribute__((section(".kdata"))) 94 volatile static_scheduler_t* 106 volatile static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 95 107 96 108 // Synchonisation before entering parallel execution … … 102 114 unsigned int _tty0_boot_mode = 0; 103 115 104 // Distributedsynchronisation barrier for parallel init by all processors116 // synchronisation barrier for parallel init by all processors 105 117 __attribute__((section(".kdata"))) 106 118 sqt_barrier_t _all_procs_barrier __attribute__((aligned(64))); 107 119 108 120 //////////////////////////////////////////////////////////////////////////////// 121 // Extern variables 122 //////////////////////////////////////////////////////////////////////////////// 109 123 110 124 // this variable is defined in tty0.c file 111 125 extern sqt_lock_t _tty0_sqt_lock; 112 126 113 114 115 /////////////////////////////////////////////////////////////////////////////////// 116 // This kernel_init() function completes the kernel initialisation in 7 steps. 117 // Step 0 is done by processor[0,0,0]. Steps 1 to 6 are executed in parallel 118 // by all procesors. 119 // - step 0 : P[0,0,0] Initialise fat, heap descriptors, barrier and TTY0 lock. 127 //////////////////////////////////////////////////////////////////////////////// 128 // This kernel_init() function completes the kernel initialisation in 6 steps: 129 // Step 0 is done by processor[0,0,0]. Steps 1 to 4 are executed in parallel 130 // by all processors. 131 // - step 0 : P[0,0,0] Initialise various global variables. 120 132 // - step 1 : Each processor initialises scheduler pointers array. 121 133 // - step 2 : Each processor initialises PTAB pointers arrays. 122 // - step 3 : Each processor initialises its private XCU masks. 123 // - step 4 : Each processor starts its private TICK timer. 124 // - step 5 : Each processor initialises its private idle task context. 125 // - step 6 : Each processor set sp, sr, ptpr, epc registers values. 126 /////////////////////////////////////////////////////////////////////////////////// 134 // - step 3 : Each processor initialise idle task and starts TICK timer. 135 // - step 4 : Each processor set sp, sr, ptpr, epc registers values. 136 //////////////////////////////////////////////////////////////////////////////// 127 137 __attribute__((section (".kinit"))) void kernel_init() 128 138 { 129 139 // gpid : hardware processor index (fixed format: X_WIDTH|Y_WIDTH|P_WIDTH) 130 // x,y,p : proc essor coordinates ( x<X_SIZE / y<Y_SIZE / p<NB_PROCS_MAX )140 // x,y,p : proc coordinates ( x < X_SIZE / y < Y_SIZE / p < NB_PROCS_MAX ) 131 141 132 142 unsigned int gpid = _get_procid(); … … 137 147 138 148 //////////////////////////////////////////////////////////////////////////// 139 // Step 0 : P[0,0,0] initialises various structures 149 // Step 0 : P[0,0,0] initialises various global vaiables 150 //////////////////////////////////////////////////////////////////////////// 140 151 141 152 if ( gpid == 0 ) 142 153 { 143 // distributed kernel heap s154 // distributed kernel heap initialisation 144 155 _heap_init(); 145 156 146 157 #if GIET_DEBUG_INIT 147 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel HEAP init\n", x, y, p ); 148 #endif 149 // kernel FAT 150 _fat_init( IOC_BOOT_MODE ); 151 152 #if GIET_DEBUG_INIT 153 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel FAT init\n", x, y, p ); 158 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel HEAP init\n", 159 x, y, p ); 154 160 #endif 155 161 // distributed lock for TTY0 … … 167 173 x , y , p ); 168 174 #endif 175 176 #if USE_PIC 177 178 // _ext_irq_index[isr][channel] initialisation 179 _ext_irq_init(); 180 181 // routing HBA IRQ to proc[0,0,0] EXT_IRQ_ONE 182 unsigned int unused = 0; 183 if ( USE_IOC_HBA ) _ext_irq_alloc( ISR_HBA , 0 , &unused ); 184 185 #if GIET_DEBUG_INIT 186 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes ext_irq init\n", 187 x , y , p ); 188 #endif 189 190 #endif // USE_PIC 169 191 170 192 // release other processors … … 176 198 } 177 199 178 /////////////////////////////////////////////////////////////////// 200 /////////////////////////////////////////////////////////////////////////// 179 201 // Step 1 : each processor get its scheduler vaddr from CP0_SCHED, 180 202 // contributes to _schedulers[] array initialisation, 181 203 // and wait completion of array initialisation. 204 /////////////////////////////////////////////////////////////////////////// 182 205 183 206 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); … … 193 216 #endif 194 217 218 ///////////////////////////////////////// 195 219 _sqt_barrier_wait( &_all_procs_barrier ); 220 ///////////////////////////////////////// 196 221 197 222 //////////////////////////////////////////////////////////////////////////// 198 223 // step 2 : each processor that is allocated at least one task loops 199 // on all allocated tasks: 200 // - contributes to _ptabs_vaddr[] & _ptabs_ptprs[] initialisation. 224 // on its allocated tasks: 225 // - contributes to _ptabs_vaddr[][][] & _ptabs_ptprs[][][] 226 // initialisation, from values stored in the tasks contexts. 201 227 // - set CTX_RA slot with the kernel _ctx_eret() virtual address. 202 228 // - set CTX_EPC slot that must contain the task entry point, 203 // and contain only at this point the virtual address of the memory 204 // location containing this entry point. 229 // and contain only at this point the virtual address of the 230 // memory slot containing this entry point. 231 //////////////////////////////////////////////////////////////////////////// 205 232 206 233 unsigned int ltid; … … 213 240 214 241 // initialize PTABS arrays 215 _ptabs_vaddr[vsid] = ptab; 216 _ptabs_ptprs[vsid] = ptpr; 217 218 #if GIET_DEBUG_INIT 219 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises PTABS arrays\n" 220 " - ptabs_vaddr[%d] = %x / ptpr_paddr[%d] = %l\n", 221 x, y, p, 222 vsid, ptab, vsid, ((unsigned long long)ptpr)<<13 ); 223 #endif 224 225 // set the ptpr to use the task page table 226 asm volatile( "mtc2 %0, $0 \n" 242 _ptabs_vaddr[vsid][x][y] = ptab; 243 _ptabs_ptprs[vsid][x][y] = ptpr; 244 245 // set the ptpr to use the local page table 246 asm volatile( "mtc2 %0, $0" 227 247 : : "r" (ptpr) ); 228 248 … … 232 252 233 253 // compute ctx_epc 234 unsigned int* ptr = (unsigned int*)_get_task_slot( x, y, p, ltid, CTX_EPC_ID ); 235 _set_task_slot( x, y, p, ltid, CTX_EPC_ID, *ptr ); 236 237 #if GIET_DEBUG_INIT 238 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] updates context for task %d\n" 239 " - ctx_epc = %x\n" 240 " - ctx_ra = %x\n", 241 x, y, p, ltid, 254 unsigned int* ptr = (unsigned int*)_get_task_slot(x,y,p,ltid,CTX_EPC_ID); 255 _set_task_slot(x,y,p,ltid,CTX_EPC_ID,*ptr); 256 257 #if GIET_DEBUG_INIT 258 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises PTABS arrays" 259 " and context for task %d \n" 260 " - ptabs_vaddr[%d][%d][%d] = %x\n" 261 " - ptabs_paddr[%d][%d][%d] = %l\n" 262 " - ctx_epc = %x\n" 263 " - ctx_ra = %x\n", 264 x , y , p , ltid , 265 vsid , x , y , ptab , 266 vsid , x , y , ((unsigned long long)ptpr)<<13 , 242 267 _get_task_slot( x, y, p, ltid, CTX_EPC_ID ), 243 268 _get_task_slot( x, y, p, ltid, CTX_RA_ID ) ); … … 246 271 } // end for tasks 247 272 273 ///////////////////////////////////////// 248 274 _sqt_barrier_wait( &_all_procs_barrier ); 249 250 //////////////////////////////////////////////////////////////////////////// 251 // step 3 : compute and set XCU masks for HWI / PTI / WTI interrupts 252 253 unsigned int isr_switch_index = 0xFFFFFFFF; 254 unsigned int hwi_mask = 0; 255 unsigned int pti_mask = 0; 256 unsigned int wti_mask = 0; 257 unsigned int irq_id; // IN_IRQ index 258 unsigned int entry; // interrupt vector entry 259 260 for (irq_id = 0; irq_id < 32; irq_id++) 275 ///////////////////////////////////////// 276 277 //////////////////////////////////////////////////////////////////////////// 278 // step 3 : - Each processor complete idle task context initialisation, 279 // (only the CTX_SP, CTX_RA, CTX_EPC slot, because the CTX_PTPR 280 // and CTX_PTAB slots have been initialised in boot code) 281 // The 4 Kbytes idle stack is implemented in the scheduler itself. 282 // - Each processor starts TICK timer, as soon as at least one task 283 // is allocated. 284 // - P[0,0,0] initialises FAT (not done before, because it must 285 // be done after the _ptabs_vaddr[v][x][y] array initialisation, 286 // for V2P translation in _fat_ioc_access() function). 287 //////////////////////////////////////////////////////////////////////////// 288 289 unsigned int sp = ((unsigned int)psched) + 0x2000; 290 unsigned int ra = (unsigned int)(&_ctx_eret); 291 unsigned int epc = (unsigned int)(&_idle_task); 292 293 _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_SP_ID , sp ); 294 _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_RA_ID , ra ); 295 _set_task_slot( x , y , p , IDLE_TASK_INDEX , CTX_EPC_ID , epc ); 296 297 if (tasks > 0) _xcu_timer_start( cluster_xy, p, GIET_TICK_VALUE ); 298 299 #if GIET_DEBUG_INIT 300 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes idle_task and starts TICK\n", 301 x, y, p ); 302 #endif 303 304 if ( gpid == 0 ) 261 305 { 262 entry = psched->hwi_vector[irq_id]; 263 if ( entry & 0x80000000 ) hwi_mask = hwi_mask | (1<<irq_id); 264 if ( (entry & 0x0000FFFF) == ISR_TICK ) isr_switch_index = irq_id; 265 266 entry = psched->pti_vector[irq_id]; 267 if ( entry & 0x80000000 ) pti_mask = pti_mask | (1<<irq_id); 268 if ( (entry & 0x0000FFFF) == ISR_TICK ) isr_switch_index = irq_id; 269 270 entry = psched->wti_vector[irq_id]; 271 if ( entry & 0x80000000 ) wti_mask = wti_mask | (1<<irq_id); 272 if ( (entry & 0x0000FFFF) == ISR_TICK ) isr_switch_index = irq_id; 306 _fat_init( 0 ); // no IRQ 307 308 #if GIET_DEBUG_INIT 309 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel FAT init\n", 310 x, y, p ); 311 #endif 312 273 313 } 274 314 275 #if GIET_DEBUG_INIT 276 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] sets XCU masks\n" 277 " - ISR_TICK_INDEX = %d\n" 278 " - XCU HWI_MASK = %x\n" 279 " - XCU WTI_MASK = %x\n" 280 " - XCU PTI_MASK = %x\n", 281 x, y, p, 282 isr_switch_index, 283 hwi_mask, wti_mask, pti_mask ); 284 #endif 285 286 unsigned int channel = p * IRQ_PER_PROCESSOR; 287 288 _xcu_set_mask( cluster_xy, channel, hwi_mask, IRQ_TYPE_HWI ); 289 _xcu_set_mask( cluster_xy, channel, wti_mask, IRQ_TYPE_WTI ); 290 _xcu_set_mask( cluster_xy, channel, pti_mask, IRQ_TYPE_PTI ); 291 292 //////////////////////////////////////////////////////////////////////////// 293 // step 4 : Each processor start TICK timer if at least one task 294 295 if (tasks > 0) 296 { 297 // one ISR_TICK must be defined for each proc 298 if (isr_switch_index == 0xFFFFFFFF) 299 { 300 _printf("\n[GIET ERROR] ISR_TICK not found for processor[%d,%d,%d]\n", 301 x, y, p ); 302 _exit(); 303 } 304 305 // start system timer 306 _xcu_timer_start( cluster_xy, isr_switch_index, GIET_TICK_VALUE ); 307 308 } 309 310 #if GIET_DEBUG_INIT 311 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] starts TICK timer\n", 312 x, y, p ); 313 #endif 314 315 //////////////////////////////////////////////////////////////////////////// 316 // step 5 : each processor updates the idle_task context: 317 // (CTX_SP, CTX_RA, CTX_EPC). 318 // The 4 Kbytes idle stack is implemented in the scheduler. 319 // The PTPR register, the CTX_PTPR and CTX_PTAB slots 320 // have been initialised in boot code. 321 322 unsigned int pstack = ((unsigned int)psched) + 0x2000; 323 324 _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_SP_ID, pstack); 325 _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_RA_ID, (unsigned int) &_ctx_eret); 326 _set_task_slot( x, y, p, IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int) &_idle_task); 327 328 #if GIET_DEBUG_INIT 329 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes IDLE task\n" 330 " - stack_base = %x\n" 331 " - stack_size = 0x1000\n", 332 x, y, p, pstack - 0x1000 ); 333 #endif 334 315 ///////////////////////////////////////// 335 316 _sqt_barrier_wait( &_all_procs_barrier ); 336 337 //////////////////////////////////////////////////////////////////////////// 338 // step 6 : Each processor compute values for registers SP, SR, PTPR, EPC, 317 ///////////////////////////////////////// 318 319 //////////////////////////////////////////////////////////////////////////// 320 // step 4 : Each processor compute values for registers SP, SR, PTPR, EPC, 339 321 // corresponding to the first allocated task (can be idle task) 340 // and jump to user code when barrier is reached 341 342 if (tasks == 0) 343 { 344 ltid = IDLE_TASK_INDEX; 345 _printf("\n[GIET WARNING] No task allocated to processor[%d,%d,%d]\n", 346 x, y, p ); 347 } 348 else 349 { 350 ltid = 0; 351 } 322 // and jumps to user code. 323 //////////////////////////////////////////////////////////////////////////// 324 325 if (tasks == 0) _printf("\n[GIET WARNING] No task allocated to P[%d,%d,%d]\n", 326 x, y, p ); 327 328 if (tasks == 0) ltid = IDLE_TASK_INDEX; 329 else ltid = 0; 352 330 353 331 unsigned int sp_value = _get_task_slot( x, y, p, ltid, CTX_SP_ID); … … 356 334 unsigned int epc_value = _get_task_slot( x, y, p, ltid, CTX_EPC_ID); 357 335 358 _sqt_barrier_wait( &_all_procs_barrier );359 360 336 #if GIET_DEBUG_INIT 361 337 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] jumps to user code at cycle %d\n" 362 " sp = %x / sr = %x / ptpr = %x / epc = %x\n",363 x , y, p, _get_proctime(),364 sp_value, sr_value, ptpr_value, epc_value );338 " ltid = %d / sp = %x / sr = %x / ptpr = %x / epc = %x\n", 339 x , y , p , _get_proctime() , 340 ltid , sp_value , sr_value , ptpr_value , epc_value ); 365 341 #endif 366 342
Note: See TracChangeset
for help on using the changeset viewer.