Ignore:
Timestamp:
Mar 18, 2020, 11:16:59 PM (4 years ago)
Author:
alain
Message:

Introduce remote_buf.c/.h & socket.c/.h files.
Update dev_nic.c/.h files.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/devices/dev_fbf.c

    r647 r657  
    22 * dev_fbf.c - FBF (Frame Buffer) generic device API implementation.
    33 *
    4  * Author  Alain Greiner    (2016,2017,2018,2019)
     4 * Author  Alain Greiner    (2016,2017,2018,2019,2020)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    2626#include <hal_gpt.h>
    2727#include <hal_drivers.h>
     28#include <hal_irqmask.h>
     29#include <hal_macros.h>
     30#include <hal_uspace.h>
     31#include <hal_vmm.h>
    2832#include <thread.h>
    2933#include <printk.h>
    3034#include <string.h>
     35#include <memcpy.h>
    3136#include <chdev.h>
    3237#include <dev_fbf.h>
     
    4146char * dev_fbf_cmd_str( uint32_t cmd_type )
    4247{
    43     if     ( cmd_type == FBF_READ       )  return "READ";
    44     else if( cmd_type == FBF_WRITE      )  return "WRITE";
    45     else if( cmd_type == FBF_GET_CONFIG )  return "GET_CONFIG";
    46     else                                   return "undefined";
     48    if     ( cmd_type == FBF_GET_CONFIG     )  return "GET_CONFIG";
     49    else if( cmd_type == FBF_CREATE_WINDOW  )  return "CREATE_WINDOW";
     50    else if( cmd_type == FBF_DELETE_WINDOW  )  return "DELETE_WINDOW";
     51    else if( cmd_type == FBF_MOVE_WINDOW    )  return "MOVE_WINDOW";
     52    else if( cmd_type == FBF_REFRESH_WINDOW )  return "REFRESH_WINDOW";
     53    else if( cmd_type == FBF_DIRECT_WRITE   )  return "DIRECT_WRITE";
     54    else if( cmd_type == FBF_DIRECT_READ    )  return "DIRECT_READ";
     55    else                                       return "undefined";
    4756}
    4857
     
    5059void dev_fbf_init( chdev_t  * fbf )
    5160{
     61    uint32_t wid;
     62
    5263    // set chdev name
    5364    strcpy( fbf->name, "fbf" );
    5465
    55     // call driver init function
     66    // initialize lock protecting the windows
     67    remote_rwlock_init( XPTR( local_cxy , &fbf->ext.fbf.windows_lock ),
     68                        LOCK_FBF_WINDOWS );
     69
     70    // initialize root of windows xlist
     71    xlist_root_init( XPTR( local_cxy , &fbf->ext.fbf.windows_root ) );
     72
     73    // initialize windows_tbl[] array
     74    for( wid = 0 ; wid < CONFIG_FBF_WINDOWS_MAX_NR ; wid++ )
     75    {
     76        fbf->ext.fbf.windows_tbl[wid] = XPTR_NULL;
     77    }
     78
     79    // initialize wid allocator bitmap
     80    bitmap_init( fbf->ext.fbf.windows_bitmap , CONFIG_FBF_WINDOWS_MAX_NR );
     81
     82    // call driver init function to initialize the harware FBF
     83    // and initialize the width, height, and subsampling FBF chdev fields
    5684    hal_drivers_fbf_init( fbf );
    5785
     
    6694    xptr_t  dev_xp = chdev_dir.fbf[0];
    6795
    68     assert( (dev_xp != XPTR_NULL) , "undefined FBF chdev descriptor" );
     96assert( (dev_xp != XPTR_NULL) , "undefined FBF chdev descriptor" );
    6997
    7098    // get FBF chdev cluster and local pointer
     
    79107}  // end dev_fbf_get_config()
    80108
    81 /////////////////////////////////////////////////////
    82 error_t dev_fbf_move_data( uint32_t   cmd_type,
    83                            void     * user_buffer,
    84                            uint32_t   length,
    85                            uint32_t   offset )
    86 {
    87     // get pointer on calling thread
    88     thread_t * this = CURRENT_THREAD;
     109///////////////////////////////////////////////
     110uint32_t dev_fbf_create_window( uint32_t   nlines,
     111                                uint32_t   npixels,
     112                                uint32_t   l_min,
     113                                uint32_t   p_min,
     114                                intptr_t * user_buffer )
     115{
     116    kmem_req_t     req;
     117    fbf_window_t * window;      // window descriptor (created in local cluster)
     118    vseg_t       * vseg;        // vseg descriptor (created in reference cluster)
     119    intptr_t       vseg_base;   // vseg base address in user space 
     120
     121    // get local pointers on calling thread and process
     122    thread_t  * this    = CURRENT_THREAD;
     123    process_t * process = this->process;
    89124
    90125#if DEBUG_DEV_FBF
    91126uint32_t   cycle = (uint32_t)hal_get_cycles();
    92127if( DEBUG_DEV_FBF < cycle )
    93 printk("\n[%s] thread[%x,%x] : %s / buffer %x / length %d / offset %x / cycle %d\n",
    94 __FUNCTION__ , this->process->pid, this->trdid, 
    95 dev_fbf_cmd_str(cmd_type), user_buffer, length, offset, cycle );
     128printk("\n[%s] thread[%x,%x] enter : nlines %d / npixels %d / l_min %d / p_min %d / cycle %d\n",
     129__FUNCTION__ , process->pid, this->trdid, nlines, npixels, l_min, p_min, cycle );
     130#endif
     131
     132    // get cluster and pointers on FBF chdev
     133    xptr_t      fbf_xp  = chdev_dir.fbf[0];
     134    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
     135    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
     136
     137// check fbf_xp definition
     138assert( (fbf_xp != XPTR_NULL) , "undefined FBF chdev descriptor" );
     139
     140    // get FBF width and height
     141    uint32_t fbf_width  = hal_remote_l32( XPTR( fbf_cxy , &fbf_ptr->ext.fbf.width ) );
     142    uint32_t fbf_height = hal_remote_l32( XPTR( fbf_cxy , &fbf_ptr->ext.fbf.height ) );
     143
     144    // check new window size and coordinates
     145    if( (((l_min + nlines) > fbf_height) || ((p_min + npixels) > fbf_width)) )
     146    {
     147        printk("\n[ERROR] in %s / thread[%x,%x]"
     148        "illegal new coordinates (%d,%d) for window (%d,%d) in fbf (%d,%d)\n",
     149        process->pid, this->trdid, p_min, l_min, npixels, nlines, fbf_width, fbf_height );
     150        return -1;
     151    }
     152
     153    // build extended pointers on windows lock, root, and wid allocator
     154    xptr_t windows_lock_xp   = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock );
     155    xptr_t windows_root_xp   = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root );
     156    xptr_t windows_bitmap_xp = XPTR( fbf_cxy ,  fbf_ptr->ext.fbf.windows_bitmap );
     157 
     158    // allocate memory for the window descriptor in local cluster
     159    req.type   = KMEM_KCM;
     160    req.order  = bits_log2( sizeof(fbf_window_t) );
     161    req.flags  = AF_ZERO | AF_KERNEL;
     162    window     = kmem_alloc( &req );
     163
     164    if( window == NULL )
     165    {
     166        printk("\n[ERROR] in %s / thread[%x,%x] cannot allocate window descriptor\n",
     167        __FUNCTION__, process->pid, this->trdid );
     168        return -1;
     169    }
     170
     171#if (DEBUG_DEV_FBF & 1)
     172cycle = (uint32_t)hal_get_cycles();
     173if( DEBUG_DEV_FBF < cycle )
     174printk("\n[%s] thread[%x,%x] created window descriptor %x / cycle %d\n",
     175__FUNCTION__ , process->pid, this->trdid, window, cycle );
     176#endif
     177
     178    // getpointers on reference process
     179    xptr_t      ref_xp  = process->ref_xp;
     180    process_t * ref_ptr = GET_PTR( ref_xp );
     181    cxy_t       ref_cxy = GET_CXY( ref_xp );
     182
     183    // allocate a new vseg, and introduce it in the reference process VSL
     184    if( ref_cxy == local_cxy )
     185    {
     186        vseg = vmm_create_vseg( process,            // owner process
     187                                VSEG_TYPE_ANON,     // localised, public
     188                                0,                  // base, unused for ANON
     189                                nlines * npixels,   // size
     190                                0,                  // file_offset, unused for ANON
     191                                0,                  // file_size, unused for ANON
     192                                XPTR_NULL,          // mapper_xp, unused for ANON
     193                                local_cxy );        // mapping cluster
     194    }
     195    else
     196    {
     197        rpc_vmm_create_vseg_client( ref_cxy,
     198                                    ref_ptr,
     199                                    VSEG_TYPE_ANON,
     200                                    0,                 // base, unused for ANON
     201                                    nlines * npixels,  // size
     202                                    0,                 // file_offset, unused for ANON
     203                                    0,                 // file size, unused for ANON
     204                                    XPTR_NULL,         // mapper_xp, unused for ANON
     205                                    local_cxy,
     206                                    &vseg );
     207    }
     208       
     209    if( vseg == NULL )
     210    {
     211        printk("\n[ERROR] in %s / thread[%x,%x] cannot create vseg in reference cluster\n",
     212        __FUNCTION__, process->pid, this->trdid );
     213        req.ptr = (void *)window;
     214        kmem_free( &req );
     215        return -1;
     216    }
     217
     218    // get vseg base
     219    vseg_base = (intptr_t)hal_remote_lpt( XPTR( ref_cxy , &vseg->min ) );
     220
     221#if (DEBUG_DEV_FBF & 1)
     222cycle = (uint32_t)hal_get_cycles();
     223if( DEBUG_DEV_FBF < cycle )
     224printk("\n[%s] thread[%x,%x] allocated vseg / base %x / cycle %d\n",
     225__FUNCTION__ , process->pid, this->trdid, vseg_base, cycle );
     226#endif
     227
     228    // take the lock protecting windows in write mode
     229    remote_rwlock_wr_acquire( windows_lock_xp );
     230
     231    // allocate a wid from allocator in FBF descriptor extension
     232    uint32_t wid = bitmap_remote_alloc( windows_bitmap_xp , CONFIG_FBF_WINDOWS_MAX_NR );
     233
     234    if( wid == 0xFFFFFFFF )
     235    {
     236        printk("\n[ERROR] in %s / thread[%x,%x] cannot allocate buffer for window\n",
     237        __FUNCTION__, process->pid, this->trdid );
     238        req.ptr = (void *)window;
     239        kmem_free( &req );
     240        vmm_remove_vseg( process , vseg );
     241        return -1;
     242    }
     243 
     244    // initialize window descriptor
     245    window->pid     = process->pid;
     246    window->wid     = wid;
     247    window->height  = nlines;
     248    window->width   = npixels;
     249    window->l_min   = l_min;
     250    window->p_min   = p_min;
     251    window->hidden  = false;
     252    window->buffer  = (uint8_t *)vseg_base;
     253
     254    // register new window in xlist rooted in FBF extension
     255    xlist_add_last( windows_root_xp , XPTR( local_cxy , &window->xlist ) );
     256
     257    // build extended pointer on relevant entry in windows_tbl[] array
     258    xptr_t windows_tbl_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_tbl[wid] );
     259
     260    // register new window in windows_tbl[] stored in FBF extension
     261    hal_remote_s64( windows_tbl_xp , XPTR( local_cxy , window ) );
     262
     263    // release the lock protecting windows in write mode
     264    remote_rwlock_wr_release( windows_lock_xp );
     265
     266#if DEBUG_DEV_FBF
     267cycle = (uint32_t)hal_get_cycles();
     268if( DEBUG_DEV_FBF < cycle )
     269printk("\n[%s] thread[%x,%x] exit / wid %d / buffer %x / cycle %d\n",
     270__FUNCTION__ , this->process->pid, this->trdid, wid , window->buffer, cycle );
     271#endif
     272
     273#if (DEBUG_DEV_FBF & 1)
     274hal_vmm_display( ref_xp , true );
     275#endif
     276
     277    // return pointer on allocated buffer
     278    *user_buffer = vseg_base;
     279
     280    return wid;
     281
     282}  // end dev_fbf_create_window()
     283
     284////////////////////////////////////////////////////////////////////////////////////////
     285// This static function is called by the dev_fbf_display() function.
     286// For a partial FBF line, identified by the <f_line>, <f_p_min>, <f_p_max> arguments
     287// in FBF reference, and for one remote window, identified by the <window_xp> argument,
     288// it updates the target buffer identified by <t_buffer>, and containing exactly
     289// (f_p_max - f_p_min) pixels.
     290// Depending on the actual overlap between the window and the <t_buffer> representing
     291// the partial FBF line, it moves up to (f_p_max - f_p_min) pixels from the window
     292// buffer to the target buffer. The number of moved pixels can be nul if no overlap.
     293////////////////////////////////////////////////////////////////////////////////////////
     294// @ f_line     : [in]  line index in FBF reference (from 0 to fbf_height-1).
     295// @ f_p_min    : [in]  first pixel in FBF line.
     296// @ f_p_max    : [in]  last pixel in FBF line (excluded).
     297// @ window_xp  : [in]  extended pointer on checked window .
     298// @ t_buffer   : [out] local pointer on target buffer to be updated.
     299///////////////////////////////////////////////////////////////////////////////////////
     300__attribute__ ((noinline)) static void handle_one_window( uint32_t  f_line,
     301                                                          uint32_t  f_p_min,
     302                                                          uint32_t  f_p_max,
     303                                                          xptr_t    window_xp,
     304                                                          uint8_t * t_buffer )
     305{
     306    // get remote window descriptor cluster and local pointer
     307    cxy_t          window_cxy = GET_CXY( window_xp );
     308    fbf_window_t * window_ptr = GET_PTR( window_xp );
     309
     310    // get remote window min/max coordinates in FBF reference
     311    uint32_t  w_l_min    = hal_remote_l32( XPTR( window_cxy , &window_ptr->l_min ) );
     312    uint32_t  w_p_min    = hal_remote_l32( XPTR( window_cxy , &window_ptr->p_min ) );
     313    uint32_t  w_height   = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) );
     314    uint32_t  w_width    = hal_remote_l32( XPTR( window_cxy , &window_ptr->width  ) );
     315    uint32_t  w_l_max    = w_l_min + w_height;
     316    uint32_t  w_p_max    = w_p_min + w_width;
     317
     318    // does nothing if partial FBF line does not overlap the window
     319    if( (f_line < w_l_min)  || (f_line >= w_l_max) ||
     320        (f_p_max < w_p_min) || (f_p_min >= w_p_max) ) return;
     321
     322    // get pointer on window buffer in user space
     323    uint8_t * w_buffer = hal_remote_lpt( XPTR( window_cxy , &window_ptr->buffer ) );
     324
     325    // get min & max indexes for pixels to be moved in FBF reference
     326    uint32_t f_pixel_min = (f_p_min < w_p_min) ? w_p_min : f_p_min;
     327    uint32_t f_pixel_max = (f_p_max < w_p_max) ? f_p_max : w_p_max;
     328
     329    // compute number of pixels to move from w_buffer to f_buffer
     330    uint32_t npixels = f_pixel_max - f_pixel_min;
     331
     332    // compute offset in target buffer
     333    uint32_t t_offset = f_pixel_min - f_p_min;
     334
     335    // compute line index in window 
     336    uint32_t w_line = f_line - w_l_min;
     337
     338    // compute offset in window buffer
     339    uint32_t w_offset = (w_line * w_height) + f_pixel_min - w_p_min;
     340
     341    // move pixels from w_buffer (user space) to t_buffer in kernel space
     342    hal_copy_from_uspace( XPTR( local_cxy  , &t_buffer[t_offset]  ),
     343                          &w_buffer[w_offset],
     344                          npixels );
     345
     346}  // end handle_one_window()
     347
     348////////////////////////////////////////////////////////////////////////////////////////
     349// This static function is called by dev_fbf_refresh_window(), dev_fbf_move_window(),
     350// dev_fbf_resize_window(), and dev_fbf_delete_window(). It updates all lines of the
     351// window identified by the <window_xp>, <line_first>, and <line_last>> arguments.
     352// It scan all registered windows to take into account the overlap priorities defined
     353// by the windows xlist. It does not take the lock protecting the xlist, that must be
     354// taken by the calling function.
     355////////////////////////////////////////////////////////////////////////////////////////
     356// @ window_xp  : [in]  extended pointer on window defining the FBF pixels to refresh.
     357// @ line_first : [in]  first line index.
     358// @ line_last  : [in]  last line index (excluded).
     359////////////////////////////////////////////////////////////////////////////////////////
     360error_t fbf_update( xptr_t    window_xp,
     361                    uint32_t  line_first,
     362                    uint32_t  line_last )
     363{
     364    uint32_t       line;                // iterator to scan the FBF lines
     365    uint32_t       pixel;               // iterator to scan pixels in one FBF line
     366    xptr_t         iter_xp;             // iterator to scan the list of windows
     367    error_t        error;
     368
     369    // this intermediate buffer stores one line in
     370    // target window, to handle other windows overlap
     371    uint8_t       line_buffer[CONFIG_FBF_WINDOWS_MAX_WIDTH];
     372
     373    // get pointer on calling thread and core lid
     374    thread_t  * this = CURRENT_THREAD;
     375
     376    // get window cluster and local pointer
     377    cxy_t          window_cxy = GET_CXY( window_xp );
     378    fbf_window_t * window_ptr = GET_PTR( window_xp );
     379
     380#if DEBUG_DEV_FBF
     381uint32_t wid   = hal_remote_l32( XPTR( window_cxy , &window_ptr->wid ) );
     382uint32_t lid   = this->core->lid;
     383uint32_t cycle = (uint32_t)hal_get_cycles();
     384if( DEBUG_DEV_FBF < cycle )
     385printk("\n[%s] core[%x,%d] enter / wid %d / cycle %d\n",
     386__FUNCTION__, local_cxy, lid, wid, cycle );
    96387#endif
    97388
     
    101392    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
    102393
    103 // check fbf_xp definition
    104 assert( (fbf_xp != XPTR_NULL) , "undefined FBF chdev descriptor" );
     394    // get frame buffer width
     395    uint32_t fbf_width  = hal_remote_l32( XPTR( fbf_cxy , &fbf_ptr->ext.fbf.width ) );
     396
     397    // get pointer on driver command function
     398    dev_cmd_t * cmd = hal_remote_lpt( XPTR( fbf_cxy , &fbf_ptr->cmd ) );
     399
     400    // build extended pointers on windows xlist root
     401    xptr_t  windows_root_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root );
     402
     403    // get window size and coordinates
     404    uint32_t  p_min     = hal_remote_l32( XPTR( window_cxy , &window_ptr->p_min ) );
     405    uint32_t  l_min     = hal_remote_l32( XPTR( window_cxy , &window_ptr->l_min ) );
     406    uint32_t  w_pixels  = hal_remote_l32( XPTR( window_cxy , &window_ptr->width  ) );
     407
     408    error = 0;
     409
     410    // loop on target window lines (FBF coordinates)
     411    for( line = l_min + line_first ; line < (l_min + line_last) ; line++ )
     412    {
     413        // reset the line buffer to default value
     414        for( pixel = 0 ; pixel < w_pixels ; pixel++ ) line_buffer[pixel] = 127;
     415
     416        // loop on all windows
     417        XLIST_FOREACH( windows_root_xp , iter_xp )
     418        {
     419            // get pointers on remote window
     420            xptr_t         tgt_xp  = XLIST_ELEMENT( iter_xp , fbf_window_t , xlist );
     421            fbf_window_t * tgt_ptr = GET_PTR( window_xp );
     422            cxy_t          tgt_cxy = GET_CXY( window_xp );
     423
     424            bool_t hidden = hal_remote_l32( XPTR( tgt_cxy , &tgt_ptr->hidden ) );
     425
     426            // fill the line_buf for this window if not hidden
     427            if( hidden == false ) handle_one_window( line,               // line index
     428                                                     p_min,              // pixel_min
     429                                                     p_min + w_pixels,   // pixel_max
     430                                                     tgt_xp,             // window_xp     
     431                                                     line_buffer );     
     432        }  // end for windows
     433
     434        // compute offset in FBF
     435        uint32_t fbf_offset = p_min + (line * fbf_width);
     436
     437        // register command in calling thread descriptor
     438        this->fbf_cmd.dev_xp    = fbf_xp;
     439        this->fbf_cmd.type      = FBF_DRIVER_KERNEL_WRITE;
     440        this->fbf_cmd.buffer    = line_buffer;
     441        this->fbf_cmd.npixels   = w_pixels;
     442        this->fbf_cmd.offset    = fbf_offset;
     443
     444        // call driver to display one line
     445        cmd( XPTR( local_cxy , this ) );
     446
     447        error |= this->fbf_cmd.error;
     448   
     449    }  // end for lines
     450
     451#if DEBUG_DEV_FBF
     452cycle = (uint32_t)hal_get_cycles();
     453if( DEBUG_DEV_FBF < cycle )
     454printk("\n[%s] core[%x,%d] exit / wid %d / cycle %d\n",
     455__FUNCTION__, local_cxy, this->core->lid, wid, cycle );
     456#endif
     457
     458    // return I/O operation status
     459    return error;
     460
     461}  // end fbf_update()
     462
     463//////////////////////////////////////////////
     464error_t dev_fbf_delete_window( uint32_t  wid )
     465{
     466    kmem_req_t     req;
     467
     468    thread_t  * this    = CURRENT_THREAD;
     469    process_t * process = this->process;
     470
     471#if DEBUG_DEV_FBF
     472uint32_t   cycle = (uint32_t)hal_get_cycles();
     473if( DEBUG_DEV_FBF < cycle )
     474printk("\n[%s] thread[%x,%x] enters : wid %d / cycle %d\n",
     475__FUNCTION__ , process->pid, this->trdid, wid, cycle );
     476#endif
     477
     478    // get cluster and pointers on FBF chdev
     479    xptr_t      fbf_xp  = chdev_dir.fbf[0];
     480    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
     481    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
     482
     483    // build extended pointers on windows lock, and wid allocator
     484    xptr_t windows_lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock );
     485    xptr_t wid_bitmap_xp   = XPTR( fbf_cxy ,  fbf_ptr->ext.fbf.windows_bitmap );
     486
     487    // build extended pointer on relevant entry in windows_tbl[] array
     488    xptr_t  windows_tbl_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_tbl[wid] );
     489
     490    // get extended pointer on remote window descriptor
     491    xptr_t window_xp  = hal_remote_l64( windows_tbl_xp );
     492
     493    if( window_xp == XPTR_NULL )
     494    {
     495        printk("\n[ERROR] in %s / thread[%x,%x] / wid %d non registered\n",
     496        __FUNCTION__, process->pid, this->trdid, wid );
     497        return -1;
     498    }
     499
     500    // get cluster and local pointer on remote window
     501    cxy_t          window_cxy = GET_CXY( window_xp );
     502    fbf_window_t * window_ptr = GET_PTR( window_xp );
     503
     504    // get process owner PID
     505    pid_t owner_pid = hal_remote_l32( XPTR( window_cxy , &window_ptr->pid ) );
     506
     507    // check caller PID / owner PID
     508    if( owner_pid != process->pid )
     509    {
     510        printk("\n[ERROR] in %s : caller PID (%x) != owner PID (%x)\n",
     511        __FUNCTION__, process->pid , owner_pid );
     512        return -1;
     513    }
     514
     515    // get associated buffer, and number of lines
     516    uint8_t  * buffer = hal_remote_lpt( XPTR( window_cxy , &window_ptr->buffer ) );
     517    uint32_t   nlines = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) );
     518
     519    // 1. take the lock protecting windows in write mode
     520    remote_rwlock_wr_acquire( windows_lock_xp );
     521
     522    // 2. update the FBF window
     523    fbf_update( window_xp , 0 , nlines );
     524
     525    // 3. remove the window from windows_tbl[] array
     526    hal_remote_s64( windows_tbl_xp , XPTR_NULL );
     527
     528    // 4. remove the window from xlist     
     529    xlist_unlink( XPTR( window_cxy , &window_ptr->xlist ) );
     530
     531    // 5. release wid to bitmap
     532    bitmap_remote_clear( wid_bitmap_xp , wid );
     533
     534    // 6. release the lock protecting windows in write mode
     535    remote_rwlock_wr_release( windows_lock_xp );
     536 
     537    // 7. release memory allocated for window descriptor
     538    req.type = KMEM_KCM;
     539    req.ptr  = window_ptr;
     540    kmem_remote_free( window_cxy , &req );
     541
     542    // 8. release the associated vseg
     543    vmm_global_delete_vseg( process , (intptr_t)buffer );
     544   
     545#if DEBUG_DEV_FBF
     546cycle = (uint32_t)hal_get_cycles();
     547if( DEBUG_DEV_FBF < cycle )
     548printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
     549__FUNCTION__ , process->pid, this->trdid, cycle );
     550#endif
     551
     552    return 0;
     553
     554}  // end dev_fbf_delete_window()
     555
     556////////////////////////////////////////////
     557error_t dev_fbf_move_window( uint32_t  wid,
     558                             uint32_t  l_min,
     559                             uint32_t  p_min )
     560{
     561    thread_t  * this    = CURRENT_THREAD;
     562    process_t * process = this->process;
     563
     564#if DEBUG_DEV_FBF
     565uint32_t   cycle = (uint32_t)hal_get_cycles();
     566if( DEBUG_DEV_FBF < cycle )
     567printk("\n[%s] thread[%x,%x] enters : wid %d / l_min %d / p_min %d / cycle %d\n",
     568__FUNCTION__ , process->pid, this->trdid, wid, l_min, p_min, cycle );
     569#endif
     570
     571    // get cluster and pointers on FBF chdev
     572    xptr_t      fbf_xp  = chdev_dir.fbf[0];
     573    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
     574    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
     575
     576    // build extended pointers on windows lock and root
     577    xptr_t windows_lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock );
     578    xptr_t windows_root_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root );
     579
     580    // build extended pointer on relevant entry in windows_tbl[] array
     581    xptr_t  windows_tbl_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_tbl[wid] );
     582
     583    // get extended pointer on remote window descriptor
     584    xptr_t window_xp  = hal_remote_l64( windows_tbl_xp );
     585
     586    if( window_xp == XPTR_NULL )
     587    {
     588        printk("\n[ERROR] in %s / thread[%x,%x] / wid %d non registered\n",
     589        __FUNCTION__, process->pid, this->trdid, wid );
     590        return -1;
     591    }
     592
     593    // get cluster and local pointer for remote window
     594    cxy_t          window_cxy = GET_CXY( window_xp );
     595    fbf_window_t * window_ptr = GET_PTR( window_xp );
     596
     597    // get process owner PID, coordinates, and number of lines
     598    pid_t    owner_pid = hal_remote_l32( XPTR( window_cxy , &window_ptr->pid ) );
     599    uint32_t p_zero    = hal_remote_l32( XPTR( window_cxy , &window_ptr->p_min ) );
     600    uint32_t l_zero    = hal_remote_l32( XPTR( window_cxy , &window_ptr->l_min ) );
     601    uint32_t nlines    = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) );
     602
     603    // check caller PID / owner PID
     604    if( owner_pid != process->pid )
     605    {
     606        printk("\n[ERROR] in %s : caller PID (%x) != owner PID (%x)\n",
     607        __FUNCTION__, process->pid , owner_pid );
     608        return -1;
     609    }
     610
     611    // does nothing if no change
     612    if( (p_zero == p_min) && (l_zero == l_min) )  return 0;
     613
     614    // 1. take the lock protecting windows in write mode
     615    remote_rwlock_wr_acquire( windows_lock_xp );
     616
     617#if ( DEBUG_DEV_FBF & 1 )
     618printk("\n[%s] lock taken\n", __FUNCTION__ );
     619#endif
     620
     621    // 2. gives the window the lowest priority
     622    xptr_t xlist_entry_xp =  XPTR( window_cxy , &window_ptr->xlist );
     623    xlist_unlink( xlist_entry_xp );
     624    xlist_add_first( windows_root_xp , xlist_entry_xp );
     625
     626#if ( DEBUG_DEV_FBF & 1 )
     627printk("\n[%s] set low priority \n", __FUNCTION__ );
     628#endif
     629
     630    // 3. set the "hidden" flag in window descriptor
     631    hal_remote_s32( XPTR( window_cxy , &window_ptr->hidden ) , true );
     632
     633#if ( DEBUG_DEV_FBF & 1 )
     634printk("\n[%s] hidden set\n", __FUNCTION__ );
     635#endif
     636
     637    // 4. refresh the FBF for the current window position
     638    fbf_update( window_xp , 0 , nlines );
     639
     640#if ( DEBUG_DEV_FBF & 1 )
     641printk("\n[%s] refreshed old position\n", __FUNCTION__ );
     642#endif
     643
     644    // 5. set the new coordinates in the window descriptor,
     645    hal_remote_s32( XPTR( window_cxy , &window_ptr->l_min ), l_min );
     646    hal_remote_s32( XPTR( window_cxy , &window_ptr->p_min ), p_min );
     647
     648#if ( DEBUG_DEV_FBF & 1 )
     649printk("\n[%s] l_min & p_min updated\n", __FUNCTION__ );
     650#endif
     651
     652    // 6. gives the window the highest priority
     653    xlist_unlink( xlist_entry_xp );
     654    xlist_add_last( windows_root_xp , xlist_entry_xp );
     655
     656#if ( DEBUG_DEV_FBF & 1 )
     657printk("\n[%s] set high priority\n", __FUNCTION__ );
     658#endif
     659
     660    // 7. reset the "hidden" flag in window descriptor
     661    hal_remote_s32( XPTR( window_cxy , &window_ptr->hidden ) , false );
     662
     663#if ( DEBUG_DEV_FBF & 1 )
     664printk("\n[%s] hidden reset\n", __FUNCTION__ );
     665#endif
     666
     667    // 8. refresh the FBF for the new window position
     668    fbf_update( window_xp , 0 , nlines );
     669
     670#if ( DEBUG_DEV_FBF & 1 )
     671printk("\n[%s] refresh new position\n", __FUNCTION__ );
     672#endif
     673
     674    // 9. release the lock protecting windows in write mode
     675    remote_rwlock_wr_release( windows_lock_xp );
     676 
     677#if DEBUG_DEV_FBF
     678cycle = (uint32_t)hal_get_cycles();
     679if( DEBUG_DEV_FBF < cycle )
     680printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
     681__FUNCTION__ , process->pid, this->trdid, cycle );
     682#endif
     683
     684    return 0;
     685
     686}  // end dev_fbf_move_window()
     687
     688/////////////////////////////////////////////
     689error_t dev_fbf_resize_window( uint32_t  wid,
     690                               uint32_t  width,
     691                               uint32_t  height )
     692{
     693    thread_t  * this    = CURRENT_THREAD;
     694    process_t * process = this->process;
     695
     696#if DEBUG_DEV_FBF
     697uint32_t   cycle = (uint32_t)hal_get_cycles();
     698if( DEBUG_DEV_FBF < cycle )
     699printk("\n[%s] thread[%x,%x] enters : wid %d / width %d / height %d / cycle %d\n",
     700__FUNCTION__ , process->pid , this->trdid , wid, width , height , cycle );
     701#endif
     702
     703    // get cluster and pointers on FBF chdev
     704    xptr_t      fbf_xp  = chdev_dir.fbf[0];
     705    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
     706    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
     707
     708    // build extended pointers on windows lock and root
     709    xptr_t windows_lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock );
     710    xptr_t windows_root_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root );
     711
     712    // build extended pointer on relevant entry in windows_tbl[] array
     713    xptr_t  windows_tbl_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_tbl[wid] );
     714
     715    // get extended pointer on remote window descriptor
     716    xptr_t window_xp  = hal_remote_l64( windows_tbl_xp );
     717
     718    if( window_xp == XPTR_NULL )
     719    {
     720        printk("\n[ERROR] in %s / thread[%x,%x] / wid %d non registered\n",
     721        __FUNCTION__, process->pid, this->trdid, wid );
     722        return -1;
     723    }
     724
     725    // get cluster and local pointer for remote window
     726    cxy_t          window_cxy = GET_CXY( window_xp );
     727    fbf_window_t * window_ptr = GET_PTR( window_xp );
     728
     729    // get process owner PID, width, height, and buffer
     730    pid_t    owner_pid = hal_remote_l32( XPTR( window_cxy , &window_ptr->pid ) );
     731    uint32_t nlines    = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) );
     732    uint32_t npixels   = hal_remote_l32( XPTR( window_cxy , &window_ptr->width ) );
     733    void   * base      = hal_remote_lpt( XPTR( window_cxy , &window_ptr->buffer ) );
     734
     735    // check caller PID / owner PID
     736    if( owner_pid != process->pid )
     737    {
     738        printk("\n[ERROR] in %s : caller PID (%x) != owner PID (%x)\n",
     739        __FUNCTION__, process->pid , owner_pid );
     740        return -1;
     741    }
     742
     743    // does nothing if no change
     744    if( (width == npixels) && (height == nlines) ) return 0;
     745
     746    // compute old_size and new size
     747    uint32_t old_size = nlines * npixels;
     748    uint32_t new_size = width * height;
     749
     750    // 1. take the lock protecting windows in write mode
     751    remote_rwlock_wr_acquire( windows_lock_xp );
     752
     753#if ( DEBUG_DEV_FBF & 1 )
     754printk("\n[%s] lock taken\n", __FUNCTION__ );
     755#endif
     756
     757    // 2. gives the window the lowest priority (remove, then add first)
     758    xptr_t xlist_entry_xp =  XPTR( window_cxy , &window_ptr->xlist );
     759    xlist_unlink( xlist_entry_xp );
     760    xlist_add_first( windows_root_xp , xlist_entry_xp );
     761
     762#if ( DEBUG_DEV_FBF & 1 )
     763printk("\n[%s] set low priority\n", __FUNCTION__ );
     764#endif
     765
     766    // 3. set the "hidden" flag in window descriptor
     767    hal_remote_s32( XPTR( window_cxy , &window_ptr->hidden ) , true );
     768
     769#if ( DEBUG_DEV_FBF & 1 )
     770printk("\n[%s] hidden set\n", __FUNCTION__ );
     771#endif
     772
     773    // 4. refresh the FBF for the current window size
     774    fbf_update( window_xp , 0 , nlines );
     775
     776#if ( DEBUG_DEV_FBF & 1 )
     777printk("\n[%s] refreshed old window\n", __FUNCTION__ );
     778#endif
     779
     780    // 5. set the new width & height in the window descriptor,
     781    hal_remote_s32( XPTR( window_cxy , &window_ptr->width  ), width );
     782    hal_remote_s32( XPTR( window_cxy , &window_ptr->height ), height );
     783
     784#if ( DEBUG_DEV_FBF & 1 )
     785printk("\n[%s] width & height updated\n", __FUNCTION__ );
     786#endif
     787
     788    // 6. resize vseg if required
     789    vmm_global_resize_vseg( process, (intptr_t)base, (intptr_t)base, width * height );
     790
     791#if ( DEBUG_DEV_FBF & 1 )
     792printk("\n[%s] vseg resized\n", __FUNCTION__ );
     793#endif
     794
     795    // 7. fill buffer extension if required
     796    if( new_size > old_size )  memset( base + old_size , 0 , new_size - old_size );
     797
     798#if ( DEBUG_DEV_FBF & 1 )
     799printk("\n[%s] buffer extension initialized\n", __FUNCTION__ );
     800#endif
     801
     802    // 8. gives the window the highest priority
     803    xlist_unlink( xlist_entry_xp );
     804    xlist_add_last( windows_root_xp , xlist_entry_xp );
     805
     806#if ( DEBUG_DEV_FBF & 1 )
     807printk("\n[%s] set high priority\n", __FUNCTION__ );
     808#endif
     809
     810    // 9. reset the "hidden" flag in window descriptor
     811    hal_remote_s32( XPTR( window_cxy , &window_ptr->hidden ) , false );
     812
     813#if ( DEBUG_DEV_FBF & 1 )
     814printk("\n[%s] hidden reset\n", __FUNCTION__ );
     815#endif
     816
     817    // 10. refresh the FBF for the new window position
     818    fbf_update( window_xp , 0 , height );
     819
     820#if ( DEBUG_DEV_FBF & 1 )
     821printk("\n[%s] refresh new position\n", __FUNCTION__ );
     822#endif
     823
     824    // 11. release the lock protecting windows in write mode
     825    remote_rwlock_wr_release( windows_lock_xp );
     826 
     827#if DEBUG_DEV_FBF
     828cycle = (uint32_t)hal_get_cycles();
     829if( DEBUG_DEV_FBF < cycle )
     830printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
     831__FUNCTION__ , process->pid, this->trdid, cycle );
     832#endif
     833
     834    return 0;
     835
     836}  // end dev_fbf_resize_window()
     837
     838///////////////////////////////////////////////
     839error_t dev_fbf_refresh_window( uint32_t  wid,
     840                                uint32_t  line_first,
     841                                uint32_t  line_last )
     842{
     843    // get local pointers on calling thread and process
     844    thread_t  * this    = CURRENT_THREAD;
     845    process_t * process = this->process;
     846
     847#if DEBUG_DEV_FBF
     848uint32_t   cycle = (uint32_t)hal_get_cycles();
     849if( DEBUG_DEV_FBF < cycle )
     850printk("\n[%s] thread[%x,%x] enters for wid %d / first %d / last %d / cycle %d\n",
     851__FUNCTION__ , process->pid, this->trdid, wid, line_first, line_last, cycle );
     852#endif
     853
     854    // get cluster and pointers on FBF chdev
     855    xptr_t      fbf_xp  = chdev_dir.fbf[0];
     856    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
     857    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
     858
     859    // build extended pointer on windows lock
     860    xptr_t  windows_lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock );
     861
     862    // build extended pointer on relevant entry in windows_tbl[] array
     863    xptr_t  windows_tbl_xp  = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_tbl[wid] );
     864
     865    // get pointers on remote window descriptor
     866    xptr_t         window_xp  = hal_remote_l64( windows_tbl_xp );
     867    cxy_t          window_cxy = GET_CXY( window_xp );
     868    fbf_window_t * window_ptr = GET_PTR( window_xp );
     869
     870    // check <wid> argument
     871    if( window_xp == XPTR_NULL )
     872    {
     873        printk("\n[ERROR] in %s / thread[%x,%x] / wid %d non registered\n",
     874        __FUNCTION__, process->pid, this->trdid, wid );
     875        return -1;
     876    }
     877
     878    // get process owner PID
     879    pid_t owner_pid = hal_remote_l32( XPTR( window_cxy , &window_ptr->pid ) );
     880
     881    // check caller PID / owner PID
     882    if( owner_pid != process->pid )
     883    {
     884        printk("\n[ERROR] in %s : caller PID (%x) != owner PID (%x)\n",
     885        __FUNCTION__, process->pid , owner_pid );
     886        return -1;
     887    }
     888
     889    // get number of lines in window
     890    uint32_t nlines = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) );
     891
     892    // check <line_first> and <line_last> arguments
     893    if( (line_first >= nlines) || (line_last > nlines) || (line_first >= line_last) )
     894    {
     895        printk("\n[ERROR] in %s : illegal (l_first %d , l_last %d) / height %d\n",
     896        __FUNCTION__, line_first, line_last, nlines );
     897        return -1;
     898    }
     899
     900    // take the lock protecting windows xlist in read mode
     901    remote_rwlock_rd_acquire( windows_lock_xp );
     902
     903    // update FBF
     904    fbf_update( window_xp , line_first , line_last );
     905
     906    // release the lock protecting windows xlist in write mode
     907    remote_rwlock_rd_release( windows_lock_xp );
     908
     909#if DEBUG_DEV_FBF
     910cycle = (uint32_t)hal_get_cycles();
     911if( DEBUG_DEV_FBF < cycle )
     912printk("\n[%s] thread[%x,%x] exit for wid %d / cycle %d\n",
     913__FUNCTION__, process->pid, this->trdid, wid, cycle );
     914#endif
     915
     916    return 0;
     917
     918}  // end dev_fbf_refresh_window()
     919
     920///////////////////////////////////////////////
     921// TODO Deprecated : january 2020 [AG]
     922///////////////////////////////////////////////
     923error_t dev_fbf_move_data( bool_t     is_write,
     924                           void     * user_buffer,
     925                           uint32_t   npixels,
     926                           uint32_t   offset )
     927{
     928    // get pointer on calling thread
     929    thread_t * this = CURRENT_THREAD;
     930
     931#if DEBUG_DEV_FBF
     932uint32_t   cycle = (uint32_t)hal_get_cycles();
     933if( DEBUG_DEV_FBF < cycle )
     934printk("\n[%s] thread[%x,%x] :  buffer %x / npixels %d / offset %x / cycle %d\n",
     935__FUNCTION__ , this->process->pid, this->trdid, 
     936user_buffer, npixels, offset, cycle );
     937#endif
     938
     939    // get pointers on FBF chdev
     940    xptr_t      fbf_xp  = chdev_dir.fbf[0];
     941    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
     942    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
    105943
    106944    // get frame buffer width and height
     
    108946    uint32_t height = hal_remote_l32 ( XPTR( fbf_cxy , &fbf_ptr->ext.fbf.height ) );
    109947
    110 // check offset and length versus FBF size
    111 assert( ((offset + length) <= (width * height)) ,
    112 "offset %d / length %d / width %d / height %d\n", offset, length, width, height );
     948    // check offset and npixels versus FBF size
     949    if( ((offset + npixels) > (width * height)) )
     950    {
     951        printk("\n[ERROR] in %s : offset (%d) + npixels (%d) / width (%d) / height (%d)\n",
     952        __FUNCTION__, offset, npixels, width, height );
     953        return -1;
     954    }
    113955
    114956    // register command in calling thread descriptor
    115957    this->fbf_cmd.dev_xp    = fbf_xp;
    116     this->fbf_cmd.type      = cmd_type;
     958    this->fbf_cmd.type      = is_write ? FBF_DRIVER_USER_WRITE : FBF_DRIVER_USER_READ;
    117959    this->fbf_cmd.buffer    = user_buffer;
    118960    this->fbf_cmd.offset    = offset;
    119     this->fbf_cmd.length    = length;
     961    this->fbf_cmd.npixels   = npixels;
    120962
    121963    // get driver command function
     
    130972cycle = (uint32_t)hal_get_cycles();
    131973if( DEBUG_DEV_FBF < cycle )
    132 printk("\n[%s] thread[%x,%x] completes %s / error = %d / cycle %d\n",
    133 __FUNCTION__ , this->process->pid, this->trdid, 
    134 dev_fbf_cmd_str(cmd_type), error , cycle );
     974printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
     975__FUNCTION__ , this->process->pid, this->trdid, cycle );
    135976#endif
    136977
     
    139980
    140981}  // end dev_fbf_move_data()
     982
     983
Note: See TracChangeset for help on using the changeset viewer.