Changeset 709 for soft/giet_vm/giet_kernel/sys_handler.c
- Timestamp:
- Oct 1, 2015, 4:20:46 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_kernel/sys_handler.c
r707 r709 26 26 #include <io.h> 27 27 28 #if !defined(X_SIZE) 29 # error: You must define X_SIZE in the hard_config.h file 30 #endif 31 32 #if !defined(Y_SIZE) 33 # error: You must define Y_SIZE in the hard_config.h file 34 #endif 35 36 #if !defined(NB_PROCS_MAX) 37 # error: You must define NB_PROCS_MAX in the hard_config.h file 38 #endif 39 28 40 #if !defined(SEG_BOOT_MAPPING_BASE) 29 41 # error: You must define SEG_BOOT_MAPPING_BASE in the hard_config.h file … … 75 87 extern unsigned int _coproc_mode[X_SIZE*Y_SIZE]; 76 88 extern unsigned int _coproc_error[X_SIZE*Y_SIZE]; 77 extern unsigned int _coproc_gtid[X_SIZE*Y_SIZE]; 78 89 extern unsigned int _coproc_trdid[X_SIZE*Y_SIZE]; 79 90 80 91 // allocated in tty_driver.c file. 81 extern unsigned int _tty_rx_full[NB_TTY_CHANNELS]; 82 extern unsigned int _tty_rx_buf[NB_TTY_CHANNELS]; 92 extern tty_fifo_t _tty_rx_fifo[NB_TTY_CHANNELS]; 83 93 84 94 // allocated in kernel_init.c file 85 95 extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 86 96 87 //////////////////////////////////////////////////////////////////////////// 88 // Channel allocators for peripherals 89 // (TTY[0] is reserved for kernel) 90 //////////////////////////////////////////////////////////////////////////// 91 97 //////////////////////////////////////////////////////////////////////////////// 98 // Channel allocators for multi-channels peripherals 99 // - The array _***_channel_allocator[channel] defines the number of user 100 // threads for a dynamically allocated channel of peripheral ***. 101 // - The array _***_channel_wti[channel] defines the WTI index and the 102 // processor coordinates for the processor receiving the channel WTI. 103 //////////////////////////////////////////////////////////////////////////////// 104 105 #if NB_TTY_CHANNELS 92 106 __attribute__((section(".kdata"))) 93 unsigned int _tty_channel [NB_TTY_CHANNELS] = {1};107 unsigned int _tty_channel_alloc[NB_TTY_CHANNELS] = {0}; 94 108 95 109 __attribute__((section(".kdata"))) 96 unsigned int _tim_channel_allocator = 0; 97 110 unsigned int _tty_channel_wti[NB_TTY_CHANNELS]; 111 #endif 112 113 #if NB_TIM_CHANNELS 98 114 __attribute__((section(".kdata"))) 99 unsigned int _ cma_channel[NB_CMA_CHANNELS]= {0};115 unsigned int _tim_channel_alloc[NB_TIM_CHANNELS] = {0}; 100 116 101 117 __attribute__((section(".kdata"))) 102 unsigned int _nic_rx_channel_allocator = 0; 103 118 unsigned int _tim_channel_wti[NB_TIM_CHANNELS]; 119 #endif 120 121 #if NB_CMA_CHANNELS 104 122 __attribute__((section(".kdata"))) 105 unsigned int _nic_tx_channel_allocator = 0; 123 unsigned int _cma_channel_alloc[NB_CMA_CHANNELS] = {0}; 124 125 __attribute__((section(".kdata"))) 126 unsigned int _cma_channel_wti[NB_CMA_CHANNELS]; 127 #endif 128 129 #if NB_NIC_CHANNELS 130 __attribute__((section(".kdata"))) 131 unsigned int _nic_rx_channel_alloc[NB_NIC_CHANNELS] = {0}; 132 133 __attribute__((section(".kdata"))) 134 unsigned int _nic_rx_channel_wti[NB_NIC_CHANNELS]; 135 136 __attribute__((section(".kdata"))) 137 unsigned int _nic_tx_channel_alloc[NB_NIC_CHANNELS] = {0}; 138 139 __attribute__((section(".kdata"))) 140 unsigned int _nic_tx_channel_wti[NB_NIC_CHANNELS]; 141 #endif 106 142 107 143 //////////////////////////////////////////////////////////////////////////// … … 140 176 &_sys_proc_xyp, /* 0x00 */ 141 177 &_get_proctime, /* 0x01 */ 142 &_sys_ tty_write,/* 0x02 */143 &_sys_ tty_read,/* 0x03 */144 &_sys_ tty_alloc,/* 0x04 */145 &_sys_ tasks_status,/* 0x05 */178 &_sys_procs_number, /* 0x02 */ 179 &_sys_xy_from_ptr, /* 0x03 */ 180 &_sys_ukn, /* 0x04 */ 181 &_sys_ukn, /* 0x05 */ 146 182 &_sys_ukn, /* 0x06 */ 147 183 &_sys_heap_info, /* 0x07 */ 148 &_sys_ local_task_id,/* 0x08 */149 &_sys_ global_task_id,/* 0x09 */184 &_sys_vseg_get_vbase, /* 0x08 */ 185 &_sys_vseg_get_length, /* 0x09 */ 150 186 &_sys_fbf_cma_alloc, /* 0x0A */ 151 187 &_sys_fbf_cma_init_buf, /* 0x0B */ … … 153 189 &_sys_fbf_cma_display, /* 0x0D */ 154 190 &_sys_fbf_cma_stop, /* 0x0E */ 155 &_sys_ task_exit,/* 0x0F */156 157 &_sys_ procs_number,/* 0x10 */191 &_sys_ukn, /* 0x0F */ 192 193 &_sys_applications_status, /* 0x10 */ 158 194 &_sys_fbf_sync_write, /* 0x11 */ 159 195 &_sys_fbf_sync_read, /* 0x12 */ 160 &_sys_ thread_id,/* 0x13 */196 &_sys_ukn, /* 0x13 */ 161 197 &_sys_tim_alloc, /* 0x14 */ 162 198 &_sys_tim_start, /* 0x15 */ … … 164 200 &_sys_kill_application, /* 0x17 */ 165 201 &_sys_exec_application, /* 0x18 */ 166 &_sys_ context_switch,/* 0x19 */167 &_sys_ vseg_get_vbase,/* 0x1A */168 &_sys_ vseg_get_length,/* 0x1B */169 &_sys_ xy_from_ptr,/* 0x1C */170 &_sys_ ukn,/* 0x1D */171 &_sys_ ukn,/* 0x1E */172 &_sys_ ukn,/* 0x1F */202 &_sys_ukn, /* 0x19 */ 203 &_sys_pthread_control, /* 0x1A */ 204 &_sys_pthread_yield, /* 0x1B */ 205 &_sys_pthread_kill, /* 0x1C */ 206 &_sys_pthread_create, /* 0x1D */ 207 &_sys_pthread_join, /* 0x1E */ 208 &_sys_pthread_exit, /* 0x1F */ 173 209 174 210 &_fat_open, /* 0x20 */ 175 &_ sys_fat_read,/* 0x21 */211 &_fat_read, /* 0x21 */ 176 212 &_fat_write, /* 0x22 */ 177 213 &_fat_lseek, /* 0x23 */ … … 195 231 &_sys_nic_stats, /* 0x34 */ 196 232 &_sys_nic_clear, /* 0x35 */ 197 &_sys_ ukn,/* 0x36 */198 &_sys_ ukn,/* 0x37 */199 &_sys_ ukn, /* 0x38 */233 &_sys_tty_write, /* 0x36 */ 234 &_sys_tty_read, /* 0x37 */ 235 &_sys_tty_alloc, /* 0x38 */ 200 236 &_sys_ukn, /* 0x39 */ 201 237 &_sys_ukn, /* 0x3A */ … … 207 243 }; 208 244 245 246 ////////////////////////////////////////////////////////////////////////////// 247 // Applications related syscall handlers 248 ////////////////////////////////////////////////////////////////////////////// 249 250 //////////////////////////////////////////////////////////////////////// 251 // This function is called by the _sys_exec_application function 252 // to reload all data segments contained in an application.elf file. 209 253 //////////////////////////////////////////////////////////////////////// 210 254 static unsigned int _load_writable_segments( mapping_vspace_t* vspace ) 211 255 { 212 #if GIET_DEBUG_SWITCH 256 257 #if GIET_DEBUG_EXEC 213 258 unsigned int gpid = _get_procid(); 214 259 unsigned int cluster_xy = gpid >> P_WIDTH; … … 216 261 unsigned int x = cluster_xy >> Y_WIDTH; 217 262 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 218 if ( _get_proctime() > GIET_DEBUG_ SWITCH)219 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : enters for %s\n",220 x , y , p , vspace->name );263 if ( _get_proctime() > GIET_DEBUG_EXEC ) 264 _printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] " 265 "enters for %s\n", x , y , p , vspace->name ); 221 266 #endif 222 267 … … 224 269 mapping_vseg_t* vseg = _get_vseg_base(header); 225 270 226 // buffer to store one cluster 227 char buf[4096]; 228 229 // open the .elf file associated to vspace 230 unsigned int vseg_id; 231 unsigned int fd = 0; 232 271 unsigned int vseg_id; // vseg index in mapping 272 char buf[4096]; // buffer to store one cluster 273 unsigned int fd = 0; // file descriptor 274 275 // first scan on vsegs in vspace to find the .elf pathname 233 276 for (vseg_id = vspace->vseg_offset; 234 277 vseg_id < (vspace->vseg_offset + vspace->vsegs); 235 278 vseg_id++) 236 279 { 237 if( vseg[vseg_id].type == VSEG_TYPE_ELF)280 if( vseg[vseg_id].type == VSEG_TYPE_ELF ) 238 281 { 282 // open the .elf file associated to vspace 239 283 fd = _fat_open( vseg[vseg_id].binpath , O_RDONLY ); 240 241 #if GIET_DEBUG_SWITCH242 if ( _get_proctime() > GIET_DEBUG_SWITCH )243 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : open %s / fd = %d\n",244 x , y , p , vseg[vseg_id].binpath , fd );245 #endif246 247 284 if ( fd < 0 ) return 1; 248 285 break; 286 287 #if GIET_DEBUG_EXEC 288 if ( _get_proctime() > GIET_DEBUG_EXEC ) 289 _printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] " 290 "open %s / fd = %d\n", x , y , p , vseg[vseg_id].binpath , fd ); 291 #endif 249 292 } 250 293 } 251 294 252 295 // load Elf-Header into buffer from .elf file 253 if ( _fat_lseek( fd, 0, SEEK_SET ) < 0 ) return 1; 254 if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 ) return 1; 255 256 #if GIET_DEBUG_SWITCH 257 if ( _get_proctime() > GIET_DEBUG_SWITCH ) 258 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : load Elf-Header\n", 259 x , y , p ); 296 if ( _fat_lseek( fd, 0, SEEK_SET ) < 0 ) 297 { 298 _fat_close( fd ); 299 return 1; 300 } 301 if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 ) 302 { 303 _fat_close( fd ); 304 return 1; 305 } 306 307 #if GIET_DEBUG_EXEC 308 if ( _get_proctime() > GIET_DEBUG_EXEC ) 309 _printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] " 310 "loaded Elf-Header\n", x , y , p ); 260 311 #endif 261 312 … … 266 317 267 318 // load Program-Header-Table from .elf file 268 if ( _fat_lseek( fd, offset, SEEK_SET ) < 0 ) return 1; 269 if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 ) return 1; 270 271 #if GIET_DEBUG_SWITCH 272 if ( _get_proctime() > GIET_DEBUG_SWITCH ) 273 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : " 274 "load Program-Header-Table\n", x , y , p ); 319 if ( _fat_lseek( fd, offset, SEEK_SET ) < 0 ) 320 { 321 _fat_close( fd ); 322 return 1; 323 } 324 if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 ) 325 { 326 _fat_close( fd ); 327 return 1; 328 } 329 330 #if GIET_DEBUG_EXEC 331 if ( _get_proctime() > GIET_DEBUG_EXEC ) 332 _printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] " 333 "loaded Program-Header-Table\n", x , y , p ); 275 334 #endif 276 335 … … 278 337 Elf32_Phdr* elf_pht_ptr = (Elf32_Phdr*)buf; 279 338 280 // scan segments to load all loadable & writable segments 281 unsigned int seg_id; 282 for (seg_id = 0 ; seg_id < nsegments ; seg_id++) 283 { 284 if ( (elf_pht_ptr[seg_id].p_type == PT_LOAD) && // loadable 285 (elf_pht_ptr[seg_id].p_flags & PF_W) ) // writable 339 // second scan on vsegs in vspace to load the seg_data segments : 340 // - type == VSEG_TYPE_ELF 341 // - non eXecutable 342 for (vseg_id = vspace->vseg_offset; 343 vseg_id < (vspace->vseg_offset + vspace->vsegs); 344 vseg_id++) 345 { 346 if( (vseg[vseg_id].type == VSEG_TYPE_ELF) && // type ELF 347 ((vseg[vseg_id].mode & 0x4) == 0) ) // non executable 286 348 { 287 // Get segment attributes 288 paddr_t seg_paddr = vseg[vseg_id].pbase; 289 unsigned int seg_offset = elf_pht_ptr[seg_id].p_offset; 290 unsigned int seg_size = elf_pht_ptr[seg_id].p_filesz; 291 292 // load the segment 293 if ( _fat_lseek( fd, seg_offset, SEEK_SET ) < 0 ) return 1; 294 if ( _fat_read( fd, seg_paddr, seg_size, 1 ) < 0 ) return 1; 295 296 #if GIET_DEBUG_SWITCH 297 if ( _get_proctime() > GIET_DEBUG_SWITCH ) 298 _printf("\n[DEBUG SWITCH] P[%d,%d,%d] _load_writable_segments() : load segment %x\n", 299 x , y , p , seg_vaddr ); 349 // get vbase and pbase 350 paddr_t pbase = vseg[vseg_id].pbase; 351 unsigned int vbase = vseg[vseg_id].vbase; 352 353 // scan segments in Progam-Header-Table to find match 354 // No match checking as the segment was previously found 355 unsigned int seg; 356 for (seg = 0 ; seg < nsegments ; seg++) 357 { 358 if ( (elf_pht_ptr[seg].p_type == PT_LOAD) && // loadable 359 (elf_pht_ptr[seg].p_flags & PF_W) && // writable 360 (elf_pht_ptr[seg].p_vaddr == vbase) ) // matching 361 { 362 // Get segment offset and size in .elf file 363 unsigned int seg_offset = elf_pht_ptr[seg].p_offset; 364 unsigned int seg_size = elf_pht_ptr[seg].p_filesz; 365 366 // compute destination address and extension for _fat_read() 367 unsigned int dest = (unsigned int)pbase; 368 unsigned int extend = (unsigned int)(pbase>>32) | 0xFFFF0000; 369 370 // load the segment 371 if ( _fat_lseek( fd, seg_offset, SEEK_SET ) < 0 ) 372 { 373 _fat_close( fd ); 374 return 1; 375 } 376 if ( _fat_read( fd, dest, seg_size, extend ) < 0 ) 377 { 378 _fat_close( fd ); 379 return 1; 380 } 381 } 382 } 383 384 #if GIET_DEBUG_EXEC 385 if ( _get_proctime() > GIET_DEBUG_EXEC ) 386 _printf("\n[DEBUG EXEC] _load_writable_segments() : P[%d,%d,%d] " 387 "loaded segment %x\n", x , y , p , vbase ); 300 388 #endif 301 389 } … … 308 396 } // end load_writable_segments() 309 397 310 ////////////////////////////////////////////////////////////////////////////// 311 // Applications related syscall handlers 312 ////////////////////////////////////////////////////////////////////////////// 398 399 400 /////////////////////////////////////// 401 int _sys_exec_application( char* name ) 402 { 403 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 404 mapping_vspace_t * vspace = _get_vspace_base(header); 405 mapping_thread_t * thread = _get_thread_base(header); 406 mapping_vseg_t * vseg = _get_vseg_base(header); 407 408 unsigned int vspace_id; 409 unsigned int thread_id; 410 411 #if GIET_DEBUG_EXEC 412 unsigned int gpid = _get_procid(); 413 unsigned int cluster_xy = gpid >> P_WIDTH; 414 unsigned int p = gpid & ((1<<P_WIDTH)-1); 415 unsigned int x = cluster_xy >> Y_WIDTH; 416 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 417 if ( _get_proctime() > GIET_DEBUG_EXEC ) 418 _printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] " 419 "enters for %s at cycle %d\n", x, y, p, name, _get_proctime() ); 420 #endif 421 422 unsigned int y_size = header->y_size; 423 424 // scan vspaces to find matching vspace name 425 for (vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++) 426 { 427 if ( _strcmp( vspace[vspace_id].name, name ) == 0 ) // vspace found 428 { 429 430 #if GIET_DEBUG_EXEC 431 if ( _get_proctime() > GIET_DEBUG_EXEC ) 432 _printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] " 433 "found vspace %s at cycle %d\n", x, y, p, name, _get_proctime() ); 434 #endif 435 // reload writable segments 436 if ( _load_writable_segments( &vspace[vspace_id] ) ) 437 { 438 _printf("[GIET ERROR] _sys_exec_application() : " 439 "can't load data segment for vspace %s\n", name ); 440 return GIET_SYSCALL_CANNOT_LOAD_DATA_SEGMENT; 441 } 442 443 #if GIET_DEBUG_EXEC 444 if ( _get_proctime() > GIET_DEBUG_EXEC ) 445 _printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] " 446 "load segments for vspace %s at cycle %d\n", x, y, p, name, _get_proctime() ); 447 #endif 448 // scan threads in vspace with three goals : 449 // - check all threads desactivated 450 // - re-initialise all threads contexts 451 // - find main thread 452 unsigned int main_found = 0; 453 unsigned int main_ltid = 0; 454 static_scheduler_t* main_psched = NULL; 455 unsigned int min = vspace[vspace_id].thread_offset; 456 unsigned int max = min + vspace[vspace_id].threads; 457 for ( thread_id = min ; thread_id < max ; thread_id++ ) 458 { 459 // get thread identifiers : [x,y,p,ltid] 460 unsigned int cid = thread[thread_id].clusterid; 461 unsigned int x = cid / y_size; 462 unsigned int y = cid % y_size; 463 unsigned int p = thread[thread_id].proclocid; 464 unsigned int ltid = thread[thread_id].ltid; 465 unsigned int vsid = thread[thread_id].stack_vseg_id; 466 467 // get scheduler pointer 468 static_scheduler_t* psched = _schedulers[x][y][p]; 469 470 // check thread non active 471 if ( psched->context[ltid].slot[CTX_NORUN_ID] == 0 ) // runnable !!! 472 { 473 _printf("\n[GIET ERROR] in _sys_exec_application() : " 474 "thread %s already active in vspace %s\n", 475 thread[thread_id].name, name ); 476 return GIET_SYSCALL_THREAD_ALREADY_ACTIVE; 477 } 478 479 // initialise thread context 480 unsigned int ctx_epc = psched->context[ltid].slot[CTX_ENTRY_ID]; 481 unsigned int ctx_sp = vseg[vsid].vbase + vseg[vsid].length; 482 unsigned int ctx_ra = (unsigned int)&_ctx_eret; 483 unsigned int ctx_sr = GIET_SR_INIT_VALUE; 484 485 psched->context[ltid].slot[CTX_EPC_ID] = ctx_epc; 486 psched->context[ltid].slot[CTX_RA_ID] = ctx_ra; 487 psched->context[ltid].slot[CTX_SR_ID] = ctx_sr; 488 psched->context[ltid].slot[CTX_SP_ID] = ctx_sp; 489 490 // register information required to activate main thread 491 // actual activation done when threads initialisation is completed 492 if ( thread[thread_id].is_main ) 493 { 494 main_psched = psched; 495 main_ltid = ltid; 496 main_found = 1; 497 } 498 499 #if GIET_DEBUG_EXEC 500 if ( _get_proctime() > GIET_DEBUG_EXEC ) 501 _printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] " 502 "initialise thread %s at cycle %d\n", 503 x, y, p, thread[thread_id].name, _get_proctime() ); 504 #endif 505 } // end loop on vspace threads 506 507 // activate main thread 508 if ( main_found ) 509 { 510 main_psched->context[main_ltid].slot[CTX_NORUN_ID] = 0; 511 } 512 else 513 { 514 _printf("\n[GIET ERROR] in _sys_exec_application() : " 515 "main not found in vspace %s\n", name ); 516 return GIET_SYSCALL_MAIN_NOT_FOUND; 517 } 518 519 #if GIET_DEBUG_EXEC 520 if ( _get_proctime() > GIET_DEBUG_EXEC ) 521 _printf("\n[DEBUG EXEC] _sys_exec_application() : P[%d,%d,%d] " 522 "lauched %s at cycle %d\n", x, y, p, name, _get_proctime() ); 523 #endif 524 return GIET_SYSCALL_OK; 525 } 526 } // end of loop on vspaces 527 528 // vspace not found 529 _printf("\n[GIET ERROR] in _sys_exec_application() : " 530 "vspace %s not found\n", name ); 531 return GIET_SYSCALL_VSPACE_NOT_FOUND; 532 533 } // end _sys_exec_application() 534 313 535 314 536 /////////////////////////////////////// … … 317 539 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 318 540 mapping_vspace_t * vspace = _get_vspace_base(header); 319 mapping_t ask_t * task = _get_task_base(header);541 mapping_thread_t * thread = _get_thread_base(header); 320 542 321 543 unsigned int vspace_id; 322 unsigned int task_id; 323 unsigned int y_size = header->y_size; 544 unsigned int thread_id; 324 545 325 546 #if GIET_DEBUG_EXEC 547 unsigned int gpid = _get_procid(); 548 unsigned int cluster_xy = gpid >> P_WIDTH; 549 unsigned int p = gpid & ((1<<P_WIDTH)-1); 550 unsigned int x = cluster_xy >> Y_WIDTH; 551 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 326 552 if ( _get_proctime() > GIET_DEBUG_EXEC ) 327 _printf("\n[DEBUG EXEC] enters _sys_kill_application() for %s\n", name ); 328 #endif 329 330 // scan vspaces 553 _printf("\n[DEBUG EXEC] _sys_kill_application() P[%d,%d,%d] " 554 "enters at cycle %d for %s\n", x, y, p, _get_proctime() , name ); 555 #endif 556 557 // shell cannot be killed 558 if ( _strcmp( name , "shell" ) == 0 ) 559 { 560 _printf("\n[GIET ERROR] in _sys_kill_application() : " 561 "%s application cannot be killed\n", name ); 562 return GIET_SYSCALL_APPLI_CANNOT_BE_KILLED; 563 } 564 565 // scan vspaces to find matching vspace name 331 566 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 332 567 { 333 568 if ( _strcmp( vspace[vspace_id].name, name ) == 0 ) 334 569 { 335 // check if application can be killed 336 if ( vspace[vspace_id].active ) return -2; 337 338 // scan tasks in vspace 339 for (task_id = vspace[vspace_id].task_offset; 340 task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks); 341 task_id++) 570 // scan threads to send KILL signal to all threads in vspace 571 unsigned int y_size = header->y_size; 572 unsigned int min = vspace[vspace_id].thread_offset; 573 unsigned int max = min + vspace[vspace_id].threads; 574 for ( thread_id = min ; thread_id < max ; thread_id++ ) 342 575 { 343 unsigned int cid = t ask[task_id].clusterid;576 unsigned int cid = thread[thread_id].clusterid; 344 577 unsigned int x = cid / y_size; 345 578 unsigned int y = cid % y_size; 346 unsigned int p = t ask[task_id].proclocid;347 unsigned int ltid = t ask[task_id].ltid;348 349 // get scheduler pointer for processor running the t ask579 unsigned int p = thread[thread_id].proclocid; 580 unsigned int ltid = thread[thread_id].ltid; 581 582 // get scheduler pointer for processor running the thread 350 583 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 351 584 352 585 // set KILL signal bit 353 _atomic_or( &psched->context[ltid] [CTX_SIG_ID] , SIG_MASK_KILL );586 _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL ); 354 587 } 355 588 356 589 #if GIET_DEBUG_EXEC 357 590 if ( _get_proctime() > GIET_DEBUG_EXEC ) 358 _printf("\n[DEBUG EXEC] exit _sys_kill_application() : %s will be killed\n", name ); 359 #endif 360 361 return 0; 591 _printf("\n[DEBUG EXEC] _sys_kill_application() P[%d,%d,%d] " 592 "kill %s at cycle %d\n", x, y, p, name, _get_proctime() ); 593 #endif 594 595 return GIET_SYSCALL_OK; 362 596 } 363 } 597 } // en loop on vspaces 598 599 _printf("\n[GIET ERROR] in _sys_kill_application() : " 600 "application %s not found\n", name ); 601 return GIET_SYSCALL_VSPACE_NOT_FOUND; 602 603 } // end _sys_kill_application() 604 605 606 607 ////////////////////////////// 608 int _sys_applications_status() 609 { 610 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 611 mapping_thread_t * thread = _get_thread_base(header); 612 mapping_vspace_t * vspace = _get_vspace_base(header); 613 mapping_cluster_t * cluster = _get_cluster_base(header); 614 615 unsigned int thread_id; 616 unsigned int vspace_id; 617 618 // scan all vspaces 619 for( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ ) 620 { 621 _user_printf("\n*** vspace %s\n", vspace[vspace_id].name ); 622 623 // scan all threads in vspace 624 unsigned int min = vspace[vspace_id].thread_offset ; 625 unsigned int max = min + vspace[vspace_id].threads ; 626 for ( thread_id = min ; thread_id < max ; thread_id++ ) 627 { 628 unsigned int clusterid = thread[thread_id].clusterid; 629 unsigned int p = thread[thread_id].proclocid; 630 unsigned int x = cluster[clusterid].x; 631 unsigned int y = cluster[clusterid].y; 632 unsigned int ltid = thread[thread_id].ltid; 633 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 634 unsigned int norun = psched->context[ltid].slot[CTX_NORUN_ID]; 635 unsigned int tty = psched->context[ltid].slot[CTX_TTY_ID]; 636 unsigned int current = psched->current; 637 638 if ( current == ltid ) 639 _user_printf(" - thread %s / P[%d,%d,%d] / ltid = %d / " 640 "TTY = %d / norun = %x : running\n", 641 thread[thread_id].name, x, y, p, ltid, tty, norun ); 642 else if ( norun == 0 ) 643 _user_printf(" - thread %s / P[%d,%d,%d] / ltid = %d / " 644 "TTY = %d / norun = %x : runable\n", 645 thread[thread_id].name, x, y, p, ltid, tty, norun); 646 else 647 _user_printf(" - thread %s / P[%d,%d,%d] / ltid = %d / " 648 "TTY = %d / norun = %x : blocked\n", 649 thread[thread_id].name, x, y, p, ltid, tty, norun); 650 } 651 } 652 _user_printf("\n"); 653 return GIET_SYSCALL_OK; 654 } // end _sys_applications_status() 655 656 657 658 ///////////////////////////////////////////////////////////////////////////// 659 // Threads related syscall handlers 660 ///////////////////////////////////////////////////////////////////////////// 661 662 //////////////////////////////////////////////// 663 int _sys_pthread_create( unsigned int* buffer, 664 void* attr, 665 void* function, 666 void* arg ) 667 { 668 // attr argument not supported 669 if ( attr != NULL ) 670 { 671 _printf("\n[GIET ERROR] in _sys_pthread_create() : " 672 "attr argument not supported\n" ); 673 674 return GIET_SYSCALL_PTHREAD_ARGUMENT_NOT_SUPPORTED; 675 } 676 677 // get pointers in mapping 678 mapping_header_t* header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 679 mapping_thread_t* thread = _get_thread_base(header); 680 mapping_vspace_t* vspace = _get_vspace_base(header); 681 mapping_cluster_t* cluster = _get_cluster_base(header); 682 683 // get scheduler for processor running the calling thread 684 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 685 686 // get calling thread local index in scheduler 687 unsigned int current = psched->current; 688 689 // get vspace index 690 unsigned int vspace_id = psched->context[current].slot[CTX_VSID_ID]; 364 691 365 692 #if GIET_DEBUG_EXEC 366 693 if ( _get_proctime() > GIET_DEBUG_EXEC ) 367 _printf("\n[DEBUG EXEC] exit _sys_kill_application() : %s not found\n", name ); 368 #endif 369 370 return -1; // not found 371 372 } // end _sys_kill_application() 694 _printf("\n[DEBUG EXEC] _sys_pthread_create() : enters at cycle %d" 695 " for vspace %s / entry = %x\n", 696 _get_proctime() , vspace[vspace_id].name , (unsigned int)function ); 697 #endif 698 699 unsigned int thread_id; // searched thread : local index in mapping 700 unsigned int clusterid; // searched thread : cluster index 701 unsigned int lpid; // searched thread : processor local index 702 unsigned int ltid; // searched thread : scheduler thread index 703 unsigned int cx; // searched thread : X coordinate for searched thread 704 unsigned int cy; // searched thread : Y coordinate for searched thread 705 unsigned int entry; // searched thread : entry point 706 unsigned int norun; // searched thread : norun vector 707 unsigned int trdid; // searched thread : thread identifier 708 709 // scan threads in vspace to find an inactive thread matching function 710 unsigned int min = vspace[vspace_id].thread_offset; 711 unsigned int max = min + vspace[vspace_id].threads; 712 unsigned int found = 0; 713 for ( thread_id = min ; (thread_id < max) && (found == 0) ; thread_id++ ) 714 { 715 // get thread coordinates [cx,cy,lpid] and ltid from mapping 716 ltid = thread[thread_id].ltid; 717 clusterid = thread[thread_id].clusterid; 718 lpid = thread[thread_id].proclocid; 719 cx = cluster[clusterid].x; 720 cy = cluster[clusterid].y; 721 722 // get thread scheduler pointer 723 psched = _schedulers[cx][cy][lpid]; 724 725 // get thread entry-point, norun-vector, and trdid from context 726 entry = psched->context[ltid].slot[CTX_ENTRY_ID]; 727 norun = psched->context[ltid].slot[CTX_NORUN_ID]; 728 trdid = psched->context[ltid].slot[CTX_TRDID_ID]; 729 730 // check matching 731 if ( ((unsigned int)function == entry ) && 732 (norun & NORUN_MASK_THREAD) ) found = 1; 733 734 } // end loop on threads 735 736 if ( found ) // one matching inactive thread has been found 737 { 738 // set argument value in thread context 739 if ( arg != NULL ) psched->context[ltid].slot[CTX_A0_ID] = (unsigned int)arg; 740 741 // activate thread 742 psched->context[ltid].slot[CTX_NORUN_ID] = 0; 743 744 // return launched thead global identifier 745 *buffer = trdid; 746 747 #if GIET_DEBUG_EXEC 748 if ( _get_proctime() > GIET_DEBUG_EXEC ) 749 _printf("\n[DEBUG EXEC] exit _sys_pthread_create() at cycle %d : thread %x launched\n", 750 _get_proctime() , trdid); 751 #endif 752 return GIET_SYSCALL_OK; 753 } 754 else // no matching thread found 755 { 756 _printf("\n[GIET ERROR] in _sys_pthread_create() : " 757 "no matching thread for entry = %x in vspace %s\n", 758 (unsigned int)function , vspace[vspace_id].name ); 759 760 return GIET_SYSCALL_THREAD_NOT_FOUND; 761 } 762 763 } // end _sys_pthread_create() 764 765 766 /////////////////////////////////////////// 767 int _sys_pthread_join( unsigned int trdid, 768 void* ptr ) 769 { 770 // ptr argument not supported 771 if ( ptr != NULL ) 772 { 773 _printf("\n[GIET ERROR] in _sys_pthread_join() : " 774 "ptr argument not supported, must be NULL\n" ); 775 776 return GIET_SYSCALL_PTHREAD_ARGUMENT_NOT_SUPPORTED; 777 } 778 779 780 #if GIET_DEBUG_EXEC 781 if ( _get_proctime() > GIET_DEBUG_EXEC ) 782 _printf("\n[DEBUG EXEC] enters _sys_pthread_join() at cycle %d for thread %x\n", 783 _get_proctime() , trdid ); 784 #endif 785 786 // get calling thread vspace 787 unsigned int caller_vspace = _get_context_slot( CTX_VSID_ID ); 788 789 // get and check target thread indexes from trdid 790 unsigned int cx = (trdid>>24) & 0xFF; 791 unsigned int cy = (trdid>>16) & 0xFF; 792 unsigned int lpid = (trdid>>8 ) & 0xFF; 793 unsigned int ltid = (trdid ) & 0xFF; 794 795 // get target thread scheduler, vspace and registered trdid 796 static_scheduler_t* psched = _schedulers[cx][cy][lpid]; 797 unsigned int target_vspace = psched->context[ltid].slot[CTX_VSID_ID]; 798 unsigned int registered_trdid = psched->context[ltid].slot[CTX_TRDID_ID]; 799 800 // check trdid 801 if ( trdid != registered_trdid ) 802 { 803 _printf("\nerror in _sys_pthread_join() : " 804 "trdid = %x / registered_trdid = %x\n", 805 trdid , registered_trdid ); 806 807 return GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT; 808 } 809 810 // check calling thread and target thread in same vspace 811 if ( caller_vspace != target_vspace ) 812 { 813 _printf("\n[GIET ERROR] in _sys_pthread_join() : " 814 " calling thread and target thread not in same vspace\n"); 815 816 return GIET_SYSCALL_NOT_IN_SAME_VSPACE; 817 } 818 819 // get target thread state 820 unsigned int* pnorun = &psched->context[ltid].slot[CTX_NORUN_ID]; 821 822 asm volatile ( "2000: \n" 823 "move $11, %0 \n" /* $11 <= ptr */ 824 "lw $11, 0($11) \n" /* $11 <= M[ptr] */ 825 "andi $11, $11, 1 \n" /* $11 <= norun & 0x1 */ 826 "beqz $11, 2000b \n" 827 : 828 : "r" (pnorun) 829 : "$11" ); 830 831 return GIET_SYSCALL_OK; 832 833 } // end _sys_pthread_join() 834 835 836 //////////////////////////////////////// 837 int _sys_pthread_kill( pthread_t trdid, 838 int signal ) 839 { 840 // get calling thread vspace 841 unsigned int caller_vspace = _get_context_slot( CTX_VSID_ID ); 842 843 // get and check target thread indexes from trdid 844 unsigned int cx = (trdid>>24) & 0xFF; 845 unsigned int cy = (trdid>>16) & 0xFF; 846 unsigned int lpid = (trdid>>8 ) & 0xFF; 847 unsigned int ltid = (trdid ) & 0xFF; 848 849 // get target thread scheduler, vspace and registered trdid 850 static_scheduler_t* psched = _schedulers[cx][cy][lpid]; 851 unsigned int target_vspace = psched->context[ltid].slot[CTX_VSID_ID]; 852 unsigned int registered_trdid = psched->context[ltid].slot[CTX_TRDID_ID]; 853 854 // check trdid 855 if ( trdid != registered_trdid ) 856 { 857 _printf("\n[GIET ERROR] in _sys_pthread_kill() : trdid = %x" 858 " / registered_trdid = %x\n", trdid , registered_trdid ); 859 return GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT; 860 } 861 862 // check calling thread and target thread in same vspace 863 if ( caller_vspace != target_vspace ) 864 { 865 _printf("\n[GIET ERROR] in _sys_pthread_kill() : not in same vspace\n"); 866 return GIET_SYSCALL_NOT_IN_SAME_VSPACE; 867 } 868 869 // register KILL signal in target thread context if required 870 if ( signal ) 871 { 872 _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL ); 873 } 874 875 return GIET_SYSCALL_OK; 876 877 } // end _sys_pthread_kill() 878 879 880 ///////////////////////////////////// 881 int _sys_pthread_exit( void* string ) 882 { 883 unsigned int date = _get_proctime(); 884 885 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 886 mapping_vspace_t * vspace = _get_vspace_base(header); 887 888 unsigned int ltid = _get_context_slot(CTX_LTID_ID); 889 unsigned int trdid = _get_context_slot(CTX_TRDID_ID); 890 unsigned int vsid = _get_context_slot(CTX_VSID_ID); 891 892 // print exit message 893 if ( string == NULL ) 894 { 895 _printf("\n[GIET WARNING] Exit thread %x in vspace %s at cycle %d\n", 896 trdid , vspace[vsid].name , date ); 897 } 898 else 899 { 900 _printf("\n[GIET WARNING] Exit thread %x in vspace %s at cycle %d\n" 901 " Cause : %s\n\n", 902 trdid , vspace[vsid].name , date , (char*) string ); 903 } 373 904 374 /////////////////////////////////////// 375 int _sys_exec_application( char* name ) 376 { 377 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 378 mapping_vseg_t * vseg = _get_vseg_base(header); 379 mapping_vspace_t * vspace = _get_vspace_base(header); 380 mapping_task_t * task = _get_task_base(header); 381 382 unsigned int vspace_id; 383 unsigned int task_id; 384 unsigned int y_size = header->y_size; 385 386 #if GIET_DEBUG_EXEC 905 // get scheduler pointer for calling thread 906 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 907 908 // register KILL signal in calling thread context (suicid request) 909 _atomic_or( &psched->context[ltid].slot[CTX_SIGS_ID] , SIGS_MASK_KILL ); 910 911 // deschedule calling thread 912 unsigned int save_sr; 913 _it_disable( &save_sr ); 914 915 _ctx_switch(); 916 917 return GIET_SYSCALL_OK; 918 919 } // end _sys_pthread_exit() 920 921 //////////////////////// 922 int _sys_pthread_yield() 923 { 924 unsigned int save_sr; 925 926 _it_disable( &save_sr ); 927 _ctx_switch(); 928 _it_restore( &save_sr ); 929 930 return GIET_SYSCALL_OK; 931 } 932 933 ////////////////////////////////////////////////// 934 int _sys_pthread_control( unsigned int command, 935 char* vspace_name, 936 char* thread_name ) 937 { 938 939 #if GIET_DEBUG_EXEC 387 940 if ( _get_proctime() > GIET_DEBUG_EXEC ) 388 _printf("\n[DEBUG EXEC] enters _sys_exec_application() at cycle %d for %s\n", 389 _get_proctime() , name ); 390 #endif 391 392 // find vspace 393 for ( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ ) 394 { 395 if ( _strcmp( vspace[vspace_id].name, name ) == 0 ) 941 _printf("\n[DEBUG EXEC] _sys_pthread_control() at cycle %d : " 942 "enter for vspace %s / thread %s / command = %d\n", 943 _get_proctime() , vspace_name, thread_name, command ); 944 #endif 945 946 // get pointers in mapping 947 mapping_header_t* header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 948 mapping_thread_t* thread = _get_thread_base(header); 949 mapping_vspace_t* vspace = _get_vspace_base(header); 950 mapping_cluster_t* cluster = _get_cluster_base(header); 951 952 unsigned int found; 953 954 // search vspace name to get vspace index: vsid 955 found = 0; 956 unsigned int vsid; 957 for( vsid = 0 ; vsid < header->vspaces ; vsid++ ) 958 { 959 if ( _strcmp( vspace[vsid].name, vspace_name ) == 0 ) 960 { 961 found = 1; 396 962 break; 397 } 398 399 if ( vspace_id == header->vspaces ) 400 { 401 _printf("\n[GIET ERROR] _sys_exec_application() : %s not found\n", name ); 402 return -1; 403 } 404 405 // scan tasks in vspace 406 for (task_id = vspace[vspace_id].task_offset; 407 task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks); 408 task_id++) 409 { 410 unsigned int cid = task[task_id].clusterid; 411 unsigned int x = cid / y_size; 412 unsigned int y = cid % y_size; 413 unsigned int p = task[task_id].proclocid; 414 unsigned int ltid = task[task_id].ltid; 415 416 // get scheduler pointer for processor running the task 417 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 418 419 // check if an application task is runnable 420 if ( psched->context[ltid][CTX_NORUN_ID] == 0 ) 963 } 964 } 965 966 if ( found == 0 ) return GIET_SYSCALL_VSPACE_NOT_FOUND; 967 968 // search thread name in vspace to get thread index: tid 969 found = 0; 970 unsigned int tid; 971 unsigned int min = vspace[vsid].thread_offset; 972 unsigned int max = min + vspace[vsid].threads; 973 for( tid = min ; tid < max ; tid++ ) 974 { 975 if ( _strcmp( thread[tid].name, thread_name ) == 0 ) 421 976 { 422 _printf( "\n[GIET ERROR] _sys_exec_application() : %s already executed\n", name );423 return -2;977 found = 1; 978 break; 424 979 } 425 980 } 426 981 427 // reload writable segments 428 if ( _load_writable_segments( &vspace[vspace_id] ) ) 429 { 430 _printf("[GIET ERROR] _sys_exec_application() : can't load segments for %s\n", name ); 431 return -3; 432 } 433 434 // scan tasks in vspace 435 for (task_id = vspace[vspace_id].task_offset; 436 task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks); 437 task_id++) 438 { 439 unsigned int cid = task[task_id].clusterid; 440 unsigned int x = cid / y_size; 441 unsigned int y = cid % y_size; 442 unsigned int p = task[task_id].proclocid; 443 unsigned int ltid = task[task_id].ltid; 444 445 // get scheduler pointer for processor running the task 446 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 447 448 // reset task context: RA / SR / SP / EPC / NORUN 449 unsigned int vseg_id = task[task_id].stack_vseg_id; 450 unsigned int sp_value = vseg[vseg_id].vbase + vseg[vseg_id].length; 451 452 psched->context[ltid][CTX_RA_ID] = (unsigned int)&_ctx_eret; 453 psched->context[ltid][CTX_SR_ID] = GIET_SR_INIT_VALUE; 454 psched->context[ltid][CTX_SP_ID] = sp_value; 455 psched->context[ltid][CTX_EPC_ID] = psched->context[ltid][CTX_ENTRY_ID]; 456 psched->context[ltid][CTX_NORUN_ID] = 0; 457 } 458 459 #if GIET_DEBUG_EXEC 460 if ( _get_proctime() > GIET_DEBUG_EXEC ) 461 _printf("\n[DEBUG EXEC] exit _sys_exec_application() at cycle %d : %s will be executed\n", 462 _get_proctime() , name ); 463 #endif 464 465 return 0; 466 } // end _sys_exec_application() 467 982 if ( found == 0 ) return GIET_SYSCALL_THREAD_NOT_FOUND; 983 984 // get thread coordinates 985 unsigned int cid = thread[tid].clusterid; 986 unsigned int x = cluster[cid].x; 987 unsigned int y = cluster[cid].y; 988 unsigned int p = thread[tid].proclocid; 989 unsigned int ltid = thread[tid].ltid; 990 991 static_scheduler_t* psched = _schedulers[x][y][p]; 992 993 // check trdid and vsid 994 unsigned int trdid = x<<24 | y<<16 | p<<8 | ltid; 995 if ( (psched->context[ltid].slot[CTX_TRDID_ID] != trdid) || 996 (psched->context[ltid].slot[CTX_VSID_ID] != vsid) ) 997 return GIET_SYSCALL_UNCOHERENT_THREAD_CONTEXT; 998 999 // execute command 1000 if ( command == THREAD_CMD_PAUSE ) 1001 { 1002 _atomic_or ( &psched->context[ltid].slot[CTX_NORUN_ID], NORUN_MASK_THREAD ); 1003 return GIET_SYSCALL_OK; 1004 } 1005 else if ( command == THREAD_CMD_RESUME ) 1006 { 1007 _atomic_and( &psched->context[ltid].slot[CTX_NORUN_ID], ~NORUN_MASK_THREAD ); 1008 return GIET_SYSCALL_OK; 1009 } 1010 else if ( command == THREAD_CMD_CONTEXT ) 1011 { 1012 _user_printf( " - CTX_TRDID = %x\n" 1013 " - CTX_VSID = %x\n" 1014 " - CTX_EPC = %x\n" 1015 " - CTX_PTAB = %x\n" 1016 " - CTX_PTPR = %x\n" 1017 " - CTX_SR = %x\n" 1018 " - CTX_RA = %x\n" 1019 " - CTX_SP = %x\n" 1020 " - CTX_ENTRY = %x\n" 1021 " - CTX_NORUN = %x\n" 1022 " - CTX_SIGS = %x\n" 1023 " - CTX_LOCKS = %x\n" 1024 " - CTX_TTY = %x\n" 1025 " - CTX_NIC_RX = %x\n" 1026 " - CTX_NIC_TX = %x\n" 1027 " - CTX_CMA_RX = %x\n" 1028 " - CTX_CMA_TX = %x\n" 1029 " - CTX_CMA_FB = %x\n", 1030 psched->context[ltid].slot[CTX_TRDID_ID], 1031 psched->context[ltid].slot[CTX_VSID_ID], 1032 psched->context[ltid].slot[CTX_EPC_ID], 1033 psched->context[ltid].slot[CTX_PTAB_ID], 1034 psched->context[ltid].slot[CTX_PTPR_ID], 1035 psched->context[ltid].slot[CTX_SR_ID], 1036 psched->context[ltid].slot[CTX_RA_ID], 1037 psched->context[ltid].slot[CTX_SP_ID], 1038 psched->context[ltid].slot[CTX_ENTRY_ID], 1039 psched->context[ltid].slot[CTX_NORUN_ID], 1040 psched->context[ltid].slot[CTX_SIGS_ID], 1041 psched->context[ltid].slot[CTX_LOCKS_ID], 1042 psched->context[ltid].slot[CTX_TTY_ID], 1043 psched->context[ltid].slot[CTX_NIC_RX_ID], 1044 psched->context[ltid].slot[CTX_NIC_TX_ID], 1045 psched->context[ltid].slot[CTX_CMA_RX_ID], 1046 psched->context[ltid].slot[CTX_CMA_TX_ID], 1047 psched->context[ltid].slot[CTX_CMA_FB_ID] ); 1048 return GIET_SYSCALL_OK; 1049 } 1050 else 1051 { 1052 return GIET_SYSCALL_ILLEGAL_THREAD_COMMAND_TYPE; 1053 } 1054 1055 } // end _sys_pthread_control() 1056 1057 1058 468 1059 469 1060 ////////////////////////////////////////////////////////////////////////////// … … 476 1067 { 477 1068 // In this implementation, the allocation policy is constrained: 478 // the coprocessor must be in the same cluster as the calling t ask,1069 // the coprocessor must be in the same cluster as the calling thread, 479 1070 // and there is at most one coprocessor per cluster 480 1071 … … 519 1110 *coproc_info = _coproc_info[cluster_id]; 520 1111 521 // register coprocessor coordinates in t askcontext1112 // register coprocessor coordinates in thread context 522 1113 unsigned int cluster_xy = (x<<Y_WIDTH) + y; 523 1114 _set_context_slot( CTX_COPROC_ID , cluster_xy ); … … 528 1119 x , y , *coproc_info , cluster_xy ); 529 1120 #endif 530 return 0;1121 return GIET_SYSCALL_OK; 531 1122 } 532 1123 else … … 535 1126 " with type %d available in cluster[%d,%d]\n", 536 1127 coproc_type , x , y ); 537 return -1;1128 return GIET_SYSCALL_COPROCESSOR_NOT_FOUND; 538 1129 } 539 1130 } // end _sys_coproc_alloc() … … 553 1144 { 554 1145 _printf("\n[GIET_ERROR] in _sys_coproc_release(): " 555 "no coprocessor allocated to t askrunning on P[%d,%d,%d]\n",1146 "no coprocessor allocated to thread running on P[%d,%d,%d]\n", 556 1147 x , y , p ); 557 return -1;1148 return GIET_SYSCALL_COPROCESSOR_NOT_FOUND; 558 1149 } 559 1150 … … 573 1164 } 574 1165 575 // deallocates coprocessor coordinates in t askcontext1166 // deallocates coprocessor coordinates in thread context 576 1167 _set_context_slot( CTX_COPROC_ID , 0xFFFFFFFF ); 577 1168 … … 584 1175 #endif 585 1176 586 return 0;1177 return GIET_SYSCALL_OK; 587 1178 } // end _sys_coproc_release() 588 1179 … … 602 1193 { 603 1194 _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): " 604 "no coprocessor allocated to t askrunning on P[%d,%d,%d]\n",1195 "no coprocessor allocated to thread running on P[%d,%d,%d]\n", 605 1196 x , y , p ); 606 return -1;1197 return GIET_SYSCALL_COPROCESSOR_NOT_FOUND; 607 1198 } 608 1199 … … 615 1206 _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): " 616 1207 " illegal mode\n"); 617 return -1;1208 return GIET_SYSCALL_COPROCESSOR_ILLEGAL_MODE; 618 1209 } 619 1210 … … 622 1213 623 1214 // physical addresses 624 paddr_tbuffer_paddr;1215 unsigned long long buffer_paddr; 625 1216 unsigned int buffer_lsb; 626 1217 unsigned int buffer_msb; 627 paddr_tmwmr_paddr = 0;1218 unsigned long long mwmr_paddr = 0; 628 1219 unsigned int mwmr_lsb; 629 1220 unsigned int mwmr_msb; 630 paddr_tlock_paddr = 0;1221 unsigned long long lock_paddr = 0; 631 1222 unsigned int lock_lsb; 632 1223 unsigned int lock_msb; … … 674 1265 #endif 675 1266 676 return 0;1267 return GIET_SYSCALL_OK; 677 1268 } // end _sys_coproc_channel_init() 678 1269 … … 691 1282 { 692 1283 _printf("\n[GIET_ERROR] in _sys_coproc_run(): " 693 "no coprocessor allocated to t askrunning on P[%d,%d,%d]\n",1284 "no coprocessor allocated to thread running on P[%d,%d,%d]\n", 694 1285 x , y , p ); 695 return -1 ;1286 return -1111; 696 1287 } 697 1288 … … 719 1310 _printf("\n[GIET_ERROR] P[%d,%d,%d] in _sys_coproc_run() for coprocessor[%d,%d]\n" 720 1311 " all channels don't have the same mode\n", x , y , p , cx , cy ); 721 return -1 ;1312 return -1111; 722 1313 } 723 1314 } … … 745 1336 #endif 746 1337 747 return 0;1338 return GIET_SYSCALL_OK; 748 1339 } 749 1340 /////////////////////////////////////////////////////////////////////////// 750 1341 else // mode == MODE_DMA_IRQ => descheduling 751 1342 { 752 // set _coproc_ gtid753 unsigned int ltid = _get_ current_task_id();754 _coproc_ gtid[cluster_id] = (procid<<16) + ltid;1343 // set _coproc_trdid 1344 unsigned int ltid = _get_thread_ltid(); 1345 _coproc_trdid[cluster_id] = (x<<24) + (y<<16) + (p<<8) + ltid; 755 1346 756 1347 // enters critical section … … 760 1351 // set NORUN_MASK_COPROC bit 761 1352 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 762 unsigned int* ptr = &psched->context[ltid] [CTX_NORUN_ID];1353 unsigned int* ptr = &psched->context[ltid].slot[CTX_NORUN_ID]; 763 1354 _atomic_or( ptr , NORUN_MASK_COPROC ); 764 1355 … … 771 1362 #endif 772 1363 773 // deschedule t ask1364 // deschedule thread 774 1365 _ctx_switch(); 775 1366 … … 802 1393 { 803 1394 _printf("\n[GIET_ERROR] in _sys_coproc_completed(): " 804 "no coprocessor allocated to t askrunning on P[%d,%d,%d]\n",1395 "no coprocessor allocated to thread running on P[%d,%d,%d]\n", 805 1396 x , y , p ); 806 return -1 ;1397 return -1111; 807 1398 } 808 1399 … … 879 1470 int _sys_tty_alloc( unsigned int shared ) 880 1471 { 881 unsigned int channel; 882 1472 unsigned int channel; // allocated TTY channel 1473 1474 // get trdid and vsid for the calling thread 1475 unsigned int vsid = _get_context_slot( CTX_VSID_ID ); 1476 unsigned int trdid = _get_thread_trdid(); 1477 1478 // check no TTY already allocated to calling thread 883 1479 if ( _get_context_slot( CTX_TTY_ID ) < NB_TTY_CHANNELS ) 884 1480 { 885 _printf("\n[GIET_ERROR] in _sys_tty_alloc() : TTY channel already allocated\n"); 886 return 0; 887 } 888 889 // get a new TTY channel 1481 _printf("\n[GIET_ERROR] in _sys_tty_alloc() : " 1482 "TTY channel already allocated to thread %x\n", trdid ); 1483 return -1111; 1484 } 1485 1486 mapping_header_t *header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 1487 mapping_vspace_t *vspace = _get_vspace_base(header); 1488 mapping_thread_t *thread = _get_thread_base(header); 1489 1490 // compute number of users 1491 unsigned int users; 1492 if ( shared ) users = vspace[vsid].threads; 1493 else users = 1; 1494 1495 // get a TTY channel 890 1496 for ( channel = 0 ; channel < NB_TTY_CHANNELS ; channel++ ) 891 1497 { 892 if ( !_tty_channel[channel] ) 893 { 894 _tty_channel[channel] = 1; 895 break; 896 } 1498 unsigned int* palloc = &_tty_channel_alloc[channel]; 1499 1500 if ( _atomic_test_and_set( palloc , users ) == 0 ) break; 897 1501 } 898 1502 if ( channel >= NB_TTY_CHANNELS ) 899 1503 { 900 _printf("\n[GIET_ERROR] in _sys_tty_alloc() : no TTY channel available\n"); 901 return -1; 902 } 903 904 // reset kernel buffer for allocated TTY channel 905 _tty_rx_full[channel] = 0; 1504 _printf("\n[GIET_ERROR] in _sys_tty_alloc() : " 1505 "no TTY channel available for thread %x\n", trdid ); 1506 return -1111; 1507 } 1508 1509 // initialise allocated TTY channel 1510 _tty_init( channel ); 906 1511 907 1512 // allocate a WTI mailbox to the calling proc if external IRQ 908 unsigned int unused; 909 if ( USE_PIC ) _ext_irq_alloc( ISR_TTY_RX , channel , &unused ); 1513 unsigned int wti_id; 1514 if ( USE_PIC ) _ext_irq_alloc( ISR_TTY_RX , channel , &wti_id ); 1515 1516 // register wti_id and coordinates for processor receiving WTI 1517 unsigned int procid = _get_procid(); 1518 unsigned int x = procid >> (Y_WIDTH + P_WIDTH); 1519 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 1520 unsigned int p = procid & ((1<<P_WIDTH)-1); 1521 _tty_channel_wti[channel] = x<<24 | y<<16 | p<<8 | wti_id; 910 1522 911 1523 // update CTX_TTY_ID 912 if ( shared ) // for all tasks in the same vspace 913 { 914 unsigned int vspace_id = _get_context_slot( CTX_VSID_ID ); 915 mapping_header_t *header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 916 mapping_vspace_t *vspace = _get_vspace_base(header); 917 mapping_task_t *task = _get_task_base(header); 918 919 // scan tasks in vspace 920 unsigned int task_id; 921 for (task_id = vspace[vspace_id].task_offset; 922 task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks); 923 task_id++) 1524 if ( shared ) // for all threads in vspace 1525 { 1526 // scan threads in vspace 1527 unsigned int tid; 1528 for (tid = vspace[vsid].thread_offset; 1529 tid < (vspace[vsid].thread_offset + vspace[vsid].threads); 1530 tid++) 924 1531 { 925 1532 unsigned int y_size = header->y_size; 926 unsigned int cid = t ask[task_id].clusterid;1533 unsigned int cid = thread[tid].clusterid; 927 1534 unsigned int x = cid / y_size; 928 1535 unsigned int y = cid % y_size; 929 unsigned int p = t ask[task_id].proclocid;930 unsigned int ltid = t ask[task_id].ltid;1536 unsigned int p = thread[tid].proclocid; 1537 unsigned int ltid = thread[tid].ltid; 931 1538 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 932 1539 933 // don't overwrite TTY_ID 934 if ( psched->context[ltid][CTX_TTY_ID] >= NB_TTY_CHANNELS ) 935 { 936 psched->context[ltid][CTX_TTY_ID] = channel; 937 } 1540 psched->context[ltid].slot[CTX_TTY_ID] = channel; 938 1541 } 939 1542 } 940 else // for calling t askonly1543 else // for calling thread only 941 1544 { 942 1545 _set_context_slot( CTX_TTY_ID, channel ); 943 1546 } 944 1547 945 return 0; 946 } 947 948 ///////////////////////////////////////// 949 // NOTE: not a syscall 950 int _sys_tty_release() 1548 return GIET_SYSCALL_OK; 1549 } // end _sys_tty_alloc() 1550 1551 ////////////////////// 1552 int _sys_tty_release() // NOTE: not a syscall 951 1553 { 952 1554 unsigned int channel = _get_context_slot( CTX_TTY_ID ); … … 954 1556 if ( channel == -1 ) 955 1557 { 956 _printf("\n[GIET_ERROR] in _sys_tty_release() : TTY channel already released\n"); 957 return -1; 958 } 959 960 // release WTI mailbox 961 if ( USE_PIC ) _ext_irq_release( ISR_TTY_RX , channel ); 962 963 // reset CTX_TTY_ID for all tasks in vspace 964 unsigned int vspace_id = _get_context_slot( CTX_VSID_ID ); 965 mapping_header_t *header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 966 mapping_vspace_t *vspace = _get_vspace_base(header); 967 mapping_task_t *task = _get_task_base(header); 968 969 unsigned int task_id; 970 for (task_id = vspace[vspace_id].task_offset; 971 task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks); 972 task_id++) 973 { 974 unsigned int y_size = header->y_size; 975 unsigned int cid = task[task_id].clusterid; 976 unsigned int x = cid / y_size; 977 unsigned int y = cid % y_size; 978 unsigned int p = task[task_id].proclocid; 979 unsigned int ltid = task[task_id].ltid; 980 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 981 982 // only clear matching TTY_ID 983 if ( psched->context[ltid][CTX_TTY_ID] == channel ) 984 { 985 psched->context[ltid][CTX_TTY_ID] = -1; 986 } 987 } 988 989 // release TTY channel 990 _tty_channel[channel] = 0; 991 992 return 0; 993 } 994 995 ///////////////////////////////////////////////// 1558 unsigned int trdid = _get_thread_trdid(); 1559 _printf("\n[GIET_ERROR] in _sys_tty_release() : " 1560 "TTY channel already released for thread %x\n", trdid ); 1561 return -1111; 1562 } 1563 1564 // reset CTX_TTY_ID for the calling thread 1565 _set_context_slot( CTX_TTY_ID , 0xFFFFFFFF ); 1566 1567 // atomically decrement the _tty_channel_allocator[] array 1568 _atomic_increment( &_tty_channel_alloc[channel] , -1 ); 1569 1570 // release WTI mailbox if TTY channel no more used 1571 if ( USE_PIC && (_tty_channel_alloc[channel] == 0) ) 1572 { 1573 _ext_irq_release( ISR_TTY_RX , channel ); 1574 } 1575 1576 return GIET_SYSCALL_OK; 1577 } // end sys_tty_release() 1578 1579 //////////////////////////////////////// 996 1580 int _sys_tty_write( const char* buffer, 997 1581 unsigned int length, // number of characters … … 1002 1586 // compute and check tty channel 1003 1587 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 1004 if( channel >= NB_TTY_CHANNELS ) return -1 ;1588 if( channel >= NB_TTY_CHANNELS ) return -1111; 1005 1589 1006 1590 // write string to TTY channel … … 1021 1605 } 1022 1606 1023 /////////////////////////////////////// /////////1607 /////////////////////////////////////// 1024 1608 int _sys_tty_read( char* buffer, 1025 1609 unsigned int length, // unused … … 1028 1612 // compute and check tty channel 1029 1613 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 1030 if( channel >= NB_TTY_CHANNELS ) return -1; 1031 1032 // read one character from TTY channel 1033 if (_tty_rx_full[channel] == 0) 1034 { 1035 return 0; 1036 } 1037 else 1038 { 1039 *buffer = _tty_rx_buf[channel]; 1040 _tty_rx_full[channel] = 0; 1041 return 1; 1042 } 1614 if( channel >= NB_TTY_CHANNELS ) return -1111; 1615 1616 unsigned int save_sr; 1617 unsigned int found = 0; 1618 1619 // get pointer on TTY_RX FIFO 1620 tty_fifo_t* fifo = &_tty_rx_fifo[channel]; 1621 1622 // try to read one character from FIFO 1623 // blocked in while loop until success 1624 while ( found == 0 ) 1625 { 1626 if ( fifo->sts == 0) // FIFO empty => deschedule 1627 { 1628 // enters critical section 1629 _it_disable( &save_sr ); 1630 1631 // set NORUN_MASK_TTY bit for calling thread 1632 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 1633 unsigned int ltid = psched->current; 1634 _atomic_or( &psched->context[ltid].slot[CTX_NORUN_ID] , NORUN_MASK_TTY ); 1635 1636 // register descheduling thread trdid 1637 fifo->trdid = _get_thread_trdid(); 1638 1639 // deschedule calling thread 1640 _ctx_switch(); 1641 1642 // exit critical section 1643 _it_restore( &save_sr ); 1644 } 1645 else // FIFO not empty => get one character 1646 { 1647 *buffer = fifo->data[fifo->ptr]; 1648 fifo->sts = fifo->sts - 1; 1649 fifo->ptr = (fifo->ptr + 1) % TTY_FIFO_DEPTH; 1650 found = 1; 1651 } 1652 } 1653 1654 return 1; 1043 1655 } 1044 1656 1045 /////////////////////////////////////////// 1046 int _sys_tty_get_lock( unsigned int channel, // unused 1047 unsigned int * save_sr_ptr ) 1048 { 1049 // check tty channel 1050 if( channel != 0 ) return 1; 1051 1052 _it_disable( save_sr_ptr ); 1053 _sqt_lock_acquire( &_tty0_sqt_lock ); 1054 return 0; 1055 } 1056 1057 /////////////////////////////////////////////// 1058 int _sys_tty_release_lock( unsigned int channel, 1059 unsigned int * save_sr_ptr ) 1060 { 1061 // check tty channel 1062 if( channel != 0 ) return 1; 1063 1064 _sqt_lock_release( &_tty0_sqt_lock ); 1065 _it_restore( save_sr_ptr ); 1066 return 0; 1067 } 1657 1068 1658 1069 1659 ////////////////////////////////////////////////////////////////////////////// 1070 // TIM related syscall handlers1660 // TIMER related syscall handlers 1071 1661 ////////////////////////////////////////////////////////////////////////////// 1072 1662 … … 1074 1664 int _sys_tim_alloc() 1075 1665 { 1076 // get a new timer index 1077 unsigned int channel = _atomic_increment( &_tim_channel_allocator, 1 ); 1078 1666 1667 #if NB_TIM_CHANNELS 1668 1669 unsigned int channel; // allocated TIMER channel 1670 1671 unsigned int trdid = _get_thread_trdid(); 1672 1673 // check no TIMER already allocated to calling thread 1674 if ( _get_context_slot( CTX_TIM_ID ) < NB_TIM_CHANNELS ) 1675 { 1676 _printf("\n[GIET_ERROR] in _sys_tim_alloc() : " 1677 "TIMER channel already allocated to thread %x\n", trdid ); 1678 return -1111; 1679 } 1680 1681 // get a TIMER channel 1682 for ( channel = 0 ; channel < NB_TIM_CHANNELS ; channel++ ) 1683 { 1684 unsigned int* palloc = &_tim_channel_alloc[channel]; 1685 1686 if ( _atomic_test_and_set( palloc , 1 ) == 0 ) break; 1687 } 1079 1688 if ( channel >= NB_TIM_CHANNELS ) 1080 1689 { 1081 _printf("\n[GIET_ERROR] in _sys_tim_alloc() : not enough TIM channels\n"); 1082 return -1; 1083 } 1084 else 1085 { 1086 _set_context_slot( CTX_TIM_ID, channel ); 1087 return 0; 1088 } 1089 } 1090 1091 //////////////////// 1092 // NOTE: not a syscall 1093 int _sys_tim_release() 1094 { 1095 // release one timer 1096 _atomic_increment( &_tim_channel_allocator, 0xFFFFFFFF ); 1097 1098 return 0; 1099 } 1690 _printf("\n[GIET_ERROR] in _sys_tim_alloc() : " 1691 "no TIMER channel available for thread %x\n", trdid ); 1692 return -1111; 1693 } 1694 1695 // allocate a WTI mailbox to the calling proc if external IRQ 1696 unsigned int wti_id; 1697 if ( USE_PIC ) _ext_irq_alloc( ISR_TIMER , channel , &wti_id ); 1698 1699 // register wti_id and coordinates for processor receiving WTI 1700 unsigned int procid = _get_procid(); 1701 unsigned int x = procid >> (Y_WIDTH + P_WIDTH); 1702 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 1703 unsigned int p = procid & ((1<<P_WIDTH)-1); 1704 _tim_channel_wti[channel] = x<<24 | y<<16 | p<<8 | wti_id; 1705 1706 // update CTX_TIM_ID in thread context 1707 _set_context_slot( CTX_TIM_ID, channel ); 1708 1709 return GIET_SYSCALL_OK; 1710 1711 #else 1712 1713 _printf("\n[GIET ERROR] in _sys_tim_alloc() : NB_TIM_CHANNELS = 0\n"); 1714 return -1111; 1715 1716 #endif 1717 } // end _sys_tim_alloc() 1718 1719 1720 ////////////////////// 1721 int _sys_tim_release() // NOTE: not a syscall 1722 { 1723 1724 #if NB_TIM_CHANNELS 1725 1726 unsigned int channel = _get_context_slot( CTX_TIM_ID ); 1727 1728 if ( channel == -1 ) 1729 { 1730 unsigned int trdid = _get_thread_trdid(); 1731 _printf("\n[GIET_ERROR] in _sys_tim_release() : " 1732 "TIMER channel already released for thread %x\n", trdid ); 1733 return -1111; 1734 } 1735 1736 // reset CTX_TIM_ID for the calling thread 1737 _set_context_slot( CTX_TIM_ID , 0xFFFFFFFF ); 1738 1739 // reset the _tim_channel_alloc[] array 1740 _tim_channel_alloc[channel] = 0; 1741 1742 // release WTI mailbox if TTY channel no more used 1743 if ( USE_PIC ) 1744 { 1745 _ext_irq_release( PERIPH_TYPE_TIM , channel ); 1746 } 1747 1748 return GIET_SYSCALL_OK; 1749 1750 #else 1751 1752 _printf("\n[GIET ERROR] in _sys_tim_release() : NB_TIM_CHANNELS = 0\n"); 1753 return -1111; 1754 1755 #endif 1756 } // end _sys_tim_release() 1100 1757 1101 1758 ///////////////////////////////////////// 1102 1759 int _sys_tim_start( unsigned int period ) 1103 1760 { 1761 1762 #if NB_TIM_CHANNELS 1763 1104 1764 // get timer index 1105 1765 unsigned int channel = _get_context_slot( CTX_TIM_ID ); … … 1107 1767 { 1108 1768 _printf("\n[GIET_ERROR] in _sys_tim_start() : not enough TIM channels\n"); 1109 return -1 ;1769 return -1111; 1110 1770 } 1111 1771 … … 1113 1773 _timer_start( channel, period ); 1114 1774 1115 return 0; 1775 return GIET_SYSCALL_OK; 1776 1777 #else 1778 1779 _printf("\n[GIET ERROR] in _sys_tim_start() : NB_TIM_CHANNELS = 0\n"); 1780 return -1111; 1781 1782 #endif 1116 1783 } 1117 1784 … … 1119 1786 int _sys_tim_stop() 1120 1787 { 1788 1789 #if NB_TIM_CHANNELS 1790 1121 1791 // get timer index 1122 1792 unsigned int channel = _get_context_slot( CTX_TIM_ID ); … … 1124 1794 { 1125 1795 _printf("\n[GIET_ERROR] in _sys_tim_stop() : illegal timer index\n"); 1126 return -1 ;1796 return -1111; 1127 1797 } 1128 1798 … … 1130 1800 _timer_stop( channel ); 1131 1801 1132 return 0; 1802 return GIET_SYSCALL_OK; 1803 1804 #else 1805 1806 _printf("\n[GIET ERROR] in _sys_tim_stop() : NB_TIM_CHANNELS = 0\n"); 1807 return -1111; 1808 1809 #endif 1133 1810 } 1811 1134 1812 1135 1813 ////////////////////////////////////////////////////////////////////////////// … … 1138 1816 1139 1817 #define NIC_CONTAINER_SIZE 4096 1818 1819 #if NB_NIC_CHANNELS 1140 1820 1141 1821 //////////////////////////////////////// … … 1144 1824 unsigned int ymax ) 1145 1825 { 1826 mapping_header_t *header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 1827 mapping_vspace_t *vspace = _get_vspace_base(header); 1828 mapping_thread_t *thread = _get_thread_base(header); 1829 1830 // get calling thread trdid, vspace index, and number of threads 1831 unsigned int trdid = _get_thread_trdid(); 1832 unsigned int vsid = _get_context_slot( CTX_VSID_ID ); 1833 unsigned int users = vspace[vsid].threads; 1834 1146 1835 // check xmax / ymax parameters 1147 if ( xmax > X_SIZE ) 1148 { 1149 _printf("\n[GIET_ERROR] in _sys_nic_alloc() xmax argument too large\n"); 1150 return -1; 1151 } 1152 if ( ymax > Y_SIZE ) 1153 { 1154 _printf("\n[GIET_ERROR] in _sys_nic_alloc() ymax argument too large\n"); 1155 return -1; 1836 if ( (xmax > X_SIZE) || (ymax > Y_SIZE) ) 1837 { 1838 _printf("\n[GIET_ERROR] in _sys_nic_alloc() " 1839 "xmax or ymax argument too large for thread %x\n", trdid ); 1840 return -1111; 1156 1841 } 1157 1842 … … 1160 1845 //////////////////////////////////////////////////////// 1161 1846 1162 // get a NIC_RX or NIC_TX channel index 1163 unsigned int nic_channel; 1164 unsigned int cma_channel; 1165 1166 if ( is_rx ) nic_channel = _atomic_increment( &_nic_rx_channel_allocator, 1 ); 1167 else nic_channel = _atomic_increment( &_nic_tx_channel_allocator, 1 ); 1168 1847 unsigned int nic_channel; 1848 unsigned int cma_channel; 1849 unsigned int* palloc; 1850 1851 // get a NIC_RX or NIC_TX channel 1852 for ( nic_channel = 0 ; nic_channel < NB_NIC_CHANNELS ; nic_channel++ ) 1853 { 1854 if ( is_rx ) palloc = &_nic_rx_channel_alloc[nic_channel]; 1855 else palloc = &_nic_tx_channel_alloc[nic_channel]; 1856 1857 if ( _atomic_test_and_set( palloc , users ) == 0 ) break; 1858 } 1169 1859 if ( (nic_channel >= NB_NIC_CHANNELS) ) 1170 1860 { 1171 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough NIC channels\n"); 1172 return -1; 1173 } 1174 1175 // get a CMA channel index 1861 _printf("\n[GIET_ERROR] in _sys_nic_alloc() : " 1862 "no NIC channel available for thread %x\n", trdid ); 1863 return -1111; 1864 } 1865 1866 // get a CMA channel 1176 1867 for ( cma_channel = 0 ; cma_channel < NB_CMA_CHANNELS ; cma_channel++ ) 1177 1868 { 1178 if ( !_cma_channel[cma_channel] ) 1869 palloc = &_cma_channel_alloc[cma_channel]; 1870 1871 if ( _atomic_test_and_set( palloc , users ) == 0 ) break; 1872 } 1873 if ( cma_channel >= NB_CMA_CHANNELS ) 1874 { 1875 _printf("\n[GIET_ERROR] in _sys_nic_alloc() : " 1876 "no CMA channel available for thread %x\n", trdid ); 1877 if ( is_rx ) _nic_rx_channel_alloc[nic_channel] = 0; 1878 else _nic_tx_channel_alloc[nic_channel] = 0; 1879 return -1111; 1880 } 1881 1882 #if GIET_DEBUG_NIC 1883 _printf("\n[GIET DEBUG NIC] Thread %d enters sys_nic_alloc() at cycle %d\n" 1884 " nic_channel = %d / cma_channel = %d\n", 1885 trdid , _get_proctime() , nic_channel , cma_channel ); 1886 #endif 1887 1888 // register nic_index and cma_index in all threads 1889 // contexts that are in the same vspace 1890 unsigned int tid; 1891 for (tid = vspace[vsid].thread_offset; 1892 tid < (vspace[vsid].thread_offset + vspace[vsid].threads); 1893 tid++) 1894 { 1895 unsigned int y_size = header->y_size; 1896 unsigned int cid = thread[tid].clusterid; 1897 unsigned int x = cid / y_size; 1898 unsigned int y = cid % y_size; 1899 unsigned int p = thread[tid].proclocid; 1900 unsigned int ltid = thread[tid].ltid; 1901 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 1902 1903 if ( is_rx ) 1179 1904 { 1180 _cma_channel[cma_channel] = 1; 1181 break; 1905 if ( (psched->context[ltid].slot[CTX_NIC_RX_ID] < NB_NIC_CHANNELS) || 1906 (psched->context[ltid].slot[CTX_CMA_RX_ID] < NB_CMA_CHANNELS) ) 1907 { 1908 _printf("\n[GIET_ERROR] in _sys_nic_alloc() : " 1909 "NIC_RX or CMA_RX channel already allocated for thread %x\n", trdid ); 1910 _nic_rx_channel_alloc[nic_channel] = 0; 1911 _cma_channel_alloc[cma_channel] = 0; 1912 return -1111; 1913 } 1914 else 1915 { 1916 psched->context[ltid].slot[CTX_NIC_RX_ID] = nic_channel; 1917 psched->context[ltid].slot[CTX_CMA_RX_ID] = cma_channel; 1918 } 1182 1919 } 1183 } 1184 1185 if ( cma_channel >= NB_CMA_CHANNELS ) 1186 { 1187 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough CMA channels\n"); 1188 return -1; 1189 } 1190 1191 #if GIET_DEBUG_NIC 1192 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 1193 _printf("\n[GIET DEBUG NIC] Task %d enters sys_nic_alloc() at cycle %d\n" 1194 " nic_channel = %d / cma_channel = %d\n", 1195 thread , _get_proctime() , nic_channel , cma_channel ); 1196 #endif 1197 1198 // register nic_index and cma_index in task context 1199 if ( is_rx ) 1200 { 1201 _set_context_slot( CTX_NIC_RX_ID, nic_channel ); 1202 _set_context_slot( CTX_CMA_RX_ID, cma_channel ); 1203 } 1204 else 1205 { 1206 _set_context_slot( CTX_NIC_TX_ID, nic_channel ); 1207 _set_context_slot( CTX_CMA_TX_ID, cma_channel ); 1208 } 1920 else // is_tx 1921 { 1922 if ( (psched->context[ltid].slot[CTX_NIC_TX_ID] < NB_NIC_CHANNELS) || 1923 (psched->context[ltid].slot[CTX_CMA_TX_ID] < NB_CMA_CHANNELS) ) 1924 { 1925 _printf("\n[GIET_ERROR] in _sys_nic_alloc() : " 1926 "NIC_TX or CMA_TX channel already allocated for thread %x\n", trdid ); 1927 _nic_tx_channel_alloc[nic_channel] = 0; 1928 _cma_channel_alloc[cma_channel] = 0; 1929 return -1111; 1930 } 1931 else 1932 { 1933 psched->context[ltid].slot[CTX_NIC_TX_ID] = nic_channel; 1934 psched->context[ltid].slot[CTX_CMA_TX_ID] = cma_channel; 1935 } 1936 } 1937 } // end loop on threads 1209 1938 1210 1939 ///////////////////////////////////////////////////////////////////////////////// … … 1241 1970 if ( vaddr == 0 ) // not enough kernel heap memory in cluster[cx,cy] 1242 1971 { 1243 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough kenel heap"1244 " in cluster[%d,%d]\n", cx, cy );1245 return -1 ;1972 _printf("\n[GIET_ERROR] in _sys_nic_alloc() : " 1973 "not enough kenel heap in cluster[%d,%d]\n", cx, cy ); 1974 return -1111; 1246 1975 } 1247 1976 … … 1252 1981 if ( cont_paddr & 0x3F ) 1253 1982 { 1254 _printf("\n[GIET ERROR] in _sys_nic_alloc() : container address of cluster[%d,%d] not aligned\n",1255 cx, cy);1256 return -1 ;1983 _printf("\n[GIET ERROR] in _sys_nic_alloc() : " 1984 "container address of cluster[%d,%d] not aligned\n", cx, cy); 1985 return -1111; 1257 1986 } 1258 1987 … … 1270 1999 if ( vaddr == 0 ) // not enough kernel heap memory in cluster[cx,cy] 1271 2000 { 1272 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough kenel heap"1273 " in cluster[%d,%d]\n", cx, cy );1274 return -1 ;2001 _printf("\n[GIET_ERROR] in _sys_nic_alloc() : " 2002 "not enough kernel heap in cluster[%d,%d]\n", cx, cy ); 2003 return -1111; 1275 2004 } 1276 2005 … … 1281 2010 if ( sts_paddr & 0x3F ) 1282 2011 { 1283 _printf("\n[GIET ERROR] in _sys_nic_alloc() : status address of cluster[%d,%d] not aligned\n",1284 cx, cy);1285 return -1 ;2012 _printf("\n[GIET ERROR] in _sys_nic_alloc() : " 2013 "status address of cluster[%d,%d] not aligned\n", cx, cy); 2014 return -1111; 1286 2015 } 1287 2016 … … 1385 2114 #endif 1386 2115 1387 return nic_channel;2116 return GIET_SYSCALL_OK; 1388 2117 } // end _sys_nic_alloc() 1389 2118 1390 2119 1391 //////////////////////////////////////// 1392 // NOTE: not a syscall 1393 int _sys_nic_release( unsigned int is_rx ) 1394 { 1395 if ( is_rx ) 1396 _atomic_increment( &_nic_rx_channel_allocator , 0xFFFFFFFF ); 1397 else 1398 _atomic_increment( &_nic_tx_channel_allocator , 0xFFFFFFFF ); 1399 1400 return 0; 1401 } 1402 1403 1404 //////////////////////////////////////// 1405 int _sys_nic_start( unsigned int is_rx, 1406 unsigned int channel ) 1407 { 2120 ////////////////////////////////////////// 2121 int _sys_nic_release( unsigned int is_rx ) // NOTE: not a syscall 2122 { 2123 unsigned int trdid = _get_thread_trdid(); 2124 1408 2125 unsigned int nic_channel; 1409 2126 unsigned int cma_channel; 1410 1411 // get NIC channel index and CMA channel index from task context2127 2128 // update the kernel tables 1412 2129 if ( is_rx ) 1413 2130 { 1414 2131 nic_channel = _get_context_slot( CTX_NIC_RX_ID ); 1415 2132 cma_channel = _get_context_slot( CTX_CMA_RX_ID ); 1416 } 2133 2134 if ( (nic_channel >= NB_NIC_CHANNELS) ) 2135 { 2136 _printf("\n[GIET ERROR] in _sys_nic_release() : " 2137 "NIC_RX channel already released for thread %x\n", trdid ); 2138 return -1111; 2139 } 2140 if ( (cma_channel >= NB_CMA_CHANNELS) ) 2141 { 2142 _printf("\n[GIET ERROR] in _sys_nic_release() : " 2143 "CMA_RX channel already released for thread %x\n", trdid ); 2144 return -1111; 2145 } 2146 2147 // atomically decrement the NIC and CMA channel allocators 2148 _atomic_increment( &_nic_rx_channel_alloc[nic_channel] , -1 ); 2149 _atomic_increment( &_cma_channel_alloc[cma_channel] , -1 ); 2150 2151 // stop the NIC and CMA peripherals channels if no more users 2152 if ( (_nic_rx_channel_alloc[nic_channel] == 0) && 2153 (_cma_channel_alloc[cma_channel] == 0) ) _sys_nic_stop( 1 ); 2154 2155 // reset the calling thread context slots 2156 _set_context_slot( CTX_NIC_RX_ID , 0xFFFFFFFF ); 2157 _set_context_slot( CTX_CMA_RX_ID , 0xFFFFFFFF ); 2158 } 1417 2159 else 1418 2160 { 1419 2161 nic_channel = _get_context_slot( CTX_NIC_TX_ID ); 1420 2162 cma_channel = _get_context_slot( CTX_CMA_TX_ID ); 2163 2164 if ( (nic_channel >= NB_NIC_CHANNELS) ) 2165 { 2166 _printf("\n[GIET ERROR] in _sys_nic_release() : " 2167 "NIC_TX channel already released for thread %x\n", trdid ); 2168 return -1111; 2169 } 2170 if ( (cma_channel >= NB_CMA_CHANNELS) ) 2171 { 2172 _printf("\n[GIET ERROR] in _sys_nic_release() : " 2173 "CMA_TX channel already released for thread %x\n", trdid ); 2174 return -1111; 2175 } 2176 2177 // atomically decrement the NIC and CMA channel allocators 2178 _atomic_increment( &_nic_tx_channel_alloc[nic_channel] , -1 ); 2179 _atomic_increment( &_cma_channel_alloc[cma_channel] , -1 ); 2180 2181 // stop the NIC and CMA peripherals channels if no more users 2182 if ( (_nic_tx_channel_alloc[nic_channel] == 0) && 2183 (_cma_channel_alloc[cma_channel] == 0) ) _sys_nic_stop( 0 ); 2184 2185 // reset the calling thread context slots 2186 _set_context_slot( CTX_NIC_TX_ID , 0xFFFFFFFF ); 2187 _set_context_slot( CTX_CMA_TX_ID , 0xFFFFFFFF ); 2188 } 2189 2190 return GIET_SYSCALL_OK; 2191 } // end sys_nic_release() 2192 2193 2194 //////////////////////////////////////// 2195 int _sys_nic_start( unsigned int is_rx ) 2196 { 2197 unsigned int trdid = _get_context_slot( CTX_TRDID_ID ); 2198 2199 unsigned int nic_channel; 2200 unsigned int cma_channel; 2201 2202 // get NIC channel index and CMA channel index from thread context 2203 if ( is_rx ) 2204 { 2205 nic_channel = _get_context_slot( CTX_NIC_RX_ID ); 2206 cma_channel = _get_context_slot( CTX_CMA_RX_ID ); 2207 } 2208 else 2209 { 2210 nic_channel = _get_context_slot( CTX_NIC_TX_ID ); 2211 cma_channel = _get_context_slot( CTX_CMA_TX_ID ); 1421 2212 } 1422 2213 1423 2214 #if GIET_DEBUG_NIC 1424 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 1425 _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_start() at cycle %d\n" 2215 _printf("\n[GIET DEBUG NIC] Thread %x in _sys_nic_start() at cycle %d\n" 1426 2216 " get NIC channel = %d / CMA channel = %d\n", 1427 t hread, _get_proctime(), nic_channel, cma_channel );2217 trdid, _get_proctime(), nic_channel, cma_channel ); 1428 2218 #endif 1429 2219 1430 2220 // check NIC and CMA channels index 1431 if ( nic_channel != channel ) 1432 { 1433 _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal NIC channel\n"); 1434 return -1; 2221 if ( nic_channel >= NB_NIC_CHANNELS ) 2222 { 2223 _printf("\n[GIET_ERROR] in _sys_nic_start() : " 2224 "illegal NIC channel for thread %x\n", trdid ); 2225 return -1111; 1435 2226 } 1436 2227 if ( cma_channel >= NB_CMA_CHANNELS ) 1437 2228 { 1438 _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal CMA channel\n"); 1439 return -1; 2229 _printf("\n[GIET_ERROR] in _sys_nic_start() : " 2230 "illegal CMA channel for thread %x\n", trdid ); 2231 return -1111; 1440 2232 } 1441 2233 … … 1450 2242 #if GIET_DEBUG_NIC 1451 2243 _printf("\n[GIET DEBUG NIC] Task %d exit _sys_nic_start() at cycle %d\n", 1452 t hread , _get_proctime() );1453 #endif 1454 1455 return 0;2244 trdid , _get_proctime() ); 2245 #endif 2246 2247 return GIET_SYSCALL_OK; 1456 2248 } // end _sys_nic_start() 1457 2249 … … 1459 2251 ////////////////////////////////////// 1460 2252 int _sys_nic_move( unsigned int is_rx, 1461 unsigned int channel,1462 2253 void* buffer ) 1463 2254 { 2255 unsigned int trdid = _get_context_slot( CTX_TRDID_ID ); 2256 2257 unsigned int channel; 1464 2258 1465 2259 #if GIET_DEBUG_NIC 1466 unsigned int thread = _get_context_slot( CTX_TRDID_ID );1467 2260 _printf("\n[GIET DEBUG NIC] Task %d enters _sys_nic_move() at cycle %d\n", 1468 thread , _get_proctime() ); 1469 #endif 2261 trdid , _get_proctime() ); 2262 #endif 2263 2264 // get NIC channel index from thread context 2265 if ( is_rx ) channel = _get_context_slot( CTX_NIC_RX_ID ); 2266 else channel = _get_context_slot( CTX_NIC_TX_ID ); 1470 2267 1471 2268 // check NIC channel index 1472 2269 if ( channel >= NB_NIC_CHANNELS ) 1473 2270 { 1474 _printf("\n[GIET_ERROR] in _sys_nic_move() : illegal NIC channel index\n"); 1475 return -1; 2271 _printf("\n[GIET_ERROR] in _sys_nic_move() : " 2272 "illegal NIC channel index for thread %x\n", trdid ); 2273 return -1111; 1476 2274 } 1477 2275 … … 1485 2283 unsigned int ymax = ker_chbuf->ymax; 1486 2284 1487 // get cluster coordinates for the processor running the calling t ask2285 // get cluster coordinates for the processor running the calling thread 1488 2286 unsigned int procid = _get_procid(); 1489 2287 unsigned int cx = procid >> (Y_WIDTH + P_WIDTH); … … 1495 2293 _printf("\n[GIET_ERROR] in _sys_nic_move() : processor X coordinate = %d" 1496 2294 " / xmax = %d\n", cx , xmax ); 1497 return -1 ;2295 return -1111; 1498 2296 } 1499 2297 if ( cy >= ymax ) … … 1501 2299 _printf("\n[GIET_ERROR] in _sys_nic_move() : processor Y coordinate = %d" 1502 2300 " / ymax = %d\n", cy , ymax ); 1503 return -1 ;2301 return -1111; 1504 2302 } 1505 2303 … … 1518 2316 { 1519 2317 _printf("\n[GIET ERROR] in _sys_nic_tx_move() : illegal user buffer address\n"); 1520 return -1 ;2318 return -1111; 1521 2319 } 1522 2320 … … 1606 2404 #endif 1607 2405 1608 return 0;2406 return GIET_SYSCALL_OK; 1609 2407 } // end _sys_nic_move() 1610 2408 1611 2409 1612 //////////////////////////////////////// 1613 int _sys_nic_stop( unsigned int is_rx, 1614 unsigned int channel ) 1615 { 2410 /////////////////////////////////////// 2411 int _sys_nic_stop( unsigned int is_rx ) 2412 { 2413 unsigned int trdid = _get_context_slot( CTX_TRDID_ID ); 2414 1616 2415 unsigned int nic_channel; 1617 2416 unsigned int cma_channel; … … 1630 2429 1631 2430 // check NIC and CMA channels index 1632 if ( nic_channel != channel ) 1633 { 1634 _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal NIC channel\n"); 1635 return -1; 2431 if ( nic_channel >= NB_NIC_CHANNELS ) 2432 { 2433 _printf("\n[GIET_ERROR] in _sys_nic_stop() : " 2434 "illegal NIC channel for thread %x\n", trdid ); 2435 return -1111; 1636 2436 } 1637 2437 if ( cma_channel >= NB_CMA_CHANNELS ) 1638 2438 { 1639 _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal CMA channel\n"); 1640 return -1; 1641 } 2439 _printf("\n[GIET_ERROR] in _sys_nic_stop() : " 2440 "illegal CMA channel for thread %x\n", trdid ); 2441 return -1111; 2442 } 2443 2444 // desactivates the CMA channel 2445 _cma_set_register( cma_channel, CHBUF_RUN , 0 ); 2446 2447 // wait until CMA channel IDLE 2448 unsigned int volatile status; 2449 do 2450 { 2451 status = _cma_get_register( cma_channel, CHBUF_STATUS ); 2452 } while ( status ); 1642 2453 1643 2454 // desactivates the NIC channel 1644 2455 _nic_channel_stop( nic_channel, is_rx ); 1645 2456 1646 // desactivates the CMA channel 1647 _cma_set_register( cma_channel, CHBUF_RUN , 0 ); 1648 1649 return 0; 2457 return GIET_SYSCALL_OK; 1650 2458 } // end _sys_nic_stop() 1651 2459 1652 2460 //////////////////////////////////////// 1653 int _sys_nic_clear( unsigned int is_rx, 1654 unsigned int channel ) 1655 { 1656 unsigned int nic_channel; 2461 int _sys_nic_clear( unsigned int is_rx ) 2462 { 2463 unsigned int trdid = _get_context_slot( CTX_TRDID_ID ); 2464 2465 unsigned int channel; 1657 2466 1658 2467 // get NIC channel 1659 if ( is_rx ) nic_channel = _get_context_slot( CTX_NIC_RX_ID ); 1660 else nic_channel = _get_context_slot( CTX_NIC_TX_ID ); 1661 1662 if ( nic_channel != channel ) 1663 { 1664 _printf("\n[GIET_ERROR] in _sys_nic_clear(): illegal NIC channel\n"); 1665 return -1; 2468 if ( is_rx ) channel = _get_context_slot( CTX_NIC_RX_ID ); 2469 else channel = _get_context_slot( CTX_NIC_TX_ID ); 2470 2471 if ( channel >= NB_NIC_CHANNELS ) 2472 { 2473 _printf("\n[GIET_ERROR] in _sys_nic_clear() : " 2474 "illegal NIC channel for thread %x\n", trdid ); 2475 return -1111; 1666 2476 } 1667 2477 … … 1688 2498 _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_BROADCAST , 0 ); 1689 2499 } 1690 return 0;2500 return GIET_SYSCALL_OK; 1691 2501 } // en _sys_nic_clear() 1692 2502 1693 2503 //////////////////////////////////////// 1694 int _sys_nic_stats( unsigned int is_rx, 1695 unsigned int channel ) 1696 { 2504 int _sys_nic_stats( unsigned int is_rx ) 2505 { 2506 unsigned int trdid = _get_context_slot( CTX_TRDID_ID ); 2507 1697 2508 unsigned int nic_channel; 1698 2509 … … 1701 2512 else nic_channel = _get_context_slot( CTX_NIC_TX_ID ); 1702 2513 1703 if ( nic_channel != channel ) 1704 { 1705 _printf("\n[GIET_ERROR] in _sys_nic_stats(): illegal NIC channel\n"); 1706 return -1; 2514 if ( nic_channel >= NB_NIC_CHANNELS ) 2515 { 2516 _printf("\n[GIET_ERROR] in _sys_nic_stats() : " 2517 "illegal NIC channel for thread %x\n", trdid ); 2518 return -1111; 1707 2519 } 1708 2520 … … 1759 2571 broadcast ); 1760 2572 } 1761 return 0;2573 return GIET_SYSCALL_OK; 1762 2574 } // end _sys_nic_stats() 2575 2576 #endif 1763 2577 1764 2578 ///////////////////////////////////////////////////////////////////////////////////////// … … 1774 2588 memcpy( fbf_address, buffer, length); 1775 2589 1776 return 0;2590 return GIET_SYSCALL_OK; 1777 2591 } 1778 2592 … … 1785 2599 memcpy( buffer, fbf_address, length); 1786 2600 1787 return 0;2601 return GIET_SYSCALL_OK; 1788 2602 } 1789 2603 … … 1791 2605 int _sys_fbf_cma_alloc() 1792 2606 { 2607 unsigned int trdid = _get_thread_trdid(); 2608 1793 2609 if ( _get_context_slot( CTX_CMA_FB_ID ) < NB_CMA_CHANNELS ) 1794 2610 { 1795 _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : CMA channel already allocated\n"); 1796 return 0; 1797 } 1798 1799 // get a new CMA channel index 2611 _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : " 2612 "CMA channel already allocated for thread %x\n", trdid ); 2613 return GIET_SYSCALL_OK; 2614 } 2615 2616 // get a CMA channel 1800 2617 unsigned int channel; 1801 1802 2618 for ( channel = 0 ; channel < NB_CMA_CHANNELS ; channel++ ) 1803 2619 { 1804 if ( !_cma_channel[channel] ) 1805 { 1806 _cma_channel[channel] = 1; 1807 break; 1808 } 1809 } 1810 2620 unsigned int* palloc = &_cma_channel_alloc[channel]; 2621 if ( _atomic_test_and_set( palloc , 1 ) == 0 ) break; 2622 } 1811 2623 if ( channel >= NB_CMA_CHANNELS ) 1812 2624 { 1813 2625 _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : no CMA channel available\n"); 1814 return -1 ;2626 return -1111; 1815 2627 } 1816 2628 else 1817 2629 { 1818 2630 _set_context_slot( CTX_CMA_FB_ID, channel ); 1819 return 0;2631 return GIET_SYSCALL_OK; 1820 2632 } 1821 2633 } // end sys_fbf_cma_alloc() 1822 2634 1823 //////////////////////// 1824 // NOTE: not a syscall 1825 int _sys_fbf_cma_release() 2635 ////////////////////////// 2636 int _sys_fbf_cma_release() // Not a syscall 1826 2637 { 1827 2638 unsigned int channel = _get_context_slot( CTX_CMA_FB_ID ); 2639 unsigned int trdid = _get_thread_trdid(); 1828 2640 1829 2641 if ( channel >= NB_CMA_CHANNELS ) 1830 2642 { 1831 _printf("\n[GIET_ERROR] in _sys_fbf_cma_release() : CMA channel already released\n"); 1832 return -1; 1833 } 1834 1835 // stop fb 2643 _printf("\n[GIET_ERROR] in _sys_fbf_cma_release() : " 2644 "CMA_FB channel already releasedifor thread %x\n", trdid ); 2645 return -1111; 2646 } 2647 2648 // stop CMA transfer 1836 2649 _sys_fbf_cma_stop(); 1837 2650 1838 // reset CTX_CMA_FB_ID for t ask1839 _set_context_slot( CTX_CMA_FB_ID, -1);2651 // reset CTX_CMA_FB_ID for thread 2652 _set_context_slot( CTX_CMA_FB_ID, 0xFFFFFFFF ); 1840 2653 1841 2654 // release CMA channel 1842 _cma_channel [channel] = 0;1843 1844 return 0;2655 _cma_channel_alloc[channel] = 0; 2656 2657 return GIET_SYSCALL_OK; 1845 2658 } 1846 2659 … … 1868 2681 { 1869 2682 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : CMA channel index too large\n"); 1870 return -1 ;2683 return -1111; 1871 2684 } 1872 2685 … … 1890 2703 { 1891 2704 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : user buffer not aligned\n"); 1892 return -1 ;2705 return -1111; 1893 2706 } 1894 2707 … … 1898 2711 { 1899 2712 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : user status not aligned\n"); 1900 return -1 ;2713 return -1111; 1901 2714 } 1902 2715 … … 1917 2730 { 1918 2731 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : buf0 not in user space\n"); 1919 return -1 ;2732 return -1111; 1920 2733 } 1921 2734 … … 1925 2738 { 1926 2739 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : sts0 not in user space\n"); 1927 return -1 ;2740 return -1111; 1928 2741 } 1929 2742 … … 1938 2751 { 1939 2752 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : buf1 not in user space\n"); 1940 return -1 ;2753 return -1111; 1941 2754 } 1942 2755 … … 1946 2759 { 1947 2760 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : sts1 not in user space\n"); 1948 return -1 ;2761 return -1111; 1949 2762 } 1950 2763 … … 1974 2787 #endif 1975 2788 1976 return 0;2789 return GIET_SYSCALL_OK; 1977 2790 1978 2791 #else 1979 2792 1980 2793 _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : NB_CMA_CHANNELS = 0\n"); 1981 return -1 ;2794 return -1111; 1982 2795 1983 2796 #endif … … 1995 2808 { 1996 2809 _printf("\n[GIET ERROR] in _fbf_cma_start() : CMA channel index too large\n"); 1997 return -1 ;2810 return -1111; 1998 2811 } 1999 2812 … … 2005 2818 _printf("\n[GIET ERROR] in _sys_fbf_cma_start() :\n" 2006 2819 "Buffer initialization has not been done\n"); 2007 return -1 ;2820 return -1111; 2008 2821 } 2009 2822 … … 2034 2847 _cma_set_register( channel, CHBUF_RUN , 1 ); 2035 2848 2036 return 0;2849 return GIET_SYSCALL_OK; 2037 2850 2038 2851 #else 2039 2852 2040 2853 _printf("\n[GIET ERROR] in _sys_fbf_cma_start() : NB_CMA_CHANNELS = 0\n"); 2041 return -1 ;2854 return -1111; 2042 2855 2043 2856 #endif … … 2058 2871 _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : " 2059 2872 "CMA channel index too large\n"); 2060 return -1 ;2873 return -1111; 2061 2874 } 2062 2875 … … 2138 2951 _mmc_sync( fbf_sts_paddr, 4 ); 2139 2952 2140 return 0;2953 return GIET_SYSCALL_OK; 2141 2954 2142 2955 #else 2143 2956 2144 2957 _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : no CMA channel allocated\n"); 2145 return -1 ;2958 return -1111; 2146 2959 2147 2960 #endif … … 2159 2972 { 2160 2973 _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : CMA channel index too large\n"); 2161 return -1 ;2974 return -1111; 2162 2975 } 2163 2976 … … 2165 2978 _cma_set_register( channel, CHBUF_RUN, 0 ); 2166 2979 2167 return 0;2980 return GIET_SYSCALL_OK; 2168 2981 2169 2982 #else 2170 2983 2171 2984 _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : no CMA channel allocated\n"); 2172 return -1 ;2985 return -1111; 2173 2986 2174 2987 #endif … … 2184 2997 { 2185 2998 _printf("\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() ); 2186 return -1;2999 return GIET_SYSCALL_UNDEFINED_SYSTEM_CALL; 2187 3000 } 2188 3001 … … 2198 3011 *p = gpid & ((1<<P_WIDTH)-1); 2199 3012 2200 return 0; 2201 } 2202 2203 ////////////////////////////////// 2204 int _sys_task_exit( char* string ) 2205 { 2206 unsigned int date = _get_proctime(); 2207 2208 unsigned int gpid = _get_procid(); 2209 unsigned int cluster_xy = gpid >> P_WIDTH; 2210 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 2211 unsigned int x = cluster_xy >> Y_WIDTH; 2212 unsigned int p = gpid & ((1<<P_WIDTH)-1); 2213 2214 unsigned int ltid = _get_context_slot(CTX_LTID_ID); 2215 2216 // print exit message 2217 _printf("\n[GIET] Exit task %d on processor[%d,%d,%d] at cycle %d" 2218 "\n Cause : %s\n\n", 2219 ltid, x, y, p, date, string ); 2220 2221 // set NORUN_MASK_TASK bit (non runnable state) 2222 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p]; 2223 unsigned int* ptr = &psched->context[ltid][CTX_NORUN_ID]; 2224 _atomic_or( ptr , NORUN_MASK_TASK ); 2225 2226 // deschedule 2227 _sys_context_switch(); 2228 2229 return 0; 2230 } 2231 2232 ///////////////////////// 2233 int _sys_context_switch() 2234 { 2235 unsigned int save_sr; 2236 2237 _it_disable( &save_sr ); 2238 _ctx_switch(); 2239 _it_restore( &save_sr ); 2240 2241 return 0; 2242 } 2243 2244 //////////////////////// 2245 int _sys_local_task_id() 2246 { 2247 return _get_context_slot(CTX_LTID_ID); 2248 } 2249 2250 ///////////////////////// 2251 int _sys_global_task_id() 2252 { 2253 return _get_context_slot(CTX_GTID_ID); 2254 } 2255 2256 //////////////////// 2257 int _sys_thread_id() 2258 { 2259 return _get_context_slot(CTX_TRDID_ID); 3013 return GIET_SYSCALL_OK; 2260 3014 } 2261 3015 … … 2312 3066 *nprocs = 0; 2313 3067 } 2314 return 0;3068 return GIET_SYSCALL_OK; 2315 3069 } 2316 3070 … … 2340 3094 { 2341 3095 *vbase = vseg[vseg_id].vbase; 2342 return 0;3096 return GIET_SYSCALL_OK; 2343 3097 } 2344 3098 } 2345 3099 } 2346 3100 } 2347 return -1; // not found3101 return GIET_SYSCALL_VSEG_NOT_FOUND; 2348 3102 } 2349 3103 … … 2373 3127 { 2374 3128 *length = vseg[vseg_id].length; 2375 return 0;3129 return GIET_SYSCALL_OK; 2376 3130 } 2377 3131 } 2378 3132 } 2379 3133 } 2380 return -1; // not found3134 return GIET_SYSCALL_VSEG_NOT_FOUND; 2381 3135 } 2382 3136 … … 2392 3146 *y = (paddr>>32) & 0xF; 2393 3147 2394 return 0;3148 return GIET_SYSCALL_OK; 2395 3149 } 2396 3150 … … 2401 3155 unsigned int y ) 2402 3156 { 3157 // checking parameters 3158 if ( (x >= X_SIZE) || (y >= Y_SIZE) ) 3159 { 3160 *vaddr = 0; 3161 *length = 0; 3162 _printf("\n[GIET ERROR] in _sys_heap_info() : " 3163 "illegal (%d,%d) coordinates\n", x , y ); 3164 return GIET_SYSCALL_ILLEGAL_CLUSTER_COORDINATES; 3165 } 3166 2403 3167 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 2404 mapping_t ask_t * task = _get_task_base(header);3168 mapping_thread_t * thread = _get_thread_base(header); 2405 3169 mapping_vseg_t * vseg = _get_vseg_base(header); 2406 3170 mapping_vspace_t * vspace = _get_vspace_base(header); 2407 3171 2408 unsigned int t ask_id;3172 unsigned int thread_id; 2409 3173 unsigned int vspace_id; 2410 3174 unsigned int vseg_id = 0xFFFFFFFF; 2411 3175 2412 // searching the heap vseg 2413 if ( (x < X_SIZE) && (y < Y_SIZE) ) // searching a task in cluster(x,y) 2414 { 2415 // get vspace global index 2416 vspace_id = _get_context_slot(CTX_VSID_ID); 2417 2418 // scan all tasks in vspace 2419 unsigned int min = vspace[vspace_id].task_offset ; 2420 unsigned int max = min + vspace[vspace_id].tasks ; 2421 for ( task_id = min ; task_id < max ; task_id++ ) 3176 // get calling thread vspace index 3177 vspace_id = _get_context_slot(CTX_VSID_ID); 3178 3179 // scan all threads in vspace to find one in clyster[x,y] 3180 unsigned int min = vspace[vspace_id].thread_offset ; 3181 unsigned int max = min + vspace[vspace_id].threads ; 3182 for ( thread_id = min ; thread_id < max ; thread_id++ ) 3183 { 3184 if ( thread[thread_id].clusterid == (x * Y_SIZE + y) ) 2422 3185 { 2423 if ( task[task_id].clusterid == (x * Y_SIZE + y) ) 2424 { 2425 vseg_id = task[task_id].heap_vseg_id; 2426 if ( vseg_id != 0xFFFFFFFF ) break; 2427 } 3186 vseg_id = thread[thread_id].heap_vseg_id; 3187 break; 2428 3188 } 2429 }2430 else // searching in the calling task2431 {2432 task_id = _get_context_slot(CTX_GTID_ID);2433 vseg_id = task[task_id].heap_vseg_id;2434 3189 } 2435 3190 … … 2439 3194 *vaddr = vseg[vseg_id].vbase; 2440 3195 *length = vseg[vseg_id].length; 2441 return 0;2442 3196 } 2443 3197 else … … 2445 3199 *vaddr = 0; 2446 3200 *length = 0; 2447 return -1; 2448 } 3201 _printf("error in _sys_heap_info() : no heap in cluster (%d,%d)\n", x , y ); 3202 } 3203 return GIET_SYSCALL_OK; 2449 3204 } // end _sys_heap_info() 2450 2451 2452 ///////////////////////2453 int _sys_tasks_status()2454 {2455 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;2456 mapping_task_t * task = _get_task_base(header);2457 mapping_vspace_t * vspace = _get_vspace_base(header);2458 mapping_cluster_t * cluster = _get_cluster_base(header);2459 2460 unsigned int task_id;2461 unsigned int vspace_id;2462 2463 // scan all vspaces2464 for( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )2465 {2466 _printf("\n*** vspace %s\n", vspace[vspace_id].name );2467 2468 // scan all tasks in vspace2469 unsigned int min = vspace[vspace_id].task_offset ;2470 unsigned int max = min + vspace[vspace_id].tasks ;2471 for ( task_id = min ; task_id < max ; task_id++ )2472 {2473 unsigned int clusterid = task[task_id].clusterid;2474 unsigned int p = task[task_id].proclocid;2475 unsigned int x = cluster[clusterid].x;2476 unsigned int y = cluster[clusterid].y;2477 unsigned int ltid = task[task_id].ltid;2478 static_scheduler_t* psched = (static_scheduler_t*)_schedulers[x][y][p];2479 unsigned int norun = psched->context[ltid][CTX_NORUN_ID];2480 unsigned int current = psched->current;2481 2482 if ( current == ltid )2483 _printf(" - task %s on P[%d,%d,%d] : running\n", task[task_id].name, x, y, p );2484 else if ( norun == 0 )2485 _printf(" - task %s on P[%d,%d,%d] : runable\n", task[task_id].name, x, y, p );2486 else2487 _printf(" - task %s on P[%d,%d,%d] : blocked\n", task[task_id].name, x, y, p );2488 }2489 }2490 return 0;2491 } // end _sys_tasks_status()2492 2493 int _sys_fat_read( unsigned int fd_id,2494 unsigned int buffer,2495 unsigned int count )2496 {2497 return _fat_read(fd_id, buffer, count, 0);2498 }2499 2500 3205 2501 3206
Note: See TracChangeset
for help on using the changeset viewer.