]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Pei/FwVol/FwVol.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Core / Pei / FwVol / FwVol.c
index e505c707b075771cd13e724e097757f1b5dd412b..60bbe57332b7fa0151cda811c02f973d88711b8f 100644 (file)
@@ -1,26 +1,28 @@
 /** @file\r
   Pei Core Firmware File System service routines.\r
-  \r
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\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
+Copyright (c) 2015 HP Development Company, L.P.\r
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "FwVol.h"\r
 \r
-EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList = {\r
-  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
-  &gEfiPeiFirmwareVolumeInfoPpiGuid,\r
-  FirmwareVolmeInfoPpiNotifyCallback \r
+EFI_PEI_NOTIFY_DESCRIPTOR  mNotifyOnFvInfoList[] = {\r
+  {\r
+    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
+    &gEfiPeiFirmwareVolumeInfoPpiGuid,\r
+    FirmwareVolumeInfoPpiNotifyCallback\r
+  },\r
+  {\r
+    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+    &gEfiPeiFirmwareVolumeInfo2PpiGuid,\r
+    FirmwareVolumeInfoPpiNotifyCallback\r
+  }\r
 };\r
 \r
-PEI_FW_VOL_INSTANCE mPeiFfs2FwVol = {\r
+PEI_FW_VOL_INSTANCE  mPeiFfs2FwVol = {\r
   PEI_FW_VOL_SIGNATURE,\r
   FALSE,\r
   {\r
@@ -29,11 +31,15 @@ PEI_FW_VOL_INSTANCE mPeiFfs2FwVol = {
     PeiFfsFvPpiFindFileByName,\r
     PeiFfsFvPpiGetFileInfo,\r
     PeiFfsFvPpiGetVolumeInfo,\r
-    PeiFfsFvPpiFindSectionByType\r
+    PeiFfsFvPpiFindSectionByType,\r
+    PeiFfsFvPpiGetFileInfo2,\r
+    PeiFfsFvPpiFindSectionByType2,\r
+    EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE,\r
+    EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION\r
   }\r
 };\r
 \r
-PEI_FW_VOL_INSTANCE mPeiFfs3FwVol = {\r
+PEI_FW_VOL_INSTANCE  mPeiFfs3FwVol = {\r
   PEI_FW_VOL_SIGNATURE,\r
   TRUE,\r
   {\r
@@ -42,10 +48,14 @@ PEI_FW_VOL_INSTANCE mPeiFfs3FwVol = {
     PeiFfsFvPpiFindFileByName,\r
     PeiFfsFvPpiGetFileInfo,\r
     PeiFfsFvPpiGetVolumeInfo,\r
-    PeiFfsFvPpiFindSectionByType\r
+    PeiFfsFvPpiFindSectionByType,\r
+    PeiFfsFvPpiGetFileInfo2,\r
+    PeiFfsFvPpiFindSectionByType2,\r
+    EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE,\r
+    EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION\r
   }\r
 };\r
-            \r
+\r
 EFI_PEI_PPI_DESCRIPTOR  mPeiFfs2FvPpiList = {\r
   (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
   &gEfiFirmwareFileSystem2Guid,\r
@@ -59,18 +69,27 @@ EFI_PEI_PPI_DESCRIPTOR  mPeiFfs3FvPpiList = {
 };\r
 \r
 /**\r
-Required Alignment             Alignment Value in FFS         Alignment Value in\r
-(bytes)                        Attributes Field               Firmware Volume Interfaces\r
-1                                    0                                     0\r
-16                                   1                                     4\r
-128                                  2                                     7\r
-512                                  3                                     9\r
-1 KB                                 4                                     10\r
-4 KB                                 5                                     12\r
-32 KB                                6                                     15\r
-64 KB                                7                                     16\r
+Required Alignment   Alignment Value in FFS   FFS_ATTRIB_DATA_ALIGNMENT2   Alignment Value in\r
+(bytes)              Attributes Field         in FFS Attributes Field      Firmware Volume Interfaces\r
+1                               0                          0                            0\r
+16                              1                          0                            4\r
+128                             2                          0                            7\r
+512                             3                          0                            9\r
+1 KB                            4                          0                            10\r
+4 KB                            5                          0                            12\r
+32 KB                           6                          0                            15\r
+64 KB                           7                          0                            16\r
+128 KB                          0                          1                            17\r
+256 KB                          1                          1                            18\r
+512 KB                          2                          1                            19\r
+1 MB                            3                          1                            20\r
+2 MB                            4                          1                            21\r
+4 MB                            5                          1                            22\r
+8 MB                            6                          1                            23\r
+16 MB                           7                          1                            24\r
 **/\r
-UINT8 mFvAttributes[] = {0, 4, 7, 9, 10, 12, 15, 16};\r
+UINT8  mFvAttributes[]  = { 0, 4, 7, 9, 10, 12, 15, 16 };\r
+UINT8  mFvAttributes2[] = { 17, 18, 19, 20, 21, 22, 23, 24 };\r
 \r
 /**\r
   Convert the FFS File Attributes to FV File Attributes\r
@@ -82,16 +101,20 @@ UINT8 mFvAttributes[] = {0, 4, 7, 9, 10, 12, 15, 16};
 **/\r
 EFI_FV_FILE_ATTRIBUTES\r
 FfsAttributes2FvFileAttributes (\r
-  IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes\r
+  IN EFI_FFS_FILE_ATTRIBUTES  FfsAttributes\r
   )\r
 {\r
-  UINT8                     DataAlignment;\r
-  EFI_FV_FILE_ATTRIBUTES    FileAttribute;\r
+  UINT8                   DataAlignment;\r
+  EFI_FV_FILE_ATTRIBUTES  FileAttribute;\r
 \r
-  DataAlignment = (UINT8) ((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);\r
+  DataAlignment = (UINT8)((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);\r
   ASSERT (DataAlignment < 8);\r
 \r
-  FileAttribute = (EFI_FV_FILE_ATTRIBUTES) mFvAttributes[DataAlignment];\r
+  if ((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT_2) != 0) {\r
+    FileAttribute = (EFI_FV_FILE_ATTRIBUTES)mFvAttributes2[DataAlignment];\r
+  } else {\r
+    FileAttribute = (EFI_FV_FILE_ATTRIBUTES)mFvAttributes[DataAlignment];\r
+  }\r
 \r
   if ((FfsAttributes & FFS_ATTRIB_FIXED) == FFS_ATTRIB_FIXED) {\r
     FileAttribute |= EFI_FV_FILE_ATTRIB_FIXED;\r
@@ -107,11 +130,11 @@ FfsAttributes2FvFileAttributes (
                          in the Attributes field.\r
   @param FfsHeader       Pointer to FFS File Header.\r
 \r
-  @retval EFI_FFS_FILE_STATE File state is set by the highest none zero bit \r
+  @retval EFI_FFS_FILE_STATE File state is set by the highest none zero bit\r
                              in the header State field.\r
 **/\r
 EFI_FFS_FILE_STATE\r
-GetFileState(\r
+GetFileState (\r
   IN UINT8                ErasePolarity,\r
   IN EFI_FFS_FILE_HEADER  *FfsHeader\r
   )\r
@@ -122,9 +145,9 @@ GetFileState(
   FileState = FfsHeader->State;\r
 \r
   if (ErasePolarity != 0) {\r
-    FileState = (EFI_FFS_FILE_STATE)~FileState;\r
+    FileState = (EFI_FFS_FILE_STATE) ~FileState;\r
   }\r
-  \r
+\r
   //\r
   // Get file state set by its highest none zero bit.\r
   //\r
@@ -134,7 +157,7 @@ GetFileState(
   }\r
 \r
   return HighestBit;\r
-} \r
+}\r
 \r
 /**\r
   Calculates the checksum of the header of a file.\r
@@ -150,26 +173,26 @@ CalculateHeaderChecksum (
   IN EFI_FFS_FILE_HEADER  *FileHeader\r
   )\r
 {\r
-  EFI_FFS_FILE_HEADER2 TestFileHeader;\r
+  EFI_FFS_FILE_HEADER2  TestFileHeader;\r
 \r
   if (IS_FFS_FILE2 (FileHeader)) {\r
     CopyMem (&TestFileHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER2));\r
     //\r
-    // Ingore State and File field in FFS header.\r
+    // Ignore State and File field in FFS header.\r
     //\r
-    TestFileHeader.State = 0;\r
+    TestFileHeader.State                        = 0;\r
     TestFileHeader.IntegrityCheck.Checksum.File = 0;\r
 \r
-    return CalculateSum8 ((CONST UINT8 *) &TestFileHeader, sizeof (EFI_FFS_FILE_HEADER2));\r
+    return CalculateSum8 ((CONST UINT8 *)&TestFileHeader, sizeof (EFI_FFS_FILE_HEADER2));\r
   } else {\r
     CopyMem (&TestFileHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER));\r
     //\r
-    // Ingore State and File field in FFS header.\r
+    // Ignore State and File field in FFS header.\r
     //\r
-    TestFileHeader.State = 0;\r
+    TestFileHeader.State                        = 0;\r
     TestFileHeader.IntegrityCheck.Checksum.File = 0;\r
 \r
-    return CalculateSum8 ((CONST UINT8 *) &TestFileHeader, sizeof (EFI_FFS_FILE_HEADER));\r
+    return CalculateSum8 ((CONST UINT8 *)&TestFileHeader, sizeof (EFI_FFS_FILE_HEADER));\r
   }\r
 }\r
 \r
@@ -177,27 +200,46 @@ CalculateHeaderChecksum (
   Find FV handler according to FileHandle in that FV.\r
 \r
   @param FileHandle      Handle of file image\r
-  \r
+\r
   @return Pointer to instance of PEI_CORE_FV_HANDLE.\r
 **/\r
-PEI_CORE_FV_HANDLE*\r
+PEI_CORE_FV_HANDLE *\r
 FileHandleToVolume (\r
-  IN   EFI_PEI_FILE_HANDLE          FileHandle\r
+  IN   EFI_PEI_FILE_HANDLE  FileHandle\r
   )\r
 {\r
   UINTN                       Index;\r
   PEI_CORE_INSTANCE           *PrivateData;\r
   EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;\r
+  UINTN                       BestIndex;\r
 \r
   PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());\r
-  \r
+  BestIndex   = PrivateData->FvCount;\r
+\r
+  //\r
+  // Find the best matched FV image that includes this FileHandle.\r
+  // FV may include the child FV, and they are in the same continuous space.\r
+  // If FileHandle is from the child FV, the updated logic can find its matched FV.\r
+  //\r
   for (Index = 0; Index < PrivateData->FvCount; Index++) {\r
     FwVolHeader = PrivateData->Fv[Index].FvHeader;\r
-    if (((UINT64) (UINTN) FileHandle > (UINT64) (UINTN) FwVolHeader ) &&   \\r
-        ((UINT64) (UINTN) FileHandle <= ((UINT64) (UINTN) FwVolHeader + FwVolHeader->FvLength - 1))) {\r
-      return &PrivateData->Fv[Index];\r
+    if (((UINT64)(UINTN)FileHandle > (UINT64)(UINTN)FwVolHeader) &&   \\r
+        ((UINT64)(UINTN)FileHandle <= ((UINT64)(UINTN)FwVolHeader + FwVolHeader->FvLength - 1)))\r
+    {\r
+      if (BestIndex == PrivateData->FvCount) {\r
+        BestIndex = Index;\r
+      } else {\r
+        if ((UINT64)(UINTN)PrivateData->Fv[BestIndex].FvHeader < (UINT64)(UINTN)FwVolHeader) {\r
+          BestIndex = Index;\r
+        }\r
+      }\r
     }\r
   }\r
+\r
+  if (BestIndex < PrivateData->FvCount) {\r
+    return &PrivateData->Fv[BestIndex];\r
+  }\r
+\r
   return NULL;\r
 }\r
 \r
@@ -206,8 +248,8 @@ FileHandleToVolume (
   FFS volume as defined by SearchType. The search starts from FileHeader inside\r
   the Firmware Volume defined by FwVolHeader.\r
   If SearchType is EFI_FV_FILETYPE_ALL, the first FFS file will return without check its file type.\r
-  If SearchType is PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE, \r
-  the first PEIM, or COMBINED PEIM or FV file type FFS file will return.  \r
+  If SearchType is PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE,\r
+  the first PEIM, or COMBINED PEIM or FV file type FFS file will return.\r
 \r
   @param FvHandle        Pointer to the FV header of the volume to search\r
   @param FileName        File name\r
@@ -222,30 +264,30 @@ FileHandleToVolume (
 **/\r
 EFI_STATUS\r
 FindFileEx (\r
-  IN  CONST EFI_PEI_FV_HANDLE        FvHandle,\r
-  IN  CONST EFI_GUID                 *FileName,   OPTIONAL\r
-  IN        EFI_FV_FILETYPE          SearchType,\r
-  IN OUT    EFI_PEI_FILE_HANDLE      *FileHandle,\r
-  IN OUT    EFI_PEI_FILE_HANDLE      *AprioriFile  OPTIONAL\r
+  IN  CONST EFI_PEI_FV_HANDLE    FvHandle,\r
+  IN  CONST EFI_GUID             *FileName    OPTIONAL,\r
+  IN        EFI_FV_FILETYPE      SearchType,\r
+  IN OUT    EFI_PEI_FILE_HANDLE  *FileHandle,\r
+  IN OUT    EFI_PEI_FILE_HANDLE  *AprioriFile  OPTIONAL\r
   )\r
 {\r
-  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;\r
-  EFI_FIRMWARE_VOLUME_EXT_HEADER        *FwVolExtHeader;\r
-  EFI_FFS_FILE_HEADER                   **FileHeader;\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
-  UINT8                                 DataCheckSum;\r
-  BOOLEAN                               IsFfs3Fv;\r
-  \r
+  EFI_FIRMWARE_VOLUME_HEADER      *FwVolHeader;\r
+  EFI_FIRMWARE_VOLUME_EXT_HEADER  *FwVolExtHeader;\r
+  EFI_FFS_FILE_HEADER             **FileHeader;\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
+  UINT8                           DataCheckSum;\r
+  BOOLEAN                         IsFfs3Fv;\r
+\r
   //\r
   // Convert the handle of FV to FV header for memory-mapped firmware volume\r
   //\r
-  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvHandle;\r
+  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvHandle;\r
   FileHeader  = (EFI_FFS_FILE_HEADER **)FileHandle;\r
 \r
   IsFfs3Fv = CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid);\r
@@ -256,7 +298,7 @@ FindFileEx (
   } else {\r
     ErasePolarity = 0;\r
   }\r
-  \r
+\r
   //\r
   // If FileHeader is not specified (NULL) or FileName is not NULL,\r
   // start with the first file in the firmware volume.  Otherwise,\r
@@ -267,161 +309,169 @@ FindFileEx (
       //\r
       // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.\r
       //\r
-      FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) ((UINT8 *) FwVolHeader + FwVolHeader->ExtHeaderOffset);\r
-      FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FwVolExtHeader + FwVolExtHeader->ExtHeaderSize);\r
-      FfsFileHeader = (EFI_FFS_FILE_HEADER *) ALIGN_POINTER (FfsFileHeader, 8);\r
+      FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->ExtHeaderOffset);\r
+      FfsFileHeader  = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolExtHeader + FwVolExtHeader->ExtHeaderSize);\r
     } else {\r
-      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *) FwVolHeader + FwVolHeader->HeaderLength);\r
+      FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);\r
     }\r
+\r
+    FfsFileHeader = (EFI_FFS_FILE_HEADER *)ALIGN_POINTER (FfsFileHeader, 8);\r
   } else {\r
     if (IS_FFS_FILE2 (*FileHeader)) {\r
       if (!IsFfs3Fv) {\r
-        DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &(*FileHeader)->Name));\r
+        DEBUG ((DEBUG_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &(*FileHeader)->Name));\r
       }\r
