Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 16 Jan 2021 23:30:01 GMT
From:      Toomas Soome <tsoome@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: ef698fabe428 - main - loader.efi: handle multiple gop instances
Message-ID:  <202101162330.10GNU15Y094001@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by tsoome:

URL: https://cgit.FreeBSD.org/src/commit/?id=ef698fabe42827bad43bf046143ef26e47d57514

commit ef698fabe42827bad43bf046143ef26e47d57514
Author:     Toomas Soome <tsoome@FreeBSD.org>
AuthorDate: 2021-01-16 17:51:23 +0000
Commit:     Toomas Soome <tsoome@FreeBSD.org>
CommitDate: 2021-01-16 23:29:35 +0000

    loader.efi: handle multiple gop instances
    
    Some systems may provide multiple GOP instances and not all are
    bound to hardware. The current loader is picking up the first GOP,
    which may not be usable. Instead we load the GOP handle array,
    and test every handle to have registered ConOut protocol. If ConOut is
    present, we can use this GOP handle to open GOP protocol.
---
 stand/efi/loader/framebuffer.c | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/stand/efi/loader/framebuffer.c b/stand/efi/loader/framebuffer.c
index a2bd054e16dc..1650f7da8760 100644
--- a/stand/efi/loader/framebuffer.c
+++ b/stand/efi/loader/framebuffer.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #include "bootstrap.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;
 static EFI_GUID uga_guid = EFI_UGA_DRAW_PROTOCOL_GUID;
@@ -466,6 +467,8 @@ efifb_from_uga(struct efi_fb *efifb, EFI_UGA_DRAW_PROTOCOL *uga)
 int
 efi_find_framebuffer(teken_gfx_t *gfx_state)
 {
+	EFI_HANDLE h, *hlist;
+	UINTN nhandles, i, hsize;
 	struct efi_fb efifb;
 	EFI_GRAPHICS_OUTPUT *gop;
 	EFI_UGA_DRAW_PROTOCOL *uga;
@@ -474,7 +477,39 @@ efi_find_framebuffer(teken_gfx_t *gfx_state)
 
 	gfx_state->tg_fb_type = FB_TEXT;
 
-	status = BS->LocateProtocol(&gop_guid, NULL, (VOID **)&gop);
+	hsize = 0;
+	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) {
 		gfx_state->tg_fb_type = FB_GOP;
 		gfx_state->tg_private = gop;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202101162330.10GNU15Y094001>