Index: trunk/hal/tsar_mips32/drivers/soclib_fbf.c
===================================================================
--- trunk/hal/tsar_mips32/drivers/soclib_fbf.c	(revision 75)
+++ trunk/hal/tsar_mips32/drivers/soclib_fbf.c	(revision 647)
@@ -2,5 +2,5 @@
  * soclib_fbf.c - soclib frame-buffer driver implementation.
  *
- * Author Alain greiner (2016)
+ * Author Alain greiner (2016,2017,2018,2019)
  *
  * Copyright (c) UPMC Sorbonne Universites
@@ -22,2 +22,106 @@
  */
 
+#include <soclib_fbf.h>
+#include <hal_kernel_types.h>
+#include <hal_uspace.h>
+#include <chdev.h>
+#include <dev_fbf.h>
+#include <printk.h>
+#include <thread.h>
+
+///////////////////////////////////////
+void soclib_fbf_init( chdev_t * chdev )
+{
+    // set driver specific fields in FBF chdev
+    chdev->cmd = &soclib_fbf_cmd;
+    chdev->isr = NULL;
+
+    // get extended pointer on SOCLIB_FBF peripheral segment base 
+	xptr_t  base_xp = chdev->base;
+
+    // get cluster and local pointer for the SOCLIB_FBF peripheral segment
+    cxy_t      base_cxy  = GET_CXY( base_xp );
+    uint32_t * base_ptr  = GET_PTR( base_xp );
+
+    // get frame buffer width, height, and type  
+	uint32_t width  = hal_remote_l32( XPTR( base_cxy , base_ptr + FBF_WIDTH_REG ) );
+	uint32_t height = hal_remote_l32( XPTR( base_cxy , base_ptr + FBF_HEIGHT_REG ) );
+    uint32_t type   = hal_remote_l32( XPTR( base_cxy , base_ptr + FBF_SUBSAMPLING_REG ) );
+
+    // set FBF chdev extension fields
+    chdev->ext.fbf.width       = width;
+    chdev->ext.fbf.height      = height;
+    chdev->ext.fbf.subsampling = type;
+
+}  // end soclib_fbf_init()
+
+/////////////////////////////////////////////////////////////////
+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   status;      // I/0 operation status (from BDV)
+
+    // get client thread cluster and local pointer
+    cxy_t      th_cxy = GET_CXY( thread_xp );
+    thread_t * th_ptr = GET_PTR( thread_xp );
+
+#if (DEBUG_HAL_FBF|| DEBUG_HAL_FBF)
+uint32_t    cycle        = (uint32_t)hal_get_cycles();
+thread_t  * this         = CURRENT_THREAD;
+process_t * process      = hal_remote_lpt( XPTR( th_cxy , &th_ptr->process ) );
+pid_t       client_pid   = hal_remote_l32( XPTR( th_cxy , &process->pid ) );
+trdid_t     client_trdid = hal_remote_l32( XPTR( th_cxy , &th_ptr->trdid ) );
+#endif 
+
+    // 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 ) );
+
+    // get cluster and local pointer on FBF chdev
+    cxy_t     fbf_cxy = GET_CXY( fbf_xp );
+    chdev_t * fbf_ptr = GET_PTR( fbf_xp );
+
+    // get extended pointer on SOCLIB_FBF peripheral segment base 
+	xptr_t  base_xp = (xptr_t)hal_remote_l64( XPTR( fbf_cxy , &fbf_ptr->base ) );
+
+    // execute command
+    if( cmd_type == FBF_READ )     // use a (kernel -> user) memcpy
+    {
+
+#if DEBUG_HAL_FBF 
+if( DEBUG_HAL_FBF < cycle )
+printk("\n[%s] thread[%x,%x] / client[%x,%x] / READ / offset / length / buffer %x / cycle %d\n",
+__FUNCTION__ , this->process->pid, this->trdid,  client_pid, client_trdid,
+offset, length, buffer, cycle );
+#endif
+        hal_copy_to_uspace( buffer,
+                            base_xp + offset,
+                            length );
+
+    }
+    else  // cmd_type == FBF_WRITE => use a (user -> kernel)  memcpy
+    {
+
+#if DEBUG_HAL_FBF 
+if( DEBUG_HAL_FBF < cycle )
+printk("\n[%s] thread[%x,%x] / client[%x,%x] / WRITE / offset / length / buffer %x / cycle %d\n",
+__FUNCTION__ , this->process->pid, this->trdid, client_pid, client_trdid,
+offset, length, buffer, cycle );
+#endif
+        hal_copy_from_uspace( base_xp + offset,
+                              buffer,
+                              length );
+    }
+
+    // set success in command
+    hal_remote_s32( XPTR( th_cxy , &th_ptr->fbf_cmd.error ) , 0 );
+            
+}  // end soclib_fbf_cmd()
+
