[syslinux:firmware] efi, vesa: Fix vesa initialization and video mode resolution

syslinux-bot for Chandramouli Narayanan chandramouli.narayanan at intel.com
Fri Nov 9 09:06:28 PST 2012


Commit-ID:  97402a0a16399ab0c396583cf1c7d16c05ac6753
Gitweb:     http://www.syslinux.org/commit/97402a0a16399ab0c396583cf1c7d16c05ac6753
Author:     Chandramouli Narayanan <chandramouli.narayanan at intel.com>
AuthorDate: Thu, 6 Sep 2012 07:55:11 +0100
Committer:  Matt Fleming <matt.fleming at intel.com>
CommitDate: Thu, 6 Sep 2012 07:55:11 +0100

efi, vesa: Fix vesa initialization and video mode resolution

Fixed undefined symbol dprintf for production build. Now dprintf.h is
included so that both debug and production builds are ok.

Fixed the initialization of mode_info structure to point to a valid
GOP mode structure prior to printing it.

Fixed the case when the requested video mode resolution is unsupported
on a platform.  Essentially, VESA initialization is passed a desirable
video resolution. The underlying platform may either grant it or
return a system supported default value.  This fix is necessitated by
EFI-enabled platforms. Appropriate changes to callers of the vesa
initialization and the BIOS centric code are made as well.

Signed-off-by: Chandramouli Narayanan <chandramouli.narayanan at intel.com>
Signed-off-by: Matt Fleming <matt.fleming at intel.com>

---
 com32/lib/sys/vesa/efi/initvesa.c |   34 ++++++++++++++++++++++++----------
 com32/lib/sys/vesa/efi/video.h    |    3 ++-
 com32/lib/sys/vesacon_write.c     |    3 ++-
 3 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/com32/lib/sys/vesa/efi/initvesa.c b/com32/lib/sys/vesa/efi/initvesa.c
index 44278d5..2144f14 100644
--- a/com32/lib/sys/vesa/efi/initvesa.c
+++ b/com32/lib/sys/vesa/efi/initvesa.c
@@ -39,6 +39,7 @@
 #include <string.h>
 #include <sys/fpu.h>
 #include <syslinux/video.h>
+#include <dprintf.h>
 #ifdef SYSLINUX_EFI
 #include <efi.h>
 #include <efilib.h>
@@ -101,7 +102,7 @@ static int vesacon_paged_mode_ok(const struct vesa_mode_info *mi)
 }
 
 #ifndef SYSLINUX_EFI
