source: trunk/kernel/devices/dev_fbf.c @ 674

Last change on this file since 674 was 674, checked in by alain, 3 years ago

1) Introduce up to 4 command lines arguments in the KSH "load" command.
These arguments are transfered to the user process through the
argc/argv mechanism, using the user space "args" vseg.

2) Introduce the named and anonymous "pipes", for inter-process communication
through the pipe() and mkfifo() syscalls.

3) Introduce the "chat" application to validate the two above mechanisms.

4) Improve printk() and assert() fonctions in printk.c.

File size: 40.5 KB
Line 
1/*
2 * dev_fbf.c - FBF (Frame Buffer) generic device API implementation.
3 *
4 * Author  Alain Greiner    (2016,2017,2018,2019,2020)
5 *
6 * Copyright (c) UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MK
9 *
10 * ALMOS-MKH.is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH.is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-kernel; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#include <kernel_config.h>
25#include <hal_kernel_types.h>
26#include <hal_gpt.h>
27#include <hal_drivers.h>
28#include <hal_irqmask.h>
29#include <hal_macros.h>
30#include <hal_uspace.h>
31#include <hal_vmm.h>
32#include <thread.h>
33#include <printk.h>
34#include <string.h>
35#include <memcpy.h>
36#include <chdev.h>
37#include <dev_fbf.h>
38
39/////////////////////////////////////////////////////////////////////////////////////////
40// Extern global variables
41/////////////////////////////////////////////////////////////////////////////////////////
42
43extern chdev_directory_t  chdev_dir;         // allocated in kernel_init.c
44
45///////////////////////////////////////////
46char * dev_fbf_cmd_str( uint32_t cmd_type )
47{
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_ACTIVE_WINDOW  )  return "ACTIVE_WINDOW";
51    else if( cmd_type == FBF_DELETE_WINDOW  )  return "DELETE_WINDOW";
52    else if( cmd_type == FBF_MOVE_WINDOW    )  return "MOVE_WINDOW";
53    else if( cmd_type == FBF_REFRESH_WINDOW )  return "REFRESH_WINDOW";
54    else if( cmd_type == FBF_FRONT_WINDOW   )  return "FRONT_WINDOW";
55    else if( cmd_type == FBF_RESIZE_WINDOW  )  return "RESIZE_WINDOW";
56
57    else if( cmd_type == FBF_DIRECT_WRITE   )  return "DIRECT_WRITE";
58    else if( cmd_type == FBF_DIRECT_READ    )  return "DIRECT_READ";
59    else                                       return "undefined";
60}
61
62////////////////////////////////////////////////
63xptr_t dev_fbf_get_xptr_from_wid( uint32_t wid )
64{
65    thread_t  * this  = CURRENT_THREAD;
66    pid_t       pid   = this->process->pid;
67    trdid_t     trdid = this->trdid;
68
69    // get cluster and pointers on FBF chdev
70    xptr_t      fbf_xp  = chdev_dir.fbf[0];
71    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
72    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
73
74    // build extended pointer on windows_tbl[wid]
75    xptr_t entry_xp  = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_tbl[wid] );
76
77    // get pointers on searched window
78    xptr_t         window_xp  = hal_remote_l64( entry_xp );
79    cxy_t          window_cxy = GET_CXY( window_xp );
80    fbf_window_t * window_ptr = GET_PTR( window_xp );
81
82    if( window_xp == XPTR_NULL )
83    {
84        printk("\n[ERROR] in %s / client thread[%x,%x] request a non registered wid (%d)\n",
85        __FUNCTION__, pid, trdid, wid );
86        return XPTR_NULL;
87    }
88
89    // get owner process PID from window descriptor
90    pid_t owner_pid = hal_remote_l32( XPTR( window_cxy , &window_ptr->pid ) );
91
92    if( pid != owner_pid )
93    {
94        printk("\n[ERROR] in %s / client thread[%x,%x] not owner of wid (%d) / owner is (%x)\n",
95        __FUNCTION__, pid, trdid, owner_pid, wid );
96        return XPTR_NULL;
97    }
98
99    return window_xp;
100
101}  // end dev_fbf_get_xptr_from_wid()
102
103////////////////////////////////////
104void dev_fbf_init( chdev_t  * fbf )
105{
106    uint32_t wid;
107
108    // set chdev name
109    strcpy( fbf->name, "fbf" );
110
111    // initialize lock protecting the windows
112    remote_rwlock_init( XPTR( local_cxy , &fbf->ext.fbf.windows_lock ),
113                        LOCK_FBF_WINDOWS ); 
114
115    // initialize root of windows xlist
116    xlist_root_init( XPTR( local_cxy , &fbf->ext.fbf.windows_root ) );
117
118    // initialize windows_tbl[] array
119    for( wid = 0 ; wid < CONFIG_FBF_WINDOWS_MAX_NR ; wid++ ) 
120    {
121        fbf->ext.fbf.windows_tbl[wid] = XPTR_NULL;
122    }
123
124    // initialize wid allocator bitmap
125    bitmap_init( fbf->ext.fbf.windows_bitmap , CONFIG_FBF_WINDOWS_MAX_NR );
126
127    // call driver init function to initialize the harware FBF
128    // and initialize the width, height, and subsampling FBF chdev fields
129    hal_drivers_fbf_init( fbf );
130
131}  // end dev_fbf_init()
132
133//////////////////////////////////////////
134void dev_fbf_get_config( uint32_t * width,
135                         uint32_t * height,
136                         uint32_t * type )
137{
138    // get extended pointer on FBF chdev descriptor
139    xptr_t  dev_xp = chdev_dir.fbf[0];
140
141assert( __FUNCTION__, (dev_xp != XPTR_NULL) , "undefined FBF chdev descriptor" );
142
143    // get FBF chdev cluster and local pointer
144    cxy_t     dev_cxy = GET_CXY( dev_xp );
145    chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp );
146
147    // return values
148    *width  = hal_remote_l32( XPTR( dev_cxy , &dev_ptr->ext.fbf.width ) );
149    *height = hal_remote_l32( XPTR( dev_cxy , &dev_ptr->ext.fbf.height ) );
150    *type   = hal_remote_l32( XPTR( dev_cxy , &dev_ptr->ext.fbf.subsampling ) );
151
152}  // end dev_fbf_get_config()
153
154/////////////////////////////////////////////////
155uint32_t dev_fbf_create_window( uint32_t   nlines,
156                                uint32_t   npixels,
157                                uint32_t   l_min,
158                                uint32_t   p_min,
159                                intptr_t * user_buffer )
160{
161    kmem_req_t     req;
162    fbf_window_t * window;      // window descriptor (created in local cluster)
163    vseg_t       * vseg;        // vseg descriptor (created in reference cluster)
164    intptr_t       vseg_base;   // vseg base address in user space 
165
166    // get local pointers on calling thread and process
167    thread_t  * this    = CURRENT_THREAD;
168    process_t * process = this->process;
169
170#if DEBUG_DEV_FBF
171uint32_t   cycle = (uint32_t)hal_get_cycles();
172if( DEBUG_DEV_FBF < cycle )
173printk("\n[%s] thread[%x,%x] enter : nlines %d / npixels %d / l_min %d / p_min %d / cycle %d\n",
174__FUNCTION__ , process->pid, this->trdid, nlines, npixels, l_min, p_min, cycle );
175#endif
176
177    // get cluster and pointers on FBF chdev
178    xptr_t      fbf_xp  = chdev_dir.fbf[0];
179    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
180    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
181
182// check fbf_xp definition
183assert( __FUNCTION__, (fbf_xp != XPTR_NULL) , "undefined FBF chdev descriptor" );
184
185    // get FBF width and height
186    uint32_t fbf_width  = hal_remote_l32( XPTR( fbf_cxy , &fbf_ptr->ext.fbf.width ) );
187    uint32_t fbf_height = hal_remote_l32( XPTR( fbf_cxy , &fbf_ptr->ext.fbf.height ) );
188
189    // check new window size and coordinates
190    if( (((l_min + nlines) > fbf_height) || ((p_min + npixels) > fbf_width)) )
191    {
192        printk("\n[ERROR] in %s / thread[%x,%x]" 
193        "illegal new coordinates (%d,%d) for window (%d,%d) in fbf (%d,%d)\n",
194        process->pid, this->trdid, p_min, l_min, npixels, nlines, fbf_width, fbf_height );
195        return -1;
196    }
197
198    // build extended pointers on windows lock, root, and wid allocator
199    xptr_t windows_lock_xp   = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock );
200    xptr_t windows_root_xp   = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root );
201    xptr_t windows_bitmap_xp = XPTR( fbf_cxy ,  fbf_ptr->ext.fbf.windows_bitmap );
202 
203    // allocate memory for the window descriptor in local cluster
204    req.type   = KMEM_KCM;
205    req.order  = bits_log2( sizeof(fbf_window_t) );
206    req.flags  = AF_ZERO | AF_KERNEL;
207    window     = kmem_alloc( &req );
208
209    if( window == NULL )
210    {
211        printk("\n[ERROR] in %s / thread[%x,%x] cannot allocate window descriptor\n",
212        __FUNCTION__, process->pid, this->trdid );
213        return -1;
214    }
215
216#if (DEBUG_DEV_FBF & 1)
217cycle = (uint32_t)hal_get_cycles();
218if( DEBUG_DEV_FBF < cycle )
219printk("\n[%s] thread[%x,%x] created window descriptor %x / cycle %d\n",
220__FUNCTION__ , process->pid, this->trdid, window, cycle );
221#endif
222
223    // getpointers on reference process
224    xptr_t      ref_xp  = process->ref_xp;
225    process_t * ref_ptr = GET_PTR( ref_xp );
226    cxy_t       ref_cxy = GET_CXY( ref_xp );
227
228    // allocate a new vseg, and introduce it in the reference process VSL
229    if( ref_cxy == local_cxy )
230    {
231        vseg = vmm_create_vseg( process,            // owner process
232                                VSEG_TYPE_ANON,     // localised, public
233                                0,                  // base, unused for ANON
234                                nlines * npixels,   // size
235                                0,                  // file_offset, unused for ANON
236                                0,                  // file_size, unused for ANON
237                                XPTR_NULL,          // mapper_xp, unused for ANON
238                                local_cxy );        // mapping cluster
239    }
240    else
241    {
242        rpc_vmm_create_vseg_client( ref_cxy,
243                                    ref_ptr,
244                                    VSEG_TYPE_ANON,
245                                    0,                 // base, unused for ANON
246                                    nlines * npixels,  // size
247                                    0,                 // file_offset, unused for ANON
248                                    0,                 // file size, unused for ANON
249                                    XPTR_NULL,         // mapper_xp, unused for ANON
250                                    local_cxy,
251                                    &vseg );
252    } 
253       
254    if( vseg == NULL )
255    {
256        printk("\n[ERROR] in %s / thread[%x,%x] cannot create vseg in reference cluster\n",
257        __FUNCTION__, process->pid, this->trdid );
258        req.ptr = (void *)window;
259        kmem_free( &req );
260        return -1;
261    }
262
263    // get vseg base
264    vseg_base = (intptr_t)hal_remote_lpt( XPTR( ref_cxy , &vseg->min ) );
265
266#if (DEBUG_DEV_FBF & 1)
267cycle = (uint32_t)hal_get_cycles();
268if( DEBUG_DEV_FBF < cycle )
269printk("\n[%s] thread[%x,%x] allocated vseg / base %x / cycle %d\n",
270__FUNCTION__ , process->pid, this->trdid, vseg_base, cycle );
271#endif
272
273    // take the lock protecting windows in write mode
274    remote_rwlock_wr_acquire( windows_lock_xp );
275
276    // allocate a wid from allocator in FBF descriptor extension
277    uint32_t wid = bitmap_remote_alloc( windows_bitmap_xp , CONFIG_FBF_WINDOWS_MAX_NR );
278
279    if( wid == 0xFFFFFFFF )
280    {
281        printk("\n[ERROR] in %s / thread[%x,%x] cannot allocate buffer for window\n",
282        __FUNCTION__, process->pid, this->trdid );
283        req.ptr = (void *)window;
284        kmem_free( &req );
285        vmm_remove_vseg( process , vseg );
286        return -1;
287    }
288 
289    // initialize window descriptor
290    window->pid     = process->pid;
291    window->wid     = wid;
292    window->height  = nlines;
293    window->width   = npixels;
294    window->l_min   = l_min;
295    window->p_min   = p_min;
296    window->hidden  = true;
297    window->buffer  = (uint8_t *)vseg_base;
298
299    // register new window in xlist rooted in FBF extension
300    xlist_add_last( windows_root_xp , XPTR( local_cxy , &window->xlist ) );
301
302    // build extended pointer on relevant entry in windows_tbl[] array
303    xptr_t windows_tbl_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_tbl[wid] );
304
305    // register new window in windows_tbl[] stored in FBF extension
306    hal_remote_s64( windows_tbl_xp , XPTR( local_cxy , window ) );
307
308    // release the lock protecting windows in write mode
309    remote_rwlock_wr_release( windows_lock_xp );
310
311#if DEBUG_DEV_FBF
312cycle = (uint32_t)hal_get_cycles();
313if( DEBUG_DEV_FBF < cycle )
314printk("\n[%s] thread[%x,%x] exit / wid %d / buffer %x / cycle %d\n",
315__FUNCTION__ , this->process->pid, this->trdid, wid , window->buffer, cycle );
316#endif
317
318    // return pointer on allocated buffer
319    *user_buffer = vseg_base;
320
321    return wid;
322
323}  // end dev_fbf_create_window()
324
325/////////////////////////////////////////////
326error_t dev_fbf_active_window( uint32_t  wid,
327                               uint32_t  active )
328{
329
330#if DEBUG_DEV_FBF
331thread_t  * thi   = CURRENT_THREAD;
332uint32_t    cycle = (uint32_t)hal_get_cycles();
333if( DEBUG_DEV_FBF < cycle )
334printk("\n[%s] thread[%x,%x] enters : wid %d / active %d / cycle %d\n",
335__FUNCTION__ , this->process->pid, this->trdid, wid, active, cycle );
336#endif
337
338    // get extended pointer on window to be activated
339    xptr_t window_xp  = dev_fbf_get_xptr_from_wid( wid );
340
341    if( window_xp == XPTR_NULL ) return -1;
342
343    // get cluster and local pointer on target window
344    cxy_t          window_cxy = GET_CXY( window_xp );
345    fbf_window_t * window_ptr = GET_PTR( window_xp );
346
347    // set/reset hidden flag in window descriptor
348    hal_remote_s32( XPTR( window_cxy , &window_ptr->hidden ) , (active == 0) ? 1 : 0 );
349
350#if DEBUG_DEV_FBF
351cycle = (uint32_t)hal_get_cycles();
352if( DEBUG_DEV_FBF < cycle )
353printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
354__FUNCTION__ , this->process->pid, this->trdid, cycle );
355#endif
356
357    return 0;
358
359}  // end dev_fbf_active_window()
360
361////////////////////////////////////////////////////////////////////////////////////////
362// This static function is called by dev_fbf_refresh_window(), dev_fbf_move_window(),
363// dev_fbf_front_window(), dev_fbf_delete_window(), and dev_fbf_resize_window().
364// It updates all lines of a pseudo window identified by the <p_min>, <p_max>, <l_min>,
365// and <l_max> arguments, that are dynamically computed by the caller.
366// This function scan all registered windows to take into account the overlap priorities
367// defined by the FBF xlist of windows. It takes the lock protecting xlist in read mode.
368////////////////////////////////////////////////////////////////////////////////////////
369// Implementation Note:
370// This function contains two loops.
371// - the external loop builds one line of the pseudo window per iteraiion in a local
372//   line_buffer. One line  contains [p_max - p_min] pixels. Then, it calls the FBF
373//   driver (one driver call per line) to write this line into the Frame Buffer.
374// - the internal loop scan the list of the registered windows in increasing priority,
375//   and for each registered window that has a non empty intersection with the handled
376//   line, it updates the line_buffer, using the hal_copy_from_uspace() function
377//   to get the most up-to-date user-defined data.
378////////////////////////////////////////////////////////////////////////////////////////
379// @ p_min   : [in]  upper left corner X coordinate in FBF reference
380// @ p_max   : [in]  upper left corner Y coordinate in FBF reference.
381// @ l_min   : [in]  lower right corner X coordinate in FBF reference (excluded).
382// @ l_max   : [in]  lower right corner Y coordinate in FBF reference (excluded).
383////////////////////////////////////////////////////////////////////////////////////////
384error_t fbf_update( uint32_t    p_min,
385                    uint32_t    l_min,
386                    uint32_t    p_max,
387                    uint32_t    l_max )
388{
389    uint32_t       line;                     // iterator to scan the FBF lines
390    uint32_t       pixel;                    // iterator to scan pixels in one FBF line
391    xptr_t         iter_xp;                  // iterator to scan the list of windows
392    error_t        error;
393
394    // this intermediate buffer to build one pseudo-window line
395    uint8_t  line_buffer[CONFIG_FBF_WINDOWS_MAX_WIDTH];
396
397    // get pointer on calling thread and core lid
398    thread_t  * this = CURRENT_THREAD;
399
400#if DEBUG_DEV_FBF
401uint32_t cycle = (uint32_t)hal_get_cycles();
402if( DEBUG_DEV_FBF < cycle )
403printk("\n[%s] enter : p_min %d / l_min %d / p_max %d / l_max %d / cycle %d\n",
404__FUNCTION__, p_min, l_min, p_max, l_max, cycle );
405#endif
406
407    // get pointers on FBF chdev
408    xptr_t      fbf_xp  = chdev_dir.fbf[0];
409    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
410    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
411
412    // get frame buffer width and height
413    uint32_t fbf_width  = hal_remote_l32( XPTR( fbf_cxy , &fbf_ptr->ext.fbf.width ) );
414    uint32_t fbf_height = hal_remote_l32( XPTR( fbf_cxy , &fbf_ptr->ext.fbf.height ) );
415
416// check arguments
417assert( __FUNCTION__, (p_min < fbf_width)  && (p_max <= fbf_width) && 
418        (l_min < fbf_height) && (l_max <= fbf_height) , "illegal arguments" );
419
420    // get pointer on driver command function
421    dev_cmd_t * cmd = hal_remote_lpt( XPTR( fbf_cxy , &fbf_ptr->cmd ) );
422
423    // build extended pointers on windows xlist root and lock
424    xptr_t  windows_root_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root );
425    xptr_t  windows_lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock );
426
427    error = 0;
428
429    // 1. external loop on pseudo window lines (in FBF reference)
430    for( line = l_min ; line < l_max ; line++ )
431    {
432        // reset the line buffer to default value
433        for( pixel = 0 ; pixel < (p_max - p_min) ; pixel++ ) line_buffer[pixel] = 127;
434
435        // take the lock in read mode
436        remote_rwlock_rd_acquire( windows_lock_xp );
437
438        // 2. internal loop on all registered windows
439        XLIST_FOREACH( windows_root_xp , iter_xp )
440        {
441            // get pointers on current target window
442            xptr_t         tgt_xp  = XLIST_ELEMENT( iter_xp , fbf_window_t , xlist );
443            fbf_window_t * tgt_ptr = GET_PTR( tgt_xp );
444            cxy_t          tgt_cxy = GET_CXY( tgt_xp );
445
446            // get target window min and max coordinates in FBF reference
447            bool_t    hidden   = hal_remote_l32( XPTR( tgt_cxy , &tgt_ptr->hidden ) );
448            uint32_t  w_l_min  = hal_remote_l32( XPTR( tgt_cxy , &tgt_ptr->l_min ) );
449            uint32_t  w_p_min  = hal_remote_l32( XPTR( tgt_cxy , &tgt_ptr->p_min ) );
450            uint32_t  w_height = hal_remote_l32( XPTR( tgt_cxy , &tgt_ptr->height ) );
451            uint32_t  w_width  = hal_remote_l32( XPTR( tgt_cxy , &tgt_ptr->width  ) );
452            uint32_t  w_l_max  = w_l_min + w_height;
453            uint32_t  w_p_max  = w_p_min + w_width;
454
455            // does nothing when target window is hidden
456            // or the pseudo window line does not overlap the target window
457            if( (hidden == true)   ||
458                (line  <  w_l_min) ||
459                (line  >= w_l_max) ||
460                (p_max <  w_p_min) ||
461                (p_min >= w_p_max) ) continue;
462
463            // get pointer on buffer associated to target window in user space
464            uint8_t * w_buffer = hal_remote_lpt( XPTR( tgt_cxy , &tgt_ptr->buffer ) ); 
465
466            // get min & max indexes for pixels to be moved in FBF reference
467            uint32_t f_pixel_min = (p_min < w_p_min) ? w_p_min : p_min;
468            uint32_t f_pixel_max = (p_max < w_p_max) ? p_max : w_p_max;
469
470            // compute number of pixels to move from w_buffer to f_buffer
471            uint32_t npixels = f_pixel_max - f_pixel_min;
472
473            // compute offset in line_buffer
474            uint32_t line_offset = f_pixel_min - p_min; 
475
476            // compute line index in window 
477            uint32_t w_line = line - w_l_min;
478
479            // compute offset in window buffer
480            uint32_t w_offset = (w_line * w_height) + f_pixel_min - w_p_min;
481
482            // move pixels from w_buffer (user space) to line_buffer (kernel space)
483            hal_copy_from_uspace( XPTR( local_cxy  , &line_buffer[line_offset] ),
484                                  &w_buffer[w_offset], 
485                                  npixels );
486        }  // end for windows
487
488        // release the lock
489        remote_rwlock_rd_release( windows_lock_xp );
490
491        // compute offset in FBF
492        uint32_t fbf_offset = p_min + (line * fbf_width);
493
494        // register command in calling thread descriptor
495        this->fbf_cmd.dev_xp    = fbf_xp;
496        this->fbf_cmd.type      = FBF_DRIVER_KERNEL_WRITE;
497        this->fbf_cmd.buffer    = line_buffer;
498        this->fbf_cmd.npixels   = p_max - p_min;
499        this->fbf_cmd.offset    = fbf_offset;
500
501        // call driver to display one line
502        cmd( XPTR( local_cxy , this ) );
503
504        error |= this->fbf_cmd.error;
505   
506    }  // end for lines
507
508#if DEBUG_DEV_FBF
509cycle = (uint32_t)hal_get_cycles();
510if( DEBUG_DEV_FBF < cycle )
511printk("\n[%s] exit / cycle %d\n",
512__FUNCTION__, cycle );
513#endif
514
515    // return I/O operation status
516    return error;
517
518}  // end fbf_update()
519
520//////////////////////////////////////////////
521error_t dev_fbf_delete_window( uint32_t  wid )
522{
523    kmem_req_t     req;
524
525    thread_t  * this    = CURRENT_THREAD;
526    process_t * process = this->process;
527
528#if DEBUG_DEV_FBF
529uint32_t   cycle = (uint32_t)hal_get_cycles();
530if( DEBUG_DEV_FBF < cycle )
531printk("\n[%s] thread[%x,%x] enters : wid %d / cycle %d\n",
532__FUNCTION__ , process->pid, this->trdid, wid, cycle );
533#endif
534
535    // get extended pointer on window to be deleted
536    xptr_t window_xp  = dev_fbf_get_xptr_from_wid( wid );
537
538    if( window_xp == XPTR_NULL ) return -1;
539
540    // get cluster and pointers on FBF chdev
541    xptr_t      fbf_xp  = chdev_dir.fbf[0];
542    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
543    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
544
545    // build extended pointers on windows lock, windows_tbl[wid] and wid allocator
546    xptr_t windows_lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock );
547    xptr_t wid_bitmap_xp   = XPTR( fbf_cxy ,  fbf_ptr->ext.fbf.windows_bitmap );
548    xptr_t windows_tbl_xp  = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_tbl[wid] );
549
550    // get cluster and local pointer on window
551    cxy_t          window_cxy = GET_CXY( window_xp );
552    fbf_window_t * window_ptr = GET_PTR( window_xp );
553
554    // get relevant info from window descriptor
555    uint32_t   p_min   = hal_remote_l32( XPTR( window_cxy , &window_ptr->p_min ) );
556    uint32_t   l_min   = hal_remote_l32( XPTR( window_cxy , &window_ptr->l_min ) );
557    uint32_t   npixels = hal_remote_l32( XPTR( window_cxy , &window_ptr->width ) );
558    uint32_t   nlines  = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) );
559    uint8_t  * buffer  = hal_remote_lpt( XPTR( window_cxy , &window_ptr->buffer ) );
560
561    // 1. set the hidden bit in window descriptor
562    hal_remote_s32( XPTR( window_cxy , &window_ptr->hidden ) , true );
563
564    // 2. refresh the window in FBF
565    fbf_update( p_min, l_min, p_min + npixels, l_min + nlines );
566
567    // 3. take the lock protecting windows in write mode
568    remote_rwlock_wr_acquire( windows_lock_xp );
569
570    // 4. remove the window from windows_tbl[] array
571    hal_remote_s64( windows_tbl_xp , XPTR_NULL );
572
573    // 5. remove the window from xlist     
574    xlist_unlink( XPTR( window_cxy , &window_ptr->xlist ) );
575
576    // 6. release wid to bitmap
577    bitmap_remote_clear( wid_bitmap_xp , wid );
578
579    // 7. release the lock protecting windows in write mode
580    remote_rwlock_wr_release( windows_lock_xp );
581 
582    // 8. release memory allocated for window descriptor
583    req.type = KMEM_KCM;
584    req.ptr  = window_ptr;
585    kmem_remote_free( window_cxy , &req );
586
587    // 9. release the associated vseg
588    vmm_global_delete_vseg( process , (intptr_t)buffer );
589   
590#if DEBUG_DEV_FBF
591cycle = (uint32_t)hal_get_cycles();
592if( DEBUG_DEV_FBF < cycle )
593printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
594__FUNCTION__ , process->pid, this->trdid, cycle );
595#endif
596
597    return 0;
598
599}  // end dev_fbf_delete_window()
600
601////////////////////////////////////////////
602error_t dev_fbf_move_window( uint32_t  wid,
603                             uint32_t  l_new,
604                             uint32_t  p_new )
605{
606
607#if DEBUG_DEV_FBF
608thread_t  * this  = CURRENT_THREAD;
609uint32_t    cycle = (uint32_t)hal_get_cycles();
610if( DEBUG_DEV_FBF < cycle )
611printk("\n[%s] thread[%x,%x] enters : wid %d / l_new %d / p_new %d / cycle %d\n",
612__FUNCTION__ , this->process->pid, this->trdid, wid, l_new, p_new, cycle );
613#endif
614
615    // get extended pointer on window to be moved
616    xptr_t window_xp  = dev_fbf_get_xptr_from_wid( wid );
617
618    if( window_xp == XPTR_NULL ) return -1;
619
620    // get cluster and pointers on FBF chdev
621    xptr_t      fbf_xp  = chdev_dir.fbf[0];
622    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
623    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
624
625    // build extended pointers on windows lock and root
626    xptr_t windows_lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock );
627    xptr_t windows_root_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root );
628
629
630    // get cluster and local pointer on target window
631    cxy_t          window_cxy = GET_CXY( window_xp );
632    fbf_window_t * window_ptr = GET_PTR( window_xp );
633
634    // get target window coordinates, width and height
635    uint32_t p_old     = hal_remote_l32( XPTR( window_cxy , &window_ptr->p_min ) );
636    uint32_t l_old     = hal_remote_l32( XPTR( window_cxy , &window_ptr->l_min ) );
637    uint32_t nlines    = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) );
638    uint32_t npixels   = hal_remote_l32( XPTR( window_cxy , &window_ptr->width ) );
639
640    // build extended pointer on window xlist_entry
641    xptr_t xlist_entry_xp =  XPTR( window_cxy , &window_ptr->xlist );
642
643    // does nothing if no change
644    if( (p_new == p_old) && (l_new == l_old) )  return 0;
645
646    // 1. set the "hidden" flag in window descriptor
647    hal_remote_s32( XPTR( window_cxy , &window_ptr->hidden ) , true );
648
649#if ( DEBUG_DEV_FBF & 1 )
650printk("\n[%s] hidden set\n", __FUNCTION__ );
651#endif
652
653    // 2. update the FBF for the old window position
654    fbf_update( p_old , l_old , p_old + npixels, l_old + nlines );
655
656#if ( DEBUG_DEV_FBF & 1 )
657printk("\n[%s] refreshed old window\n", __FUNCTION__ );
658#endif
659
660    // 3. take the lock protecting windows in write mode
661    remote_rwlock_wr_acquire( windows_lock_xp );
662
663#if ( DEBUG_DEV_FBF & 1 )
664printk("\n[%s] lock taken\n", __FUNCTION__ );
665#endif
666
667    // 4. set the new coordinates in the window descriptor,
668    hal_remote_s32( XPTR( window_cxy , &window_ptr->l_min ), l_new );
669    hal_remote_s32( XPTR( window_cxy , &window_ptr->p_min ), p_new );
670
671#if ( DEBUG_DEV_FBF & 1 )
672printk("\n[%s] l_min & p_min updated\n", __FUNCTION__ );
673#endif
674
675    // 5. gives the window the highest priority
676    xlist_unlink( xlist_entry_xp );
677    xlist_add_last( windows_root_xp , xlist_entry_xp );
678
679#if ( DEBUG_DEV_FBF & 1 )
680printk("\n[%s] set high priority\n", __FUNCTION__ );
681#endif
682
683    // 6. release the lock protecting windows in write mode
684    remote_rwlock_wr_release( windows_lock_xp );
685 
686#if ( DEBUG_DEV_FBF & 1 )
687printk("\n[%s] lock released\n", __FUNCTION__ );
688#endif
689
690    // 7. reset the "hidden" flag in window descriptor
691    hal_remote_s32( XPTR( window_cxy , &window_ptr->hidden ) , false );
692
693#if ( DEBUG_DEV_FBF & 1 )
694printk("\n[%s] hidden reset\n", __FUNCTION__ );
695#endif
696
697    // 8. update the FBF for the new window position
698    fbf_update( p_new , l_new , p_new + npixels, l_new + nlines );
699
700#if ( DEBUG_DEV_FBF & 1 )
701printk("\n[%s] refresh new new window\n", __FUNCTION__ );
702#endif
703
704#if DEBUG_DEV_FBF
705cycle = (uint32_t)hal_get_cycles();
706if( DEBUG_DEV_FBF < cycle )
707printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
708__FUNCTION__ , this->process->pid, this->trdid, cycle );
709#endif
710
711    return 0;
712
713}  // end dev_fbf_move_window()
714
715/////////////////////////////////////////////
716error_t dev_fbf_resize_window( uint32_t  wid,
717                               uint32_t  width,
718                               uint32_t  height )
719{
720    thread_t  * this    = CURRENT_THREAD;
721    process_t * process = this->process;
722
723#if DEBUG_DEV_FBF
724uint32_t    cycle = (uint32_t)hal_get_cycles();
725if( DEBUG_DEV_FBF < cycle )
726printk("\n[%s] thread[%x,%x] enters : wid %d / width %d / height %d / cycle %d\n",
727__FUNCTION__ , process->pid , this->trdid , wid, width , height , cycle );
728#endif
729
730    // get extended pointer on window to be resized
731    xptr_t window_xp  = dev_fbf_get_xptr_from_wid( wid );
732
733    if( window_xp == XPTR_NULL ) return -1;
734
735    // get cluster and pointers on FBF chdev
736    xptr_t      fbf_xp  = chdev_dir.fbf[0];
737    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
738    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
739
740    // build extended pointers on windows lock and root
741    xptr_t windows_lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock );
742    xptr_t windows_root_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root );
743
744    // get cluster and local pointer on target window
745    cxy_t          window_cxy = GET_CXY( window_xp );
746    fbf_window_t * window_ptr = GET_PTR( window_xp );
747
748    // get process owner PID, width, height, and buffer
749    uint32_t p_min   = hal_remote_l32( XPTR( window_cxy , &window_ptr->p_min ) );
750    uint32_t l_min   = hal_remote_l32( XPTR( window_cxy , &window_ptr->l_min ) );
751    uint32_t nlines  = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) );
752    uint32_t npixels = hal_remote_l32( XPTR( window_cxy , &window_ptr->width ) );
753    void   * base    = hal_remote_lpt( XPTR( window_cxy , &window_ptr->buffer ) );
754
755    // build extended pointer on window xlist_entry
756    xptr_t xlist_entry_xp =  XPTR( window_cxy , &window_ptr->xlist );
757
758    // does nothing if no change
759    if( (width == npixels) && (height == nlines) ) return 0;
760
761    // compute old_size and new size
762    uint32_t old_size = nlines * npixels;
763    uint32_t new_size = width * height;
764
765    // 1. set the "hidden" flag in window descriptor
766    hal_remote_s32( XPTR( window_cxy , &window_ptr->hidden ) , true );
767
768#if ( DEBUG_DEV_FBF & 1 )
769printk("\n[%s] hidden set\n", __FUNCTION__ );
770#endif
771
772    // 2. refresh the FBF for the current window size
773    fbf_update( p_min , l_min , p_min + npixels, l_min + nlines );
774
775#if ( DEBUG_DEV_FBF & 1 )
776printk("\n[%s] refreshed old window\n", __FUNCTION__ );
777#endif
778
779    // 3. take the lock protecting windows in write mode
780    remote_rwlock_wr_acquire( windows_lock_xp );
781
782#if ( DEBUG_DEV_FBF & 1 )
783printk("\n[%s] lock taken\n", __FUNCTION__ );
784#endif
785
786    // 4. set the new width & height in the window descriptor,
787    hal_remote_s32( XPTR( window_cxy , &window_ptr->width  ), width );
788    hal_remote_s32( XPTR( window_cxy , &window_ptr->height ), height );
789
790#if ( DEBUG_DEV_FBF & 1 )
791printk("\n[%s] width & height updated\n", __FUNCTION__ );
792#endif
793
794    // 5. resize vseg if required
795    vmm_global_resize_vseg( process, (intptr_t)base, (intptr_t)base, width * height );
796
797#if ( DEBUG_DEV_FBF & 1 )
798printk("\n[%s] vseg resized\n", __FUNCTION__ );
799#endif
800
801    // 6. fill buffer extension if required
802    if( new_size > old_size )  memset( base + old_size , 0 , new_size - old_size );
803
804#if ( DEBUG_DEV_FBF & 1 )
805printk("\n[%s] buffer extension initialized\n", __FUNCTION__ );
806#endif
807
808    // 7. gives the window the highest priority
809    xlist_unlink( xlist_entry_xp );
810    xlist_add_last( windows_root_xp , xlist_entry_xp );
811
812#if ( DEBUG_DEV_FBF & 1 )
813printk("\n[%s] set high priority\n", __FUNCTION__ );
814#endif
815
816    // 8. release the lock protecting windows in write mode
817    remote_rwlock_wr_release( windows_lock_xp );
818 
819#if ( DEBUG_DEV_FBF & 1 )
820printk("\n[%s] lock released\n", __FUNCTION__ );
821#endif
822
823    // 9. reset the "hidden" flag in window descriptor
824    hal_remote_s32( XPTR( window_cxy , &window_ptr->hidden ) , false );
825
826#if ( DEBUG_DEV_FBF & 1 )
827printk("\n[%s] hidden reset\n", __FUNCTION__ );
828#endif
829
830    // 10. refresh the FBF for the new window position
831    fbf_update( p_min , l_min , p_min + width, l_min + height );
832
833#if ( DEBUG_DEV_FBF & 1 )
834printk("\n[%s] refreshed new window\n", __FUNCTION__ );
835#endif
836
837#if DEBUG_DEV_FBF
838cycle = (uint32_t)hal_get_cycles();
839if( DEBUG_DEV_FBF < cycle )
840printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
841__FUNCTION__ , process->pid, this->trdid, cycle );
842#endif
843
844    return 0;
845
846}  // end dev_fbf_resize_window()
847
848//////////////////////////////////////////////
849error_t dev_fbf_refresh_window( uint32_t  wid,
850                                uint32_t  line_min,
851                                uint32_t  line_max )
852{
853
854#if DEBUG_DEV_FBF
855thread_t  * thi   = CURRENT_THREAD;
856uint32_t    cycle = (uint32_t)hal_get_cycles();
857if( DEBUG_DEV_FBF < cycle )
858printk("\n[%s] thread[%x,%x] enters for wid %d / first %d / last %d / cycle %d\n",
859__FUNCTION__ , this->process->pid, this->trdid, wid, line_min, line_max, cycle );
860#endif
861
862    // get extended pointer on window to be refreshed
863    xptr_t window_xp  = dev_fbf_get_xptr_from_wid( wid );
864
865    if( window_xp == XPTR_NULL ) return -1;
866
867    // get cluster and local pointer on target window
868    cxy_t          window_cxy = GET_CXY( window_xp );
869    fbf_window_t * window_ptr = GET_PTR( window_xp );
870
871    // get p_min, l_min, nlines  & npixels from window descriptor
872    uint32_t p_min   = hal_remote_l32( XPTR( window_cxy , &window_ptr->p_min ) ); 
873    uint32_t l_min   = hal_remote_l32( XPTR( window_cxy , &window_ptr->l_min ) ); 
874    uint32_t npixels = hal_remote_l32( XPTR( window_cxy , &window_ptr->width ) ); 
875    uint32_t nlines  = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) ); 
876
877    // check <line_min> and <line_max> arguments
878    if( (line_min >= nlines) || (line_max > nlines) || (line_min >= line_max) )
879    {
880        printk("\n[ERROR] in %s : illegal arguments / l_first %d / l_last %d / nlines %d\n",
881        __FUNCTION__, line_min, line_max, nlines );
882        return -1;
883    }
884
885    // update FBF
886    fbf_update( p_min , l_min + line_min , p_min + npixels , l_min + line_max );
887
888#if DEBUG_DEV_FBF
889cycle = (uint32_t)hal_get_cycles();
890if( DEBUG_DEV_FBF < cycle )
891printk("\n[%s] thread[%x,%x] exit for wid %d / cycle %d\n",
892__FUNCTION__, this->process->pid, this->trdid, wid, cycle );
893#endif
894
895    return 0;
896
897}  // end dev_fbf_refresh_window()
898
899////////////////////////////////////////////
900error_t dev_fbf_front_window( uint32_t wid )
901{
902
903#if DEBUG_DEV_FBF
904thread_t  * this  = CURRENT_THREAD;
905uint32_t    cycle = (uint32_t)hal_get_cycles();
906if( DEBUG_DEV_FBF < cycle )
907printk("\n[%s] thread[%x,%x] enters for wid %d / cycle %d\n",
908__FUNCTION__ , this->process->pid, this->trdid, wid, cycle );
909#endif
910
911    // get extended pointer on window to be refreshed
912    xptr_t window_xp  = dev_fbf_get_xptr_from_wid( wid );
913
914    if( window_xp == XPTR_NULL ) return -1;
915
916    // get cluster and pointers on FBF chdev
917    xptr_t      fbf_xp  = chdev_dir.fbf[0];
918    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
919    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
920
921    // build extended pointer on windows lock and root
922    xptr_t  windows_lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock );
923    xptr_t  windows_root_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root );
924
925    // get cluster and local pointers on window
926    cxy_t          window_cxy = GET_CXY( window_xp );
927    fbf_window_t * window_ptr = GET_PTR( window_xp );
928
929    // get target window coordinates, width, height, and hidden
930    uint32_t p_min     = hal_remote_l32( XPTR( window_cxy , &window_ptr->p_min ) );
931    uint32_t l_min     = hal_remote_l32( XPTR( window_cxy , &window_ptr->l_min ) );
932    uint32_t nlines    = hal_remote_l32( XPTR( window_cxy , &window_ptr->height ) );
933    uint32_t npixels   = hal_remote_l32( XPTR( window_cxy , &window_ptr->width ) );
934    bool_t   hidden    = hal_remote_l32( XPTR( window_cxy , &window_ptr->hidden ) );
935
936    // build extended pointer on window xlist_entry
937    xptr_t xlist_entry_xp =  XPTR( window_cxy , &window_ptr->xlist );
938
939    // 1. take the lock protecting windows in write mode
940    remote_rwlock_wr_acquire( windows_lock_xp );
941
942#if ( DEBUG_DEV_FBF & 1 )
943printk("\n[%s] lock taken\n", __FUNCTION__ );
944#endif
945
946    // 2. gives the window the highest priority
947    xlist_unlink( xlist_entry_xp );
948    xlist_add_last( windows_root_xp , xlist_entry_xp );
949
950#if ( DEBUG_DEV_FBF & 1 )
951printk("\n[%s] set high priority \n", __FUNCTION__ );
952#endif
953
954    // 3. release the lock protecting windows from write mode
955    remote_rwlock_wr_release( windows_lock_xp );
956 
957#if ( DEBUG_DEV_FBF & 1 )
958printk("\n[%s] lock released\n", __FUNCTION__ );
959#endif
960
961    // 4. update the FBF for this window when not hidden
962    if( hidden == false ) fbf_update( p_min , l_min , p_min + npixels, l_min + nlines );
963
964#if ( DEBUG_DEV_FBF & 1 )
965printk("\n[%s] refresh window in FBF\n", __FUNCTION__ );
966#endif
967
968#if DEBUG_DEV_FBF
969cycle = (uint32_t)hal_get_cycles();
970if( DEBUG_DEV_FBF < cycle )
971printk("\n[%s] thread[%x,%x] exit for wid %d / cycle %d\n",
972__FUNCTION__ , this->process->pid, this->trdid, wid, cycle );
973#endif
974
975    return 0;
976
977}   // end dev_fbf_front_window()
978
979/////////////////////////////////////////
980void dev_fbf_display_windows( pid_t pid )
981{
982    xptr_t  iter_xp;
983
984    // display header
985    printk("\n***** registered FBF windows *****\n"
986           "   wid   | hide  | lzero | pzero | lines | pixel | pid\n" );
987
988    // get cluster and pointers on FBF chdev
989    xptr_t      fbf_xp  = chdev_dir.fbf[0];
990    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
991    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
992
993    // build extended pointer on windows lock and root
994    xptr_t  lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock );
995    xptr_t  root_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root );
996
997    // take the lock in read mode
998    remote_rwlock_rd_acquire( lock_xp );
999
1000    XLIST_FOREACH_BACKWARD( root_xp , iter_xp )
1001    {
1002        xptr_t         w_xp  = XLIST_ELEMENT( iter_xp , fbf_window_t , xlist );
1003        fbf_window_t * w_ptr = GET_PTR( w_xp );
1004        cxy_t          w_cxy = GET_CXY( w_xp );
1005
1006        uint32_t wid       = hal_remote_l32( XPTR( w_cxy , &w_ptr->wid   ) );
1007        uint32_t owner_pid = hal_remote_l32( XPTR( w_cxy , &w_ptr->pid   ) );
1008        uint32_t hide      = hal_remote_l32( XPTR( w_cxy , &w_ptr->hidden ) );
1009        uint32_t lzero     = hal_remote_l32( XPTR( w_cxy , &w_ptr->l_min ) );
1010        uint32_t pzero     = hal_remote_l32( XPTR( w_cxy , &w_ptr->p_min ) );
1011        uint32_t lines     = hal_remote_l32( XPTR( w_cxy , &w_ptr->height ) );
1012        uint32_t pixels    = hal_remote_l32( XPTR( w_cxy , &w_ptr->width ) );
1013
1014        if( (pid == 0) || (pid == owner_pid) )
1015        { 
1016            printk("%d\t | %d\t | %d\t | %d\t | %d\t | %d\t | %x\n",
1017                    wid,   hide,  lzero, pzero, lines, pixels, pid );
1018        }
1019    }
1020
1021    // release the lock
1022    remote_rwlock_rd_release( lock_xp );
1023
1024}  // end dev_fbf_display_windows()
1025
1026/////////////////////////////////
1027void dev_fbf_cleanup( pid_t pid )
1028{
1029    xptr_t  iter_xp;
1030
1031    // get cluster and pointers on FBF chdev
1032    xptr_t      fbf_xp  = chdev_dir.fbf[0];
1033    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
1034    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
1035
1036    // build extended pointer on windows lock and root
1037    xptr_t  lock_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_lock );
1038    xptr_t  root_xp = XPTR( fbf_cxy , &fbf_ptr->ext.fbf.windows_root );
1039
1040    // take the lock in read mode
1041    remote_rwlock_rd_acquire( lock_xp );
1042
1043    XLIST_FOREACH( root_xp , iter_xp )
1044    {
1045        xptr_t         w_xp  = XLIST_ELEMENT( iter_xp , fbf_window_t , xlist );
1046        fbf_window_t * w_ptr = GET_PTR( w_xp );
1047        cxy_t          w_cxy = GET_CXY( w_xp );
1048
1049        // get owner process PID and WID
1050        uint32_t   owner_pid  = hal_remote_l32( XPTR( w_cxy , &w_ptr->pid ) );
1051        uint32_t   wid        = hal_remote_l32( XPTR( w_cxy , &w_ptr->wid ) );
1052
1053        // delete matching window
1054        if( pid == owner_pid ) dev_fbf_delete_window( wid );
1055    }
1056
1057    // release the lock from read mode
1058    remote_rwlock_rd_release( lock_xp );
1059
1060}  // end dev_fbf_cleanup()
1061
1062
1063
1064
1065///////////////////////////////////////////////
1066// TODO Deprecated : january 2020 [AG]
1067///////////////////////////////////////////////
1068error_t dev_fbf_move_data( bool_t     is_write,
1069                           void     * user_buffer,
1070                           uint32_t   npixels,
1071                           uint32_t   offset )
1072{
1073    // get pointer on calling thread
1074    thread_t * this = CURRENT_THREAD;
1075
1076#if DEBUG_DEV_FBF
1077uint32_t   cycle = (uint32_t)hal_get_cycles();
1078if( DEBUG_DEV_FBF < cycle )
1079printk("\n[%s] thread[%x,%x] :  buffer %x / npixels %d / offset %x / cycle %d\n",
1080__FUNCTION__ , this->process->pid, this->trdid, 
1081user_buffer, npixels, offset, cycle );
1082#endif
1083
1084    // get pointers on FBF chdev
1085    xptr_t      fbf_xp  = chdev_dir.fbf[0];
1086    cxy_t       fbf_cxy = GET_CXY( fbf_xp );
1087    chdev_t   * fbf_ptr = GET_PTR( fbf_xp );
1088
1089    // get frame buffer width and height
1090    uint32_t width  = hal_remote_l32 ( XPTR( fbf_cxy , &fbf_ptr->ext.fbf.width ) );
1091    uint32_t height = hal_remote_l32 ( XPTR( fbf_cxy , &fbf_ptr->ext.fbf.height ) );
1092
1093    // check offset and npixels versus FBF size
1094    if( ((offset + npixels) > (width * height)) )
1095    {
1096        printk("\n[ERROR] in %s : offset (%d) + npixels (%d) / width (%d) / height (%d)\n",
1097        __FUNCTION__, offset, npixels, width, height ); 
1098        return -1;
1099    }
1100
1101    // register command in calling thread descriptor
1102    this->fbf_cmd.dev_xp    = fbf_xp;
1103    this->fbf_cmd.type      = is_write ? FBF_DRIVER_USER_WRITE : FBF_DRIVER_USER_READ;
1104    this->fbf_cmd.buffer    = user_buffer;
1105    this->fbf_cmd.offset    = offset;
1106    this->fbf_cmd.npixels   = npixels;
1107
1108    // get driver command function
1109    dev_cmd_t * cmd = (dev_cmd_t *)hal_remote_lpt( XPTR( fbf_cxy , &fbf_ptr->cmd ) );
1110
1111    // call driver
1112    cmd( XPTR( local_cxy , this ) );
1113
1114    error_t error = this->fbf_cmd.error;
1115
1116#if DEBUG_DEV_FBF
1117cycle = (uint32_t)hal_get_cycles();
1118if( DEBUG_DEV_FBF < cycle )
1119printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
1120__FUNCTION__ , this->process->pid, this->trdid, cycle );
1121#endif
1122
1123    // return I/O operation status
1124    return error;
1125
1126}  // end dev_fbf_move_data()
1127
1128
Note: See TracBrowser for help on using the repository browser.