ArmPkg/PlatformBootManagerLib: load platform boot options
authorHaojian Zhuang <haojian.zhuang@linaro.org>
Mon, 23 Apr 2018 06:21:54 +0000 (14:21 +0800)
committerLeif Lindholm <leif.lindholm@linaro.org>
Tue, 5 Jun 2018 14:50:11 +0000 (15:50 +0100)
Make platform driver to create predefined boot options and related
hot keys.

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
ArmPkg/Library/PlatformBootManagerLib/PlatformBm.c
ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf

index 61ab61ccc7801ba802dbe5366f9ff76c2fd0d4a7..3456a71fbb9cd12912a443abc1907d2015cb0944 100644 (file)
@@ -30,6 +30,7 @@
 #include <Protocol/LoadedImage.h>\r
 #include <Protocol/PciIo.h>\r
 #include <Protocol/PciRootBridgeIo.h>\r
 #include <Protocol/LoadedImage.h>\r
 #include <Protocol/PciIo.h>\r
 #include <Protocol/PciRootBridgeIo.h>\r
+#include <Protocol/PlatformBootManager.h>\r
 #include <Guid/EventGroup.h>\r
 #include <Guid/TtyTerm.h>\r
 \r
 #include <Guid/EventGroup.h>\r
 #include <Guid/TtyTerm.h>\r
 \r
@@ -390,6 +391,106 @@ PlatformRegisterFvBootOption (
 }\r
 \r
 \r
 }\r
 \r
 \r
+STATIC\r
+VOID\r
+GetPlatformOptions (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  EFI_BOOT_MANAGER_LOAD_OPTION    *CurrentBootOptions;\r
+  EFI_BOOT_MANAGER_LOAD_OPTION    *BootOptions;\r
+  EFI_INPUT_KEY                   *BootKeys;\r
+  PLATFORM_BOOT_MANAGER_PROTOCOL  *PlatformBootManager;\r
+  UINTN                           CurrentBootOptionCount;\r
+  UINTN                           Index;\r
+  UINTN                           BootCount;\r
+\r
+  Status = gBS->LocateProtocol (&gPlatformBootManagerProtocolGuid, NULL,\r
+                  (VOID **)&PlatformBootManager);\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+  Status = PlatformBootManager->GetPlatformBootOptionsAndKeys (\r
+                                  &BootCount,\r
+                                  &BootOptions,\r
+                                  &BootKeys\r
+                                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+  //\r
+  // Fetch the existent boot options. If there are none, CurrentBootCount\r
+  // will be zeroed.\r
+  //\r
+  CurrentBootOptions = EfiBootManagerGetLoadOptions (\r
+                         &CurrentBootOptionCount,\r
+                         LoadOptionTypeBoot\r
+                         );\r
+  //\r
+  // Process the platform boot options.\r
+  //\r
+  for (Index = 0; Index < BootCount; Index++) {\r
+    INTN    Match;\r
+    UINTN   BootOptionNumber;\r
+\r
+    //\r
+    // If there are any preexistent boot options, and the subject platform boot\r
+    // option is already among them, then don't try to add it. Just get its\r
+    // assigned boot option number so we can associate a hotkey with it. Note\r
+    // that EfiBootManagerFindLoadOption() deals fine with (CurrentBootOptions\r
+    // == NULL) if (CurrentBootCount == 0).\r
+    //\r
+    Match = EfiBootManagerFindLoadOption (\r
+              &BootOptions[Index],\r
+              CurrentBootOptions,\r
+              CurrentBootOptionCount\r
+              );\r
+    if (Match >= 0) {\r
+      BootOptionNumber = CurrentBootOptions[Match].OptionNumber;\r
+    } else {\r
+      //\r
+      // Add the platform boot options as a new one, at the end of the boot\r
+      // order. Note that if the platform provided this boot option with an\r
+      // unassigned option number, then the below function call will assign a\r
+      // number.\r
+      //\r
+      Status = EfiBootManagerAddLoadOptionVariable (\r
+                 &BootOptions[Index],\r
+                 MAX_UINTN\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        DEBUG ((DEBUG_ERROR, "%a: failed to register \"%s\": %r\n",\r
+          __FUNCTION__, BootOptions[Index].Description, Status));\r
+        continue;\r
+      }\r
+      BootOptionNumber = BootOptions[Index].OptionNumber;\r
+    }\r
+\r
+    //\r
+    // Register a hotkey with the boot option, if requested.\r
+    //\r
+    if (BootKeys[Index].UnicodeChar == L'\0') {\r
+      continue;\r
+    }\r
+\r
+    Status = EfiBootManagerAddKeyOptionVariable (\r
+               NULL,\r
+               BootOptionNumber,\r
+               0,\r
+               BootKeys[Index],\r
+               NULL\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_ERROR, "%a: failed to register hotkey for \"%s\": %r\n",\r
+        __FUNCTION__, BootOptions[Index].Description, Status));\r
+    }\r
+  }\r
+  EfiBootManagerFreeLoadOptions (CurrentBootOptions, CurrentBootOptionCount);\r
+  EfiBootManagerFreeLoadOptions (BootOptions, BootCount);\r
+  FreePool (BootKeys);\r
+}\r
+\r
 STATIC\r
 VOID\r
 PlatformRegisterOptionsAndKeys (\r
 STATIC\r
 VOID\r
 PlatformRegisterOptionsAndKeys (\r
@@ -402,6 +503,8 @@ PlatformRegisterOptionsAndKeys (
   EFI_INPUT_KEY                Esc;\r
   EFI_BOOT_MANAGER_LOAD_OPTION BootOption;\r
 \r
   EFI_INPUT_KEY                Esc;\r
   EFI_BOOT_MANAGER_LOAD_OPTION BootOption;\r
 \r
+  GetPlatformOptions ();\r
+\r
   //\r
   // Register ENTER as CONTINUE key\r
   //\r
   //\r
   // Register ENTER as CONTINUE key\r
   //\r
index 71f1d04a87ee870b55aa820aed675c546e2151ff..e8cbb10dabdd257605e84e8e926416b557517c92 100644 (file)
@@ -35,6 +35,7 @@
   PlatformBm.c\r
 \r
 [Packages]\r
   PlatformBm.c\r
 \r
 [Packages]\r
+  EmbeddedPkg/EmbeddedPkg.dec\r
   MdeModulePkg/MdeModulePkg.dec\r
   MdePkg/MdePkg.dec\r
   ShellPkg/ShellPkg.dec\r
   MdeModulePkg/MdeModulePkg.dec\r
   MdePkg/MdePkg.dec\r
   ShellPkg/ShellPkg.dec\r
@@ -84,3 +85,4 @@
   gEfiPciRootBridgeIoProtocolGuid\r
   gEfiSimpleFileSystemProtocolGuid\r
   gEsrtManagementProtocolGuid\r
   gEfiPciRootBridgeIoProtocolGuid\r
   gEfiSimpleFileSystemProtocolGuid\r
   gEsrtManagementProtocolGuid\r
+  gPlatformBootManagerProtocolGuid\r