source: rtems/c/src/lib/libbsp/i386/pc386/console/fb_vga.c @ 573e3b2

4.104.115
Last change on this file since 573e3b2 was 573e3b2, checked in by Joel Sherrill <joel.sherrill@…>, on 08/21/09 at 18:35:28

2009-08-21 Roxana Leontie <roxana.leontie@…>

  • pc386/console/fb_vga.c: added read/write functionality; added thread safety to prevent multiple open() operations of the frame buffer device.
  • Property mode set to 100644
File size: 7.5 KB
Line 
1/*
2 * Copyright (c) 2000 - Rosimildo da Silva ( rdasilva@connecttel.com )
3 *
4 * MODULE DESCRIPTION:
5 * This module implements FB driver for "Bare VGA". It uses the
6 * routines for "bare hardware" found in vgainit.c.
7 *
8 *  $Id$
9 *
10 */
11
12#include <stdlib.h>
13#include <stdio.h>
14#include <errno.h>
15#include <sys/types.h>
16#include <pthread.h>
17
18#include <bsp.h>
19#include <bsp/irq.h>
20#include <rtems/libio.h>
21
22#include <rtems/fb.h>
23
24/* these routines are defined in vgainit.c.*/
25extern void ega_hwinit( void );
26extern void ega_hwterm( void );
27
28/* mutex attribure */
29pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
30
31/* screen information for the VGA driver */
32static struct fb_var_screeninfo fb_var =
33{
34  .xres                = 640,
35  .yres                = 480,
36  .bits_per_pixel      = 4
37};
38
39static struct fb_fix_screeninfo fb_fix =
40{
41  .smem_start          = (volatile char *)0xA0000,     /* buffer pointer    */
42  .smem_len            = 0x10000,                      /* buffer size       */
43  .type                = FB_TYPE_VGA_PLANES,           /* type of dsplay    */
44  .visual              = FB_VISUAL_PSEUDOCOLOR,        /* color scheme used */
45  .line_length         = 80                            /* chars per line    */
46};
47
48
49static uint16_t red16[] = {
50   0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa,
51   0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff
52};
53static uint16_t green16[] = {
54   0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa,
55   0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff
56};
57static uint16_t blue16[] = {
58   0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa,
59   0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff
60};
61
62/* Functionality to support multiple VGA frame buffers can be added easily,
63 * but is not supported at this moment because there is no need for two or
64 * more "classic" VGA adapters.  Multiple frame buffer drivers may be
65 * implemented and If we had implement it they would be named as "/dev/fb0",
66 * "/dev/fb1", "/dev/fb2" and so on.
67 */
68/*
69 * fbvga device driver INITIALIZE entry point.
70 */
71rtems_device_driver frame_buffer_initialize(
72  rtems_device_major_number  major,
73  rtems_device_minor_number  minor,
74  void                      *arg
75)
76{
77  rtems_status_code status;
78
79  printk( "FBVGA -- driver initializing..\n" );
80
81  /*
82   * Register the device
83   */
84  status = rtems_io_register_name ("/dev/fb0", major, 0);
85  if (status != RTEMS_SUCCESSFUL) {
86    printk("Error registering /dev/fb0 FBVGA framebuffer device!\n");
87    rtems_fatal_error_occurred( status );
88  }
89 
90  return RTEMS_SUCCESSFUL;
91}
92
93/*
94 * fbvga device driver OPEN entry point
95 */
96rtems_device_driver frame_buffer_open(
97  rtems_device_major_number  major,
98  rtems_device_minor_number  minor,
99  void                      *arg
100)
101{
102  if (pthread_mutex_trylock(&mutex)== 0){
103      /* restore previous state.  for VGA this means return to text mode.
104       * leave out if graphics hardware has been initialized in
105       * frame_buffer_initialize()
106       */
107      ega_hwinit();
108      printk( "FBVGA open called.\n" );     
109      return RTEMS_SUCCESSFUL;
110  }
111 
112  return RTEMS_UNSATISFIED;
113}
114
115/*
116 * fbvga device driver CLOSE entry point
117 */
118rtems_device_driver frame_buffer_close(
119  rtems_device_major_number  major,
120  rtems_device_minor_number  minor,
121  void                      *arg
122)
123{
124  if (pthread_mutex_unlock(&mutex) == 0){
125    /* restore previous state.  for VGA this means return to text mode.
126     * leave out if graphics hardware has been initialized in
127     * frame_buffer_initialize() */
128    ega_hwterm();
129    printk( "FBVGA close called.\n" );
130    return RTEMS_SUCCESSFUL;
131  }
132
133  return RTEMS_UNSATISFIED;
134}
135
136/*
137 * fbvga device driver READ entry point.
138 */
139rtems_device_driver frame_buffer_read(
140  rtems_device_major_number  major,
141  rtems_device_minor_number  minor,
142  void                      *arg
143)
144{
145  /*printk( "FBVGA read called.\n" );*/
146  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
147  if ( (rw_args->offset >= fb_fix.smem_len) || (rw_args->count < 0) ){
148     return RTEMS_UNSATISFIED;
149  }
150  else
151  {
152        /*partial reading*/
153        if ( (rw_args->offset + rw_args->count) > fb_fix.smem_len ){
154           rw_args->count = fb_fix.smem_len - rw_args->offset;
155           memcpy(rw_args->buffer, (const void *) (rw_args->offset + fb_fix.smem_start), rw_args->count);
156           rw_args->bytes_moved = rw_args->count;
157           return RTEMS_SUCCESSFUL;
158        }
159        /*best reading case*/
160        else{
161           memcpy(rw_args->buffer, (const void *) (rw_args->offset + fb_fix.smem_start), rw_args->count);
162           rw_args->bytes_moved = rw_args->count;
163           return RTEMS_SUCCESSFUL;
164        }
165   }     
166}
167
168/*
169 * frame_buffer device driver WRITE entry point.
170 */
171rtems_device_driver frame_buffer_write(
172  rtems_device_major_number  major,
173  rtems_device_minor_number  minor,
174  void                      *arg
175)
176{
177  /*printk( "FBVGA write called.\n" );*/
178  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
179  if ( (rw_args->offset >= fb_fix.smem_len) || (rw_args->count < 0) ){
180     return RTEMS_UNSATISFIED;
181  }
182  else
183  {
184        /*partial writing*/
185        if ( (rw_args->offset + rw_args->count) > fb_fix.smem_len ){
186           rw_args->count = fb_fix.smem_len - rw_args->offset;
187           memcpy( (void *) (rw_args->offset + fb_fix.smem_start), rw_args->buffer, rw_args->count);
188           rw_args->bytes_moved = rw_args->count;
189           return RTEMS_SUCCESSFUL;
190        }
191        /* best writing case*/
192        else{
193           memcpy( (void *) (rw_args->offset + fb_fix.smem_start), rw_args->buffer, rw_args->count);
194           rw_args->bytes_moved = rw_args->count;
195           return RTEMS_SUCCESSFUL;
196        }
197   }         
198}
199
200static int get_fix_screen_info( struct fb_fix_screeninfo *info )
201{
202  *info = fb_fix;
203  return 0;
204}
205
206static int get_var_screen_info( struct fb_var_screeninfo *info )
207{
208  *info =  fb_var;
209  return 0;
210}
211
212static int get_palette( struct fb_cmap *cmap )
213{
214  uint32_t i;
215
216  if ( cmap->start + cmap->len >= 16 )
217    return 1;
218
219  for( i = 0; i < cmap->len; i++ ) {
220    cmap->red[ cmap->start + i ]   = red16[ cmap->start + i ];
221    cmap->green[ cmap->start + i ] = green16[ cmap->start + i ];
222    cmap->blue[ cmap->start + i ]  = blue16[ cmap->start + i ];
223  }
224  return 0;
225}
226
227static int set_palette( struct fb_cmap *cmap )
228{
229  uint32_t i;
230
231  if ( cmap->start + cmap->len >= 16 )
232    return 1;
233
234  for( i = 0; i < cmap->len; i++ ) {
235    red16[ cmap->start + i ] = cmap->red[ cmap->start + i ];
236    green16[ cmap->start + i ] = cmap->green[ cmap->start + i ];
237    blue16[ cmap->start + i ] = cmap->blue[ cmap->start + i ];
238  }
239  return 0;
240}
241
242/*
243 * IOCTL entry point -- This method is called to carry
244 * all services of this interface.
245 */
246rtems_device_driver frame_buffer_control(
247  rtems_device_major_number  major,
248  rtems_device_minor_number  minor,
249  void                      *arg
250)
251{
252  rtems_libio_ioctl_args_t *args = arg;
253
254  printk( "FBVGA ioctl called, cmd=%x\n", args->command  );
255
256  switch( args->command ) {
257    case FBIOGET_FSCREENINFO:
258      args->ioctl_return =  get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer );
259      break;
260    case FBIOGET_VSCREENINFO:
261      args->ioctl_return =  get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer );
262      break;
263    case FBIOPUT_VSCREENINFO:
264      /* not implemented yet*/
265      args->ioctl_return = -1;
266      return RTEMS_UNSATISFIED;
267    case FBIOGETCMAP:
268      args->ioctl_return =  get_palette( ( struct fb_cmap * ) args->buffer );
269      break;
270    case FBIOPUTCMAP:
271      args->ioctl_return =  set_palette( ( struct fb_cmap * ) args->buffer );
272      break;
273
274    default:
275     args->ioctl_return = 0;
276     break;
277  }
278  return RTEMS_SUCCESSFUL;
279}
Note: See TracBrowser for help on using the repository browser.