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>