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
#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
#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
\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
}\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