Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Jan 2021 11:08:20 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: 50180d2b52cc - main - loader.efi: reworked framebuffer setup
Message-ID:  <202101121108.10CB8Kjj044141@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=50180d2b52cc16ecb6a6617fdc53f5d83c71a8b4

commit 50180d2b52cc16ecb6a6617fdc53f5d83c71a8b4
Author:     Toomas Soome <tsoome@FreeBSD.org>
AuthorDate: 2021-01-11 21:54:23 +0000
Commit:     Toomas Soome <tsoome@FreeBSD.org>
CommitDate: 2021-01-12 11:07:27 +0000

    loader.efi: reworked framebuffer setup
    
    Pass gfx_state to efi_find_framebuffer(), so we can pick between
    GOP and UGA in efi_find_framebuffer(), also we can then
    set up struct gen_fb in gfx_state from efifb and isolate efi fb data
    processing into framebuffer.c.
    
    This change does allow us to clean up efi_cons_init() and reduce
    BS->LocateProtocol() calls.
    
    A little downside is that we now need to translate gen_fb back to
    efifb in bootinfo.c (for passing to kernel), and we need to add few
    -I options to CFLAGS.
---
 stand/efi/libefi/Makefile      |  1 +
 stand/efi/libefi/efi_console.c | 61 +++++++++++++-----------------------------
 stand/efi/loader/Makefile      |  4 +++
 stand/efi/loader/bootinfo.c    | 33 ++++++++++++++---------
 stand/efi/loader/framebuffer.c | 50 +++++++++++++++++++++++++++++-----
 stand/efi/loader/framebuffer.h |  4 ++-
 6 files changed, 90 insertions(+), 63 deletions(-)

diff --git a/stand/efi/libefi/Makefile b/stand/efi/libefi/Makefile
index 010754b5238a..6d342aaa8007 100644
--- a/stand/efi/libefi/Makefile
+++ b/stand/efi/libefi/Makefile
@@ -50,6 +50,7 @@ CFLAGS+= -fPIC -mno-red-zone
 CFLAGS+= -I${EFIINC}
 CFLAGS+= -I${EFIINCMD}
 CFLAGS.efi_console.c+= -I${SRCTOP}/sys/teken -I${SRCTOP}/contrib/pnglite
+CFLAGS.efi_console.c+= -I${.CURDIR}/../loader
 CFLAGS.teken.c+= -I${SRCTOP}/sys/teken
 .if ${MK_LOADER_ZFS} != "no"
 CFLAGS+=	-I${ZFSSRC}
diff --git a/stand/efi/libefi/efi_console.c b/stand/efi/libefi/efi_console.c
index 6782cf5696a8..533f4458c15b 100644
--- a/stand/efi/libefi/efi_console.c
+++ b/stand/efi/libefi/efi_console.c
@@ -34,10 +34,10 @@ __FBSDID("$FreeBSD$");
 #include <sys/reboot.h>
 #include <machine/metadata.h>
 #include <gfx_fb.h>
+#include <framebuffer.h>
 #include "bootstrap.h"
 
 extern EFI_GUID gop_guid;
-extern int efi_find_framebuffer(struct efi_fb *efifb);
 static EFI_GUID simple_input_ex_guid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
 static SIMPLE_TEXT_OUTPUT_INTERFACE	*conout;
 static SIMPLE_INPUT_INTERFACE		*conin;
@@ -884,52 +884,29 @@ cons_update_mode(bool use_gfx_mode)
 	const teken_attr_t *a;
 	teken_attr_t attr;
 	EFI_STATUS status;
-	EFI_GRAPHICS_OUTPUT *gop = NULL;
-	struct efi_fb efifb;
 	char env[10], *ptr;
 
