/** @file
  Implementations for Firmware Volume Block protocol.

  It consumes FV HOBs and creates read-only Firmare Volume Block protocol
  instances for each of them.

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "DxeMain.h"
#include "FwVolBlock.h"

FV_MEMMAP_DEVICE_PATH  mFvMemmapDevicePathTemplate = {
  {
    {
      HARDWARE_DEVICE_PATH,
      HW_MEMMAP_DP,
      {
        (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
        (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8)
      }
    },
    EfiMemoryMappedIO,
    (EFI_PHYSICAL_ADDRESS)0,
    (EFI_PHYSICAL_ADDRESS)0,
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    {
      END_DEVICE_PATH_LENGTH,
      0
    }
  }
};

FV_PIWG_DEVICE_PATH  mFvPIWGDevicePathTemplate = {
  {
    {
      MEDIA_DEVICE_PATH,
      MEDIA_PIWG_FW_VOL_DP,
      {
        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)),
        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8)
      }
    },
    { 0 }
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    {
      END_DEVICE_PATH_LENGTH,
      0
    }
  }
};

EFI_FW_VOL_BLOCK_DEVICE  mFwVolBlock = {
  FVB_DEVICE_SIGNATURE,
  NULL,
  NULL,
  {
    FwVolBlockGetAttributes,
    (EFI_FVB_SET_ATTRIBUTES)FwVolBlockSetAttributes,
    FwVolBlockGetPhysicalAddress,
    FwVolBlockGetBlockSize,
    FwVolBlockReadBlock,
    (EFI_FVB_WRITE)FwVolBlockWriteBlock,
    (EFI_FVB_ERASE_BLOCKS)FwVolBlockEraseBlock,
    NULL
  },
  0,
  NULL,
  0,
  0,
  0
};

/**
  Retrieves Volume attributes.  No polarity translations are done.

  @param  This                   Calling context
  @param  Attributes             output buffer which contains attributes

  @retval EFI_SUCCESS            The firmware volume attributes were returned.

**/
EFI_STATUS
EFIAPI
FwVolBlockGetAttributes (
  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
  OUT       EFI_FVB_ATTRIBUTES_2                *Attributes
  )
{
  EFI_FW_VOL_BLOCK_DEVICE  *FvbDevice;

  FvbDevice = FVB_DEVICE_FROM_THIS (This);

  //
  // Since we are read only, it's safe to get attributes data from our in-memory copy.
  //
  *Attributes = FvbDevice->FvbAttributes & ~EFI_FVB2_WRITE_STATUS;

  return EFI_SUCCESS;
}

/**
  Modifies the current settings of the firmware volume according to the input parameter.

  @param  This                   Calling context
  @param  Attributes             input buffer which contains attributes

  @retval EFI_SUCCESS            The firmware volume attributes were returned.
  @retval EFI_INVALID_PARAMETER  The attributes requested are in conflict with
                                 the capabilities as declared in the firmware
                                 volume header.
  @retval EFI_UNSUPPORTED        Not supported.

**/
EFI_STATUS
EFIAPI
FwVolBlockSetAttributes (
  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
  IN CONST  EFI_FVB_ATTRIBUTES_2                *Attributes
  )
{
  return EFI_UNSUPPORTED;
}

