diff options
Diffstat (limited to 'c/src/lib/libbsp/i386/pc386/console/fb_vesa_rm.c')
-rw-r--r-- | c/src/lib/libbsp/i386/pc386/console/fb_vesa_rm.c | 1004 |
1 files changed, 0 insertions, 1004 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/console/fb_vesa_rm.c b/c/src/lib/libbsp/i386/pc386/console/fb_vesa_rm.c deleted file mode 100644 index 1c42956fce..0000000000 --- a/c/src/lib/libbsp/i386/pc386/console/fb_vesa_rm.c +++ /dev/null @@ -1,1004 +0,0 @@ -/** - * @file fb_vesa_rm.c - * - * @ingroup i386_pc386 - * - * @brief FB driver for graphic hardware compatible with VESA Bios Extension - * Real mode interface utilized - * Tested on real HW. - * - * Public sources related: - * - VESA BIOS EXTENSION (VBE) Core Function Standard, Ver: 3.0, Sep 16, 1998 - * - VESA Enhanced Extended Display Identification Data (E-EDID) Standard - * Release A, Revision 2, September 25, 2006 - * - * Hardware is completely initialized upon boot of the system. - * Therefore there is no way to change graphics mode later. - * - * Interrupt 0x10 is used for entering graphics BIOS. - * - * Driver reads parameter from multiboot command line to setup video: - * "--video=<resX>x<resY>[-<bpp>]" - * "--video=auto" - try EDID to find mode that fits the display attached best - * "--video=none" / "--video=off" - do not initialize the driver - * If cmdline parameter is not specified the rtems_fb_default_mode - * variable content is tested (see doc below). - * Command line option has higher priority. rtems_fb_default_mode is probed - * only if cmdline "--video=" is not specified at all. - * - * If neither of the above options is specified the driver is not initialized. - */ - -/* - * Copyright (c) 2014 - CTU in Prague - * Jan Doležal ( dolezj21@fel.cvut.cz ) - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - * - * The code for rtems_buffer_* functions was greatly - * inspired or coppied from: - * - RTEMS fb_cirrus.c - Alexandru-Sever Horin (alex.sever.h@gmail.com) - */ - -#include <inttypes.h> - -#include <bsp.h> - -#include <bsp/fb_default_mode.h> -#include <bsp/fb_vesa.h> -#include <bsp/realmode_int.h> - -#include <pthread.h> - -#include <rtems/libio.h> - -#include <rtems/fb.h> -#include <rtems/framebuffer.h> - -#include <rtems/score/atomic.h> - -#include <stdlib.h> - -#define FB_VESA_NAME "FB_VESA_RM" - -/** - * @brief Allows to enable initialization of VESA real mode driver from - * an application by setting the value of this variable to non null value in - * user's module. The value of this variable will be then updated - * when linked with application's object. - * - * Further the value should point to string in the following format: - * "<resX>x<resY>[-<bpp>]" - e.g. "1024x768-32" - * "auto" - try EDID to find mode that fits the display attached best - * "none" / "off" - do not initialize the driver - * the given parameters are used if applicable. - * - * Command line argument "--video=" has priority over this string. - */ -const char * const rtems_fb_default_mode; - -/** - * @brief Initializes VBE framebuffer during bootup. - * - * utilizes switches to real mode interrupts and therefore must be - * called during bootup before tick is set up and real-time - * interrupt vectors utilized - */ -void vesa_realmode_bootup_init(void); - -/* flag to limit driver to protect against multiple opens */ -static Atomic_Flag driver_mutex; - -/* screen information for the VGA driver - * standard structures - from RTEMS fb interface - */ -static struct fb_var_screeninfo fb_var; -static struct fb_fix_screeninfo fb_fix; - -static int32_t vbe_used_mode; - -uint32_t VBE_controller_information( VBE_vbe_info_block *info_block, - uint16_t queried_VBE_Version) -{ - uint16_t size; - VBE_vbe_info_block *VBE_buffer = - (VBE_vbe_info_block *)i386_get_default_rm_buffer(&size); - i386_realmode_interrupt_registers parret; - parret.reg_eax = VBE_RetVBEConInf; - uint16_t seg, off; - i386_Physical_to_real(VBE_buffer, &seg, &off); - parret.reg_edi = (uint32_t)off; - parret.reg_es = seg; - /* indicate to graphic's bios that VBE2.0 extended information is desired */ - if (queried_VBE_Version >= 0x200) - { - memcpy( - &VBE_buffer->VbeSignature, - VBE20plus_SIGNATURE, - sizeof(VBE_buffer->VbeSignature) - ); - } - if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) - return -1; - if ((parret.reg_eax & 0xFFFF) == - (VBE_callSuccessful<<8 | VBE_functionSupported)) - { - *info_block = *VBE_buffer; - } - return (parret.reg_eax & 0xFFFF); -} - -uint32_t VBE_mode_information( VBE_mode_info_block *info_block, - uint16_t mode_number) -{ - uint16_t size; - VBE_mode_info_block *VBE_buffer = - (VBE_mode_info_block *)i386_get_default_rm_buffer(&size); - i386_realmode_interrupt_registers parret; - parret.reg_eax = VBE_RetVBEModInf; - parret.reg_ecx = mode_number; - uint16_t seg, off; - i386_Physical_to_real(VBE_buffer, &seg, &off); - parret.reg_edi = (uint32_t)off; - parret.reg_es = seg; - if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) - return -1; - if ((parret.reg_eax & 0xFFFF) == - (VBE_callSuccessful<<8 | VBE_functionSupported)) - { - *info_block = *VBE_buffer; - } - return (parret.reg_eax & 0xFFFF); -} - -uint32_t VBE_set_mode( uint16_t mode_number, - VBE_CRTC_info_block *info_block) -{ - uint16_t size; - VBE_CRTC_info_block *VBE_buffer = - (VBE_CRTC_info_block *)i386_get_default_rm_buffer(&size); - i386_realmode_interrupt_registers parret; - /* copy CRTC */ - *VBE_buffer = *info_block; - parret.reg_eax = VBE_SetVBEMod; - parret.reg_ebx = mode_number; - uint16_t seg, off; - i386_Physical_to_real(VBE_buffer, &seg, &off); - parret.reg_edi = (uint32_t)off; - parret.reg_es = seg; - if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) - return -1; - return (parret.reg_eax & 0xFFFF); -} - -uint32_t VBE_current_mode(uint16_t *mode_number) -{ - i386_realmode_interrupt_registers parret; - parret.reg_eax = VBE_RetCurVBEMod; - if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) - return -1; - *mode_number = (uint16_t)parret.reg_ebx; - return (parret.reg_eax & 0xFFFF); -} - -uint32_t VBE_report_DDC_capabilities(uint16_t controller_unit_number, - uint8_t *seconds_to_transfer_EDID_block, - uint8_t *DDC_level_supported) -{ - i386_realmode_interrupt_registers parret; - parret.reg_eax = VBE_DisDatCha; - parret.reg_ebx = VBEDDC_Capabilities; - parret.reg_ecx = controller_unit_number; - parret.reg_edi = 0; - parret.reg_es = 0; - if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) - return -1; - *seconds_to_transfer_EDID_block = (uint8_t)parret.reg_ebx >> 8; - *DDC_level_supported = (uint8_t)parret.reg_ebx; - return (parret.reg_eax & 0xFFFF); -} - -uint32_t VBE_read_EDID(uint16_t controller_unit_number, - uint16_t EDID_block_number, - EDID_edid1 *buffer) -{ - uint16_t size; - EDID_edid1 *VBE_buffer = (EDID_edid1*)i386_get_default_rm_buffer(&size); - i386_realmode_interrupt_registers parret; - parret.reg_eax = VBE_DisDatCha; - parret.reg_ebx = VBEDDC_ReadEDID; - parret.reg_ecx = controller_unit_number; - parret.reg_edx = EDID_block_number; - uint16_t seg, off; - i386_Physical_to_real(VBE_buffer, &seg, &off); - parret.reg_edi = (uint32_t)off; - parret.reg_es = seg; - if (i386_real_interrupt_call(INTERRUPT_NO_VIDEO_SERVICES, &parret) == 0) - return -1; - if ((parret.reg_eax & 0xFFFF) == - (VBE_callSuccessful<<8 | VBE_functionSupported)) - { - *buffer = *VBE_buffer; - } - return (parret.reg_eax & 0xFFFF); -} - -/** - * @brief Basic graphic's mode parameters - */ -typedef struct { - /** number of the graphic's mode */ - uint16_t mode_number; - /** number of pixels in one line */ - uint16_t resX; - /** number of lines */ - uint16_t resY; - /** bits per pixel */ - uint8_t bpp; -} Mode_params; - -typedef enum { - NO_SUITABLE_MODE = -1, - BAD_FORMAT = -2, - AUTO_SELECT = -3, - DONT_INIT = -4, - NO_MODE_REQ = -5, -} mode_err_ret_val; - -/** - * @brief Find mode by resolution in the given list of modes - * - * finds mode in \p mode_list of \p list_length length according to resolution - * given in \p searched_resolution . If bpp is given in that struct as well - * mode with such color depth and resolution is searched for. Otherwise bpp - * has to be zero. Mode number found is returned and also filled into - * \p searched_resolution . bpp is also filled into \p searchedResolution if it - * was 0 before call. - * - * @param[in] mode_list list of modes to be searched - * @param[in] list_length number of modes in the list - * @param[in,out] searched_resolution element filled with searched resolution - * or/and bpp; mode_number is filled in if appropriate mode found - * @retval mode number satisfying given parameters - * @retval -1 no suitable mode found - */ -static int32_t find_mode_by_resolution(Mode_params *mode_list, - uint8_t list_length, - Mode_params *searched_resolution) -{ - uint8_t i = 0; - while (i < list_length) - { - if (searched_resolution->resX == mode_list[i].resX && - searched_resolution->resY == mode_list[i].resY) - { - if (searched_resolution->bpp==0 || - searched_resolution->bpp==mode_list[i].bpp) - { - searched_resolution->bpp = mode_list[i].bpp; - searched_resolution->mode_number = mode_list[i].mode_number; - return mode_list[i].mode_number; - } - } - i++; - } - return NO_SUITABLE_MODE; -} - -/** - * @brief Find mode given in string format. - * - * expected format - * <resX>x<resY>[-<bpp>] - * numbers <resX>, <resY> and <bpp> are decadic - * - * @param[in] mode_list list of modes to be searched - * @param[in] list_length number of modes in the list - * @param[in] video_string string to be parsed - * @retval video mode number to be set - * @retval -1 no suitable mode found - * @retval -2 bad format of the video_string - * @retval -3 automatic mode selection requested - * @retval -4 request to not initialize graphics - * @retval -5 no mode requested/empty video string - */ -static int32_t find_mode_from_string(Mode_params *mode_list, - uint8_t list_length, - const char *video_string) -{ - const char* opt; - Mode_params cmdline_mode; - char* endptr; - cmdline_mode.bpp = 16; /* default bpp */ - opt = video_string; - if (opt) - { - if (strncmp(opt, "auto", 4) == 0) - return AUTO_SELECT; - if (strncmp(opt, "none", 4) == 0 || - strncmp(opt, "off", 3) == 0) - { - return DONT_INIT; - } - cmdline_mode.resX = strtol(opt, &endptr, 10); - if (*endptr != 'x') - { - return BAD_FORMAT; - } - opt = endptr+1; - cmdline_mode.resY = strtol(opt, &endptr, 10); - switch (*endptr) - { - case '-': - opt = endptr+1; - if (strlen(opt) <= 2) - cmdline_mode.bpp = strtol(opt, &endptr, 10); - else - { - cmdline_mode.bpp = strtol(opt, &endptr, 10); - if (*endptr != ' ') - { - return BAD_FORMAT; - } - } - case ' ': - case 0: - break; - default: - return BAD_FORMAT; - } - - return find_mode_by_resolution(mode_list, list_length, &cmdline_mode); - } - return NO_MODE_REQ; -} - -/** - * @brief Find mode given within command line. - * - * Parse command line option "--video=" if available. - * expected format - * --video=<resX>x<resY>[-<bpp>] - * numbers <resX>, <resY> and <bpp> are decadic - * - * @param[in] mode_list list of modes to be searched - * @param[in] list_length number of modes in the list - * @retval video mode number to be set - * @retval -1 no suitable mode found - * @retval -2 bad format of the video_string - * @retval -3 automatic mode selection requested - * @retval -4 request to not initialize graphics - * @retval -5 no mode requested/empty video string - */ -static int32_t find_mode_using_cmdline(Mode_params *mode_list, - uint8_t list_length) -{ - const char* opt; - opt = bsp_cmdline_arg("--video="); - if (opt) - { - opt += sizeof("--video=")-1; - return find_mode_from_string(mode_list, list_length, opt); - } - return NO_MODE_REQ; -} - -/** - * @brief Find mode number best fitting to monitor attached - * - * @param[in] mode_list list of modes to be searched - * @param[in] list_length number of modes in the list - * @retval video mode number to be set - * @retval -1 on parsing error or when no suitable mode found - */ -static int32_t find_mode_using_EDID( Mode_params *mode_list, - uint8_t list_length) -{ - EDID_edid1 edid; - uint8_t checksum, iterator; - uint8_t index, j; - Mode_params EDIDmode; - checksum = 0; - iterator = 0; - EDIDmode.bpp = 0; - if (VBE_read_EDID(0, 0, &edid) != - (VBE_callSuccessful<<8 | VBE_functionSupported)) - { - printk(FB_VESA_NAME " Function 15h (read EDID) not supported.\n"); - return -1; - } -/* version of EDID structure */ - if (edid.Version == 1) - { /* EDID version 1 */ - while (iterator < sizeof(EDID_edid1)) - { - checksum += *((uint8_t *)&edid+iterator); - iterator++; - } - if (checksum) - /* not implemented: try to read EDID again */ - printk(FB_VESA_NAME " EDID v1 checksum failed\n"); - - /* try to find Detailed Timing Descriptor (defined in BASE EDID) - in controller mode list; first should be preffered mode */ - index = 0; - while (index < 4) - { - /* skip if it is monitor descriptor */ - if (edid.dtd_md[index].md.Flag0[0] == 0 && - edid.dtd_md[index].md.Flag0[1] == 0 && - edid.dtd_md[index].md.Flag1 == 0) - { - index++; - continue; - } - EDIDmode.resX = DTD_horizontal_active(&edid.dtd_md[0].dtd); - EDIDmode.resY = DTD_vertical_active(&edid.dtd_md[0].dtd); - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - - index++; - } - /* try to find Detailed Timing Descriptor (defined in optional EXTENSION - Blocks) in controller mode list */ - if (edid.ExtensionFlag > 0) - { - /* not implemented */ - } - /* try to find CVT (defined in BASE EDID) in controller mode list */ - index = 1; - while (index < 4) - { - if (edid.dtd_md[index].md.DataTypeTag == - EDID_DTT_CVT3ByteTimingCodes && - edid.dtd_md[index].md.Flag0[0] == 0 && - edid.dtd_md[index].md.Flag0[1] == 0 && - edid.dtd_md[index].md.Flag1 == 0 && - edid.dtd_md[index].md.Flag2 == 0) - { - EDID_CVT_timing_codes_3B *cvt = (EDID_CVT_timing_codes_3B *) - &edid.dtd_md[index].md.DescriptorData[0]; - j = 0; - while (j < 4) - { - EDIDmode.resY = edid1_CVT_addressable_lines_high( - &cvt->cvt[j] - ); - switch (edid1_CVT_aspect_ratio(&cvt->cvt[j])) - { - case EDID_CVT_AspectRatio_4_3: - EDIDmode.resX = (EDIDmode.resY*4)/3; - break; - case EDID_CVT_AspectRatio_16_9: - EDIDmode.resX = (EDIDmode.resY*16)/9; - break; - case EDID_CVT_AspectRatio_16_10: - EDIDmode.resX = (EDIDmode.resY*16)/10; - break; - case EDID_CVT_AspectRatio_15_9: - EDIDmode.resX = (EDIDmode.resY*15)/9; - break; - } - EDIDmode.resX = (EDIDmode.resX/8)*8; - if (find_mode_by_resolution( - mode_list, list_length, &EDIDmode) != -1) - return EDIDmode.mode_number; - - j++; - } - } - index++; - } - /* try to find CVT (defined in optional EXTENSION Blocks) - in controller mode list */ - /* not implemented */ - /* try to find Standard Timings (listed in BASE EDID) - in controller mode list */ - index = 0; - while (index < 8) - { - /* check if descriptor is unused */ - if (edid1_STI_is_unused(&edid.STI[index])) - { - index++; - continue; - } - EDIDmode.resX = (edid.STI[index].HorizontalActivePixels+31)*8; - switch (edid.STI[index].ImageAspectRatio_RefreshRate & - EDID1_STI_ImageAspectRatioMask) - { - case EDID_STI_AspectRatio_16_10: - EDIDmode.resY = (EDIDmode.resX*10)/16; - break; - case EDID_STI_AspectRatio_4_3: - EDIDmode.resY = (EDIDmode.resX*3)/4; - break; - case EDID_STI_AspectRatio_5_4: - EDIDmode.resY = (EDIDmode.resX*4)/5; - break; - case EDID_STI_AspectRatio_16_9: - EDIDmode.resY = (EDIDmode.resX*9)/16; - break; - } - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - - index++; - } - /* try to find Standard Timings (listed in optional EXTENSION Blocks) - in controller mode list */ - /* not implemented */ - /* use Established Timings */ - if (edid1_established_tim(&edid, EST_1280x1024_75Hz)) - { - EDIDmode.resX = 1280; - EDIDmode.resY = 1024; - EDIDmode.bpp = 0; - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - } - if (edid1_established_tim(&edid, EST_1152x870_75Hz)) - { - EDIDmode.resX = 1152; - EDIDmode.resY = 870; - EDIDmode.bpp = 0; - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - } - if (edid1_established_tim(&edid, EST_1024x768_75Hz) || - edid1_established_tim(&edid, EST_1024x768_70Hz) || - edid1_established_tim(&edid, EST_1024x768_60Hz) || - edid1_established_tim(&edid, EST_1024x768_87Hz)) - { - EDIDmode.resX = 1024; - EDIDmode.resY = 768; - EDIDmode.bpp = 0; - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - } - if (edid1_established_tim(&edid, EST_832x624_75Hz)) - { - EDIDmode.resX = 832; - EDIDmode.resY = 624; - EDIDmode.bpp = 0; - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - } - if (edid1_established_tim(&edid, EST_800x600_60Hz) || - edid1_established_tim(&edid, EST_800x600_56Hz) || - edid1_established_tim(&edid, EST_800x600_75Hz) || - edid1_established_tim(&edid, EST_800x600_72Hz)) - { - EDIDmode.resX = 800; - EDIDmode.resY = 600; - EDIDmode.bpp = 0; - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - } - if (edid1_established_tim(&edid, EST_720x400_88Hz) || - edid1_established_tim(&edid, EST_720x400_70Hz)) - { - EDIDmode.resX = 720; - EDIDmode.resY = 400; - EDIDmode.bpp = 0; - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - } - if (edid1_established_tim(&edid, EST_640x480_75Hz) || - edid1_established_tim(&edid, EST_640x480_72Hz) || - edid1_established_tim(&edid, EST_640x480_67Hz) || - edid1_established_tim(&edid, EST_640x480_60Hz)) - { - EDIDmode.resX = 640; - EDIDmode.resY = 480; - EDIDmode.bpp = 0; - if (find_mode_by_resolution(mode_list, list_length, &EDIDmode) != - -1) - return EDIDmode.mode_number; - } - } - else - printk(FB_VESA_NAME " error reading EDID: unsupported version\n"); - return -1; -} - -void vesa_realmode_bootup_init(void) -{ - uint32_t vbe_ret_val; - uint16_t size; - VBE_vbe_info_block *vib = (VBE_vbe_info_block *) - i386_get_default_rm_buffer(&size); - vbe_ret_val = VBE_controller_information(vib, 0x300); - if (vbe_ret_val == -1) - { - printk(FB_VESA_NAME " error calling real mode interrupt.\n"); - return; - } - if (vbe_ret_val != (VBE_callSuccessful<<8 | VBE_functionSupported)) - { - printk(FB_VESA_NAME " Function 00h (read VBE info block)" - "not supported.\n"); - } -/* Helper array is later filled with mode numbers and their parameters - sorted from the biggest values to the smalest where priorities of - parameters are from the highest to the lowest: resolution X, - resolution Y, bits per pixel. - The array is used for search the monitor provided parameters in EDID - structure and if found we set such mode using corresponding - VESA function. */ -#define MAX_NO_OF_SORTED_MODES 100 - Mode_params sorted_mode_params[MAX_NO_OF_SORTED_MODES]; - - uint16_t *vmpSegOff = (uint16_t *)&vib->VideoModePtr; - uint16_t *modeNOPtr = (uint16_t*) - i386_Real_to_physical(*(vmpSegOff+1), *vmpSegOff); - uint16_t iterator = 0; - - if (*(uint16_t*)vib->VideoModePtr == VBE_STUB_VideoModeList) - { - printk(FB_VESA_NAME " VBE Core not implemented!\n"); - } - else - { - /* prepare list of modes */ - while (*(modeNOPtr+iterator) != VBE_END_OF_VideoModeList && - *(modeNOPtr+iterator) != 0) - { /* some bios implementations ends the list incorrectly with 0 */ - if (iterator < MAX_NO_OF_SORTED_MODES) - { - sorted_mode_params[iterator].mode_number =*(modeNOPtr+iterator); - iterator ++; - } - else - break; - } - if (iterator < MAX_NO_OF_SORTED_MODES) - sorted_mode_params[iterator].mode_number = 0; - } - - VBE_mode_info_block *mib = (VBE_mode_info_block *) - i386_get_default_rm_buffer(&size); - iterator = 0; - uint8_t nextFilteredMode = 0; - uint16_t required_mode_attributes = VBE_modSupInHWMask | - VBE_ColorModeMask | VBE_GraphicsModeMask | VBE_LinFraBufModeAvaiMask; - /* get parameters of modes and filter modes according to set - required parameters */ - while (iterator < MAX_NO_OF_SORTED_MODES && - sorted_mode_params[iterator].mode_number!=0) - { - VBE_mode_information(mib, sorted_mode_params[iterator].mode_number); - if ((mib->ModeAttributes&required_mode_attributes) == - required_mode_attributes) - { - sorted_mode_params[nextFilteredMode].mode_number = - sorted_mode_params[iterator].mode_number; - sorted_mode_params[nextFilteredMode].resX = mib->XResolution; - sorted_mode_params[nextFilteredMode].resY = mib->YResolution; - sorted_mode_params[nextFilteredMode].bpp = mib->BitsPerPixel; - nextFilteredMode ++; - } - iterator ++; - } - sorted_mode_params[nextFilteredMode].mode_number = 0; - - uint8_t number_of_modes = nextFilteredMode; - - /* first search for video argument in multiboot options */ - vbe_used_mode = find_mode_using_cmdline(sorted_mode_params, - number_of_modes); - - if (vbe_used_mode == NO_MODE_REQ) { - vbe_used_mode = find_mode_from_string(sorted_mode_params, - number_of_modes, rtems_fb_default_mode); - if (vbe_used_mode != NO_MODE_REQ) { - printk(FB_VESA_NAME " using application option to select" - " video mode\n"); - } - } - else - { - printk(FB_VESA_NAME " using command line option '--video='" - "to select video mode\n"); - } - - switch (vbe_used_mode) { - case NO_SUITABLE_MODE: - printk(FB_VESA_NAME " requested mode not found\n"); - return; - case BAD_FORMAT: - printk(FB_VESA_NAME " bad format of video requested\n"); - return; - case DONT_INIT: - printk(FB_VESA_NAME " selected not to initialize graphics\n"); - return; - case NO_MODE_REQ: - printk(FB_VESA_NAME " not initialized, no video selected\n"); - return; - } - - /* sort filtered modes */ - Mode_params modeXchgPlace; - iterator = 0; - uint8_t j; - uint8_t idxBestMode; - while (iterator < number_of_modes) - { - idxBestMode = iterator; - j = iterator+1; - while (j < number_of_modes) - { - if (sorted_mode_params[j].resX > - sorted_mode_params[idxBestMode].resX) - idxBestMode = j; - else if (sorted_mode_params[j].resX == - sorted_mode_params[idxBestMode].resX) - { - if (sorted_mode_params[j].resY > - sorted_mode_params[idxBestMode].resY) - idxBestMode = j; - else if (sorted_mode_params[j].resY == - sorted_mode_params[idxBestMode].resY) - { - if (sorted_mode_params[j].bpp > - sorted_mode_params[idxBestMode].bpp) - idxBestMode = j; - } - } - j++; - } - if (idxBestMode != iterator) - { - modeXchgPlace = sorted_mode_params[iterator]; - sorted_mode_params[iterator] = sorted_mode_params[idxBestMode]; - sorted_mode_params[idxBestMode] = modeXchgPlace; - } - iterator++; - } - - if (vbe_used_mode == AUTO_SELECT) - { - printk(FB_VESA_NAME " auto video mode selected" - "\n\ttrying EDID ...\n"); - /* second search monitor for good resolution */ - vbe_used_mode = find_mode_using_EDID(sorted_mode_params, - number_of_modes); - if (vbe_used_mode == -1) - { - printk(FB_VESA_NAME" monitor's EDID video parameters not supported" - "\n\tusing mode with highest resolution, bpp\n"); - /* third set highest values */ - vbe_used_mode = sorted_mode_params[0].mode_number; - } - } - - /* fill framebuffer structs with info about selected mode */ - vbe_ret_val = VBE_mode_information(mib, vbe_used_mode); - if ((vbe_ret_val&0xff)!=VBE_functionSupported || - (vbe_ret_val>>8)!=VBE_callSuccessful) - { - printk(FB_VESA_NAME " Cannot get mode info anymore. ax=0x%lx\n", - vbe_ret_val); - } - - fb_var.xres = mib->XResolution; - fb_var.yres = mib->YResolution; - fb_var.bits_per_pixel = mib->BitsPerPixel; - fb_var.red.offset = mib->LinRedFieldPosition; - fb_var.red.length = mib->LinRedMaskSize; - fb_var.red.msb_right = 0; - fb_var.green.offset = mib->LinGreenFieldPosition; - fb_var.green.length = mib->LinGreenMaskSize; - fb_var.green.msb_right = 0; - fb_var.blue.offset = mib->LinBlueFieldPosition; - fb_var.blue.length = mib->LinBlueMaskSize; - fb_var.blue.msb_right = 0; - fb_var.transp.offset = mib->LinRsvdFieldPosition; - fb_var.transp.length = mib->LinRsvdMaskSize; - fb_var.transp.msb_right =0; - - fb_fix.smem_start = (char *)mib->PhysBasePtr; - fb_fix.line_length = mib->LinBytesPerScanLine; - fb_fix.smem_len = fb_fix.line_length*fb_var.yres; - fb_fix.type = FB_TYPE_PACKED_PIXELS; - if (fb_var.bits_per_pixel < 24) - fb_fix.visual = FB_VISUAL_DIRECTCOLOR; - else - fb_fix.visual = FB_VISUAL_TRUECOLOR; - - /* set selected mode */ - vbe_ret_val = VBE_set_mode(vbe_used_mode | VBE_linearFlatFrameBufMask, - (VBE_CRTC_info_block *)(i386_get_default_rm_buffer(&size))); - if (vbe_ret_val>>8 == VBE_callFailed) - printk(FB_VESA_NAME " VBE: Requested mode is not available."); - - if ((vbe_ret_val&0xff)!= (VBE_functionSupported | VBE_callSuccessful<<8)) - printk(FB_VESA_NAME " Call to function 2h (set VBE mode) failed. " - "ax=0x%" PRIx32 "\n", vbe_ret_val); - - vib = (void *) 0; - mib = (void *) 0; -} - -/* - * fb_vesa device driver INITIALIZE entry point. - */ -rtems_device_driver -frame_buffer_initialize( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code status; - - printk(FB_VESA_NAME " frame buffer -- driver initializing..\n" ); - - /* - * Register the device. - */ - status = rtems_io_register_name(FRAMEBUFFER_DEVICE_0_NAME, major, 0); - if (status != RTEMS_SUCCESSFUL) - { - printk("Error registering " FRAMEBUFFER_DEVICE_0_NAME - " - " FB_VESA_NAME " frame buffer device!\n"); - rtems_fatal_error_occurred( status ); - } - - _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); - - return RTEMS_SUCCESSFUL; -} - -/* - * fb_vesa device driver OPEN entry point - */ -rtems_device_driver -frame_buffer_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - printk( FB_VESA_NAME " open device\n" ); - - if (_Atomic_Flag_test_and_set(&driver_mutex, ATOMIC_ORDER_ACQUIRE) != 0 ) - { - printk( FB_VESA_NAME " could not lock vesa_mutex\n" ); - - return RTEMS_UNSATISFIED; - } - - return RTEMS_SUCCESSFUL; - -} - -/* - * fb_vesa device driver CLOSE entry point - */ -rtems_device_driver -frame_buffer_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - printk( FB_VESA_NAME " close device\n" ); - _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); - /* restore previous state. for VGA this means return to text mode. - * leave out if graphics hardware has been initialized in - * frame_buffer_initialize() */ - - printk(FB_VESA_NAME ": close called.\n" ); - return RTEMS_SUCCESSFUL; -} - -/* - * fb_vesa device driver READ entry point. - */ -rtems_device_driver -frame_buffer_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - printk( FB_VESA_NAME " read device\n" ); - rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; - rw_args->bytes_moved = - ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? - (fb_fix.smem_len - rw_args->offset) : - rw_args->count; - memcpy(rw_args->buffer, (const void *) - (fb_fix.smem_start + rw_args->offset), rw_args->bytes_moved); - return RTEMS_SUCCESSFUL; -} - -/* - * frame_vesa device driver WRITE entry point. - */ -rtems_device_driver -frame_buffer_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - printk( FB_VESA_NAME " write device\n" ); - rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; - rw_args->bytes_moved = - ((rw_args->offset + rw_args->count) > fb_fix.smem_len ) ? - (fb_fix.smem_len - rw_args->offset) : - rw_args->count; - memcpy( (void *) (fb_fix.smem_start + rw_args->offset), - rw_args->buffer, rw_args->bytes_moved); - return RTEMS_SUCCESSFUL; -} - -static int get_fix_screen_info( struct fb_fix_screeninfo *info ) -{ - *info = fb_fix; - return 0; -} - -static int get_var_screen_info( struct fb_var_screeninfo *info ) -{ - *info = fb_var; - return 0; -} - -/* - * IOCTL entry point -- This method is called to carry - * all services of this interface. - */ -rtems_device_driver -frame_buffer_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_ioctl_args_t *args = arg; - - printk( FB_VESA_NAME " ioctl called, cmd=%" PRIx32 "\n", args->command ); - printk("fbxres %lu, fbyres %lu\n", fb_var.xres, fb_var.yres); - printk("fbbpp %lu\n", fb_var.bits_per_pixel); - - switch (args->command) - { - case FBIOGET_FSCREENINFO: - args->ioctl_return = - get_fix_screen_info( ( struct fb_fix_screeninfo * ) args->buffer ); - break; - case FBIOGET_VSCREENINFO: - args->ioctl_return = - get_var_screen_info( ( struct fb_var_screeninfo * ) args->buffer ); - break; - case FBIOPUT_VSCREENINFO: - /* not implemented yet */ - args->ioctl_return = -1; - return RTEMS_UNSATISFIED; - case FBIOGETCMAP: - /* no palette - truecolor mode */ - args->ioctl_return = -1; - return RTEMS_UNSATISFIED; - case FBIOPUTCMAP: - /* no palette - truecolor mode */ - args->ioctl_return = -1; - return RTEMS_UNSATISFIED; - default: - args->ioctl_return = 0; - break; - } - return RTEMS_SUCCESSFUL; -} |