]> git.proxmox.com Git - mirror_edk2.git/commitdiff
StandaloneMmPkg/FvLib: Add a common FV Library for management mode.
authorSupreeth Venkatesh <supreeth.venkatesh@arm.com>
Fri, 13 Jul 2018 15:05:22 +0000 (23:05 +0800)
committerJiewen Yao <jiewen.yao@intel.com>
Fri, 20 Jul 2018 02:55:26 +0000 (10:55 +0800)
This patch implements a firmware volume library that can be used by the
Standalone management mode core module to parse the firmware volume.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Supreeth Venkatesh <supreeth.venkatesh@arm.com>
Reviewed-by: Achin Gupta <achin.gupta@arm.com>
Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
Signed-off-by: Sughosh Ganu <sughosh.ganu@arm.com>
StandaloneMmPkg/Include/Library/FvLib.h [new file with mode: 0644]
StandaloneMmPkg/Library/FvLib/FvLib.c [new file with mode: 0644]
StandaloneMmPkg/Library/FvLib/FvLib.inf [new file with mode: 0644]

diff --git a/StandaloneMmPkg/Include/Library/FvLib.h b/StandaloneMmPkg/Include/Library/FvLib.h
new file mode 100644 (file)
index 0000000..64e65b4
--- /dev/null
@@ -0,0 +1,109 @@
+/** @file\r
+\r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _FV_LIB_H_\r
+#define _FV_LIB_H_\r
+\r
+#include <Uefi.h>\r
+#include <Pi/PiFirmwareVolume.h>\r
+#include <Pi/PiFirmwareFile.h>\r
+\r
+/**\r
+  Given the input file pointer, search for the next matching file in the\r
+  FFS volume as defined by SearchType. The search starts from FileHeader inside\r
+  the Firmware Volume defined by FwVolHeader.\r
+\r
+  @param  SearchType  Filter to find only files of this type.\r
+                      Type EFI_FV_FILETYPE_ALL causes no filtering to be done.\r
+  @param  FwVolHeader Pointer to the FV header of the volume to search.\r
+                      This parameter must point to a valid FFS volume.\r
+  @param  FileHeader  Pointer to the current file from which to begin searching.\r
+                      This pointer will be updated upon return to reflect the file found.\r
+\r
+  @retval EFI_NOT_FOUND  No files matching the search criteria were found\r
+  @retval EFI_SUCCESS\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FfsFindNextFile (\r
+  IN EFI_FV_FILETYPE             SearchType,\r
+  IN EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,\r
+  IN OUT EFI_FFS_FILE_HEADER     **FileHeader\r
+  );\r
+\r
+/**\r
+  Given the input file pointer, search for the next matching section in the\r
+  FFS volume.\r
+\r
+  @param  SearchType    Filter to find only sections of this type.\r
+  @param  FfsFileHeader Pointer to the current file to search.\r
+  @param  SectionHeader Pointer to the Section matching SectionType in FfsFileHeader.\r
+                        NULL if section not found\r
+\r
+  @retval  EFI_NOT_FOUND  No files matching the search criteria were found\r
+  @retval  EFI_SUCCESS\r
+**/\r
+EFI_STATUS\r
+FfsFindSection (\r
+  IN EFI_SECTION_TYPE              SectionType,\r
+  IN EFI_FFS_FILE_HEADER           *FfsFileHeader,\r
+  IN OUT EFI_COMMON_SECTION_HEADER **SectionHeader\r
+  );\r
+\r
+/**\r
+  Locates a section within a series of sections\r
+  with the specified section type.\r
+\r
+  @param[in]   Sections        The sections to search\r
+  @param[in]   SizeOfSections  Total size of all sections\r
+  @param[in]   SectionType     The section type to locate\r
+  @param[out]  FoundSection    The FFS section if found\r
+\r
+  @retval EFI_SUCCESS           The file and section was found\r
+  @retval EFI_NOT_FOUND         The file and section was not found\r
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FindFfsSectionInSections (\r
+  IN  VOID                             *Sections,\r
+  IN  UINTN                            SizeOfSections,\r
+  IN  EFI_SECTION_TYPE                 SectionType,\r
+  OUT EFI_COMMON_SECTION_HEADER        **FoundSection\r
+  );\r
+\r
+/**\r
+  Given the input file pointer, search for the next matching section in the\r
+  FFS volume.\r
+\r
+  @param  SearchType      Filter to find only sections of this type.\r
+  @param  FfsFileHeader   Pointer to the current file to search.\r
+  @param  SectionData     Pointer to the Section matching SectionType in FfsFileHeader.\r
+                          NULL if section not found\r
+  @param  SectionDataSize The size of SectionData\r
+\r
+  @retval  EFI_NOT_FOUND  No files matching the search criteria were found\r
+  @retval  EFI_SUCCESS\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FfsFindSectionData (\r
+  IN EFI_SECTION_TYPE              SectionType,\r
+  IN EFI_FFS_FILE_HEADER           *FfsFileHeader,\r
+  OUT VOID                         **SectionData,\r
+  OUT UINTN                        *SectionDataSize\r
+  );\r
+\r
+#endif\r
diff --git a/StandaloneMmPkg/Library/FvLib/FvLib.c b/StandaloneMmPkg/Library/FvLib/FvLib.c
new file mode 100644 (file)
index 0000000..b6d4916
--- /dev/null
@@ -0,0 +1,385 @@
+/** @file\r
+\r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Library/FvLib.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \\r
+  (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))\r
+\r
+/**\r
+  Returns the highest bit set of the State field\r
+\r
+  @param ErasePolarity   Erase Polarity  as defined by EFI_FVB_ERASE_POLARITY\r
+                         in the Attributes field.\r
+  @param FfsHeader       Pointer to FFS File Header.\r
+\r
+  @return the highest bit in the State field\r
+**/\r
+EFI_FFS_FILE_STATE\r
+GetFileState (\r
+  IN UINT8                ErasePolarity,\r
+  IN EFI_FFS_FILE_HEADER  *FfsHeader\r
+  )\r
+{\r
+  EFI_FFS_FILE_STATE  FileState;\r
+  EFI_FFS_FILE_STATE  HighestBit;\r
+\r
+  FileState = FfsHeader->State;\r
+\r
+  if (ErasePolarity != 0) {\r
+    FileState = (EFI_FFS_FILE_STATE)~FileState;\r
+  }\r
+\r
+  HighestBit = 0x80;\r
+  while (HighestBit != 0 && (HighestBit & FileState) == 0) {\r
+    HighestBit >>= 1;\r
+  }\r
+\r
+  return HighestBit;\r
+}\r
+\r
+/**\r
+  Calculates the checksum of the header of a file.\r
+\r
+  @param FileHeader       Pointer to FFS File Header.\r
+\r
+  @return Checksum of the header.\r
+**/\r
+UINT8\r
+CalculateHeaderChecksum (\r
+  IN EFI_FFS_FILE_HEADER  *FileHeader\r
+  )\r
+{\r
+  UINT8 *ptr;\r
+  UINTN Index;\r
+  UINT8 Sum;\r
+\r
+  Sum = 0;\r
+  ptr = (UINT8 *) FileHeader;\r
+\r
+  for (Index = 0; Index < sizeof (EFI_FFS_FILE_HEADER) - 3; Index += 4) {\r
+    Sum = (UINT8) (Sum + ptr[Index]);\r
+    Sum = (UINT8) (Sum + ptr[Index + 1]);\r
+    Sum = (UINT8) (Sum + ptr[Index + 2]);\r
+    Sum = (UINT8) (Sum + ptr[Index + 3]);\r
+  }\r
+\r
+  for (; Index < sizeof (EFI_FFS_FILE_HEADER); Index++) {\r
+    Sum = (UINT8) (Sum + ptr[Index]);\r
+  }\r
+  //\r
+  // State field (since this indicates the different state of file).\r
+  //\r
+  Sum = (UINT8) (Sum - FileHeader->State);\r
+  //\r
+  // Checksum field of the file is not part of the header checksum.\r
+  //\r
+  Sum = (UINT8) (Sum - FileHeader->IntegrityCheck.Checksum.File);\r
+\r
+  return Sum;\r
+}\r
+\r
+/**\r
+  Given the input file pointer, search for the next matching file in the\r
+  FFS volume as defined by SearchType. The search starts from FileHeader inside\r
+  the Firmware Volume defined by FwVolHeader.\r
+\r
+  @param  SearchType  Filter to find only files of this type.\r
+                      Type EFI_FV_FILETYPE_ALL causes no filtering to be done.\r
+  @param  FwVolHeader Pointer to the FV header of the volume to search.\r
+                      This parameter must point to a valid FFS volume.\r
+  @param  FileHeader  Pointer to the current file from which to begin searching.\r
+                      This pointer will be updated upon return to reflect the file found.\r
+\r
+  @retval EFI_NOT_FOUND  No files matching the search criteria were found\r
+  @retval EFI_SUCCESS\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FfsFindNextFile (\r
+  IN EFI_FV_FILETYPE             SearchType,\r
+  IN EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader,\r
+  IN OUT EFI_FFS_FILE_HEADER     **FileHeader\r
+  )\r
+{\r
+  EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader;\r
+\r
+  EFI_FFS_FILE_HEADER *FfsFileHeader;\r
+  UINT32              FileLength;\r
+  UINT32              FileOccupiedSize;\r
+  UINT32              FileOffset;\r
+  UINT64              FvLength;\r
+  UINT8               ErasePolarity;\r
+  UINT8               FileState;\r
+\r
+  FvLength = FwVolHeader->FvLength;\r
+  if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {\r
+    ErasePolarity = 1;\r
+  } else {\r
+    ErasePolarity = 0;\r
+  }\r
+  //\r
+  // If FileHeader is not specified (NULL) start with the first file in the\r
+  // firmware volume.  Otherwise, start from the FileHeader.\r
+  //\r
+  if (*FileHeader == NULL) {\r
+\r
+    if (FwVolHeader->ExtHeaderOffset != 0) {\r
+\r
+      FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FwVolHeader +\r
+                                                       FwVolHeader->ExtHeaderOffset);\r
+\r
+      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FvExtHeader +\r
+                                              FvExtHeader->ExtHeaderSize);\r
+\r
+    } else {\r
+\r
+      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader +\r
+                                              FwVolHeader->HeaderLength);\r
+\r
+    }\r
+\r
+    FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINTN)FwVolHeader +\r
+                                            ALIGN_VALUE((UINTN)FfsFileHeader -\r
+                                                        (UINTN)FwVolHeader, 8));\r
+  } else {\r
+    //\r
+    // Length is 24 bits wide so mask upper 8 bits\r
+    // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.\r
+    //\r
+    FileLength        = FFS_FILE_SIZE(*FileHeader);\r
+    FileOccupiedSize  = GET_OCCUPIED_SIZE (FileLength, 8);\r
+    FfsFileHeader     = (EFI_FFS_FILE_HEADER *) ((UINT8 *) *FileHeader + FileOccupiedSize);\r
+  }\r
+\r
+  FileOffset = (UINT32) ((UINT8 *) FfsFileHeader - (UINT8 *) FwVolHeader);\r
+\r
+  while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {\r
+    //\r
+    // Get FileState which is the highest bit of the State\r
+    //\r
+    FileState = GetFileState (ErasePolarity, FfsFileHeader);\r
+\r
+    switch (FileState) {\r
+\r
+    case EFI_FILE_HEADER_INVALID:\r
+      FileOffset += sizeof (EFI_FFS_FILE_HEADER);\r
+      FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));\r
+      break;\r
+\r
+    case EFI_FILE_DATA_VALID:\r
+    case EFI_FILE_MARKED_FOR_UPDATE:\r
+      if (CalculateHeaderChecksum (FfsFileHeader) == 0) {\r
+        FileLength        = FFS_FILE_SIZE(FfsFileHeader);\r
+        FileOccupiedSize  = GET_OCCUPIED_SIZE (FileLength, 8);\r
+\r
+        if ((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) {\r
+\r
+          *FileHeader = FfsFileHeader;\r
+\r
+          return EFI_SUCCESS;\r
+        }\r
+\r
+        FileOffset += FileOccupiedSize;\r
+        FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);\r
+      } else {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+      break;\r
+\r
+    case EFI_FILE_DELETED:\r
+      FileLength        = FFS_FILE_SIZE(FfsFileHeader);\r
+      FileOccupiedSize  = GET_OCCUPIED_SIZE (FileLength, 8);\r
+      FileOffset += FileOccupiedSize;\r
+      FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);\r
+      break;\r
+\r
+    default:\r
+      return EFI_NOT_FOUND;\r
+\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Locates a section within a series of sections\r
+  with the specified section type.\r
+\r
+  @param[in]   Sections        The sections to search\r
+  @param[in]   SizeOfSections  Total size of all sections\r
+  @param[in]   SectionType     The section type to locate\r
+  @param[out]  FoundSection    The FFS section if found\r
+\r
+  @retval EFI_SUCCESS           The file and section was found\r
+  @retval EFI_NOT_FOUND         The file and section was not found\r
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FindFfsSectionInSections (\r
+  IN  VOID                             *Sections,\r
+  IN  UINTN                            SizeOfSections,\r
+  IN  EFI_SECTION_TYPE                 SectionType,\r
+  OUT EFI_COMMON_SECTION_HEADER        **FoundSection\r
+  )\r
+{\r
+  EFI_PHYSICAL_ADDRESS        CurrentAddress;\r
+  UINT32                      Size;\r
+  EFI_PHYSICAL_ADDRESS        EndOfSections;\r
+  EFI_COMMON_SECTION_HEADER   *Section;\r
+  EFI_PHYSICAL_ADDRESS        EndOfSection;\r
+\r
+  //\r
+  // Loop through the FFS file sections\r
+  //\r
+  EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;\r
+  EndOfSections = EndOfSection + SizeOfSections;\r
+  for (;;) {\r
+    if (EndOfSection == EndOfSections) {\r
+      break;\r
+    }\r
+    CurrentAddress = EndOfSection;\r
+\r
+    Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;\r
+\r
+    Size = SECTION_SIZE (Section);\r
+    if (Size < sizeof (*Section)) {\r
+      return EFI_VOLUME_CORRUPTED;\r
+    }\r
+\r
+    EndOfSection = CurrentAddress + Size;\r
+    if (EndOfSection > EndOfSections) {\r
+      return EFI_VOLUME_CORRUPTED;\r
+    }\r
+    Size = GET_OCCUPIED_SIZE (Size, 4);\r
+\r
+    //\r
+    // Look for the requested section type\r
+    //\r
+    if (Section->Type == SectionType) {\r
+      *FoundSection = Section;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Given the input file pointer, search for the next matching section in the\r
+  FFS volume.\r
+\r
+  @param  SearchType    Filter to find only sections of this type.\r
+  @param  FfsFileHeader Pointer to the current file to search.\r
+  @param  SectionHeader Pointer to the Section matching SectionType in FfsFileHeader.\r
+                        NULL if section not found\r
+\r
+  @retval  EFI_NOT_FOUND  No files matching the search criteria were found\r
+  @retval  EFI_SUCCESS\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FfsFindSection (\r
+  IN EFI_SECTION_TYPE              SectionType,\r
+  IN EFI_FFS_FILE_HEADER           *FfsFileHeader,\r
+  IN OUT EFI_COMMON_SECTION_HEADER **SectionHeader\r
+  )\r
+{\r
+  UINT32                    FileSize;\r
+  EFI_COMMON_SECTION_HEADER *Section;\r
+  EFI_STATUS                Status;\r
+\r
+  //\r
+  // Size is 24 bits wide so mask upper 8 bits.\r
+  //    Does not include FfsFileHeader header size\r
+  // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.\r
+  //\r
+  Section   = (EFI_COMMON_SECTION_HEADER *) (FfsFileHeader + 1);\r
+  FileSize  = FFS_FILE_SIZE(FfsFileHeader);\r
+  FileSize -= sizeof (EFI_FFS_FILE_HEADER);\r
+\r
+  Status = FindFfsSectionInSections (\r
+             Section,\r
+             FileSize,\r
+             SectionType,\r
+             SectionHeader\r
+             );\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Given the input file pointer, search for the next matching section in the\r
+  FFS volume.\r
+\r
+  @param  SearchType      Filter to find only sections of this type.\r
+  @param  FfsFileHeader   Pointer to the current file to search.\r
+  @param  SectionData     Pointer to the Section matching SectionType in FfsFileHeader.\r
+                          NULL if section not found\r
+  @param  SectionDataSize The size of SectionData\r
+\r
+  @retval  EFI_NOT_FOUND  No files matching the search criteria were found\r
+  @retval  EFI_SUCCESS\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FfsFindSectionData (\r
+  IN EFI_SECTION_TYPE      SectionType,\r
+  IN EFI_FFS_FILE_HEADER   *FfsFileHeader,\r
+  IN OUT VOID              **SectionData,\r
+  IN OUT UINTN             *SectionDataSize\r
+  )\r
+{\r
+  UINT32                    FileSize;\r
+  EFI_COMMON_SECTION_HEADER *Section;\r
+  UINT32                    SectionLength;\r
+  UINT32                    ParsedLength;\r
+\r
+  //\r
+  // Size is 24 bits wide so mask upper 8 bits.\r
+  // Does not include FfsFileHeader header size\r
+  // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.\r
+  //\r
+  Section   = (EFI_COMMON_SECTION_HEADER *) (FfsFileHeader + 1);\r
+  FileSize  = FFS_FILE_SIZE(FfsFileHeader);\r
+  FileSize -= sizeof (EFI_FFS_FILE_HEADER);\r
+\r
+  *SectionData  = NULL;\r
+  ParsedLength  = 0;\r
+  while (ParsedLength < FileSize) {\r
+    if (Section->Type == SectionType) {\r
+      *SectionData = (VOID *) (Section + 1);\r
+      *SectionDataSize = SECTION_SIZE(Section);\r
+      return EFI_SUCCESS;\r
+    }\r
+    //\r
+    // Size is 24 bits wide so mask upper 8 bits.\r
+    // SectionLength is adjusted it is 4 byte aligned.\r
+    // Go to the next section\r
+    //\r
+    SectionLength = SECTION_SIZE(Section);\r
+    SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
+\r
+    ParsedLength += SectionLength;\r
+    Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength);\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
diff --git a/StandaloneMmPkg/Library/FvLib/FvLib.inf b/StandaloneMmPkg/Library/FvLib/FvLib.inf
new file mode 100644 (file)
index 0000000..f768810
--- /dev/null
@@ -0,0 +1,57 @@
+## @file\r
+#\r
+#  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  INF_VERSION                    = 0x0001001A\r
+  BASE_NAME                      = FvLib\r
+  FILE_GUID                      = C20085E9-E3AB-4938-A727-C10935FEEE2B\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = FvLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32\r
+#\r
+\r
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources]\r
+  FvLib.c\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  StandaloneMmPkg/StandaloneMmPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r