Dear MdeModulePkg maintainers,

Please see attached patch. I follow the suggestions from previous email thread 
and update the patch.

MdeModulePkg : Add a new DxeServicesLib GetFileDevicePathFromAnyFv () function

Contributed-under: TianoCore Contribution Agreement 1.0
From: Shia Cinnamon <cinnamon.s...@hpe.com>
Signed-off-by: Wang Nickle <nickle.w...@hpe.com>
--
MdePkg/Include/Library/DxeServicesLib.h        |  43 +++++++
MdePkg/Library/DxeServicesLib/DxeServicesLib.c | 156 +++++++++++++++++++++++++
2 files changed, 199 insertions(+)

diff --git a/MdePkg/Include/Library/DxeServicesLib.h 
b/MdePkg/Include/Library/DxeServicesLib.h
index e01dd49..79d880d 100644
--- a/MdePkg/Include/Library/DxeServicesLib.h
+++ b/MdePkg/Include/Library/DxeServicesLib.h
@@ -3,6 +3,7 @@
   These functions help access data from sections of FFS files or from file 
path.
 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<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.
 The full text of the license may be found at
@@ -262,5 +263,47 @@ GetFileBufferByFilePath (
   OUT UINT32                           *AuthenticationStatus
   );
+/**
+  Searches all the available firmware volumes and returns the file device path 
of 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 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().
+
+  @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  FvFileDevicePath     Device path for the target FFS
+                               file.
+
+  @retval  EFI_SUCCESS          The specified file device path of FFS section 
was returned.
+  @retval  EFI_NOT_FOUND        The specified file device path of FFS section 
could not be found.
+  @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.
+  @retval  EFI_INVALID_PARAMETER FvFileDevicePath is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetFileDevicePathFromAnyFv (
+  IN CONST  EFI_GUID                  *NameGuid,
+  IN        EFI_SECTION_TYPE          SectionType,
+  IN        UINTN                     SectionInstance,
+  OUT       EFI_DEVICE_PATH_PROTOCOL  **FvFileDevicePath
+  );
+
#endif
diff --git a/MdePkg/Library/DxeServicesLib/DxeServicesLib.c 
b/MdePkg/Library/DxeServicesLib/DxeServicesLib.c
index c8f0014..10f6042 100644
--- a/MdePkg/Library/DxeServicesLib/DxeServicesLib.c
+++ b/MdePkg/Library/DxeServicesLib/DxeServicesLib.c
@@ -3,6 +3,7 @@
   These functions help access data from sections of FFS files or from file 
path.
   Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<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
@@ -927,3 +928,158 @@ Finish:
   return ImageBuffer;
}
+
+/**
+  Searches all the available firmware volumes and returns the file device path 
of 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 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().
+
+  @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  FvFileDevicePath     Device path for the target FFS
+                               file.
+
+  @retval  EFI_SUCCESS          The specified file device path of FFS section 
was returned.
+  @retval  EFI_NOT_FOUND        The specified file device path of FFS section 
could not be found.
+  @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.
+  @retval  EFI_INVALID_PARAMETER FvFileDevicePath is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetFileDevicePathFromAnyFv (
+  IN CONST  EFI_GUID                  *NameGuid,
+  IN        EFI_SECTION_TYPE          SectionType,
+  IN        UINTN                     SectionInstance,
+  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;
+  VOID                              *Buffer;
+  UINTN                             Size;
+
+  if (FvFileDevicePath == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  HandleBuffer         = NULL;
+  FvDevicePath         = NULL;
+  TempFvFileDevicePath = NULL;
+  Buffer               = NULL;
+  Size                 = 0;
+
+  //
+  // 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)) {
+        //
+        // Update FvHandle to the current handle.
+        //
+        FvHandle = HandleBuffer[Index];
+        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 (Buffer != NULL) {
+    FreePool (Buffer);
+  }
+
+  if (HandleBuffer != NULL) {
+    FreePool (HandleBuffer);
+  }
+
+  return Status;
+}
--
2.5.1.windows.1

From: Shia, Cinnamon
Sent: Friday, December 12, 2014 11:01 PM
To: edk2-de...@lists.sourceforge.net<mailto:edk2-de...@lists.sourceforge.net>
Subject: Re: [edk2] [PATHCH] MdeModulePkg : Add a new DxeServicesLib 
GetSectionFromAnyFvEx() function

Hello Feng and Mike,

After rethinking about the your proposal, it looks great and make sense to me. 
Will submit a new patch later.
Thanks!

Thanks,
Cinnamon Shia

From: Kinney, Michael D [mailto:michael.d.kin...@intel.com]
Sent: Friday, December 12, 2014 2:03 AM
To: edk2-de...@lists.sourceforge.net<mailto:edk2-de...@lists.sourceforge.net>
Subject: Re: [edk2] [PATHCH] MdeModulePkg : Add a new DxeServicesLib 
GetSectionFromAnyFvEx() function

Cinnamon Shia,

I think the original proposal would read the FFS file contents twice.

Since the new API being proposed returns the Device Path to the FFS file in a 
specific FV, LoadImage() will not search.  It knows from the Device Patch 
exactly where to load the FFS file from.

Mike

From: Shia, Cinnamon [mailto:cinnamon.s...@hp.com]
Sent: Thursday, December 11, 2014 6:55 AM
To: edk2-de...@lists.sourceforge.net<mailto:edk2-de...@lists.sourceforge.net>
Subject: Re: [edk2] [PATHCH] MdeModulePkg : Add a new DxeServicesLib 
GetSectionFromAnyFvEx() function

Hello Feng,

After checking the usage of LoadImage(), your new proposal makes sense to me.

  If SourceBuffer is NULL, the function is a file copy operation that uses the 
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.

My concern is that searching all the firmware volumes for FFS files will be 
done twice. (One is from GetSectionFromAnyFvEx() and the other one is from 
LoadImage().)

Thanks,
Cinnamon Shia

From: Shia, Cinnamon
Sent: Thursday, December 11, 2014 9:18 PM
To: edk2-de...@lists.sourceforge.net<mailto:edk2-de...@lists.sourceforge.net>
Subject: Re: [edk2] [PATHCH] MdeModulePkg : Add a new DxeServicesLib 
GetSectionFromAnyFvEx() function

Hello Feng,

If I understand your proposal correctly, for loading and starting an image from 
FVs, we have to call GetSectionFromAnyFv to load the section to memory, and 
then call GetSectionFromAnyFvEx to get the device path, right?
If so, it means searching all the firmware volumes for FFS files will be done 
twice.

The thought for the original proposal is that It doesn't affect the existing 
code: For the case of loading/starting an image from FVs, we can use 
GetSectionFromAnyFvEx. In other cases, we can call GetSectionFromAnyFv().

Your feedback is appreciated.

Thanks,
Cinnamon Shia

From: Tian, Feng [mailto:feng.t...@intel.com]
Sent: Wednesday, December 10, 2014 10:32 AM
To: edk2-de...@lists.sourceforge.net<mailto:edk2-de...@lists.sourceforge.net>
Subject: Re: [edk2] [PATHCH] MdeModulePkg : Add a new DxeServicesLib 
GetSectionFromAnyFvEx() function

Hi, Samer and Cinnamon,

After internal discussion on your usage model, we suggest to only return 
FvFileDevicePath and not return Buffer and Size at new API, that's

+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
+  );

Of course you can propose a new func name for this new API:)

Thanks
Feng

From: Tian, Feng
Sent: Monday, December 08, 2014 09:43
To: edk2-de...@lists.sourceforge.net<mailto:edk2-de...@lists.sourceforge.net>
Cc: Tian, Feng
Subject: RE: [edk2] [PATHCH] MdeModulePkg : Add a new DxeServicesLib 
GetSectionFromAnyFvEx() function

Samer and Cinnamon,

I am not sure if it's valuable for being a library service. Look like you can 
put the constructing of the device patch outside the GetSectionFromAnyFvEx() 
also.

Anyway I have known your usage model now. Let me raise it to internal for more 
discussions.

PS: Why do other APIs in DxeSerivceLib have no such Ex() extensions?

Thanks
Feng

From: El-Haj-Mahmoud, Samer [mailto:samer.el-haj-mahm...@hp.com]
Sent: Saturday, December 06, 2014 03:25
To: edk2-de...@lists.sourceforge.net<mailto:edk2-de...@lists.sourceforge.net>
Subject: Re: [edk2] [PATHCH] MdeModulePkg : Add a new DxeServicesLib 
GetSectionFromAnyFvEx() function

Feng,

In addition to Secure Boot, there are other use cases where an application 
would like to identify where it was loaded from (by examining the device path 
of the image). Without this change, an application embedded in an FV does not 
get its device path passed to it using the Image Load service.


From: Shia, Cinnamon
Sent: Wednesday, December 03, 2014 9:41 PM
To: edk2-de...@lists.sourceforge.net<mailto:edk2-de...@lists.sourceforge.net>
Subject: Re: [edk2] [PATHCH] MdeModulePkg : Add a new DxeServicesLib 
GetSectionFromAnyFvEx() function

Hello Feng,

Thanks for your reply.

The problem is that if secure boot is enabled, the loadImage() needs device 
paths to determine where the image is.
If a NULL device path is passed, it would be treated as an invalid image by 
DxeImageVerificationHandler(), which is called in LoadImage().


Thanks,
Cinnamon Shia

From: Tian, Feng [mailto:feng.t...@intel.com]
Sent: Tuesday, December 02, 2014 1:18 PM
To: edk2-de...@lists.sourceforge.net<mailto:edk2-de...@lists.sourceforge.net>
Subject: Re: [edk2] [PATCH] MdeModulePkg : Add a new DxeServicesLib 
GetSectionFromAnyFvEx() function

Hi, Samer

If it's such usage case, why you don't use the below logic?

      Status = GetSectionFromAnyFv (
            &AppGuid,
            EFI_SECTION_PE32,
            0,
            &AppImageBase,
            &AppImageSize
            );
      Status = gBS->LoadImage (
                  TRUE,
                  gImageHandle,
                  NULL,
                  AppImageBase,
                  AppImageSize,
                  &ImageHandle
                  );
      Status = gBS->StartImage (ImageHandle, NULL, NULL);

It doesn't need construct device path at all.

Thanks
Feng

From: El-Haj-Mahmoud, Samer [mailto:samer.el-haj-mahm...@hp.com]
Sent: Tuesday, December 02, 2014 03:22
To: edk2-de...@lists.sourceforge.net<mailto:edk2-de...@lists.sourceforge.net>
Subject: Re: [edk2] [PATCH] MdeModulePkg : Add a new DxeServicesLib 
GetSectionFromAnyFvEx() function

One possible usage is to be able to load an application from a FV.


*         Need to search for the EFI application in all FVs using 
GetSectionFromAnyFvEx()

*         Once found, the file is loaded from FV to memory (in Buffer and Size 
outputs of GetSectionFromAnyFvEx()

*         We then need to load and start the image using gBS->LoadImage() and 
gBS->StartImage()

*         Load image has a DevicePath input parameter of where the image is 
loaded from

The original GetSectionFromAnyFv() did not return the device path and was not 
suitable for this use case.

Thanks,
--Samer


From: Tian, Feng [mailto:feng.t...@intel.com]
Sent: Tuesday, November 25, 2014 6:24 PM
To: edk2-de...@lists.sourceforge.net<mailto:edk2-de...@lists.sourceforge.net>
Subject: Re: [edk2] [PATCH] MdeModulePkg : Add a new DxeServicesLib 
GetSectionFromAnyFvEx() function

Hi, Samer

As your proposed patch involves interface change, we need review it carefully 
and the response may be slow.

Could you let me know at which case/usage model you need to get this FV file's 
device path?

Thanks
Feng

From: El-Haj-Mahmoud, Samer [mailto:samer.el-haj-mahm...@hp.com]
Sent: Wednesday, November 26, 2014 06:28
To: edk2-de...@lists.sourceforge.net<mailto:edk2-de...@lists.sourceforge.net>
Subject: Re: [edk2] [PATCH] MdeModulePkg : Add a new DxeServicesLib 
GetSectionFromAnyFvEx() function

Resending with actual patch file

Thanks,
--Samer

From: El-Haj-Mahmoud, Samer
Sent: Tuesday, November 25, 2014 4:24 PM
To: edk2-de...@lists.sourceforge.net<mailto:edk2-de...@lists.sourceforge.net>
Subject: [PATCH] MdeModulePkg : Add a new DxeServicesLib 
GetSectionFromAnyFvEx() function

Dear MdeModulePkg maintainers,

Please see attached patch


Add a new DxeServicesLib function GetSectionFromAnyFvEx() to search all 
firmware volumes for

A specified FFS file, and return the first matching FFS section. The function 
is identical to

GetSectionFromAnyFv(), but it also returns a pointer to the FV file device path.


Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Samer El-Haj-Mahmoud el...@hp.com<mailto:el...@hp.com>

Thanks,

Samer El-Haj-Mahmoud
System Firmware Architect
HP Servers

el...@hp.com<mailto:el...@hp.com>
T +1.281.514.5973
C +1.512.659.1523
Hewlett-Packard Company
hp.com/go/proliant/uefi<http://hp.com/go/proliant/uefi>

[Description: Description: C:\Users\elhajmah\HpLogo.png]


_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to