Changeset 760 for soft/giet_vm/giet_kernel/sys_handler.c
- Timestamp:
- Jan 19, 2016, 11:23:02 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_kernel/sys_handler.c
r754 r760 95 95 extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 96 96 97 // allocated in bdv_driver.c file98 spin_lock_t _bdv_lock; 97 // allocated in kernel_init.c file 98 extern unsigned long long _ptabs_paddr[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE]; 99 99 100 100 //////////////////////////////////////////////////////////////////////////////// … … 229 229 230 230 &_fat_open, /* 0x20 */ 231 &_ fat_read,/* 0x21 */232 &_ fat_write,/* 0x22 */231 &_sys_fat_read, /* 0x21 */ 232 &_sys_fat_write, /* 0x22 */ 233 233 &_fat_lseek, /* 0x23 */ 234 234 &_fat_file_info, /* 0x24 */ … … 240 240 &_fat_closedir, /* 0x2A */ 241 241 &_fat_readdir, /* 0x2B */ 242 &_sys_ ukn,/* 0x2C */243 &_sys_ ukn,/* 0x2D */244 &_sys_ ukn,/* 0x2E */242 &_sys_fat_pread, /* 0x2C */ 243 &_sys_fat_mmap, /* 0x2D */ 244 &_sys_fat_munmap, /* 0x2E */ 245 245 &_sys_ukn, /* 0x2F */ 246 246 … … 274 274 275 275 276 277 /////////////////////////////////////////////////////////////////////////////////// 278 // File system related syscall handlers 279 /////////////////////////////////////////////////////////////////////////////////// 280 281 /////////////////////////////////////////////////////////////////////////////////// 282 // This function is called by the _sys_fat_mmap() function. 283 // It implements a simplistic pages allocator from the MMAP vseg of the vspace 284 // identified by the <vspace_id> argument. The number of pages is defined by 285 // the <count> argument. 286 // Allocated pages are never released, and the allocator is the "psegid" field 287 // in the vseg mapping, that is initialised to 0 by the boot code. 288 // In order to support concurrent system calls, the allocator must be 289 // atomically incremented. 290 /////////////////////////////////////////////////////////////////////////////////// 291 // Returns the buffer vbase address in case of success. 292 // Returns 0 in case of error (no MMAP vseg or not enough space). 293 /////////////////////////////////////////////////////////////////////////////////// 294 static unsigned int _mmap_pages_alloc( unsigned int vspace_id, 295 unsigned int count ) 296 { 297 mapping_header_t* header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; 298 mapping_vspace_t* vspace = _get_vspace_base( header ); 299 mapping_vseg_t* vseg = _get_vseg_base( header ); 300 301 // loop on the vsegs to find the MMAP vseg vbase, length, and offset 302 unsigned int vseg_id; 303 unsigned int vbase; 304 unsigned int offset; 305 unsigned int length; 306 unsigned int found = 0; 307 for (vseg_id = vspace[vspace_id].vseg_offset; 308 vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs); 309 vseg_id++) 310 { 311 if ( vseg[vseg_id].type == VSEG_TYPE_MMAP ) 312 { 313 offset = _atomic_increment( &vseg[vseg_id].psegid , count ); 314 vbase = vseg[vseg_id].vbase; 315 length = vseg[vseg_id].length; 316 found = 1; 317 break; 318 } 319 } 320 321 if ( (found == 0) || (((offset + count)<<12) > length) ) 322 { 323 return 0; 324 } 325 else 326 { 327 return vbase + (offset<<12); 328 } 329 } // end _mmap_pages_alloc() 330 331 332 /////////////////////////////////////////////////////////////////////////////////// 333 // This function implements the giet_fat_read() system call. 334 /////////////////////////////////////////////////////////////////////////////////// 335 int _sys_fat_read( unsigned int fd_id, 336 unsigned int vaddr, 337 unsigned int count ) 338 { 339 return _fat_read( fd_id, 340 vaddr, 341 count, 342 0, // no paddr extension 343 0, // no forced offset 344 0 ); // no special mode 345 } 346 347 //////////////////////////////////////////////////////////////// 348 // This function implements the giet_fat_pread() system call. 349 //////////////////////////////////////////////////////////////// 350 int _sys_fat_pread( unsigned int fd_id, 351 unsigned int vaddr, 352 unsigned int count, 353 unsigned int offset ) 354 { 355 return _fat_read( fd_id, 356 vaddr, 357 count, 358 0, // no paddr extension 359 offset, 360 FAT_FORCED_OFFSET ); 361 } 362 363 //////////////////////////////////////////////////////////////// 364 // This function implements the giet_fat_write() system call. 365 //////////////////////////////////////////////////////////////// 366 int _sys_fat_write( unsigned int fd_id, 367 unsigned int vaddr, 368 unsigned int count ) 369 { 370 return _fat_write( fd_id, 371 vaddr, 372 count, 373 0, // no paddr extension 374 0 ); // no special mode 375 } 376 377 /////////////////////////////////////////////////////////////////////////////////// 378 // This function implements the "giet_fat_mmap()" system call. 379 // It allocates <count> contiguous pages from the MMAP vseg of the calling vspace. 380 // It maps all these pages directly to the file_cache defined by <fd_id>. 381 // The <offset> in the file is a number of pages. 382 // The <prot> argument defines the access modes MAP_PROT_WRITE and MAP_PROT_EXEC. 383 // In writable mode, the file size is extended to the (offset + count) pages. 384 // In non writable mode, the file size must be >= (offset + count) pages. 385 // It has the following limitations: 386 // - it does not support MAP_PRIVATE (no copy on write). 387 // - it does not support MAP_FIXED (no forced user buffer address). 388 // - it does not support MAP_ANONYMOUS (only file mapping). 389 // - the <offset> and <count> arguments must multiple of 4 Kbytes. 390 /////////////////////////////////////////////////////////////////////////////////// 391 // Returns memory buffer vbase in case of success. 392 // Returns 0 on error. 393 /////////////////////////////////////////////////////////////////////////////////// 394 int _sys_fat_mmap( unsigned int fd_id, 395 unsigned int count, 396 unsigned int offset, 397 unsigned int prot ) 398 { 399 // takes the FAT lock and register it in thread context 400 static_scheduler_t* psched = _get_sched(); 401 unsigned int ltid = _get_thread_ltid(); 402 _spin_lock_acquire( &_fat.fat_lock ); 403 _atomic_or( &psched->context[ltid].slot[CTX_LOCKS_ID] , LOCKS_MASK_FAT ); 404 405 // check fd_id overflow 406 if ( fd_id >= GIET_OPEN_FILES_MAX ) 407 { 408 _spin_lock_release( &_fat.fat_lock ); 409 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 410 411 _printf("\n[GIET ERROR] _sys_fat_mmap(): illegal file descriptor\n"); 412 return 0; 413 } 414 415 // check file open 416 if ( _fat.fd[fd_id].allocated == 0 ) 417 { 418 _spin_lock_release( &_fat.fat_lock ); 419 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 420 421 _printf("\n[GIET ERROR] _sys_fat_mmap(): file not open\n" ); 422 return 0; 423 } 424 425 // get access modes 426 unsigned int writable = prot & MAP_PROT_WRITE; 427 unsigned int executable = prot & MAP_PROT_EXEC; 428 429 // get inode pointer 430 fat_inode_t* inode = _fat.fd[fd_id].inode; 431 432 // check file writable 433 if ( _fat.fd[fd_id].read_only && writable ) 434 { 435 _spin_lock_release( &_fat.fat_lock ); 436 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 437 438 _printf("\n[GIET ERROR] _sys_fat_mmap(): file <%s> is read-only\n", 439 inode->name ); 440 return 0; 441 } 442 443 // get vspace index and calling proc coordinates 444 unsigned int vsid = _get_context_slot( CTX_VSID_ID ); 445 446 // compute first and last cluster indexes 447 unsigned int first_cluster = offset; 448 unsigned int last_cluster = offset + count - 1; 449 450 #if GIET_DEBUG_MMAP 451 unsigned int procid = _get_procid(); 452 unsigned int x_id = procid >> (Y_WIDTH + P_WIDTH); 453 unsigned int y_id = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 454 unsigned int p_id = procid & ((1<<P_WIDTH)-1); 455 if ( _get_proctime() > GIET_DEBUG_MMAP ) 456 _printf("\n[DEBUG MMAP] _sys_fat_mmap() : P[%d,%d,%d] enters at cycle %d\n" 457 " for file %s / size = %x / cluster = %x / cache = %x / desc[0] = %x\n" 458 " first_cluster = %d / last_cluster = %d\n", 459 x_id , y_id , p_id , _get_proctime() , 460 inode->name , inode->size , inode->cluster , 461 (unsigned int)inode->cache , (unsigned int)inode->cache->children[0] , 462 first_cluster , last_cluster ); 463 #endif 464 465 // get buffer vbase from MMAP vseg in calling vspace 466 unsigned int buffer_vbase = _mmap_pages_alloc( vsid, count ); 467 if ( buffer_vbase == 0 ) 468 { 469 _spin_lock_release( &_fat.fat_lock ); 470 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 471 472 _printf("\n[GIET ERROR] _sys_fat_mmap(): no space in MMAP vseg to map file %s\n", 473 _fat.fd[fd_id].inode->name ); 474 return 0; 475 } 476 477 // set flags for all pages in buffer 478 unsigned int flags = 0; 479 flags |= PTE_C; // cachable 480 flags |= PTE_U; // user access 481 flags |= PTE_L; // local access (unused) 482 flags |= PTE_R; // remote access (unused) 483 if ( executable ) flags |= PTE_X; 484 if ( writable ) flags |= PTE_W; 485 486 // loop on pages to be mapped 487 unsigned int cid; 488 unsigned int user_vaddr = buffer_vbase; 489 for ( cid = first_cluster ; cid <= last_cluster ; cid++ ) 490 { 491 // get file_cache buffer vaddr 492 unsigned char* cache_vaddr; 493 fat_cache_desc_t* pdesc; 494 if ( _get_file_cache_buffer( inode, 495 cid, 496 writable, 497 &pdesc ) ) 498 { 499 _spin_lock_release( &_fat.fat_lock ); 500 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 501 502 _printf("\n[FAT ERROR] _sys_fat_mmap(): cannot access file <%s>\n", 503 _fat.fd[fd_id].inode->name ); 504 return 0; 505 } 506 507 cache_vaddr = pdesc->buffer; 508 509 // compute buffer paddr 510 unsigned long long cache_paddr; 511 unsigned int unused; 512 cache_paddr = _v2p_translate( (unsigned int)cache_vaddr, &unused ); 513 514 // map the user_vaddr to cache_paddr 515 // in all pages tables defined for the vspace 516 unsigned int x_cur; 517 unsigned int y_cur; 518 for ( x_cur = 0 ; x_cur < X_SIZE ; x_cur++ ) 519 { 520 for ( y_cur = 0 ; y_cur < Y_SIZE ; y_cur++ ) 521 { 522 if ( _ptabs_paddr[vsid][x_cur][y_cur] ) // Page table is defined 523 { 524 _v2p_add_pte2( vsid, 525 x_cur, 526 y_cur, 527 user_vaddr >> 12, 528 flags, 529 cache_paddr >> 12, 530 0 ); 531 } 532 } 533 } 534 535 #if GIET_DEBUG_MMAP 536 if ( _get_proctime() > GIET_DEBUG_MMAP ) 537 _printf("\n[DEBUG MMAP] _sys_fat_mmap() : P[%d,%d,%d] map cluster %d\n" 538 " user_vaddr = %x / cache_paddr = %l\n", 539 x_id , y_id , p_id , cid , user_vaddr , cache_paddr ); 540 #endif 541 542 // increment user buffer vaddr 543 user_vaddr += 4096; 544 } 545 546 // releases the FAT lock 547 _spin_lock_release( &_fat.fat_lock ); 548 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 549 550 #if GIET_DEBUG_MMAP 551 if ( _get_proctime() > GIET_DEBUG_MMAP ) 552 _printf("\n[DEBUG MMAP] _sys_fat_mmap() : P[%d,%d,%d] returns buffer %x for file %s\n", 553 x_id , y_id , p_id , buffer_vbase , inode->name ); 554 #endif 555 556 // returns pointer on mapped buffer in user space 557 return buffer_vbase; 558 559 } // end _sys_fat_mmap() 560 561 562 ////////////////////////////////////////////////////////////////// 563 // This function implements the giet_fat_munmap() system call. 564 ////////////////////////////////////////////////////////////////// 565 int _sys_fat_munmap( unsigned int vaddr, 566 unsigned int count ) 567 { 568 // get vspace index 569 unsigned int vsid = _get_context_slot( CTX_VSID_ID ); 570 571 // loop on pages 572 unsigned int page; 573 for ( page = 0 ; page < count ; page++ ) 574 { 575 unsigned int vpn = (vaddr>>12) + page; 576 577 // loop on all page tables defined for the vspace 578 unsigned int x_cur; 579 unsigned int y_cur; 580 for ( x_cur = 0 ; x_cur < X_SIZE ; x_cur++ ) 581 { 582 for ( y_cur = 0 ; y_cur < Y_SIZE ; y_cur++ ) 583 { 584 if ( _ptabs_paddr[vsid][x_cur][y_cur] ) // Page table is defined 585 { 586 _v2p_del_pte2( vsid , x_cur , y_cur , vpn ); 587 } 588 } 589 } 590 } 591 return 0; 592 } // end _sys_fat_munmap() 593 594 595 276 596 ////////////////////////////////////////////////////////////////////////////// 277 597 // Applications related syscall handlers … … 279 599 280 600 //////////////////////////////////////////////////////////////////////// 281 // This function is called by the _sys_exec_application function601 // This function is called by the _sys_exec_application() function 282 602 // to reload all data segments contained in an application.elf file. 283 603 // File checking is minimal, because these segments have already … … 344 664 return 1; 345 665 } 346 if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 )666 if ( _fat_read( fd, (unsigned int)buf, 4096, 0, 0, 0 ) < 0 ) 347 667 { 348 668 _printf("\n[GIET ERROR] _load_writable_segments() : cannot read\n"); … … 369 689 return 1; 370 690 } 371 if ( _fat_read( fd, (unsigned int)buf, 4096, 0 ) < 0 )691 if ( _fat_read( fd, (unsigned int)buf, 4096, 0, 0, 0 ) < 0 ) 372 692 { 373 693 _fat_close( fd ); … … 414 734 // compute destination address and extension for _fat_read() 415 735 unsigned int dest = (unsigned int)pbase; 416 unsigned int extend = (unsigned int)(pbase>>32) | 0xFFFF0000;736 unsigned int extend = (unsigned int)(pbase>>32); 417 737 418 738 // load the segment … … 422 742 return 1; 423 743 } 424 if ( _fat_read( fd, dest, seg_size, extend ) < 0 )744 if ( _fat_read( fd, dest, seg_size, extend, 0, FAT_PADDR_MODE ) < 0 ) 425 745 { 426 746 _fat_close( fd );
Note: See TracChangeset
for help on using the changeset viewer.