From 9adc70887e06e23975eeea6e62b3d8921ef2b1a1 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Mon, 17 Feb 2020 16:36:13 -0600 Subject: [PATCH] efi: Call console-control to enter text mode Change-Id: Ife1df3415bc5a31801bcb3d925f1b7c3a105f51b Reviewed-on: https://review.haiku-os.org/c/haiku/+/2250 Reviewed-by: Adrien Destugues --- .../platform/efi/protocol/console-control.h | 34 ++++++++++++++ src/system/boot/platform/efi/console.cpp | 46 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 headers/private/kernel/platform/efi/protocol/console-control.h diff --git a/headers/private/kernel/platform/efi/protocol/console-control.h b/headers/private/kernel/platform/efi/protocol/console-control.h new file mode 100644 index 0000000000..d259c1efc7 --- /dev/null +++ b/headers/private/kernel/platform/efi/protocol/console-control.h @@ -0,0 +1,34 @@ +// Copyright 2020 Haiku, Inc. All rights reserved +// Released under the terms of the MIT License + +#pragma once + +#include + +#define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \ + {0xf42f7782, 0x012e, 0x4c12, \ + {0x99, 0x56, 0x49, 0xf9, 0x43, 0x04, 0xf7, 0x21}} + +extern efi_guid ConsoleControlProtocol; + +typedef enum { + EfiConsoleControlScreenText, + EfiConsoleControlScreenGraphics, + EfiConsoleControlScreenMax +} efi_console_control_screen_mode; + +typedef struct efi_console_control_protocol { + uint64_t Revision; + + efi_status (*GetMode) (struct efi_console_control_protocol* self, + efi_console_control_screen_mode* mode, + bool* gopUgaExists, + bool* stdInLocked) EFIAPI; + + efi_status (*SetMode) (struct efi_console_control_protocol* self, + efi_console_control_screen_mode mode) EFIAPI; + + efi_status (*LockStdIn) (struct efi_console_control_protocol* self, + uint16_t* password); + +} efi_console_control_protocol; diff --git a/src/system/boot/platform/efi/console.cpp b/src/system/boot/platform/efi/console.cpp index be04d3b8b7..5747436632 100644 --- a/src/system/boot/platform/efi/console.cpp +++ b/src/system/boot/platform/efi/console.cpp @@ -14,11 +14,22 @@ #include #include +#include #include #include "efi_platform.h" +// This likely won't work without moving things around. +// Too early (pre-console init) +//#define TRACE_CONSOLE +#ifdef TRACE_CONSOLE +# define TRACE(x...) dprintf(x) +#else +# define TRACE(x...) +#endif + + class Console : public ConsoleNode { public: Console(); @@ -202,9 +213,43 @@ static void update_screen_size(void) } +static void +console_control(bool graphics) +{ + TRACE("Checking for EFI Console Control...\n"); + efi_guid consoleControlProtocolGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID; + efi_console_control_protocol* consoleControl = NULL; + + efi_status status = kSystemTable->BootServices->LocateProtocol( + &consoleControlProtocolGUID, NULL, (void**)&consoleControl); + + // Some EFI implementations boot up in an EFI graphics mode (Apple) + // If this protocol doesn't exist, we can assume we're already in text mode. + if (status != EFI_SUCCESS || consoleControl == NULL) { + TRACE("EFI Console Control not found. Skipping.\n"); + return; + } + + TRACE("Located EFI Console Control. Setting EFI %s mode...\n", + graphics ? "graphics" : "text"); + + if (graphics) { + status = consoleControl->SetMode(consoleControl, + EfiConsoleControlScreenGraphics); + } else { + status = consoleControl->SetMode(consoleControl, + EfiConsoleControlScreenText); + } + + TRACE("Setting EFI %s mode was%s successful.\n", + graphics ? "graphics" : "text", (status == EFI_SUCCESS) ? "" : " not"); +} + + status_t console_init(void) { + console_control(true); update_screen_size(); console_hide_cursor(); console_clear_screen(); @@ -243,6 +288,7 @@ console_check_boot_keys(void) extern "C" void platform_switch_to_text_mode(void) { + console_control(false); kSystemTable->ConOut->Reset(kSystemTable->ConOut, false); kSystemTable->ConOut->SetMode(kSystemTable->ConOut, sScreenMode); }