+\r
       FileLength = FFS_FILE2_SIZE (*FileHeader);\r
       ASSERT (FileLength > 0x00FFFFFF);\r
     } else {\r
       FileLength = FFS_FILE_SIZE (*FileHeader);\r
     }\r
+\r
     //\r
     // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.\r
     //\r
     FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r
-    FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);\r
+    FfsFileHeader    = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);\r
   }\r
-  \r
-  FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);\r
+\r
+  FileOffset = (UINT32)((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);\r
   ASSERT (FileOffset <= 0xFFFFFFFF);\r
 \r
   while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {\r
     //\r
-    // Get FileState which is the highest bit of the State \r
+    // Get FileState which is the highest bit of the State\r
     //\r
     FileState = GetFileState (ErasePolarity, FfsFileHeader);\r
     switch (FileState) {\r
+      case EFI_FILE_HEADER_CONSTRUCTION:\r
+      case EFI_FILE_HEADER_INVALID:\r
+        if (IS_FFS_FILE2 (FfsFileHeader)) {\r
+          if (!IsFfs3Fv) {\r
+            DEBUG ((DEBUG_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r
+          }\r
 \r
-    case EFI_FILE_HEADER_CONSTRUCTION:\r
-    case EFI_FILE_HEADER_INVALID:\r
-      if (IS_FFS_FILE2 (FfsFileHeader)) {\r
-        if (!IsFfs3Fv) {\r
-          DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r
+          FileOffset   += sizeof (EFI_FFS_FILE_HEADER2);\r
+          FfsFileHeader =  (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));\r
+        } else {\r
+          FileOffset   += sizeof (EFI_FFS_FILE_HEADER);\r
+          FfsFileHeader =  (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));\r
         }\r
-        FileOffset    += sizeof (EFI_FFS_FILE_HEADER2);\r
-        FfsFileHeader =  (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));\r
-      } else {\r
-        FileOffset    += sizeof (EFI_FFS_FILE_HEADER);\r
-        FfsFileHeader =  (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));\r
-      }\r
-      break;\r
-        \r
-    case EFI_FILE_DATA_VALID:\r
-    case EFI_FILE_MARKED_FOR_UPDATE:\r
-      if (CalculateHeaderChecksum (FfsFileHeader) != 0) {\r
-        ASSERT (FALSE);\r
-        *FileHeader = NULL;\r
-        return EFI_NOT_FOUND;\r
-      }\r
 \r
-      if (IS_FFS_FILE2 (FfsFileHeader)) {\r
-        FileLength = FFS_FILE2_SIZE (FfsFileHeader);\r
-        ASSERT (FileLength > 0x00FFFFFF);\r
-        FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r
-        if (!IsFfs3Fv) {\r
-          DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r
-          FileOffset += FileOccupiedSize;\r
-          FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);\r
-          break;\r
+        break;\r
+\r
+      case EFI_FILE_DATA_VALID:\r
+      case EFI_FILE_MARKED_FOR_UPDATE:\r
+        if (CalculateHeaderChecksum (FfsFileHeader) != 0) {\r
+          ASSERT (FALSE);\r
+          *FileHeader = NULL;\r
+          return EFI_NOT_FOUND;\r
         }\r
-      } else {\r
-        FileLength = FFS_FILE_SIZE (FfsFileHeader);\r
-        FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r
-      }\r
 \r
-      DataCheckSum = FFS_FIXED_CHECKSUM;\r
-      if ((FfsFileHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) {\r
         if (IS_FFS_FILE2 (FfsFileHeader)) {\r
-          DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2), FileLength - sizeof(EFI_FFS_FILE_HEADER2));\r
+          FileLength = FFS_FILE2_SIZE (FfsFileHeader);\r
+          ASSERT (FileLength > 0x00FFFFFF);\r
+          FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r
+          if (!IsFfs3Fv) {\r
+            DEBUG ((DEBUG_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r
+            FileOffset   += FileOccupiedSize;\r
+            FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
+            break;\r
+          }\r
         } else {\r
-          DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER), FileLength - sizeof(EFI_FFS_FILE_HEADER));\r
+          FileLength       = FFS_FILE_SIZE (FfsFileHeader);\r
+          FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r
         }\r
-      }\r
-      if (FfsFileHeader->IntegrityCheck.Checksum.File != DataCheckSum) {\r
-        ASSERT (FALSE);\r
-        *FileHeader = NULL;\r
-        return EFI_NOT_FOUND;\r
-      }\r
 \r
-      if (FileName != NULL) {\r
-        if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID*)FileName)) {\r
-          *FileHeader = FfsFileHeader;\r
-          return EFI_SUCCESS;\r
+        DataCheckSum = FFS_FIXED_CHECKSUM;\r
+        if ((FfsFileHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) {\r
+          if (IS_FFS_FILE2 (FfsFileHeader)) {\r
+            DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2), FileLength - sizeof (EFI_FFS_FILE_HEADER2));\r
+          } else {\r
+            DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER), FileLength - sizeof (EFI_FFS_FILE_HEADER));\r
+          }\r
         }\r
