File indexing completed on 2025-05-11 08:23:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <stdlib.h>
0011 #include <stdio.h>
0012 #include <errno.h>
0013 #include <sys/types.h>
0014 #include <pthread.h>
0015
0016 #include <bsp.h>
0017 #include <bsp/irq.h>
0018 #include <rtems/libio.h>
0019
0020 #include <rtems/fb.h>
0021 #include <rtems/framebuffer.h>
0022
0023 #include <rtems/score/atomic.h>
0024
0025
0026 extern void ega_hwinit( void );
0027 extern void ega_hwterm( void );
0028
0029
0030 static Atomic_Flag driver_mutex;
0031
0032
0033 static struct fb_var_screeninfo fb_var =
0034 {
0035 .xres = 640,
0036 .yres = 480,
0037 .bits_per_pixel = 4
0038 };
0039
0040 static struct fb_fix_screeninfo fb_fix =
0041 {
0042 .smem_start = (volatile char *)0xA0000,
0043 .smem_len = 0x10000,
0044 .type = FB_TYPE_VGA_PLANES,
0045 .visual = FB_VISUAL_PSEUDOCOLOR,
0046 .line_length = 80
0047 };
0048
0049
0050 static uint16_t red16[] = {
0051 0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa,
0052 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff
0053 };
0054 static uint16_t green16[] = {
0055 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa,
0056 0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff
0057 };
0058 static uint16_t blue16[] = {
0059 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa,
0060 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff
0061 };
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 rtems_device_driver frame_buffer_initialize(
0073 rtems_device_major_number major,
0074 rtems_device_minor_number minor,
0075 void *arg
0076 )
0077 {
0078 rtems_status_code status;
0079
0080 printk( "FBVGA -- driver initializing..\n" );
0081
0082
0083
0084
0085 status = rtems_io_register_name (FRAMEBUFFER_DEVICE_0_NAME, major, 0);
0086 if (status != RTEMS_SUCCESSFUL) {
0087 printk("Error registering " FRAMEBUFFER_DEVICE_0_NAME
0088 " FBVGA framebuffer device!\n");
0089 rtems_fatal_error_occurred( status );
0090 }
0091
0092 _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE);
0093
0094 return RTEMS_SUCCESSFUL;
0095 }
0096
0097
0098
0099
0100 rtems_device_driver frame_buffer_open(
0101 rtems_device_major_number major,
0102 rtems_device_minor_number minor,
0103 void *arg
0104 )
0105 {
0106 if (_Atomic_Flag_test_and_set(&driver_mutex, ATOMIC_ORDER_ACQUIRE) != 0 ) {
0107
0108
0109
0110
0111 ega_hwinit();
0112 printk( "FBVGA open called.\n" );
0113 return RTEMS_SUCCESSFUL;
0114 }
0115
0116 return RTEMS_UNSATISFIED;
0117 }
0118
0119
0120
0121
0122 rtems_device_driver frame_buffer_close(
0123 rtems_device_major_number major,
0124 rtems_device_minor_number minor,
0125 void *arg
0126 )
0127 {
0128 _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE);
0129
0130
0131
0132 ega_hwterm();
0133 printk( "FBVGA close called.\n" );
0134 return RTEMS_SUCCESSFUL;
0135
0136
0137
0138
0139 rtems_device_driver frame_buffer_read(
0140 rtems_device_major_number major,
0141 rtems_device_minor_number minor,
0142 void *arg
0143 )
0144 {
0145 rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
0146 rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
0147 memcpy(rw_args->buffer, (const void *) (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved);
0148 return RTEMS_SUCCESSFUL;
0149 }
0150
0151
0152
0153
0154 rtems_device_driver frame_buffer_write(
0155 rtems_device_major_number major,
0156 rtems_device_minor_number minor,
0157 void *arg
0158 )
0159 {
0160 rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
0161 rw_args->bytes_moved = ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? (fb_fix.smem_len - rw_args->offset) : rw_args->count;
0162 memcpy( (void *) (fb_fix.smem_start + rw_args->offset), rw_args->buffer, rw_args->bytes_moved);
0163 return RTEMS_SUCCESSFUL;
0164 }
0165
0166 static int get_fix_screen_info( struct fb_fix_screeninfo *info )
0167 {
0168 *info = fb_fix;
0169 return 0;
0170 }
0171
0172 static int get_var_screen_info( struct fb_var_screeninfo *info )
0173 {
0174 *info = fb_var;
0175 return 0;
0176 }
0177
0178 static int get_palette( struct fb_cmap *cmap )
0179 {
0180 uint32_t i;
0181
0182 if ( cmap->start + cmap->len >= 16 )
0183 return 1;
0184
0185 for( i = 0; i < cmap->len; i++ ) {
0186 cmap->red[ cmap->start + i ] = red16[ cmap->start + i ];
0187 cmap->green[ cmap->start + i ] = green16[ cmap->start + i ];
0188 cmap->blue[ cmap->start + i ] = blue16[ cmap->start + i ];
0189 }
0190 return 0;
0191 }
0192
0193 static int set_palette( struct fb_cmap *cmap )
0194 {
0195 uint32_t i;
0196
0197 if ( cmap->start + cmap->len >= 16 )
0198 return 1;
0199
0200 for( i = 0; i < cmap->len; i++ ) {
0201 red16[ cmap->start + i ] = cmap->red[ cmap->start + i ];
0202 green16[ cmap->start + i ] = cmap->green[ cmap->start + i ];
0203 blue16[ cmap->start + i ] = cmap->blue[ cmap->start + i ];
0204 }
0205 return 0;
0206 }
0207
0208
0209
0210
0211
0212 rtems_device_driver frame_buffer_control(
0213 rtems_device_major_number major,
0214 rtems_device_minor_number minor,
0215 void *arg
0216 )
0217 {
0218 rtems_libio_ioctl_args_t *args = arg;
0219
0220 printk( "FBVGA ioctl called, cmd=%x\n", args->command );
0221
0222 switch( args->command ) {
0223 case FBIOGET_FSCREENINFO:
0224 args->ioctl_return = get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer );
0225 break;
0226 case FBIOGET_VSCREENINFO:
0227 args->ioctl_return = get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer );
0228 break;
0229 case FBIOPUT_VSCREENINFO:
0230
0231 args->ioctl_return = -1;
0232 return RTEMS_UNSATISFIED;
0233 case FBIOGETCMAP:
0234 args->ioctl_return = get_palette( ( struct fb_cmap * ) args->buffer );
0235 break;
0236 case FBIOPUTCMAP:
0237 args->ioctl_return = set_palette( ( struct fb_cmap * ) args->buffer );
0238 break;
0239
0240 default:
0241 args->ioctl_return = 0;
0242 break;
0243 }
0244 return RTEMS_SUCCESSFUL;
0245 }