]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/UefiBootManagerLib/BmMisc.c
MdeModulePkg/UefiBootManagerLib: Generate boot description for NVME
[mirror_edk2.git] / MdeModulePkg / Library / UefiBootManagerLib / BmMisc.c
index 93502fe7d2de443fc06cb29d6e714898f8ed61b6..11ab86792a52534120070a4541d784838375fc7d 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
@@ -130,13 +130,10 @@ BmMatchDevicePaths (
 \r
   @param Boot               TRUE if current boot option belongs to boot\r
                             category instead of application category.\r
-  @param RamDiskSizeInPages Reserved memory size in pages occupied by\r
-                            RAM Disk.\r
 **/\r
 VOID\r
 BmSetMemoryTypeInformationVariable (\r
-  IN BOOLEAN                    Boot,\r
-  IN UINTN                      RamDiskSizeInPages\r
+  IN BOOLEAN                    Boot\r
   )\r
 {\r
   EFI_STATUS                   Status;\r
@@ -208,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
@@ -229,14 +229,6 @@ BmSetMemoryTypeInformationVariable (
       continue;\r
     }\r
 \r
-    //\r
-    // Do not count the reserved memory occupied by RAM Disk.\r
-    //\r
-    if ((CurrentMemoryTypeInformation[Index1].Type == EfiReservedMemoryType) &&\r
-        (CurrentMemoryTypeInformation[Index1].NumberOfPages > ((UINT32) RamDiskSizeInPages))) {\r
-      CurrentMemoryTypeInformation[Index1].NumberOfPages -= (UINT32) RamDiskSizeInPages;\r
-    }\r
-\r
     //\r
     // Previous is the number of pages pre-allocated\r
     // Current is the number of pages actually needed\r
@@ -289,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
@@ -417,14 +413,127 @@ 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