Index: MdePkg/Include/Library/DxeServicesLib.h
===================================================================
--- MdePkg/Include/Library/DxeServicesLib.h	(revision 16222)
+++ MdePkg/Include/Library/DxeServicesLib.h	(working copy)
@@ -2,6 +2,7 @@
   MDE DXE Services Library provides functions that simplify the development of DXE Drivers.  
   These functions help access data from sections of FFS files or from file path.
 
+Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>   
 Copyright (c) 2006 - 2012, 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 that accompanies this distribution.  
@@ -262,5 +263,59 @@
   OUT UINT32                           *AuthenticationStatus
   );
 
+/**
+  Searches all the available firmware volumes and returns the first matching FFS section. 
+
+  This function searches all the firmware volumes for FFS files with an FFS filename specified by NameGuid.  
+  The order that the firmware volumes is searched is not deterministic. For each FFS file found a search 
+  is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance instances 
+  of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer. 
+  Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size. 
+  It is the caller's responsibility to use FreePool() to free the allocated buffer.  
+  See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections 
+  are retrieved from an FFS file based on SectionType and SectionInstance.
+
+  If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, 
+  the search will be retried with a section type of EFI_SECTION_PE32.
+  This function must be called with a TPL <= TPL_NOTIFY.
+
+  If NameGuid is NULL, then ASSERT().
+  If Buffer is NULL, then ASSERT().
+  If Size is NULL, then ASSERT().
+
+
+  @param  NameGuid             A pointer to to the FFS filename GUID to search for  
+                               within any of the firmware volumes in the platform. 
+  @param  SectionType          Indicates the FFS section type to search for within 
+                               the FFS file specified by NameGuid.
+  @param  SectionInstance      Indicates which section instance within the FFS file 
+                               specified by NameGuid to retrieve.
+  @param  Buffer               On output, a pointer to a callee allocated buffer 
+                               containing the FFS file section that was found.  
+                               Is it the caller's responsibility to free this buffer 
+                               using FreePool().
+  @param  Size                 On output, a pointer to the size, in bytes, of Buffer.
+  @param  DevicePath           Device path for the FFS file.
+
+  @retval  EFI_SUCCESS          The specified FFS section was returned.
+  @retval  EFI_NOT_FOUND        The specified FFS section could not be found.
+  @retval  EFI_OUT_OF_RESOURCES There are not enough resources available to 
+                                retrieve the matching FFS section.
+  @retval  EFI_DEVICE_ERROR     The FFS section could not be retrieves due to a 
+                                device error.
+  @retval  EFI_ACCESS_DENIED    The FFS section could not be retrieves because the 
+                                firmware volume that 
+                                contains the matching FFS section does not allow reads.
+**/
+EFI_STATUS
+EFIAPI
+GetSectionFromAnyFvEx (
+  IN CONST  EFI_GUID                  *NameGuid,
+  IN        EFI_SECTION_TYPE          SectionType,
+  IN        UINTN                     SectionInstance,
+  OUT       VOID                      **Buffer,
+  OUT       UINTN                     *Size,
+  OUT       EFI_DEVICE_PATH_PROTOCOL  **FvFileDevicePath
+  );
 #endif
 
Index: MdePkg/Library/DxeServicesLib/DxeServicesLib.c
===================================================================
--- MdePkg/Library/DxeServicesLib/DxeServicesLib.c	(revision 16222)
+++ MdePkg/Library/DxeServicesLib/DxeServicesLib.c	(working copy)
@@ -2,6 +2,7 @@
   MDE DXE Services Library provides functions that simplify the development of DXE Drivers.  
   These functions help access data from sections of FFS files or from file path.
 
+  Copyright (c) 2013 - 2014, Hewlett-Packard Development Company, L.P.<BR>
   Copyright (c) 2007 - 2012, 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
@@ -925,3 +926,159 @@
 
   return ImageBuffer;
 }
