FBF device API
A) General principles
This device provide access to an external graphic display, that is seen by the kernel as a fixed size frame buffer, mapped in the kernel address space. The only pixel encoding type in the current Almos-mkh implementation is one byte per pixel (256 levels of gray).
It defines a first user API, used by the user-level system calls, and implementing a simple, kernel controlled, windows manager. This windows manager allows any process to create and use for display one (or several) window(s). Each window defines a private buffer, dynamically allocated in user space, that can be directly accessed (for read and write) by the owner process, without system call.
These windows can overlap. They can be moved in the frame buffer, or they can be resized, using dedicated system calls. The refresh of a window in the FBF must be explicitly required by the owner process. they can overlap other windows,.
A window must be entirely contained in the frame buffer.
To avoid contention, the window descriptor, and the associated user buffer are not allocated in the cluster containing the FBF chdev, but are distributed: each window is allocated in the cluster defined by the thread that required the window creation.
Each window has a single process owner, but all the windows are registered in the FBF chdev in a windows_tbl[] array, indexed by the window identifier (wid). Each array entry contains an extended pointer on the window descriptor. All windows are also registered in a trans-cluster xlist, defining the overlapping order (last window in xlist has the highest priority).
To access the various drivers, this FBF device defines a lower-level driver API, that must be implemented by all drivers.
All FBF access functions are defined in the dev_fbf.c et dev_fbf.h files.
B) Initialisation
The dev_fbf_init() function makes two initializations :
- it completes the FBF specific fields of the chdev descriptor.
- It calls the fbf_driver_init() function, to initialise the specific hardware device, when required.
It must be called by a local thread.
C) "User" API
All functions defined in this user API do NOT use the the FBF device waiting queue, the associated device thread and the FBF IRQ, as the client thread does NOT deschedules,
1) void dev_fbf_get_config( uint32_t * width, uint32_t * height, uint32_t type )
This function implements the fbf_get_config() syscall. It returns the FBF number of lines, the number of pixels per line, and the pixel encoding type. It can be called by a client thread running in any cluster. It does not access the hardware, as these informations have been registered in the chdev descriptor extension by the dev_fbf_init() function.
2) uint32_t dev_fbf_create_window( uint32_t nlines, npixels, l_min, p_min, intptr_t * user_base )
This blocking function implements the fbf_create_window() sys-call. It registers a new window in the windows_tbl[] array, and in the windows list, rooted in FBF device descriptor. It registers in the reference VSL an ANON vseg, that will be mapped in local cluster. It returns the dynamically allocated window index <wid>. The owner process is the calling process. The FBF window is defined by the <nlines>, <npixels>, <l_min>, <p_min> arguments. The created vseg base address in user space is returned in the <user_base> argument. It can be called by any thread running in any cluster.
As the vseg associated to the window is not directly mapped to the frame buffer, the owner process can read and write in the window buffer without syscall. As for any other vseg, the physical memory is allocated on demand, at each page fault.
3) error_t dev_fbf_refresh_window( uint32_t wid, uint32_t line_first, uint32_t line_last )
This blocking function implements the fbf_refresh_window() sys-call. It allows the owner process to signal the windows manager that some lines of a window identified by the <wid>, <line_min>, and <line_max> arguments have been modified, and must be refreshed in the FBF. It scans all the registered FBF windows to respect the overlap order defined by the windows xlist. It can be called by any thread running in any cluster.
4) error_t dev_fbf_move_window( uint32_t wid, uint32_t l_min, uint32_t p_min )
This blocking function implements the fbf_move_window() sys-call. It moves a window identified by the <wid> argument to a new position in the FBF, defined by the <l_min> and <p_min> arguments (FBF coordinates). It can be called by any thread running in any cluster.
5) error_t dev_fbf_resize_window( uint32_t wid, uint32_t width, uint32_t height )
This blocking function implements the fbf_resize_window() sys-call. It changes the <width> and <height> of a window identified by the <wid> argument. It updates the size of the associated vseg, but does not change the vseg "base". When the new window buffer is larger than the existing one, this buffer is 0 filled. It can be called by any thread running in any cluster.
6) error_t dev_fbf_delete_window( uint32_t wid )
This function implements the fbf_delete_window() sys-call to delete a FBF window identified by the <wid> argument. It releases all memory allocated for the window buffer and for the window descriptor. It can be called by any thread running in any cluster.
7) error_t dev_fbf_move_data( bool_t is_write, void * user_buffer, uint32_t npixels, uint32_t offset )
This function is deprecated. It implements the deprecated fbf_read() and fbf_write() sys-calls. This function allows an user application to directly access the Frame Buffer, without using any intermediate window. It calls directly the driver to synchronously move <npixels> between an user <buffer> and the FBF, starting at a given <offset> in the FBF. The transfer direction is defined by the <is_write> argument.
D) "Driver" API
All FBF drivers must define three functions:
- void fbf_driver_init( chdev_t *ioc_chdev )
- void fbf_driver_cmd( xptr_t thread_xp )
- void fbf_driver_isr( chdev_t * ioc_chdev )
The fbf_driver_cmd() function moves pixels between a kernel or user buffer identified and the FBF frame buffer. It supports four command types:
- FBF_DRIVER_KERNEL_WRITE : move pixels from a kernel buffer to the FBF.
- FBF_DRIVER_KERNEL_READ : move pixels from the FBF to a kernel buffer.
- FBF_DRIVER_USER_WRITE : move bytes from an user buffer to the FBF.
- FBF_DRIVER_USER_READ : move bytes from the FBF to an user buffer.
These four commands use the following arguments, that must be registered iin the fbf_command_t structure embedded in the client thread descriptor :
- type : command type.
- npixels : number of pixels to be moved.
- buffer : pointer on buffer in (can be in user space or in kernel space).
- offset : offset in FBF (number of pixels).
For FBF implementation generating events signaled by an FBF_IRQ, the fbf_driver_isr() function access the FBF hardware registers to get the event parameters, and execute the requested action (such as move, resize, hide, a pointed window).