[PATCH 1/2] i386/pc386/VESA framebuffer driver: modified and extended initialization options
Jan Dolezal
dolezj21 at fel.cvut.cz
Tue May 19 14:34:57 UTC 2015
driver is not initialized by default
initialization is possible through multiboot command line option or
through string variable set in user's module allowing the driver
to evaluate this variable after the two modules are linked together
---
c/src/lib/libbsp/i386/pc386/console/fb_vesa_rm.c | 152 +++++++++++++++++++----
1 file changed, 127 insertions(+), 25 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
index d6fd174..5c4d8bf 100644
--- a/c/src/lib/libbsp/i386/pc386/console/fb_vesa_rm.c
+++ b/c/src/lib/libbsp/i386/pc386/console/fb_vesa_rm.c
@@ -19,8 +19,14 @@
*
* Driver reads parameter from multiboot command line to setup video:
* "--video=<resX>x<resY>[-<bpp>]"
- * If cmdline parameter is not specified an attempt for obtaining
- * resolution from display attached is made.
+ * "--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_console_vbe_default
+ * variable content is tested (see doc below).
+ * Command line option has higher priority. rtems_console_vbe_default is probed
+ * only if cmdline "--video=" is not specified at all.
+ *
+ * If neither of the above options is specified the driver is not initialized.
*/
/*
@@ -31,7 +37,7 @@
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
- * The code for rtems_buffer_* functions were greatly
+ * The code for rtems_buffer_* functions was greatly
* inspired or coppied from:
* - RTEMS fb_cirrus.c - Alexandru-Sever Horin (alex.sever.h at gmail.com)
*/
@@ -53,6 +59,22 @@
#define FB_VESA_NAME "FB_VESA_RM"
/**
+ * @brief Allows to enable initialization of this 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 if the value points to string in format:
+ * "<resX>x<resY>[-<bpp>]"
+ * "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 option string has priority over this string.
+ */
+const char * const rtems_console_vbe_default;
+
+/**
* @brief Initializes VBE framebuffer during bootup.
*
* utilizes switches to real mode interrupts and therefore must be
@@ -212,6 +234,14 @@ typedef struct {
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
*
@@ -249,37 +279,48 @@ static uint16_t find_mode_by_resolution(Mode_params *mode_list,
}
i++;
}
- return -1;
+ return NO_SUITABLE_MODE;
}
/**
- * @brief Find mode given within command line.
+ * @brief Find mode given in string format.
*
- * Parse command line option "--video=" if available.
* expected format
- * --video=<resX>x<resY>[-<bpp>]
+ * <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 on parsing error or when no suitable mode found
+ * @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 uint16_t find_mode_using_cmdline(Mode_params *mode_list,
- uint8_t list_length)
+static uint16_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 = 0;
- opt = bsp_cmdline_arg("--video=");
+ cmdline_mode.bpp = 16; /* default bpp */
+ opt = video_string;
if (opt)
{
- opt += sizeof("--video=")-1;
+ 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 -1;
+ return BAD_FORMAT;
}
opt = endptr+1;
cmdline_mode.resY = strtol(opt, &endptr, 10);
@@ -294,21 +335,50 @@ static uint16_t find_mode_using_cmdline(Mode_params *mode_list,
cmdline_mode.bpp = strtol(opt, &endptr, 10);
if (*endptr != ' ')
{
- return -1;
+ return BAD_FORMAT;
}
}
case ' ':
case 0:
break;
default:
- return -1;
+ return BAD_FORMAT;
}
- if (find_mode_by_resolution(mode_list, list_length, &cmdline_mode) !=
- (uint16_t)-1)
- return cmdline_mode.mode_number;
+ return find_mode_by_resolution(mode_list, list_length, &cmdline_mode);
}
- return -1;
+ 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 uint16_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;
}
/**
@@ -569,6 +639,7 @@ void vesa_realmode_bootup_init(void)
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");
@@ -618,6 +689,40 @@ void vesa_realmode_bootup_init(void)
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 == (uint16_t) NO_MODE_REQ) {
+ vbe_used_mode = find_mode_from_string(sorted_mode_params,
+ number_of_modes, rtems_console_vbe_default);
+ if (vbe_used_mode != (uint16_t) 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 (uint16_t) NO_SUITABLE_MODE:
+ printk(FB_VESA_NAME " requested mode not found\n");
+ return;
+ case (uint16_t) BAD_FORMAT:
+ printk(FB_VESA_NAME " bad format of video requested\n");
+ return;
+ case (uint16_t) DONT_INIT:
+ printk(FB_VESA_NAME " selected not to initialize graphics\n");
+ return;
+ case (uint16_t) NO_MODE_REQ:
+ printk(FB_VESA_NAME " not initialized, no video selected\n");
+ return;
+ }
+
/* sort filtered modes */
Mode_params modeXchgPlace;
iterator = 0;
@@ -657,12 +762,9 @@ void vesa_realmode_bootup_init(void)
iterator++;
}
- /* 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 == (uint16_t)-1)
+ if (vbe_used_mode == (uint16_t)AUTO_SELECT)
{
- printk(FB_VESA_NAME " video on command line not provided"
+ 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,
--
1.9.1
More information about the devel
mailing list