summaryrefslogtreecommitdiffstats
path: root/EmbeddedPkg/Drivers
diff options
context:
space:
mode:
Diffstat (limited to 'EmbeddedPkg/Drivers')
-rw-r--r--EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.c293
-rw-r--r--EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.h31
-rw-r--r--EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.inf62
-rw-r--r--EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefHii.uni27
-rw-r--r--EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefHii.vfr51
5 files changed, 464 insertions, 0 deletions
diff --git a/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.c b/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.c
new file mode 100644
index 0000000000..996d1a6036
--- /dev/null
+++ b/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.c
@@ -0,0 +1,293 @@
+/** @file
+*
+* Copyright (c) 2017, Linaro, Ltd. All rights reserved.
+*
+* This program and the accompanying materials are licensed and made available
+* under the terms and conditions of the BSD License which accompanies this
+* distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Uefi.h>
+#include <IndustryStandard/Acpi.h>
+#include <libfdt.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <Protocol/AcpiTable.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+
+#include "ConsolePrefDxe.h"
+
+#define SPCR_SIG EFI_ACPI_2_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE
+
+extern UINT8 ConsolePrefHiiBin[];
+extern UINT8 ConsolePrefDxeStrings[];
+
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+STATIC HII_VENDOR_DEVICE_PATH mConsolePrefDxeVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ CONSOLE_PREF_FORMSET_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8) (END_DEVICE_PATH_LENGTH),
+ (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+STATIC EFI_EVENT mReadyToBootEvent;
+
+STATIC
+EFI_STATUS
+InstallHiiPages (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+ EFI_HANDLE DriverHandle;
+
+ DriverHandle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (&DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mConsolePrefDxeVendorDevicePath,
+ NULL);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ HiiHandle = HiiAddPackages (&gConsolePrefFormSetGuid,
+ DriverHandle,
+ ConsolePrefDxeStrings,
+ ConsolePrefHiiBin,
+ NULL);
+
+ if (HiiHandle == NULL) {
+ gBS->UninstallMultipleProtocolInterfaces (DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mConsolePrefDxeVendorDevicePath,
+ NULL);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+RemoveDtStdoutPath (
+ VOID
+)
+{
+ VOID *Dtb;
+ INT32 Node;
+ INT32 Error;
+ EFI_STATUS Status;
+
+ Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &Dtb);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "%a: could not retrieve DT blob - %r\n", __FUNCTION__,
+ Status));
+ return;
+ }
+
+ Node = fdt_path_offset (Dtb, "/chosen");
+ if (Node < 0) {
+ return;
+ }
+
+ Error = fdt_delprop (Dtb, Node, "stdout-path");
+ if (Error) {
+ DEBUG ((DEBUG_INFO, "%a: Failed to delete 'stdout-path' property: %a\n",
+ __FUNCTION__, fdt_strerror (Error)));
+ }
+}
+
+STATIC
+VOID
+RemoveSpcrTable (
+ VOID
+ )
+{
+ EFI_ACPI_SDT_PROTOCOL *Sdt;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
+ EFI_STATUS Status;
+ UINTN TableIndex;
+ EFI_ACPI_SDT_HEADER *TableHeader;
+ EFI_ACPI_TABLE_VERSION TableVersion;
+ UINTN TableKey;
+
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL,
+ (VOID **)&AcpiTable);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&Sdt);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ TableIndex = 0;
+ TableKey = 0;
+ TableHeader = NULL;
+
+ do {
+ Status = Sdt->GetAcpiTable (TableIndex++, &TableHeader, &TableVersion,
+ &TableKey);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (TableHeader->Signature != SPCR_SIG) {
+ continue;
+ }
+
+ Status = AcpiTable->UninstallAcpiTable (AcpiTable, TableKey);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "%a: failed to uninstall SPCR table - %r\n",
+ __FUNCTION__, Status));
+ }
+ break;
+ } while (TRUE);
+}
+
+STATIC
+VOID
+OnReadyToBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ CONSOLE_PREF_VARSTORE_DATA ConsolePref;
+ UINTN BufferSize;
+ EFI_STATUS Status;
+ VOID *Gop;
+
+ BufferSize = sizeof (ConsolePref);
+ Status = gRT->GetVariable (CONSOLE_PREF_VARIABLE_NAME,
+ &gConsolePrefFormSetGuid, NULL, &BufferSize, &ConsolePref);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR,
+ "%a: variable '%s' could not be read - bailing!\n", __FUNCTION__,
+ CONSOLE_PREF_VARIABLE_NAME));
+ return;
+ }
+
+ if (ConsolePref.Console == CONSOLE_PREF_SERIAL) {
+ DEBUG ((DEBUG_INFO,
+ "%a: serial console preferred - doing nothing\n", __FUNCTION__));
+ return;
+ }
+
+ //
+ // Check if any GOP instances exist: if so, disable stdout-path and SPCR
+ //
+ Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, NULL, &Gop);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO,
+ "%a: no GOP instances found - doing nothing (%r)\n", __FUNCTION__,
+ Status));
+ return;
+ }
+
+ RemoveDtStdoutPath ();
+ RemoveSpcrTable ();
+}
+
+/**
+ The entry point for ConsolePrefDxe driver.
+
+ @param[in] ImageHandle The image handle of the driver.
+ @param[in] SystemTable The system table.
+
+ @retval EFI_ALREADY_STARTED The driver already exists in system.
+ @retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of
+ resources.
+ @retval EFI_SUCCES All the related protocols are installed on
+ the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+ConsolePrefDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ CONSOLE_PREF_VARSTORE_DATA ConsolePref;
+ UINTN BufferSize;
+
+ //
+ // Get the current console preference from the ConsolePref variable.
+ //
+ BufferSize = sizeof (ConsolePref);
+ Status = gRT->GetVariable (CONSOLE_PREF_VARIABLE_NAME,
+ &gConsolePrefFormSetGuid, NULL, &BufferSize, &ConsolePref);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO,
+ "%a: no console preference found, defaulting to graphical\n",
+ __FUNCTION__));
+ ConsolePref.Console = CONSOLE_PREF_GRAPHICAL;
+ }
+
+ if (!EFI_ERROR (Status) &&
+ ConsolePref.Console != CONSOLE_PREF_GRAPHICAL &&
+ ConsolePref.Console != CONSOLE_PREF_SERIAL) {
+ DEBUG ((DEBUG_WARN, "%a: invalid value for %s, defaulting to graphical\n",
+ __FUNCTION__, CONSOLE_PREF_VARIABLE_NAME));
+ ConsolePref.Console = CONSOLE_PREF_GRAPHICAL;
+ Status = EFI_INVALID_PARAMETER; // trigger setvar below
+ }
+
+ //
+ // Write the newly selected value back to the variable store.
+ //
+ if (EFI_ERROR (Status)) {
+ ZeroMem (&ConsolePref.Reserved, sizeof (ConsolePref.Reserved));
+ Status = gRT->SetVariable (CONSOLE_PREF_VARIABLE_NAME,
+ &gConsolePrefFormSetGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (ConsolePref), &ConsolePref);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: gRT->SetVariable () failed - %r\n",
+ __FUNCTION__, Status));
+ return Status;
+ }
+ }
+
+ Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
+ OnReadyToBoot, NULL, &gEfiEventReadyToBootGuid,
+ &mReadyToBootEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ return InstallHiiPages ();
+}
diff --git a/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.h b/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.h
new file mode 100644
index 0000000000..8315e739d3
--- /dev/null
+++ b/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.h
@@ -0,0 +1,31 @@
+/** @file
+*
+* Copyright (c) 2017, Linaro Limited. All rights reserved.
+*
+* This program and the accompanying materials are licensed and made available
+* under the terms and conditions of the BSD License which accompanies this
+* distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __CONSOLE_PREF_DXE_H__
+#define __CONSOLE_PREF_DXE_H__
+
+#include <Guid/HiiPlatformSetupFormset.h>
+#include <Guid/ConsolePrefFormSet.h>
+
+#define CONSOLE_PREF_GRAPHICAL 0x0
+#define CONSOLE_PREF_SERIAL 0x1
+
+#define CONSOLE_PREF_VARIABLE_NAME L"ConsolePref"
+
+typedef struct {
+ UINT8 Console;
+ UINT8 Reserved[3];
+} CONSOLE_PREF_VARSTORE_DATA;
+
+#endif
diff --git a/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.inf b/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.inf
new file mode 100644
index 0000000000..d8b412b920
--- /dev/null
+++ b/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.inf
@@ -0,0 +1,62 @@
+## @file
+#
+# Copyright (c) 2017, Linaro, Ltd. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made
+# available under the terms and conditions of the BSD License which
+# accompanies this distribution. The full text of the license may be
+# found at http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+# IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010019
+ BASE_NAME = ConsolePrefDxe
+ FILE_GUID = bbe2668c-0efc-46fb-9137-4f2da8f419f3
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ConsolePrefDxeEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ ConsolePrefDxe.c
+ ConsolePrefHii.vfr
+ ConsolePrefHii.uni
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ FdtLib
+ HiiLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+ UefiRuntimeServicesTableLib
+
+[Guids]
+ gConsolePrefFormSetGuid
+ gFdtTableGuid
+ gEfiEventReadyToBootGuid
+
+[Protocols]
+ gEfiAcpiTableProtocolGuid
+ gEfiAcpiSdtProtocolGuid
+ gEfiGraphicsOutputProtocolGuid
+
+[Depex]
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid
diff --git a/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefHii.uni b/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefHii.uni
new file mode 100644
index 0000000000..947cf70a48
--- /dev/null
+++ b/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefHii.uni
@@ -0,0 +1,27 @@
+/** @file
+*
+* Copyright (c) 2017, Linaro, Ltd. All rights reserved.
+*
+* This program and the accompanying materials are licensed and made available
+* under the terms and conditions of the BSD License which accompanies this
+* distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#langdef en-US "English"
+
+#string STR_FORM_SET_TITLE #language en-US "Console Preference Selection"
+#string STR_FORM_SET_TITLE_HELP #language en-US "Press <Enter> to choose between graphical and serial console."
+
+#string STR_MAIN_FORM_TITLE #language en-US "Console Preference Selection"
+#string STR_NULL_STRING #language en-US ""
+
+#string STR_CONSOLE_PREF_SELECT_PROMPT #language en-US "Preferred console"
+#string STR_CONSOLE_PREF_SELECT_HELP #language en-US "Select the preferred console if both graphical and serial are available."
+
+#string STR_CONSOLE_PREF_GRAPHICAL #language en-US "Graphical"
+#string STR_CONSOLE_PREF_SERIAL #language en-US "Serial"
diff --git a/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefHii.vfr b/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefHii.vfr
new file mode 100644
index 0000000000..a1e603abf0
--- /dev/null
+++ b/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefHii.vfr
@@ -0,0 +1,51 @@
+/** @file
+*
+* Copyright (c) 2017, Linaro, Ltd. All rights reserved.
+*
+* This program and the accompanying materials are licensed and made available
+* under the terms and conditions of the BSD License which accompanies this
+* distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "ConsolePrefDxe.h"
+
+//
+// EFI Variable attributes
+//
+#define EFI_VARIABLE_NON_VOLATILE 0x00000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
+#define EFI_VARIABLE_READ_ONLY 0x00000008
+
+formset
+ guid = CONSOLE_PREF_FORMSET_GUID,
+ title = STRING_TOKEN(STR_FORM_SET_TITLE),
+ help = STRING_TOKEN(STR_FORM_SET_TITLE_HELP),
+ classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,
+
+ efivarstore CONSOLE_PREF_VARSTORE_DATA,
+ attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, // EFI variable attributes
+ name = ConsolePref,
+ guid = CONSOLE_PREF_FORMSET_GUID;
+
+ form formid = 0x1000,
+ title = STRING_TOKEN(STR_MAIN_FORM_TITLE);
+
+ oneof varid = ConsolePref.Console,
+ prompt = STRING_TOKEN(STR_CONSOLE_PREF_SELECT_PROMPT),
+ help = STRING_TOKEN(STR_CONSOLE_PREF_SELECT_HELP),
+ flags = NUMERIC_SIZE_1 | INTERACTIVE,
+ option text = STRING_TOKEN(STR_CONSOLE_PREF_GRAPHICAL), value = CONSOLE_PREF_GRAPHICAL, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_CONSOLE_PREF_SERIAL), value = CONSOLE_PREF_SERIAL, flags = 0;
+ endoneof;
+
+ subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+ endform;
+
+endformset;