OvmfPkg/PlatformBootManagerLib: Register boot options and hot keys

The patch registers "Enter" key as the continue key (hot key to skip
the boot timeout wait), maps "F2" key to UI, and registers Shell
boot option.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
index 3432e02..ed90a45 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -88,6 +88,111 @@
   VOID

   );

 

+VOID

+PlatformRegisterFvBootOption (

+  EFI_GUID                         *FileGuid,

+  CHAR16                           *Description,

+  UINT32                           Attributes

+  )

+{

+  EFI_STATUS                        Status;

+  INTN                              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 = DevicePathFromHandle (LoadedImage->DeviceHandle);

+  ASSERT (DevicePath != NULL);

+  DevicePath = AppendDevicePathNode (

+                 DevicePath,

+                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode

+                 );

+  ASSERT (DevicePath != NULL);

+

+  Status = EfiBootManagerInitializeLoadOption (

+             &NewOption,

+             LoadOptionNumberUnassigned,

+             LoadOptionTypeBoot,

+             Attributes,

+             Description,

+             DevicePath,

+             NULL,

+             0

+             );

+  ASSERT_EFI_ERROR (Status);

+  FreePool (DevicePath);

+

+  BootOptions = EfiBootManagerGetLoadOptions (

+                  &BootOptionCount, LoadOptionTypeBoot

+                  );

+

+  OptionIndex = EfiBootManagerFindLoadOption (

+                  &NewOption, BootOptions, BootOptionCount

+                  );

+

+  if (OptionIndex == -1) {

+    Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);

+    ASSERT_EFI_ERROR (Status);

+  }

+  EfiBootManagerFreeLoadOption (&NewOption);

+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);

+}

+

+VOID

+PlatformRegisterOptionsAndKeys (

+  VOID

+  )

+{

+  EFI_STATUS                   Status;

+  EFI_INPUT_KEY                Enter;

+  EFI_INPUT_KEY                F2;

+  EFI_INPUT_KEY                Esc;

+  EFI_BOOT_MANAGER_LOAD_OPTION BootOption;

+

+  //

+  // Register ENTER as CONTINUE key

+  //

+  Enter.ScanCode    = SCAN_NULL;

+  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;

+  Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Map F2 to Boot Manager Menu

+  //

+  F2.ScanCode     = SCAN_F2;

+  F2.UnicodeChar  = CHAR_NULL;

+  Esc.ScanCode    = SCAN_ESC;

+  Esc.UnicodeChar = CHAR_NULL;

+  Status = EfiBootManagerGetBootManagerMenu (&BootOption);

+  ASSERT_EFI_ERROR (Status);

+  Status = EfiBootManagerAddKeyOptionVariable (

+             NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL

+             );

+  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);

+  Status = EfiBootManagerAddKeyOptionVariable (

+             NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL

+             );

+  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);

+  //

+  // Register UEFI Shell

+  //

+  PlatformRegisterFvBootOption (

+    PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE

+    );

+}

+

 EFI_STATUS

 EFIAPI

 ConnectRootBridge (

@@ -167,6 +272,8 @@
 

   PlatformInitializeConsole (gPlatformConsole);

   PcdSet16 (PcdPlatformBootTimeOut, GetFrontPageTimeoutFromQemu ());

+

+  PlatformRegisterOptionsAndKeys ();

 }

 

 

diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
index 8e11d44..b14410c 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
@@ -55,6 +55,7 @@
 #include <Protocol/PciRootBridgeIo.h>

 #include <Protocol/S3SaveState.h>

 #include <Protocol/DxeSmmReadyToLock.h>

+#include <Protocol/LoadedImage.h>

 

 #include <Guid/Acpi.h>

 #include <Guid/SmBios.h>

diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
index 76ebba2..5f6421d 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -60,6 +60,7 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable

   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId

   gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut

+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile

 

 [Pcd.IA32, Pcd.X64]

   gEfiMdePkgTokenSpaceGuid.PcdFSBClock

@@ -69,6 +70,7 @@
   gEfiPciRootBridgeIoProtocolGuid

   gEfiS3SaveStateProtocolGuid                   # PROTOCOL SOMETIMES_CONSUMED

   gEfiDxeSmmReadyToLockProtocolGuid             # PROTOCOL SOMETIMES_PRODUCED

+  gEfiLoadedImageProtocolGuid                   # PROTOCOL SOMETIMES_PRODUCED

 

 [Guids]

   gEfiEndOfDxeEventGroupGuid