aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToomas Soome <tsoome@FreeBSD.org>2021-01-11 21:54:23 +0000
committerToomas Soome <tsoome@FreeBSD.org>2021-01-12 11:07:27 +0000
commit50180d2b52cc16ecb6a6617fdc53f5d83c71a8b4 (patch)
treed8ec324718c7bc62b3bc43539cd9207a900e81c4
parent85d028223bc2768651f4d44881644ceb5dc2a664 (diff)
downloadsrc-50180d2b52cc16ecb6a6617fdc53f5d83c71a8b4.tar.gz
src-50180d2b52cc16ecb6a6617fdc53f5d83c71a8b4.zip
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.
-rw-r--r--stand/efi/libefi/Makefile1
-rw-r--r--stand/efi/libefi/efi_console.c61
-rw-r--r--stand/efi/loader/Makefile4
-rw-r--r--stand/efi/loader/bootinfo.c33
-rw-r--r--stand/efi/loader/framebuffer.c50
-rw-r--r--stand/efi/loader/framebuffer.h4
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_ */