/**
  The EraseBlock() function erases one or more blocks as denoted by the
  variable argument list. The entire parameter list of blocks must be verified
  prior to erasing any blocks.  If a block is requested that does not exist
  within the associated firmware volume (it has a larger index than the last
  block of the firmware volume), the EraseBlock() function must return
  EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.

  @param  This                   Calling context
  @param  ...                    Starting LBA followed by Number of Lba to erase.
                                 a -1 to terminate the list.

  @retval EFI_SUCCESS            The erase request was successfully completed.
  @retval EFI_ACCESS_DENIED      The firmware volume is in the WriteDisabled
                                 state.
  @retval EFI_DEVICE_ERROR       The block device is not functioning correctly
                                 and could not be written. The firmware device
                                 may have been partially erased.
  @retval EFI_INVALID_PARAMETER  One or more of the LBAs listed in the variable
                                 argument list do
  @retval EFI_UNSUPPORTED        Not supported.

**/
EFI_STATUS
EFIAPI
FwVolBlockEraseBlock (
  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
  ...
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Read the specified number of bytes from the block to the input buffer.

  @param  This                   Indicates the calling context.
  @param  Lba                    The starting logical block index to read.
  @param  Offset                 Offset into the block at which to begin reading.
  @param  NumBytes               Pointer to a UINT32. At entry, *NumBytes
                                 contains the total size of the buffer. At exit,
                                 *NumBytes contains the total number of bytes
                                 actually read.
  @param  Buffer                 Pinter to a caller-allocated buffer that
                                 contains the destine for the read.

  @retval EFI_SUCCESS            The firmware volume was read successfully.
  @retval EFI_BAD_BUFFER_SIZE    The read was attempted across an LBA boundary.
  @retval EFI_ACCESS_DENIED      Access denied.
  @retval EFI_DEVICE_ERROR       The block device is malfunctioning and could not
                                 be read.

**/
EFI_STATUS
EFIAPI
FwVolBlockReadBlock (
  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
  IN CONST  EFI_LBA                             Lba,
  IN CONST  UINTN                               Offset,
  IN OUT    UINTN                               *NumBytes,
  IN OUT    UINT8                               *Buffer
  )
{
  EFI_FW_VOL_BLOCK_DEVICE     *FvbDevice;
  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;
  UINT8                       *LbaOffset;
  UINTN                       LbaStart;
  UINTN                       NumOfBytesRead;
  UINTN                       LbaIndex;

  FvbDevice = FVB_DEVICE_FROM_THIS (This);

  //
  // Check if This FW can be read
  //
  if ((FvbDevice->FvbAttributes & EFI_FVB2_READ_STATUS) == 0) {
    return EFI_ACCESS_DENIED;
  }

  LbaIndex = (UINTN)Lba;
  if (LbaIndex >= FvbDevice->NumBlocks) {
    //
    // Invalid Lba, read nothing.
    //
    *NumBytes = 0;
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Offset > FvbDevice->LbaCache[LbaIndex].Length) {
    //
    // all exceed boundary, read nothing.
    //
    *NumBytes = 0;
    return EFI_BAD_BUFFER_SIZE;
  }

  NumOfBytesRead = *NumBytes;
  if (Offset + NumOfBytesRead > FvbDevice->LbaCache[LbaIndex].Length) {
    //
    // partial exceed boundary, read data from current postion to end.
    //
    NumOfBytesRead = FvbDevice->LbaCache[LbaIndex].Length - Offset;
  }

  LbaStart    = FvbDevice->LbaCache[LbaIndex].Base;
  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbDevice->BaseAddress);
  LbaOffset   = (UINT8 *)FwVolHeader + LbaStart + Offset;

  //
  // Perform read operation
  //
  CopyMem (Buffer, LbaOffset, NumOfBytesRead);

  if (NumOfBytesRead == *NumBytes) {
    return EFI_SUCCESS;
  }

  *NumBytes = NumOfBytesRead;
  return EFI_BAD_BUFFER_SIZE;
}

