summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrpaulo <rpaulo@FreeBSD.org>2015-04-04 04:27:54 +0000
committerrpaulo <rpaulo@FreeBSD.org>2015-04-04 04:27:54 +0000
commit0e7c1179da33965306e740c3a1b2bf9ab2ff58a8 (patch)
tree4a917b562bf8e22b15111c87e7cdfd0222f25ce7
parent2533468b8cafd57d889a5fcad80b7b8ce3cb301b (diff)
downloadFreeBSD-src-0e7c1179da33965306e740c3a1b2bf9ab2ff58a8.zip
FreeBSD-src-0e7c1179da33965306e740c3a1b2bf9ab2ff58a8.tar.gz
boot1 EFI: reset the screen and select the best mode.
It's necessary to reset the screen to make sure any vendor pixels are gone when we start boot1. In the Lenovo X1 (3rd gen), this is the only way to clear the screen. Previously, the Lenovo logo would only disappear after the kernel started scrolling the display. After resetting the screen, EFI could put us in the worst LCD mode (oversized characters), so we now find the largest mode we can use and hope it's the most appropriate one (it's not trivial to tell what's the correct LCD resolution at this point). It's worth noting that the final stage loader has a 'mode' command that can be used to switch text modes. While there, enable the software cursor, just like in the legacy boot mode. MFC after: 1 week
-rw-r--r--sys/boot/efi/boot1/boot1.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/sys/boot/efi/boot1/boot1.c b/sys/boot/efi/boot1/boot1.c
index 15f5d63..43e49d1 100644
--- a/sys/boot/efi/boot1/boot1.c
+++ b/sys/boot/efi/boot1/boot1.c
@@ -108,11 +108,12 @@ EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab)
{
EFI_HANDLE handles[128];
EFI_BLOCK_IO *blkio;
- UINTN i, nparts = sizeof(handles);
+ UINTN i, nparts = sizeof(handles), cols, rows, max_dim, best_mode;
EFI_STATUS status;
EFI_DEVICE_PATH *devpath;
EFI_BOOT_SERVICES *BS;
EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
+ SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
char *path = _PATH_LOADER;
systab = Xsystab;
@@ -124,6 +125,26 @@ EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab)
if (status == EFI_SUCCESS)
(void)ConsoleControl->SetMode(ConsoleControl,
EfiConsoleControlScreenText);
+ /*
+ * Reset the console and find the best text mode.
+ */
+ conout = systab->ConOut;
+ conout->Reset(conout, TRUE);
+ max_dim = best_mode = 0;
+ for (i = 0; ; i++) {
+ status = conout->QueryMode(conout, i,
+ &cols, &rows);
+ if (EFI_ERROR(status))
+ break;
+ 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);
printf(" \n>> FreeBSD EFI boot block\n");
printf(" Loader path: %s\n", path);
OpenPOWER on IntegriCloud