From 2e04a2f99a03f5f5259aded7ae203bc826769988 Mon Sep 17 00:00:00 2001 From: Ruiyu Ni Date: Mon, 11 May 2015 06:34:53 +0000 Subject: [PATCH] MdeModulePkg: Add BootManagerPolicyDxe to produce BootManagerPolicy protocol. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Reviewed-by: Eric Dong git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17405 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/MdeModulePkg.dsc | 1 + .../BootManagerPolicyDxe.c | 287 ++++++++++++++++++ .../BootManagerPolicyDxe.inf | 58 ++++ 3 files changed, 346 insertions(+) create mode 100644 MdeModulePkg/Universal/BootManagerPolicyDxe/BootManagerPolicyDxe.c create mode 100644 MdeModulePkg/Universal/BootManagerPolicyDxe/BootManagerPolicyDxe.inf diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index b525e3ac51..16a6eb5774 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -276,6 +276,7 @@ MdeModulePkg/Universal/BdsDxe/BdsDxe.inf MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf + MdeModulePkg/Universal/BootManagerPolicyDxe/BootManagerPolicyDxe.inf MdeModulePkg/Universal/CapsulePei/CapsulePei.inf MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf diff --git a/MdeModulePkg/Universal/BootManagerPolicyDxe/BootManagerPolicyDxe.c b/MdeModulePkg/Universal/BootManagerPolicyDxe/BootManagerPolicyDxe.c new file mode 100644 index 0000000000..a39daa4c32 --- /dev/null +++ b/MdeModulePkg/Universal/BootManagerPolicyDxe/BootManagerPolicyDxe.c @@ -0,0 +1,287 @@ +/** @file + This module produces Boot Manager Policy protocol. + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +CHAR16 mNetworkDeviceList[] = L"_NDL"; + +/** + Connect all the system drivers to controllers and create the network device list in NV storage. + + @retval EFI_SUCCESS Network devices are connected. + @retval EFI_DEVICE_ERROR No network device is connected. + +**/ +EFI_STATUS +ConnectAllAndCreateNetworkDeviceList ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HANDLE *Handles; + UINTN HandleCount; + EFI_DEVICE_PATH_PROTOCOL *SingleDevice; + EFI_DEVICE_PATH_PROTOCOL *Devices; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + + EfiBootManagerConnectAll (); + + Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiManagedNetworkServiceBindingProtocolGuid, NULL, &HandleCount, &Handles); + if (EFI_ERROR (Status)) { + Handles = NULL; + HandleCount = 0; + } + + Devices = NULL; + while (HandleCount-- != 0) { + Status = gBS->HandleProtocol (Handles[HandleCount], &gEfiDevicePathProtocolGuid, (VOID **) &SingleDevice); + if (EFI_ERROR (Status) || (SingleDevice == NULL)) { + continue; + } + TempDevicePath = Devices; + Devices = AppendDevicePathInstance (Devices, SingleDevice); + if (TempDevicePath != NULL) { + FreePool (TempDevicePath); + } + } + + if (Devices != NULL) { + Status = gRT->SetVariable ( + mNetworkDeviceList, + &gEfiCallerIdGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, + GetDevicePathSize (Devices), + Devices + ); + // + // Fails to save the network device list to NV storage is not a fatal error. + // Only impact is performance. + // + FreePool (Devices); + } + + return (Devices == NULL) ? EFI_DEVICE_ERROR : EFI_SUCCESS; +} + +/** + Connect the network devices. + + @retval EFI_SUCCESS At least one network device was connected. + @retval EFI_DEVICE_ERROR Network devices were not connected due to an error. +**/ +EFI_STATUS +ConnectNetwork ( + VOID + ) +{ + EFI_STATUS Status; + BOOLEAN OneConnected; + EFI_DEVICE_PATH_PROTOCOL *Devices; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + EFI_DEVICE_PATH_PROTOCOL *SingleDevice; + UINTN Size; + + OneConnected = FALSE; + GetVariable2 (mNetworkDeviceList, &gEfiCallerIdGuid, (VOID **) &Devices, NULL); + TempDevicePath = Devices; + while (TempDevicePath != NULL) { + SingleDevice = GetNextDevicePathInstance (&TempDevicePath, &Size); + Status = EfiBootManagerConnectDevicePath (SingleDevice, NULL); + if (!EFI_ERROR (Status)) { + OneConnected = TRUE; + } + FreePool (SingleDevice); + } + if (Devices != NULL) { + FreePool (Devices); + } + + if (OneConnected) { + return EFI_SUCCESS; + } else { + // + // Cached network devices list doesn't exist or is NOT valid. + // + return ConnectAllAndCreateNetworkDeviceList (); + } +} + +/** + Connect a device path following the platforms EFI Boot Manager policy. + + The ConnectDevicePath() function allows the caller to connect a DevicePath using the + same policy as the EFI Boot Manger. + + @param[in] This A pointer to the EFI_BOOT_MANAGER_POLICY_PROTOCOL instance. + @param[in] DevicePath Points to the start of the EFI device path to connect. + If DevicePath is NULL then all the controllers in the + system will be connected using the platforms EFI Boot + Manager policy. + @param[in] Recursive If TRUE, then ConnectController() is called recursively + until the entire tree of controllers below the + controller specified by DevicePath have been created. + If FALSE, then the tree of controllers is only expanded + one level. If DevicePath is NULL then Recursive is ignored. + + @retval EFI_SUCCESS The DevicePath was connected. + @retval EFI_NOT_FOUND The DevicePath was not found. + @retval EFI_NOT_FOUND No driver was connected to DevicePath. + @retval EFI_SECURITY_VIOLATION The user has no permission to start UEFI device + drivers on the DevicePath. + @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION. +**/ +EFI_STATUS +EFIAPI +BootManagerPolicyConnectDevicePath ( + IN EFI_BOOT_MANAGER_POLICY_PROTOCOL *This, + IN EFI_DEVICE_PATH *DevicePath, + IN BOOLEAN Recursive + ) +{ + EFI_STATUS Status; + EFI_HANDLE Controller; + + if (EfiGetCurrentTpl () != TPL_APPLICATION) { + return EFI_UNSUPPORTED; + } + + if (DevicePath == NULL) { + EfiBootManagerConnectAll (); + return EFI_SUCCESS; + } + + if (Recursive) { + Status = EfiBootManagerConnectDevicePath (DevicePath, NULL); + } else { + Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &Controller); + if (!EFI_ERROR (Status)) { + Status = gBS->ConnectController (Controller, NULL, DevicePath, FALSE); + } + } + return Status; +} +/** + Connect a class of devices using the platform Boot Manager policy. + + The ConnectDeviceClass() function allows the caller to request that the Boot + Manager connect a class of devices. + + If Class is EFI_BOOT_MANAGER_POLICY_CONSOLE_GUID then the Boot Manager will + use platform policy to connect consoles. Some platforms may restrict the + number of consoles connected as they attempt to fast boot, and calling + ConnectDeviceClass() with a Class value of EFI_BOOT_MANAGER_POLICY_CONSOLE_GUID + must connect the set of consoles that follow the Boot Manager platform policy, + and the EFI_SIMPLE_TEXT_INPUT_PROTOCOL, EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL, and + the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL are produced on the connected handles. + The Boot Manager may restrict which consoles get connect due to platform policy, + for example a security policy may require that a given console is not connected. + + If Class is EFI_BOOT_MANAGER_POLICY_NETWORK_GUID then the Boot Manager will + connect the protocols the platforms supports for UEFI general purpose network + applications on one or more handles. If more than one network controller is + available a platform will connect, one, many, or all of the networks based + on platform policy. Connecting UEFI networking protocols, like EFI_DHCP4_PROTOCOL, + does not establish connections on the network. The UEFI general purpose network + application that called ConnectDeviceClass() may need to use the published + protocols to establish the network connection. The Boot Manager can optionally + have a policy to establish a network connection. + + If Class is EFI_BOOT_MANAGER_POLICY_CONNECT_ALL_GUID then the Boot Manager + will connect all UEFI drivers using the UEFI Boot Service + EFI_BOOT_SERVICES.ConnectController(). If the Boot Manager has policy + associated with connect all UEFI drivers this policy will be used. + + A platform can also define platform specific Class values as a properly generated + EFI_GUID would never conflict with this specification. + + @param[in] This A pointer to the EFI_BOOT_MANAGER_POLICY_PROTOCOL instance. + @param[in] Class A pointer to an EFI_GUID that represents a class of devices + that will be connected using the Boot Mangers platform policy. + + @retval EFI_SUCCESS At least one devices of the Class was connected. + @retval EFI_DEVICE_ERROR Devices were not connected due to an error. + @retval EFI_NOT_FOUND The Class is not supported by the platform. + @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION. +**/ +EFI_STATUS +EFIAPI +BootManagerPolicyConnectDeviceClass ( + IN EFI_BOOT_MANAGER_POLICY_PROTOCOL *This, + IN EFI_GUID *Class + ) +{ + if (EfiGetCurrentTpl () != TPL_APPLICATION) { + return EFI_UNSUPPORTED; + } + + if (CompareGuid (Class, &gEfiBootManagerPolicyConnectAllGuid)) { + ConnectAllAndCreateNetworkDeviceList (); + return EFI_SUCCESS; + } + + if (CompareGuid (Class, &gEfiBootManagerPolicyConsoleGuid)) { + return EfiBootManagerConnectAllDefaultConsoles (); + } + + if (CompareGuid (Class, &gEfiBootManagerPolicyNetworkGuid)) { + return ConnectNetwork (); + } + + return EFI_NOT_FOUND; +} + +EFI_BOOT_MANAGER_POLICY_PROTOCOL mBootManagerPolicy = { + EFI_BOOT_MANAGER_POLICY_PROTOCOL_REVISION, + BootManagerPolicyConnectDevicePath, + BootManagerPolicyConnectDeviceClass +}; + +/** + Install Boot Manager Policy Protocol. + + @param ImageHandle The image handle. + @param SystemTable The system table. + + @retval EFI_SUCEESS The Boot Manager Policy protocol is successfully installed. + @retval Other Return status from gBS->InstallMultipleProtocolInterfaces(). + +**/ +EFI_STATUS +EFIAPI +BootManagerPolicyInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_HANDLE Handle; + + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiBootManagerPolicyProtocolGuid); + + Handle = NULL; + return gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiBootManagerPolicyProtocolGuid, &mBootManagerPolicy, + NULL + ); +} \ No newline at end of file diff --git a/MdeModulePkg/Universal/BootManagerPolicyDxe/BootManagerPolicyDxe.inf b/MdeModulePkg/Universal/BootManagerPolicyDxe/BootManagerPolicyDxe.inf new file mode 100644 index 0000000000..3970dee82f --- /dev/null +++ b/MdeModulePkg/Universal/BootManagerPolicyDxe/BootManagerPolicyDxe.inf @@ -0,0 +1,58 @@ +## @file +# This module produces Boot Manager Policy protocol. +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BootManagerPolicyDxe + FILE_GUID = E622443C-284E-4b47-A984-FD66B482DAC0 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = BootManagerPolicyInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + BootManagerPolicyDxe.c + + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseMemoryLib + MemoryAllocationLib + UefiLib + DevicePathLib + DebugLib + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + UefiBootManagerLib + +[Guids] + gEfiBootManagerPolicyConnectAllGuid ## CONSUMES ## GUID + gEfiBootManagerPolicyNetworkGuid ## CONSUMES ## GUID + gEfiBootManagerPolicyConsoleGuid ## CONSUMES ## GUID + +[Protocols] + gEfiManagedNetworkServiceBindingProtocolGuid ## CONSUMES + gEfiBootManagerPolicyProtocolGuid ## PRODUCES + +[Depex] + TRUE -- 2.39.2