summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2021-01-17 10:20:41 +0200
committerToomas Soome <tsoome@me.com>2021-02-10 21:17:30 +0200
commit72973a2ec5f92e2ddf35c4a344567980fae70ec1 (patch)
treeb3014dfab6f96a13b98c1728bac7f136e37e0f65 /usr/src
parenta8e6450ff6a17b0dab01ca8f09ba123395cf94fa (diff)
downloadillumos-joyent-72973a2ec5f92e2ddf35c4a344567980fae70ec1.tar.gz
13453 loader.efi: handle multiple gop instances
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.version2
-rw-r--r--usr/src/boot/sys/boot/efi/loader/framebuffer.c38
2 files changed, 38 insertions, 2 deletions
diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version
index 6f851b7eef..cb628e3286 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)-2020.12.11.1
+BOOT_VERSION = $(LOADER_VERSION)-2021.01.17.1
diff --git a/usr/src/boot/sys/boot/efi/loader/framebuffer.c b/usr/src/boot/sys/boot/efi/loader/framebuffer.c
index 534e00cf9c..1100f2e4e1 100644
--- a/usr/src/boot/sys/boot/efi/loader/framebuffer.c
+++ b/usr/src/boot/sys/boot/efi/loader/framebuffer.c
@@ -46,6 +46,7 @@
#include "gfx_fb.h"
#include "framebuffer.h"
+EFI_GUID conout_guid = EFI_CONSOLE_OUT_DEVICE_GUID;
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;
@@ -506,6 +507,8 @@ efifb_get_edid(edid_res_list_t *res)
int
efi_find_framebuffer(struct efi_fb *efifb)
{
+ EFI_HANDLE h, *hlist;
+ UINTN nhandles, i, hsize;
extern EFI_GRAPHICS_OUTPUT *gop;
extern EFI_UGA_DRAW_PROTOCOL *uga;
EFI_STATUS status;
@@ -514,7 +517,40 @@ efi_find_framebuffer(struct efi_fb *efifb)
if (gop != NULL)
return (efifb_from_gop(efifb, gop->Mode, gop->Mode->Info));
- status = BS->LocateProtocol(&gop_guid, NULL, (void **)&gop);
+ hsize = 0;
+ hlist = NULL;
+ status = BS->LocateHandle(ByProtocol, &gop_guid, NULL, &hsize, hlist);
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ hlist = malloc(hsize);
+ if (hlist == NULL)
+ return (ENOMEM);
+ status = BS->LocateHandle(ByProtocol, &gop_guid, NULL, &hsize,
+ hlist);
+ if (EFI_ERROR(status))
+ free(hlist);
+ }
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
+
+ nhandles = hsize / sizeof (*hlist);
+
+ /*
+ * Search for ConOut protocol, if not found, use first handle.
+ */
+ h = *hlist;
+ for (i = 0; i < nhandles; i++) {
+ void *dummy = NULL;
+
+ status = OpenProtocolByHandle(hlist[i], &conout_guid, &dummy);
+ if (status == EFI_SUCCESS) {
+ h = hlist[i];
+ break;
+ }
+ }
+
+ status = OpenProtocolByHandle(h, &gop_guid, (void **)&gop);
+ free(hlist);
+
if (status == EFI_SUCCESS) {
/* Save default mode. */
if (default_mode == UINT32_MAX) {