]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/DxePiLib/DxePiLib.c
Merge branch of PI tree to main trunk
[mirror_edk2.git] / MdePkg / Library / DxePiLib / DxePiLib.c
index 3261e08ade6db7cec3a77da643cc1b37b23d1ca1..32e0337c19c97e2b073134431e4f6b6524b9a55c 100644 (file)
@@ -16,6 +16,7 @@
 #include <Library/DebugLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/PiLib.h>\r
 #include <Protocol/FirmwareVolume2.h>\r
 #include <Protocol/LoadedImage.h>\r
 \r
@@ -40,7 +41,7 @@
 **/\r
 STATIC\r
 EFI_STATUS\r
-GetImageFromFv (\r
+InternalGetImageFromFv (\r
   IN         EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,\r
   IN  CONST  EFI_GUID           *NameGuid,\r
   IN         EFI_SECTION_TYPE   SectionType,\r
@@ -193,7 +194,7 @@ GetSectionFromFvFile (
                     (VOID **) &ImageFv\r
                     );\r
     if (!EFI_ERROR (Status)) {\r
-      Status = GetImageFromFv (ImageFv, NameGuid, SectionType, Buffer, Size);\r
+      Status = InternalGetImageFromFv (ImageFv, NameGuid, SectionType, Buffer, Size);\r
     }\r
   }\r
 \r
@@ -231,7 +232,7 @@ GetSectionFromFvFile (
       continue;\r
     }\r
 \r
-    Status = GetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size);\r
+    Status = InternalGetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size);\r
 \r
     if (!EFI_ERROR (Status)) {\r
       goto Done;\r
@@ -254,3 +255,216 @@ Done:
   return Status;\r
 }\r
 \r
+EFI_HANDLE\r
+EFIAPI\r
+ImageHandleToFvHandle (\r
+  EFI_HANDLE ImageHandle\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;\r
+  \r
+  ASSERT (ImageHandle != NULL);\r
+\r
+  Status = gBS->HandleProtocol (\r
+             (EFI_HANDLE *) ImageHandle,\r
+             &gEfiLoadedImageProtocolGuid,\r
+             (VOID **) &LoadedImage\r
+             );\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return LoadedImage->DeviceHandle;\r
+\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetSectionFromAnyFv (\r
+  IN CONST  EFI_GUID           *NameGuid,\r
+  IN        EFI_SECTION_TYPE   SectionType,\r
+  IN        UINTN              Instance,\r
+  OUT       VOID               **Buffer,\r
+  OUT       UINTN              *Size\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_HANDLE                    *HandleBuffer;\r
+  UINTN                         HandleCount;\r
+  UINTN                         Index;\r
+  EFI_HANDLE                    FvHandle;\r
+  EFI_TPL                       OldTpl;\r
+\r
+  //\r
+  // Search the FV that contain the caller's FFS first.\r
+  // FV builder can choose to build FFS into the this FV\r
+  // so that this implementation of GetSectionFromAnyFv\r
+  // will locate the FFS faster.\r
+  //\r
+  FvHandle = ImageHandleToFvHandle (gImageHandle);\r
+  Status = GetSectionFromFv (\r
+             FvHandle,\r
+             NameGuid,\r
+             SectionType,\r
+             Instance,\r
+             Buffer,\r
+             Size\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+  \r
+  HandleBuffer = NULL;\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiFirmwareVolume2ProtocolGuid,\r
+                  NULL,\r
+                  &HandleCount,\r
+                  &HandleBuffer\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  for (Index = 0; Index < HandleCount; ++Index) {\r
+    //\r
+    // Skip the FV that contain the caller's FFS\r
+    //\r
+    if (HandleBuffer[Index] == FvHandle) {\r
+      continue;\r
+    }\r
+\r
+    Status = GetSectionFromFv (\r
+               HandleBuffer[Index], \r
+               NameGuid, \r
+               SectionType, \r
+               Instance,\r
+               Buffer, \r
+               Size\r
+               );\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  if (Index == HandleCount) {\r
+    Status = EFI_NOT_FOUND;\r
+  }\r
+\r
+Done:\r
+  \r
+  gBS->RestoreTPL (OldTpl);\r
+  \r
+  if (HandleBuffer != NULL) {  \r
+    FreePool(HandleBuffer);\r
+  }\r
+  return Status;\r
+  \r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetSectionFromFv (\r
+  IN  EFI_HANDLE                    FvHandle,\r
+  IN  CONST EFI_GUID                *NameGuid,\r
+  IN  EFI_SECTION_TYPE              SectionType,\r
+  IN  UINTN                         Instance,\r
+  OUT VOID                          **Buffer,\r
+  OUT UINTN                         *Size\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
+  UINT32                        AuthenticationStatus;\r
+\r
+  ASSERT (FvHandle != NULL);\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  FvHandle,\r
+                  &gEfiFirmwareVolume2ProtocolGuid,\r
+                  (VOID **) &Fv\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Read desired section content in NameGuid file\r
+  //\r
+  *Buffer     = NULL;\r
+  *Size       = 0;\r
+  Status      = Fv->ReadSection (\r
+                      Fv,\r
+                      NameGuid,\r
+                      SectionType,\r
+                      0,\r
+                      Buffer,\r
+                      Size,\r
+                      &AuthenticationStatus\r
+                      );\r
+\r
+  if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {\r
+    //\r
+    // Try reading PE32 section, if the required section is TE type \r
+    //\r
+    *Buffer = NULL;\r
+    *Size   = 0;\r
+    Status  = Fv->ReadSection (\r
+                    Fv,\r
+                    NameGuid,\r
+                    EFI_SECTION_PE32,\r
+                    0,\r
+                    Buffer,\r
+                    Size,\r
+                    &AuthenticationStatus\r
+                    );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetSectionFromCurrentFv (\r
+  IN  CONST EFI_GUID                *NameGuid,\r
+  IN  EFI_SECTION_TYPE              SectionType,\r
+  IN  UINTN                         Instance,\r
+  OUT VOID                          **Buffer,\r
+  OUT UINTN                         *Size\r
+    )\r
+{\r
+  return GetSectionFromFv(\r
+          ImageHandleToFvHandle(gImageHandle),\r
+          NameGuid,\r
+          SectionType,\r
+          Instance,\r
+          Buffer,\r
+          Size\r
+          );\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+GetSectionFromCurrentFfs (\r
+  IN  EFI_SECTION_TYPE              SectionType,\r
+  IN  UINTN                         Instance,\r
+  OUT VOID                          **Buffer,\r
+  OUT UINTN                         *Size\r
+    )\r
+{\r
+  return GetSectionFromFv(\r
+          ImageHandleToFvHandle(gImageHandle),\r
+          &gEfiCallerIdGuid,\r
+          SectionType,\r
+          Instance,\r
+          Buffer,\r
+          Size\r
+          );\r
+}\r
+\r