UEFI: Ditch console mode setting, choose optimal GOP mode later in boot

boot1 is too early to be deciding a good resolution. Console modes don't map
cleanly/predictably to actual screen resolutions, and GOP does not reflect
the actual screen resolution after a console mode change. Rip it out.

Add an efi-autoresizecons command to loader to choose an optimal screen
resolution based on the current environment. We'll explicitly execute this
later, preferably before we draw anything of value but after we load config
and pick up any tunables we may need to decide where we're going.

This method also allows us to actually pass the correct framebuffer
information on to the kernel.

UGA autoresizing is not implemented because it doesn't have the kind of mode
enumeration that GOP does. If an interested person with relevant hardware
could get in contact, we can take a look at implementing UGA autoresize.

This effectively "fixes" the breakage caused by r327058, but doesn't
actually set the resolution correctly until the interpreter calls
efi-autoresizcons. The lualoader version of this has been included for
reference; the forth equivalent will follow.

Reviewed by:	imp (with some hestitation), manu
Differential Revision:	https://reviews.freebsd.org/D14788
This commit is contained in:
Kyle Evans 2018-03-21 20:36:57 +00:00
parent 9895e5d41b
commit 5f8cfbe134
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=331321
4 changed files with 78 additions and 14 deletions

View File

@ -391,7 +391,7 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
EFI_STATUS status;
EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
UINTN i, max_dim, best_mode, cols, rows, hsize, nhandles;
UINTN i, hsize, nhandles;
CHAR16 *text;
UINT16 boot_current;
size_t sz;
@ -410,22 +410,11 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
(void)ConsoleControl->SetMode(ConsoleControl,
EfiConsoleControlScreenText);
/*
* Reset the console and find the best text mode.
* Reset the console enable the cursor. Later we'll choose a better
* console size through GOP/UGA.
*/
conout = ST->ConOut;
conout->Reset(conout, TRUE);
max_dim = best_mode = 0;
for (i = 0; i < conout->Mode->MaxMode; i++) {
status = conout->QueryMode(conout, i, &cols, &rows);
if (EFI_ERROR(status))
continue;
if (cols * rows > max_dim) {
max_dim = cols * rows;
best_mode = i;
}
}
if (max_dim > 0)
conout->SetMode(conout, best_mode);
conout->EnableCursor(conout, TRUE);
conout->ClearScreen(conout);

View File

@ -462,6 +462,72 @@ print_efifb(int mode, struct efi_fb *efifb, int verbose)
}
}
static int
gop_autoresize(EFI_GRAPHICS_OUTPUT *gop)
{
struct efi_fb efifb;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
EFI_STATUS status;
UINTN infosz;
UINT32 best_mode, currdim, maxdim, mode;
best_mode = maxdim = 0;
for (mode = 0; mode < gop->Mode->MaxMode; mode++) {
status = gop->QueryMode(gop, mode, &infosz, &info);
if (EFI_ERROR(status))
continue;
efifb_from_gop(&efifb, gop->Mode, info);
currdim = info->HorizontalResolution * info->VerticalResolution;
/* XXX TODO: Allow tunable or something for max resolution */
if (currdim > maxdim) {
maxdim = currdim;
best_mode = mode;
}
}
status = gop->SetMode(gop, best_mode);
if (EFI_ERROR(status)) {
snprintf(command_errbuf, sizeof(command_errbuf),
"gop_autoresize: Unable to set mode to %u (error=%lu)",
mode, EFI_ERROR_CODE(status));
return (CMD_ERROR);
}
return (CMD_OK);
}
static int
uga_autoresize(EFI_UGA_DRAW_PROTOCOL *gop)
{
return (CMD_OK);
}
COMMAND_SET(efi_autoresize, "efi-autoresizecons", "EFI Auto-resize Console", command_autoresize);
static int
command_autoresize(int argc, char *argv[])
{
EFI_GRAPHICS_OUTPUT *gop;
EFI_UGA_DRAW_PROTOCOL *uga;
EFI_STATUS status;
u_int mode;
gop = NULL;
uga = NULL;
status = BS->LocateProtocol(&gop_guid, NULL, (VOID **)&gop);
if (EFI_ERROR(status) == 0)
return (gop_autoresize(gop));
status = BS->LocateProtocol(&uga_guid, NULL, (VOID **)&uga);
if (EFI_ERROR(status) == 0)
return (uga_autoresize(uga));
snprintf(command_errbuf, sizeof(command_errbuf),
"%s: Neither Graphics Output Protocol nor Universal Graphics Adapter present",
argv[0]);
return (CMD_ERROR);
}
COMMAND_SET(gop, "gop", "graphics output protocol", command_gop);
static int

View File

@ -274,6 +274,12 @@ function core.isSingleUserBoot()
return single_user ~= nil and single_user:lower() == "yes"
end
function core.isUEFIBoot()
local efiver = loader.getenv("efi-version")
return efiver ~= nil
end
function core.isZFSBoot()
local c = loader.getenv("currdev")

View File

@ -50,6 +50,9 @@ if result ~= nil then
end
config.load()
if core.isUEFIBoot() then
loader.perform("efi-autoresizecons")
end
-- Our console may have been setup for a different color scheme before we get
-- here, so make sure we set the default.
if color.isEnabled() then