[grub/f17] Sigh.

Matthew Garrett mjg59 at fedoraproject.org
Fri Apr 27 15:38:19 UTC 2012


commit 49e10f5e71ed9428effeb67db1bad4d75b6bde20
Author: Matthew Garrett <mjg at redhat.com>
Date:   Fri Apr 27 11:38:11 2012 -0400

    Sigh.

 0008-fix-gop.patch |  474 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 469 insertions(+), 5 deletions(-)
---
diff --git a/0008-fix-gop.patch b/0008-fix-gop.patch
index 2cffead..9e58fb8 100644
--- a/0008-fix-gop.patch
+++ b/0008-fix-gop.patch
@@ -1,12 +1,476 @@
-From eeb9127a6642caebb7759b8510d24208d23346c9 Mon Sep 17 00:00:00 2001
+From 412155e73f6945b615c3de87fb6162a2e14a59db Mon Sep 17 00:00:00 2001
 From: Matthew Garrett <mjg at redhat.com>
-Date: Fri, 27 Apr 2012 11:28:44 -0400
-Subject: [PATCH] Fix i386 build
+Date: Thu, 26 Apr 2012 17:38:54 -0400
+Subject: [PATCH] Simplify GOP setup
 
+We're adding a lot of complexity to the graphics setup, and all we're
+getting out of it is a broken display on some hardware. Just use the mode
+the firmware gave us and we'll let the kernel pick a better one later.
 ---
- efi/grub/i386/linux.h |    3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
+ efi/efigraph.c        |  319 +++----------------------------------------------
+ efi/grub/efi/api.h    |    5 +
+ efi/grub/i386/linux.h |    3 +-
+ 3 files changed, 21 insertions(+), 306 deletions(-)
 
