diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-08-21 18:35:28 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-08-21 18:35:28 +0000 |
commit | 573e3b2f7f361d56e745710a5d052b6a5a2c9465 (patch) | |
tree | 1b9c9d46b8b4a29bb0da6e9f9b1b300ab2830a49 /c | |
parent | 2009-08-21 Joel Sherrill <joel.sherrill@OARcorp.com> (diff) | |
download | rtems-573e3b2f7f361d56e745710a5d052b6a5a2c9465.tar.bz2 |
2009-08-21 Roxana Leontie <roxana.leontie@gmail.com>
* pc386/console/fb_vga.c: added read/write functionality; added thread
safety to prevent multiple open() operations of the frame buffer device.
Diffstat (limited to 'c')
-rw-r--r-- | c/src/lib/libbsp/i386/pc386/ChangeLog | 5 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/pc386/console/fb_vga.c | 116 |
2 files changed, 88 insertions, 33 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/ChangeLog b/c/src/lib/libbsp/i386/pc386/ChangeLog index a986cb0d0a..d8f5c99ce0 100644 --- a/c/src/lib/libbsp/i386/pc386/ChangeLog +++ b/c/src/lib/libbsp/i386/pc386/ChangeLog @@ -1,3 +1,8 @@ +2009-08-21 Roxana Leontie <roxana.leontie@gmail.com> + + * pc386/console/fb_vga.c: added read/write functionality; added thread + safety to prevent multiple open() operations of the frame buffer device. + 2009-08-21 Joel Sherrill <joel.sherrill@OARcorp.com> * include/bsp.h: Eliminate BSPs defining NUMBER_OF_TERMIOS_PORTS. diff --git a/c/src/lib/libbsp/i386/pc386/console/fb_vga.c b/c/src/lib/libbsp/i386/pc386/console/fb_vga.c index ab8ff8e0a3..09d56e21c3 100644 --- a/c/src/lib/libbsp/i386/pc386/console/fb_vga.c +++ b/c/src/lib/libbsp/i386/pc386/console/fb_vga.c @@ -2,8 +2,8 @@ * Copyright (c) 2000 - Rosimildo da Silva ( rdasilva@connecttel.com ) * * MODULE DESCRIPTION: - * This module implements the micro FB driver for "Bare VGA". It uses the - * routines for "bare hardware" that comes with MicroWindows. + * This module implements FB driver for "Bare VGA". It uses the + * routines for "bare hardware" found in vgainit.c. * * $Id$ * @@ -13,6 +13,7 @@ #include <stdio.h> #include <errno.h> #include <sys/types.h> +#include <pthread.h> #include <bsp.h> #include <bsp/irq.h> @@ -20,13 +21,13 @@ #include <rtems/fb.h> -/* these routines are defined in the microwindows code. This - driver is here more as an example of how to implement and - use the micro FB interface -*/ +/* these routines are defined in vgainit.c.*/ extern void ega_hwinit( void ); extern void ega_hwterm( void ); +/* mutex attribure */ +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + /* screen information for the VGA driver */ static struct fb_var_screeninfo fb_var = { @@ -44,6 +45,7 @@ static struct fb_fix_screeninfo fb_fix = .line_length = 80 /* chars per line */ }; + static uint16_t red16[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff @@ -57,6 +59,12 @@ static uint16_t blue16[] = { 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff }; +/* Functionality to support multiple VGA frame buffers can be added easily, + * but is not supported at this moment because there is no need for two or + * more "classic" VGA adapters. Multiple frame buffer drivers may be + * implemented and If we had implement it they would be named as "/dev/fb0", + * "/dev/fb1", "/dev/fb2" and so on. + */ /* * fbvga device driver INITIALIZE entry point. */ @@ -75,10 +83,10 @@ rtems_device_driver frame_buffer_initialize( */ status = rtems_io_register_name ("/dev/fb0", major, 0); if (status != RTEMS_SUCCESSFUL) { - printk("Error registering FBVGA device!\n"); + printk("Error registering /dev/fb0 FBVGA framebuffer device!\n"); rtems_fatal_error_occurred( status ); } - + return RTEMS_SUCCESSFUL; } @@ -91,10 +99,17 @@ rtems_device_driver frame_buffer_open( void *arg ) { - ega_hwinit(); - printk( "FBVGA open called.\n" ); - - return RTEMS_SUCCESSFUL; + if (pthread_mutex_trylock(&mutex)== 0){ + /* restore previous state. for VGA this means return to text mode. + * leave out if graphics hardware has been initialized in + * frame_buffer_initialize() + */ + ega_hwinit(); + printk( "FBVGA open called.\n" ); + return RTEMS_SUCCESSFUL; + } + + return RTEMS_UNSATISFIED; } /* @@ -106,15 +121,20 @@ rtems_device_driver frame_buffer_close( void *arg ) { - ega_hwterm(); - printk( "FBVGA close called.\n" ); + if (pthread_mutex_unlock(&mutex) == 0){ + /* restore previous state. for VGA this means return to text mode. + * leave out if graphics hardware has been initialized in + * frame_buffer_initialize() */ + ega_hwterm(); + printk( "FBVGA close called.\n" ); + return RTEMS_SUCCESSFUL; + } - return RTEMS_SUCCESSFUL; + return RTEMS_UNSATISFIED; } /* * fbvga device driver READ entry point. - * Read characters from the PS/2 mouse. */ rtems_device_driver frame_buffer_read( rtems_device_major_number major, @@ -122,18 +142,31 @@ rtems_device_driver frame_buffer_read( void *arg ) { + /*printk( "FBVGA read called.\n" );*/ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; - - printk( "FBVGA read called.\n" ); - - rw_args->bytes_moved = 0; - - return RTEMS_SUCCESSFUL; + if ( (rw_args->offset >= fb_fix.smem_len) || (rw_args->count < 0) ){ + return RTEMS_UNSATISFIED; + } + else + { + /*partial reading*/ + if ( (rw_args->offset + rw_args->count) > fb_fix.smem_len ){ + rw_args->count = fb_fix.smem_len - rw_args->offset; + memcpy(rw_args->buffer, (const void *) (rw_args->offset + fb_fix.smem_start), rw_args->count); + rw_args->bytes_moved = rw_args->count; + return RTEMS_SUCCESSFUL; + } + /*best reading case*/ + else{ + memcpy(rw_args->buffer, (const void *) (rw_args->offset + fb_fix.smem_start), rw_args->count); + rw_args->bytes_moved = rw_args->count; + return RTEMS_SUCCESSFUL; + } + } } /* * frame_buffer device driver WRITE entry point. - * Write characters to the PS/2 mouse. */ rtems_device_driver frame_buffer_write( rtems_device_major_number major, @@ -141,11 +174,27 @@ rtems_device_driver frame_buffer_write( void *arg ) { + /*printk( "FBVGA write called.\n" );*/ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; - - printk( "FBVGA write called.\n" ); - rw_args->bytes_moved = 0; - return RTEMS_SUCCESSFUL; + if ( (rw_args->offset >= fb_fix.smem_len) || (rw_args->count < 0) ){ + return RTEMS_UNSATISFIED; + } + else + { + /*partial writing*/ + if ( (rw_args->offset + rw_args->count) > fb_fix.smem_len ){ + rw_args->count = fb_fix.smem_len - rw_args->offset; + memcpy( (void *) (rw_args->offset + fb_fix.smem_start), rw_args->buffer, rw_args->count); + rw_args->bytes_moved = rw_args->count; + return RTEMS_SUCCESSFUL; + } + /* best writing case*/ + else{ + memcpy( (void *) (rw_args->offset + fb_fix.smem_start), rw_args->buffer, rw_args->count); + rw_args->bytes_moved = rw_args->count; + return RTEMS_SUCCESSFUL; + } + } } static int get_fix_screen_info( struct fb_fix_screeninfo *info ) @@ -156,7 +205,7 @@ static int get_fix_screen_info( struct fb_fix_screeninfo *info ) static int get_var_screen_info( struct fb_var_screeninfo *info ) { - *info = fb_var; + *info = fb_var; return 0; } @@ -206,19 +255,20 @@ rtems_device_driver frame_buffer_control( switch( args->command ) { case FBIOGET_FSCREENINFO: - args->ioctl_return = get_fix_screen_info( args->buffer ); + args->ioctl_return = get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer ); break; case FBIOGET_VSCREENINFO: - args->ioctl_return = get_var_screen_info( args->buffer ); + args->ioctl_return = get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer ); break; case FBIOPUT_VSCREENINFO: /* not implemented yet*/ - break; + args->ioctl_return = -1; + return RTEMS_UNSATISFIED; case FBIOGETCMAP: - args->ioctl_return = get_palette( args->buffer ); + args->ioctl_return = get_palette( ( struct fb_cmap * ) args->buffer ); break; case FBIOPUTCMAP: - args->ioctl_return = set_palette( args->buffer ); + args->ioctl_return = set_palette( ( struct fb_cmap * ) args->buffer ); break; default: |