]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg: Enable PlatformRecovery in BdsDxe driver
authorRuiyu Ni <ruiyu.ni@intel.com>
Tue, 17 Nov 2015 10:15:09 +0000 (10:15 +0000)
committerniruiyu <niruiyu@Edk2>
Tue, 17 Nov 2015 10:15:09 +0000 (10:15 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Sunny Wang <sunnywang@hpe.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18863 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/BdsDxe/Bds.h
MdeModulePkg/Universal/BdsDxe/BdsEntry.c

index 2171d14791ea3ef1efa3c04805c2a5cdce4ae294..ac54482b76dd27683ff6355efbaaf824c8f26d56 100644 (file)
@@ -24,9 +24,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/Bds.h>\r
 #include <Protocol/LoadedImage.h>\r
 #include <Protocol/VariableLock.h>\r
-#include <Protocol/BlockIo.h>\r
-#include <Protocol/LoadFile.h>\r
-#include <Protocol/SimpleFileSystem.h>\r
 \r
 #include <Library/UefiDriverEntryPoint.h>\r
 #include <Library/DebugLib.h>\r
index b632ada5f6c9cf217b8bb936fc0a6a3494702a14..f06684c96ae4d1ba00edc2d5e75ce6ad26e06395 100644 (file)
@@ -51,10 +51,10 @@ CHAR16  *mReadOnlyVariables[] = {
 CHAR16 *mBdsLoadOptionName[] = {\r
   L"Driver",\r
   L"SysPrep",\r
-  L"Boot"\r
+  L"Boot",\r
+  L"PlatformRecovery"\r
 };\r
 \r
-CHAR16  mRecoveryBoot[] = L"Recovery Boot";\r
 /**\r
   Event to Connect ConIn.\r
 \r
@@ -121,187 +121,6 @@ BdsInitialize (
   return Status;\r
 }\r
 \r
-/**\r
-  Emuerate all possible bootable medias in the following order:\r
-  1. Removable BlockIo            - The boot option only points to the removable media\r
-                                    device, like USB key, DVD, Floppy etc.\r
-  2. Fixed BlockIo                - The boot option only points to a Fixed blockIo device,\r
-                                    like HardDisk.\r
-  3. Non-BlockIo SimpleFileSystem - The boot option points to a device supporting\r
-                                    SimpleFileSystem Protocol, but not supporting BlockIo\r
-                                    protocol.\r
-  4. LoadFile                     - The boot option points to the media supporting \r
-                                    LoadFile protocol.\r
-  Reference: UEFI Spec chapter 3.3 Boot Option Variables Default Boot Behavior\r
-\r
-  @param BootOptionCount   Return the boot option count which has been found.\r
-\r
-  @retval   Pointer to the boot option array.\r
-**/\r
-EFI_BOOT_MANAGER_LOAD_OPTION *\r
-BdsEnumerateBootOptions (\r
-  UINTN                                 *BootOptionCount\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  EFI_BOOT_MANAGER_LOAD_OPTION          *BootOptions;\r
-  UINTN                                 HandleCount;\r
-  EFI_HANDLE                            *Handles;\r
-  EFI_BLOCK_IO_PROTOCOL                 *BlkIo;\r
-  UINTN                                 Removable;\r
-  UINTN                                 Index;\r
-\r
-  ASSERT (BootOptionCount != NULL);\r
-\r
-  *BootOptionCount = 0;\r
-  BootOptions      = NULL;\r
-\r
-  //\r
-  // Parse removable block io followed by fixed block io\r
-  //\r
-  gBS->LocateHandleBuffer (\r
-         ByProtocol,\r
-         &gEfiBlockIoProtocolGuid,\r
-         NULL,\r
-         &HandleCount,\r
-         &Handles\r
-         );\r
-\r
-  for (Removable = 0; Removable < 2; Removable++) {\r
-    for (Index = 0; Index < HandleCount; Index++) {\r
-      Status = gBS->HandleProtocol (\r
-                      Handles[Index],\r
-                      &gEfiBlockIoProtocolGuid,\r
-                      (VOID **) &BlkIo\r
-                      );\r
-      if (EFI_ERROR (Status)) {\r
-        continue;\r
-      }\r
-\r
-      //\r
-      // Skip the logical partitions\r
-      //\r
-      if (BlkIo->Media->LogicalPartition) {\r
-        continue;\r
-      }\r
-\r
-      //\r
-      // Skip the fixed block io then the removable block io\r
-      //\r
-      if (BlkIo->Media->RemovableMedia == ((Removable == 0) ? FALSE : TRUE)) {\r
-        continue;\r
-      }\r
-\r
-      BootOptions = ReallocatePool (\r
-                      sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),\r
-                      sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),\r
-                      BootOptions\r
-                      );\r
-      ASSERT (BootOptions != NULL);\r
-\r
-      Status = EfiBootManagerInitializeLoadOption (\r
-                 &BootOptions[(*BootOptionCount)++],\r
-                 LoadOptionNumberUnassigned,\r
-                 LoadOptionTypeBoot,\r
-                 LOAD_OPTION_ACTIVE,\r
-                 mRecoveryBoot,\r
-                 DevicePathFromHandle (Handles[Index]),\r
-                 NULL,\r
-                 0\r
-                 );\r
-      ASSERT_EFI_ERROR (Status);\r
-    }\r
-  }\r
-\r
-  if (HandleCount != 0) {\r
-    FreePool (Handles);\r
-  }\r
-\r
-  //\r
-  // Parse simple file system not based on block io\r
-  //\r
-  gBS->LocateHandleBuffer (\r
-         ByProtocol,\r
-         &gEfiSimpleFileSystemProtocolGuid,\r
-         NULL,\r
-         &HandleCount,\r
-         &Handles\r
-         );\r
-  for (Index = 0; Index < HandleCount; Index++) {\r
-    Status = gBS->HandleProtocol (\r
-                    Handles[Index],\r
-                    &gEfiBlockIoProtocolGuid,\r
-                    (VOID **) &BlkIo\r
-                    );\r
-     if (!EFI_ERROR (Status)) {\r
-      //\r
-      //  Skip if the file system handle supports a BlkIo protocol, which we've handled in above\r
-      //\r
-      continue;\r
-    }\r
-    BootOptions = ReallocatePool (\r
-                    sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),\r
-                    sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),\r
-                    BootOptions\r
-                    );\r
-    ASSERT (BootOptions != NULL);\r
-\r
-    Status = EfiBootManagerInitializeLoadOption (\r
-               &BootOptions[(*BootOptionCount)++],\r
-               LoadOptionNumberUnassigned,\r
-               LoadOptionTypeBoot,\r
-               LOAD_OPTION_ACTIVE,\r
-               mRecoveryBoot,\r
-               DevicePathFromHandle (Handles[Index]),\r
-               NULL,\r
-               0\r
-               );\r
-    ASSERT_EFI_ERROR (Status);\r
-  }\r
-\r
-  if (HandleCount != 0) {\r
-    FreePool (Handles);\r
-  }\r
-\r
-  //\r
-  // Parse load file, assuming UEFI Network boot option\r
-  //\r
-  gBS->LocateHandleBuffer (\r
-         ByProtocol,\r
-         &gEfiLoadFileProtocolGuid,\r
-         NULL,\r
-         &HandleCount,\r
-         &Handles\r
-         );\r
-  for (Index = 0; Index < HandleCount; Index++) {\r
-\r
-    BootOptions = ReallocatePool (\r
-                    sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),\r
-                    sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),\r
-                    BootOptions\r
-                    );\r
-    ASSERT (BootOptions != NULL);\r
-\r
-    Status = EfiBootManagerInitializeLoadOption (\r
-               &BootOptions[(*BootOptionCount)++],\r
-               LoadOptionNumberUnassigned,\r
-               LoadOptionTypeBoot,\r
-               LOAD_OPTION_ACTIVE,\r
-               mRecoveryBoot,\r
-               DevicePathFromHandle (Handles[Index]),\r
-               NULL,\r
-               0\r
-               );\r
-    ASSERT_EFI_ERROR (Status);\r
-  }\r
-\r
-  if (HandleCount != 0) {\r
-    FreePool (Handles);\r
-  }\r
-\r
-  return BootOptions;\r
-}\r
-\r
 /**\r
   Function waits for a given event to fire, or for an optional timeout to expire.\r
 \r
@@ -445,14 +264,16 @@ BdsWait (
 \r
   @param BootOptions       Input boot option array.\r
   @param BootOptionCount   Input boot option count.\r
+  @param BootManagerMenu   Input boot manager menu.\r
 \r
   @retval TRUE  Successfully boot one of the boot options.\r
   @retval FALSE Failed boot any of the boot options.\r
 **/\r
 BOOLEAN\r
