diff options
3 files changed, 346 insertions, 0 deletions
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.<BR>
+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 <Uefi.h>
+#include <Protocol/BootManagerPolicy.h>
+#include <Protocol/ManagedNetwork.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootManagerLib.h>
+
+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.<BR>
+# 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
|