-	if (use_gfx_mode == true) {
-		gfx_state.tg_fb_type = FB_GOP;
-		if (gfx_state.tg_private == NULL) {
-			(void) BS->LocateProtocol(&gop_guid, NULL,
-			    (void **)&gop);
-			gfx_state.tg_private = gop;
-		} else {
-			gop = gfx_state.tg_private;
-		}
+	/*
+	 * Despite the use_gfx_mode, we want to make sure we call
+	 * efi_find_framebuffer(). This will populate the fb data,
+	 * which will be passed to kernel.
+	 */
+	if (efi_find_framebuffer(&gfx_state) == 0 && use_gfx_mode) {
+		int roff, goff, boff;
 
+		roff = ffs(gfx_state.tg_fb.fb_mask_red) - 1;
+		goff = ffs(gfx_state.tg_fb.fb_mask_green) - 1;
+		boff = ffs(gfx_state.tg_fb.fb_mask_blue) - 1;
+
+		(void) generate_cons_palette(cmap, COLOR_FORMAT_RGB,
+		    gfx_state.tg_fb.fb_mask_red >> roff, roff,
+		    gfx_state.tg_fb.fb_mask_green >> goff, goff,
+		    gfx_state.tg_fb.fb_mask_blue >> boff, boff);
+	} else {
 		/*
-		 * We have FB but no GOP - it must be UGA.
+		 * Either text mode was asked by user or we failed to
+		 * find frame buffer.
 		 */
-		if (gop == NULL)
-			gfx_state.tg_fb_type = FB_UGA;
-
-		if (efi_find_framebuffer(&efifb) == 0) {
-			int roff, goff, boff;
-
-			gfx_state.tg_fb.fb_addr = efifb.fb_addr;
-			gfx_state.tg_fb.fb_size = efifb.fb_size;
-			gfx_state.tg_fb.fb_height = efifb.fb_height;
-			gfx_state.tg_fb.fb_width = efifb.fb_width;
-			gfx_state.tg_fb.fb_stride = efifb.fb_stride;
-			gfx_state.tg_fb.fb_mask_red = efifb.fb_mask_red;
-			gfx_state.tg_fb.fb_mask_green = efifb.fb_mask_green;
-			gfx_state.tg_fb.fb_mask_blue = efifb.fb_mask_blue;
-			gfx_state.tg_fb.fb_mask_reserved =
-			    efifb.fb_mask_reserved;
-			roff = ffs(efifb.fb_mask_red) - 1;
-			goff = ffs(efifb.fb_mask_green) - 1;
-			boff = ffs(efifb.fb_mask_blue) - 1;
-
-			(void) generate_cons_palette(cmap, COLOR_FORMAT_RGB,
-			    efifb.fb_mask_red >> roff, roff,
-			    efifb.fb_mask_green >> goff, goff,
-			    efifb.fb_mask_blue >> boff, boff);
-			gfx_state.tg_fb.fb_bpp = fls(
-			    efifb.fb_mask_red | efifb.fb_mask_green |
-			    efifb.fb_mask_blue | efifb.fb_mask_reserved);
-		}
-	} else {
 		gfx_state.tg_fb_type = FB_TEXT;
 	}
 
diff --git a/stand/efi/loader/Makefile b/stand/efi/loader/Makefile
index 3cf2df933cc3..f7032c78926d 100644
--- a/stand/efi/loader/Makefile
+++ b/stand/efi/loader/Makefile
@@ -35,6 +35,10 @@ CFLAGS+=	-DEFI_ZFS_BOOT
 HAVE_ZFS=	yes
 .endif
 
+CFLAGS.bootinfo.c += -I$(SRCTOP)/sys/teken
+CFLAGS.bootinfo.c += -I${SRCTOP}/contrib/pnglite
+CFLAGS.framebuffer.c += -I$(SRCTOP)/sys/teken
+CFLAGS.framebuffer.c += -I${SRCTOP}/contrib/pnglite
 CFLAGS.gfx_fb.c += -I$(SRCTOP)/sys/teken
 CFLAGS.gfx_fb.c += -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/lz4
 CFLAGS.gfx_fb.c += -I${SRCTOP}/contrib/pnglite
diff --git a/stand/efi/loader/bootinfo.c b/stand/efi/loader/bootinfo.c
index 108f46c5f9c4..a11c45d05a0f 100644
--- a/stand/efi/loader/bootinfo.c
+++ b/stand/efi/loader/bootinfo.c
@@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/specialreg.h>
 #endif
 
-#include "framebuffer.h"
+#include "gfx_fb.h"
 
 #if defined(LOADER_FDT_SUPPORT)
 #include <fdt_platform.h>
@@ -300,19 +300,26 @@ bi_load_efi_data(struct preloaded_file *kfp)
 #if defined(__amd64__) || defined(__aarch64__)
 	struct efi_fb efifb;
 
-	if (efi_find_framebuffer(&efifb) == 0) {
-		printf("EFI framebuffer information:\n");
-		printf("addr, size     0x%jx, 0x%jx\n", efifb.fb_addr,
-		    efifb.fb_size);
-		printf("dimensions     %d x %d\n", efifb.fb_width,
-		    efifb.fb_height);
-		printf("stride         %d\n", efifb.fb_stride);
-		printf("masks          0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
-		    efifb.fb_mask_red, efifb.fb_mask_green, efifb.fb_mask_blue,
-		    efifb.fb_mask_reserved);
-
+	efifb.fb_addr = gfx_state.tg_fb.fb_addr;
+	efifb.fb_size = gfx_state.tg_fb.fb_size;
+	efifb.fb_height = gfx_state.tg_fb.fb_height;
+	efifb.fb_width = gfx_state.tg_fb.fb_width;
+	efifb.fb_stride = gfx_state.tg_fb.fb_stride;
+	efifb.fb_mask_red = gfx_state.tg_fb.fb_mask_red;
+	efifb.fb_mask_green = gfx_state.tg_fb.fb_mask_green;
+	efifb.fb_mask_blue = gfx_state.tg_fb.fb_mask_blue;
+	efifb.fb_mask_reserved = gfx_state.tg_fb.fb_mask_reserved;
+
+	printf("EFI framebuffer information:\n");
+	printf("addr, size     0x%jx, 0x%jx\n", efifb.fb_addr, efifb.fb_size);
+	printf("dimensions     %d x %d\n", efifb.fb_width, efifb.fb_height);
+	printf("stride         %d\n", efifb.fb_stride);
+	printf("masks          0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+	    efifb.fb_mask_red, efifb.fb_mask_green, efifb.fb_mask_blue,
+	    efifb.fb_mask_reserved);
+
+	if (efifb.fb_addr != 0)
 		file_addmetadata(kfp, MODINFOMD_EFI_FB, sizeof(efifb), &efifb);
-	}
 #endif
 
 	do_vmap = true;
diff --git a/stand/efi/loader/framebuffer.c b/stand/efi/loader/framebuffer.c
index db7bcb49f2f4..a2bd054e16dc 100644
--- a/stand/efi/loader/framebuffer.c
+++ b/stand/efi/loader/framebuffer.c
@@ -464,21 +464,57 @@ efifb_from_uga(struct efi_fb *efifb, EFI_UGA_DRAW_PROTOCOL *uga)
 }
 
 int
