Ignore:
Timestamp:
Jun 18, 2017, 10:06:41 PM (7 years ago)
Author:
alain
Message:

Introduce syscalls.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/mm/mapper.c

    r18 r23  
    2626#include <hal_types.h>
    2727#include <hal_special.h>
     28#include <hal_uspace.h>
    2829#include <grdxt.h>
    2930#include <rwlock.h>
     
    108109        {
    109110            // remove page from mapper and release to PPM
    110                 error = mapper_release_page( mapper , found_index , page );
     111                error = mapper_release_page( mapper , page );
    111112
    112113            if ( error ) return error;
     
    148149
    149150    // test if page available in mapper
    150     if( ( page == NULL) || page_is_flag( page , PG_INLOAD ) )  // page not available            /
     151    if( ( page == NULL) || page_is_flag( page , PG_INLOAD ) )  // page not available
    151152    {
    152153        // release the lock in READ_MODE and take it in WRITE_MODE
     
    194195                printk("\n[ERROR] in %s : thread %x cannot insert page in mapper\n",
    195196                       __FUNCTION__ , this->trdid );
    196                 mapper_release_page( mapper , index , page );
     197                mapper_release_page( mapper , page );
    197198                page_clear_flag( page , PG_ALL );
    198199                req.ptr  = page;
     
    203204
    204205            // launch I/O operation to load page from file system
    205             error = mapper_updt_page( mapper , index , page );
     206            error = vfs_move_page_to_mapper( page );
    206207
    207208            if( error )
     
    209210                printk("\n[ERROR] in %s : thread %x cannot load page from device\n",
    210211                       __FUNCTION__ , this->trdid );
    211                 mapper_release_page( mapper , index , page );
     212                mapper_release_page( mapper , page );
    212213                page_clear_flag( page , PG_ALL );
    213214                req.ptr  = page;
     
    255256///////////////////////////////////////////////
    256257error_t mapper_release_page( mapper_t * mapper,
    257                              uint32_t   index,
    258258                             page_t   * page )
    259259{
     
    261261
    262262    // lauch IO operation to update page to file system
    263     error = mapper_sync_page( mapper , index , page );
     263    error = vfs_move_page_from_mapper( page );
    264264
    265265    if( error )
     
    288288}  // end mapper_release_page()
    289289
    290 ////////////////////////////////////////////
    291 error_t mapper_updt_page( mapper_t * mapper,
    292                           uint32_t   index,
    293                           page_t   * page )
    294 {
    295     uint32_t      type;
    296     vfs_inode_t * inode;
    297     error_t       error = 0;
    298 
    299     if( page == NULL )
    300     {
    301         printk("\n[PANIC] in %s : page pointer is NULL\n", __FUNCTION__ );
    302         hal_core_sleep();
    303     }
    304 
    305     if( mapper == NULL )
    306     {
    307         printk("\n[PANIC] in %s : no mapper for this page\n", __FUNCTION__ );
    308         hal_core_sleep();
    309     }
    310 
    311     // get file system type and inode pointer
    312     inode = mapper->inode;
    313     type  = inode->ctx->type;
    314 
    315     // get page lock
    316     page_lock( page );
    317 
    318     // get mapper lock in WRITE_MODE
    319     rwlock_wr_lock( &mapper->lock );
    320 
    321     // call proper I/O operation to update file system
    322     if     ( type == FS_TYPE_FATFS ) error = fatfs_read_page( page );
    323     else if( type == FS_TYPE_RAMFS ) error = ramfs_read_page( page );
    324     else
    325     {
    326         printk("\n[PANIC] in %s : undefined file system type\n", __FUNCTION__ );
    327         hal_core_sleep();
    328     }
    329 
    330     // release mapper lock from WRITE_MODE
    331     rwlock_wr_unlock( &mapper->lock );
    332 
    333     // release page lock
    334     page_unlock( page );
    335 
    336     if( error )
    337     {
    338         printk("\n[PANIC] in %s : cannot access file system\n", __FUNCTION__ );
    339         return EIO;
    340     }
    341 
    342     return 0;
    343 }  // end mapper_updt_page
    344 
    345 ////////////////////////////////////////////
    346 error_t mapper_sync_page( mapper_t * mapper,
    347                           uint32_t   index,
    348                           page_t   * page )
    349 {
    350     uint32_t      type;
    351     vfs_inode_t * inode;
    352     error_t       error = 0;
    353 
    354     if( page == NULL )
    355     {
    356         printk("\n[PANIC] in %s : page pointer is NULL\n", __FUNCTION__ );
    357         hal_core_sleep();
    358     }
    359 
    360     if( mapper == NULL )
    361     {
    362         printk("\n[PANIC] in %s : no mapper for this page\n", __FUNCTION__ );
    363         hal_core_sleep();
    364     }
    365 
    366         if( page_is_flag( page , PG_DIRTY ) )
    367         {
    368         // get file system type and inode pointer
    369         inode = mapper->inode;
    370         type  = inode->ctx->type;
    371 
    372         // get page lock
    373         page_lock( page );
    374 
    375         // get mapper lock in READ_MODE
    376         rwlock_rd_lock( &mapper->lock );
    377 
    378         // call proper I/O operation to update file system
    379         if     ( type == FS_TYPE_FATFS ) error = fatfs_write_page( page );
    380         else if( type == FS_TYPE_RAMFS ) error = ramfs_write_page( page );
    381         else
    382         {
    383             printk("\n[PANIC] in %s : undefined file system type\n", __FUNCTION__ );
    384             hal_core_sleep();
    385         }
    386 
    387         // release mapper lock from READ_MODE
    388         rwlock_rd_unlock( &mapper->lock );
    389 
    390         // release page lock
    391         page_unlock( page );
    392 
    393         if( error )
    394         {
    395             printk("\n[PANIC] in %s : cannot update file system\n", __FUNCTION__ );
    396             return EIO;
    397         }
    398 
    399         // clear dirty bit
    400                 page_undo_dirty( page );
    401      }
    402 
    403     return 0;
    404 
    405 }  // end mapper_sync_page()
    406 
    407 ///////////////////////////////////////////////////////////////////////////////////////
    408 // This static function is called by the mapper_move fragments() function.
    409 // It moves one fragment between an user buffer and the kernel mapper.
    410 // Implementation Note: It can require access to one or two pages in mapper:
    411 //  [max_page_index == min_page_index]     <=>  fragment fit in one mapper page
    412 //  [max_page index == min_page_index + 1] <=>  fragment spread on two mapper pages
    413 ///////////////////////////////////////////////////////////////////////////////////////
    414 static error_t mapper_move_one_fragment( mapper_t   * mapper,
    415                                          bool_t       to_buffer,
    416                                          fragment_t * fragment )
    417 {
    418     uint32_t   size;                 // number of bytes in fragment
    419     cxy_t      buf_cxy;              // cluster identifier for user buffer
    420     uint8_t  * buf_ptr;              // local pointer on first byte in user buffer
    421 
    422     xptr_t     xp_buf;               // extended pointer on byte in user buffer
    423     xptr_t     xp_map;               // extended pointer on byte in kernel mapper
    424 
    425     uint32_t   min_file_offset;      // offset of first byte in file
    426     uint32_t   max_file_offset;      // offset of last byte in file
    427 
    428     uint32_t   first_page_index;     // index of first page in mapper
    429     uint32_t   first_page_offset;    // offset of first byte in first page in mapper
    430     uint32_t   first_page_size;      // offset of first byte in first page in mapper
    431 
    432     uint32_t   second_page_index;    // index of last page in mapper
    433     uint32_t   second_page_offset;   // offset of last byte in last page in mapper
    434     uint32_t   second_page_size;     // offset of last byte in last page in mapper
    435 
    436     page_t   * page;                 // pointer on one page descriptor in mapper
    437     uint8_t  * map_ptr;              // local pointer on first byte in mapper
    438 
    439     // get fragment attributes in user buffer
    440     buf_cxy = fragment->buf_cxy;
    441     buf_ptr = fragment->buf_ptr;
    442     size    = fragment->size;
    443 
    444     if( size > CONFIG_PPM_PAGE_SIZE )
    445     {
    446         printk("\n[PANIC] in %s : illegal fragment size = %d\n",
    447                __FUNCTION__ , size );
    448         return EINVAL;
    449     }
     290/////////////////////////////////////////
     291error_t mapper_move( mapper_t  *  mapper,
     292                     bool_t       to_buffer,
     293                     uint32_t     file_offset,
     294                     void      *  buffer,
     295                     uint32_t     size )
     296{
     297    uint32_t   page_offset;    // first byte to move to/from a mapper page
     298    uint32_t   page_count;     // number of bytes to move to/from a mapper page
     299    uint32_t   index;          // current mapper page index
     300    uint32_t   done;           // number of moved bytes
     301    page_t   * page;           // current mapper page descriptor
     302    uint8_t  * map_ptr;        // current mapper  address
     303    uint8_t  * buf_ptr;        // current buffer  address
    450304
    451305    // compute offsets of first and last bytes in file
    452     min_file_offset = fragment->file_offset;
    453     max_file_offset = min_file_offset + size;
     306    uint32_t min_byte = file_offset;
     307    uint32_t max_byte = file_offset + size -1;
    454308
    455309    // compute indexes of pages for first and last byte in mapper
    456     first_page_index  = min_file_offset >> CONFIG_PPM_PAGE_SHIFT;
    457     second_page_index = max_file_offset >> CONFIG_PPM_PAGE_SHIFT;
    458 
    459     if ( first_page_index == second_page_index )  // only one page in mapper
    460     {
    461         // compute offset and size for page in mapper
    462         first_page_offset = min_file_offset & (1<<CONFIG_PPM_PAGE_SHIFT);
    463         first_page_size   = size;
    464 
    465         // get pointer on first page in mapper
    466         page = mapper_get_page( mapper , first_page_index );
     310    uint32_t first = min_byte >> CONFIG_PPM_PAGE_SHIFT;
     311    uint32_t last  = max_byte >> CONFIG_PPM_PAGE_SHIFT;
     312
     313    done = 0;
     314
     315    // loop on pages in mapper
     316    for( index = first ; index <= last ; index++ )
     317    {
     318        // compute page_offset
     319        if( index == first ) page_offset = min_byte & CONFIG_PPM_PAGE_MASK;
     320        else                 page_offset = 0;
     321
     322        // compute page_count
     323        if      ( first == last  ) page_count = size;
     324        else if ( index == first ) page_count = CONFIG_PPM_PAGE_SIZE - page_offset;
     325        else if ( index == last  ) page_count = (max_byte & CONFIG_PPM_PAGE_MASK) + 1;
     326        else                       page_count = CONFIG_PPM_PAGE_SIZE;
     327
     328        // get page descriptor
     329        page = mapper_get_page( mapper , index );
    467330
    468331        if ( page == NULL ) return EINVAL;
    469332
    470         // compute pointer on fragment first byte in mapper
    471         map_ptr = (uint8_t *)ppm_page2base( page ) + first_page_offset;
    472 
    473         // compute extended pointers in mapper and in buffer
    474         xp_map = XPTR( local_cxy , map_ptr );
    475         xp_buf = XPTR( buf_cxy , buf_ptr );
     333        // compute pointer in mapper
     334        map_ptr = (uint8_t *)ppm_page2base( page ) + page_offset;
     335
     336        // compute pointer in buffer
     337        buf_ptr = (uint8_t *)buffer + done;
    476338
    477339        // move fragment
    478340        if( to_buffer )
    479341        {
    480             hal_remote_memcpy( xp_buf , xp_map , first_page_size );
     342            hal_copy_to_uspace( buf_ptr , map_ptr , page_count );
    481343        }
    482344        else
    483345        {
    484346            page_do_dirty( page );
    485             hal_remote_memcpy( xp_map , xp_buf , first_page_size );
    486         }
    487     }
    488     else                                        // two pages in mapper
    489     {
    490         // compute offset and size for first page in mapper
    491         first_page_offset = min_file_offset & (1<<CONFIG_PPM_PAGE_SHIFT);
    492         first_page_size   = CONFIG_PPM_PAGE_SIZE - first_page_offset;
    493 
    494         // get pointer on first page descriptor in mapper
    495         page = mapper_get_page( mapper , first_page_index );
    496 
    497         if ( page == NULL ) return EINVAL;
    498 
    499         // compute local pointer on first byte in first page in mapper
    500         map_ptr = (uint8_t *)ppm_page2base(page) + first_page_offset;
    501 
    502         // compute extended pointers
    503         xp_map = XPTR( local_cxy , map_ptr );
    504         xp_buf = XPTR( buf_cxy , buf_ptr );
    505 
    506         // move fragment to/from first page
    507         if( to_buffer )
    508         {
    509             hal_remote_memcpy( xp_buf , xp_map , first_page_size );
    510         }
    511         else
    512         {
    513             page_do_dirty( page );
    514             hal_remote_memcpy( xp_map , xp_buf , first_page_size );
    515         }
    516 
    517         // compute offset and size for second page in mapper
    518         second_page_offset = 0;
    519         second_page_size   = size - first_page_size;
    520 
    521         // get pointer on second page in mapper
    522         page = mapper_get_page( mapper , second_page_index );
    523 
    524         if ( page == NULL ) return EINVAL;
    525 
    526         // compute local pointer on first byte in second page in mapper
    527         map_ptr = (uint8_t *)ppm_page2base( page ) + second_page_offset;
    528 
    529         // compute extended pointers
    530         xp_map = XPTR( local_cxy , map_ptr );
    531         xp_buf = XPTR( buf_cxy , buf_ptr + first_page_offset );
    532 
    533         // move fragment to/from second page
    534         if( to_buffer )
    535         {
    536             hal_remote_memcpy( xp_buf , xp_map , second_page_size );
    537         }
    538         else
    539         {
    540             page_do_dirty( page );
    541             hal_remote_memcpy( xp_map , xp_buf , second_page_size );
    542         }
     347            hal_copy_from_uspace( map_ptr , buf_ptr , page_count );
     348        }
     349
     350        done += page_count;
    543351    }
    544352
    545353    return 0;
    546 }  // end mapper_move_one_fragment()
    547 
    548 /////////////////////////////////////////////////
    549 error_t mapper_move_fragments( mapper_t * mapper,
    550                                bool_t     read,
    551                                uint32_t   nb_frags,
    552                                xptr_t     xp_frags )
    553 {
    554         uint32_t     index;
    555         error_t      error;
    556     fragment_t   local_frags[CONFIG_MAPPER_MAX_FRAGMENTS];   // local copy of fragments array
    557     fragment_t * frags_array;                                // pointer on fragments array
    558 
    559     // check nb_frags
    560     if( nb_frags > CONFIG_MAPPER_MAX_FRAGMENTS )
    561     {
    562         printk("\n[PANIC] in %s : number of fragments cannot be larger than %d\n",
    563                __FUNCTION__ , CONFIG_MAPPER_MAX_FRAGMENTS );
    564         return EINVAL;
    565     }
    566 
    567     // get client cluster and local pointer on fragments array
    568     cxy_t        client_cxy   = GET_CXY( xp_frags );
    569     fragment_t * client_frags = (fragment_t *)GET_PTR( xp_frags );
    570 
    571     if ( local_cxy == client_cxy ) // use the local fragments array if possible
    572     {
    573         frags_array = client_frags;
    574     }
    575     else                           // make a local copy of fragments array
    576     {
    577         hal_remote_memcpy( XPTR( local_cxy , local_frags ) , xp_frags ,
    578                            sizeof(fragment_t) * nb_frags );
    579         frags_array = local_frags;
    580     }
    581 
    582     // loop on fragments
    583     for( index = 0 ; index < nb_frags ; index ++ )
    584     {
    585         error = mapper_move_one_fragment( mapper , read , &frags_array[index] );
    586         if ( error ) return error;
    587     }
    588 
    589     return 0;
    590 
    591 }  // end mapper_move_fragments()
    592 
    593 
     354
     355}  // end mapper_move()
     356
     357
     358
Note: See TracChangeset for help on using the changeset viewer.