-      } else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) {\r
-        if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) || \r
-            (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER) ||\r
-            (FfsFileHeader->Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE)) { \r
-          \r
+\r
+        if (FfsFileHeader->IntegrityCheck.Checksum.File != DataCheckSum) {\r
+          ASSERT (FALSE);\r
+          *FileHeader = NULL;\r
+          return EFI_NOT_FOUND;\r
+        }\r
+\r
+        if (FileName != NULL) {\r
+          if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID *)FileName)) {\r
+            *FileHeader = FfsFileHeader;\r
+            return EFI_SUCCESS;\r
+          }\r
+        } else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) {\r
+          if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) ||\r
+              (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER) ||\r
+              (FfsFileHeader->Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE))\r
+          {\r
+            *FileHeader = FfsFileHeader;\r
+            return EFI_SUCCESS;\r
+          } else if (AprioriFile != NULL) {\r
+            if (FfsFileHeader->Type == EFI_FV_FILETYPE_FREEFORM) {\r
+              if (CompareGuid (&FfsFileHeader->Name, &gPeiAprioriFileNameGuid)) {\r
+                *AprioriFile = (EFI_PEI_FILE_HANDLE)FfsFileHeader;\r
+              }\r
+            }\r
+          }\r
+        } else if (((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) &&\r
+                   (FfsFileHeader->Type != EFI_FV_FILETYPE_FFS_PAD))\r
+        {\r
           *FileHeader = FfsFileHeader;\r
           return EFI_SUCCESS;\r
-        } else if (AprioriFile != NULL) {\r
-          if (FfsFileHeader->Type == EFI_FV_FILETYPE_FREEFORM) {\r
-            if (CompareGuid (&FfsFileHeader->Name, &gPeiAprioriFileNameGuid)) {\r
-              *AprioriFile = FfsFileHeader;\r
-            }           \r
-          } \r
         }\r
-      } else if (((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) && \r
-                 (FfsFileHeader->Type != EFI_FV_FILETYPE_FFS_PAD)) { \r
-        *FileHeader = FfsFileHeader;\r
-        return EFI_SUCCESS;\r
-      }\r
 \r
-      FileOffset    += FileOccupiedSize; \r
-      FfsFileHeader =  (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
-      break;\r
-    \r
-    case EFI_FILE_DELETED:\r
-      if (IS_FFS_FILE2 (FfsFileHeader)) {\r
-        if (!IsFfs3Fv) {\r
-          DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r
+        FileOffset   += FileOccupiedSize;\r
+        FfsFileHeader =  (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
+        break;\r
+\r
+      case EFI_FILE_DELETED:\r
+        if (IS_FFS_FILE2 (FfsFileHeader)) {\r
+          if (!IsFfs3Fv) {\r
+            DEBUG ((DEBUG_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r
+          }\r
+\r
+          FileLength = FFS_FILE2_SIZE (FfsFileHeader);\r
+          ASSERT (FileLength > 0x00FFFFFF);\r
+        } else {\r
+          FileLength = FFS_FILE_SIZE (FfsFileHeader);\r
         }\r
-        FileLength = FFS_FILE2_SIZE (FfsFileHeader);\r
-        ASSERT (FileLength > 0x00FFFFFF);\r
-      } else {\r
-        FileLength = FFS_FILE_SIZE (FfsFileHeader);\r
-      }\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
-      *FileHeader = NULL;\r
-      return EFI_NOT_FOUND;\r
-    } \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
+        *FileHeader = NULL;\r
+        return EFI_NOT_FOUND;\r
+    }\r
   }\r
-  \r
+\r
   *FileHeader = NULL;\r
-  return EFI_NOT_FOUND;  \r
+  return EFI_NOT_FOUND;\r
 }\r
 \r
 /**\r
-  Initialize PeiCore Fv List.\r
+  Initialize PeiCore FV List.\r
 \r
   @param PrivateData     - Pointer to PEI_CORE_INSTANCE.\r
   @param SecCoreData     - Pointer to EFI_SEC_PEI_HAND_OFF.\r
 **/\r
-VOID \r
+VOID\r
 PeiInitializeFv (\r
-  IN  PEI_CORE_INSTANCE           *PrivateData,\r
-  IN CONST EFI_SEC_PEI_HAND_OFF   *SecCoreData\r
+  IN  PEI_CORE_INSTANCE          *PrivateData,\r
+  IN CONST EFI_SEC_PEI_HAND_OFF  *SecCoreData\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  EFI_PEI_FIRMWARE_VOLUME_PPI   *FvPpi;\r
-  EFI_PEI_FV_HANDLE             FvHandle;\r
-  EFI_FIRMWARE_VOLUME_HEADER    *BfvHeader;\r
-  \r
+  EFI_STATUS                   Status;\r
+  EFI_PEI_FIRMWARE_VOLUME_PPI  *FvPpi;\r
+  EFI_PEI_FV_HANDLE            FvHandle;\r
+  EFI_FIRMWARE_VOLUME_HEADER   *BfvHeader;\r
+\r
   //\r
   // Install FV_PPI for FFS2 file system.\r
   //\r
@@ -433,7 +483,7 @@ PeiInitializeFv (
   PeiServicesInstallPpi (&mPeiFfs3FvPpiList);\r
 \r
   BfvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;\r
-  \r
+\r
   //\r
   // The FV_PPI in BFV's format should be installed.\r
   //\r
@@ -441,133 +491,186 @@ PeiInitializeFv (
              &BfvHeader->FileSystemGuid,\r
              0,\r
              NULL,\r
-             (VOID**)&FvPpi\r
+             (VOID **)&FvPpi\r
              );\r
   ASSERT_EFI_ERROR (Status);\r
-    \r
+\r
   //\r
   // Get handle of BFV\r
   //\r
-  FvPpi->ProcessVolume (\r
-           FvPpi, \r
-           SecCoreData->BootFirmwareVolumeBase,\r
-           (UINTN)BfvHeader->FvLength,\r
-           &FvHandle\r
-           );\r
+  Status = FvPpi->ProcessVolume (\r
+                    FvPpi,\r
+                    SecCoreData->BootFirmwareVolumeBase,\r
+                    (UINTN)BfvHeader->FvLength,\r
+                    &FvHandle\r
+                    );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  PrivateData->Fv = AllocateZeroPool (sizeof (PEI_CORE_FV_HANDLE) * FV_GROWTH_STEP);\r
+  ASSERT (PrivateData->Fv != NULL);\r
+  PrivateData->MaxFvCount = FV_GROWTH_STEP;\r
 \r
   //\r
   // Update internal PEI_CORE_FV array.\r
   //\r
-  PrivateData->Fv[PrivateData->FvCount].FvHeader = BfvHeader;\r
-  PrivateData->Fv[PrivateData->FvCount].FvPpi    = FvPpi;\r
-  PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;\r
+  PrivateData->Fv[PrivateData->FvCount].FvHeader             = BfvHeader;\r
+  PrivateData->Fv[PrivateData->FvCount].FvPpi                = FvPpi;\r
+  PrivateData->Fv[PrivateData->FvCount].FvHandle             = FvHandle;\r
+  PrivateData->Fv[PrivateData->FvCount].AuthenticationStatus = 0;\r
   DEBUG ((\r
-    EFI_D_INFO, \r
-    "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n", \r
-    (UINT32) PrivateData->FvCount, \r
-    (VOID *) BfvHeader, \r
-    BfvHeader->FvLength,\r
+    DEBUG_INFO,\r
+    "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",\r
+    (UINT32)PrivateData->FvCount,\r
+    (VOID *)BfvHeader,\r
+    (UINT32)BfvHeader->FvLength,\r
     FvHandle\r
-    ));    \r
-  PrivateData->FvCount ++;\r
-                            \r
+    ));\r
+  PrivateData->FvCount++;\r
+\r
   //\r
-  // Post a call-back for the FvInfoPPI services to expose\r
-  // additional Fvs to PeiCore.\r
+  // Post a call-back for the FvInfoPPI and FvInfo2PPI services to expose\r
+  // additional FVs to PeiCore.\r
   //\r
-  Status = PeiServicesNotifyPpi (&mNotifyOnFvInfoList);\r
+  Status = PeiServicesNotifyPpi (mNotifyOnFvInfoList);\r
   ASSERT_EFI_ERROR (Status);\r
-\r
 }\r
-  \r
+\r
 /**\r
-  Process Firmware Volum Information once FvInfoPPI install.\r
+  Process Firmware Volume Information once FvInfoPPI or FvInfo2PPI install.\r
   The FV Info will be registered into PeiCore private data structure.\r
-  And search the inside FV image, if found, the new FV INFO PPI will be installed.\r
+  And search the inside FV image, if found, the new FV INFO(2) PPI will be installed.\r
 \r
   @param PeiServices       An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
   @param NotifyDescriptor  Address of the notification descriptor data structure.\r
   @param Ppi               Address of the PPI that was installed.\r
 \r
   @retval EFI_SUCCESS    The FV Info is registered into PeiCore private data structure.\r
-  @return if not EFI_SUCESS, fail to verify FV.\r
+  @return if not EFI_SUCCESS, fail to verify FV.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-FirmwareVolmeInfoPpiNotifyCallback (\r
-  IN EFI_PEI_SERVICES              **PeiServices,\r
-  IN EFI_PEI_NOTIFY_DESCRIPTOR     *NotifyDescriptor,\r
-  IN VOID                          *Ppi\r
+FirmwareVolumeInfoPpiNotifyCallback (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
   )\r
 {\r
-  EFI_PEI_FIRMWARE_VOLUME_INFO_PPI      *FvInfoPpi;\r
-  EFI_PEI_FIRMWARE_VOLUME_PPI           *FvPpi;\r
-  PEI_CORE_INSTANCE                     *PrivateData;\r
-  EFI_STATUS                            Status;\r
-  EFI_PEI_FV_HANDLE                     FvHandle;\r
-  UINTN                                 FvIndex;\r
-  EFI_PEI_FILE_HANDLE                   FileHandle;\r
-  VOID                                  *DepexData;\r
-  \r
-  Status       = EFI_SUCCESS;\r
-  PrivateData  = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
-\r
-  if (PrivateData->FvCount >= FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
-    DEBUG ((EFI_D_ERROR, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData->FvCount + 1, FixedPcdGet32 (PcdPeiCoreMaxFvSupported)));\r
-    DEBUG ((EFI_D_ERROR, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));\r
-    ASSERT (FALSE);\r
+  EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI  FvInfo2Ppi;\r
+  EFI_PEI_FIRMWARE_VOLUME_PPI        *FvPpi;\r
+  PEI_CORE_INSTANCE                  *PrivateData;\r
+  EFI_STATUS                         Status;\r
+  EFI_PEI_FV_HANDLE                  FvHandle;\r
+  UINTN                              FvIndex;\r
+  EFI_PEI_FILE_HANDLE                FileHandle;\r
+  VOID                               *DepexData;\r
+  BOOLEAN                            IsFvInfo2;\r
+  UINTN                              CurFvCount;\r
+  VOID                               *TempPtr;\r
+\r
+  Status      = EFI_SUCCESS;\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
+\r
+  if (CompareGuid (NotifyDescriptor->Guid, &gEfiPeiFirmwareVolumeInfo2PpiGuid)) {\r
+    //\r
+    // It is FvInfo2PPI.\r
+    //\r
+    CopyMem (&FvInfo2Ppi, Ppi, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI));\r
+    IsFvInfo2 = TRUE;\r
+  } else {\r
+    //\r
+    // It is FvInfoPPI.\r
+    //\r
+    CopyMem (&FvInfo2Ppi, Ppi, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI));\r
+    FvInfo2Ppi.AuthenticationStatus = 0;\r
+    IsFvInfo2                       = FALSE;\r
   }\r
 \r
-  FvInfoPpi = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi;\r
+  if (CompareGuid (&FvInfo2Ppi.FvFormat, &gEfiFirmwareFileSystem2Guid)) {\r
+    //\r
+    // gEfiFirmwareFileSystem2Guid is specified for FvFormat, then here to check the\r
+    // FileSystemGuid pointed by FvInfo against gEfiFirmwareFileSystem2Guid to make sure\r
+    // FvInfo has the firmware file system 2 format.\r
+    //\r
+    // If the ASSERT really appears, FvFormat needs to be specified correctly, for example,\r
+    // gEfiFirmwareFileSystem3Guid can be used for firmware file system 3 format, or\r
+    // ((EFI_FIRMWARE_VOLUME_HEADER *) FvInfo)->FileSystemGuid can be just used for both\r
+    // firmware file system 2 and 3 format.\r
+    //\r
+    ASSERT (CompareGuid (&(((EFI_FIRMWARE_VOLUME_HEADER *)FvInfo2Ppi.FvInfo)->FileSystemGuid), &gEfiFirmwareFileSystem2Guid));\r
+  }\r
 \r
   //\r
-  // Locate the corresponding FV_PPI according to founded FV's format guid\r
+  // Locate the corresponding FV_PPI according to the format GUID of the FV found\r
   //\r
   Status = PeiServicesLocatePpi (\r
-             &FvInfoPpi->FvFormat, \r
-             0, \r
+             &FvInfo2Ppi.FvFormat,\r
+             0,\r
              NULL,\r
-             (VOID**)&FvPpi\r
+             (VOID **)&FvPpi\r
              );\r
   if (!EFI_ERROR (Status)) {\r
     //\r
     // Process new found FV and get FV handle.\r
     //\r
-    Status = FvPpi->ProcessVolume (FvPpi, FvInfoPpi->FvInfo, FvInfoPpi->FvInfoSize, &FvHandle);\r
+    Status = FvPpi->ProcessVolume (FvPpi, FvInfo2Ppi.FvInfo, FvInfo2Ppi.FvInfoSize, &FvHandle);\r
     if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "Fail to process new found FV, FV may be corrupted!\n"));\r
+      DEBUG ((DEBUG_ERROR, "Fail to process new found FV, FV may be corrupted!\n"));\r
       return Status;\r
     }\r
 \r
     //\r
     // Check whether the FV has already been processed.\r
     //\r
-    for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex ++) {\r
+    for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex++) {\r
       if (PrivateData->Fv[FvIndex].FvHandle == FvHandle) {\r
-        DEBUG ((EFI_D_INFO, "The Fv %p has already been processed!\n", FvInfoPpi->FvInfo));\r
+        if (IsFvInfo2 && (FvInfo2Ppi.AuthenticationStatus != PrivateData->Fv[FvIndex].AuthenticationStatus)) {\r
+          PrivateData->Fv[FvIndex].AuthenticationStatus = FvInfo2Ppi.AuthenticationStatus;\r
+          DEBUG ((DEBUG_INFO, "Update AuthenticationStatus of the %dth FV to 0x%x!\n", FvIndex, FvInfo2Ppi.AuthenticationStatus));\r
+        }\r
+\r
+        DEBUG ((DEBUG_INFO, "The FV %p has already been processed!\n", FvInfo2Ppi.FvInfo));\r
         return EFI_SUCCESS;\r
       }\r
     }\r
 \r
+    if (PrivateData->FvCount >= PrivateData->MaxFvCount) {\r
+      //\r
+      // Run out of room, grow the buffer.\r
+      //\r
+      TempPtr = AllocateZeroPool (\r
+                  sizeof (PEI_CORE_FV_HANDLE) * (PrivateData->MaxFvCount + FV_GROWTH_STEP)\r
+                  );\r
+      ASSERT (TempPtr != NULL);\r
+      CopyMem (\r
+        TempPtr,\r
+        PrivateData->Fv,\r
+        sizeof (PEI_CORE_FV_HANDLE) * PrivateData->MaxFvCount\r
+        );\r
+      PrivateData->Fv         = TempPtr;\r
+      PrivateData->MaxFvCount = PrivateData->MaxFvCount + FV_GROWTH_STEP;\r
+    }\r
+\r
     //\r
     // Update internal PEI_CORE_FV array.\r
     //\r
-    PrivateData->Fv[PrivateData->FvCount].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) FvInfoPpi->FvInfo;\r
-    PrivateData->Fv[PrivateData->FvCount].FvPpi    = FvPpi;\r
-    PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;\r
+    PrivateData->Fv[PrivateData->FvCount].FvHeader             = (EFI_FIRMWARE_VOLUME_HEADER *)FvInfo2Ppi.FvInfo;\r
+    PrivateData->Fv[PrivateData->FvCount].FvPpi                = FvPpi;\r
+    PrivateData->Fv[PrivateData->FvCount].FvHandle             = FvHandle;\r
+    PrivateData->Fv[PrivateData->FvCount].AuthenticationStatus = FvInfo2Ppi.AuthenticationStatus;\r
+    CurFvCount                                                 = PrivateData->FvCount;\r
     DEBUG ((\r
-      EFI_D_INFO, \r
-      "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n", \r
-      (UINT32) PrivateData->FvCount, \r
-      (VOID *) FvInfoPpi->FvInfo, \r
-      FvInfoPpi->FvInfoSize,\r
+      DEBUG_INFO,\r
+      "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",\r
+      (UINT32)CurFvCount,\r
+      (VOID *)FvInfo2Ppi.FvInfo,\r
+      FvInfo2Ppi.FvInfoSize,\r
       FvHandle\r
-      ));    \r
-    PrivateData->FvCount ++;\r
+      ));\r
+    PrivateData->FvCount++;\r
 \r
     //\r
-    // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE \r
+    // Scan and process the new discovered FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\r
     //\r
     FileHandle = NULL;\r
     do {\r
@@ -576,13 +679,13 @@ FirmwareVolmeInfoPpiNotifyCallback (
                         EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r
                         FvHandle,\r
                         &FileHandle\r
-                       );\r
+                        );\r
       if (!EFI_ERROR (Status)) {\r
         Status = FvPpi->FindSectionByType (\r
                           FvPpi,\r
                           EFI_SECTION_PEI_DEPEX,\r
                           FileHandle,\r
-                          (VOID**)&DepexData\r
+                          (VOID **)&DepexData\r
                           );\r
         if (!EFI_ERROR (Status)) {\r
           if (!PeimDispatchReadiness (PeiServices, DepexData)) {\r
@@ -592,17 +695,17 @@ FirmwareVolmeInfoPpiNotifyCallback (
             continue;\r
           }\r
         }\r
-        \r
-        DEBUG ((EFI_D_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, PrivateData->FvCount - 1, FvHandle));\r
-        ProcessFvFile (&PrivateData->Fv[PrivateData->FvCount - 1], FileHandle);\r
+\r
+        DEBUG ((DEBUG_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, CurFvCount, FvHandle));\r
+        ProcessFvFile (PrivateData, &PrivateData->Fv[CurFvCount], FileHandle);\r
       }\r
     } while (FileHandle != NULL);\r
   } else {\r
-    DEBUG ((EFI_D_ERROR, "Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found!\n", FvInfoPpi->FvInfo));\r
-    \r
-    AddUnknownFormatFvInfo (PrivateData, &FvInfoPpi->FvFormat, FvInfoPpi->FvInfo, FvInfoPpi->FvInfoSize);\r
+    DEBUG ((DEBUG_ERROR, "Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found!\n", FvInfo2Ppi.FvInfo));\r
+\r
+    AddUnknownFormatFvInfo (PrivateData, &FvInfo2Ppi);\r
   }\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -615,14 +718,14 @@ FirmwareVolmeInfoPpiNotifyCallback (
 \r
   @return TRUE      The GuidedSectionGuid could be identified, and the pointer to\r
                     the Guided Section Extraction Ppi will be returned to *GuidedSectionExtraction.\r
-  @return FALSE     The GuidedSectionGuid could not be identified, or \r
+  @return FALSE     The GuidedSectionGuid could not be identified, or\r
                     the Guided Section Extraction Ppi has not been installed yet.\r
 \r
 **/\r
 BOOLEAN\r
 VerifyGuidedSectionGuid (\r
-  IN  EFI_GUID                                  *GuidedSectionGuid,\r
-  OUT EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI     **GuidedSectionExtraction\r
+  IN  EFI_GUID                               *GuidedSectionGuid,\r
+  OUT EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI  **GuidedSectionExtraction\r
   )\r
 {\r
   EFI_PEI_HOB_POINTERS  Hob;\r
@@ -635,19 +738,20 @@ VerifyGuidedSectionGuid (
   //\r
   Hob.Raw = GetFirstGuidHob (GuidedSectionGuid);\r
   if (Hob.Raw != NULL) {\r
-    GuidRecorded = (EFI_GUID *) GET_GUID_HOB_DATA (Hob);\r
+    GuidRecorded = (EFI_GUID *)GET_GUID_HOB_DATA (Hob);\r
     if (CompareGuid (GuidRecorded, GuidedSectionGuid)) {\r
       //\r
       // Found the recorded GuidedSectionGuid.\r
       //\r
-      Status = PeiServicesLocatePpi (GuidedSectionGuid, 0, NULL, (VOID **) &Interface);\r
-      if (!EFI_ERROR (Status) && Interface != NULL) {\r
+      Status = PeiServicesLocatePpi (GuidedSectionGuid, 0, NULL, (VOID **)&Interface);\r
+      if (!EFI_ERROR (Status) && (Interface != NULL)) {\r
         //\r
         // Found the supported Guided Section Extraction Ppi for the Guided Section.\r
         //\r
-        *GuidedSectionExtraction = (EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *) Interface;\r
+        *GuidedSectionExtraction = (EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *)Interface;\r
         return TRUE;\r
       }\r
+\r
       return FALSE;\r
     }\r
   }\r
@@ -656,16 +760,18 @@ VerifyGuidedSectionGuid (
 }\r
 \r
 /**\r
-  Go through the file to search SectionType section. \r
-  Search within encapsulation sections (compression and GUIDed) recursively, \r
+  Go through the file to search SectionType section.\r
+  Search within encapsulation sections (compression and GUIDed) recursively,\r
   until the match section is found.\r
-  \r
+\r
   @param PeiServices       An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
   @param SectionType       Filter to find only section of this type.\r
+  @param SectionInstance   Pointer to the filter to find the specific instance of section.\r
   @param Section           From where to search.\r
   @param SectionSize       The file size to search.\r
   @param OutputBuffer      A pointer to the discovered section, if successful.\r
                            NULL if section not found\r
+  @param AuthenticationStatus Updated upon return to point to the authentication status for this section.\r
   @param IsFfs3Fv          Indicates the FV format.\r
 \r
   @return EFI_NOT_FOUND    The match section is not found.\r
@@ -676,23 +782,29 @@ EFI_STATUS
 ProcessSection (\r
   IN CONST EFI_PEI_SERVICES     **PeiServices,\r
   IN EFI_SECTION_TYPE           SectionType,\r
+  IN OUT UINTN                  *SectionInstance,\r
   IN EFI_COMMON_SECTION_HEADER  *Section,\r
   IN UINTN                      SectionSize,\r
   OUT VOID                      **OutputBuffer,\r
+  OUT UINT32                    *AuthenticationStatus,\r
   IN BOOLEAN                    IsFfs3Fv\r
   )\r
 {\r
-  EFI_STATUS                              Status;\r
-  UINT32                                  SectionLength;\r
-  UINT32                                  ParsedLength;\r
-  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI   *GuidSectionPpi;\r
-  EFI_PEI_DECOMPRESS_PPI                  *DecompressPpi;\r
-  VOID                                    *PpiOutput;\r
-  UINTN                                   PpiOutputSize;\r
-  UINTN                                   Index;\r
-  UINT32                                  Authentication;\r
-  PEI_CORE_INSTANCE                       *PrivateData;\r
-  EFI_GUID                                *SectionDefinitionGuid;\r
+  EFI_STATUS                             Status;\r
+  UINT32                                 SectionLength;\r
+  UINT32                                 ParsedLength;\r
+  EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI  *GuidSectionPpi;\r
+  EFI_PEI_DECOMPRESS_PPI                 *DecompressPpi;\r
+  VOID                                   *PpiOutput;\r
+  UINTN                                  PpiOutputSize;\r
+  UINTN                                  Index;\r
+  UINT32                                 Authentication;\r
+  PEI_CORE_INSTANCE                      *PrivateData;\r
+  EFI_GUID                               *SectionDefinitionGuid;\r
+  BOOLEAN                                SectionCached;\r
+  VOID                                   *TempOutputBuffer;\r
+  UINT32                                 TempAuthenticationStatus;\r
+  UINT16                                 GuidedSectionAttributes;\r
 \r
   PrivateData   = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
   *OutputBuffer = NULL;\r
@@ -702,11 +814,10 @@ ProcessSection (
   PpiOutput     = NULL;\r
   PpiOutputSize = 0;\r
   while (ParsedLength < SectionSize) {\r
-\r
     if (IS_SECTION2 (Section)) {\r
       ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF);\r
       if (!IsFfs3Fv) {\r
-        DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted section in a non-FFS3 formatted FV.\n"));\r
+        DEBUG ((DEBUG_ERROR, "Found a FFS3 formatted section in a non-FFS3 formatted FV.\n"));\r
         SectionLength = SECTION2_SIZE (Section);\r
         //\r
         // SectionLength is adjusted it is 4 byte aligned.\r
@@ -715,88 +826,162 @@ ProcessSection (
         SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
         ASSERT (SectionLength != 0);\r
         ParsedLength += SectionLength;\r
-        Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength);\r
+        Section       = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);\r
         continue;\r
       }\r
     }\r
 \r
     if (Section->Type == SectionType) {\r
-      if (IS_SECTION2 (Section)) {\r
-        *OutputBuffer = (VOID *)((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));\r
+      //\r
+      // The type matches, so check the instance count to see if it's the one we want.\r
+      //\r
+      (*SectionInstance)--;\r
+      if (*SectionInstance == 0) {\r
+        //\r
+        // Got it!\r
+        //\r
+        if (IS_SECTION2 (Section)) {\r
+          *OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2));\r
+        } else {\r
+          *OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER));\r
+        }\r
+\r
+        return EFI_SUCCESS;\r
       } else {\r
-        *OutputBuffer = (VOID *)((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));\r
+        if (IS_SECTION2 (Section)) {\r
+          SectionLength = SECTION2_SIZE (Section);\r
+        } else {\r
+          SectionLength = SECTION_SIZE (Section);\r
+        }\r
+\r
+        //\r
+        // SectionLength is adjusted it is 4 byte aligned.\r
+        // Go to the next section\r
+        //\r
+        SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
+        ASSERT (SectionLength != 0);\r
+        ParsedLength += SectionLength;\r
+        Section       = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);\r
+        continue;\r
       }\r
-      return EFI_SUCCESS;\r
     } else if ((Section->Type == EFI_SECTION_GUID_DEFINED) || (Section->Type == EFI_SECTION_COMPRESSION)) {\r
       //\r
       // Check the encapsulated section is extracted into the cache data.\r
       //\r
-      for (Index = 0; Index < PrivateData->CacheSection.AllSectionCount; Index ++) {\r
+      SectionCached = FALSE;\r
+      for (Index = 0; Index < PrivateData->CacheSection.AllSectionCount; Index++) {\r
         if (Section == PrivateData->CacheSection.Section[Index]) {\r
-          PpiOutput     = PrivateData->CacheSection.SectionData[Index];\r
-          PpiOutputSize = PrivateData->CacheSection.SectionSize[Index];\r
+          SectionCached  = TRUE;\r
+          PpiOutput      = PrivateData->CacheSection.SectionData[Index];\r
+          PpiOutputSize  = PrivateData->CacheSection.SectionSize[Index];\r
+          Authentication = PrivateData->CacheSection.AuthenticationStatus[Index];\r
           //\r
           // Search section directly from the cache data.\r
           //\r
-          return ProcessSection (\r
-                   PeiServices,\r
-                   SectionType, \r
-                   PpiOutput, \r
-                   PpiOutputSize, \r
-                   OutputBuffer,\r
-                   IsFfs3Fv\r
-                   );\r
+          TempAuthenticationStatus = 0;\r
+          Status                   = ProcessSection (\r
+                                       PeiServices,\r
+                                       SectionType,\r
+                                       SectionInstance,\r
+                                       PpiOutput,\r
+                                       PpiOutputSize,\r
+                                       &TempOutputBuffer,\r
+                                       &TempAuthenticationStatus,\r
+                                       IsFfs3Fv\r
+                                       );\r
+          if (!EFI_ERROR (Status)) {\r
+            *OutputBuffer         = TempOutputBuffer;\r
+            *AuthenticationStatus = TempAuthenticationStatus | Authentication;\r
+            return EFI_SUCCESS;\r
+          }\r
         }\r
       }\r
-      \r
-      Status = EFI_NOT_FOUND;\r
-      if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r
-        if (IS_SECTION2 (Section)) {\r
-          SectionDefinitionGuid = &((EFI_GUID_DEFINED_SECTION2 *)Section)->SectionDefinitionGuid;\r
-        } else {\r
-          SectionDefinitionGuid = &((EFI_GUID_DEFINED_SECTION *)Section)->SectionDefinitionGuid;\r
-        }\r
-        if (VerifyGuidedSectionGuid (SectionDefinitionGuid, &GuidSectionPpi)) {\r
-          Status = GuidSectionPpi->ExtractSection (\r
-                                     GuidSectionPpi,\r
-                                     Section,\r
-                                     &PpiOutput,\r
-                                     &PpiOutputSize,\r
-                                     &Authentication\r
-                                     );\r
+\r
+      //\r
+      // If SectionCached is TRUE, the section data has been cached and scanned.\r
+      //\r
+      if (!SectionCached) {\r
+        Status         = EFI_NOT_FOUND;\r
+        Authentication = 0;\r
+        if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r
+          if (IS_SECTION2 (Section)) {\r
+            SectionDefinitionGuid   = &((EFI_GUID_DEFINED_SECTION2 *)Section)->SectionDefinitionGuid;\r
+            GuidedSectionAttributes = ((EFI_GUID_DEFINED_SECTION2 *)Section)->Attributes;\r
+          } else {\r
+            SectionDefinitionGuid   = &((EFI_GUID_DEFINED_SECTION *)Section)->SectionDefinitionGuid;\r
+            GuidedSectionAttributes = ((EFI_GUID_DEFINED_SECTION *)Section)->Attributes;\r
+          }\r
+\r
+          if (VerifyGuidedSectionGuid (SectionDefinitionGuid, &GuidSectionPpi)) {\r
+            Status = GuidSectionPpi->ExtractSection (\r
+                                       GuidSectionPpi,\r
+                                       Section,\r
+                                       &PpiOutput,\r
+                                       &PpiOutputSize,\r
+                                       &Authentication\r
+                                       );\r
+          } else if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {\r
+            //\r
+            // Figure out the proper authentication status for GUIDED section without processing required\r
+            //\r
+            Status = EFI_SUCCESS;\r
+            if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {\r
+              Authentication |= EFI_AUTH_STATUS_IMAGE_SIGNED | EFI_AUTH_STATUS_NOT_TESTED;\r
+            }\r
+\r
+            if (IS_SECTION2 (Section)) {\r
+              PpiOutputSize = SECTION2_SIZE (Section) - ((EFI_GUID_DEFINED_SECTION2 *)Section)->DataOffset;\r
+              PpiOutput     = (UINT8 *)Section + ((EFI_GUID_DEFINED_SECTION2 *)Section)->DataOffset;\r
+            } else {\r
+              PpiOutputSize = SECTION_SIZE (Section) - ((EFI_GUID_DEFINED_SECTION *)Section)->DataOffset;\r
+              PpiOutput     = (UINT8 *)Section + ((EFI_GUID_DEFINED_SECTION *)Section)->DataOffset;\r
+            }\r
+          }\r
+        } else if (Section->Type == EFI_SECTION_COMPRESSION) {\r
+          Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **)&DecompressPpi);\r
+          if (!EFI_ERROR (Status)) {\r
+            Status = DecompressPpi->Decompress (\r
+                                      DecompressPpi,\r
+                                      (CONST EFI_COMPRESSION_SECTION *)Section,\r
+                                      &PpiOutput,\r
+                                      &PpiOutputSize\r
+                                      );\r
+          }\r
         }\r
-      } else if (Section->Type == EFI_SECTION_COMPRESSION) {\r
-        Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi);\r
+\r
         if (!EFI_ERROR (Status)) {\r
-          Status = DecompressPpi->Decompress (\r
-                                    DecompressPpi,\r
-                                    (CONST EFI_COMPRESSION_SECTION*) Section,\r
-                                    &PpiOutput,\r
-                                    &PpiOutputSize\r
-                                    );\r
-        }\r
-      }\r
-      \r
-      if (!EFI_ERROR (Status)) {\r
-        //\r
-        // Update cache section data.\r
-        //\r
-        if (PrivateData->CacheSection.AllSectionCount < CACHE_SETION_MAX_NUMBER) {\r
-          PrivateData->CacheSection.AllSectionCount ++;\r
+          if ((Authentication & EFI_AUTH_STATUS_NOT_TESTED) == 0) {\r
+            //\r
+            // Update cache section data.\r
+            //\r
+            if (PrivateData->CacheSection.AllSectionCount < CACHE_SETION_MAX_NUMBER) {\r
+              PrivateData->CacheSection.AllSectionCount++;\r
+            }\r
+\r
+            PrivateData->CacheSection.Section[PrivateData->CacheSection.SectionIndex]              = Section;\r
+            PrivateData->CacheSection.SectionData[PrivateData->CacheSection.SectionIndex]          = PpiOutput;\r
+            PrivateData->CacheSection.SectionSize[PrivateData->CacheSection.SectionIndex]          = PpiOutputSize;\r
+            PrivateData->CacheSection.AuthenticationStatus[PrivateData->CacheSection.SectionIndex] = Authentication;\r
+            PrivateData->CacheSection.SectionIndex                                                 = (PrivateData->CacheSection.SectionIndex + 1)%CACHE_SETION_MAX_NUMBER;\r
+          }\r
+\r
+          TempAuthenticationStatus = 0;\r
+          Status                   = ProcessSection (\r
+                                       PeiServices,\r
+                                       SectionType,\r
+                                       SectionInstance,\r
+                                       PpiOutput,\r
+                                       PpiOutputSize,\r
+                                       &TempOutputBuffer,\r
+                                       &TempAuthenticationStatus,\r
+                                       IsFfs3Fv\r
+                                       );\r
+          if (!EFI_ERROR (Status)) {\r
+            *OutputBuffer         = TempOutputBuffer;\r
+            *AuthenticationStatus = TempAuthenticationStatus | Authentication;\r
+            return EFI_SUCCESS;\r
+          }\r
         }\r
-        PrivateData->CacheSection.Section [PrivateData->CacheSection.SectionIndex]     = Section;\r
-        PrivateData->CacheSection.SectionData [PrivateData->CacheSection.SectionIndex] = PpiOutput;\r
-        PrivateData->CacheSection.SectionSize [PrivateData->CacheSection.SectionIndex] = PpiOutputSize;\r
-        PrivateData->CacheSection.SectionIndex = (PrivateData->CacheSection.SectionIndex + 1)%CACHE_SETION_MAX_NUMBER;\r
-        \r
-        return ProcessSection (\r
-                 PeiServices,\r
-                 SectionType, \r
-                 PpiOutput, \r
-                 PpiOutputSize, \r
-                 OutputBuffer,\r
-                 IsFfs3Fv\r
-                 );\r
       }\r
     }\r
 \r
@@ -805,6 +990,7 @@ ProcessSection (
     } else {\r
       SectionLength = SECTION_SIZE (Section);\r
     }\r
+\r
     //\r
     // SectionLength is adjusted it is 4 byte aligned.\r
     // Go to the next section\r
@@ -812,13 +998,12 @@ ProcessSection (
     SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
     ASSERT (SectionLength != 0);\r
     ParsedLength += SectionLength;\r
-    Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);\r
+    Section       = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);\r
   }\r
-  \r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
-\r
 /**\r
   Searches for the next matching section within the specified file.\r
 \r
@@ -835,22 +1020,67 @@ ProcessSection (
 EFI_STATUS\r
 EFIAPI\r
 PeiFfsFindSectionData (\r
-  IN CONST EFI_PEI_SERVICES    **PeiServices,\r
-  IN     EFI_SECTION_TYPE      SectionType,\r
-  IN     EFI_PEI_FILE_HANDLE   FileHandle,\r
-  OUT VOID                     **SectionData\r
+  IN CONST EFI_PEI_SERVICES   **PeiServices,\r
+  IN     EFI_SECTION_TYPE     SectionType,\r
+  IN     EFI_PEI_FILE_HANDLE  FileHandle,\r
+  OUT VOID                    **SectionData\r
   )\r
 {\r
-  PEI_CORE_FV_HANDLE           *CoreFvHandle;\r
-  \r
+  PEI_CORE_FV_HANDLE  *CoreFvHandle;\r
+\r
   CoreFvHandle = FileHandleToVolume (FileHandle);\r
   if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {\r
     return EFI_NOT_FOUND;\r
   }\r
-  \r
+\r
   return CoreFvHandle->FvPpi->FindSectionByType (CoreFvHandle->FvPpi, SectionType, FileHandle, SectionData);\r
 }\r
 \r
+/**\r
+  Searches for the next matching section within the specified file.\r
+\r
+  @param  PeiServices           An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
+  @param  SectionType           The value of the section type to find.\r
+  @param  SectionInstance       Section instance to find.\r
+  @param  FileHandle            Handle of the firmware file to search.\r
+  @param  SectionData           A pointer to the discovered section, if successful.\r
+  @param  AuthenticationStatus  A pointer to the authentication status for this section.\r
+\r
+  @retval EFI_SUCCESS      The section was found.\r
+  @retval EFI_NOT_FOUND    The section was not found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeiFfsFindSectionData3 (\r
+  IN CONST EFI_PEI_SERVICES   **PeiServices,\r
+  IN     EFI_SECTION_TYPE     SectionType,\r
+  IN     UINTN                SectionInstance,\r
+  IN     EFI_PEI_FILE_HANDLE  FileHandle,\r
+  OUT VOID                    **SectionData,\r
+  OUT UINT32                  *AuthenticationStatus\r
+  )\r
+{\r
+  PEI_CORE_FV_HANDLE  *CoreFvHandle;\r
+\r
+  CoreFvHandle = FileHandleToVolume (FileHandle);\r
+  if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  if ((CoreFvHandle->FvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) &&\r
+      (CoreFvHandle->FvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION))\r
+  {\r
+    return CoreFvHandle->FvPpi->FindSectionByType2 (CoreFvHandle->FvPpi, SectionType, SectionInstance, FileHandle, SectionData, AuthenticationStatus);\r
+  }\r
+\r
+  //\r
+  // The old FvPpi doesn't support to find section by section instance\r
+  // and return authentication status, so return EFI_UNSUPPORTED.\r
+  //\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
 /**\r
   Searches for the next matching file in the firmware volume.\r
 \r
@@ -870,33 +1100,23 @@ PeiFfsFindSectionData (
 EFI_STATUS\r
 EFIAPI\r
 PeiFfsFindNextFile (\r
-  IN CONST EFI_PEI_SERVICES      **PeiServices,\r
-  IN UINT8                       SearchType,\r
-  IN EFI_PEI_FV_HANDLE           FvHandle,\r
-  IN OUT EFI_PEI_FILE_HANDLE     *FileHandle\r
+  IN CONST EFI_PEI_SERVICES   **PeiServices,\r
+  IN UINT8                    SearchType,\r
+  IN EFI_PEI_FV_HANDLE        FvHandle,\r
+  IN OUT EFI_PEI_FILE_HANDLE  *FileHandle\r
   )\r
 {\r
-  PEI_CORE_FV_HANDLE      *CoreFvHandle;\r
-  \r
+  PEI_CORE_FV_HANDLE  *CoreFvHandle;\r
+\r
   CoreFvHandle = FvHandleToCoreHandle (FvHandle);\r
-  \r
-  //\r
-  // To make backward compatiblity, if can not find corresponding the handle of FV\r
-  // then treat FV as build-in FFS2/FFS3 format and memory mapped FV that FV handle is pointed\r
-  // to the address of first byte of FV.\r
-  //\r
-  if ((CoreFvHandle == NULL) && FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {\r
-    return FindFileEx (FvHandle, NULL, SearchType, FileHandle, NULL);\r
-  } \r
-  \r
-  if ((CoreFvHandle == NULL) || CoreFvHandle->FvPpi == NULL) {\r
+\r
+  if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {\r
     return EFI_NOT_FOUND;\r
   }\r
-  \r
+\r
   return CoreFvHandle->FvPpi->FindFileByType (CoreFvHandle->FvPpi, SearchType, FvHandle, FileHandle);\r
 }\r
 \r
-\r
 /**\r
   Search the firmware volumes by index\r
 \r
@@ -910,41 +1130,40 @@ PeiFfsFindNextFile (
   @retval EFI_SUCCESS            The volume was found.\r
 \r
 **/\r
-EFI_STATUS \r
+EFI_STATUS\r
 EFIAPI\r
 PeiFfsFindNextVolume (\r
-  IN CONST EFI_PEI_SERVICES         **PeiServices,\r
-  IN     UINTN                      Instance,\r
-  IN OUT EFI_PEI_FV_HANDLE          *VolumeHandle\r
+  IN CONST EFI_PEI_SERVICES  **PeiServices,\r
+  IN     UINTN               Instance,\r
+  IN OUT EFI_PEI_FV_HANDLE   *VolumeHandle\r
   )\r
 {\r
-  PEI_CORE_INSTANCE  *Private;\r
-  PEI_CORE_FV_HANDLE *CoreFvHandle;\r
-  \r
+  PEI_CORE_INSTANCE   *Private;\r
+  PEI_CORE_FV_HANDLE  *CoreFvHandle;\r
+\r
   if (VolumeHandle == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
-  \r
+\r
   CoreFvHandle = FindNextCoreFvHandle (Private, Instance);\r
   if (CoreFvHandle == NULL) {\r
     *VolumeHandle = NULL;\r
     return EFI_NOT_FOUND;\r
   }\r
-  \r
+\r
   *VolumeHandle = CoreFvHandle->FvHandle;\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Find a file within a volume by its name.\r
 \r
   @param FileName        A pointer to the name of the file to find within the firmware volume.\r
   @param VolumeHandle    The firmware volume to search\r
-  @param FileHandle      Upon exit, points to the found file's handle \r
+  @param FileHandle      Upon exit, points to the found file's handle\r
                          or NULL if it could not be found.\r
 \r
   @retval EFI_SUCCESS            File was found.\r
@@ -953,24 +1172,24 @@ PeiFfsFindNextVolume (
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI \r
+EFIAPI\r
 PeiFfsFindFileByName (\r
-  IN  CONST EFI_GUID        *FileName,\r
-  IN  EFI_PEI_FV_HANDLE     VolumeHandle,\r
-  OUT EFI_PEI_FILE_HANDLE   *FileHandle\r
+  IN  CONST EFI_GUID       *FileName,\r
+  IN  EFI_PEI_FV_HANDLE    VolumeHandle,\r
+  OUT EFI_PEI_FILE_HANDLE  *FileHandle\r
   )\r
 {\r
-  PEI_CORE_FV_HANDLE            *CoreFvHandle;\r
-  \r
+  PEI_CORE_FV_HANDLE  *CoreFvHandle;\r
+\r
   if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   CoreFvHandle = FvHandleToCoreHandle (VolumeHandle);\r
   if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {\r
     return EFI_NOT_FOUND;\r
   }\r
-  \r
+\r
   return CoreFvHandle->FvPpi->FindFileByName (CoreFvHandle->FvPpi, FileName, &VolumeHandle, FileHandle);\r
 }\r
 \r
@@ -986,14 +1205,14 @@ PeiFfsFindFileByName (
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI \r
+EFIAPI\r
 PeiFfsGetFileInfo (\r
   IN EFI_PEI_FILE_HANDLE  FileHandle,\r
   OUT EFI_FV_FILE_INFO    *FileInfo\r
   )\r
 {\r
-  PEI_CORE_FV_HANDLE          *CoreFvHandle;\r
-  \r
+  PEI_CORE_FV_HANDLE  *CoreFvHandle;\r
+\r
   if ((FileHandle == NULL) || (FileInfo == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -1009,6 +1228,50 @@ PeiFfsGetFileInfo (
   return CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, FileHandle, FileInfo);\r
 }\r
 \r
+/**\r
+  Returns information about a specific file.\r
+\r
+  @param FileHandle       Handle of the file.\r
+  @param FileInfo         Upon exit, points to the file's information.\r
+\r
+  @retval EFI_INVALID_PARAMETER If FileInfo is NULL.\r
+  @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.\r
+  @retval EFI_SUCCESS           File information returned.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeiFfsGetFileInfo2 (\r
+  IN EFI_PEI_FILE_HANDLE  FileHandle,\r
+  OUT EFI_FV_FILE_INFO2   *FileInfo\r
+  )\r
+{\r
+  PEI_CORE_FV_HANDLE  *CoreFvHandle;\r
+\r
+  if ((FileHandle == NULL) || (FileInfo == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Retrieve the FirmwareVolume which the file resides in.\r
+  //\r
+  CoreFvHandle = FileHandleToVolume (FileHandle);\r
+  if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if ((CoreFvHandle->FvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) &&\r
+      (CoreFvHandle->FvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION))\r
+  {\r
+    return CoreFvHandle->FvPpi->GetFileInfo2 (CoreFvHandle->FvPpi, FileHandle, FileInfo);\r
+  }\r
+\r
+  //\r
+  // The old FvPpi doesn't support to return file info with authentication status,\r
+  // so return EFI_UNSUPPORTED.\r
+  //\r
+  return EFI_UNSUPPORTED;\r
+}\r
 \r
 /**\r
   Returns information about the specified volume.\r
@@ -1028,56 +1291,127 @@ PeiFfsGetFileInfo (
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI \r
+EFIAPI\r
 PeiFfsGetVolumeInfo (\r
   IN EFI_PEI_FV_HANDLE  VolumeHandle,\r
   OUT EFI_FV_INFO       *VolumeInfo\r
   )\r
 {\r
-  PEI_CORE_FV_HANDLE                     *CoreHandle;\r
-  \r
+  PEI_CORE_FV_HANDLE  *CoreHandle;\r
+\r
   if ((VolumeInfo == NULL) || (VolumeHandle == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   CoreHandle = FvHandleToCoreHandle (VolumeHandle);\r
-  \r
+\r
   if ((CoreHandle == NULL) || (CoreHandle->FvPpi == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   return CoreHandle->FvPpi->GetVolumeInfo (CoreHandle->FvPpi, VolumeHandle, VolumeInfo);\r
 }\r
 \r
 /**\r
-  Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.\r
+  Find USED_SIZE FV_EXT_TYPE entry in FV extension header and get the FV used size.\r
 \r
-  @param ParentFvCoreHandle   Pointer of EFI_CORE_FV_HANDLE to parent Fv image that contain this Fv image.\r
-  @param ParentFvFileHandle   File handle of a Fv type file that contain this Fv image.\r
+  @param[in]  FvHeader      Pointer to FV header.\r
+  @param[out] FvUsedSize    Pointer to FV used size returned,\r
+                            only valid if USED_SIZE FV_EXT_TYPE entry is found.\r
+  @param[out] EraseByte     Pointer to erase byte returned,\r
+                            only valid if USED_SIZE FV_EXT_TYPE entry is found.\r
+\r
+  @retval TRUE              USED_SIZE FV_EXT_TYPE entry is found,\r
+                            FV used size and erase byte are returned.\r
+  @retval FALSE             No USED_SIZE FV_EXT_TYPE entry found.\r
 \r
-  @retval EFI_NOT_FOUND         FV image can't be found.\r
-  @retval EFI_SUCCESS           Successfully to process it.\r
-  @retval EFI_OUT_OF_RESOURCES  Can not allocate page when aligning FV image\r
-  @retval Others                Can not find EFI_SECTION_FIRMWARE_VOLUME_IMAGE section\r
-  \r
 **/\r
-EFI_STATUS\r
-ProcessFvFile (\r
-  IN  PEI_CORE_FV_HANDLE          *ParentFvCoreHandle,\r
-  IN  EFI_PEI_FILE_HANDLE         ParentFvFileHandle\r
+BOOLEAN\r
+GetFvUsedSize (\r
+  IN EFI_FIRMWARE_VOLUME_HEADER  *FvHeader,\r
+  OUT UINT32                     *FvUsedSize,\r
+  OUT UINT8                      *EraseByte\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  EFI_FV_INFO                   ParentFvImageInfo;\r
-  UINT32                        FvAlignment;\r
-  VOID                          *NewFvBuffer;\r
-  EFI_PEI_HOB_POINTERS          HobPtr;\r
-  EFI_PEI_FIRMWARE_VOLUME_PPI   *ParentFvPpi;\r
-  EFI_PEI_FV_HANDLE             ParentFvHandle;\r
-  EFI_FIRMWARE_VOLUME_HEADER    *FvHeader;\r
-  EFI_FV_FILE_INFO              FileInfo;\r
-  UINT64                        FvLength;\r
-  \r
+  UINT16                                        ExtHeaderOffset;\r
+  EFI_FIRMWARE_VOLUME_EXT_HEADER                *ExtHeader;\r
+  EFI_FIRMWARE_VOLUME_EXT_ENTRY                 *ExtEntryList;\r
+  EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE  *ExtEntryUsedSize;\r
+\r
+  ExtHeaderOffset = ReadUnaligned16 (&FvHeader->ExtHeaderOffset);\r
+  if (ExtHeaderOffset != 0) {\r
+    ExtHeader    = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FvHeader + ExtHeaderOffset);\r
+    ExtEntryList = (EFI_FIRMWARE_VOLUME_EXT_ENTRY *)(ExtHeader + 1);\r
+    while ((UINTN)ExtEntryList < ((UINTN)ExtHeader + ReadUnaligned32 (&ExtHeader->ExtHeaderSize))) {\r
+      if (ReadUnaligned16 (&ExtEntryList->ExtEntryType) == EFI_FV_EXT_TYPE_USED_SIZE_TYPE) {\r
+        //\r
+        // USED_SIZE FV_EXT_TYPE entry is found.\r
+        //\r
+        ExtEntryUsedSize = (EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE *)ExtEntryList;\r
+        *FvUsedSize      = ReadUnaligned32 (&ExtEntryUsedSize->UsedSize);\r
+        if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ERASE_POLARITY) != 0) {\r
+          *EraseByte = 0xFF;\r
+        } else {\r
+          *EraseByte = 0;\r
+        }\r
+\r
+        DEBUG ((\r
+          DEBUG_INFO,\r
+          "FV at 0x%x has 0x%x used size, and erase byte is 0x%02x\n",\r
+          FvHeader,\r
+          *FvUsedSize,\r
+          *EraseByte\r
+          ));\r
+        return TRUE;\r
+      }\r
+\r
+      ExtEntryList = (EFI_FIRMWARE_VOLUME_EXT_ENTRY *)\r
+                     ((UINT8 *)ExtEntryList + ReadUnaligned16 (&ExtEntryList->ExtEntrySize));\r
+    }\r
+  }\r
+\r
+  //\r
+  // No USED_SIZE FV_EXT_TYPE entry found.\r
+  //\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Get FV image(s) from the FV type file, then install FV INFO(2) PPI, Build FV(2, 3) HOB.\r
+\r
+  @param PrivateData          PeiCore's private data structure\r
+  @param ParentFvCoreHandle   Pointer of EFI_CORE_FV_HANDLE to parent FV image that contain this FV image.\r
+  @param ParentFvFileHandle   File handle of a FV type file that contain this FV image.\r
+\r
+  @retval EFI_NOT_FOUND         FV image can't be found.\r
+  @retval EFI_SUCCESS           Successfully to process it.\r
+  @retval EFI_OUT_OF_RESOURCES  Can not allocate page when aligning FV image\r
+  @retval EFI_SECURITY_VIOLATION Image is illegal\r
+  @retval Others                Can not find EFI_SECTION_FIRMWARE_VOLUME_IMAGE section\r
+\r
+**/\r
+EFI_STATUS\r
+ProcessFvFile (\r
+  IN  PEI_CORE_INSTANCE    *PrivateData,\r
+  IN  PEI_CORE_FV_HANDLE   *ParentFvCoreHandle,\r
+  IN  EFI_PEI_FILE_HANDLE  ParentFvFileHandle\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  EFI_FV_INFO                  ParentFvImageInfo;\r
+  UINT32                       FvAlignment;\r
+  VOID                         *NewFvBuffer;\r
+  EFI_PEI_HOB_POINTERS         HobPtr;\r
+  EFI_PEI_FIRMWARE_VOLUME_PPI  *ParentFvPpi;\r
+  EFI_PEI_FV_HANDLE            ParentFvHandle;\r
+  EFI_FIRMWARE_VOLUME_HEADER   *FvHeader;\r
+  EFI_FV_FILE_INFO             FileInfo;\r
+  UINT64                       FvLength;\r
+  UINT32                       AuthenticationStatus;\r
+  UINT32                       FvUsedSize;\r
+  UINT8                        EraseByte;\r
+  UINTN                        Index;\r
+\r
   //\r
   // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already\r
   // been extracted.\r
@@ -1088,94 +1422,182 @@ ProcessFvFile (
       //\r
       // this FILE has been dispatched, it will not be dispatched again.\r
       //\r
-      DEBUG ((EFI_D_INFO, "FV file %p has been dispatched!\r\n", ParentFvFileHandle));\r
+      DEBUG ((DEBUG_INFO, "FV file %p has been dispatched!\r\n", ParentFvFileHandle));\r
       return EFI_SUCCESS;\r
     }\r
+\r
     HobPtr.Raw = GET_NEXT_HOB (HobPtr);\r
   }\r
 \r
   ParentFvHandle = ParentFvCoreHandle->FvHandle;\r
   ParentFvPpi    = ParentFvCoreHandle->FvPpi;\r
-  \r
-  //\r
-  // Find FvImage in FvFile\r
-  //\r
-  Status = ParentFvPpi->FindSectionByType (\r
-                          ParentFvPpi,\r
-                          EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
-                          ParentFvFileHandle,\r
-                          (VOID **)&FvHeader\r
-                          );\r
-             \r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
+\r
+  Status = EFI_SUCCESS;\r
 \r
   //\r
-  // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume\r
-  // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from\r
-  // its initial linked location and maintain its alignment.\r
+  // Find FvImage(s) in FvFile\r
   //\r
-  if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {\r
-    //\r
-    // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.\r
-    //\r
-    FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);\r
-    if (FvAlignment < 8) {\r
-      FvAlignment = 8;\r
+  Index = 0;\r
+  do {\r
+    AuthenticationStatus = 0;\r
+    if ((ParentFvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) &&\r
+        (ParentFvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION))\r
+    {\r
+      Status = ParentFvPpi->FindSectionByType2 (\r
+                              ParentFvPpi,\r
+                              EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
+                              Index,\r
+                              ParentFvFileHandle,\r
+                              (VOID **)&FvHeader,\r
+                              &AuthenticationStatus\r
+                              );\r
+    } else {\r
+      //\r
+      // Old FvPpi has no parameter to input SearchInstance,\r
+      // only one instance is supported.\r
+      //\r
+      if (Index > 0) {\r
+        break;\r
+      }\r
+\r
+      Status = ParentFvPpi->FindSectionByType (\r
+                              ParentFvPpi,\r
+                              EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
+                              ParentFvFileHandle,\r
+                              (VOID **)&FvHeader\r
+                              );\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+\r
+    Status = VerifyPeim (PrivateData, ParentFvHandle, ParentFvFileHandle, AuthenticationStatus);\r
+    if (Status == EFI_SECURITY_VIOLATION) {\r
+      break;\r
     }\r
 \r
     //\r
-    // Check FvImage\r
+    // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume\r
+    // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from\r
+    // its initial linked location and maintain its alignment.\r
     //\r
-    if ((UINTN) FvHeader % FvAlignment != 0) {\r
-      FvLength    = ReadUnaligned64 (&FvHeader->FvLength);\r
-      NewFvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32) FvLength), FvAlignment);\r
-      if (NewFvBuffer == NULL) {\r
-        return EFI_OUT_OF_RESOURCES;\r
+    if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {\r
+      //\r
+      // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.\r
+      //\r
+      FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);\r
+      if (FvAlignment < 8) {\r
+        FvAlignment = 8;\r
+      }\r
+\r
+      DEBUG ((\r
+        DEBUG_INFO,\r
+        "%a() FV at 0x%x, FvAlignment required is 0x%x\n",\r
+        __FUNCTION__,\r
+        FvHeader,\r
+        FvAlignment\r
+        ));\r
+\r
+      //\r
+      // Check FvImage alignment.\r
+      //\r
+      if ((UINTN)FvHeader % FvAlignment != 0) {\r
+        FvLength    = ReadUnaligned64 (&FvHeader->FvLength);\r
+        NewFvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32)FvLength), FvAlignment);\r
+        if (NewFvBuffer == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          break;\r
+        }\r
+\r
+        if (GetFvUsedSize (FvHeader, &FvUsedSize, &EraseByte)) {\r
+          //\r
+          // Copy the used bytes and fill the rest with the erase value.\r
+          //\r
+          CopyMem (NewFvBuffer, FvHeader, (UINTN)FvUsedSize);\r
+          SetMem (\r
+            (UINT8 *)NewFvBuffer + FvUsedSize,\r
+            (UINTN)(FvLength - FvUsedSize),\r
+            EraseByte\r
+            );\r
+        } else {\r
+          CopyMem (NewFvBuffer, FvHeader, (UINTN)FvLength);\r
+        }\r
+\r
+        FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)NewFvBuffer;\r
       }\r
-      CopyMem (NewFvBuffer, FvHeader, (UINTN) FvLength);\r
-      FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) NewFvBuffer;\r
     }\r
-  }\r
 \r
-  Status = ParentFvPpi->GetVolumeInfo (ParentFvPpi, ParentFvHandle, &ParentFvImageInfo);\r
-  ASSERT_EFI_ERROR (Status);\r
-  \r
-  Status = ParentFvPpi->GetFileInfo (ParentFvPpi, ParentFvFileHandle, &FileInfo);\r
-  ASSERT_EFI_ERROR (Status);\r
-  \r
-  //\r
-  // Install FvPpi and Build FvHob\r
-  //\r
-  PeiServicesInstallFvInfoPpi (\r
-    &FvHeader->FileSystemGuid,\r
-    (VOID**) FvHeader,\r
-    (UINT32) FvHeader->FvLength,\r
-    &ParentFvImageInfo.FvName,\r
-    &FileInfo.FileName\r
-    );\r
+    Status = ParentFvPpi->GetVolumeInfo (ParentFvPpi, ParentFvHandle, &ParentFvImageInfo);\r
+    ASSERT_EFI_ERROR (Status);\r
 \r
-  //\r
-  // Inform the extracted FvImage to Fv HOB consumer phase, i.e. DXE phase\r
-  //\r
-  BuildFvHob (\r
-    (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
-    FvHeader->FvLength\r
-    );\r
+    Status = ParentFvPpi->GetFileInfo (ParentFvPpi, ParentFvFileHandle, &FileInfo);\r
+    ASSERT_EFI_ERROR (Status);\r
 \r
-  //\r
-  // Makes the encapsulated volume show up in DXE phase to skip processing of\r
-  // encapsulated file again.\r
-  //\r
-  BuildFv2Hob (\r
-    (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
-    FvHeader->FvLength,\r
-    &ParentFvImageInfo.FvName,\r
-    &FileInfo.FileName\r
-    );\r
+    //\r
+    // Install FvInfo(2) Ppi\r
+    // NOTE: FvInfo2 must be installed before FvInfo so that recursive processing of encapsulated\r
+    // FVs inherit the proper AuthenticationStatus.\r
+    //\r
+    PeiServicesInstallFvInfo2Ppi (\r
+      &FvHeader->FileSystemGuid,\r
+      (VOID **)FvHeader,\r
+      (UINT32)FvHeader->FvLength,\r
+      &ParentFvImageInfo.FvName,\r
+      &FileInfo.FileName,\r
+      AuthenticationStatus\r
+      );\r
+\r
+    PeiServicesInstallFvInfoPpi (\r
+      &FvHeader->FileSystemGuid,\r
+      (VOID **)FvHeader,\r
+      (UINT32)FvHeader->FvLength,\r
+      &ParentFvImageInfo.FvName,\r
+      &FileInfo.FileName\r
+      );\r
 \r
-  return EFI_SUCCESS;\r
+    //\r
+    // Expose the extracted FvImage to the FV HOB consumer phase, i.e. DXE phase\r
+    //\r
+    BuildFvHob (\r
+      (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,\r
+      FvHeader->FvLength\r
+      );\r
+\r
+    //\r
+    // Makes the encapsulated volume show up in DXE phase to skip processing of\r
+    // encapsulated file again.\r
+    //\r
+    BuildFv2Hob (\r
+      (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,\r
+      FvHeader->FvLength,\r
+      &ParentFvImageInfo.FvName,\r
+      &FileInfo.FileName\r
+      );\r
+\r
+    //\r
+    // Build FV3 HOB with authentication status to be propagated to DXE.\r
+    //\r
+    BuildFv3Hob (\r
+      (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,\r
+      FvHeader->FvLength,\r
+      AuthenticationStatus,\r
+      TRUE,\r
+      &ParentFvImageInfo.FvName,\r
+      &FileInfo.FileName\r
+      );\r
+\r
+    Index++;\r
+  } while (TRUE);\r
+\r
+  if (Index > 0) {\r
+    //\r
+    // At least one FvImage has been processed successfully.\r
+    //\r
+    return EFI_SUCCESS;\r
+  } else {\r
+    return Status;\r
+  }\r
 }\r
 \r
 /**\r
@@ -1188,15 +1610,15 @@ ProcessFvFile (
   buffer which contains the necessary information for creating\r
   the firmware volume handle. Normally, these values are derived\r
   from the EFI_FIRMWARE_VOLUME_INFO_PPI.\r
-  \r
-  \r
+\r
+\r
   @param This                   Points to this instance of the\r
                                 EFI_PEI_FIRMWARE_VOLUME_PPI.\r
   @param Buffer                 Points to the start of the buffer.\r
   @param BufferSize             Size of the buffer.\r
   @param FvHandle               Points to the returned firmware volume\r
                                 handle. The firmware volume handle must\r
-                                be unique within the system. \r
+                                be unique within the system.\r
 \r
   @retval EFI_SUCCESS           Firmware volume handle created.\r
   @retval EFI_VOLUME_CORRUPTED  Volume was corrupt.\r
@@ -1205,42 +1627,42 @@ ProcessFvFile (
 EFI_STATUS\r
 EFIAPI\r
 PeiFfsFvPpiProcessVolume (\r
-  IN  CONST  EFI_PEI_FIRMWARE_VOLUME_PPI *This,\r
-  IN  VOID                               *Buffer,\r
-  IN  UINTN                              BufferSize,\r
-  OUT EFI_PEI_FV_HANDLE                  *FvHandle\r
+  IN  CONST  EFI_PEI_FIRMWARE_VOLUME_PPI  *This,\r
+  IN  VOID                                *Buffer,\r
+  IN  UINTN                               BufferSize,\r
+  OUT EFI_PEI_FV_HANDLE                   *FvHandle\r
   )\r
 {\r
-  EFI_STATUS          Status;\r
-  \r
+  EFI_STATUS  Status;\r
+\r
   ASSERT (FvHandle != NULL);\r
-  \r
+\r
   if (Buffer == NULL) {\r
     return EFI_VOLUME_CORRUPTED;\r
   }\r
-  \r
+\r
   //\r
   // The build-in EFI_PEI_FIRMWARE_VOLUME_PPI for FFS2/FFS3 support memory-mapped\r
-  // FV image and the handle is pointed to Fv image's buffer.\r
+  // FV image and the handle is pointed to FV image's buffer.\r
   //\r
-  *FvHandle = (EFI_PEI_FV_HANDLE) Buffer;\r
-  \r
+  *FvHandle = (EFI_PEI_FV_HANDLE)Buffer;\r
+\r
   //\r
   // Do verify for given FV buffer.\r
   //\r
-  Status = VerifyFv ((EFI_FIRMWARE_VOLUME_HEADER*) Buffer);\r
-  if (EFI_ERROR(Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Fail to verify FV which address is 0x%11p", Buffer));\r
+  Status = VerifyFv ((EFI_FIRMWARE_VOLUME_HEADER *)Buffer);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Fail to verify FV which address is 0x%11p", Buffer));\r
     return EFI_VOLUME_CORRUPTED;\r
   }\r
 \r
   return EFI_SUCCESS;\r
-}  \r
+}\r
 \r
 /**\r
   Finds the next file of the specified type.\r
 \r
-  This service enables PEI modules to discover additional firmware files. \r
+  This service enables PEI modules to discover additional firmware files.\r
   The FileHandle must be unique within the system.\r
 \r
   @param This           Points to this instance of the\r
@@ -1262,18 +1684,18 @@ PeiFfsFvPpiProcessVolume (
 EFI_STATUS\r
 EFIAPI\r
 PeiFfsFvPpiFindFileByType (\r
-  IN CONST  EFI_PEI_FIRMWARE_VOLUME_PPI *This,\r
-  IN        EFI_FV_FILETYPE             SearchType,\r
-  IN        EFI_PEI_FV_HANDLE           FvHandle,\r
-  IN OUT    EFI_PEI_FILE_HANDLE         *FileHandle\r
+  IN CONST  EFI_PEI_FIRMWARE_VOLUME_PPI  *This,\r
+  IN        EFI_FV_FILETYPE              SearchType,\r
+  IN        EFI_PEI_FV_HANDLE            FvHandle,\r
+  IN OUT    EFI_PEI_FILE_HANDLE          *FileHandle\r
   )\r
-{ \r
+{\r
   return FindFileEx (FvHandle, NULL, SearchType, FileHandle, NULL);\r
 }\r
 \r
 /**\r
-  Find a file within a volume by its name. \r
-  \r
+  Find a file within a volume by its name.\r
+\r
   This service searches for files with a specific name, within\r
   either the specified firmware volume or all firmware volumes.\r
 \r
@@ -1299,33 +1721,33 @@ PeiFfsFvPpiFindFileByType (
 EFI_STATUS\r
 EFIAPI\r
 PeiFfsFvPpiFindFileByName (\r
-  IN  CONST  EFI_PEI_FIRMWARE_VOLUME_PPI *This,\r
-  IN  CONST  EFI_GUID                    *FileName,\r
-  IN  EFI_PEI_FV_HANDLE                  *FvHandle,\r
-  OUT EFI_PEI_FILE_HANDLE                *FileHandle  \r
+  IN  CONST  EFI_PEI_FIRMWARE_VOLUME_PPI  *This,\r
+  IN  CONST  EFI_GUID                     *FileName,\r
+  IN  EFI_PEI_FV_HANDLE                   *FvHandle,\r
+  OUT EFI_PEI_FILE_HANDLE                 *FileHandle\r
   )\r
 {\r
-  EFI_STATUS        Status;\r
-  PEI_CORE_INSTANCE *PrivateData;\r
-  UINTN             Index;\r
-  \r
+  EFI_STATUS         Status;\r
+  PEI_CORE_INSTANCE  *PrivateData;\r
+  UINTN              Index;\r
+\r
   if ((FvHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   if (*FvHandle != NULL) {\r
     Status = FindFileEx (*FvHandle, FileName, 0, FileHandle, NULL);\r
     if (Status == EFI_NOT_FOUND) {\r
       *FileHandle = NULL;\r
     }\r
-  } else {   \r
+  } else {\r
     //\r
     // If *FvHandle = NULL, so search all FV for given filename\r
     //\r
     Status = EFI_NOT_FOUND;\r
-    \r
-    PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());\r
-    for (Index = 0; Index < PrivateData->FvCount; Index ++) {\r
+\r
+    PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());\r
+    for (Index = 0; Index < PrivateData->FvCount; Index++) {\r
       //\r
       // Only search the FV which is associated with a EFI_PEI_FIRMWARE_VOLUME_PPI instance.\r
       //\r
@@ -1338,17 +1760,17 @@ PeiFfsFvPpiFindFileByName (
       }\r
     }\r
   }\r
-  \r
-  return Status;  \r
-}  \r
+\r
+  return Status;\r
+}\r
 \r
 /**\r
   Returns information about a specific file.\r
 \r
   This function returns information about a specific\r
   file, including its file name, type, attributes, starting\r
-  address and size. \r
-   \r
+  address and size.\r
+\r
   @param This                     Points to this instance of the\r
                                   EFI_PEI_FIRMWARE_VOLUME_PPI.\r
   @param FileHandle               Handle of the file.\r
@@ -1359,21 +1781,21 @@ PeiFfsFvPpiFindFileByName (
   @retval EFI_INVALID_PARAMETER   If FileHandle does not\r
                                   represent a valid file.\r
   @retval EFI_INVALID_PARAMETER   If FileInfo is NULL.\r
-  \r
-**/ \r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 PeiFfsFvPpiGetFileInfo (\r
-  IN  CONST EFI_PEI_FIRMWARE_VOLUME_PPI   *This, \r
-  IN        EFI_PEI_FILE_HANDLE           FileHandle, \r
-  OUT       EFI_FV_FILE_INFO              *FileInfo\r
+  IN  CONST EFI_PEI_FIRMWARE_VOLUME_PPI  *This,\r
+  IN        EFI_PEI_FILE_HANDLE          FileHandle,\r
+  OUT       EFI_FV_FILE_INFO             *FileInfo\r
   )\r
 {\r
-  UINT8                       FileState;\r
-  UINT8                       ErasePolarity;\r
-  EFI_FFS_FILE_HEADER         *FileHeader;\r
-  PEI_CORE_FV_HANDLE          *CoreFvHandle;\r
-  PEI_FW_VOL_INSTANCE         *FwVolInstance;\r
+  UINT8                FileState;\r
+  UINT8                ErasePolarity;\r
+  EFI_FFS_FILE_HEADER  *FileHeader;\r
+  PEI_CORE_FV_HANDLE   *CoreFvHandle;\r
+  PEI_FW_VOL_INSTANCE  *FwVolInstance;\r
 \r
   if ((FileHandle == NULL) || (FileInfo == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1396,43 +1818,96 @@ PeiFfsFvPpiGetFileInfo (
   }\r
 \r
   //\r
-  // Get FileState which is the highest bit of the State \r
+  // Get FileState which is the highest bit of the State\r
   //\r
-  FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle);\r
+  FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER *)FileHandle);\r
 \r
   switch (FileState) {\r
     case EFI_FILE_DATA_VALID:\r
     case EFI_FILE_MARKED_FOR_UPDATE:\r
-      break;  \r
+      break;\r
     default:\r
       return EFI_INVALID_PARAMETER;\r
-    }\r
+  }\r
 \r
   FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;\r
-  CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID));\r
-  FileInfo->FileType = FileHeader->Type;\r
-  FileInfo->FileAttributes = FfsAttributes2FvFileAttributes (FileHeader->Attributes);\r
-  if ((CoreFvHandle->FvHeader->Attributes & EFI_FVB2_MEMORY_MAPPED) == EFI_FVB2_MEMORY_MAPPED) {\r
-    FileInfo->FileAttributes |= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED;\r
-  }\r
   if (IS_FFS_FILE2 (FileHeader)) {\r
     ASSERT (FFS_FILE2_SIZE (FileHeader) > 0x00FFFFFF);\r
     if (!FwVolInstance->IsFfs3Fv) {\r
-      DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FileHeader->Name));\r
+      DEBUG ((DEBUG_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FileHeader->Name));\r
       return EFI_INVALID_PARAMETER;\r
     }\r
+\r
     FileInfo->BufferSize = FFS_FILE2_SIZE (FileHeader) - sizeof (EFI_FFS_FILE_HEADER2);\r
-    FileInfo->Buffer = (UINT8 *) FileHeader + sizeof (EFI_FFS_FILE_HEADER2);\r
+    FileInfo->Buffer     = (UINT8 *)FileHeader + sizeof (EFI_FFS_FILE_HEADER2);\r
   } else {\r
     FileInfo->BufferSize = FFS_FILE_SIZE (FileHeader) - sizeof (EFI_FFS_FILE_HEADER);\r
-    FileInfo->Buffer = (UINT8 *) FileHeader + sizeof (EFI_FFS_FILE_HEADER);\r
+    FileInfo->Buffer     = (UINT8 *)FileHeader + sizeof (EFI_FFS_FILE_HEADER);\r
+  }\r
+\r
+  CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof (EFI_GUID));\r
+  FileInfo->FileType       = FileHeader->Type;\r
+  FileInfo->FileAttributes = FfsAttributes2FvFileAttributes (FileHeader->Attributes);\r
+  if ((CoreFvHandle->FvHeader->Attributes & EFI_FVB2_MEMORY_MAPPED) == EFI_FVB2_MEMORY_MAPPED) {\r
+    FileInfo->FileAttributes |= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Returns information about a specific file.\r
+\r
+  This function returns information about a specific\r
+  file, including its file name, type, attributes, starting\r
+  address, size and authentication status.\r
+\r
+  @param This                     Points to this instance of the\r
+                                  EFI_PEI_FIRMWARE_VOLUME_PPI.\r
+  @param FileHandle               Handle of the file.\r
+  @param FileInfo                 Upon exit, points to the file's\r
+                                  information.\r
+\r
+  @retval EFI_SUCCESS             File information returned.\r
+  @retval EFI_INVALID_PARAMETER   If FileHandle does not\r
+                                  represent a valid file.\r
+  @retval EFI_INVALID_PARAMETER   If FileInfo is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeiFfsFvPpiGetFileInfo2 (\r
+  IN  CONST EFI_PEI_FIRMWARE_VOLUME_PPI  *This,\r
+  IN        EFI_PEI_FILE_HANDLE          FileHandle,\r
+  OUT       EFI_FV_FILE_INFO2            *FileInfo\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  PEI_CORE_FV_HANDLE  *CoreFvHandle;\r
+\r
+  if ((FileHandle == NULL) || (FileInfo == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
-  return EFI_SUCCESS;  \r
-}  \r
-  \r
+\r
+  //\r
+  // Retrieve the FirmwareVolume which the file resides in.\r
+  //\r
+  CoreFvHandle = FileHandleToVolume (FileHandle);\r
+  if (CoreFvHandle == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = PeiFfsFvPpiGetFileInfo (This, FileHandle, (EFI_FV_FILE_INFO *)FileInfo);\r
+  if (!EFI_ERROR (Status)) {\r
+    FileInfo->AuthenticationStatus = CoreFvHandle->AuthenticationStatus;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
   This function returns information about the firmware volume.\r
-  \r
+\r
   @param This                     Points to this instance of the\r
                                   EFI_PEI_FIRMWARE_VOLUME_PPI.\r
   @param FvHandle                 Handle to the firmware handle.\r
@@ -1443,56 +1918,56 @@ PeiFfsFvPpiGetFileInfo (
   @retval EFI_INVALID_PARAMETER   FvHandle does not indicate a valid\r
                                   firmware volume or VolumeInfo is NULL.\r
 \r
-**/   \r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 PeiFfsFvPpiGetVolumeInfo (\r
-  IN  CONST  EFI_PEI_FIRMWARE_VOLUME_PPI   *This, \r
-  IN  EFI_PEI_FV_HANDLE                    FvHandle, \r
-  OUT EFI_FV_INFO                          *VolumeInfo\r
+  IN  CONST  EFI_PEI_FIRMWARE_VOLUME_PPI  *This,\r
+  IN  EFI_PEI_FV_HANDLE                   FvHandle,\r
+  OUT EFI_FV_INFO                         *VolumeInfo\r
   )\r
 {\r
-  EFI_FIRMWARE_VOLUME_HEADER             FwVolHeader;\r
-  EFI_FIRMWARE_VOLUME_EXT_HEADER         *FwVolExHeaderInfo;\r
+  EFI_FIRMWARE_VOLUME_HEADER      FwVolHeader;\r
+  EFI_FIRMWARE_VOLUME_EXT_HEADER  *FwVolExHeaderInfo;\r
 \r
   if ((VolumeInfo == NULL) || (FvHandle == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   //\r
-  // VolumeHandle may not align at 8 byte, \r
-  // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte. \r
+  // VolumeHandle may not align at 8 byte,\r
+  // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.\r
   // So, Copy FvHeader into the local FvHeader structure.\r
   //\r
   CopyMem (&FwVolHeader, FvHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
 \r
   //\r
-  // Check Fv Image Signature\r
+  // Check FV Image Signature\r
   //\r
   if (FwVolHeader.Signature != EFI_FVH_SIGNATURE) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   ZeroMem (VolumeInfo, sizeof (EFI_FV_INFO));\r
-  VolumeInfo->FvAttributes  = FwVolHeader.Attributes;\r
-  VolumeInfo->FvStart       = (VOID *) FvHandle;\r
-  VolumeInfo->FvSize        = FwVolHeader.FvLength;\r
-  CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof(EFI_GUID));\r
+  VolumeInfo->FvAttributes = FwVolHeader.Attributes;\r
+  VolumeInfo->FvStart      = (VOID *)FvHandle;\r
+  VolumeInfo->FvSize       = FwVolHeader.FvLength;\r
+  CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof (EFI_GUID));\r
 \r
   if (FwVolHeader.ExtHeaderOffset != 0) {\r
-    FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)FvHandle) + FwVolHeader.ExtHeaderOffset);\r
-    CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));\r
+    FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(((UINT8 *)FvHandle) + FwVolHeader.ExtHeaderOffset);\r
+    CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof (EFI_GUID));\r
   }\r
-  \r
-  return EFI_SUCCESS;  \r
-}    \r
+\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 /**\r
   Find the next matching section in the firmware file.\r
-  \r
+\r
   This service enables PEI modules to discover sections\r
   of a given type within a valid file.\r
-  \r
+\r
   @param This             Points to this instance of the\r
                           EFI_PEI_FIRMWARE_VOLUME_PPI.\r
   @param SearchType       A filter to find only sections of this\r
@@ -1501,7 +1976,7 @@ PeiFfsFvPpiGetVolumeInfo (
                           search.\r
   @param SectionData      Updated upon return to point to the\r
                           section found.\r
-  \r
+\r
   @retval EFI_SUCCESS     Section was found.\r
   @retval EFI_NOT_FOUND   Section of the specified type was not\r
                           found. SectionData contains NULL.\r
@@ -1509,78 +1984,147 @@ PeiFfsFvPpiGetVolumeInfo (
 EFI_STATUS\r
 EFIAPI\r
 PeiFfsFvPpiFindSectionByType (\r
-  IN  CONST EFI_PEI_FIRMWARE_VOLUME_PPI    *This,\r
-  IN        EFI_SECTION_TYPE               SearchType,\r
-  IN        EFI_PEI_FILE_HANDLE            FileHandle,\r
-  OUT VOID                                 **SectionData\r
+  IN  CONST EFI_PEI_FIRMWARE_VOLUME_PPI  *This,\r
+  IN        EFI_SECTION_TYPE             SearchType,\r
+  IN        EFI_PEI_FILE_HANDLE          FileHandle,\r
+  OUT VOID                               **SectionData\r
   )\r
 {\r
-  EFI_FFS_FILE_HEADER                     *FfsFileHeader;\r
-  UINT32                                  FileSize;\r
-  EFI_COMMON_SECTION_HEADER               *Section;\r
-  PEI_FW_VOL_INSTANCE                     *FwVolInstance;\r
+  UINT32  AuthenticationStatus;\r
+\r
+  return PeiFfsFvPpiFindSectionByType2 (This, SearchType, 0, FileHandle, SectionData, &AuthenticationStatus);\r
+}\r
+\r
+/**\r
+  Find the next matching section in the firmware file.\r
+\r
+  This service enables PEI modules to discover sections\r
+  of a given instance and type within a valid file.\r
+\r
+  @param This                   Points to this instance of the\r
+                                EFI_PEI_FIRMWARE_VOLUME_PPI.\r
+  @param SearchType             A filter to find only sections of this\r
+                                type.\r
+  @param SearchInstance         A filter to find the specific instance\r
+                                of sections.\r
+  @param FileHandle             Handle of firmware file in which to\r
+                                search.\r
+  @param SectionData            Updated upon return to point to the\r
+                                section found.\r
+  @param AuthenticationStatus   Updated upon return to point to the\r
+                                authentication status for this section.\r
+\r
+  @retval EFI_SUCCESS     Section was found.\r
+  @retval EFI_NOT_FOUND   Section of the specified type was not\r
+                          found. SectionData contains NULL.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PeiFfsFvPpiFindSectionByType2 (\r
+  IN  CONST EFI_PEI_FIRMWARE_VOLUME_PPI  *This,\r
+  IN        EFI_SECTION_TYPE             SearchType,\r
+  IN        UINTN                        SearchInstance,\r
+  IN        EFI_PEI_FILE_HANDLE          FileHandle,\r
+  OUT VOID                               **SectionData,\r
+  OUT UINT32                             *AuthenticationStatus\r
+  )\r
+{\r
+  EFI_STATUS                 Status;\r
+  EFI_FFS_FILE_HEADER        *FfsFileHeader;\r
+  UINT32                     FileSize;\r
+  EFI_COMMON_SECTION_HEADER  *Section;\r
+  PEI_FW_VOL_INSTANCE        *FwVolInstance;\r
+  PEI_CORE_FV_HANDLE         *CoreFvHandle;\r
+  UINTN                      Instance;\r
+  UINT32                     ExtractedAuthenticationStatus;\r
+\r
+  if (SectionData == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
 \r
   FwVolInstance = PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This);\r
 \r
+  //\r
+  // Retrieve the FirmwareVolume which the file resides in.\r
+  //\r
+  CoreFvHandle = FileHandleToVolume (FileHandle);\r
+  if (CoreFvHandle == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
   FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);\r
 \r
   if (IS_FFS_FILE2 (FfsFileHeader)) {\r
     ASSERT (FFS_FILE2_SIZE (FfsFileHeader) > 0x00FFFFFF);\r
     if (!FwVolInstance->IsFfs3Fv) {\r
-      DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r
+      DEBUG ((DEBUG_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r
       return EFI_NOT_FOUND;\r
     }\r
-    Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));\r
+\r
+    Section  = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));\r
     FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);\r
   } else {\r
-    Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));\r
+    Section  = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));\r
     FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);\r
   }\r
 \r
-  return ProcessSection (\r
-           GetPeiServicesTablePointer (),\r
-           SearchType, \r
-           Section, \r
-           FileSize, \r
-           SectionData,\r
-           FwVolInstance->IsFfs3Fv\r
-           );  \r
-}  \r
+  Instance                      = SearchInstance + 1;\r
+  ExtractedAuthenticationStatus = 0;\r
+  Status                        = ProcessSection (\r
+                                    GetPeiServicesTablePointer (),\r
+                                    SearchType,\r
+                                    &Instance,\r
+                                    Section,\r
+                                    FileSize,\r
+                                    SectionData,\r
+                                    &ExtractedAuthenticationStatus,\r
+                                    FwVolInstance->IsFfs3Fv\r
+                                    );\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Inherit the authentication status.\r
+    //\r
+    *AuthenticationStatus = ExtractedAuthenticationStatus | CoreFvHandle->AuthenticationStatus;\r
+  }\r
+\r
+  return Status;\r
+}\r
 \r
 /**\r
   Convert the handle of FV to pointer of corresponding PEI_CORE_FV_HANDLE.\r
-  \r
+\r
   @param FvHandle   The handle of a FV.\r
-  \r
+\r
   @retval NULL if can not find.\r
-  @return Pointer of corresponding PEI_CORE_FV_HANDLE. \r
+  @return Pointer of corresponding PEI_CORE_FV_HANDLE.\r
 **/\r
 PEI_CORE_FV_HANDLE *\r
 FvHandleToCoreHandle (\r
   IN EFI_PEI_FV_HANDLE  FvHandle\r
   )\r
 {\r
-  UINTN             Index;\r
-  PEI_CORE_INSTANCE *PrivateData;\r
-  \r
-  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());  \r
-  for (Index = 0; Index < PrivateData->FvCount; Index ++) {\r
+  UINTN              Index;\r
+  PEI_CORE_INSTANCE  *PrivateData;\r
+\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());\r
+  for (Index = 0; Index < PrivateData->FvCount; Index++) {\r
     if (FvHandle == PrivateData->Fv[Index].FvHandle) {\r
       return &PrivateData->Fv[Index];\r
     }\r
   }\r
-  \r
+\r
   return NULL;\r
-}  \r
+}\r
 \r
 /**\r
-  Get instance of PEI_CORE_FV_HANDLE for next volume according to given index.\r
-  \r
-  This routine also will install FvInfo ppi for FV hob in PI ways.\r
-  \r
+  Gets a PEI_CORE_FV_HANDLE instance for the next volume according to the given index.\r
+\r
+  This routine also will install an instance of the FvInfo PPI for the FV HOB\r
+  as defined in the PI specification.\r
+\r
   @param Private    Pointer of PEI_CORE_INSTANCE\r
-  @param Instance   The index of FV want to be searched.\r
-  \r
+  @param Instance   Index of the FV to search\r
+\r
   @return Instance of PEI_CORE_FV_HANDLE.\r
 **/\r
 PEI_CORE_FV_HANDLE *\r
