Add a gop command to help diagnose VT efifb problems. The gop

command has the following sub-commands:
  list		- list all possible modes (paged)
  get		- return the current mode
  set <mode>	- set the current mode to <mode>
This commit is contained in:
Marcel Moolenaar 2015-08-30 01:39:59 +00:00
parent 60caf0c9c2
commit d81907ecbf

View File

@ -29,6 +29,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <bootstrap.h>
#include <stand.h>
#include <efi.h>
@ -83,3 +84,97 @@ efi_find_framebuffer(struct efi_fb *efifb)
}
return (0);
}
COMMAND_SET(gop, "gop", "graphics output protocol", command_gop);
static void
command_gop_display(u_int mode, EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info)
{
printf("mode %u: %ux%u, stride=%u, color=", mode,
info->HorizontalResolution, info->VerticalResolution,
info->PixelsPerScanLine);
switch (info->PixelFormat) {
case PixelRedGreenBlueReserved8BitPerColor:
printf("32-bit (RGB)");
break;
case PixelBlueGreenRedReserved8BitPerColor:
printf("32-bit (BGR)");
break;
case PixelBitMask:
printf("mask (R=%x, G=%x, B=%x, X=%x)",
info->PixelInformation.RedMask,
info->PixelInformation.GreenMask,
info->PixelInformation.BlueMask,
info->PixelInformation.ReservedMask);
break;
case PixelBltOnly:
printf("unsupported (blt only)");
break;
default:
printf("unsupported (unknown)");
break;
}
}
static int
command_gop(int argc, char *argv[])
{
EFI_GRAPHICS_OUTPUT *gop;
EFI_STATUS status;
u_int mode;
status = BS->LocateProtocol(&gop_guid, NULL, (VOID **)&gop);
if (EFI_ERROR(status)) {
sprintf(command_errbuf, "%s: Graphics Output Protocol not "
"present (error=%lu)", argv[0], status & ~EFI_ERROR_MASK);
return (CMD_ERROR);
}
if (argc == 1)
goto usage;
if (!strcmp(argv[1], "set")) {
char *cp;
if (argc != 3)
goto usage;
mode = strtol(argv[2], &cp, 0);
if (cp[0] != '\0') {
sprintf(command_errbuf, "mode is an integer");
return (CMD_ERROR);
}
status = gop->SetMode(gop, mode);
if (EFI_ERROR(status)) {
sprintf(command_errbuf, "%s: Unable to set mode to "
"%u (error=%lu)", argv[0], mode,
status & ~EFI_ERROR_MASK);
return (CMD_ERROR);
}
} else if (!strcmp(argv[1], "get")) {
command_gop_display(gop->Mode->Mode, gop->Mode->Info);
printf("\n frame buffer: address=%jx, size=%lx\n",
(uintmax_t)gop->Mode->FrameBufferBase,
gop->Mode->FrameBufferSize);
} else if (!strcmp(argv[1], "list")) {
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
UINTN infosz;
pager_open();
for (mode = 0; mode < gop->Mode->MaxMode; mode++) {
status = gop->QueryMode(gop, mode, &infosz, &info);
if (EFI_ERROR(status))
continue;
command_gop_display(mode, info);
if (pager_output("\n"))
break;
}
pager_close();
}
return (CMD_OK);
usage:
sprintf(command_errbuf, "usage: %s [list | get | set <mode>]",
argv[0]);
return (CMD_ERROR);
}