diff options
author | Toomas Soome <tsoome@me.com> | 2021-02-22 00:16:23 +0200 |
---|---|---|
committer | Toomas Soome <tsoome@me.com> | 2021-03-16 20:15:13 +0200 |
commit | f38f28fdbc29b3c5020295a6c6cb1ac52e949978 (patch) | |
tree | 5223e6294621f7ce55f6183724c3ed0da76b1f3c /usr/src | |
parent | 8781de92560745751daa24953330574a84de46e6 (diff) | |
download | illumos-joyent-f38f28fdbc29b3c5020295a6c6cb1ac52e949978.tar.gz |
13574 loader.efi: efifb_gop_get_edid() is broken
Reviewed by: Robert Mustacchi <rm@fingolfin.org>
Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/boot/Makefile.version | 2 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/efi/loader/framebuffer.c | 41 |
2 files changed, 24 insertions, 19 deletions
diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version index 32d625d23a..486e265893 100644 --- a/usr/src/boot/Makefile.version +++ b/usr/src/boot/Makefile.version @@ -34,4 +34,4 @@ LOADER_VERSION = 1.1 # Use date like formatting here, YYYY.MM.DD.XX, without leading zeroes. # The version is processed from left to right, the version number can only # be increased. -BOOT_VERSION = $(LOADER_VERSION)-2021.03.07.1 +BOOT_VERSION = $(LOADER_VERSION)-2021.03.12.1 diff --git a/usr/src/boot/sys/boot/efi/loader/framebuffer.c b/usr/src/boot/sys/boot/efi/loader/framebuffer.c index d638d136ac..799678b222 100644 --- a/usr/src/boot/sys/boot/efi/loader/framebuffer.c +++ b/usr/src/boot/sys/boot/efi/loader/framebuffer.c @@ -31,6 +31,7 @@ #include <stand.h> #include <bootstrap.h> #include <sys/endian.h> +#include <sys/param.h> #include <sys/font.h> #include <sys/consplat.h> #include <sys/limits.h> @@ -51,11 +52,13 @@ EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; static EFI_GUID pciio_guid = EFI_PCI_IO_PROTOCOL_GUID; EFI_GUID uga_guid = EFI_UGA_DRAW_PROTOCOL_GUID; static EFI_GUID active_edid_guid = EFI_EDID_ACTIVE_PROTOCOL_GUID; +static EFI_GUID discovered_edid_guid = EFI_EDID_DISCOVERED_PROTOCOL_GUID; +static EFI_HANDLE gop_handle; /* Saved initial GOP mode. */ static uint32_t default_mode = UINT32_MAX; /* Cached EDID. */ -static struct vesa_edid_info *edid_info; +static struct vesa_edid_info *edid_info = NULL; static uint32_t gop_default_mode(void); static int efifb_set_mode(EFI_GRAPHICS_OUTPUT *, uint_t); @@ -450,7 +453,7 @@ efifb_from_uga(struct efi_fb *efifb, EFI_UGA_DRAW_PROTOCOL *uga) * Fetch EDID info. Caller must free the buffer. */ static struct vesa_edid_info * -efifb_gop_get_edid(EFI_HANDLE gop) +efifb_gop_get_edid(EFI_HANDLE h) { const uint8_t magic[] = EDID_MAGIC; EFI_EDID_ACTIVE_PROTOCOL *edid; @@ -460,22 +463,25 @@ efifb_gop_get_edid(EFI_HANDLE gop) size_t size; guid = &active_edid_guid; - status = OpenProtocolByHandle(gop, guid, (void **)&edid); - if (status != EFI_SUCCESS) - return (NULL); + status = BS->OpenProtocol(h, guid, (void **)&edid, IH, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (status != EFI_SUCCESS || + edid->SizeOfEdid == 0) { + guid = &discovered_edid_guid; + status = BS->OpenProtocol(h, guid, (void **)&edid, IH, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (status != EFI_SUCCESS || + edid->SizeOfEdid == 0) + return (NULL); + } - size = sizeof (*edid_infop); - if (size < edid->SizeOfEdid) - size = edid->SizeOfEdid; + size = MAX(sizeof (*edid_infop), edid->SizeOfEdid); edid_infop = calloc(1, size); - if (edid_infop == NULL) { - status = BS->CloseProtocol(gop, guid, IH, NULL); + if (edid_infop == NULL) return (NULL); - } memcpy(edid_infop, edid->Edid, edid->SizeOfEdid); - status = BS->CloseProtocol(gop, guid, IH, NULL); /* Validate EDID */ if (memcmp(edid_infop, magic, sizeof (magic)) != 0) @@ -493,11 +499,10 @@ error: static bool efifb_get_edid(edid_res_list_t *res) { - extern EFI_GRAPHICS_OUTPUT *gop; bool rv = false; if (edid_info == NULL) - edid_info = efifb_gop_get_edid(gop); + edid_info = efifb_gop_get_edid(gop_handle); if (edid_info != NULL) rv = gfx_get_edid_resolution(edid_info, res); @@ -508,7 +513,7 @@ efifb_get_edid(edid_res_list_t *res) int efi_find_framebuffer(struct efi_fb *efifb) { - EFI_HANDLE h, *hlist; + EFI_HANDLE *hlist; UINTN nhandles, i, hsize; extern EFI_GRAPHICS_OUTPUT *gop; extern EFI_UGA_DRAW_PROTOCOL *uga; @@ -538,18 +543,18 @@ efi_find_framebuffer(struct efi_fb *efifb) /* * Search for ConOut protocol, if not found, use first handle. */ - h = *hlist; + gop_handle = *hlist; for (i = 0; i < nhandles; i++) { void *dummy = NULL; status = OpenProtocolByHandle(hlist[i], &conout_guid, &dummy); if (status == EFI_SUCCESS) { - h = hlist[i]; + gop_handle = hlist[i]; break; } } - status = OpenProtocolByHandle(h, &gop_guid, (void **)&gop); + status = OpenProtocolByHandle(gop_handle, &gop_guid, (void **)&gop); free(hlist); if (status == EFI_SUCCESS) { |