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.
This commit is contained in:
parent
85d028223b
commit
50180d2b52
@ -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}
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
* We have FB but no GOP - it must be UGA.
|
||||
*/
|
||||
if (gop == NULL)
|
||||
gfx_state.tg_fb_type = FB_UGA;
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
(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 {
|
||||
/*
|
||||
* Either text mode was asked by user or we failed to
|
||||
* find frame buffer.
|
||||
*/
|
||||
gfx_state.tg_fb_type = FB_TEXT;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user