Changeset 494 for soft/giet_vm/giet_kernel/kernel_init.c
- Timestamp:
- Feb 8, 2015, 12:50:23 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_kernel/kernel_init.c
r478 r494 13 13 #include <tty0.h> 14 14 #include <kernel_malloc.h> 15 #include <kernel_locks.h> 16 #include <kernel_barriers.h> 15 17 #include <fat32.h> 16 18 #include <xcu_driver.h> … … 72 74 73 75 76 // Distributed kernel heap descriptors array 77 // __attribute__((section(".kdata"))) 78 // kernel_heap_t kernel_heap[X_SIZE][Y_SIZE]; 79 80 // FAT internal representation for kernel code 81 __attribute__((section(".kdata"))) 82 fat32_fs_t fat __attribute__((aligned(512))); 83 84 // array of page tables virtual addresses 85 __attribute__((section(".kdata"))) 86 volatile unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX]; 87 88 // array of page tables PTPR values (physical addresses >> 13) 89 __attribute__((section(".kdata"))) 90 volatile unsigned int _ptabs_ptprs[GIET_NB_VSPACE_MAX]; 91 92 // Array of pointers on the schedulers 93 __attribute__((section(".kdata"))) 94 volatile static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 95 96 // Synchonisation before entering parallel execution 97 __attribute__((section(".kdata"))) 98 volatile unsigned int _kernel_init_done = 0; 99 100 // Kernel uses sqt_lock to protect TTY0 101 __attribute__((section(".kdata"))) 102 unsigned int _tty0_boot_mode = 0; 103 104 // Distributed synchronisation barrier for parallel init by all processors 105 __attribute__((section(".kdata"))) 106 sqt_barrier_t _all_procs_barrier __attribute__((aligned(64))); 107 108 109 110 // this variable is defined in tty0.c file 111 extern sqt_lock_t _tty0_sqt_lock; 112 113 114 74 115 /////////////////////////////////////////////////////////////////////////////////// 75 // Ditributed kernel heap descriptors array (for dynamic memory allocation) 76 /////////////////////////////////////////////////////////////////////////////////// 77 78 kernel_heap_t kernel_heap[X_SIZE][Y_SIZE]; 79 80 /////////////////////////////////////////////////////////////////////////////////// 81 // FAT internal representation for kernel code 82 /////////////////////////////////////////////////////////////////////////////////// 83 84 fat32_fs_t fat __attribute__((aligned(512))); 85 86 /////////////////////////////////////////////////////////////////////////////////// 87 // array of pointers on the page tables (virtual addresses) 88 /////////////////////////////////////////////////////////////////////////////////// 89 90 volatile unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX]; // virtual addresses 91 volatile unsigned int _ptabs_ptprs[GIET_NB_VSPACE_MAX]; // physical addresses >> 13 92 93 /////////////////////////////////////////////////////////////////////////////////// 94 // Array of pointers on the schedulers (physical addresses) 95 /////////////////////////////////////////////////////////////////////////////////// 96 97 volatile static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 98 99 //////////////////////////////////////////////////////////////////////////////////// 100 // Synchonisation barrier before jumping to user code 101 //////////////////////////////////////////////////////////////////////////////////// 102 103 volatile unsigned int kernel_init_barrier = 0; 104 105 //////////////////////////////////////////////////////////////////////////////////// 106 // Global variables for TTY/kernel communications 107 //////////////////////////////////////////////////////////////////////////////////// 108 109 unsigned int _tty_rx_buf[NB_TTY_CHANNELS]; 110 unsigned int _tty_rx_full[NB_TTY_CHANNELS]; 111 112 //////////////////////////////////////////////////////////////////////////////////// 113 // Distributed locks protecting TTY terminals 114 //////////////////////////////////////////////////////////////////////////////////// 115 116 sbt_lock_t _tty_tx_lock[NB_TTY_CHANNELS] __attribute__((aligned(64))); 117 118 /////////////////////////////////////////////////////////////////////////////////// 119 // This kernel_init() function completes the kernel initialisation in 7 steps: 120 // All processors execute this code, but this is done sequencially. 121 // - step 0 : Initialise fat, heap descriptors, and tty locks 122 // - step 1 : Initialise scheduler pointers array 123 // - step 2 : Initialise PTAB pointers arrays 124 // - step 3 : Initialise private XCU masks 125 // - step 4 : 126 // - step 5 : 127 // - step 6 : 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. 120 // - step 1 : Each processor initialises scheduler pointers array. 121 // - 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. 128 126 /////////////////////////////////////////////////////////////////////////////////// 129 127 __attribute__((section (".kinit"))) void kernel_init() 130 128 { 131 // gpid : hardware processor index (fixed format: X_WIDTH|Y_WIDTH|P_WIDTH) 132 // p : local processor id in a cluster ( p < NB_PROCS_MAX) 133 // cpid : continuous processor index = (((x * Y_SIZE + y) * NB_PROCS_MAX) + p 129 // gpid : hardware processor index (fixed format: X_WIDTH|Y_WIDTH|P_WIDTH) 130 // x,y,p : processor coordinates ( x<X_SIZE / y<Y_SIZE / p<NB_PROCS_MAX ) 134 131 135 132 unsigned int gpid = _get_procid(); … … 138 135 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 139 136 unsigned int p = gpid & ((1<<P_WIDTH)-1); 140 unsigned int cpid = ((( x * Y_SIZE) + y) * NB_PROCS_MAX) + p; 141 142 // This initialisation is done sequencially by each processor 143 while( cpid != kernel_init_barrier ) asm volatile ( "nop" ); 144 145 // Step 0 : P[0,0,0] initialises various complex structures 146 // - kernel FAT 147 // - distributed kernel heaps 148 // - distributed locks protecting TTY channels 149 // - distributed locks protecting MMC components 137 138 //////////////////////////////////////////////////////////////////////////// 139 // Step 0 : P[0,0,0] initialises various structures 140 150 141 if ( gpid == 0 ) 151 142 { 143 // distributed kernel heaps 152 144 _heap_init(); 153 145 … … 155 147 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel HEAP init\n", x, y, p ); 156 148 #endif 157 unsigned int channel; 158 for ( channel = 0 ; channel < NB_TTY_CHANNELS ; channel++ ) 159 { 160 _sbt_lock_init( &_tty_tx_lock[channel] ); 161 162 #if GIET_DEBUG_INIT 163 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes TTY[%d] lock init\n", 164 x , y , p , channel ); 165 #endif 166 } 167 168 /* 169 unsigned int cx, cy; 170 for ( cx = 0 ; cx < X_SIZE ; cx++ ) 171 { 172 for ( cy = 0 ; cy < X_SIZE ; cy++ ) 173 { 174 _sbt_lock_init( &_mmc_lock[cx][cy] ); 175 176 #if GIET_DEBUG_INIT 177 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes MMC[%d][%d] lock init\n", 178 x , y , p , cx , cy ); 179 #endif 180 } 181 } 182 */ 149 // kernel FAT 183 150 _fat_init( IOC_BOOT_MODE ); 184 151 … … 186 153 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel FAT init\n", x, y, p ); 187 154 #endif 188 189 } 190 191 // Step 1 : each processor get its scheduler virtual address from CP0_SCHED register 192 // and contributes to _schedulers[] array initialisation 155 // distributed lock for TTY0 156 _sqt_lock_init( &_tty0_sqt_lock ); 157 158 #if GIET_DEBUG_INIT 159 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes TTY0 lock init\n", 160 x , y , p ); 161 #endif 162 // distributed kernel barrier between all processors 163 _sqt_barrier_init( &_all_procs_barrier ); 164 165 #if GIET_DEBUG_INIT 166 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes barrier init\n", 167 x , y , p ); 168 #endif 169 170 // release other processors 171 _kernel_init_done = 1; 172 } 173 else 174 { 175 while( _kernel_init_done == 0 ) asm volatile ( "nop" ); 176 } 177 178 /////////////////////////////////////////////////////////////////// 179 // Step 1 : each processor get its scheduler vaddr from CP0_SCHED, 180 // contributes to _schedulers[] array initialisation, 181 // and wait completion of array initialisation. 193 182 194 183 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); … … 198 187 199 188 #if GIET_DEBUG_INIT 200 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises SCHED array\n" 201 " - scheduler vbase = %x\n" 202 " - tasks = %d\n", 203 x, y, p, (unsigned int)psched, tasks ); 204 #endif 205 189 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises SCHED array\n" 190 " - scheduler vbase = %x\n" 191 " - tasks = %d\n", 192 x, y, p, (unsigned int)psched, tasks ); 193 #endif 194 195 _sqt_barrier_wait( &_all_procs_barrier ); 196 197 //////////////////////////////////////////////////////////////////////////// 206 198 // step 2 : each processor that is allocated at least one task loops 207 199 // on all allocated tasks: … … 225 217 226 218 #if GIET_DEBUG_INIT 227 _ nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises PTABS arrays\n"219 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises PTABS arrays\n" 228 220 " - ptabs_vaddr[%d] = %x / ptpr_paddr[%d] = %l\n", 229 221 x, y, p, … … 244 236 245 237 #if GIET_DEBUG_INIT 246 _ nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] updates context for task %d\n"247 248 249 250 251 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, 242 _get_task_slot( x, y, p, ltid, CTX_EPC_ID ), 243 _get_task_slot( x, y, p, ltid, CTX_RA_ID ) ); 252 244 #endif 253 245 254 246 } // end for tasks 255 247 256 // step 3 : compute and set XCU masks 248 _sqt_barrier_wait( &_all_procs_barrier ); 249 250 //////////////////////////////////////////////////////////////////////////// 251 // step 3 : compute and set XCU masks for HWI / PTI / WTI interrupts 257 252 258 253 unsigned int isr_switch_index = 0xFFFFFFFF; … … 279 274 280 275 #if GIET_DEBUG_INIT 281 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] sets XCU masks\n" 282 " - XCU HWI_MASK = %x\n" 283 " - XCU WTI_MASK = %x\n" 284 " - XCU PTI_MASK = %x\n", 285 x, y, p, hwi_mask, wti_mask, pti_mask ); 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 ); 286 284 #endif 287 285 … … 292 290 _xcu_set_mask( cluster_xy, channel, pti_mask, IRQ_TYPE_PTI ); 293 291 294 // step 4 : start TICK timer if at least one task 292 //////////////////////////////////////////////////////////////////////////// 293 // step 4 : Each processor start TICK timer if at least one task 294 295 295 if (tasks > 0) 296 296 { … … 298 298 if (isr_switch_index == 0xFFFFFFFF) 299 299 { 300 _ nolock_printf("\n[GIET ERROR] ISR_TICK not found for processor[%d,%d,%d]\n",300 _printf("\n[GIET ERROR] ISR_TICK not found for processor[%d,%d,%d]\n", 301 301 x, y, p ); 302 302 _exit(); … … 309 309 310 310 #if GIET_DEBUG_INIT 311 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] starts TICK timer\n", 312 x, y, p ); 313 #endif 314 311 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] starts TICK timer\n", 312 x, y, p ); 313 #endif 314 315 //////////////////////////////////////////////////////////////////////////// 315 316 // step 5 : each processor updates the idle_task context: 316 317 // (CTX_SP, CTX_RA, CTX_EPC). … … 326 327 327 328 #if GIET_DEBUG_INIT 328 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes IDLE task\n" 329 " - stack_base = %x\n" 330 " - stack_size = 0x1000\n", 331 x, y, p, pstack - 0x1000 ); 332 #endif 333 334 // step 6 : when all processors reach the synchronisation barrier, 335 // each processor set registers SP, SR, PTPR, EPC, 336 // with the values corresponding to the first allocated task, 337 // or to the idle_task if there is no task allocated, 338 // and jump to user code 339 340 if (tasks == 0) 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 335 _sqt_barrier_wait( &_all_procs_barrier ); 336 337 //////////////////////////////////////////////////////////////////////////// 338 // step 6 : Each processor compute values for registers SP, SR, PTPR, EPC, 339 // 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) 341 343 { 342 344 ltid = IDLE_TASK_INDEX; 343 344 _nolock_printf("\n[GIET WARNING] No task allocated to processor[%d,%d,%d]\n", 345 x, y, p ); 345 _printf("\n[GIET WARNING] No task allocated to processor[%d,%d,%d]\n", 346 x, y, p ); 346 347 } 347 348 else … … 355 356 unsigned int epc_value = _get_task_slot( x, y, p, ltid, CTX_EPC_ID); 356 357 357 #if GIET_DEBUG_INIT 358 _nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] reach barrier at cycle %d\n", 359 x, y, p, _get_proctime() ); 360 #endif 361 362 // increment barrier counter 363 kernel_init_barrier++; 364 365 // busy waiting until all processors synchronized 366 while ( kernel_init_barrier != NB_TOTAL_PROCS ); 367 368 #if GIET_DEBUG_INIT 369 _printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes registers at cycle %d\n" 370 " - sp = %x\n" 371 " - sr = %x\n" 372 " - ptpr = %x\n" 373 " - epc = %x\n", 358 _sqt_barrier_wait( &_all_procs_barrier ); 359 360 #if GIET_DEBUG_INIT 361 _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", 374 363 x, y, p, _get_proctime(), 375 364 sp_value, sr_value, ptpr_value, epc_value );
Note: See TracChangeset
for help on using the changeset viewer.