+diff --git a/efi/efigraph.c b/efi/efigraph.c
+index 9fbfdfd..399c190 100644
+--- a/efi/efigraph.c
++++ b/efi/efigraph.c
+@@ -74,6 +74,7 @@ typedef struct grub_pixel_info grub_pixel_info_t;
+ 
+ static grub_efi_guid_t graphics_output_guid = GRUB_EFI_GRAPHICS_OUTPUT_GUID;
+ static grub_efi_guid_t pci_io_guid = GRUB_EFI_PCI_IO_GUID;
++static grub_efi_guid_t edid_guid = GRUB_EFI_EDID_DISCOVERED_GUID;
+ 
+ #ifndef MIN
+ #define MIN(x,y) ( ((x) < (y)) ? (x) : (y))
+@@ -178,39 +179,6 @@ get_graphics_mode_info(struct eg *eg)
+ }
+ 
+ static void
+-print_mode_info(struct video_mode *mode)
+-{
+-	grub_efi_graphics_output_mode_information_t *info = mode->info;
+-	dprintf("mode %d (%dx%d, pitch %d, ",
+-		mode->number,
+-		info->horizontal_resolution,
+-		info->vertical_resolution,
+-		info->pixels_per_scan_line);
+-	switch(info->pixel_format) {
+-		case GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR:
+-			dprintf("rgbr 8bpc");
+-			break;
+-		case GRUB_EFI_PIXEL_BGRR_8BIT_PER_COLOR:
+-			dprintf("bgrr 8bpc");
+-			break;
+-		case GRUB_EFI_PIXEL_BIT_MASK:
+-			dprintf("bitmask color");
+-			break;
+-		case GRUB_EFI_PIXEL_BLT_ONLY:
+-			dprintf("blt only");
+-			break;
+-	}
+-	dprintf(")\n");
+-	if (info->pixel_format == GRUB_EFI_PIXEL_BIT_MASK) {
+-		dprintf("red: %08x green: %08x blue: %08x res: %08x\n",
+-		info->pixel_information.red_mask,
+-		info->pixel_information.green_mask,
+-		info->pixel_information.blue_mask,
+-		info->pixel_information.reserved_mask);
+-	}
+-}
+-
+-static void
+ set_kernel_params(struct graphics_backend *backend,
+             struct linux_kernel_params *params)
+ {
+@@ -247,6 +215,7 @@ set_kernel_params(struct graphics_backend *backend,
+         params->vesapm_segment = 0;
+         params->vesapm_offset = 0;
+         params->vesa_attrib = 0;
++	params->capabilities = 1;
+         if (gop_info->pixel_format == GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR) {
+             params->lfb_depth = 32;
+             params->red_mask_size = 8;
+@@ -322,15 +291,6 @@ set_kernel_params(struct graphics_backend *backend,
+ }
+ 
+ static void
+-pixel_to_rgb(grub_efi_graphics_output_pixel_t *pixel,
+-             int *red, int *green, int *blue)
+-{
+-    *red = pixel->bgrr.red;
+-    *green = pixel->bgrr.green;
+-    *blue = pixel->bgrr.blue;
+-}
+-
+-static void
+ rgb_to_pixel(int red, int green, int blue,
+              grub_efi_graphics_output_pixel_t *pixel)
+ {
+@@ -346,14 +306,6 @@ position_to_phys(struct eg *eg, position_t *virt, position_t *phys)
+     phys->y = virt->y + eg->screen_pos.y;
+ }
+ 
+-static int
+-abs_paddr(struct eg *eg, position_t *virt)
+-{
+-    position_t phys;
+-    position_to_phys(eg, virt, &phys);
+-    return phys.x + phys.y * eg->screen_size.x;
+-}
+-
+ struct bltbuf {
+     grub_efi_uintn_t width;
+     grub_efi_uintn_t height;
+@@ -554,18 +506,6 @@ blt_to_screen_pos(struct eg *eg, struct bltbuf *bltbuf, position_t *pos)
+     blt_pos_to_screen_pos(eg, bltbuf, &bltpos, &bltsz, pos);
+ }
+ 
+-static int
+-save_video_mode(struct eg *eg, struct video_mode *mode)
+-{
+-	grub_efi_status_t status;
+-
+-
+-
+-	status = Call_Service_4(eg->output_intf->query_mode, eg->output_intf,
+-                                mode->number, &mode->size, &mode->info);
+-	return status == GRUB_EFI_SUCCESS;
+-}
+-
+ static void
+ get_screen_size(struct graphics_backend *backend, position_t *size)
+ {
+@@ -591,20 +531,6 @@ bltbuf_set_pixel(struct bltbuf *bltbuf, position_t *pos,
+ }
+ 
+ static void
+-bltbuf_get_pixel(struct bltbuf *bltbuf, position_t *pos,
+-                 grub_efi_graphics_output_pixel_t *pixel)
+-{
+-    if (bltbuf && pos->x < bltbuf->width && pos->y < bltbuf->height) {
+-    	grub_memmove(pixel, &bltbuf->pixbuf[pos->x + pos->y * bltbuf->width],
+-            sizeof *pixel);
+-    } else {
+-	pixel->bgrr.red = 0x00;
+-	pixel->bgrr.green = 0x00;
+-	pixel->bgrr.blue = 0x00;
+-    }
+-}
+-
+-static void
+ bltbuf_set_pixel_rgb(struct bltbuf *bltbuf, position_t *pos,
+                      int red, int green, int blue)
+ {
+@@ -620,19 +546,6 @@ bltbuf_set_pixel_idx(struct eg *eg, struct bltbuf *bltbuf,
+     bltbuf_set_pixel(bltbuf, pos, &eg->palette[idx]);
+ }
+ 
+-static void
+-bltbuf_get_pixel_idx(struct bltbuf *bltbuf, position_t *pos, int *idx)
+-{
+-    grub_efi_graphics_output_pixel_t pixel;
+-
+-    rgb_to_pixel(0, 0, 0, &pixel);
+-    bltbuf_get_pixel(bltbuf, pos, &pixel);
+-    for (*idx = 0; *idx < 16; (*idx)++) {
+-        if (pixel_equal(cga_colors[*idx], pixel))
+-            break;
+-    }
+-}
+-
+ static struct bltbuf *
+ xpm_to_bltbuf(struct xpm *xpm)
+ {
+@@ -820,31 +733,6 @@ blank(struct graphics_backend *backend)
+     grub_free(bltbuf);
+ }
+ 
+-
+-static void
+-draw_white_box(struct graphics_backend *backend)
+-{
+-    struct eg *eg = backend->priv;
+-    struct bltbuf *bltbuf;
+-    position_t pos = {0, 0}, bltpos = {0, 0}, bltsz = {100,100};
+-
+-    bltbuf = alloc_bltbuf(bltsz.x, bltsz.y);
+-    for (pos.y = 0; pos.y < bltsz.y; pos.y++) {
+-        for (pos.x = 0; pos.x < bltsz.x; pos.x++) {
+-            bltbuf_set_pixel_rgb(bltbuf, &pos, 0xff, 0xff, 0xff);
+-        }
+-    }
+-
+-    blt_pos_to_screen_pos(eg, bltbuf, &bltpos, &bltsz, &pos);
+-
+-#if 0
+-    Call_Service_10(eg->output_intf->blt, eg->output_intf, bltbuf->pixbuf,
+-        GRUB_EFI_BLT_BUFFER_TO_VIDEO, 0, 0, 100, 100, x, y, 0);
+-#endif
+-
+-    grub_free(bltbuf);
+-}
+-
+ static void
+ bltbuf_cp_bl(struct bltbuf *d, position_t dpos,
+              struct bltbuf *s, position_t spos)
+@@ -890,18 +778,6 @@ bltbuf_draw_bg(struct graphics_backend *backend, struct bltbuf *bltbuf,
+     bltbuf_cp_bl(bltbuf, blpos, eg->background, bgpos);
+ }
+ 
+-static void
+-dbg_dump_palette(struct graphics_backend *backend)
+-{
+-    struct eg *eg;
+-    int i;
+-    if (!backend || !backend->priv)
+-        return;
+-    eg = backend->priv;
+-    if (!eg->palette)
+-        return;
+-}
+-
+ static int
+ is_shadow_pixel(position_t screensz, position_t textpos, position_t bitpos,
+                 position_t fontsz)
+@@ -1157,130 +1033,11 @@ fill_pixel_info (grub_pixel_info_t *pixel_info,
+   return 1;
+ }
+ 
+-/* 1 = prefer a
+- * 0 = prefer neither
+- * -1 = prefer b
+- */
+-static int
+-modecmp_helper(struct eg *eg, struct video_mode *amode, struct video_mode *bmode)
+-{
+-        grub_efi_graphics_output_mode_information_t *a = amode->info;
+-        grub_efi_graphics_output_mode_information_t *b = bmode->info;
+-
+-        if (a != NULL && b == NULL)
+-                return 1;
+-        if (a == NULL && b == NULL)
+-                return 0;
+-        if (a == NULL && b != NULL)
+-                return -1;
+-
+-#if 0
+-	if (amode->number == eg->graphics_mode && bmode->number != eg->graphics_mode)
+-		return 1;
+-	if (amode->number == eg->graphics_mode && bmode->number == eg->graphics_mode)
+-		return 0;
+-	if (amode->number != eg->graphics_mode && bmode->number == eg->graphics_mode)
+-		return -1;
+-#endif
+-
+-
+-	/* kernel doesn't deal with blt only modes, so prefer against them. */
+-        if (a->pixel_format != GRUB_EFI_PIXEL_BLT_ONLY &&
+-                        b->pixel_format == GRUB_EFI_PIXEL_BLT_ONLY)
+-                return 1;
+-        if (b->pixel_format != GRUB_EFI_PIXEL_BLT_ONLY &&
+-                        a->pixel_format == GRUB_EFI_PIXEL_BLT_ONLY)
+-                return -1;
+-
+-	/* XXX PJFIX there's something wrong with what we're passing to the
+-	 * kernel for stride in the bgrr/rgbr modes, and I haven't figured out
+-	 * just what yet, so for now, prefer bitmask modes.
+-	 */
+-	if (a->pixel_format == GRUB_EFI_PIXEL_BIT_MASK &&
+-			b->pixel_format != GRUB_EFI_PIXEL_BIT_MASK)
+-		return 1;
+-	if (a->pixel_format != GRUB_EFI_PIXEL_BIT_MASK &&
+-			b->pixel_format == GRUB_EFI_PIXEL_BIT_MASK)
+-		return -1;
+-
+-        if (a->pixel_format == GRUB_EFI_PIXEL_BGRR_8BIT_PER_COLOR &&
+-			b->pixel_format != GRUB_EFI_PIXEL_BGRR_8BIT_PER_COLOR)
+-		return 1;
+-        if (a->pixel_format != GRUB_EFI_PIXEL_BGRR_8BIT_PER_COLOR &&
+-			b->pixel_format == GRUB_EFI_PIXEL_BGRR_8BIT_PER_COLOR)
+-		return -1;
+-
+-        if (a->pixel_format == GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR &&
+-			b->pixel_format != GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR)
+-		return 1;
+-        if (a->pixel_format != GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR &&
+-			b->pixel_format == GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR)
+-		return -1;
+-
+-        if (a->horizontal_resolution > b->horizontal_resolution &&
+-                        a->vertical_resolution > b->vertical_resolution)
+-                return 1;
+-        if (a->horizontal_resolution < b->horizontal_resolution &&
+-                        a->vertical_resolution < b->vertical_resolution)
+-                return -1;
+-        return 0;
+-}
+-
+-static int
+-modecmp(struct eg *eg, struct video_mode *amode, struct video_mode *bmode)
+-{
+-        int rc;
+-#if 0
+-        grub_efi_graphics_output_mode_information_t *a = amode->info;
+-        grub_efi_graphics_output_mode_information_t *b = bmode->info;
+-#endif
+-        rc = modecmp_helper(eg, amode, bmode);
+-#if 0
+-        grub_printf("comparing nodes:\n");
+-        print_mode_info(amode);
+-        print_mode_info(bmode);
+-        if (rc > 0)
+-                grub_printf("result: a > b\n");
+-        else if (rc < 0)
+-                grub_printf("result: a < b\n");
+-        else
+-                grub_printf("result: a == b\n");
+-
+-        //dbgdelay(__FILE__, __LINE__);
+-#endif
+-        return rc;
+-}
+-
+-static void
+-modeswap(struct video_mode *amode, struct video_mode *bmode)
+-{
+-        struct video_mode tmp;
+-
+-        memcpy(&tmp, amode, sizeof (tmp));
+-        memcpy(amode, bmode, sizeof (tmp));
+-        memcpy(bmode, &tmp, sizeof(tmp));
+-}
+-
+-static void
+-sort_modes(struct eg *eg, int p, int r)
+-{
+-	struct video_mode **modes = eg->modes;
+-
+-        int i, j;
+-	for (i = 0; i < eg->max_mode; i++) {
+-		for (j = i + 1; j < eg->max_mode; j++) {
+-			if (modecmp(eg, modes[j], modes[i]) < 0)
+-				modeswap(modes[j], modes[i]);
+-		}
+-	}
+-}
+-
+ static int
+ try_enable(struct graphics_backend *backend)
+ {
+     struct eg *eg = backend->priv;
+     grub_efi_status_t efi_status = GRUB_EFI_UNSUPPORTED;
+-    int i;
+ 
+     if (eg->text_mode == 0xffffffff) {
+         grub_efi_set_text_mode(1);
+@@ -1288,7 +1045,6 @@ try_enable(struct graphics_backend *backend)
+     }
+ 
+     if (eg->graphics_mode == 0xffffffff) {
+-        grub_efi_graphics_output_mode_information_t *info;
+ 
+         if (!graphics_alloc_text_buf())
+             return 0;
+@@ -1296,66 +1052,14 @@ try_enable(struct graphics_backend *backend)
+         grub_efi_set_text_mode(0);
+         eg->graphics_mode = eg->output_intf->mode->mode;
+         grub_efi_set_text_mode(1);
+-#if 0
+-	dprintf("graphics mode is %d\n", eg->graphics_mode);
+-	/* this is okay here because we haven't sorted yet.*/
+-	print_mode_info(eg->modes[eg->graphics_mode]);
+-	dprintf("text mode is %d\n", eg->text_mode);
+-	print_mode_info(eg->modes[eg->text_mode]);
+-#endif
+-
+-        sort_modes(eg, 0, eg->max_mode-1);
+-
+-#if 0
+-        for (i = eg->max_mode - 1; i >= 0; i--)
+-            print_mode_info(eg->modes[i]);
+-	dbgdelay(__FILE__, __LINE__);
+-#endif
+ 
+-	efi_status = GRUB_EFI_UNSUPPORTED;
++	efi_status = set_video_mode(eg, eg->graphics_mode);
+ 
+-        for (i = eg->max_mode - 1; i >= 0; i--) {
+-            if (!eg->modes[i])
+-                continue;
++	if (efi_status != GRUB_EFI_SUCCESS)
++	  return 0;
+ 
+-            info = eg->modes[i]->info;
+-
+-#if 0
+-            if (info->pixel_format != GRUB_EFI_PIXEL_RGBR_8BIT_PER_COLOR &&
+-                 info->pixel_format != GRUB_EFI_PIXEL_BGRR_8BIT_PER_COLOR &&
+-                 info->pixel_format != GRUB_EFI_PIXEL_BIT_MASK) {
+-                continue;
+-            }
+-#endif
+-
+-            grub_efi_set_text_mode(0);
+-            efi_status = set_video_mode(eg, eg->modes[i]->number);
+-            if (efi_status == GRUB_EFI_SUCCESS) {
+-#if 0
+-                grub_efi_set_text_mode(1);
+-	        dprintf("switched to mode %d successfully\n",
+-		        eg->modes[i]->number);
+-	        dbgdelay(__FILE__,__LINE__);
+-                grub_efi_set_text_mode(0);
+-#endif
+-                eg->graphics_mode = eg->modes[i]->number;
+-	        fill_pixel_info(&eg->pixel_info, info);
+-                break;
+-            } else {
+-#if 0
+-                set_video_mode(eg, eg->text_mode);
+-                grub_efi_set_text_mode(1);
+-		dprintf("return code was %d\n", efi_status);
+-#endif
+-            }
+-        }
+-        if (efi_status != GRUB_EFI_SUCCESS) {
+-#if 1
+-            grub_efi_set_text_mode(1);
+-            set_video_mode(eg, eg->text_mode);
+-#endif
+-            return 0;
+-        }
++	fill_pixel_info(&eg->pixel_info, eg->modes[eg->graphics_mode]->info);
++	grub_efi_set_text_mode(0);
+ 
+     }
+ 
+@@ -1378,6 +1082,7 @@ enable(struct graphics_backend *backend)
+ 	grub_efi_handle_t *handle, *handles;
+ 	grub_efi_uintn_t num_handles;
+ 	grub_efi_pci_io_t *pci_proto;
++	void *edid;
+ 
+         if (!(eg = grub_malloc(sizeof (*eg))))
+             return 0;
+@@ -1399,7 +1104,10 @@ enable(struct graphics_backend *backend)
+ 	    pci_proto = grub_efi_open_protocol (*handle, &pci_io_guid,
+ 					 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ 
+-	    if (!pci_proto)
++	    edid = grub_efi_open_protocol (*handle, &edid_guid,
++					 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
++
++	    if (!pci_proto && !edid)
+ 	      continue;
+ 
+ 	    eg->output_intf = grub_efi_open_protocol (*handle,
+@@ -1407,7 +1115,8 @@ enable(struct graphics_backend *backend)
+ 
+ 	    if (eg->output_intf)
+ 	      {
+-		grub_efi_setup_gfx_pci(*handle);
++		if (pci_proto)
++		  grub_efi_setup_gfx_pci(*handle);
+ 		break;
+ 	      }
+ 	  }
+diff --git a/efi/grub/efi/api.h b/efi/grub/efi/api.h
+index 81a0b3f..4fdf73a 100644
+--- a/efi/grub/efi/api.h
++++ b/efi/grub/efi/api.h
+@@ -70,6 +70,11 @@
+ 
+ #define GRUB_EFI_OPTIONAL_PTR	0x00000001
+ 
++#define GRUB_EFI_EDID_DISCOVERED_GUID \
++  {0x1c0c34f6,0xd380,0x41fa, {0xa0,0x49,0x8a,0xd0, \
++0x6c,0x1a,0x66,0xaa}}
++
++
+ #define GRUB_EFI_PCI_IO_GUID	\
+   { 0x4cf5b200, 0x68b8, 0x4ca5, \
+     { 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x02, 0x9a } \
 diff --git a/efi/grub/i386/linux.h b/efi/grub/i386/linux.h
 index 1545a7a..215a5d5 100644
 --- a/efi/grub/i386/linux.h


More information about the scm-commits mailing list