-static int vesacon_set_mode(int x, int y)
+static int vesacon_set_mode(int *x, int *y)
 {
     com32sys_t rm;
     uint8_t *rom_font;
@@ -196,7 +197,7 @@ static int vesacon_set_mode(int x, int y)
 	    continue;
 
 	/* Must be the chosen size */
-	if (mi->h_res != x || mi->v_res != y)
+	if (mi->h_res != *x || mi->v_res != *y)
 	    continue;
 
 	/* We don't support multibank (interlaced memory) modes */
@@ -338,7 +339,7 @@ static void find_pixmask_bits(uint32_t mask, uint8_t *first_bit, uint8_t *len) {
     *first_bit = bit_pos;
     *len = bit_len;
 }
-static int vesacon_set_mode(int x, int y)
+static int vesacon_set_mode(int *x, int *y)
 {
     EFI_GUID GraphicsOutputProtocolGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
     EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput = NULL;
@@ -365,6 +366,7 @@ static int vesacon_set_mode(int x, int y)
     /* We use the VESA info structure to store relevant GOP info as much as possible */
     gop_mode = GraphicsOutput->Mode;
 
+    mode_info = gop_mode->Info;
     dprintf("mode %d version %d pixlfmt %d hres=%d vres=%d\n", mode_num, 
 			mode_info->Version, mode_info->PixelFormat,
 			mode_info->HorizontalResolution, mode_info->VerticalResolution);
@@ -378,7 +380,7 @@ static int vesacon_set_mode(int x, int y)
 		/* For now, simply pick the best mode that suits caller's resolution (x,y)
 		 * FIXME: Consider any additional criteria for matching mode
 		 */
-		mode_match = ((uint32_t)x == mode_info->HorizontalResolution && (uint32_t)y == mode_info->VerticalResolution);
+		mode_match = ((uint32_t)*x == mode_info->HorizontalResolution && (uint32_t)*y == mode_info->VerticalResolution);
 		debug("mode %d hres=%d vres=%d\n", mode_num, mode_info->HorizontalResolution, mode_info->VerticalResolution);
 		if (mode_match) {
 			bestmode = mode_num;
@@ -388,8 +390,15 @@ static int vesacon_set_mode(int x, int y)
     }
 
     if (!mode_match) {
-	debug("No matching mode available for resolution (x=%d, y=%d)\n", x, y);
-	return 4; /* no mode found */
+	/* Instead of bailing out, set the mode to the system default.
+ 	 * Some systems do not have support for 640x480 for instance
+ 	 * This code deals with such cases.
+ 	 */
+	mode_info = gop_mode->Info;
+	*x = mode_info->HorizontalResolution;
+	*y = mode_info->VerticalResolution;
+	bestmode = gop_mode->Mode;
+	debug("No matching mode, setting to available default mode %d (x=%d, y=%d)\n", bestmode, *x, *y);
     }
 
     /* Allocate space in the bounce buffer for these structures */
@@ -402,8 +411,8 @@ static int vesacon_set_mode(int x, int y)
     gi = &vi->gi;
     mi = &vi->mi;
     /* Set up mode-specific information */
-    mi->h_res = x;
-    mi->v_res = y;
+    mi->h_res = *x;
+    mi->v_res = *y;
     mi->lfb_ptr = (uint8_t *)(VOID *)(UINTN)gop_mode->FrameBufferBase;
     mi->lfb_size = gop_mode->FrameBufferSize;
 
@@ -601,7 +610,12 @@ static int init_text_display(void)
     return 0;
 }
 
-int __vesacon_init(int x, int y)
+/* On input, VESA initialization is passed a desirable resolution
+ * On return, either the requested resolution is set or the system
+ * supported default resolution is set and returned to the caller
+ * This change is added for EFI enabled platforms.
+ */
+int __vesacon_init(int *x, int *y)
 {
     int rv;
 
@@ -614,7 +628,7 @@ int __vesacon_init(int x, int y)
 #ifndef SYSLINUX_EFI
     if (rv) {
 	/* Try to see if we can just patch the BIOS... */
-	if (__vesacon_i915resolution(x, y))
+	if (__vesacon_i915resolution(*x, *y))
 	    return rv;
 	if (vesacon_set_mode(x, y))
 	    return rv;
diff --git a/com32/lib/sys/vesa/efi/video.h b/com32/lib/sys/vesa/efi/video.h
index d14494b..bc24af6 100644
--- a/com32/lib/sys/vesa/efi/video.h
+++ b/com32/lib/sys/vesa/efi/video.h
@@ -81,7 +81,8 @@ extern const uint8_t __vesacon_linear_to_srgb[4080];
 
 int __vesacon_init_background(void);
 int vesacon_load_background(const char *);
-int __vesacon_init(int, int);
+/* Prototype changes to deal with video mode resolution changes */
+int __vesacon_init(int *, int *);
 void __vesacon_init_cursor(int);
 void __vesacon_erase(int, int, int, int, attr_t);
 void __vesacon_scroll_up(int, attr_t);
diff --git a/com32/lib/sys/vesacon_write.c b/com32/lib/sys/vesacon_write.c
index c683c60..88f8348 100644
--- a/com32/lib/sys/vesacon_write.c
+++ b/com32/lib/sys/vesacon_write.c
@@ -102,7 +102,8 @@ int __vesacon_open(struct file_info *fp)
 	    ti.cols = 80;
 	} else {
 	    /* Switch mode */
-	    if (__vesacon_init(vesacon_resolution.x, vesacon_resolution.y)) {
+	    /* Deal with a resolution different from default build */
+	    if (__vesacon_init(&vesacon_resolution.x, &vesacon_resolution.y)) {
 		vesacon_counter = -1;
 		return EAGAIN;
 	    }


More information about the Syslinux-commits mailing list