]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Library/PlatformBootManagerLib/PlatformBm.c
ArmPkg: Enable boot discovery policy for ARM package.
[mirror_edk2.git] / ArmPkg / Library / PlatformBootManagerLib / PlatformBm.c
index 5ceb23d822e5d121158d87d437253559ef8d7eab..1e4020487aa73571164bc78132d7b7e4b0a7330a 100644 (file)
@@ -2,9 +2,10 @@
   Implementation for PlatformBootManagerLib library class interfaces.\r
 \r
   Copyright (C) 2015-2016, Red Hat, Inc.\r
-  Copyright (c) 2014 - 2019, ARM Ltd. All rights reserved.<BR>\r
+  Copyright (c) 2014 - 2021, ARM Ltd. All rights reserved.<BR>\r
   Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
   Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
+  Copyright (c) 2021, Semihalf All rights reserved.<BR>\r
 \r
   SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
@@ -19,6 +20,7 @@
 #include <Library/UefiBootManagerLib.h>\r
 #include <Library/UefiLib.h>\r
 #include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Protocol/BootManagerPolicy.h>\r
 #include <Protocol/DevicePath.h>\r
 #include <Protocol/EsrtManagement.h>\r
 #include <Protocol/GraphicsOutput.h>\r
@@ -27,6 +29,7 @@
 #include <Protocol/PciIo.h>\r
 #include <Protocol/PciRootBridgeIo.h>\r
 #include <Protocol/PlatformBootManager.h>\r
+#include <Guid/BootDiscoveryPolicy.h>\r
 #include <Guid/EventGroup.h>\r
 #include <Guid/NonDiscoverableDevice.h>\r
 #include <Guid/TtyTerm.h>\r
@@ -703,6 +706,113 @@ HandleCapsules (
 \r
 #define VERSION_STRING_PREFIX    L"Tianocore/EDK2 firmware version "\r
 \r
+/**\r
+  This functions checks the value of BootDiscoverPolicy variable and\r
+  connect devices of class specified by that variable. Then it refreshes\r
+  Boot order for newly discovered boot device.\r
+\r
+  @retval  EFI_SUCCESS  Devices connected successfully or connection\r
+                        not required.\r
+  @retval  others       Return values from GetVariable(), LocateProtocol()\r
+                        and ConnectDeviceClass().\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+BootDiscoveryPolicyHandler (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  UINT32                           DiscoveryPolicy;\r
+  UINT32                           DiscoveryPolicyOld;\r
+  UINTN                            Size;\r
+  EFI_BOOT_MANAGER_POLICY_PROTOCOL *BMPolicy;\r
+  EFI_GUID                         *Class;\r
+\r
+  Size = sizeof (DiscoveryPolicy);\r
+  Status = gRT->GetVariable (\r
+                  BOOT_DISCOVERY_POLICY_VAR,\r
+                  &gBootDiscoveryPolicyMgrFormsetGuid,\r
+                  NULL,\r
+                  &Size,\r
+                  &DiscoveryPolicy\r
+                  );\r
+  if (Status == EFI_NOT_FOUND) {\r
+    DiscoveryPolicy = PcdGet32 (PcdBootDiscoveryPolicy);\r
+    Status = PcdSet32S (PcdBootDiscoveryPolicy, DiscoveryPolicy);\r
+    if (Status == EFI_NOT_FOUND) {\r
+      return EFI_SUCCESS;\r
+    } else if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  } else if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (DiscoveryPolicy == BDP_CONNECT_MINIMAL) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  switch (DiscoveryPolicy) {\r
+    case BDP_CONNECT_NET:\r
+      Class = &gEfiBootManagerPolicyNetworkGuid;\r
+      break;\r
+    case BDP_CONNECT_ALL:\r
+      Class = &gEfiBootManagerPolicyConnectAllGuid;\r
+      break;\r
+    default:\r
+      DEBUG ((\r
+        DEBUG_INFO,\r
+        "%a - Unexpected DiscoveryPolicy (0x%x). Run Minimal Discovery Policy\n",\r
+        __FUNCTION__,\r
+        DiscoveryPolicy\r
+        ));\r
+      return EFI_SUCCESS;\r
+  }\r
+\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiBootManagerPolicyProtocolGuid,\r
+                  NULL,\r
+                  (VOID **)&BMPolicy\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_INFO, "%a - Failed to locate gEfiBootManagerPolicyProtocolGuid."\r
+      "Driver connect will be skipped.\n", __FUNCTION__));\r
+    return Status;\r
+  }\r
+\r
+  Status = BMPolicy->ConnectDeviceClass (BMPolicy, Class);\r
+  if (EFI_ERROR (Status)){\r
+    DEBUG ((DEBUG_ERROR, "%a - ConnectDeviceClass returns - %r\n", __FUNCTION__, Status));\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Refresh Boot Options if Boot Discovery Policy has been changed\r
+  //\r
+  Size = sizeof (DiscoveryPolicyOld);\r
+  Status = gRT->GetVariable (\r
+                  BOOT_DISCOVERY_POLICY_OLD_VAR,\r
+                  &gBootDiscoveryPolicyMgrFormsetGuid,\r
+                  NULL,\r
+                  &Size,\r
+                  &DiscoveryPolicyOld\r
+                  );\r
+  if ((Status == EFI_NOT_FOUND) || (DiscoveryPolicyOld != DiscoveryPolicy)) {\r
+    EfiBootManagerRefreshAllBootOption ();\r
+\r
+    Status = gRT->SetVariable (\r
+                    BOOT_DISCOVERY_POLICY_OLD_VAR,\r
+                    &gBootDiscoveryPolicyMgrFormsetGuid,\r
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+                    sizeof (DiscoveryPolicyOld),\r
+                    &DiscoveryPolicy\r
+                    );\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Do the platform specific action after the console is ready\r
   Possible things that can be done in PlatformBootManagerAfterConsole:\r
@@ -753,6 +863,12 @@ PlatformBootManagerAfterConsole (
     }\r
   }\r
 \r
+  //\r
+  // Connect device specified by BootDiscoverPolicy variable and\r
+  // refresh Boot order for newly discovered boot devices\r
+  //\r
+  BootDiscoveryPolicyHandler ();\r
+\r
   //\r
   // On ARM, there is currently no reason to use the phased capsule\r
   // update approach where some capsules are dispatched before EndOfDxe\r