]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / FwVolBlock / FwVolBlock.c
index 27e9f9e0b1147a87c0c5f7bdb1ae0706e5667822..d81334ce24d1a2a1bbf8370b48e2165a5c306b03 100644 (file)
@@ -4,21 +4,15 @@
   It consumes FV HOBs and creates read-only Firmare Volume Block protocol\r
   instances for each of them.\r
 \r
-Copyright (c) 2006 - 2008, 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
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "DxeMain.h"\r
 #include "FwVolBlock.h"\r
 \r
-FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = {\r
+FV_MEMMAP_DEVICE_PATH  mFvMemmapDevicePathTemplate = {\r
   {\r
     {\r
       HARDWARE_DEVICE_PATH,\r
@@ -29,8 +23,8 @@ FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = {
       }\r
     },\r
     EfiMemoryMappedIO,\r
-    (EFI_PHYSICAL_ADDRESS) 0,\r
-    (EFI_PHYSICAL_ADDRESS) 0,\r
+    (EFI_PHYSICAL_ADDRESS)0,\r
+    (EFI_PHYSICAL_ADDRESS)0,\r
   },\r
   {\r
     END_DEVICE_PATH_TYPE,\r
@@ -42,7 +36,7 @@ FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = {
   }\r
 };\r
 \r
-FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = {\r
+FV_PIWG_DEVICE_PATH  mFvPIWGDevicePathTemplate = {\r
   {\r
     {\r
       MEDIA_DEVICE_PATH,\r
@@ -81,11 +75,10 @@ EFI_FW_VOL_BLOCK_DEVICE  mFwVolBlock = {
   0,\r
   NULL,\r
   0,\r
+  0,\r
   0\r
 };\r
 \r
-\r
-\r
 /**\r
   Retrieves Volume attributes.  No polarity translations are done.\r
 \r
@@ -102,7 +95,7 @@ FwVolBlockGetAttributes (
   OUT       EFI_FVB_ATTRIBUTES_2                *Attributes\r
   )\r
 {\r
-  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;\r
+  EFI_FW_VOL_BLOCK_DEVICE  *FvbDevice;\r
 \r
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
 \r
@@ -114,8 +107,6 @@ FwVolBlockGetAttributes (
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
-\r
 /**\r
   Modifies the current settings of the firmware volume according to the input parameter.\r
 \r
@@ -139,8 +130,6 @@ FwVolBlockSetAttributes (
   return EFI_UNSUPPORTED;\r
 }\r
 \r
-\r
-\r
 /**\r
   The EraseBlock() function erases one or more blocks as denoted by the\r
   variable argument list. The entire parameter list of blocks must be verified\r
@@ -167,15 +156,13 @@ FwVolBlockSetAttributes (
 EFI_STATUS\r
 EFIAPI\r
 FwVolBlockEraseBlock (\r
-  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,\r
+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,\r
   ...\r
   )\r
 {\r
   return EFI_UNSUPPORTED;\r
 }\r
 \r
-\r
-\r
 /**\r
   Read the specified number of bytes from the block to the input buffer.\r
 \r
@@ -199,19 +186,19 @@ FwVolBlockEraseBlock (
 EFI_STATUS\r
 EFIAPI\r
 FwVolBlockReadBlock (\r
-  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,\r
-  IN CONST  EFI_LBA                              Lba,\r
-  IN CONST  UINTN                                Offset,\r
-  IN OUT    UINTN                                *NumBytes,\r
-  IN OUT    UINT8                                *Buffer\r
+  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,\r
+  IN CONST  EFI_LBA                             Lba,\r
+  IN CONST  UINTN                               Offset,\r
+  IN OUT    UINTN                               *NumBytes,\r
+  IN OUT    UINT8                               *Buffer\r
   )\r
 {\r
-  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;\r
-  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;\r
-  UINT8                                 *LbaOffset;\r
-  UINTN                                 LbaStart;\r
-  UINTN                                 NumOfBytesRead;\r
-  UINTN                                 LbaIndex;\r
+  EFI_FW_VOL_BLOCK_DEVICE     *FvbDevice;\r
+  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;\r
+  UINT8                       *LbaOffset;\r
+  UINTN                       LbaStart;\r
+  UINTN                       NumOfBytesRead;\r
+  UINTN                       LbaIndex;\r
 \r
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
 \r
@@ -222,7 +209,7 @@ FwVolBlockReadBlock (
     return EFI_ACCESS_DENIED;\r
   }\r
 \r
-  LbaIndex = (UINTN) Lba;\r
+  LbaIndex = (UINTN)Lba;\r
   if (LbaIndex >= FvbDevice->NumBlocks) {\r
     //\r
     // Invalid Lba, read nothing.\r
@@ -233,7 +220,7 @@ FwVolBlockReadBlock (
 \r
   if (Offset > FvbDevice->LbaCache[LbaIndex].Length) {\r
     //\r
-    // all exceed boundry, read nothing.\r
+    // all exceed boundary, read nothing.\r
     //\r
     *NumBytes = 0;\r
     return EFI_BAD_BUFFER_SIZE;\r
@@ -242,14 +229,14 @@ FwVolBlockReadBlock (
   NumOfBytesRead = *NumBytes;\r
   if (Offset + NumOfBytesRead > FvbDevice->LbaCache[LbaIndex].Length) {\r
     //\r
-    // partial exceed boundry, read data from current postion to end.\r
+    // partial exceed boundary, read data from current postion to end.\r
     //\r
     NumOfBytesRead = FvbDevice->LbaCache[LbaIndex].Length - Offset;\r
   }\r
 \r
-  LbaStart = FvbDevice->LbaCache[LbaIndex].Base;\r
-  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN) FvbDevice->BaseAddress);\r
-  LbaOffset = (UINT8 *) FwVolHeader + LbaStart + Offset;\r
+  LbaStart    = FvbDevice->LbaCache[LbaIndex].Base;\r
+  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbDevice->BaseAddress);\r
+  LbaOffset   = (UINT8 *)FwVolHeader + LbaStart + Offset;\r
 \r
   //\r
   // Perform read operation\r
@@ -264,8 +251,6 @@ FwVolBlockReadBlock (
   return EFI_BAD_BUFFER_SIZE;\r
 }\r
 \r
-\r
-\r
 /**\r
   Writes the specified number of bytes from the input buffer to the block.\r
 \r
@@ -293,18 +278,16 @@ FwVolBlockReadBlock (
 EFI_STATUS\r
 EFIAPI\r
 FwVolBlockWriteBlock (\r
-  IN     EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,\r
-  IN     EFI_LBA                              Lba,\r
-  IN     UINTN                                Offset,\r
-  IN OUT UINTN                                *NumBytes,\r
-  IN     UINT8                                *Buffer\r
+  IN     EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,\r
+  IN     EFI_LBA                             Lba,\r
+  IN     UINTN                               Offset,\r
+  IN OUT UINTN                               *NumBytes,\r
+  IN     UINT8                               *Buffer\r
   )\r
 {\r
   return EFI_UNSUPPORTED;\r
 }\r
 \r
-\r
-\r
 /**\r
   Get Fvb's base address.\r
 \r
@@ -322,7 +305,7 @@ FwVolBlockGetPhysicalAddress (
   OUT       EFI_PHYSICAL_ADDRESS                *Address\r
   )\r
 {\r
-  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;\r
+  EFI_FW_VOL_BLOCK_DEVICE  *FvbDevice;\r
 \r
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
 \r
@@ -334,8 +317,6 @@ FwVolBlockGetPhysicalAddress (
   return EFI_UNSUPPORTED;\r
 }\r
 \r
-\r
-\r
 /**\r
   Retrieves the size in bytes of a specific block within a firmware volume.\r
 \r
@@ -362,10 +343,10 @@ FwVolBlockGetBlockSize (
   IN OUT    UINTN                               *NumberOfBlocks\r
   )\r
 {\r
-  UINTN                                 TotalBlocks;\r
-  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;\r
-  EFI_FV_BLOCK_MAP_ENTRY                *PtrBlockMapEntry;\r
-  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;\r
+  UINTN                       TotalBlocks;\r
+  EFI_FW_VOL_BLOCK_DEVICE     *FvbDevice;\r
+  EFI_FV_BLOCK_MAP_ENTRY      *PtrBlockMapEntry;\r
+  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;\r
 \r
   FvbDevice = FVB_DEVICE_FROM_THIS (This);\r
 \r
@@ -384,7 +365,7 @@ FwVolBlockGetBlockSize (
   // Search the block map for the given block\r
   //\r
   TotalBlocks = 0;\r
-  while ((PtrBlockMapEntry->NumBlocks != 0) || (PtrBlockMapEntry->Length !=)) {\r
+  while ((PtrBlockMapEntry->NumBlocks != 0) || (PtrBlockMapEntry->Length != 0)) {\r
     TotalBlocks += PtrBlockMapEntry->NumBlocks;\r
     if (Lba < TotalBlocks) {\r
       //\r
@@ -396,13 +377,37 @@ FwVolBlockGetBlockSize (
     PtrBlockMapEntry++;\r
   }\r
 \r
-  *BlockSize = PtrBlockMapEntry->Length;\r
+  *BlockSize      = PtrBlockMapEntry->Length;\r
   *NumberOfBlocks = TotalBlocks - (UINTN)Lba;\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+\r
+  Get FVB authentication status\r
+\r
+  @param FvbProtocol    FVB protocol.\r
+\r
+  @return Authentication status.\r
+\r
+**/\r
+UINT32\r
+GetFvbAuthenticationStatus (\r
+  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvbProtocol\r
+  )\r
+{\r
+  EFI_FW_VOL_BLOCK_DEVICE  *FvbDevice;\r
+  UINT32                   AuthenticationStatus;\r
+\r
+  AuthenticationStatus = 0;\r
+  FvbDevice            = BASE_CR (FvbProtocol, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance);\r
+  if (FvbDevice->Signature == FVB_DEVICE_SIGNATURE) {\r
+    AuthenticationStatus = FvbDevice->AuthenticationStatus;\r
+  }\r
 \r
+  return AuthenticationStatus;\r
+}\r
 \r
 /**\r
   This routine produces a firmware volume block protocol on a given\r
@@ -411,8 +416,10 @@ FwVolBlockGetBlockSize (
   @param  BaseAddress            base address of the firmware volume image\r
   @param  Length                 length of the firmware volume image\r
   @param  ParentHandle           handle of parent firmware volume, if this image\r
-                                 came from an FV image file in another firmware\r
+                                 came from an FV image file and section in another firmware\r
                                  volume (ala capsules)\r
+  @param  AuthenticationStatus   Authentication status inherited, if this image\r
+                                 came from an FV image file and section in another firmware volume.\r
   @param  FvProtocol             Firmware volume block protocol produced.\r
 \r
   @retval EFI_VOLUME_CORRUPTED   Volume corrupted.\r
@@ -423,45 +430,63 @@ FwVolBlockGetBlockSize (
 **/\r
 EFI_STATUS\r
 ProduceFVBProtocolOnBuffer (\r
-  IN EFI_PHYSICAL_ADDRESS   BaseAddress,\r
-  IN UINT64                 Length,\r
-  IN EFI_HANDLE             ParentHandle,\r
-  OUT EFI_HANDLE            *FvProtocol  OPTIONAL\r
+  IN EFI_PHYSICAL_ADDRESS  BaseAddress,\r
+  IN UINT64                Length,\r
+  IN EFI_HANDLE            ParentHandle,\r
+  IN UINT32                AuthenticationStatus,\r
+  OUT EFI_HANDLE           *FvProtocol  OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  EFI_FW_VOL_BLOCK_DEVICE       *FvbDev;\r
-  EFI_FIRMWARE_VOLUME_HEADER    *FwVolHeader;\r
-  UINTN                         BlockIndex;\r
-  UINTN                         BlockIndex2;\r
-  UINTN                         LinearOffset;\r
-  UINT32                        FvAlignment;\r
-  EFI_FV_BLOCK_MAP_ENTRY        *PtrBlockMapEntry;\r
+  EFI_STATUS                  Status;\r
+  EFI_FW_VOL_BLOCK_DEVICE     *FvbDev;\r
+  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;\r
+  UINTN                       BlockIndex;\r
+  UINTN                       BlockIndex2;\r
+  UINTN                       LinearOffset;\r
+  UINT32                      FvAlignment;\r
+  EFI_FV_BLOCK_MAP_ENTRY      *PtrBlockMapEntry;\r
 \r
   FvAlignment = 0;\r
-  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN) BaseAddress;\r
+  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)BaseAddress;\r
   //\r
   // Validate FV Header, if not as expected, return\r
   //\r
   if (FwVolHeader->Signature != EFI_FVH_SIGNATURE) {\r
     return EFI_VOLUME_CORRUPTED;\r
   }\r
+\r
   //\r
-  // Get FvHeader alignment\r
-  //\r
-  FvAlignment = 1 << ((FwVolHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
-  //\r
-  // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value. \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 (FvAlignment < 8) {\r
-    FvAlignment = 8;\r
-  }\r
-  if ((UINTN)BaseAddress % FvAlignment != 0) {\r
+  if ((FwVolHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {\r
     //\r
-    // FvImage buffer is not at its required alignment.\r
+    // Get FvHeader alignment\r
     //\r
-    return EFI_VOLUME_CORRUPTED;\r
+    FvAlignment = 1 << ((FwVolHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
+    //\r
+    // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.\r
+    //\r
+    if (FvAlignment < 8) {\r
+      FvAlignment = 8;\r
+    }\r
+\r
+    if ((UINTN)BaseAddress % FvAlignment != 0) {\r
+      //\r
+      // FvImage buffer is not at its required alignment.\r
+      //\r
+      DEBUG ((\r
+        DEBUG_ERROR,\r
+        "Unaligned FvImage found at 0x%lx:0x%lx, the required alignment is 0x%x\n",\r
+        BaseAddress,\r
+        Length,\r
+        FvAlignment\r
+        ));\r
+      return EFI_VOLUME_CORRUPTED;\r
+    }\r
   }\r
+\r
   //\r
   // Allocate EFI_FW_VOL_BLOCK_DEVICE\r
   //\r
@@ -470,9 +495,10 @@ ProduceFVBProtocolOnBuffer (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  FvbDev->BaseAddress   = BaseAddress;\r
-  FvbDev->FvbAttributes = FwVolHeader->Attributes;\r
+  FvbDev->BaseAddress                     = BaseAddress;\r
+  FvbDev->FvbAttributes                   = FwVolHeader->Attributes;\r
   FvbDev->FwVolBlockInstance.ParentHandle = ParentHandle;\r
+  FvbDev->AuthenticationStatus            = AuthenticationStatus;\r
 \r
   //\r
   // Init the block caching fields of the device\r
@@ -481,29 +507,37 @@ ProduceFVBProtocolOnBuffer (
   FvbDev->NumBlocks = 0;\r
   for (PtrBlockMapEntry = FwVolHeader->BlockMap;\r
        PtrBlockMapEntry->NumBlocks != 0;\r
-       PtrBlockMapEntry++) {\r
+       PtrBlockMapEntry++)\r
+  {\r
     FvbDev->NumBlocks += PtrBlockMapEntry->NumBlocks;\r
   }\r
+\r
   //\r
   // Second, allocate the cache\r
   //\r
+  if (FvbDev->NumBlocks >= (MAX_ADDRESS / sizeof (LBA_CACHE))) {\r
+    CoreFreePool (FvbDev);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
   FvbDev->LbaCache = AllocatePool (FvbDev->NumBlocks * sizeof (LBA_CACHE));\r
   if (FvbDev->LbaCache == NULL) {\r
     CoreFreePool (FvbDev);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   //\r
   // Last, fill in the cache with the linear address of the blocks\r
   //\r
-  BlockIndex = 0;\r
+  BlockIndex   = 0;\r
   LinearOffset = 0;\r
   for (PtrBlockMapEntry = FwVolHeader->BlockMap;\r
-       PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {\r
+       PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++)\r
+  {\r
     for (BlockIndex2 = 0; BlockIndex2 < PtrBlockMapEntry->NumBlocks; BlockIndex2++) {\r
-      FvbDev->LbaCache[BlockIndex].Base = LinearOffset;\r
+      FvbDev->LbaCache[BlockIndex].Base   = LinearOffset;\r
       FvbDev->LbaCache[BlockIndex].Length = PtrBlockMapEntry->Length;\r
-      LinearOffset += PtrBlockMapEntry->Length;\r
+      LinearOffset                       += PtrBlockMapEntry->Length;\r
       BlockIndex++;\r
     }\r
   }\r
@@ -515,36 +549,40 @@ ProduceFVBProtocolOnBuffer (
     //\r
     // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH\r
     //\r
-    FvbDev->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);\r
+    FvbDev->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)AllocateCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);\r
     if (FvbDev->DevicePath == NULL) {\r
       FreePool (FvbDev);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
-    ((FV_MEMMAP_DEVICE_PATH *) FvbDev->DevicePath)->MemMapDevPath.StartingAddress = BaseAddress;\r
-    ((FV_MEMMAP_DEVICE_PATH *) FvbDev->DevicePath)->MemMapDevPath.EndingAddress   = BaseAddress + FwVolHeader->FvLength - 1;\r
+\r
+    ((FV_MEMMAP_DEVICE_PATH *)FvbDev->DevicePath)->MemMapDevPath.StartingAddress = BaseAddress;\r
+    ((FV_MEMMAP_DEVICE_PATH *)FvbDev->DevicePath)->MemMapDevPath.EndingAddress   = BaseAddress + FwVolHeader->FvLength - 1;\r
   } else {\r
     //\r
     // FV contains extension header, then produce MEDIA_FW_VOL_DEVICE_PATH\r
     //\r
-    FvbDev->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate);\r
+    FvbDev->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)AllocateCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate);\r
     if (FvbDev->DevicePath == NULL) {\r
       FreePool (FvbDev);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
+\r
     CopyGuid (\r
-      &((FV_PIWG_DEVICE_PATH *)FvbDev->DevicePath)->FvDevPath.FvName, \r
+      &((FV_PIWG_DEVICE_PATH *)FvbDev->DevicePath)->FvDevPath.FvName,\r
       (GUID *)(UINTN)(BaseAddress + FwVolHeader->ExtHeaderOffset)\r
       );\r
   }\r
-  \r
+\r
   //\r
   //\r
   // Attach FvVolBlock Protocol to new handle\r
   //\r
   Status = CoreInstallMultipleProtocolInterfaces (\r
              &FvbDev->Handle,\r
-             &gEfiFirmwareVolumeBlockProtocolGuid,     &FvbDev->FwVolBlockInstance,\r
-             &gEfiDevicePathProtocolGuid,              FvbDev->DevicePath,\r
+             &gEfiFirmwareVolumeBlockProtocolGuid,\r
+             &FvbDev->FwVolBlockInstance,\r
+             &gEfiDevicePathProtocolGuid,\r
+             FvbDev->DevicePath,\r
              NULL\r
              );\r
 \r
@@ -558,8 +596,6 @@ ProduceFVBProtocolOnBuffer (
   return Status;\r
 }\r
 \r
-\r
-\r
 /**\r
   This routine consumes FV hobs and produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate.\r
 \r
@@ -573,34 +609,54 @@ ProduceFVBProtocolOnBuffer (
 EFI_STATUS\r
 EFIAPI\r
 FwVolBlockDriverInit (\r
-  IN EFI_HANDLE                 ImageHandle,\r
-  IN EFI_SYSTEM_TABLE           *SystemTable\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
   )\r
 {\r
-  EFI_PEI_HOB_POINTERS          FvHob;\r
+  EFI_PEI_HOB_POINTERS  FvHob;\r
+  EFI_PEI_HOB_POINTERS  Fv3Hob;\r
+  UINT32                AuthenticationStatus;\r
 \r
   //\r
   // Core Needs Firmware Volumes to function\r
   //\r
   FvHob.Raw = GetHobList ();\r
   while ((FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw)) != NULL) {\r
+    AuthenticationStatus = 0;\r
+    //\r
+    // Get the authentication status propagated from PEI-phase to DXE.\r
+    //\r
+    Fv3Hob.Raw = GetHobList ();\r
+    while ((Fv3Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV3, Fv3Hob.Raw)) != NULL) {\r
+      if ((Fv3Hob.FirmwareVolume3->BaseAddress == FvHob.FirmwareVolume->BaseAddress) &&\r
+          (Fv3Hob.FirmwareVolume3->Length == FvHob.FirmwareVolume->Length))\r
+      {\r
+        AuthenticationStatus = Fv3Hob.FirmwareVolume3->AuthenticationStatus;\r
+        break;\r
+      }\r
+\r
+      Fv3Hob.Raw = GET_NEXT_HOB (Fv3Hob);\r
+    }\r
+\r
     //\r
     // Produce an FVB protocol for it\r
     //\r
-    ProduceFVBProtocolOnBuffer (FvHob.FirmwareVolume->BaseAddress, FvHob.FirmwareVolume->Length, NULL, NULL);\r
+    ProduceFVBProtocolOnBuffer (FvHob.FirmwareVolume->BaseAddress, FvHob.FirmwareVolume->Length, NULL, AuthenticationStatus, NULL);\r
     FvHob.Raw = GET_NEXT_HOB (FvHob);\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
-\r
 /**\r
   This DXE service routine is used to process a firmware volume. In\r
   particular, it can be called by BDS to process a single firmware\r
   volume found in a capsule.\r
 \r
+  Caution: The caller need validate the input firmware volume to follow\r
+  PI specification.\r
+  DxeCore will trust the input data and process firmware volume directly.\r
+\r
   @param  FvHeader               pointer to a firmware volume header\r
   @param  Size                   the size of the buffer pointed to by FvHeader\r
   @param  FVProtocolHandle       the handle on which a firmware volume protocol\r
@@ -616,21 +672,22 @@ FwVolBlockDriverInit (
 EFI_STATUS\r
 EFIAPI\r
 CoreProcessFirmwareVolume (\r
-  IN VOID                             *FvHeader,\r
-  IN UINTN                            Size,\r
-  OUT EFI_HANDLE                      *FVProtocolHandle\r
+  IN VOID         *FvHeader,\r
+  IN UINTN        Size,\r
+  OUT EFI_HANDLE  *FVProtocolHandle\r
   )\r
 {\r
   VOID        *Ptr;\r
   EFI_STATUS  Status;\r
 \r
   *FVProtocolHandle = NULL;\r
-  Status = ProduceFVBProtocolOnBuffer (\r
-            (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
-            (UINT64)Size,\r
-            NULL,\r
-            FVProtocolHandle\r
-            );\r
+  Status            = ProduceFVBProtocolOnBuffer (\r
+                        (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,\r
+                        (UINT64)Size,\r
+                        NULL,\r
+                        0,\r
+                        FVProtocolHandle\r
+                        );\r
   //\r
   // Since in our implementation we use register-protocol-notify to put a\r
   // FV protocol on the FVB protocol handle, we can't directly verify that\r
@@ -639,16 +696,16 @@ CoreProcessFirmwareVolume (
   // well. Otherwise we have to assume that the volume was corrupted\r
   // somehow.\r
   //\r
-  if (!EFI_ERROR(Status)) {\r
-    Ptr = NULL;\r
-    Status = CoreHandleProtocol (*FVProtocolHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **) &Ptr);\r
-    if (EFI_ERROR(Status) || (Ptr == NULL)) {\r
+  if (!EFI_ERROR (Status)) {\r
+    ASSERT (*FVProtocolHandle != NULL);\r
+    Ptr    = NULL;\r
+    Status = CoreHandleProtocol (*FVProtocolHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Ptr);\r
+    if (EFI_ERROR (Status) || (Ptr == NULL)) {\r
       return EFI_VOLUME_CORRUPTED;\r
     }\r
+\r
     return EFI_SUCCESS;\r
   }\r
+\r
   return Status;\r
 }\r
-\r
-\r
-\r