]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/UefiBootManagerLib/BmMisc.c
MdeModulePkg/Bds: Remove assertion in BmCharToUint
[mirror_edk2.git] / MdeModulePkg / Library / UefiBootManagerLib / BmMisc.c
index 2a60f0643e44078f28f01a52bdd9870fb186fa11..a3fa254245928656827c6ddc74aa7f91fd9e855c 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Misc library functions.\r
 \r
-Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>\r
 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
@@ -205,8 +205,11 @@ BmSetMemoryTypeInformationVariable (
     //\r
     return;\r
   }\r
-  PreviousMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob);\r
-  VariableSize = GET_GUID_HOB_DATA_SIZE (GuidHob);\r
+  VariableSize                  = GET_GUID_HOB_DATA_SIZE (GuidHob);\r
+  PreviousMemoryTypeInformation = AllocateCopyPool (VariableSize, GET_GUID_HOB_DATA (GuidHob));\r
+  if (PreviousMemoryTypeInformation == NULL) {\r
+    return;\r
+  }\r
 \r
   //\r
   // Use a heuristic to adjust the Memory Type Information for the next boot\r
@@ -278,14 +281,18 @@ BmSetMemoryTypeInformationVariable (
       // then reset the platform so the new Memory Type Information setting will be used to guarantee that an S4\r
       // entry/resume cycle will not fail.\r
       //\r
-      if (MemoryTypeInformationModified && Boot && PcdGetBool (PcdResetOnMemoryTypeInformationChange)) {\r
-        DEBUG ((EFI_D_INFO, "Memory Type Information settings change. Warm Reset!!!\n"));\r
-        gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
+      if (MemoryTypeInformationModified) {\r
+        DEBUG ((EFI_D_INFO, "Memory Type Information settings change.\n"));\r
+        if (Boot && PcdGetBool (PcdResetOnMemoryTypeInformationChange)) {\r
+          DEBUG ((EFI_D_INFO, "...Warm Reset!!!\n"));\r
+          gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
+        }\r
       }\r
     } else {\r
       DEBUG ((EFI_D_ERROR, "Memory Type Information settings cannot be saved. OS S4 may fail!\n"));\r
     }\r
   }\r
+  FreePool (PreviousMemoryTypeInformation);\r
 }\r
 \r
 /**\r
@@ -406,14 +413,126 @@ BmCharToUint (
   )\r
 {\r
   if ((Char >= L'0') && (Char <= L'9')) {\r
-    return (UINTN) (Char - L'0');\r
+    return (Char - L'0');\r
   }\r
 \r
   if ((Char >= L'A') && (Char <= L'F')) {\r
-    return (UINTN) (Char - L'A' + 0xA);\r
+    return (Char - L'A' + 0xA);\r
   }\r
 \r
-  ASSERT (FALSE);\r
   return (UINTN) -1;\r
 }\r
 \r
+/**\r
+  Dispatch the deferred images that are returned from all DeferredImageLoad instances.\r
+\r
+  @retval EFI_SUCCESS       At least one deferred image is loaded successfully and started.\r
+  @retval EFI_NOT_FOUND     There is no deferred image.\r
+  @retval EFI_ACCESS_DENIED There are deferred images but all of them are failed to load.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiBootManagerDispatchDeferredImages (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                         Status;\r
+  EFI_DEFERRED_IMAGE_LOAD_PROTOCOL   *DeferredImage;\r
+  UINTN                              HandleCount;\r
+  EFI_HANDLE                         *Handles;\r
+  UINTN                              Index;\r
+  UINTN                              ImageIndex;\r
+  EFI_DEVICE_PATH_PROTOCOL           *ImageDevicePath;\r
+  VOID                               *Image;\r
+  UINTN                              ImageSize;\r
+  BOOLEAN                            BootOption;\r
+  EFI_HANDLE                         ImageHandle;\r
+  UINTN                              ExitDataSize;\r
+  CHAR16                             *ExitData;\r
+  UINTN                              ImageCount;\r
+  UINTN                              LoadCount;\r
+\r
+  //\r
+  // Find all the deferred image load protocols.\r
+  //\r
+  HandleCount = 0;\r
+  Handles = NULL;\r
+  Status = gBS->LocateHandleBuffer (\r
+    ByProtocol,\r
+    &gEfiDeferredImageLoadProtocolGuid,\r
+    NULL,\r
+    &HandleCount,\r
+    &Handles\r
+  );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  ImageCount = 0;\r
+  LoadCount  = 0;\r
+  for (Index = 0; Index < HandleCount; Index++) {\r
+    Status = gBS->HandleProtocol (Handles[Index], &gEfiDeferredImageLoadProtocolGuid, (VOID **) &DeferredImage);\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+    for (ImageIndex = 0; ;ImageIndex++) {\r
+      //\r
+      // Load all the deferred images in this protocol instance.\r
+      //\r
+      Status = DeferredImage->GetImageInfo (\r
+                                DeferredImage,\r
+                                ImageIndex,\r
+                                &ImageDevicePath,\r
+                                (VOID **) &Image,\r
+                                &ImageSize,\r
+                                &BootOption\r
+                                );\r
+      if (EFI_ERROR (Status)) {\r
+        break;\r
+      }\r
+      ImageCount++;\r
+      //\r
+      // Load and start the image.\r
+      //\r
+      Status = gBS->LoadImage (\r
+        BootOption,\r
+        gImageHandle,\r
+        ImageDevicePath,\r
+        NULL,\r
+        0,\r
+        &ImageHandle\r
+      );\r
+      if (!EFI_ERROR (Status)) {\r
+        LoadCount++;\r
+        //\r
+        // Before calling the image, enable the Watchdog Timer for\r
+        // a 5 Minute period\r
+        //\r
+        gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);\r
+        Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);\r
+        if (ExitData != NULL) {\r
+          FreePool (ExitData);\r
+        }\r
+\r
+        //\r
+        // Clear the Watchdog Timer after the image returns.\r
+        //\r
+        gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);\r
+      }\r
+    }\r
+  }\r
+  if (Handles != NULL) {\r
+    FreePool (Handles);\r
+  }\r
+\r
+  if (ImageCount == 0) {\r
+    return EFI_NOT_FOUND;\r
+  } else {\r
+    if (LoadCount == 0) {\r
+      return EFI_ACCESS_DENIED;\r
+    } else {\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+}\r