Index: trunk/hal/tsar_mips32/drivers/soclib_fbf.c
===================================================================
--- trunk/hal/tsar_mips32/drivers/soclib_fbf.c	(revision 654)
+++ trunk/hal/tsar_mips32/drivers/soclib_fbf.c	(revision 657)
@@ -2,5 +2,5 @@
  * soclib_fbf.c - soclib frame-buffer driver implementation.
  *
- * Author Alain greiner (2016,2017,2018,2019)
+ * Author Alain greiner (2016,2017,2018,2019,2020)
  *
  * Copyright (c) UPMC Sorbonne Universites
@@ -59,10 +59,10 @@
 void __attribute__((noinline)) soclib_fbf_cmd( xptr_t thread_xp )
 {
-    uint32_t   cmd_type;    // READ / WRITE / SYNC_READ / SYNC_WRITE
-    uint32_t   offset;
-    uint32_t   length;
-    void     * buffer;      // pointer on memory buffer in user space
-    xptr_t     fbf_xp;
+    uint32_t   type;        // USER_WRITE / USER_READ / KERNEL_WRITE / KERNEL_READ
+    uint32_t   offset;      // offset in FBF (in pixels)
+    uint32_t   npixels;     // number of pixels to move
+    xptr_t     fbf_xp;      // extended pointer on FBF chdev descriptor
     uint32_t   status;      // I/0 operation status (from BDV)
+    void     * buffer;      // pointer on kernel or user buffer 
 
     // get client thread cluster and local pointer
@@ -78,9 +78,9 @@
 
     // get command arguments
-    cmd_type =         hal_remote_l32( XPTR( th_cxy , &th_ptr->fbf_cmd.type   ) );
-    offset   =         hal_remote_l32( XPTR( th_cxy , &th_ptr->fbf_cmd.offset ) );
-    length   =         hal_remote_l32( XPTR( th_cxy , &th_ptr->fbf_cmd.length ) );
-    buffer   =         hal_remote_lpt( XPTR( th_cxy , &th_ptr->fbf_cmd.buffer ) );
-    fbf_xp   = (xptr_t)hal_remote_l64( XPTR( th_cxy , &th_ptr->fbf_cmd.dev_xp ) );
+    type     = hal_remote_l32( XPTR( th_cxy , &th_ptr->fbf_cmd.type    ) );
+    offset   = hal_remote_l32( XPTR( th_cxy , &th_ptr->fbf_cmd.offset  ) );
+    npixels  = hal_remote_l32( XPTR( th_cxy , &th_ptr->fbf_cmd.npixels ) );
+    fbf_xp   = hal_remote_l64( XPTR( th_cxy , &th_ptr->fbf_cmd.dev_xp  ) );
+    buffer   = hal_remote_lpt( XPTR( th_cxy , &th_ptr->fbf_cmd.buffer  ) );
 
     // get cluster and local pointer on FBF chdev
@@ -92,45 +92,61 @@
 
     // execute command
-    if( cmd_type == FBF_READ )     // use a (kernel -> user) memcpy
+    if( type == FBF_DRIVER_USER_WRITE )     // user_buffer => FBF 
     {
 
 #if DEBUG_HAL_FBF 
 if( DEBUG_HAL_FBF < cycle )
-printk("\n[%s] client thread[%x,%x] / READ / offset %d / length %d / buffer %x / fbf (%x,%x)\n",
-__FUNCTION__ , client_pid, client_trdid,
-offset, length, buffer, GET_CXY(base_xp), GET_PTR(base_xp) );
+printk("\n[%s] client thread[%x,%x] / USER_WRITE / offset %d / npixels %d / buf %x\n",
+__FUNCTION__ , client_pid, client_trdid, offset, npixels, buffer );
 #endif
-        hal_copy_to_uspace( buffer,
-                            base_xp + offset,
-                            length );
-#if DEBUG_HAL_FBF 
-if( DEBUG_HAL_FBF < cycle )
-printk("\n[%s] client thread[%x,%x] / READ successful / cycle %d\n",
-__FUNCTION__ , client_pid, client_trdid , cycle );
-#endif
-
+        hal_copy_from_uspace( base_xp + offset,
+                              buffer,
+                              npixels );
     }
-    else  // cmd_type == FBF_WRITE => use a (user -> kernel)  memcpy
+    else if( type == FBF_DRIVER_USER_READ )  // FBF => user_buffer
     {
 
 #if DEBUG_HAL_FBF 
 if( DEBUG_HAL_FBF < cycle )
-printk("\n[%s] client thread[%x,%x] / WRITE / offset %d / length %d / buffer %x / fbf (%x,%x)\n",
-__FUNCTION__ , client_pid, client_trdid, 
-offset, length, buffer, GET_CXY(base_xp), GET_PTR(base_xp) );
+printk("\n[%s] client thread[%x,%x] / USER_READ / offset %d / npixels %d / buf %x\n",
+__FUNCTION__ , client_pid, client_trdid, offset, npixels, buffer );
 #endif
-        hal_copy_from_uspace( base_xp + offset,
-                              buffer,
-                              length );
+        hal_copy_to_uspace( buffer,
+                            base_xp + offset,
+                            npixels );
+    }
+    else if( type == FBF_DRIVER_KERNEL_WRITE )  // kernel_buffer => FBF
+    {
+
 #if DEBUG_HAL_FBF 
 if( DEBUG_HAL_FBF < cycle )
-printk("\n[%s] client thread[%x,%x] / WRITE successful / cycle %d\n",
-__FUNCTION__ , client_pid, client_trdid , cycle );
+printk("\n[%s] client thread[%x,%x] / KERNEL_WRITE / offset %d / npixels %d / buf %x\n",
+__FUNCTION__ , client_pid, client_trdid, offset, npixels, buffer );
 #endif
+        hal_remote_memcpy( base_xp + offset,
+                           XPTR( local_cxy , buffer ),
+                           npixels );
+    }
+    else if( type == FBF_DRIVER_KERNEL_READ )  // FBF => kernel_buffer
+    {
 
+#if DEBUG_HAL_FBF 
+if( DEBUG_HAL_FBF < cycle )
+printk("\n[%s] client thread[%x,%x] / KERNEL_READ / offset %d / npixels %d / buf %x\n",
+__FUNCTION__ , client_pid, client_trdid, offset, npixels, buffer );
+#endif
+        hal_remote_memcpy( XPTR( local_cxy , buffer ),
+                           base_xp + offset,
+                           npixels );
     }
 
     // set success in command
     hal_remote_s32( XPTR( th_cxy , &th_ptr->fbf_cmd.error ) , 0 );
+
+#if DEBUG_HAL_FBF 
+if( DEBUG_HAL_FBF < cycle )
+printk("\n[%s] client thread[%x,%x] / successful move / cycle %d\n",
+__FUNCTION__ , client_pid, client_trdid , cycle );
+#endif
             
 }  // end soclib_fbf_cmd()
