summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c')
-rw-r--r--src/VBox/Devices/EFI/Firmware/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c265
1 files changed, 265 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c b/src/VBox/Devices/EFI/Firmware/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
new file mode 100644
index 00000000..0e95c4c8
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
@@ -0,0 +1,265 @@
+/** @file
+ This file include all platform action which can be customized
+ by IBV/OEM.
+
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlatformBootManager.h"
+#include "PlatformConsole.h"
+
+VOID
+InstallReadyToLock (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
+
+ DEBUG((DEBUG_INFO,"InstallReadyToLock entering......\n"));
+ //
+ // Inform the SMM infrastructure that we're entering BDS and may run 3rd party code hereafter
+ // Since PI1.2.1, we need signal EndOfDxe as ExitPmAuth
+ //
+ EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
+ DEBUG((DEBUG_INFO,"All EndOfDxe callbacks have returned successfully\n"));
+
+ //
+ // Install DxeSmmReadyToLock protocol in order to lock SMM
+ //
+ Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **) &SmmAccess);
+ if (!EFI_ERROR (Status)) {
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gEfiDxeSmmReadyToLockProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ DEBUG((DEBUG_INFO,"InstallReadyToLock end\n"));
+ return;
+}
+
+/**
+ Return the index of the load option in the load option array.
+
+ The function consider two load options are equal when the
+ OptionType, Attributes, Description, FilePath and OptionalData are equal.
+
+ @param Key Pointer to the load option to be found.
+ @param Array Pointer to the array of load options to be found.
+ @param Count Number of entries in the Array.
+
+ @retval -1 Key wasn't found in the Array.
+ @retval 0 ~ Count-1 The index of the Key in the Array.
+**/
+INTN
+PlatformFindLoadOption (
+ IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key,
+ IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array,
+ IN UINTN Count
+)
+{
+ UINTN Index;
+
+ for (Index = 0; Index < Count; Index++) {
+ if ((Key->OptionType == Array[Index].OptionType) &&
+ (Key->Attributes == Array[Index].Attributes) &&
+ (StrCmp (Key->Description, Array[Index].Description) == 0) &&
+ (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) &&
+ (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&
+ (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 0)) {
+ return (INTN) Index;
+ }
+ }
+
+ return -1;
+}
+
+/**
+ Register a boot option using a file GUID in the FV.
+
+ @param FileGuid The file GUID name in FV.
+ @param Description The boot option description.
+ @param Attributes The attributes used for the boot option loading.
+**/
+VOID
+PlatformRegisterFvBootOption (
+ EFI_GUID *FileGuid,
+ CHAR16 *Description,
+ UINT32 Attributes
+)
+{
+ EFI_STATUS Status;
+ UINTN OptionIndex;
+ EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
+ UINTN BootOptionCount;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ Status = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
+ ASSERT_EFI_ERROR (Status);
+
+ EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+ DevicePath = AppendDevicePathNode (
+ DevicePathFromHandle (LoadedImage->DeviceHandle),
+ (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
+ );
+
+ Status = EfiBootManagerInitializeLoadOption (
+ &NewOption,
+ LoadOptionNumberUnassigned,
+ LoadOptionTypeBoot,
+ Attributes,
+ Description,
+ DevicePath,
+ NULL,
+ 0
+ );
+ if (!EFI_ERROR (Status)) {
+ BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
+
+ OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount);
+
+ if (OptionIndex == -1) {
+ Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1);
+ ASSERT_EFI_ERROR (Status);
+ }
+ EfiBootManagerFreeLoadOption (&NewOption);
+ EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+ }
+}
+
+/**
+ Do the platform specific action before the console is connected.
+
+ Such as:
+ Update console variable;
+ Register new Driver#### or Boot####;
+ Signal ReadyToLock event.
+**/
+VOID
+EFIAPI
+PlatformBootManagerBeforeConsole (
+ VOID
+)
+{
+ EFI_INPUT_KEY Enter;
+ EFI_INPUT_KEY F2;
+ EFI_INPUT_KEY Down;
+ EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
+
+ //
+ // Register ENTER as CONTINUE key
+ //
+ Enter.ScanCode = SCAN_NULL;
+ Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
+ EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
+
+ //
+ // Map F2 to Boot Manager Menu
+ //
+ F2.ScanCode = SCAN_F2;
+ F2.UnicodeChar = CHAR_NULL;
+ EfiBootManagerGetBootManagerMenu (&BootOption);
+ EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL);
+
+ //
+ // Also add Down key to Boot Manager Menu since some serial terminals don't support F2 key.
+ //
+ Down.ScanCode = SCAN_DOWN;
+ Down.UnicodeChar = CHAR_NULL;
+ EfiBootManagerGetBootManagerMenu (&BootOption);
+ EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &Down, NULL);
+
+ //
+ // Install ready to lock.
+ // This needs to be done before option rom dispatched.
+ //
+ InstallReadyToLock ();
+
+ //
+ // Dispatch deferred images after EndOfDxe event and ReadyToLock installation.
+ //
+ EfiBootManagerDispatchDeferredImages ();
+
+ PlatformConsoleInit ();
+}
+
+/**
+ Do the platform specific action after the console is connected.
+
+ Such as:
+ Dynamically switch output mode;
+ Signal console ready platform customized event;
+ Run diagnostics like memory testing;
+ Connect certain devices;
+ Dispatch additional option roms.
+**/
+VOID
+EFIAPI
+PlatformBootManagerAfterConsole (
+ VOID
+)
+{
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL White;
+
+ Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
+ White.Blue = White.Green = White.Red = White.Reserved = 0xFF;
+
+ EfiBootManagerConnectAll ();
+ EfiBootManagerRefreshAllBootOption ();
+
+ //
+ // Register UEFI Shell
+ //
+ PlatformRegisterFvBootOption (PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE);
+
+ Print (
+ L"\n"
+ L"F2 or Down to enter Boot Manager Menu.\n"
+ L"ENTER to boot directly.\n"
+ L"\n"
+ );
+
+}
+
+/**
+ This function is called each second during the boot manager waits the timeout.
+
+ @param TimeoutRemain The remaining timeout.
+**/
+VOID
+EFIAPI
+PlatformBootManagerWaitCallback (
+ UINT16 TimeoutRemain
+)
+{
+ return;
+}
+
+/**
+ The function is called when no boot option could be launched,
+ including platform recovery options and options pointing to applications
+ built into firmware volumes.
+
+ If this function returns, BDS attempts to enter an infinite loop.
+**/
+VOID
+EFIAPI
+PlatformBootManagerUnableToBoot (
+ VOID
+ )
+{
+ return;
+}
+