-BootAllBootOptions (\r
+BootBootOptions (\r
   IN EFI_BOOT_MANAGER_LOAD_OPTION    *BootOptions,\r
-  IN UINTN                           BootOptionCount\r
+  IN UINTN                           BootOptionCount,\r
+  IN EFI_BOOT_MANAGER_LOAD_OPTION    *BootManagerMenu\r
   )\r
 {\r
   UINTN                              Index;\r
@@ -486,9 +307,10 @@ BootAllBootOptions (
     EfiBootManagerBoot (&BootOptions[Index]);\r
 \r
     //\r
-    // Successful boot breaks the loop, otherwise tries next boot option\r
+    // If the boot via Boot#### returns with a status of EFI_SUCCESS, platform firmware\r    // supports boot manager menu, and if firmware is configured to boot in an\r    // interactive mode, the boot manager will stop processing the BootOrder variable and\r    // present a boot manager menu to the user.\r
     //\r
     if (BootOptions[Index].Status == EFI_SUCCESS) {\r
+      EfiBootManagerBoot (BootManagerMenu);\r
       break;\r
     }\r
   }\r
@@ -497,72 +319,10 @@ BootAllBootOptions (
 }\r
 \r
 /**\r
-  This function attempts to boot per the boot order specified by platform policy.\r
-\r
-  If the boot via Boot#### returns with a status of EFI_SUCCESS the boot manager will stop \r
-  processing the BootOrder variable and present a boot manager menu to the user. If a boot via \r
-  Boot#### returns a status other than EFI_SUCCESS, the boot has failed and the next Boot####\r
-  in the BootOrder variable will be tried until all possibilities are exhausted.\r
-                                  -- Chapter 3.1.1 Boot Manager Programming, the 4th paragraph\r
-**/\r
-VOID\r
-DefaultBootBehavior (\r
-  VOID\r
-  )\r
-{\r
-  UINTN                        BootOptionCount;\r
-  EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
-  EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu;\r
-\r
-  EfiBootManagerGetBootManagerMenu (&BootManagerMenu);\r
-  //\r
-  // BootManagerMenu always contains the correct information even the above function returns failure.\r
-  //\r
-\r
-  BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
-\r
-  if (BootAllBootOptions (BootOptions, BootOptionCount)) {\r
-    //\r
-    // Follow generic rule, Call BdsDxeOnConnectConInCallBack to connect ConIn before enter UI\r
-    //\r
-    if (PcdGetBool (PcdConInConnectOnDemand)) {\r
-      BdsDxeOnConnectConInCallBack (NULL, NULL);\r
-    }\r
-\r
-    //\r
-    // Show the Boot Manager Menu after successful boot\r
-    //\r
-    EfiBootManagerBoot (&BootManagerMenu);\r
-  } else {\r
-    EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
-    //\r
-    // Re-scan all EFI boot options in case all the boot#### are deleted or failed to boot\r
-    //\r
-    // If no valid boot options exist, the boot manager will enumerate all removable media\r
-    // devices followed by all fixed media devices. The order within each group is undefined.\r
-    // These new default boot options are not saved to non volatile storage.The boot manger\r
-    // will then attempt toboot from each boot option.\r
-    //                            -- Chapter 3.3 Boot Manager Programming, the 2nd paragraph\r
-    //\r
-    EfiBootManagerConnectAll ();\r
-    BootOptions = BdsEnumerateBootOptions (&BootOptionCount);\r
-\r
-    if (!BootAllBootOptions (BootOptions, BootOptionCount)) {\r
-      DEBUG ((EFI_D_ERROR, "[Bds]No bootable device!\n"));\r
-      EfiBootManagerBoot (&BootManagerMenu);\r
-    }\r
-  }\r
-\r
-  EfiBootManagerFreeLoadOption (&BootManagerMenu);\r
-  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
-}\r
-\r
-/**\r
-  The function will load and start every Driver####/SysPrep####.\r
+  The function will load and start every Driver####, SysPrep#### or PlatformRecovery####.\r
 \r
   @param  LoadOptions        Load option array.\r
   @param  LoadOptionCount    Load option count.\r
-\r
 **/\r
 VOID\r
 ProcessLoadOptions (\r
@@ -575,7 +335,7 @@ ProcessLoadOptions (
   BOOLEAN                           ReconnectAll;\r
   EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType;\r
 \r
-  ReconnectAll = FALSE;\r
+  ReconnectAll   = FALSE;\r
   LoadOptionType = LoadOptionTypeMax;\r
 \r
   //\r
@@ -585,16 +345,23 @@ ProcessLoadOptions (
     //\r
     // All the load options in the array should be of the same type.\r
     //\r
-    if (LoadOptionType == LoadOptionTypeMax) {\r
+    if (Index == 0) {\r
       LoadOptionType = LoadOptions[Index].OptionType;\r
     }\r
     ASSERT (LoadOptionType == LoadOptions[Index].OptionType);\r
-    ASSERT (LoadOptionType == LoadOptionTypeDriver || LoadOptionType == LoadOptionTypeSysPrep);\r
 \r
     Status = EfiBootManagerProcessLoadOption (&LoadOptions[Index]);\r
 \r
-    if (!EFI_ERROR (Status) && ((LoadOptions[Index].Attributes & LOAD_OPTION_FORCE_RECONNECT) != 0)) {\r
-      ReconnectAll = TRUE;\r
+    if (!EFI_ERROR (Status)) {\r
+      if (LoadOptionType == LoadOptionTypePlatformRecovery) {\r
+        //\r
+        // Stop processing if any entry is successful\r
+        //\r
+        break;\r
+      }\r
+      if ((LoadOptions[Index].Attributes & LOAD_OPTION_FORCE_RECONNECT) != 0) {\r
+        ReconnectAll = TRUE;\r
+      }\r
     }\r
   }\r
 \r
@@ -670,7 +437,7 @@ BdsFormalizeOSIndicationVariable (
   //\r
   // OS indicater support variable\r
   //\r
-  OsIndicationSupport = EFI_OS_INDICATIONS_BOOT_TO_FW_UI;\r
+  OsIndicationSupport = EFI_OS_INDICATIONS_BOOT_TO_FW_UI | EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY;\r
   Status = gRT->SetVariable (\r
                   EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME,\r
                   &gEfiGlobalVariableGuid,\r
@@ -828,10 +595,13 @@ BdsEntry (
   CHAR16                          BootNextVariableName[sizeof ("Boot####")];\r
   EFI_BOOT_MANAGER_LOAD_OPTION    BootManagerMenu;\r
   BOOLEAN                         BootFwUi;\r
+  BOOLEAN                         PlatformRecovery;\r
+  BOOLEAN                         BootSuccess;\r
   EFI_DEVICE_PATH_PROTOCOL        *FilePath;\r
 \r
   HotkeyTriggered = NULL;\r
   Status          = EFI_SUCCESS;\r
+  BootSuccess     = FALSE;\r
 \r
   //\r
   // Insert the performance probe\r
@@ -1038,9 +808,24 @@ BdsEntry (
   PERF_START (NULL, "PlatformBootManagerAfterConsole", "BDS", 0);\r
   PlatformBootManagerAfterConsole ();\r
   PERF_END   (NULL, "PlatformBootManagerAfterConsole", "BDS", 0);\r
+  //\r
+  // Boot to Boot Manager Menu when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot\r
+  //\r
+  DataSize = sizeof (UINT64);\r
+  Status = gRT->GetVariable (\r
+                  EFI_OS_INDICATIONS_VARIABLE_NAME,\r
+                  &gEfiGlobalVariableGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &OsIndication\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    OsIndication = 0;\r
+  }\r
 \r
   DEBUG_CODE (\r
     EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType;\r
+    DEBUG ((EFI_D_INFO, "[Bds]OsIndication: %016x\n", OsIndication));\r
     DEBUG ((EFI_D_INFO, "[Bds]=============Begin Load Options Dumping ...=============\n"));\r
     for (LoadOptionType = 0; LoadOptionType < LoadOptionTypeMax; LoadOptionType++) {\r
       DEBUG ((\r
@@ -1063,26 +848,17 @@ BdsEntry (
   );\r
 \r
   //\r
-  // Boot to Boot Manager Menu when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot\r
+  // BootManagerMenu always contains the correct information even call fails.\r
   //\r
-  DataSize = sizeof (UINT64);\r
-  Status = gRT->GetVariable (\r
-                  EFI_OS_INDICATIONS_VARIABLE_NAME,\r
-                  &gEfiGlobalVariableGuid,\r
-                  NULL,\r
-                  &DataSize,\r
-                  &OsIndication\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    OsIndication = 0;\r
-  }\r
+  EfiBootManagerGetBootManagerMenu (&BootManagerMenu);\r
 \r
-  BootFwUi = (BOOLEAN) ((OsIndication & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0);\r
+  BootFwUi         = (BOOLEAN) ((OsIndication & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0);\r
+  PlatformRecovery = (BOOLEAN) ((OsIndication & EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY) != 0);\r
   //\r
   // Clear EFI_OS_INDICATIONS_BOOT_TO_FW_UI to acknowledge OS\r
   // \r
-  if (BootFwUi) {\r
-    OsIndication &= ~((UINT64) EFI_OS_INDICATIONS_BOOT_TO_FW_UI);\r
+  if (BootFwUi || PlatformRecovery) {\r
+    OsIndication &= ~((UINT64) (EFI_OS_INDICATIONS_BOOT_TO_FW_UI | EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY));\r
     Status = gRT->SetVariable (\r
                EFI_OS_INDICATIONS_VARIABLE_NAME,\r
                &gEfiGlobalVariableGuid,\r
@@ -1109,62 +885,70 @@ BdsEntry (
 \r
     //\r
     // Directly enter the setup page.\r
-    // BootManagerMenu always contains the correct information even call fails.\r
     //\r
-    EfiBootManagerGetBootManagerMenu (&BootManagerMenu);\r
     EfiBootManagerBoot (&BootManagerMenu);\r
-    EfiBootManagerFreeLoadOption (&BootManagerMenu);\r
   }\r
 \r
-  //\r
-  // Execute SysPrep####\r
-  //\r
-  LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypeSysPrep);\r
-  ProcessLoadOptions (LoadOptions, LoadOptionCount);\r
-  EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);\r
+  if (!PlatformRecovery) {\r
+    //\r
+    // Execute SysPrep####\r
+    //\r
+    LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypeSysPrep);\r
+    ProcessLoadOptions (LoadOptions, LoadOptionCount);\r
+    EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);\r
 \r
-  //\r
-  // Execute Key####\r
-  //\r
-  PERF_START (NULL, "BdsWait", "BDS", 0);\r
-  BdsWait (HotkeyTriggered);\r
-  PERF_END   (NULL, "BdsWait", "BDS", 0);\r
+    //\r
+    // Execute Key####\r
+    //\r
+    PERF_START (NULL, "BdsWait", "BDS", 0);\r
+    BdsWait (HotkeyTriggered);\r
+    PERF_END   (NULL, "BdsWait", "BDS", 0);\r
 \r
-  //\r
-  // BdsReadKeys() be removed after all keyboard drivers invoke callback in timer callback.\r
-  //\r
-  BdsReadKeys ();\r
+    //\r
+    // BdsReadKeys() can be removed after all keyboard drivers invoke callback in timer callback.\r
+    //\r
+    BdsReadKeys ();\r
 \r
-  EfiBootManagerHotkeyBoot ();\r
+    EfiBootManagerHotkeyBoot ();\r
 \r
-  //\r
-  // Boot to "BootNext"\r
-  //\r
-  if (BootNext != NULL) {\r
-    UnicodeSPrint (BootNextVariableName, sizeof (BootNextVariableName), L"Boot%04x", *BootNext);\r
-    Status = EfiBootManagerVariableToLoadOption (BootNextVariableName, &LoadOption);\r
-    if (!EFI_ERROR (Status)) {\r
-      EfiBootManagerBoot (&LoadOption);\r
-      EfiBootManagerFreeLoadOption (&LoadOption);\r
-      if (LoadOption.Status == EFI_SUCCESS) {\r
-        //\r
-        // Boot to Boot Manager Menu upon EFI_SUCCESS\r
-        //\r
-        EfiBootManagerGetBootManagerMenu (&LoadOption);\r
+    //\r
+    // Boot to "BootNext"\r
+    //\r
+    if (BootNext != NULL) {\r
+      UnicodeSPrint (BootNextVariableName, sizeof (BootNextVariableName), L"Boot%04x", *BootNext);\r
+      Status = EfiBootManagerVariableToLoadOption (BootNextVariableName, &LoadOption);\r
+      if (!EFI_ERROR (Status)) {\r
         EfiBootManagerBoot (&LoadOption);\r
         EfiBootManagerFreeLoadOption (&LoadOption);\r
+        if (LoadOption.Status == EFI_SUCCESS) {\r
+          //\r
+          // Boot to Boot Manager Menu upon EFI_SUCCESS\r
+          //\r
+          EfiBootManagerBoot (&BootManagerMenu);\r
+        }\r
       }\r
     }\r
+\r
+    do {\r
+      //\r
+      // Retry to boot if any of the boot succeeds\r
+      //\r
+      LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypeBoot);\r
+      BootSuccess = BootBootOptions (LoadOptions, LoadOptionCount, &BootManagerMenu);\r
+      EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);\r
+    } while (BootSuccess);\r
   }\r
 \r
-  while (TRUE) {\r
-    //\r
-    // BDS select the boot device to load OS\r
-    // Try next upon boot failure\r
-    // Show Boot Manager Menu upon boot success\r
-    //\r
-    DefaultBootBehavior ();\r
+  EfiBootManagerFreeLoadOption (&BootManagerMenu);\r
+\r
+  if (!BootSuccess) {\r
+    LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypePlatformRecovery);\r
+    ProcessLoadOptions (LoadOptions, LoadOptionCount);\r
+    EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);\r
   }\r
+\r
+  DEBUG ((EFI_D_ERROR, "[Bds] Unable to boot!\n"));\r
+  CpuDeadLoop ();\r
 }\r
 \r
 /**\r