@@ -1589,81 +2133,24 @@ FindNextCoreFvHandle (
   IN UINTN              Instance\r
   )\r
 {\r
-  UINTN                    Index;\r
-  BOOLEAN                  Match;\r
-  EFI_HOB_FIRMWARE_VOLUME  *FvHob;\r
-  \r
-  //\r
-  // Handle Framework FvHob and Install FvInfo Ppi for it.\r
-  //\r
-  if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {\r
-    //\r
-    // Loop to search the wanted FirmwareVolume which supports FFS\r
-    //\r
-    FvHob = (EFI_HOB_FIRMWARE_VOLUME *)GetFirstHob (EFI_HOB_TYPE_FV);\r
-    while (FvHob != NULL) {\r
-      //\r
-      // Search whether FvHob has been installed into PeiCore's FV database.\r
-      // If found, no need install new FvInfoPpi for it.\r
-      //\r
-      for (Index = 0, Match = FALSE; Index < Private->FvCount; Index++) {\r
-        if ((EFI_PEI_FV_HANDLE)(UINTN)FvHob->BaseAddress == Private->Fv[Index].FvHeader) {\r
-          Match = TRUE;\r
-          break;\r
-        }\r
-      }\r
-      \r
-      //\r
-      // Search whether FvHob has been cached into PeiCore's Unknown FV database.\r
-      // If found, no need install new FvInfoPpi for it.\r
-      //\r
-      if (!Match) {\r
-        for (Index = 0; Index < Private->UnknownFvInfoCount; Index ++) {\r
-          if ((UINTN)FvHob->BaseAddress == (UINTN)Private->UnknownFvInfo[Index].FvInfo) {\r
-            Match = TRUE;\r
-            break;\r
-          }\r
-        }\r
-      }\r
-\r
-      //\r
-      // If the Fv in FvHob has not been installed into PeiCore's FV database and has\r
-      // not been cached into PeiCore's Unknown FV database, install a new FvInfoPpi\r
-      // for it then PeiCore will dispatch it in callback of FvInfoPpi.\r
-      //\r
-      if (!Match) {\r
-        PeiServicesInstallFvInfoPpi (\r
-          &(((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHob->BaseAddress)->FileSystemGuid),\r
-          (VOID *)(UINTN)FvHob->BaseAddress,\r
-          (UINT32)FvHob->Length,\r
-          NULL,\r
-          NULL\r
-          );\r
-      }\r
-      \r
-      FvHob = (EFI_HOB_FIRMWARE_VOLUME *)GetNextHob (EFI_HOB_TYPE_FV, (VOID *)((UINTN)FvHob + FvHob->Header.HobLength)); \r
-    }\r
-  }\r
-\r
-  ASSERT (Private->FvCount <= FixedPcdGet32 (PcdPeiCoreMaxFvSupported));\r
   if (Instance >= Private->FvCount) {\r
     return NULL;\r
   }\r
 \r
   return &Private->Fv[Instance];\r
-}  \r
+}\r
 \r
 /**\r
   After PeiCore image is shadowed into permanent memory, all build-in FvPpi should\r
-  be re-installed with the instance in permanent memory and all cached FvPpi pointers in \r
-  PrivateData->Fv[] array should be fixed up to be pointed to the one in permenant\r
+  be re-installed with the instance in permanent memory and all cached FvPpi pointers in\r
+  PrivateData->Fv[] array should be fixed up to be pointed to the one in permanent\r
   memory.\r
-  \r
+\r
   @param PrivateData   Pointer to PEI_CORE_INSTANCE.\r
-**/  \r
+**/\r
 VOID\r
 PeiReinitializeFv (\r
-  IN  PEI_CORE_INSTANCE           *PrivateData\r
+  IN  PEI_CORE_INSTANCE  *PrivateData\r
   )\r
 {\r
   VOID                    *OldFfsFvPpi;\r
@@ -1676,11 +2163,11 @@ PeiReinitializeFv (
   // in flash.\r
   //\r
   Status = PeiServicesLocatePpi (\r
-            &gEfiFirmwareFileSystem2Guid,\r
-            0,\r
-            &OldDescriptor,\r
-            &OldFfsFvPpi\r
-            );\r
+             &gEfiFirmwareFileSystem2Guid,\r
+             0,\r
+             &OldDescriptor,\r
+             &OldFfsFvPpi\r
+             );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
@@ -1693,7 +2180,7 @@ PeiReinitializeFv (
   //\r
   // Fixup all FvPpi pointers for the implementation in flash to permanent memory.\r
   //\r
-  for (Index = 0; Index < FixedPcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) {\r
+  for (Index = 0; Index < PrivateData->FvCount; Index++) {\r
     if (PrivateData->Fv[Index].FvPpi == OldFfsFvPpi) {\r
       PrivateData->Fv[Index].FvPpi = &mPeiFfs2FwVol.Fv;\r
     }\r
@@ -1721,7 +2208,7 @@ PeiReinitializeFv (
   //\r
   // Fixup all FvPpi pointers for the implementation in flash to permanent memory.\r
   //\r
-  for (Index = 0; Index < FixedPcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) {\r
+  for (Index = 0; Index < PrivateData->FvCount; Index++) {\r
     if (PrivateData->Fv[Index].FvPpi == OldFfsFvPpi) {\r
       PrivateData->Fv[Index].FvPpi = &mPeiFfs3FwVol.Fv;\r
     }\r
@@ -1729,147 +2216,166 @@ PeiReinitializeFv (
 }\r
 \r
 /**\r
-  Report the information for a new discoveried FV in unknown third-party format.\r
-  \r
-  If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been installed for third-party FV format, but\r
-  the FV in this format has been discoveried, then this FV's information will be cached into \r
-  PEI_CORE_INSTANCE's UnknownFvInfo array.\r
-  Also a notification would be installed for unknown third-party FV format guid, if EFI_PEI_FIRMWARE_VOLUME_PPI\r
-  is installed later by platform's PEIM, the original unknown third-party FV will be processed by\r
+  Report the information for a newly discovered FV in an unknown format.\r
+\r
+  If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been installed for a third-party FV format, but\r
+  the FV has been discovered, then the information of this FV will be cached into PEI_CORE_INSTANCE's\r
+  UnknownFvInfo array.\r
+\r
+  Also a notification would be installed for unknown FV format GUID, if EFI_PEI_FIRMWARE_VOLUME_PPI\r
+  is installed later by platform's PEIM, the original unknown FV will be processed by\r
   using new installed EFI_PEI_FIRMWARE_VOLUME_PPI.\r
-  \r
+\r
   @param PrivateData  Point to instance of PEI_CORE_INSTANCE\r
-  @param Format       Point to the unknown third-party format guid.\r
-  @param FvInfo       Point to FvInfo buffer.\r
-  @param FvInfoSize   The size of FvInfo buffer.\r
-  \r
+  @param FvInfo2Ppi   Point to FvInfo2 PPI.\r
+\r
   @retval EFI_OUT_OF_RESOURCES  The FV info array in PEI_CORE_INSTANCE has no more spaces.\r
   @retval EFI_SUCCESS           Success to add the information for unknown FV.\r
 **/\r
 EFI_STATUS\r
 AddUnknownFormatFvInfo (\r
-  IN PEI_CORE_INSTANCE *PrivateData,\r
-  IN EFI_GUID          *Format,\r
-  IN VOID              *FvInfo,\r
-  IN UINT32            FvInfoSize\r
+  IN PEI_CORE_INSTANCE                  *PrivateData,\r
+  IN EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI  *FvInfo2Ppi\r
   )\r
 {\r
-  PEI_CORE_UNKNOW_FORMAT_FV_INFO    *NewUnknownFv;\r
-  \r
-  if (PrivateData->UnknownFvInfoCount + 1 >= FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+  PEI_CORE_UNKNOW_FORMAT_FV_INFO  *NewUnknownFv;\r
+  VOID                            *TempPtr;\r
+\r
+  if (PrivateData->UnknownFvInfoCount >= PrivateData->MaxUnknownFvInfoCount) {\r
+    //\r
+    // Run out of room, grow the buffer.\r
+    //\r
+    TempPtr = AllocateZeroPool (\r
+                sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO) * (PrivateData->MaxUnknownFvInfoCount + FV_GROWTH_STEP)\r
+                );\r
+    ASSERT (TempPtr != NULL);\r
+    CopyMem (\r
+      TempPtr,\r
+      PrivateData->UnknownFvInfo,\r
+      sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO) * PrivateData->MaxUnknownFvInfoCount\r
+      );\r
+    PrivateData->UnknownFvInfo         = TempPtr;\r
+    PrivateData->MaxUnknownFvInfoCount = PrivateData->MaxUnknownFvInfoCount + FV_GROWTH_STEP;\r
   }\r
-  \r
+\r
   NewUnknownFv = &PrivateData->UnknownFvInfo[PrivateData->UnknownFvInfoCount];\r
-  PrivateData->UnknownFvInfoCount ++;\r
-  \r
-  CopyGuid (&NewUnknownFv->FvFormat, Format);\r
-  NewUnknownFv->FvInfo     = FvInfo;\r
-  NewUnknownFv->FvInfoSize = FvInfoSize;\r
+  PrivateData->UnknownFvInfoCount++;\r
+\r
+  CopyGuid (&NewUnknownFv->FvFormat, &FvInfo2Ppi->FvFormat);\r
+  NewUnknownFv->FvInfo                  = FvInfo2Ppi->FvInfo;\r
+  NewUnknownFv->FvInfoSize              = FvInfo2Ppi->FvInfoSize;\r
+  NewUnknownFv->AuthenticationStatus    = FvInfo2Ppi->AuthenticationStatus;\r
   NewUnknownFv->NotifyDescriptor.Flags  = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
   NewUnknownFv->NotifyDescriptor.Guid   = &NewUnknownFv->FvFormat;\r
   NewUnknownFv->NotifyDescriptor.Notify = ThirdPartyFvPpiNotifyCallback;\r
-  \r
+\r
   PeiServicesNotifyPpi (&NewUnknownFv->NotifyDescriptor);\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  Find the FV information according to third-party FV format guid.\r
-  \r
-  This routine also will remove the FV information found by given FV format guid from\r
+  Find the FV information according to third-party FV format GUID.\r
+\r
+  This routine also will remove the FV information found by given FV format GUID from\r
   PrivateData->UnknownFvInfo[].\r
-  \r
+\r
   @param PrivateData      Point to instance of PEI_CORE_INSTANCE\r
-  @param Format           Point to given FV format guid\r
+  @param Format           Point to given FV format GUID\r
   @param FvInfo           On return, the pointer of FV information buffer\r
   @param FvInfoSize       On return, the size of FV information buffer.\r
-  \r
+  @param AuthenticationStatus On return, the authentication status of FV information buffer.\r
+\r
   @retval EFI_NOT_FOUND  The FV is not found for new installed EFI_PEI_FIRMWARE_VOLUME_PPI\r
   @retval EFI_SUCCESS    Success to find a FV which could be processed by new installed EFI_PEI_FIRMWARE_VOLUME_PPI.\r
 **/\r
 EFI_STATUS\r
 FindUnknownFormatFvInfo (\r
-  IN  PEI_CORE_INSTANCE *PrivateData,\r
-  IN  EFI_GUID          *Format,\r
-  OUT VOID              **FvInfo,\r
-  OUT UINT32            *FvInfoSize\r
+  IN  PEI_CORE_INSTANCE  *PrivateData,\r
+  IN  EFI_GUID           *Format,\r
+  OUT VOID               **FvInfo,\r
+  OUT UINT32             *FvInfoSize,\r
+  OUT UINT32             *AuthenticationStatus\r
   )\r
 {\r
-  UINTN Index;\r
-  UINTN Index2;\r
+  UINTN  Index;\r
+  UINTN  Index2;\r
 \r
   Index = 0;\r
-  for (; Index < PrivateData->UnknownFvInfoCount; Index ++) {\r
+  for ( ; Index < PrivateData->UnknownFvInfoCount; Index++) {\r
     if (CompareGuid (Format, &PrivateData->UnknownFvInfo[Index].FvFormat)) {\r
       break;\r
     }\r
   }\r
-  \r
+\r
   if (Index == PrivateData->UnknownFvInfoCount) {\r
     return EFI_NOT_FOUND;\r
   }\r
-  \r
-  *FvInfo     = PrivateData->UnknownFvInfo[Index].FvInfo;\r
-  *FvInfoSize = PrivateData->UnknownFvInfo[Index].FvInfoSize;\r
-  \r
+\r
+  *FvInfo               = PrivateData->UnknownFvInfo[Index].FvInfo;\r
+  *FvInfoSize           = PrivateData->UnknownFvInfo[Index].FvInfoSize;\r
+  *AuthenticationStatus = PrivateData->UnknownFvInfo[Index].AuthenticationStatus;\r
+\r
   //\r
   // Remove an entry from UnknownFvInfo array.\r
   //\r
   Index2 = Index + 1;\r
-  for (;Index2 < PrivateData->UnknownFvInfoCount; Index2 ++, Index ++) {\r
+  for ( ; Index2 < PrivateData->UnknownFvInfoCount; Index2++, Index++) {\r
     CopyMem (&PrivateData->UnknownFvInfo[Index], &PrivateData->UnknownFvInfo[Index2], sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO));\r
   }\r
-  PrivateData->UnknownFvInfoCount --;\r
+\r
+  PrivateData->UnknownFvInfoCount--;\r
   return EFI_SUCCESS;\r
-}  \r
+}\r
 \r
 /**\r
   Notification callback function for EFI_PEI_FIRMWARE_VOLUME_PPI.\r
-  \r
-  When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format, this \r
-  routine is called to process all discoveried FVs in this format.\r
-  \r
+\r
+  When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format, this\r
+  routine is called to process all discovered FVs in this format.\r
+\r
   @param PeiServices       An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
   @param NotifyDescriptor  Address of the notification descriptor data structure.\r
   @param Ppi               Address of the PPI that was installed.\r
-  \r
+\r
   @retval EFI_SUCCESS  The notification callback is processed correctly.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 ThirdPartyFvPpiNotifyCallback (\r
-  IN EFI_PEI_SERVICES              **PeiServices,\r
-  IN EFI_PEI_NOTIFY_DESCRIPTOR     *NotifyDescriptor,\r
-  IN VOID                          *Ppi\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
   )\r
 {\r
   PEI_CORE_INSTANCE            *PrivateData;\r
   EFI_PEI_FIRMWARE_VOLUME_PPI  *FvPpi;\r
   VOID                         *FvInfo;\r
   UINT32                       FvInfoSize;\r
+  UINT32                       AuthenticationStatus;\r
   EFI_STATUS                   Status;\r
   EFI_PEI_FV_HANDLE            FvHandle;\r
   BOOLEAN                      IsProcessed;\r
   UINTN                        FvIndex;\r
   EFI_PEI_FILE_HANDLE          FileHandle;\r
-  VOID                         *DepexData;  \r
-  \r
-  PrivateData  = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
-  FvPpi = (EFI_PEI_FIRMWARE_VOLUME_PPI*) Ppi;\r
-  \r
+  VOID                         *DepexData;\r
+  UINTN                        CurFvCount;\r
+  VOID                         *TempPtr;\r
+\r
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
+  FvPpi       = (EFI_PEI_FIRMWARE_VOLUME_PPI *)Ppi;\r
+\r
   do {\r
-    Status = FindUnknownFormatFvInfo (PrivateData, NotifyDescriptor->Guid, &FvInfo, &FvInfoSize);\r
+    Status = FindUnknownFormatFvInfo (PrivateData, NotifyDescriptor->Guid, &FvInfo, &FvInfoSize, &AuthenticationStatus);\r
     if (EFI_ERROR (Status)) {\r
       return EFI_SUCCESS;\r
     }\r
-    \r
+\r
     //\r
     // Process new found FV and get FV handle.\r
     //\r
     Status = FvPpi->ProcessVolume (FvPpi, FvInfo, FvInfoSize, &FvHandle);\r
     if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "Fail to process the FV 0x%p, FV may be corrupted!\n", FvInfo));\r
+      DEBUG ((DEBUG_ERROR, "Fail to process the FV 0x%p, FV may be corrupted!\n", FvInfo));\r
       continue;\r
     }\r
 \r
@@ -1877,42 +2383,55 @@ ThirdPartyFvPpiNotifyCallback (
     // Check whether the FV has already been processed.\r
     //\r
     IsProcessed = FALSE;\r
-    for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex ++) {\r
+    for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex++) {\r
       if (PrivateData->Fv[FvIndex].FvHandle == FvHandle) {\r
-        DEBUG ((EFI_D_INFO, "The Fv %p has already been processed!\n", FvInfo));\r
+        DEBUG ((DEBUG_INFO, "The FV %p has already been processed!\n", FvInfo));\r
         IsProcessed = TRUE;\r
         break;\r
       }\r
     }\r
-  \r
+\r
     if (IsProcessed) {\r
       continue;\r
     }\r
-    \r
-    if (PrivateData->FvCount >= FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
-      DEBUG ((EFI_D_ERROR, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData->FvCount + 1, FixedPcdGet32 (PcdPeiCoreMaxFvSupported)));\r
-      DEBUG ((EFI_D_ERROR, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));\r
-      ASSERT (FALSE);\r
+\r
+    if (PrivateData->FvCount >= PrivateData->MaxFvCount) {\r
+      //\r
+      // Run out of room, grow the buffer.\r
+      //\r
+      TempPtr = AllocateZeroPool (\r
+                  sizeof (PEI_CORE_FV_HANDLE) * (PrivateData->MaxFvCount + FV_GROWTH_STEP)\r
+                  );\r
+      ASSERT (TempPtr != NULL);\r
+      CopyMem (\r
+        TempPtr,\r
+        PrivateData->Fv,\r
+        sizeof (PEI_CORE_FV_HANDLE) * PrivateData->MaxFvCount\r
+        );\r
+      PrivateData->Fv         = TempPtr;\r
+      PrivateData->MaxFvCount = PrivateData->MaxFvCount + FV_GROWTH_STEP;\r
     }\r
-        \r
+\r
     //\r
     // Update internal PEI_CORE_FV array.\r
     //\r
-    PrivateData->Fv[PrivateData->FvCount].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) FvInfo;\r
-    PrivateData->Fv[PrivateData->FvCount].FvPpi    = FvPpi;\r
-    PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;\r
+    PrivateData->Fv[PrivateData->FvCount].FvHeader             = (EFI_FIRMWARE_VOLUME_HEADER *)FvInfo;\r
+    PrivateData->Fv[PrivateData->FvCount].FvPpi                = FvPpi;\r
+    PrivateData->Fv[PrivateData->FvCount].FvHandle             = FvHandle;\r
+    PrivateData->Fv[PrivateData->FvCount].AuthenticationStatus = AuthenticationStatus;\r
+    CurFvCount                                                 = PrivateData->FvCount;\r
     DEBUG ((\r
-      EFI_D_INFO, \r
-      "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n", \r
-      (UINT32) PrivateData->FvCount, \r
-      (VOID *) FvInfo, \r
+      DEBUG_INFO,\r
+      "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n",\r
+      (UINT32)CurFvCount,\r
+      (VOID *)FvInfo,\r
       FvInfoSize,\r
       FvHandle\r
-      ));    \r
-    PrivateData->FvCount ++;\r
+      ));\r
+    PrivateData->FvCount++;\r
 \r
     //\r
-    // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE \r
+    // Scan and process the new discovered FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\r
     //\r
     FileHandle = NULL;\r
     do {\r
@@ -1921,13 +2440,13 @@ ThirdPartyFvPpiNotifyCallback (
                         EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r
                         FvHandle,\r
                         &FileHandle\r
-                       );\r
+                        );\r
       if (!EFI_ERROR (Status)) {\r
         Status = FvPpi->FindSectionByType (\r
                           FvPpi,\r
                           EFI_SECTION_PEI_DEPEX,\r
                           FileHandle,\r
-                          (VOID**)&DepexData\r
+                          (VOID **)&DepexData\r
                           );\r
         if (!EFI_ERROR (Status)) {\r
           if (!PeimDispatchReadiness (PeiServices, DepexData)) {\r
@@ -1937,9 +2456,9 @@ ThirdPartyFvPpiNotifyCallback (
             continue;\r
           }\r
         }\r
-        \r
-        DEBUG ((EFI_D_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, PrivateData->FvCount - 1, FvHandle));\r
-        ProcessFvFile (&PrivateData->Fv[PrivateData->FvCount - 1], FileHandle);\r
+\r
+        DEBUG ((DEBUG_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, CurFvCount, FvHandle));\r
+        ProcessFvFile (PrivateData, &PrivateData->Fv[CurFvCount], FileHandle);\r
       }\r
     } while (FileHandle != NULL);\r
   } while (TRUE);\r