loader.efi: add "gop blt <on|off>" command

Some systems have very slow console output and it may be about either
wrong memory attributes are set or gop->Blt() implementation is bad.

We do not have good way to set memory attributes, but we can
choose which Blt() to use (or we can set "gop off" to fall back on
use of SimpleTextOutput protocol).

This update adds argument for "gop" command to switch gop->Blt() use.
Note, this update does not fix the problem, but allows us to try to
understand the possible cause.

PR:		254381
Reported by:	Michael Galassi

Reviewed by:	manu, imp
Differential Revision:	https://reviews.freebsd.org/D49073
This commit is contained in:
Toomas Soome
2025-02-20 21:50:20 +02:00
parent 8dcdffdb08
commit 21b5b8b38b
2 changed files with 32 additions and 4 deletions
+9 -1
View File
@@ -161,6 +161,14 @@ static const int vga_to_cons_colors[NCOLORS] = {
8, 9, 10, 11, 12, 13, 14, 15
};
/*
* It is reported very slow console draw in some systems.
* in order to exclude buggy gop->Blt(), we want option
* to use direct draw to framebuffer and avoid gop->Blt.
* Can be toggled with "gop" command.
*/
bool ignore_gop_blt = false;
struct text_pixel *screen_buffer;
#if defined(EFI)
static EFI_GRAPHICS_OUTPUT_BLT_PIXEL *GlyphBuffer;
@@ -795,7 +803,7 @@ gfxfb_blt(void *BltBuffer, GFXFB_BLT_OPERATION BltOperation,
* done as they are provided by protocols that disappear when exit
* boot services.
*/
if (gop != NULL && boot_services_active) {
if (!ignore_gop_blt && gop != NULL && boot_services_active) {
tpl = BS->RaiseTPL(TPL_NOTIFY);
switch (BltOperation) {
case GfxFbBltVideoFill:
+23 -3
View File
@@ -856,6 +856,7 @@ command_gop(int argc, char *argv[])
struct efi_fb efifb;
EFI_STATUS status;
u_int mode;
extern bool ignore_gop_blt;
if (gop == NULL) {
snprintf(command_errbuf, sizeof(command_errbuf),
@@ -866,7 +867,7 @@ command_gop(int argc, char *argv[])
if (argc < 2)
goto usage;
if (!strcmp(argv[1], "set")) {
if (strcmp(argv[1], "set") == 0) {
char *cp;
if (argc != 3)
@@ -884,7 +885,26 @@ command_gop(int argc, char *argv[])
return (CMD_ERROR);
}
(void) cons_update_mode(true);
} else if (strcmp(argv[1], "blt") == 0) {
/*
* "blt on" does allow gop->Blt() to be used (default).
* "blt off" does block gop->Blt() to be used and use
* software rendering instead.
*/
if (argc != 3)
goto usage;
if (strcmp(argv[2], "on") == 0)
ignore_gop_blt = false;
else if (strcmp(argv[2], "off") == 0)
ignore_gop_blt = true;
else
goto usage;
} else if (strcmp(argv[1], "off") == 0) {
/*
* Tell console to use SimpleTextOutput protocol.
* This means that we do not render the glyphs, but rely on
* UEFI firmware to draw on ConsOut device(s).
*/
(void) cons_update_mode(false);
} else if (strcmp(argv[1], "get") == 0) {
edid_res_list_t res;
@@ -908,7 +928,7 @@ command_gop(int argc, char *argv[])
}
print_efifb(gop->Mode->Mode, &efifb, 1);
printf("\n");
} else if (!strcmp(argv[1], "list")) {
} else if (strcmp(argv[1], "list") == 0) {
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
UINTN infosz;
@@ -931,7 +951,7 @@ command_gop(int argc, char *argv[])
usage:
snprintf(command_errbuf, sizeof(command_errbuf),
"usage: %s [list | get | set <mode> | off]", argv[0]);
"usage: %s [list | get | set <mode> | off | blt <on|off>]", argv[0]);
return (CMD_ERROR);
}