+/**
+  Searches all the available firmware volumes and returns the first matching FFS section. 
+
+  This function searches all the firmware volumes for FFS files with an FFS filename specified by NameGuid.  
+  The order that the firmware volumes is searched is not deterministic. For each FFS file found a search 
+  is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance instances 
+  of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer. 
+  Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size. 
+  It is the caller's responsibility to use FreePool() to free the allocated buffer.  
+  See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections 
+  are retrieved from an FFS file based on SectionType and SectionInstance.
+
+  If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, 
+  the search will be retried with a section type of EFI_SECTION_PE32.
+  This function must be called with a TPL <= TPL_NOTIFY.
+
+  If NameGuid is NULL, then ASSERT().
+  If Buffer is NULL, then ASSERT().
+  If Size is NULL, then ASSERT().
+
+
+  @param  NameGuid             A pointer to to the FFS filename GUID to search for  
+                               within any of the firmware volumes in the platform. 
+  @param  SectionType          Indicates the FFS section type to search for within 
+                               the FFS file specified by NameGuid.
+  @param  SectionInstance      Indicates which section instance within the FFS file 
+                               specified by NameGuid to retrieve.
+  @param  Buffer               On output, a pointer to a callee allocated buffer 
+                               containing the FFS file section that was found.  
+                               Is it the caller's responsibility to free this buffer 
+                               using FreePool().
+  @param  Size                 On output, a pointer to the size, in bytes, of Buffer.
+  @param  DevicePath           Device path for the FFS file.
+
+  @retval  EFI_SUCCESS          The specified FFS section was returned.
+  @retval  EFI_NOT_FOUND        The specified FFS section could not be found.
+  @retval  EFI_OUT_OF_RESOURCES There are not enough resources available to 
+                                retrieve the matching FFS section.
+  @retval  EFI_DEVICE_ERROR     The FFS section could not be retrieves due to a 
+                                device error.
+  @retval  EFI_ACCESS_DENIED    The FFS section could not be retrieves because the 
+                                firmware volume that 
+                                contains the matching FFS section does not allow reads.
+**/
+EFI_STATUS
+EFIAPI
+GetSectionFromAnyFvEx (
+  IN CONST  EFI_GUID                  *NameGuid,
+  IN        EFI_SECTION_TYPE          SectionType,
+  IN        UINTN                     SectionInstance,
+  OUT       VOID                      **Buffer,
+  OUT       UINTN                     *Size,
+  OUT       EFI_DEVICE_PATH_PROTOCOL  **FvFileDevicePath
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_HANDLE                        *HandleBuffer;
+  UINTN                             HandleCount;
+  UINTN                             Index;
+  EFI_HANDLE                        FvHandle;
+  EFI_DEVICE_PATH_PROTOCOL          *FvDevicePath;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *TempFvFileDevicePath;
+
+
+  if (Buffer == NULL || Size == NULL || FvFileDevicePath == NULL) {
+    return EFI_INVALID_PARAMETER;  
+  }
+
+  HandleBuffer         = NULL;
+  FvDevicePath         = NULL;
+  TempFvFileDevicePath = NULL;
+
+  //
+  // Search the FV that contain the caller's FFS first.
+  // FV builder can choose to build FFS into the this FV
+  // so that this implementation of GetSectionFromAnyFv
+  // will locate the FFS faster.
+  //
+  FvHandle = InternalImageHandleToFvHandle (gImageHandle);
+  Status = InternalGetSectionFromFv (
+             FvHandle,
+             NameGuid,
+             SectionType,
+             SectionInstance,
+             Buffer,
+             Size
+             );
+  if (!EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  for (Index = 0; Index < HandleCount; Index++) {
+    //
+    // Skip the FV that contain the caller's FFS
+    //
+    if (HandleBuffer[Index] != FvHandle) {
+      Status = InternalGetSectionFromFv (
+                 HandleBuffer[Index], 
+                 NameGuid, 
+                 SectionType, 
+                 SectionInstance,
+                 Buffer, 
+                 Size
+                 );
+
+      if (!EFI_ERROR (Status)) {
+        goto Done;
+      }
+    }
+  }
+
+  if (Index == HandleCount) {
+    Status = EFI_NOT_FOUND;
+  }
+
+Done:
+  if (Status == EFI_SUCCESS) {
+    //
+    // Build a device path to the file in the FV to pass into gBS->LoadImage
+    //
+    Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
+    if (EFI_ERROR (Status)) {
+      *FvFileDevicePath = NULL;
+    } else {
+      TempFvFileDevicePath = AllocateZeroPool (sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + END_DEVICE_PATH_LENGTH);
+      if (TempFvFileDevicePath == NULL) {
+        *FvFileDevicePath = NULL;
+        return EFI_OUT_OF_RESOURCES;
+      }
+      EfiInitializeFwVolDevicepathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempFvFileDevicePath, NameGuid);
+      SetDevicePathEndNode (NextDevicePathNode (TempFvFileDevicePath));
+      *FvFileDevicePath = AppendDevicePath (
+                            FvDevicePath,
+                            (EFI_DEVICE_PATH_PROTOCOL *)TempFvFileDevicePath
+                            );
+    }
+    FreePool (TempFvFileDevicePath);
+  }
+
+  if (HandleBuffer != NULL) {  
+    FreePool (HandleBuffer);
+  }
+  return Status;
+  
+}
