Changeset 494 for soft/giet_vm
- Timestamp:
- Feb 8, 2015, 12:50:23 PM (10 years ago)
- Location:
- soft/giet_vm/giet_kernel
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_kernel/irq_handler.c
r459 r494 27 27 #endif 28 28 29 // ISR_TYPE names for display 29 //////////////////////////////////////////// 30 // ISR_TYPE names for display 31 /////////////////////////////////////////// 32 __attribute__((section(".kdata"))) 30 33 char* _isr_type_name[] = { "DEFAULT", 31 34 "TICK" , -
soft/giet_vm/giet_kernel/kernel.ld
r322 r494 22 22 seg_kernel_data : 23 23 { 24 *(.iommu)25 *(.fatdata)26 *(.descriptor)27 24 *(.kdata) 28 *(.rodata)29 *(.rodata.*)30 *(.data)31 *(.lit8)32 *(.lit4)33 *(.sdata)34 *(.bss)35 *(COMMON)36 *(.sbss)37 *(.scommon)38 25 } 39 26 -
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 ); -
soft/giet_vm/giet_kernel/sys_handler.c
r489 r494 65 65 //////////////////////////////////////////////////////////////////////////// 66 66 67 __attribute__((section(".kdata"))) 67 68 unsigned int _tty_channel_allocator = 1; 69 70 __attribute__((section(".kdata"))) 68 71 unsigned int _tim_channel_allocator = 0; 72 73 __attribute__((section(".kdata"))) 69 74 unsigned int _cma_channel_allocator = 0; 75 76 __attribute__((section(".kdata"))) 70 77 unsigned int _nic_rx_channel_allocator = 0; 78 79 __attribute__((section(".kdata"))) 71 80 unsigned int _nic_tx_channel_allocator = 0; 81 82 //////////////////////////////////////////////////////////////////////////// 83 // These global variables is defined in tty0.c and tty_driver.c files. 84 //////////////////////////////////////////////////////////////////////////// 85 86 extern sqt_lock_t _tty0_sqt_lock; 87 88 extern unsigned int _tty_rx_full[NB_TTY_CHANNELS]; 89 90 extern unsigned int _tty_rx_buf[NB_TTY_CHANNELS]; 72 91 73 92 //////////////////////////////////////////////////////////////////////////// … … 75 94 //////////////////////////////////////////////////////////////////////////// 76 95 96 __attribute__((section(".kdata"))) 77 97 nic_chbuf_t _nic_rx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64))); 78 98 99 __attribute__((section(".kdata"))) 79 100 nic_chbuf_t _nic_tx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64))); 80 101 … … 84 105 //////////////////////////////////////////////////////////////////////////// 85 106 107 __attribute__((section(".kdata"))) 86 108 fbf_chbuf_t _fbf_chbuf[NB_CMA_CHANNELS] __attribute__((aligned(64))); 87 109 110 __attribute__((section(".kdata"))) 88 111 unsigned long long _fbf_chbuf_paddr[NB_CMA_CHANNELS]; 89 112 … … 92 115 // Note: This array must be synchronised with the define in file stdio.h 93 116 //////////////////////////////////////////////////////////////////////////// 117 118 __attribute__((section(".kdata"))) 94 119 const void * _syscall_vector[64] = 95 120 { … … 241 266 242 267 /////////////////////////////////////////// 243 int _sys_tty_get_lock( unsigned int channel, 268 int _sys_tty_get_lock( unsigned int channel, // unused 244 269 unsigned int * save_sr_ptr ) 245 270 { 246 // compute and check tty channel 247 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 248 if( channel >= NB_TTY_CHANNELS ) return -1; 271 // check tty channel 272 if( channel != 0 ) return 1; 249 273 250 274 _it_disable( save_sr_ptr ); 251 _s bt_lock_acquire( &_tty_tx_lock[channel]);275 _sqt_lock_acquire( &_tty0_sqt_lock ); 252 276 return 0; 253 277 } … … 257 281 unsigned int * save_sr_ptr ) 258 282 { 259 // compute and check tty channel 260 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 261 if( channel >= NB_TTY_CHANNELS ) return -1; 262 263 _sbt_lock_release( &_tty_tx_lock[channel] ); 283 // check tty channel 284 if( channel != 0 ) return 1; 285 286 _sqt_lock_release( &_tty0_sqt_lock ); 264 287 _it_restore( save_sr_ptr ); 265 288 return 0; … … 332 355 #define NIC_CONTAINER_SIZE 4096 333 356 334 /////////////////////////////////////////// 335 int _sys_nic_alloc( unsigned int is_rx ) 336 { 357 //////////////////////////////////////// 358 int _sys_nic_alloc( unsigned int is_rx, 359 unsigned int xmax, 360 unsigned int ymax ) 361 { 362 // check xmax / ymax parameters 363 if ( xmax > X_SIZE ) 364 { 365 _printf("\n[GIET_ERROR] in _sys_nic_alloc() xmax argument too large\n"); 366 return -1; 367 } 368 if ( ymax > Y_SIZE ) 369 { 370 _printf("\n[GIET_ERROR] in _sys_nic_alloc() ymax argument too large\n"); 371 return -1; 372 } 373 374 // get a NIC_RX or NIC_TX channel index 375 unsigned int nic_channel; 376 unsigned int cma_channel; 377 378 if ( is_rx ) nic_channel = _atomic_increment( &_nic_rx_channel_allocator, 1 ); 379 else nic_channel = _atomic_increment( &_nic_tx_channel_allocator, 1 ); 380 381 if ( (nic_channel >= NB_NIC_CHANNELS) ) 382 { 383 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough NIC channels\n"); 384 return -1; 385 } 386 387 // get a CMA channel index 388 cma_channel = _atomic_increment( &_cma_channel_allocator, 1 ); 389 390 if ( cma_channel >= NB_CMA_CHANNELS ) 391 { 392 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough CMA channels\n"); 393 return -1; 394 } 337 395 338 396 #if GIET_DEBUG_NIC 339 397 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 340 _printf("\n[GIET DEBUG NIC] Task %d enters sys_nic_alloc() at cycle %d\n", 341 thread, _get_proctime() ); 342 #endif 343 344 unsigned int nic_channel; 345 unsigned int cma_channel; 346 347 // get a NIC_RX or NIC_TX channel index 348 if ( is_rx ) nic_channel = _atomic_increment( &_nic_rx_channel_allocator, 1 ); 349 else nic_channel = _atomic_increment( &_nic_tx_channel_allocator, 1 ); 350 351 if ( (nic_channel >= NB_NIC_CHANNELS) ) 352 { 353 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough NIC channels\n"); 354 return -1; 355 } 356 357 // get a CMA channel index 358 cma_channel = _atomic_increment( &_cma_channel_allocator, 1 ); 359 360 if ( cma_channel >= NB_CMA_CHANNELS ) 361 { 362 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough CMA channels\n"); 363 return -1; 364 } 398 _printf("\n[GIET DEBUG NIC] Task %d enters sys_nic_alloc() at cycle %d\n" 399 " nic_channel = %d / cma_channel = %d\n" 400 thread , _get_proctime() , nic_channel , cma_channel ); 401 #endif 365 402 366 403 // register nic_index and cma_index in task context … … 376 413 } 377 414 378 #if GIET_DEBUG_NIC 379 _printf("\n[GIET DEBUG NIC] Task %d exit _sys_nic_alloc() at cycle %d : " 380 "NIC channel = %d / CMA channel = %d\n", 381 thread, _get_proctime(), nic_channel, cma_channel ); 382 #endif 383 384 return nic_channel; 385 } // end _sys_nic_alloc() 386 387 //////////////////////////////////////// 388 int _sys_nic_start( unsigned int is_rx, 389 unsigned int channel ) 390 { 391 392 #if GIET_DEBUG_NIC 393 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 394 _printf("\n[GIET DEBUG NIC] Task %d enters _sys_nic_start() at cycle %d\n", 395 thread , _get_proctime() ); 396 #endif 397 398 unsigned int nic_channel; 399 unsigned int cma_channel; 400 401 // get NIC channel index and CMA channel index 402 if ( is_rx ) 403 { 404 nic_channel = _get_context_slot( CTX_NIC_RX_ID ); 405 cma_channel = _get_context_slot( CTX_CMA_RX_ID ); 406 } 407 else 408 { 409 nic_channel = _get_context_slot( CTX_NIC_TX_ID ); 410 cma_channel = _get_context_slot( CTX_CMA_TX_ID ); 411 } 412 413 #if GIET_DEBUG_NIC 414 _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_start() at cycle %d" 415 " get NIC channel = %d / CMA channel = %d\n", 416 thread, _get_proctime(), nic_channel, cma_channel ); 417 #endif 418 419 if ( nic_channel != channel ) 420 { 421 _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal NIC channel\n"); 422 return -1; 423 } 424 if ( cma_channel >= NB_CMA_CHANNELS ) 425 { 426 _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal CMA channel\n"); 427 return -1; 428 } 429 415 // physical addresses to be registered in the CMA registers 430 416 unsigned long long nic_chbuf_pbase; // NIC chbuf physical address 431 417 unsigned long long ker_chbuf_pbase; // kernel chbuf physical address … … 437 423 unsigned int vaddr; 438 424 439 // allocate two containers per cluster440 unsigned int cx; // container X coordinate441 unsigned int cy; // container Y coordinate442 unsigned int index; // container index in chbuf443 unsigned long long cont_paddr; // container physical address444 445 for ( cx = 0 ; cx < X_SIZE; cx++ )446 { 447 for ( cy = 0 ; cy < Y_SIZE; cy++ )425 // allocate one kernel container per cluster in the (xmax / ymax) mesh 426 unsigned int cx; // cluster X coordinate 427 unsigned int cy; // cluster Y coordinate 428 unsigned int index; // container index in chbuf 429 unsigned long long cont_paddr; // container physical address 430 431 for ( cx = 0 ; cx < xmax ; cx++ ) 432 { 433 for ( cy = 0 ; cy < ymax ; cy++ ) 448 434 { 449 435 // compute index in chbuf 450 index = (cx * Y_SIZE) + cy;451 452 // allocate the container436 index = (cx * ymax) + cy; 437 438 // allocate the kernel container 453 439 vaddr = (unsigned int)_remote_malloc( NIC_CONTAINER_SIZE, cx, cy ); 440 441 if ( vaddr == 0 ) // not enough kernel heap memory in cluster[cx,cy] 442 { 443 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough kenel heap" 444 " in cluster[%d,%d]\n", cx, cy ); 445 return -1; 446 } 454 447 455 448 // compute container physical address … … 460 453 cont_paddr = (((unsigned long long)ppn) << 12) | (vaddr & 0x00000FFF); 461 454 462 // initialize chbuf 455 // initialize chbuf entry 463 456 if ( is_rx ) _nic_rx_chbuf[nic_channel].buffer[index].desc = cont_paddr; 464 457 else _nic_tx_chbuf[nic_channel].buffer[index].desc = cont_paddr; … … 470 463 #endif 471 464 } 465 } 466 467 // complete kernel chbuf initialisation 468 if ( is_rx ) 469 { 470 _nic_rx_chbuf[nic_channel].xmax = xmax; 471 _nic_rx_chbuf[nic_channel].ymax = ymax; 472 } 473 else 474 { 475 _nic_tx_chbuf[nic_channel].xmax = xmax; 476 _nic_tx_chbuf[nic_channel].ymax = ymax; 472 477 } 473 478 … … 511 516 _cma_set_register( cma_channel, CHBUF_DST_DESC , (unsigned int)(ker_chbuf_pbase) ); 512 517 _cma_set_register( cma_channel, CHBUF_DST_EXT , (unsigned int)(ker_chbuf_pbase>>32) ); 513 _cma_set_register( cma_channel, CHBUF_DST_NBUFS, X_SIZE*Y_SIZE);518 _cma_set_register( cma_channel, CHBUF_DST_NBUFS, xmax * ymax ); 514 519 } 515 520 else // kernel to NIC … … 517 522 _cma_set_register( cma_channel, CHBUF_SRC_DESC , (unsigned int)(ker_chbuf_pbase) ); 518 523 _cma_set_register( cma_channel, CHBUF_SRC_EXT , (unsigned int)(ker_chbuf_pbase>>32) ); 519 _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, X_SIZE*Y_SIZE);524 _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, xmax * ymax ); 520 525 _cma_set_register( cma_channel, CHBUF_DST_DESC , (unsigned int)(nic_chbuf_pbase) ); 521 526 _cma_set_register( cma_channel, CHBUF_DST_EXT , (unsigned int)(nic_chbuf_pbase>>32) ); 522 527 _cma_set_register( cma_channel, CHBUF_DST_NBUFS, 2 ); 528 } 529 530 #if GIET_DEBUG_NIC 531 _printf("\n[GIET DEBUG NIC] Task %d exit _sys_nic_alloc() at cycle %d\n", 532 thread, _get_proctime() ); 533 #endif 534 535 return nic_channel; 536 } // end _sys_nic_alloc() 537 538 539 //////////////////////////////////////// 540 int _sys_nic_start( unsigned int is_rx, 541 unsigned int channel ) 542 { 543 unsigned int nic_channel; 544 unsigned int cma_channel; 545 546 // get NIC channel index and CMA channel index from task context 547 if ( is_rx ) 548 { 549 nic_channel = _get_context_slot( CTX_NIC_RX_ID ); 550 cma_channel = _get_context_slot( CTX_CMA_RX_ID ); 551 } 552 else 553 { 554 nic_channel = _get_context_slot( CTX_NIC_TX_ID ); 555 cma_channel = _get_context_slot( CTX_CMA_TX_ID ); 556 } 557 558 #if GIET_DEBUG_NIC 559 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 560 _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_start() at cycle %d" 561 " get NIC channel = %d / CMA channel = %d\n", 562 thread, _get_proctime(), nic_channel, cma_channel ); 563 #endif 564 565 // check NIC and CMA channels index 566 if ( nic_channel != channel ) 567 { 568 _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal NIC channel\n"); 569 return -1; 570 } 571 if ( cma_channel >= NB_CMA_CHANNELS ) 572 { 573 _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal CMA channel\n"); 574 return -1; 523 575 } 524 576 … … 539 591 } // end sys_nic_start() 540 592 593 541 594 ////////////////////////////////////// 542 595 int _sys_nic_move( unsigned int is_rx, … … 551 604 #endif 552 605 606 // check NIC channel index 607 if ( channel >= NB_NIC_CHANNELS ) 608 { 609 _printf("\n[GIET_ERROR] in _sys_nic_move() : illegal NIC channel index\n"); 610 return -1; 611 } 612 613 // get kernel chbuf virtual address 614 nic_chbuf_t* chbuf; 615 if ( is_rx ) chbuf = &_nic_rx_chbuf[channel]; 616 else chbuf = &_nic_tx_chbuf[channel]; 617 618 // get xmax / ymax parameters 619 unsigned int xmax = chbuf->xmax; 620 unsigned int ymax = chbuf->ymax; 621 553 622 // get cluster coordinates for the processor running the calling task 554 623 unsigned int procid = _get_procid(); 555 624 unsigned int cx = procid >> (Y_WIDTH + P_WIDTH); 556 625 unsigned int cy = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 626 627 // check processor coordinates / (xmax,ymax) 628 if ( cx >= xmax ) 629 { 630 _printf("\n[GIET_ERROR] in _sys_nic_move() : processor X coordinate = %d" 631 " / xmax = %d\n", cx , xmax ); 632 return -1; 633 } 634 if ( cy >= ymax ) 635 { 636 _printf("\n[GIET_ERROR] in _sys_nic_move() : processor Y coordinate = %d" 637 " / ymax = %d\n", cy , ymax ); 638 return -1; 639 } 557 640 558 641 unsigned long long user_buffer_paddr; // user buffer physical address … … 588 671 #endif 589 672 590 // check NIC channel index591 if ( channel >= NB_NIC_CHANNELS )592 {593 _printf("\n[GIET_ERROR] in _sys_nic_move() : illegal NIC channel index\n");594 return -1;595 }596 597 // get kernel chbuf virtual address598 nic_chbuf_t* chbuf;599 if ( is_rx ) chbuf = &_nic_rx_chbuf[channel];600 else chbuf = &_nic_tx_chbuf[channel];601 602 673 // compute kernel chbuf physical address (required for sync) 603 674 vaddr = (unsigned int)chbuf; … … 608 679 kernel_chbuf_paddr = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF); 609 680 610 // poll chbufuntil success681 // poll local kernel container status until success 611 682 while ( 1 ) 612 683 { 613 684 // compute buffer index and buffer descriptor paddr 614 index = ( Y_SIZE* cx) + cy;685 index = (ymax * cx) + cy; 615 686 buffer_desc_paddr = kernel_chbuf_paddr + (index<<6); 616 687 … … 633 704 kernel_buffer_paddr = buffer_desc & 0x0000FFFFFFFFFFFFULL; 634 705 635 // move one container , using a physical_memcpy636 if ( is_rx ) 706 // move one container 707 if ( is_rx ) // RX transfer 637 708 { 638 709 // inval kernel buffer in L2 before read in L2 … … 650 721 651 722 } 652 else 723 else // TX transfer 653 724 { 654 725 // transfer data from user buffer to kernel buffer … … 683 754 } // end _sys_nic_move() 684 755 756 685 757 //////////////////////////////////////// 686 758 int _sys_nic_stop( unsigned int is_rx, … … 702 774 } 703 775 776 // check NIC and CMA channels index 704 777 if ( nic_channel != channel ) 705 778 { 706 _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal NIC channel\n" 707 " allocated channel = %d / requested channel = %d\n", 708 nic_channel , channel ); 779 _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal NIC channel\n"); 709 780 return -1; 710 781 } … … 722 793 723 794 return 0; 724 } 795 } // end _sys_nic_stop() 725 796 726 797 //////////////////////////////////////// … … 763 834 } 764 835 return 0; 765 } 836 } // en _sys_nic_clear() 766 837 767 838 //////////////////////////////////////// … … 834 905 } 835 906 return 0; 836 } 907 } // end _sys_nic_stats() 837 908 838 909 ///////////////////////////////////////////////////////////////////////////////////////// … … 1231 1302 } 1232 1303 1233 ////////////////////////////////////// 1234 int _sys_procs_number( unsigned int x,1235 unsigned int y,1236 unsigned int* n umber)1237 { 1238 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;1304 //////////////////////////////////////////// 1305 int _sys_procs_number( unsigned int* x_size, 1306 unsigned int* y_size, 1307 unsigned int* nprocs ) 1308 { 1309 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 1239 1310 mapping_cluster_t * cluster = _get_cluster_base(header); 1240 1311 1241 if ( (x < X_SIZE) && (y < Y_SIZE) ) 1242 { 1243 *number = cluster[(x*Y_SIZE)+y].procs; 1244 return 0; 1245 } 1246 else 1247 { 1248 _printf("\n[GIET ERROR] in _sys_procs_number() : illegal (x,y) coordinates\n" ); 1249 return -1; 1250 } 1312 unsigned int x; 1313 unsigned int y; 1314 unsigned int okmin = 1; 1315 unsigned int okmax = 1; 1316 1317 // compute max values 1318 unsigned int xmax = header->x_size; 1319 unsigned int ymax = header->y_size; 1320 unsigned int procs = cluster[0].procs; 1321 1322 // check the (ymax-1) lower rows 1323 for ( y = 0 ; y < ymax-1 ; y++ ) 1324 { 1325 for ( x = 0 ; x < xmax ; x++ ) 1326 { 1327 if (cluster[x*ymax+y].procs != procs ) okmin = 0; 1328 } 1329 } 1330 1331 // check the upper row 1332 for ( x = 0 ; x < xmax ; x++ ) 1333 { 1334 if (cluster[x*ymax+ymax-1].procs != procs ) okmax = 0; 1335 } 1336 1337 // return values 1338 if ( okmin && okmax ) 1339 { 1340 *x_size = xmax; 1341 *y_size = ymax; 1342 *nprocs = procs; 1343 } 1344 else if ( okmin ) 1345 { 1346 *x_size = xmax; 1347 *y_size = ymax-1; 1348 *nprocs = procs; 1349 } 1350 else 1351 { 1352 *x_size = 0; 1353 *y_size = 0; 1354 *nprocs = 0; 1355 } 1356 return 0; 1251 1357 } 1252 1358 -
soft/giet_vm/giet_kernel/sys_handler.h
r489 r494 14 14 15 15 #include "giet_config.h" 16 #include " locks.h"16 #include "kernel_locks.h" 17 17 18 18 /////////////////////////////////////////////////////////////////////////////////// … … 41 41 // This structure is used by the CMA component to move a stream 42 42 // of images from two user buffers to the frame buffer in kernel space. 43 // it must be 64 bytes aligned.44 43 // It contains two chbuf arrays: 45 44 // - The SRC chbuf contains two buffers (buf0 & buf1), in user space. 46 45 // - The DST cbuf contains one single buffer (fbf), that is the frame buffer. 47 46 // - The length field define the buffer size (bytes) 47 // This structure must be 64 bytes aligned. 48 48 /////////////////////////////////////////////////////////////////////////////////// 49 49 … … 60 60 // This structure is used by the CMA component to move a stream of containers 61 61 // between the NIC chbuf containing 2 buffers, and a kernel chbuf 62 // containing (X_SIZE * Y_SIZE) buffers (one buffer per cluster).62 // containing up to (X_SIZE * Y_SIZE) buffers (one buffer per cluster). 63 63 // The same structure is used for both TX or RX transfers. 64 // It must be 64 bytes aligned. 64 // The number of distributed containers can be smaller than (X_SIZE * YSIZE). 65 // The actual number of buffers used in the chbuf is defined by (xmax * ymax). 66 // This structure must be 64 bytes aligned. 65 67 ////////////////////////////////////////////////////////////////////////////////// 66 68 … … 68 70 { 69 71 buffer_descriptor_t buffer[X_SIZE*Y_SIZE]; // kernel chbuf 72 unsigned int xmax; // nb clusters in a row 73 unsigned int ymax; // nb clusters in a column 70 74 } nic_chbuf_t; 71 75 … … 104 108 ////////////////////////////////////////////////////////////////////////////// 105 109 106 int _sys_nic_alloc( unsigned int is_rx ); 110 int _sys_nic_alloc( unsigned int is_rx, 111 unsigned int xmax, 112 unsigned int ymax ); 113 107 114 108 115 int _sys_nic_start( unsigned int is_rx, … … 164 171 int _sys_thread_id(); 165 172 166 int _sys_procs_number( unsigned int x,167 unsigned int y,168 unsigned int* n umber);173 int _sys_procs_number( unsigned int* x_size, 174 unsigned int* y_size, 175 unsigned int* nprocs ); 169 176 170 177 int _sys_vobj_get_vbase( char* vspace_name,
Note: See TracChangeset
for help on using the changeset viewer.