/**
  Writes the specified number of bytes from the input buffer to the block.

  @param  This                   Indicates the calling context.
  @param  Lba                    The starting logical block index to write to.
  @param  Offset                 Offset into the block at which to begin writing.
  @param  NumBytes               Pointer to a UINT32. At entry, *NumBytes
                                 contains the total size of the buffer. At exit,
                                 *NumBytes contains the total number of bytes
                                 actually written.
  @param  Buffer                 Pinter to a caller-allocated buffer that
                                 contains the source for the write.

  @retval EFI_SUCCESS            The firmware volume was written successfully.
  @retval EFI_BAD_BUFFER_SIZE    The write was attempted across an LBA boundary.
                                 On output, NumBytes contains the total number of
                                 bytes actually written.
  @retval EFI_ACCESS_DENIED      The firmware volume is in the WriteDisabled
                                 state.
  @retval EFI_DEVICE_ERROR       The block device is malfunctioning and could not
                                 be written.
  @retval EFI_UNSUPPORTED        Not supported.

**/
EFI_STATUS
EFIAPI
FwVolBlockWriteBlock (
  IN     EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
  IN     EFI_LBA                             Lba,
  IN     UINTN                               Offset,
  IN OUT UINTN                               *NumBytes,
  IN     UINT8                               *Buffer
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Get Fvb's base address.

  @param  This                   Indicates the calling context.
  @param  Address                Fvb device base address.

  @retval EFI_SUCCESS            Successfully got Fvb's base address.
  @retval EFI_UNSUPPORTED        Not supported.

**/
EFI_STATUS
EFIAPI
FwVolBlockGetPhysicalAddress (
  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
  OUT       EFI_PHYSICAL_ADDRESS                *Address
  )
{
  EFI_FW_VOL_BLOCK_DEVICE  *FvbDevice;

  FvbDevice = FVB_DEVICE_FROM_THIS (This);

  if ((FvbDevice->FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) {
    *Address = FvbDevice->BaseAddress;
    return EFI_SUCCESS;
  }

  return EFI_UNSUPPORTED;
}

/**
  Retrieves the size in bytes of a specific block within a firmware volume.

  @param  This                   Indicates the calling context.
  @param  Lba                    Indicates the block for which to return the
                                 size.
  @param  BlockSize              Pointer to a caller-allocated UINTN in which the
                                 size of the block is returned.
  @param  NumberOfBlocks         Pointer to a caller-allocated UINTN in which the
                                 number of consecutive blocks starting with Lba
                                 is returned. All blocks in this range have a
                                 size of BlockSize.

  @retval EFI_SUCCESS            The firmware volume base address is returned.
  @retval EFI_INVALID_PARAMETER  The requested LBA is out of range.

**/
EFI_STATUS
EFIAPI
FwVolBlockGetBlockSize (
  IN CONST  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
  IN CONST  EFI_LBA                             Lba,
  IN OUT    UINTN                               *BlockSize,
  IN OUT    UINTN                               *NumberOfBlocks
  )
{
  UINTN                       TotalBlocks;
  EFI_FW_VOL_BLOCK_DEVICE     *FvbDevice;
  EFI_FV_BLOCK_MAP_ENTRY      *PtrBlockMapEntry;
  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;

  FvbDevice = FVB_DEVICE_FROM_THIS (This);

  //
  // Do parameter checking
  //
  if (Lba >= FvbDevice->NumBlocks) {
    return EFI_INVALID_PARAMETER;
  }

  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbDevice->BaseAddress);

  PtrBlockMapEntry = FwVolHeader->BlockMap;

  //
  // Search the block map for the given block
  //
  TotalBlocks = 0;
  while ((PtrBlockMapEntry->NumBlocks != 0) || (PtrBlockMapEntry->Length != 0)) {
    TotalBlocks += PtrBlockMapEntry->NumBlocks;
    if (Lba < TotalBlocks) {
      //
      // We find the range
      //
      break;
    }

    PtrBlockMapEntry++;
  }

  *BlockSize      = PtrBlockMapEntry->Length;
  *NumberOfBlocks = TotalBlocks - (UINTN)Lba;

  return EFI_SUCCESS;
}

/**

  Get FVB authentication status

  @param FvbProtocol    FVB protocol.

  @return Authentication status.

**/
UINT32
GetFvbAuthenticationStatus (
  IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvbProtocol
  )
{
  EFI_FW_VOL_BLOCK_DEVICE  *FvbDevice;
  UINT32                   AuthenticationStatus;

  AuthenticationStatus = 0;
  FvbDevice            = BASE_CR (FvbProtocol, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance);
  if (FvbDevice->Signature == FVB_DEVICE_SIGNATURE) {
    AuthenticationStatus = FvbDevice->AuthenticationStatus;
  }

  return AuthenticationStatus;
}

/**
  This routine produces a firmware volume block protocol on a given
  buffer.

  @param  BaseAddress            base address of the firmware volume image
  @param  Length                 length of the firmware volume image
  @param  ParentHandle           handle of parent firmware volume, if this image
                                 came from an FV image file and section in another firmware
                                 volume (ala capsules)
  @param  AuthenticationStatus   Authentication status inherited, if this image
                                 came from an FV image file and section in another firmware volume.
  @param  FvProtocol             Firmware volume block protocol produced.

  @retval EFI_VOLUME_CORRUPTED   Volume corrupted.
  @retval EFI_OUT_OF_RESOURCES   No enough buffer to be allocated.
  @retval EFI_SUCCESS            Successfully produced a FVB protocol on given
                                 buffer.

**/
EFI_STATUS
ProduceFVBProtocolOnBuffer (
  IN EFI_PHYSICAL_ADDRESS  BaseAddress,
  IN UINT64                Length,
  IN EFI_HANDLE            ParentHandle,
  IN UINT32                AuthenticationStatus,
  OUT EFI_HANDLE           *FvProtocol  OPTIONAL
  )
{
  EFI_STATUS                  Status;
  EFI_FW_VOL_BLOCK_DEVICE     *FvbDev;
  EFI_FIRMWARE_VOLUME_HEADER  *FwVolHeader;
  UINTN                       BlockIndex;
  UINTN                       BlockIndex2;
  UINTN                       LinearOffset;
  UINT32                      FvAlignment;
  EFI_FV_BLOCK_MAP_ENTRY      *PtrBlockMapEntry;

  FvAlignment = 0;
  FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)BaseAddress;
  //
  // Validate FV Header, if not as expected, return
  //
  if (FwVolHeader->Signature != EFI_FVH_SIGNATURE) {
    return EFI_VOLUME_CORRUPTED;
  }

  //
  // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume
  // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from
  // its initial linked location and maintain its alignment.
  //
  if ((FwVolHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {
    //
    // Get FvHeader alignment
    //
    FvAlignment = 1 << ((FwVolHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);
    //
    // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.
    //
    if (FvAlignment < 8) {
      FvAlignment = 8;
    }

    if ((UINTN)BaseAddress % FvAlignment != 0) {
      //
      // FvImage buffer is not at its required alignment.
      //
      DEBUG ((
        DEBUG_ERROR,
        "Unaligned FvImage found at 0x%lx:0x%lx, the required alignment is 0x%x\n",
        BaseAddress,
        Length,
        FvAlignment
        ));
      return EFI_VOLUME_CORRUPTED;
    }
  }

  //
  // Allocate EFI_FW_VOL_BLOCK_DEVICE
  //
  FvbDev = AllocateCopyPool (sizeof (EFI_FW_VOL_BLOCK_DEVICE), &mFwVolBlock);
  if (FvbDev == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  FvbDev->BaseAddress                     = BaseAddress;
  FvbDev->FvbAttributes                   = FwVolHeader->Attributes;
  FvbDev->FwVolBlockInstance.ParentHandle = ParentHandle;
  FvbDev->AuthenticationStatus            = AuthenticationStatus;

  //
  // Init the block caching fields of the device
  // First, count the number of blocks
  //
  FvbDev->NumBlocks = 0;
  for (PtrBlockMapEntry = FwVolHeader->BlockMap;
       PtrBlockMapEntry->NumBlocks != 0;
       PtrBlockMapEntry++)
  {
    FvbDev->NumBlocks += PtrBlockMapEntry->NumBlocks;
  }

  //
  // Second, allocate the cache
  //
  if (FvbDev->NumBlocks >= (MAX_ADDRESS / sizeof (LBA_CACHE))) {
    CoreFreePool (FvbDev);
    return EFI_OUT_OF_RESOURCES;
  }

  FvbDev->LbaCache = AllocatePool (FvbDev->NumBlocks * sizeof (LBA_CACHE));
  if (FvbDev->LbaCache == NULL) {
    CoreFreePool (FvbDev);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Last, fill in the cache with the linear address of the blocks
  //
  BlockIndex   = 0;
  LinearOffset = 0;
  for (PtrBlockMapEntry = FwVolHeader->BlockMap;
       PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++)
  {
    for (BlockIndex2 = 0; BlockIndex2 < PtrBlockMapEntry->NumBlocks; BlockIndex2++) {
      FvbDev->LbaCache[BlockIndex].Base   = LinearOffset;
      FvbDev->LbaCache[BlockIndex].Length = PtrBlockMapEntry->Length;
      LinearOffset                       += PtrBlockMapEntry->Length;
      BlockIndex++;
    }
  }

  //
  // Judget whether FV name guid is produced in Fv extension header
  //
  if (FwVolHeader->ExtHeaderOffset == 0) {
    //
    // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH
    //
    FvbDev->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)AllocateCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);
    if (FvbDev->DevicePath == NULL) {
      FreePool (FvbDev);
      return EFI_OUT_OF_RESOURCES;
    }

    ((FV_MEMMAP_DEVICE_PATH *)FvbDev->DevicePath)->MemMapDevPath.StartingAddress = BaseAddress;
    ((FV_MEMMAP_DEVICE_PATH *)FvbDev->DevicePath)->MemMapDevPath.EndingAddress   = BaseAddress + FwVolHeader->FvLength - 1;
  } else {
    //
    // FV contains extension header, then produce MEDIA_FW_VOL_DEVICE_PATH
    //
    FvbDev->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)AllocateCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate);
    if (FvbDev->DevicePath == NULL) {
      FreePool (FvbDev);
      return EFI_OUT_OF_RESOURCES;
    }

    CopyGuid (
      &((FV_PIWG_DEVICE_PATH *)FvbDev->DevicePath)->FvDevPath.FvName,
      (GUID *)(UINTN)(BaseAddress + FwVolHeader->ExtHeaderOffset)
      );
  }

  //
  //
  // Attach FvVolBlock Protocol to new handle
  //
  Status = CoreInstallMultipleProtocolInterfaces (
             &FvbDev->Handle,
             &gEfiFirmwareVolumeBlockProtocolGuid,
             &FvbDev->FwVolBlockInstance,
             &gEfiDevicePathProtocolGuid,
             FvbDev->DevicePath,
             NULL
             );

  //
  // If they want the handle back, set it.
  //
  if (FvProtocol != NULL) {
    *FvProtocol = FvbDev->Handle;
  }

  return Status;
}

/**
  This routine consumes FV hobs and produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate.

  @param  ImageHandle            The image handle.
  @param  SystemTable            The system table.

  @retval EFI_SUCCESS            Successfully initialized firmware volume block
                                 driver.

**/
EFI_STATUS
EFIAPI
FwVolBlockDriverInit (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_PEI_HOB_POINTERS  FvHob;
  EFI_PEI_HOB_POINTERS  Fv3Hob;
  UINT32                AuthenticationStatus;

  //
  // Core Needs Firmware Volumes to function
  //
  FvHob.Raw = GetHobList ();
  while ((FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw)) != NULL) {
    AuthenticationStatus = 0;
    //
    // Get the authentication status propagated from PEI-phase to DXE.
    //
    Fv3Hob.Raw = GetHobList ();
    while ((Fv3Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV3, Fv3Hob.Raw)) != NULL) {
      if ((Fv3Hob.FirmwareVolume3->BaseAddress == FvHob.FirmwareVolume->BaseAddress) &&
          (Fv3Hob.FirmwareVolume3->Length == FvHob.FirmwareVolume->Length))
      {
        AuthenticationStatus = Fv3Hob.FirmwareVolume3->AuthenticationStatus;
        break;
      }

      Fv3Hob.Raw = GET_NEXT_HOB (Fv3Hob);
    }

    //
    // Produce an FVB protocol for it
    //
    ProduceFVBProtocolOnBuffer (FvHob.FirmwareVolume->BaseAddress, FvHob.FirmwareVolume->Length, NULL, AuthenticationStatus, NULL);
    FvHob.Raw = GET_NEXT_HOB (FvHob);
  }

  return EFI_SUCCESS;
}

