Changeset 440 for soft/giet_vm/giet_kernel/sys_handler.c
- Timestamp:
- Nov 3, 2014, 11:03:55 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_kernel/sys_handler.c
r428 r440 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The sys_handler.c and sys_handler.h files are part of the GIET-VM nano-kernel.8 // It define the syscall_vector[] (at the end of this file), as well as the9 // associated syscall handlers that are not related to peripherals.10 // The syscall handlers for peripherals are defined in the drivers.c file.11 ///////////////////////////////////////////////////////////////////////////////////12 7 13 8 #include <sys_handler.h> … … 16 11 #include <ioc_driver.h> 17 12 #include <nic_driver.h> 18 #include <fbf_driver.h> 13 #include <mmc_driver.h> 14 #include <cma_driver.h> 19 15 #include <ctx_handler.h> 20 16 #include <fat32.h> 21 17 #include <utils.h> 18 #include <kernel_utils.h> 22 19 #include <vmem.h> 23 20 #include <hard_config.h> … … 28 25 # error: You must define SEG_BOOT_MAPPING_BASE in the hard_config.h file 29 26 #endif 27 28 //////////////////////////////////////////////////////////////////////////// 29 // Channel allocators for peripherals 30 // (TTY[0] is reserved for kernel) 31 //////////////////////////////////////////////////////////////////////////// 32 33 unsigned int _tty_channel_allocator = 1; 34 unsigned int _tim_channel_allocator = 0; 35 unsigned int _cma_channel_allocator = 0; 36 unsigned int _nic_channel_allocator = 0; 30 37 31 38 //////////////////////////////////////////////////////////////////////////// … … 35 42 const void * _syscall_vector[64] = 36 43 { 37 &_ proc_xyp,/* 0x00 */38 &_get_proctime, /* 0x01 */39 &_ tty_write,/* 0x02 */40 &_ tty_read,/* 0x03 */41 &_ timer_start,/* 0x04 */42 &_ timer_stop,/* 0x05 */43 &_ tty_get_lock,/* 0x06 */44 &_ tty_release_lock,/* 0x07 */45 &_ heap_info,/* 0x08 */46 &_ local_task_id, /* 0x09 */47 &_ global_task_id, /* 0x0A */48 &_ fb_cma_init,/* 0x0B */49 &_ fb_cma_write,/* 0x0C */50 &_ fb_cma_stop,/* 0x0D */51 &_ task_exit,/* 0x0E */52 &_ procs_number,/* 0x0F */53 54 &_ fb_sync_write,/* 0x10 */55 &_ fb_sync_read,/* 0x11 */56 &_ thread_id,/* 0x12 */57 &_sys_ukn, /* 0x13 */58 &_sys_ ukn,/* 0x14 */59 &_sys_ ukn,/* 0x15 */60 &_sys_ ukn,/* 0x16 */61 &_sys_ukn, /* 0x17 */62 &_sys_ukn, /* 0x18 */63 &_context_switch, /* 0x19 */64 &_ vobj_get_vbase,/* 0x1A */65 &_ get_xy_from_ptr,/* 0x1B */66 &_ nic_cma_start,/* 0x1C */67 &_ nic_cma_stop, /* 0x1D */68 &_ nic_sync_read,/* 0x1E */69 &_ nic_sync_write,/* 0x1F */70 71 &_fat_user_open, /* 0x20 */72 &_fat_user_read, /* 0x21 */73 &_fat_user_write, /* 0x22 */74 &_fat_user_lseek, /* 0x23 */75 &_fat_fstat, /* 0x24 */76 &_fat_close, /* 0x25 */77 &_sys_ukn, /* 0x26 */78 &_sys_ukn, /* 0x27 */79 &_sys_ukn, /* 0x28 */80 &_sys_ukn, /* 0x29 */81 &_sys_ukn, /* 0x2A */82 &_sys_ukn, /* 0x2B */83 &_sys_ukn, /* 0x2C */84 &_sys_ukn, /* 0x2D */85 &_sys_ukn, /* 0x2E */86 &_sys_ukn, /* 0x2F */87 88 &_sys_ukn, /* 0x30 */89 &_sys_ukn, /* 0x31 */90 &_sys_ukn, /* 0x32 */91 &_sys_ukn, /* 0x33 */92 &_sys_ukn, /* 0x34 */93 &_sys_ukn, /* 0x35 */94 &_sys_ukn, /* 0x36 */95 &_sys_ukn, /* 0x37 */96 &_sys_ukn, /* 0x38 */97 &_sys_ukn, /* 0x39 */98 &_sys_ukn, /* 0x3A */99 &_sys_ukn, /* 0x3B */100 &_sys_ukn, /* 0x3C */101 &_sys_ukn, /* 0x3D */102 &_sys_ukn, /* 0x3E */103 &_sys_ukn, /* 0x3F */44 &_sys_proc_xyp, /* 0x00 */ 45 &_get_proctime, /* 0x01 */ 46 &_sys_tty_write, /* 0x02 */ 47 &_sys_tty_read, /* 0x03 */ 48 &_sys_tty_alloc, /* 0x04 */ 49 &_sys_tty_get_lock, /* 0x05 */ 50 &_sys_tty_release_lock, /* 0x06 */ 51 &_sys_heap_info, /* 0x07 */ 52 &_sys_local_task_id, /* 0x08 */ 53 &_sys_global_task_id, /* 0x09 */ 54 &_sys_fbf_cma_alloc, /* 0x0A */ 55 &_sys_fbf_cma_start, /* 0x0B */ 56 &_sys_fbf_cma_display, /* 0x0C */ 57 &_sys_fbf_cma_stop, /* 0x0D */ 58 &_sys_task_exit, /* 0x0E */ 59 &_sys_procs_number, /* 0x0F */ 60 61 &_sys_fbf_sync_write, /* 0x10 */ 62 &_sys_fbf_sync_read, /* 0x11 */ 63 &_sys_thread_id, /* 0x12 */ 64 &_sys_ukn, /* 0x13 */ 65 &_sys_tim_alloc, /* 0x14 */ 66 &_sys_tim_start, /* 0x15 */ 67 &_sys_tim_stop, /* 0x16 */ 68 &_sys_ukn, /* 0x17 */ 69 &_sys_ukn, /* 0x18 */ 70 &_context_switch, /* 0x19 */ 71 &_sys_vobj_get_vbase, /* 0x1A */ 72 &_sys_vobj_get_length, /* 0x1B */ 73 &_sys_xy_from_ptr, /* 0x1C */ 74 &_sys_nic_alloc, /* 0x1D */ 75 &_sys_nic_sync_send, /* 0x1E */ 76 &_sys_nic_sync_receive, /* 0x1F */ 77 78 &_fat_user_open, /* 0x20 */ 79 &_fat_user_read, /* 0x21 */ 80 &_fat_user_write, /* 0x22 */ 81 &_fat_user_lseek, /* 0x23 */ 82 &_fat_fstat, /* 0x24 */ 83 &_fat_close, /* 0x25 */ 84 &_sys_ukn, /* 0x26 */ 85 &_sys_ukn, /* 0x27 */ 86 &_sys_ukn, /* 0x28 */ 87 &_sys_ukn, /* 0x29 */ 88 &_sys_ukn, /* 0x2A */ 89 &_sys_ukn, /* 0x2B */ 90 &_sys_ukn, /* 0x2C */ 91 &_sys_ukn, /* 0x2D */ 92 &_sys_ukn, /* 0x2E */ 93 &_sys_ukn, /* 0x2F */ 94 95 &_sys_ukn, /* 0x30 */ 96 &_sys_ukn, /* 0x31 */ 97 &_sys_ukn, /* 0x32 */ 98 &_sys_ukn, /* 0x33 */ 99 &_sys_ukn, /* 0x34 */ 100 &_sys_ukn, /* 0x35 */ 101 &_sys_ukn, /* 0x36 */ 102 &_sys_ukn, /* 0x37 */ 103 &_sys_ukn, /* 0x38 */ 104 &_sys_ukn, /* 0x39 */ 105 &_sys_ukn, /* 0x3A */ 106 &_sys_ukn, /* 0x3B */ 107 &_sys_ukn, /* 0x3C */ 108 &_sys_ukn, /* 0x3D */ 109 &_sys_ukn, /* 0x3E */ 110 &_sys_ukn, /* 0x3F */ 104 111 }; 105 112 106 113 ////////////////////////////////////////////////////////////////////////////// 107 // function executed in case of undefined syscall114 // TTY related syscall handlers 108 115 ////////////////////////////////////////////////////////////////////////////// 109 void _sys_ukn() 110 { 111 _printf("\n\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() ); 112 _exit(); 116 117 //////////////////// 118 int _sys_tty_alloc() 119 { 120 // get a new TTY terminal index 121 unsigned int channel = _tty_channel_allocator; 122 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 123 unsigned int vspace = _get_context_slot( CTX_VSID_ID ); 124 125 if ( channel >= NB_TTY_CHANNELS ) 126 { 127 _printf("\n[GIET_ERROR] in _sys_tty_alloc() : not enough TTY channels\n"); 128 return -1; 129 } 130 else 131 { 132 _printf("\n[GIET WARNING] TTY channel %d allocated " 133 " to thread %d in vspace %d\n", channel, thread, vspace ); 134 } 135 136 // register timer index in task context 137 _set_context_slot( CTX_TTY_ID, _tty_channel_allocator ); 138 139 // update timer allocator 140 _tty_channel_allocator++; 141 142 return 0; 143 } 144 145 ///////////////////////////////////////////////// 146 int _sys_tty_write( const char* buffer, 147 unsigned int length, // number of characters 148 unsigned int channel) // channel index 149 { 150 unsigned int nwritten; 151 152 // compute and check tty channel 153 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 154 if( channel >= NB_TTY_CHANNELS ) return -1; 155 156 // write string to TTY channel 157 for (nwritten = 0; nwritten < length; nwritten++) 158 { 159 // check tty's status 160 if ( _tty_get_register( channel, TTY_STATUS ) & 0x2 ) break; 161 162 // write one byte 163 if (buffer[nwritten] == '\n') 164 { 165 _tty_set_register( channel, TTY_WRITE, (unsigned int)'\r' ); 166 } 167 _tty_set_register( channel, TTY_WRITE, (unsigned int)buffer[nwritten] ); 168 } 169 170 return nwritten; 171 } 172 173 //////////////////////////////////////////////// 174 int _sys_tty_read( char* buffer, 175 unsigned int length, // unused 176 unsigned int channel) // channel index 177 { 178 // compute and check tty channel 179 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 180 if( channel >= NB_TTY_CHANNELS ) return -1; 181 182 // read one character from TTY channel 183 if (_tty_rx_full[channel] == 0) 184 { 185 return 0; 186 } 187 else 188 { 189 *buffer = _tty_rx_buf[channel]; 190 _tty_rx_full[channel] = 0; 191 return 1; 192 } 193 } 194 195 /////////////////////////////////////////// 196 int _sys_tty_get_lock( unsigned int channel, 197 unsigned int * save_sr_ptr ) 198 { 199 // compute and check tty channel 200 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 201 if( channel >= NB_TTY_CHANNELS ) return -1; 202 203 _it_disable( save_sr_ptr ); 204 _get_lock( &_tty_lock[channel] ); 205 return 0; 206 } 207 208 /////////////////////////////////////////////// 209 int _sys_tty_release_lock( unsigned int channel, 210 unsigned int * save_sr_ptr ) 211 { 212 // compute and check tty channel 213 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 214 if( channel >= NB_TTY_CHANNELS ) return -1; 215 216 _release_lock( &_tty_lock[channel] ); 217 _it_restore( save_sr_ptr ); 218 return 0; 113 219 } 114 220 115 221 ////////////////////////////////////////////////////////////////////////////// 116 // This function returns the processor (x,y,p) identifiers.222 // TIM related syscall handlers 117 223 ////////////////////////////////////////////////////////////////////////////// 118 void _proc_xyp( unsigned int* x, 119 unsigned int* y, 120 unsigned int* p ) 224 225 //////////////////// 226 int _sys_tim_alloc() 227 { 228 // get a new timer index 229 unsigned int channel = _tim_channel_allocator; 230 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 231 unsigned int vspace = _get_context_slot( CTX_VSID_ID ); 232 233 if ( channel >= NB_TIM_CHANNELS ) 234 { 235 _printf("\n[GIET_ERROR] in _sys_tim_alloc() : not enough TIM channels\n"); 236 return -1; 237 } 238 else 239 { 240 _printf("\n[GIET WARNING] TIM channel %d allocated " 241 " to thread %d in vspace %d\n", channel, thread, vspace ); 242 } 243 244 // register timer index in task context 245 _set_context_slot( CTX_TIM_ID, channel ); 246 247 // update timer allocator 248 _tim_channel_allocator++; 249 250 return 0; 251 } 252 253 ///////////////////////////////////////// 254 int _sys_tim_start( unsigned int period ) 255 { 256 // get timer index 257 unsigned int channel = _get_context_slot( CTX_TIM_ID ); 258 if ( channel >= NB_TIM_CHANNELS ) 259 { 260 _printf("\n[GIET_ERROR] in _sys_tim_start() : not enough TIM channels\n"); 261 return -1; 262 } 263 264 // start timer 265 _timer_start( channel, period ); 266 267 return 0; 268 } 269 270 /////////////////// 271 int _sys_tim_stop() 272 { 273 // get timer index 274 unsigned int channel = _get_context_slot( CTX_TIM_ID ); 275 if ( channel >= NB_TIM_CHANNELS ) 276 { 277 _printf("\n[GIET_ERROR] in _sys_tim_stop() : illegal timer index\n"); 278 return -1; 279 } 280 281 // stop timer 282 _timer_stop( channel ); 283 284 return 0; 285 } 286 287 ////////////////////////////////////////////////////////////////////////////// 288 // NIC related syscall handlers 289 ////////////////////////////////////////////////////////////////////////////// 290 291 //////////////////// 292 int _sys_nic_alloc() 293 { 294 // get a new NIC channel index 295 unsigned int channel = _nic_channel_allocator; 296 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 297 unsigned int vspace = _get_context_slot( CTX_VSID_ID ); 298 299 if ( channel >= NB_NIC_CHANNELS ) 300 { 301 _printf("\n[GIET_ERROR] in _sys_nic_alloc() : not enough NIC channels\n"); 302 return -1; 303 } 304 else 305 { 306 _printf("\n[GIET WARNING] NIC channel %d allocated " 307 " to thread %d in vspace %d\n", channel, thread, vspace ); 308 } 309 310 // register channel index in task context 311 _set_context_slot( CTX_NIC_ID, channel ); 312 313 // update NIC channel allocator 314 _nic_channel_allocator++; 315 316 return 0; 317 } 318 319 //////////////////////////////////// 320 int _sys_nic_sync_send( void* vbuf ) 321 { 322 unsigned int ppn; 323 unsigned int flags; 324 unsigned int vaddr = (unsigned int)vbuf; 325 326 // get NIC channel index 327 unsigned int channel = _get_context_slot( CTX_NIC_ID ); 328 if ( channel >= NB_NIC_CHANNELS ) 329 { 330 _printf("\n[GIET_ERROR] in _sys_nic_sync_send() : illegal NIC channel index\n"); 331 return -1; 332 } 333 334 // get page table pointer 335 unsigned int user_ptab = _get_context_slot( CTX_PTAB_ID ); 336 337 // Compute user buffer physical address and check access rights 338 unsigned int ko = _v2p_translate( (page_table_t*)user_ptab, 339 vaddr, 340 &ppn, 341 &flags ); 342 if ( ko ) 343 { 344 _printf("\n[GIET ERROR] in _sys_nic_sync_send() : user buffer unmapped\n"); 345 return -1; 346 } 347 if ( (flags & PTE_U) == 0 ) 348 { 349 _printf("\n[GIET ERROR] in _sys_nic_sync_send() : illegal buffer address\n"); 350 return -1; 351 } 352 unsigned long long pbuf = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF); 353 354 _nic_sync_send( channel, pbuf ); 355 356 return 0; 357 } 358 359 /////////////////////////////////////// 360 int _sys_nic_sync_receive( void* vbuf ) 361 { 362 unsigned int ppn; 363 unsigned int flags; 364 unsigned int vaddr = (unsigned int)vbuf; 365 366 // get NIC channel index 367 unsigned int channel = _get_context_slot( CTX_NIC_ID ); 368 if ( channel >= NB_NIC_CHANNELS ) 369 { 370 _printf("\n[GIET_ERROR] in _sys_nic_sync_send() : illegal NIC channel index\n"); 371 return -1; 372 } 373 374 // get page table pointer 375 unsigned int user_ptab = _get_context_slot( CTX_PTAB_ID ); 376 377 // Compute user buffer physical address and check access rights 378 unsigned int ko = _v2p_translate( (page_table_t*)user_ptab, 379 vaddr, 380 &ppn, 381 &flags ); 382 if ( ko ) 383 { 384 _printf("\n[GIET ERROR] in _sys_nic_sync_send() : user buffer unmapped\n"); 385 return -1; 386 } 387 if ( (flags & PTE_U) == 0 ) 388 { 389 _printf("\n[GIET ERROR] in _sys_nic_sync_send() : illegal buffer address\n"); 390 return -1; 391 } 392 unsigned long long pbuf = ((unsigned long long)ppn << 12) | (vaddr & 0x00000FFF); 393 394 _nic_sync_receive( channel, pbuf ); 395 396 return 0; 397 } 398 399 ///////////////////////////////////////////////////////////////////////////////////////// 400 // FBF related syscall handlers 401 ///////////////////////////////////////////////////////////////////////////////////////// 402 403 // Array of fbf_chbuf descriptors, indexed by the CMA channel index. 404 __attribute__((section (".unckdata"))) 405 volatile fbf_chbuf_t _fbf_chbuf[NB_CMA_CHANNELS] __attribute__((aligned(32))); 406 407 // Physical addresses of these fbf_chbuf descriptors (required for L2 cache sync) 408 __attribute__((section (".unckdata"))) 409 unsigned long long _fbf_chbuf_paddr[NB_CMA_CHANNELS]; 410 411 ///////////////////////////////////////////// 412 int _sys_fbf_sync_write( unsigned int offset, 413 void* buffer, 414 unsigned int length ) 415 { 416 char* fbf_address = (char *)SEG_FBF_BASE + offset; 417 memcpy( fbf_address, buffer, length); 418 419 return 0; 420 } 421 422 ///////////////////////////////////////////// 423 int _sys_fbf_sync_read( unsigned int offset, 424 void* buffer, 425 unsigned int length ) 426 { 427 char* fbf_address = (char *)SEG_FBF_BASE + offset; 428 memcpy( buffer, fbf_address, length); 429 430 return 0; 431 } 432 433 //////////////////////// 434 int _sys_fbf_cma_alloc() 435 { 436 #if NB_CMA_CHANNELS > 0 437 438 // get a new CMA channel index 439 unsigned int channel = _cma_channel_allocator; 440 unsigned int thread = _get_context_slot( CTX_TRDID_ID ); 441 unsigned int vspace = _get_context_slot( CTX_VSID_ID ); 442 443 if ( channel >= NB_CMA_CHANNELS ) 444 { 445 _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : not enough CMA channels\n"); 446 return -1; 447 } 448 else 449 { 450 _printf("\n[GIET WARNING] FBF_CMA channel %d allocated " 451 " to thread %d in vspace %d\n", channel, thread, vspace ); 452 } 453 454 // register channel index in task context 455 _set_context_slot( CTX_FBCMA_ID, channel ); 456 457 // update CMA channel allocator 458 _cma_channel_allocator++; 459 460 return 0; 461 462 #else 463 464 _printf("\n[GIET ERROR] in _fb_cma_start() : NB_CMA_CHANNELS = 0\n"); 465 return -1; 466 467 #endif 468 } // end sys_fbf_cma_alloc() 469 470 //////////////////////////////////////////// 471 int _sys_fbf_cma_start( void* vbase0, 472 void* vbase1, 473 unsigned int length ) 474 { 475 #if NB_CMA_CHANNELS > 0 476 477 unsigned int ptab; // page table virtual address 478 unsigned int ko; // unsuccessfull V2P translation 479 unsigned int vaddr; // virtual address 480 unsigned int flags; // protection flags 481 unsigned int ppn; // physical page number 482 unsigned long long chbuf_paddr; // physical address of source chbuf descriptor 483 484 // get channel index 485 unsigned int channel = _get_context_slot( CTX_FBCMA_ID ); 486 487 if ( channel >= NB_CMA_CHANNELS ) 488 { 489 _printf("\n[GIET ERROR] in _fbf_cma_start() : CMA channel index too large\n"); 490 return -1; 491 } 492 493 #if GIET_DEBUG_FBF_CMA 494 _printf("\n[FBF_CMA DEBUG] enters _sys_fbf_cma_start()\n" 495 " - channel = %d\n" 496 " - buf0 vbase = %x\n" 497 " - buf1 vbase = %x\n" 498 " - buffer size = %x\n", 499 channel, 500 (unsigned int)vbase0, 501 (unsigned int)vbase1, 502 length ); 503 #endif 504 505 // checking user buffers virtual addresses and length alignment 506 if ( ((unsigned int)vbase0 & 0x3) || ((unsigned int)vbase1 & 0x3) || (length & 0x3) ) 507 { 508 _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer not word aligned\n"); 509 return -1; 510 } 511 512 // get page table virtual address 513 ptab = _get_context_slot(CTX_PTAB_ID); 514 515 // compute frame buffer physical address and initialize _fbf_chbuf[channel] 516 vaddr = ((unsigned int)SEG_FBF_BASE); 517 ko = _v2p_translate( (page_table_t*) ptab, 518 (vaddr >> 12), 519 &ppn, 520 &flags ); 521 if (ko) 522 { 523 _printf("\n[GIET ERROR] in _fb_cma_start() : frame buffer unmapped\n"); 524 return -1; 525 } 526 527 _fbf_chbuf[channel].fbf = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF); 528 529 // Compute user buffer 0 physical addresses and intialize _fbf_chbuf[channel] 530 vaddr = (unsigned int)vbase0; 531 ko = _v2p_translate( (page_table_t*) ptab, 532 (vaddr >> 12), 533 &ppn, 534 &flags ); 535 if (ko) 536 { 537 _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 0 unmapped\n"); 538 return -1; 539 } 540 if ((flags & PTE_U) == 0) 541 { 542 _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 0 not in user space\n"); 543 return -1; 544 } 545 546 _fbf_chbuf[channel].buf0 = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF); 547 548 // Compute user buffer 1 physical addresses and intialize _fbf_chbuf[channel] 549 vaddr = (unsigned int)vbase1; 550 ko = _v2p_translate( (page_table_t*) ptab, 551 (vaddr >> 12), 552 &ppn, 553 &flags ); 554 if (ko) 555 { 556 _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 1 unmapped\n"); 557 return -1; 558 } 559 if ((flags & PTE_U) == 0) 560 { 561 _printf("\n[GIET ERROR] in _fbf_cma_start() : user buffer 1 not in user space\n"); 562 return -1; 563 } 564 565 _fbf_chbuf[channel].buf1 = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF); 566 567 // initializes buffer length 568 _fbf_chbuf[channel].length = length; 569 570 // Compute and register physical adress of the chbuf descriptor 571 vaddr = (unsigned int)(&_fbf_chbuf[channel]); 572 ko = _v2p_translate( (page_table_t*) ptab, 573 (vaddr >> 12), 574 &ppn, 575 &flags ); 576 if (ko) 577 { 578 _printf("\n[GIET ERROR] in _fbf_cma_start() : chbuf descriptor unmapped\n"); 579 return -1; 580 } 581 582 chbuf_paddr = (((paddr_t)ppn) << 12) | (vaddr & 0x00000FFF); 583 584 _fbf_chbuf_paddr[channel] = chbuf_paddr; 585 586 587 if ( USE_IOB ) 588 { 589 // SYNC request for channel descriptor 590 _mmc_sync( chbuf_paddr, 32 ); 591 } 592 593 #if GIET_DEBUG_FBF_CMA 594 _printf(" - fbf pbase = %l\n" 595 " - buf0 pbase = %l\n" 596 " - buf1 pbase = %l\n" 597 " - chbuf pbase = %l\n", 598 _fbf_chbuf[channel].fbf, 599 _fbf_chbuf[channel].buf0, 600 _fbf_chbuf[channel].buf1, 601 chbuf_paddr ); 602 #endif 603 604 // call CMA driver to start transfer 605 _cma_start_channel( channel, 606 chbuf_paddr, 607 2, 608 chbuf_paddr + 16, 609 1, 610 length ); 611 return 0; 612 613 #else 614 615 _printf("\n[GIET ERROR] in _sys_fbf_cma_start() : NB_CMA_CHANNELS = 0\n"); 616 return -1; 617 618 #endif 619 } // end _sys_fbf_cma_start() 620 621 ///////////////////////////////////////////////////// 622 int _sys_fbf_cma_display( unsigned int buffer_index ) 623 { 624 #if NB_CMA_CHANNELS > 0 625 626 volatile paddr_t buf_paddr; 627 unsigned int full = 1; 628 629 // get channel index 630 unsigned int channel = _get_context_slot( CTX_FBCMA_ID ); 631 632 if ( channel >= NB_CMA_CHANNELS ) 633 { 634 _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : CMA channel index too large\n"); 635 return -1; 636 } 637 638 #if GIET_DEBUG_FBF_CMA 639 _printf("\n[FBF_CMA DEBUG] enters _sys_fb_cma_display()\n" 640 " - channel = %d\n" 641 " - buffer = %d\n", 642 channel, buffer_index ); 643 #endif 644 645 // waiting user buffer empty 646 while ( full ) 647 { 648 if ( USE_IOB ) 649 { 650 // INVAL L1 cache for the chbuf descriptor, 651 _dcache_buf_invalidate( (unsigned int)&_fbf_chbuf[channel], 32 ); 652 653 // INVAL L2 cache for the chbuf descriptor, 654 _mmc_inval( _fbf_chbuf_paddr[channel], 32 ); 655 } 656 657 // read user buffer descriptor 658 if ( buffer_index == 0 ) buf_paddr = _fbf_chbuf[channel].buf0; 659 else buf_paddr = _fbf_chbuf[channel].buf1; 660 661 full = ( (unsigned int)(buf_paddr>>63) ); 662 } 663 664 if ( USE_IOB ) 665 { 666 // SYNC request for the user buffer, because 667 // it will be read from XRAM by the CMA component 668 _mmc_sync( buf_paddr, _fbf_chbuf[channel].length ); 669 } 670 671 // set user buffer status 672 if ( buffer_index == 0 ) _fbf_chbuf[channel].buf0 = buf_paddr | 0x8000000000000000ULL; 673 else _fbf_chbuf[channel].buf1 = buf_paddr | 0x8000000000000000ULL; 674 675 // reset fbf buffer status 676 _fbf_chbuf[channel].fbf = _fbf_chbuf[channel].fbf & 0x7FFFFFFFFFFFFFFFULL; 677 678 if ( USE_IOB ) 679 { 680 // SYNC request for the channel descriptor, because 681 // it will be read from XRAM by the CMA component 682 _mmc_sync( _fbf_chbuf_paddr[channel], 32 ); 683 } 684 685 #if GIET_DEBUG_FBF_CMA 686 _printf(" - fbf pbase = %l\n" 687 " - buf0 pbase = %l\n" 688 " - buf1 pbase = %l\n", 689 _fbf_chbuf[channel].fbf, 690 _fbf_chbuf[channel].buf0, 691 _fbf_chbuf[channel].buf1 ); 692 #endif 693 694 695 return 0; 696 697 #else 698 699 _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : no CMA channel allocated\n"); 700 return -1; 701 702 #endif 703 } // end _sys_fbf_cma_display() 704 705 /////////////////////// 706 int _sys_fbf_cma_stop() 707 { 708 #if NB_CMA_CHANNELS > 0 709 710 // get channel index 711 unsigned int channel = _get_context_slot( CTX_FBCMA_ID ); 712 713 if ( channel >= NB_CMA_CHANNELS ) 714 { 715 _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : CMA channel index too large\n"); 716 return -1; 717 } 718 719 // Desactivate CMA channel 720 _cma_stop_channel( channel ); 721 722 return 0; 723 724 #else 725 726 _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : no CMA channel allocated\n"); 727 return -1; 728 729 #endif 730 } // end _sys_fbf_cma_stop() 731 732 733 ////////////////////////////////////////////////////////////////////////////// 734 // Miscelaneous syscall handlers 735 ////////////////////////////////////////////////////////////////////////////// 736 737 /////////////// 738 int _sys_ukn() 739 { 740 _printf("\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() ); 741 return -1; 742 } 743 744 //////////////////////////////////// 745 int _sys_proc_xyp( unsigned int* x, 746 unsigned int* y, 747 unsigned int* p ) 121 748 { 122 749 unsigned int gpid = _get_procid(); // global processor index from CPO register … … 125 752 *y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 126 753 *p = gpid & ((1<<P_WIDTH)-1); 127 } 128 //////////////////////////////////////////////////////////////////////////// 129 // Task suicide... after printing a death message. 130 //////////////////////////////////////////////////////////////////////////// 131 void _task_exit( char* string ) 754 755 return 0; 756 } 757 758 ////////////////////////////////// 759 int _sys_task_exit( char* string ) 132 760 { 133 761 unsigned int date = _get_proctime(); … … 141 769 unsigned int task_id = _get_context_slot(CTX_LTID_ID); 142 770 143 // print deathmessage771 // print exit message 144 772 _printf("\n[GIET] Exit task %d on processor[%d,%d,%d] at cycle %d" 145 773 "\n Cause : %s\n\n", … … 151 779 // deschedule 152 780 _context_switch(); 781 782 return 0; 153 783 } 154 784 155 ////////////////////////////////////////////////////////////////////////////// 156 // returns in buffer argument the number of processors in the cluster 157 // specified by the cluster_id argument. 158 ////////////////////////////////////////////////////////////////////////////// 159 unsigned int _procs_number(unsigned int cluster_id, 160 unsigned int* buffer) 785 ////////////////////// 786 int _context_switch() 787 { 788 unsigned int save_sr; 789 790 _it_disable( &save_sr ); 791 _ctx_switch(); 792 _it_restore( &save_sr ); 793 794 return 0; 795 } 796 797 //////////////////////// 798 int _sys_local_task_id() 799 { 800 return _get_context_slot(CTX_LTID_ID); 801 } 802 803 ///////////////////////// 804 int _sys_global_task_id() 805 { 806 return _get_context_slot(CTX_GTID_ID); 807 } 808 809 //////////////////// 810 int _sys_thread_id() 811 { 812 return _get_context_slot(CTX_TRDID_ID); 813 } 814 815 ////////////////////////////////////// 816 int _sys_procs_number( unsigned int x, 817 unsigned int y, 818 unsigned int* number ) 161 819 { 162 820 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 163 821 mapping_cluster_t * cluster = _get_cluster_base(header); 164 822 165 if ( cluster_id < X_SIZE * Y_SIZE )166 { 167 * buffer = cluster[cluster_id].procs;823 if ( (x < X_SIZE) && (y < Y_SIZE) ) 824 { 825 *number = cluster[(x*Y_SIZE)+y].procs; 168 826 return 0; 169 827 } 170 828 else 171 829 { 172 return 1; 173 } 174 } 175 176 ///////////////////////////////////////////////////////////////////////////// 177 // Returns current task local index. 178 ///////////////////////////////////////////////////////////////////////////// 179 unsigned int _local_task_id() 180 { 181 return _get_context_slot(CTX_LTID_ID); 182 } 183 184 ///////////////////////////////////////////////////////////////////////////// 185 // Returns current task global index. 186 ///////////////////////////////////////////////////////////////////////////// 187 unsigned int _global_task_id() 188 { 189 return _get_context_slot(CTX_GTID_ID); 190 } 191 192 ///////////////////////////////////////////////////////////////////////////// 193 // Returns current thread index. 194 ///////////////////////////////////////////////////////////////////////////// 195 unsigned int _thread_id() 196 { 197 return _get_context_slot(CTX_TRDID_ID); 198 } 199 200 ///////////////////////////////////////////////////////////////////////////// 201 // This function writes in res_vobj a pointer on a vobj 202 // identified by the (vspace_name / vobj_name ) couple. 203 // returns 0 if success, >0 if not found 204 ///////////////////////////////////////////////////////////////////////////// 205 int _get_vobj( char* vspace_name, 206 char* vobj_name, 207 mapping_vobj_t** res_vobj ) 830 _printf("\n[GIET ERROR] in _sys_procs_number() : illegal (x,y) coordinates\n" ); 831 return -1; 832 } 833 } 834 835 /////////////////////////////////////////////////////// 836 int _sys_vobj_get_vbase( char* vspace_name, 837 char* vobj_name, 838 unsigned int* vbase ) 208 839 { 209 840 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; … … 226 857 if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 227 858 { 228 * res_vobj = &vobj[vobj_id];859 *vbase = vobj[vobj_id].vbase; 229 860 return 0; 230 861 } … … 232 863 } 233 864 } 234 return 1; //not found 235 } 236 237 ///////////////////////////////////////////////////////////////////////////// 238 // This function writes in vobj_vbase the virtual base address of a vobj 239 // identified by the (vspace_name / vobj_name ) couple. 240 // returns 0 if success, >0 if not found 241 ///////////////////////////////////////////////////////////////////////////// 242 unsigned int _vobj_get_vbase( char* vspace_name, 243 char* vobj_name, 244 unsigned int* vobj_vbase ) 245 { 246 mapping_vobj_t* res_vobj; 247 unsigned int ret; 248 if ((ret = _get_vobj(vspace_name, vobj_name, &res_vobj))) 249 { 250 return ret; 251 } 252 *vobj_vbase = res_vobj->vbase; 253 return 0; 254 } 255 256 ///////////////////////////////////////////////////////////////////////////// 257 // This function writes in vobj_length the length of a vobj 258 // identified by the (vspace_name / vobj_name ) couple. 259 // returns 0 if success, >0 if not found 260 ///////////////////////////////////////////////////////////////////////////// 261 unsigned int _vobj_get_length( char* vspace_name, 262 char* vobj_name, 263 unsigned int* vobj_length ) 264 { 265 mapping_vobj_t * res_vobj; 266 unsigned int ret; 267 if ((ret = _get_vobj(vspace_name, vobj_name, &res_vobj))) 268 { 269 return ret; 270 } 271 *vobj_length = res_vobj->length; 272 return 0; 273 } 274 275 ///////////////////////////////////////////////////////////////////////////// 276 // This function returns in the (x,y) arguments the coordinates of the 277 // where is mapped the ptr virtual address. It use the _get_context_slot() 278 // function to get the calling task page table, and uses the _v2p_translate() 279 // function to obtain the physical address. 280 // returns 0 if success, > 0 if ptr not mapped in the calling task vspace. 281 ///////////////////////////////////////////////////////////////////////////// 282 283 unsigned int _get_xy_from_ptr( void* ptr, 284 unsigned int* px, 285 unsigned int* py ) 865 return -1; // not found 866 } 867 868 ///////////////////////////////////////////////////////// 869 int _sys_vobj_get_length( char* vspace_name, 870 char* vobj_name, 871 unsigned int* length ) 872 { 873 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 874 mapping_vspace_t * vspace = _get_vspace_base(header); 875 mapping_vobj_t * vobj = _get_vobj_base(header); 876 877 unsigned int vspace_id; 878 unsigned int vobj_id; 879 880 // scan vspaces 881 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 882 { 883 if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 884 { 885 // scan vobjs 886 for (vobj_id = vspace[vspace_id].vobj_offset; 887 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 888 vobj_id++) 889 { 890 if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 891 { 892 *length = vobj[vobj_id].length; 893 return 0; 894 } 895 } 896 } 897 } 898 return -1; // not found 899 } 900 901 //////////////////////////////////////// 902 int _sys_xy_from_ptr( void* ptr, 903 unsigned int* x, 904 unsigned int* y ) 286 905 { 287 906 unsigned int ret; … … 294 913 295 914 // compute the physical address 296 if ( (ret = _v2p_translate( pt, vpn, &ppn, &flags )) ) 297 { 298 return ret; 299 } 300 301 *px = (ppn>>24) & 0xF; 302 *py = (ppn>>20) & 0xF; 303 return 0; 304 } 305 306 //////////////////////////////////////////////////////////////////////////// 307 // This sysrem function deschedule the requestint task. 308 // It mask interrupts before calling the _ctx_switch, and restore it 309 // when the task is rescheduled. 310 //////////////////////////////////////////////////////////////////////////// 311 void _context_switch() 312 { 313 unsigned int save_sr; 314 315 _it_disable( &save_sr ); 316 _ctx_switch(); 317 _it_restore( &save_sr ); 318 } 915 if ( (ret = _v2p_translate( pt, vpn, &ppn, &flags )) ) return -1; 916 917 *x = (ppn>>24) & 0xF; 918 *y = (ppn>>20) & 0xF; 919 return 0; 920 } 921 922 ///////////////////////////////////////// 923 int _sys_heap_info( unsigned int* vaddr, 924 unsigned int* length, 925 unsigned int x, 926 unsigned int y ) 927 { 928 mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 929 mapping_task_t * tasks = _get_task_base(header); 930 mapping_vobj_t * vobjs = _get_vobj_base(header); 931 mapping_vspace_t * vspaces = _get_vspace_base(header); 932 933 unsigned int task_id; 934 unsigned int vspace_id; 935 unsigned int vobj_id = 0xFFFFFFFF; 936 937 // searching the heap vobj_id 938 if ( (x < X_SIZE) && (y < Y_SIZE) ) // searching a task in cluster(x,y) 939 { 940 // get vspace global index 941 vspace_id = _get_context_slot(CTX_VSID_ID); 942 943 // scan all tasks in vspace 944 unsigned int min = vspaces[vspace_id].task_offset ; 945 unsigned int max = min + vspaces[vspace_id].tasks ; 946 for ( task_id = min ; task_id < max ; task_id++ ) 947 { 948 if ( tasks[task_id].clusterid == (x * Y_SIZE + y) ) 949 { 950 vobj_id = tasks[task_id].heap_vobj_id; 951 if ( vobj_id != 0xFFFFFFFF ) break; 952 } 953 } 954 } 955 else // searching in the calling task 956 { 957 task_id = _get_context_slot(CTX_GTID_ID); 958 vobj_id = tasks[task_id].heap_vobj_id; 959 } 960 961 // analysing the vobj_id 962 if ( vobj_id != 0xFFFFFFFF ) 963 { 964 *vaddr = vobjs[vobj_id].vbase; 965 *length = vobjs[vobj_id].length; 966 return 0; 967 } 968 else 969 { 970 *vaddr = 0; 971 *length = 0; 972 return -1; 973 } 974 } // end _sys_heap_info() 975 319 976 320 977 // Local Variables:
Note: See TracChangeset
for help on using the changeset viewer.