-efi_find_framebuffer(struct efi_fb *efifb)
+efi_find_framebuffer(teken_gfx_t *gfx_state)
 {
+	struct efi_fb efifb;
 	EFI_GRAPHICS_OUTPUT *gop;
 	EFI_UGA_DRAW_PROTOCOL *uga;
 	EFI_STATUS status;
+	int rv;
+
+	gfx_state->tg_fb_type = FB_TEXT;
 
 	status = BS->LocateProtocol(&gop_guid, NULL, (VOID **)&gop);
-	if (status == EFI_SUCCESS)
-		return (efifb_from_gop(efifb, gop->Mode, gop->Mode->Info));
+	if (status == EFI_SUCCESS) {
+		gfx_state->tg_fb_type = FB_GOP;
+		gfx_state->tg_private = gop;
+	} else {
+		status = BS->LocateProtocol(&uga_guid, NULL, (VOID **)&uga);
+		if (status == EFI_SUCCESS) {
+			gfx_state->tg_fb_type = FB_UGA;
+			gfx_state->tg_private = uga;
+		} else {
+			return (1);
+		}
+	}
 
-	status = BS->LocateProtocol(&uga_guid, NULL, (VOID **)&uga);
-	if (status == EFI_SUCCESS)
-		return (efifb_from_uga(efifb, uga));
+	switch (gfx_state->tg_fb_type) {
+	case FB_GOP:
+		rv = efifb_from_gop(&efifb, gop->Mode, gop->Mode->Info);
+		break;
 
-	return (1);
+	case FB_UGA:
+		rv = efifb_from_uga(&efifb, uga);
+		break;
+
+	default:
+		return (1);
+	}
+
+	gfx_state->tg_fb.fb_addr = efifb.fb_addr;
+	gfx_state->tg_fb.fb_size = efifb.fb_size;
+	gfx_state->tg_fb.fb_height = efifb.fb_height;
+	gfx_state->tg_fb.fb_width = efifb.fb_width;
+	gfx_state->tg_fb.fb_stride = efifb.fb_stride;
+	gfx_state->tg_fb.fb_mask_red = efifb.fb_mask_red;
+	gfx_state->tg_fb.fb_mask_green = efifb.fb_mask_green;
+	gfx_state->tg_fb.fb_mask_blue = efifb.fb_mask_blue;
+	gfx_state->tg_fb.fb_mask_reserved = efifb.fb_mask_reserved;
+
+	gfx_state->tg_fb.fb_bpp = fls(efifb.fb_mask_red | efifb.fb_mask_green |
+	    efifb.fb_mask_blue | efifb.fb_mask_reserved);
+
+	return (0);
 }
 
 static void
diff --git a/stand/efi/loader/framebuffer.h b/stand/efi/loader/framebuffer.h
index 2ec9017dc3ee..008df7f6c167 100644
--- a/stand/efi/loader/framebuffer.h
+++ b/stand/efi/loader/framebuffer.h
@@ -28,9 +28,11 @@
  * $FreeBSD$
  */
 
+#include <gfx_fb.h>
+
 #ifndef	_EFIFB_H_
 #define	_EFIFB_H_
 
-int	efi_find_framebuffer(struct efi_fb *efifb);
+int	efi_find_framebuffer(teken_gfx_t *gfx_state);
 
 #endif /* _EFIFB_H_ */



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