/**
  This DXE service routine is used to process a firmware volume. In
  particular, it can be called by BDS to process a single firmware
  volume found in a capsule.

  Caution: The caller need validate the input firmware volume to follow
  PI specification.
  DxeCore will trust the input data and process firmware volume directly.

  @param  FvHeader               pointer to a firmware volume header
  @param  Size                   the size of the buffer pointed to by FvHeader
  @param  FVProtocolHandle       the handle on which a firmware volume protocol
                                 was produced for the firmware volume passed in.

  @retval EFI_OUT_OF_RESOURCES   if an FVB could not be produced due to lack of
                                 system resources
  @retval EFI_VOLUME_CORRUPTED   if the volume was corrupted
  @retval EFI_SUCCESS            a firmware volume protocol was produced for the
                                 firmware volume

**/
EFI_STATUS
EFIAPI
CoreProcessFirmwareVolume (
  IN VOID         *FvHeader,
  IN UINTN        Size,
  OUT EFI_HANDLE  *FVProtocolHandle
  )
{
  VOID        *Ptr;
  EFI_STATUS  Status;

  *FVProtocolHandle = NULL;
  Status            = ProduceFVBProtocolOnBuffer (
                        (EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader,
                        (UINT64)Size,
                        NULL,
                        0,
                        FVProtocolHandle
                        );
  //
  // Since in our implementation we use register-protocol-notify to put a
  // FV protocol on the FVB protocol handle, we can't directly verify that
  // the FV protocol was produced. Therefore here we will check the handle
  // and make sure an FV protocol is on it. This indicates that all went
  // well. Otherwise we have to assume that the volume was corrupted
  // somehow.
  //
  if (!EFI_ERROR (Status)) {
    ASSERT (*FVProtocolHandle != NULL);
    Ptr    = NULL;
    Status = CoreHandleProtocol (*FVProtocolHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Ptr);
    if (EFI_ERROR (Status) || (Ptr == NULL)) {
      return EFI_VOLUME_CORRUPTED;
    }

    return EFI_SUCCESS;
  }

  return Status;
}
