/** @file
  The logic to process capsule.

  Caution: This module requires additional review when modified.
  This driver will have external input - capsule image.
  This external input must be validated carefully to avoid security issue like
  buffer overflow, integer overflow.

  CapsuleDataCoalesce() will do basic validation before coalesce capsule data
  into memory.

(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Uefi.h>
#include <PiPei.h>

#include <Guid/CapsuleVendor.h>

#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PrintLib.h>
#include <Library/BaseLib.h>

#include "CommonHeader.h"

#define MIN_COALESCE_ADDR  (1024 * 1024)

/**
  Given a pointer to the capsule block list, info on the available system
  memory, and the size of a buffer, find a free block of memory where a
  buffer of the given size can be copied to safely.

  @param BlockList   Pointer to head of capsule block descriptors
  @param MemBase     Pointer to the base of memory in which we want to find free space
  @param MemSize     The size of the block of memory pointed to by MemBase
  @param DataSize    How big a free block we want to find

  @return A pointer to a memory block of at least DataSize that lies somewhere
          between MemBase and (MemBase + MemSize). The memory pointed to does not
          contain any of the capsule block descriptors or capsule blocks pointed to
          by the BlockList.

**/
UINT8 *
FindFreeMem (
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *BlockList,
  UINT8                         *MemBase,
  UINTN                         MemSize,
  UINTN                         DataSize
  );

/**
  The capsule block descriptors may be fragmented and spread all over memory.
  To simplify the coalescing of capsule blocks, first coalesce all the
  capsule block descriptors low in memory.

  The descriptors passed in can be fragmented throughout memory. Here
  they are relocated into memory to turn them into a contiguous (null
  terminated) array.

  @param PeiServices    pointer to PEI services table
  @param BlockList      pointer to the capsule block descriptors
  @param NumDescriptors number of capsule data block descriptors, whose Length is non-zero.
  @param MemBase        base of system memory in which we can work
  @param MemSize        size of the system memory pointed to by MemBase

  @retval NULL    could not relocate the descriptors
  @retval Pointer to the base of the successfully-relocated block descriptors.

**/
EFI_CAPSULE_BLOCK_DESCRIPTOR *
RelocateBlockDescriptors (
  IN EFI_PEI_SERVICES              **PeiServices,
  IN EFI_CAPSULE_BLOCK_DESCRIPTOR  *BlockList,
  IN UINTN                         NumDescriptors,
  IN UINT8                         *MemBase,
  IN UINTN                         MemSize
  );

/**
  Check every capsule header.

  @param CapsuleHeader   The pointer to EFI_CAPSULE_HEADER

  @retval FALSE  Capsule is OK
  @retval TRUE   Capsule is corrupted

**/
BOOLEAN
IsCapsuleCorrupted (
  IN EFI_CAPSULE_HEADER  *CapsuleHeader
  );

/**
  Determine if two buffers overlap in memory.

  @param Buff1   pointer to first buffer
  @param Size1   size of Buff1
  @param Buff2   pointer to second buffer
  @param Size2   size of Buff2

  @retval TRUE    Buffers overlap in memory.
  @retval FALSE   Buffer doesn't overlap.

**/
BOOLEAN
IsOverlapped (
  UINT8  *Buff1,
  UINTN  Size1,
  UINT8  *Buff2,
  UINTN  Size2
  );

/**
  Given a pointer to a capsule block descriptor, traverse the list to figure
  out how many legitimate descriptors there are, and how big the capsule it
  refers to is.

  @param Desc            Pointer to the capsule block descriptors
  @param NumDescriptors  Optional pointer to where to return the number of capsule data descriptors, whose Length is non-zero.
  @param CapsuleSize     Optional pointer to where to return the capsule image size
  @param CapsuleNumber   Optional pointer to where to return the number of capsule

  @retval EFI_NOT_FOUND   No descriptors containing data in the list
  @retval EFI_SUCCESS     Return data is valid

**/
EFI_STATUS
GetCapsuleInfo (
  IN EFI_CAPSULE_BLOCK_DESCRIPTOR  *Desc,
  IN OUT UINTN                     *NumDescriptors OPTIONAL,
  IN OUT UINTN                     *CapsuleSize OPTIONAL,
  IN OUT UINTN                     *CapsuleNumber OPTIONAL
  );

/**
  Given a pointer to the capsule block list, info on the available system
  memory, and the size of a buffer, find a free block of memory where a
  buffer of the given size can be copied to safely.

  @param BlockList   Pointer to head of capsule block descriptors
  @param MemBase     Pointer to the base of memory in which we want to find free space
  @param MemSize     The size of the block of memory pointed to by MemBase
  @param DataSize    How big a free block we want to find

  @return A pointer to a memory block of at least DataSize that lies somewhere
          between MemBase and (MemBase + MemSize). The memory pointed to does not
          contain any of the capsule block descriptors or capsule blocks pointed to
          by the BlockList.

**/
UINT8 *
FindFreeMem (
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *BlockList,
  UINT8                         *MemBase,
  UINTN                         MemSize,
  UINTN                         DataSize
  )
{
  UINTN                         Size;
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *CurrDesc;
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *TempDesc;
  UINT8                         *MemEnd;
  BOOLEAN                       Failed;

  //
  // Need at least enough to copy the data to at the end of the buffer, so
  // say the end is less the data size for easy comparisons here.
  //
  MemEnd   = MemBase + MemSize - DataSize;
  CurrDesc = BlockList;
  //
  // Go through all the descriptor blocks and see if any obstruct the range
  //
  while (CurrDesc != NULL) {
    //
    // Get the size of this block list and see if it's in the way
    //
    Failed   = FALSE;
    TempDesc = CurrDesc;
    Size     = sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
    while (TempDesc->Length != 0) {
      Size += sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
      TempDesc++;
    }

    if (IsOverlapped (MemBase, DataSize, (UINT8 *)CurrDesc, Size)) {
      //
      // Set our new base to the end of this block list and start all over
      //
      MemBase  = (UINT8 *)CurrDesc + Size;
      CurrDesc = BlockList;
      if (MemBase > MemEnd) {
        return NULL;
      }

      Failed = TRUE;
    }

    //
    // Now go through all the blocks and make sure none are in the way
    //
    while ((CurrDesc->Length != 0) && (!Failed)) {
      if (IsOverlapped (MemBase, DataSize, (UINT8 *)(UINTN)CurrDesc->Union.DataBlock, (UINTN)CurrDesc->Length)) {
        //
        // Set our new base to the end of this block and start all over
        //
        Failed   = TRUE;
        MemBase  = (UINT8 *)((UINTN)CurrDesc->Union.DataBlock) + CurrDesc->Length;
        CurrDesc = BlockList;
        if (MemBase > MemEnd) {
          return NULL;
        }
      }

      CurrDesc++;
    }

    //
    // Normal continuation -- jump to next block descriptor list
    //
    if (!Failed) {
      CurrDesc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *)(UINTN)CurrDesc->Union.ContinuationPointer;
    }
  }

  return MemBase;
}

/**
  Validate capsule by MemoryResource.

  @param MemoryResource  Pointer to the buffer of memory resource descriptor.
  @param Address         Address to be validated.
  @param Size            Size to be validated.

  @retval TRUE  No memory resource descriptor reported in HOB list before capsule Coalesce,
                or it is valid in one MemoryResource.
          FALSE It is not in any MemoryResource.

**/
BOOLEAN
ValidateCapsuleByMemoryResource (
  IN MEMORY_RESOURCE_DESCRIPTOR  *MemoryResource,
  IN EFI_PHYSICAL_ADDRESS        Address,
  IN UINT64                      Size
  )
{
  UINTN  Index;

  //
  // Sanity Check
  //
  if (Size > MAX_ADDRESS) {
    DEBUG ((DEBUG_ERROR, "ERROR: Size(0x%lx) > MAX_ADDRESS\n", Size));
    return FALSE;
  }

  //
  // Sanity Check
  //
  if (Address > (MAX_ADDRESS - Size)) {
    DEBUG ((DEBUG_ERROR, "ERROR: Address(0x%lx) > (MAX_ADDRESS - Size(0x%lx))\n", Address, Size));
    return FALSE;
  }

  if (MemoryResource == NULL) {
    //
    // No memory resource descriptor reported in HOB list before capsule Coalesce.
    //
    return TRUE;
  }

  for (Index = 0; MemoryResource[Index].ResourceLength != 0; Index++) {
    if ((Address >= MemoryResource[Index].PhysicalStart) &&
        ((Address + Size) <= (MemoryResource[Index].PhysicalStart + MemoryResource[Index].ResourceLength)))
    {
      DEBUG ((
        DEBUG_INFO,
        "Address(0x%lx) Size(0x%lx) in MemoryResource[0x%x] - Start(0x%lx) Length(0x%lx)\n",
        Address,
        Size,
        Index,
        MemoryResource[Index].PhysicalStart,
        MemoryResource[Index].ResourceLength
        ));
      return TRUE;
    }
  }

  DEBUG ((DEBUG_ERROR, "ERROR: Address(0x%lx) Size(0x%lx) not in any MemoryResource\n", Address, Size));
  return FALSE;
}

/**
  Check the integrity of the capsule descriptors.

  @param BlockList       Pointer to the capsule descriptors
  @param MemoryResource  Pointer to the buffer of memory resource descriptor.

  @retval NULL           BlockList is not valid.
  @retval LastBlockDesc  Last one Block in BlockList

**/
EFI_CAPSULE_BLOCK_DESCRIPTOR *
ValidateCapsuleIntegrity (
  IN EFI_CAPSULE_BLOCK_DESCRIPTOR  *BlockList,
  IN MEMORY_RESOURCE_DESCRIPTOR    *MemoryResource
  )
{
  EFI_CAPSULE_HEADER            *CapsuleHeader;
  UINT64                        CapsuleSize;
  UINTN                         CapsuleCount;
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *Ptr;

  DEBUG ((DEBUG_INFO, "ValidateCapsuleIntegrity\n"));

  //
  // Go through the list to look for inconsistencies. Check for:
  //   * misaligned block descriptors.
  //   * The first capsule header guid
  //   * The first capsule header flag
  //   * The first capsule header HeaderSize
  //   * Below check will be done in ValidateCapsuleByMemoryResource()
  //     Length > MAX_ADDRESS
  //     Ptr + sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR) > MAX_ADDRESS
  //     DataBlock + Length > MAX_ADDRESS
  //
  CapsuleSize  = 0;
  CapsuleCount = 0;
  Ptr          = BlockList;

  if (!ValidateCapsuleByMemoryResource (MemoryResource, (EFI_PHYSICAL_ADDRESS)(UINTN)Ptr, sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR))) {
    return NULL;
  }

  DEBUG ((DEBUG_INFO, "Ptr - 0x%p\n", Ptr));
  DEBUG ((DEBUG_INFO, "Ptr->Length - 0x%lx\n", Ptr->Length));
  DEBUG ((DEBUG_INFO, "Ptr->Union - 0x%lx\n", Ptr->Union.ContinuationPointer));
  while ((Ptr->Length != 0) || (Ptr->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS)(UINTN)NULL)) {
    //
    // Make sure the descriptor is aligned at UINT64 in memory
    //
    if ((UINTN)Ptr & (sizeof (UINT64) - 1)) {
      DEBUG ((DEBUG_ERROR, "ERROR: BlockList address failed alignment check\n"));
      return NULL;
    }

    if (Ptr->Length == 0) {
      //
      // Descriptor points to another list of block descriptors somewhere
      // else.
      //
      Ptr = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *)(UINTN)Ptr->Union.ContinuationPointer;
      if (!ValidateCapsuleByMemoryResource (MemoryResource, (EFI_PHYSICAL_ADDRESS)(UINTN)Ptr, sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR))) {
        return NULL;
      }

      DEBUG ((DEBUG_INFO, "Ptr(C) - 0x%p\n", Ptr));
      DEBUG ((DEBUG_INFO, "Ptr->Length - 0x%lx\n", Ptr->Length));
      DEBUG ((DEBUG_INFO, "Ptr->Union - 0x%lx\n", Ptr->Union.ContinuationPointer));
    } else {
      if (!ValidateCapsuleByMemoryResource (MemoryResource, Ptr->Union.DataBlock, Ptr->Length)) {
        return NULL;
      }

      //
      // To enhance the reliability of check-up, the first capsule's header is checked here.
      // More reliabilities check-up will do later.
      //
      if (CapsuleSize == 0) {
        //
        // Move to the first capsule to check its header.
        //
        CapsuleHeader = (EFI_CAPSULE_HEADER *)((UINTN)Ptr->Union.DataBlock);
        //
        // Sanity check
        //
        if (Ptr->Length < sizeof (EFI_CAPSULE_HEADER)) {
          DEBUG ((DEBUG_ERROR, "ERROR: Ptr->Length(0x%lx) < sizeof(EFI_CAPSULE_HEADER)\n", Ptr->Length));
          return NULL;
        }

        //
        // Make sure HeaderSize field is valid
        //
        if (CapsuleHeader->HeaderSize > CapsuleHeader->CapsuleImageSize) {
          DEBUG ((DEBUG_ERROR, "ERROR: CapsuleHeader->HeaderSize(0x%x) > CapsuleHeader->CapsuleImageSize(0x%x)\n", CapsuleHeader->HeaderSize, CapsuleHeader->CapsuleImageSize));
          return NULL;
        }

        if (IsCapsuleCorrupted (CapsuleHeader)) {
          return NULL;
        }

        CapsuleCount++;
        CapsuleSize = CapsuleHeader->CapsuleImageSize;
      }

      if (CapsuleSize >= Ptr->Length) {
        CapsuleSize = CapsuleSize - Ptr->Length;
      } else {
        DEBUG ((DEBUG_ERROR, "ERROR: CapsuleSize(0x%lx) < Ptr->Length(0x%lx)\n", CapsuleSize, Ptr->Length));
        //
        // Sanity check
        //
        return NULL;
      }

      //
      // Move to next BLOCK descriptor
      //
      Ptr++;
      if (!ValidateCapsuleByMemoryResource (MemoryResource, (EFI_PHYSICAL_ADDRESS)(UINTN)Ptr, sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR))) {
        return NULL;
      }

      DEBUG ((DEBUG_INFO, "Ptr(B) - 0x%p\n", Ptr));
      DEBUG ((DEBUG_INFO, "Ptr->Length - 0x%lx\n", Ptr->Length));
      DEBUG ((DEBUG_INFO, "Ptr->Union - 0x%lx\n", Ptr->Union.ContinuationPointer));
    }
  }

  if (CapsuleCount == 0) {
    //
    // No any capsule is found in BlockList
    //
    DEBUG ((DEBUG_ERROR, "ERROR: CapsuleCount(0x%x) == 0\n", CapsuleCount));
    return NULL;
  }

  if (CapsuleSize != 0) {
    //
    // Capsule data is incomplete.
    //
    DEBUG ((DEBUG_ERROR, "ERROR: CapsuleSize(0x%lx) != 0\n", CapsuleSize));
    return NULL;
  }

  return Ptr;
}

/**
  The capsule block descriptors may be fragmented and spread all over memory.
  To simplify the coalescing of capsule blocks, first coalesce all the
  capsule block descriptors low in memory.

  The descriptors passed in can be fragmented throughout memory. Here
  they are relocated into memory to turn them into a contiguous (null
  terminated) array.

  @param PeiServices    pointer to PEI services table
  @param BlockList      pointer to the capsule block descriptors
  @param NumDescriptors number of capsule data block descriptors, whose Length is non-zero.
  @param MemBase        base of system memory in which we can work
  @param MemSize        size of the system memory pointed to by MemBase

  @retval NULL    could not relocate the descriptors
  @retval Pointer to the base of the successfully-relocated block descriptors.

**/
EFI_CAPSULE_BLOCK_DESCRIPTOR  *
RelocateBlockDescriptors (
  IN EFI_PEI_SERVICES              **PeiServices,
  IN EFI_CAPSULE_BLOCK_DESCRIPTOR  *BlockList,
  IN UINTN                         NumDescriptors,
  IN UINT8                         *MemBase,
  IN UINTN                         MemSize
  )
{
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *NewBlockList;
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *CurrBlockDescHead;
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *TempBlockDesc;
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *PrevBlockDescTail;
  UINTN                         BufferSize;
  UINT8                         *RelocBuffer;
  UINTN                         BlockListSize;

  //
  // Get the info on the blocks and descriptors. Since we're going to move
  // the descriptors low in memory, adjust the base/size values accordingly here.
  // NumDescriptors is the number of legit data descriptors, so add one for
  // a terminator. (Already done by caller, no check is needed.)
  //

  BufferSize   = NumDescriptors * sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
  NewBlockList = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)MemBase;
  if (MemSize < BufferSize) {
    return NULL;
  }

  MemSize -= BufferSize;
  MemBase += BufferSize;
  //
  // Go through all the blocks and make sure none are in the way
  //
  TempBlockDesc = BlockList;
  while (TempBlockDesc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS)(UINTN)NULL) {
    if (TempBlockDesc->Length == 0) {
      //
      // Next block of descriptors
      //
      TempBlockDesc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *)(UINTN)TempBlockDesc->Union.ContinuationPointer;
    } else {
      //
      // If the capsule data pointed to by this descriptor is in the way,
      // move it.
      //
      if (IsOverlapped (
            (UINT8 *)NewBlockList,
            BufferSize,
            (UINT8 *)(UINTN)TempBlockDesc->Union.DataBlock,
            (UINTN)TempBlockDesc->Length
            ))
      {
        //
        // Relocate the block
        //
        RelocBuffer = FindFreeMem (BlockList, MemBase, MemSize, (UINTN)TempBlockDesc->Length);
        if (RelocBuffer == NULL) {
          return NULL;
        }

        CopyMem ((VOID *)RelocBuffer, (VOID *)(UINTN)TempBlockDesc->Union.DataBlock, (UINTN)TempBlockDesc->Length);
        DEBUG ((DEBUG_INFO, "Capsule relocate descriptors from/to/size  0x%lX 0x%lX 0x%lX\n", TempBlockDesc->Union.DataBlock, (UINT64)(UINTN)RelocBuffer, TempBlockDesc->Length));
        TempBlockDesc->Union.DataBlock = (EFI_PHYSICAL_ADDRESS)(UINTN)RelocBuffer;
      }

      TempBlockDesc++;
    }
  }

  //
  // Now go through all the block descriptors to make sure that they're not
  // in the memory region we want to copy them to.
  //
  CurrBlockDescHead = BlockList;
  PrevBlockDescTail = NULL;
  while ((CurrBlockDescHead != NULL) && (CurrBlockDescHead->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS)(UINTN)NULL)) {
    //
    // Get the size of this list then see if it overlaps our low region
    //
    TempBlockDesc = CurrBlockDescHead;
    BlockListSize = sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
    while (TempBlockDesc->Length != 0) {
      BlockListSize += sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
      TempBlockDesc++;
    }

    if (IsOverlapped (
          (UINT8 *)NewBlockList,
          BufferSize,
          (UINT8 *)CurrBlockDescHead,
          BlockListSize
          ))
    {
      //
      // Overlaps, so move it out of the way
      //
      RelocBuffer = FindFreeMem (BlockList, MemBase, MemSize, BlockListSize);
      if (RelocBuffer == NULL) {
        return NULL;
      }

      CopyMem ((VOID *)RelocBuffer, (VOID *)CurrBlockDescHead, BlockListSize);
      DEBUG ((DEBUG_INFO, "Capsule reloc descriptor block #2\n"));
      //
      // Point the previous block's next point to this copied version. If
      // the tail pointer is null, then this is the first descriptor block.
      //
      if (PrevBlockDescTail == NULL) {
        BlockList = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *)RelocBuffer;
      } else {
        PrevBlockDescTail->Union.DataBlock = (EFI_PHYSICAL_ADDRESS)(UINTN)RelocBuffer;
      }
    }

    //
    // Save our new tail and jump to the next block list
    //
    PrevBlockDescTail = TempBlockDesc;
    CurrBlockDescHead = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *)(UINTN)TempBlockDesc->Union.ContinuationPointer;
  }

  //
  // Cleared out low memory. Now copy the descriptors down there.
  //
  TempBlockDesc     = BlockList;
  CurrBlockDescHead = NewBlockList;
  while ((TempBlockDesc != NULL) && (TempBlockDesc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS)(UINTN)NULL)) {
    if (TempBlockDesc->Length != 0) {
      CurrBlockDescHead->Union.DataBlock = TempBlockDesc->Union.DataBlock;
      CurrBlockDescHead->Length          = TempBlockDesc->Length;
      CurrBlockDescHead++;
      TempBlockDesc++;
    } else {
      TempBlockDesc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *)(UINTN)TempBlockDesc->Union.ContinuationPointer;
    }
  }

  //
  // Null terminate
  //
  CurrBlockDescHead->Union.ContinuationPointer = (EFI_PHYSICAL_ADDRESS)(UINTN)NULL;
  CurrBlockDescHead->Length                    = 0;
  return NewBlockList;
}

/**
  Determine if two buffers overlap in memory.

  @param Buff1   pointer to first buffer
  @param Size1   size of Buff1
  @param Buff2   pointer to second buffer
  @param Size2   size of Buff2

  @retval TRUE    Buffers overlap in memory.
  @retval FALSE   Buffer doesn't overlap.

**/
BOOLEAN
IsOverlapped (
  UINT8  *Buff1,
  UINTN  Size1,
  UINT8  *Buff2,
  UINTN  Size2
  )
{
  //
  // If buff1's end is less than the start of buff2, then it's ok.
  // Also, if buff1's start is beyond buff2's end, then it's ok.
  //
  if (((Buff1 + Size1) <= Buff2) || (Buff1 >= (Buff2 + Size2))) {
    return FALSE;
  }

  return TRUE;
}

/**
  Given a pointer to a capsule block descriptor, traverse the list to figure
  out how many legitimate descriptors there are, and how big the capsule it
  refers to is.

  @param Desc            Pointer to the capsule block descriptors
  @param NumDescriptors  Optional pointer to where to return the number of capsule data descriptors, whose Length is non-zero.
  @param CapsuleSize     Optional pointer to where to return the capsule image size
  @param CapsuleNumber   Optional pointer to where to return the number of capsule

  @retval EFI_NOT_FOUND   No descriptors containing data in the list
  @retval EFI_SUCCESS     Return data is valid

**/
EFI_STATUS
GetCapsuleInfo (
  IN EFI_CAPSULE_BLOCK_DESCRIPTOR  *Desc,
  IN OUT UINTN                     *NumDescriptors OPTIONAL,
  IN OUT UINTN                     *CapsuleSize OPTIONAL,
  IN OUT UINTN                     *CapsuleNumber OPTIONAL
  )
{
  UINTN               Count;
  UINTN               Size;
  UINTN               Number;
  UINTN               ThisCapsuleImageSize;
  EFI_CAPSULE_HEADER  *CapsuleHeader;

  DEBUG ((DEBUG_INFO, "GetCapsuleInfo enter\n"));

  ASSERT (Desc != NULL);

  Count                = 0;
  Size                 = 0;
  Number               = 0;
  ThisCapsuleImageSize = 0;

  while (Desc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS)(UINTN)NULL) {
    if (Desc->Length == 0) {
      //
      // Descriptor points to another list of block descriptors somewhere
      //
      Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *)(UINTN)Desc->Union.ContinuationPointer;
    } else {
      //
      // Sanity Check
      // It is needed, because ValidateCapsuleIntegrity() only validate one individual capsule Size.
      // While here we need check all capsules size.
      //
      if (Desc->Length >= (MAX_ADDRESS - Size)) {
        DEBUG ((DEBUG_ERROR, "ERROR: Desc->Length(0x%lx) >= (MAX_ADDRESS - Size(0x%x))\n", Desc->Length, Size));
        return EFI_OUT_OF_RESOURCES;
      }

      Size += (UINTN)Desc->Length;
      Count++;

      //
      // See if this is first capsule's header
      //
      if (ThisCapsuleImageSize == 0) {
        CapsuleHeader = (EFI_CAPSULE_HEADER *)((UINTN)Desc->Union.DataBlock);
        //
        // This has been checked in ValidateCapsuleIntegrity()
        //
        Number++;
        ThisCapsuleImageSize = CapsuleHeader->CapsuleImageSize;
      }

      //
      // This has been checked in ValidateCapsuleIntegrity()
      //
      ASSERT (ThisCapsuleImageSize >= Desc->Length);
      ThisCapsuleImageSize = (UINTN)(ThisCapsuleImageSize - Desc->Length);

      //
      // Move to next
      //
      Desc++;
    }
  }

  //
  // If no descriptors, then fail
  //
  if (Count == 0) {
    DEBUG ((DEBUG_ERROR, "ERROR: Count == 0\n"));
    return EFI_NOT_FOUND;
  }

  //
  // checked in ValidateCapsuleIntegrity()
  //
  ASSERT (ThisCapsuleImageSize == 0);

  if (NumDescriptors != NULL) {
    *NumDescriptors = Count;
  }

  if (CapsuleSize != NULL) {
    *CapsuleSize = Size;
  }

  if (CapsuleNumber != NULL) {
    *CapsuleNumber = Number;
  }

  return EFI_SUCCESS;
}

/**
  Check every capsule header.

  @param CapsuleHeader   The pointer to EFI_CAPSULE_HEADER

  @retval FALSE  Capsule is OK
  @retval TRUE   Capsule is corrupted

**/
BOOLEAN
IsCapsuleCorrupted (
  IN EFI_CAPSULE_HEADER  *CapsuleHeader
  )
{
  //
  // A capsule to be updated across a system reset should contain CAPSULE_FLAGS_PERSIST_ACROSS_RESET.
  //
  if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) == 0) {
    return TRUE;
  }

  //
  // Make sure the flags combination is supported by the platform.
  //
  if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {
    return TRUE;
  }

  if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) {
    return TRUE;
  }

  return FALSE;
}

/**
  Try to verify the integrity of a capsule test pattern before the
  capsule gets coalesced. This can be useful in narrowing down
  where capsule data corruption occurs.

  The test pattern mode fills in memory with a counting UINT32 value.
  If the capsule is not divided up in a multiple of 4-byte blocks, then
  things get messy doing the check. Therefore there are some cases
  here where we just give up and skip the pre-coalesce check.

  @param PeiServices  PEI services table
  @param Desc         Pointer to capsule descriptors
**/
VOID
CapsuleTestPatternPreCoalesce (
  IN EFI_PEI_SERVICES              **PeiServices,
  IN EFI_CAPSULE_BLOCK_DESCRIPTOR  *Desc
  )
{
  UINT32  *TestPtr;
  UINT32  TestCounter;
  UINT32  TestSize;

  DEBUG ((DEBUG_INFO, "CapsuleTestPatternPreCoalesce\n"));

  //
  // Find first data descriptor
  //
  while ((Desc->Length == 0) && (Desc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS)(UINTN)NULL)) {
    Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *)(UINTN)Desc->Union.ContinuationPointer;
  }

  if (Desc->Union.ContinuationPointer == 0) {
    return;
  }

  //
  // First one better be long enough to at least hold the test signature
  //
  if (Desc->Length < sizeof (UINT32)) {
    DEBUG ((DEBUG_INFO, "Capsule test pattern pre-coalesce punted #1\n"));
    return;
  }

  TestPtr = (UINT32 *)(UINTN)Desc->Union.DataBlock;
  //
  // 0x54534554 "TEST"
  //
  if (*TestPtr != 0x54534554) {
    return;
  }

  TestCounter = 0;
  TestSize    = (UINT32)Desc->Length - 2 * sizeof (UINT32);
  //
  // Skip over the signature and the size fields in the pattern data header
  //
  TestPtr += 2;
  while (1) {
    if ((TestSize & 0x03) != 0) {
      DEBUG ((DEBUG_INFO, "Capsule test pattern pre-coalesce punted #2\n"));
      return;
    }

    while (TestSize > 0) {
      if (*TestPtr != TestCounter) {
        DEBUG ((DEBUG_INFO, "Capsule test pattern pre-coalesce failed data corruption check\n"));
        return;
      }

      TestSize -= sizeof (UINT32);
      TestCounter++;
      TestPtr++;
    }

    Desc++;
    while ((Desc->Length == 0) && (Desc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS)(UINTN)NULL)) {
      Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *)(UINTN)Desc->Union.ContinuationPointer;
    }

    if (Desc->Union.ContinuationPointer == (EFI_PHYSICAL_ADDRESS)(UINTN)NULL) {
      return;
    }

    TestSize = (UINT32)Desc->Length;
    TestPtr  = (UINT32 *)(UINTN)Desc->Union.DataBlock;
  }
}

/**
  Checks for the presence of capsule descriptors.
  Get capsule descriptors from variable CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...

  @param BlockListBuffer            Pointer to the buffer of capsule descriptors variables
  @param MemoryResource             Pointer to the buffer of memory resource descriptor.
  @param BlockDescriptorList        Pointer to the capsule descriptors list

  @retval EFI_SUCCESS               a valid capsule is present
  @retval EFI_NOT_FOUND             if a valid capsule is not present
**/
EFI_STATUS
BuildCapsuleDescriptors (
  IN  EFI_PHYSICAL_ADDRESS          *BlockListBuffer,
  IN  MEMORY_RESOURCE_DESCRIPTOR    *MemoryResource,
  OUT EFI_CAPSULE_BLOCK_DESCRIPTOR  **BlockDescriptorList
  )
{
  UINTN                         Index;
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *LastBlock;
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *TempBlock;
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *HeadBlock;

  DEBUG ((DEBUG_INFO, "BuildCapsuleDescriptors enter\n"));

  LastBlock = NULL;
  HeadBlock = NULL;
  TempBlock = NULL;
  Index     = 0;

  while (BlockListBuffer[Index] != 0) {
    //
    // Test integrity of descriptors.
    //
    if (BlockListBuffer[Index] < MAX_ADDRESS) {
      TempBlock = ValidateCapsuleIntegrity ((EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)BlockListBuffer[Index], MemoryResource);
      if (TempBlock != NULL) {
        if (LastBlock == NULL) {
          LastBlock = TempBlock;

          //
          // Return the base of the block descriptors
          //
          HeadBlock = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)BlockListBuffer[Index];
        } else {
          //
          // Combine the different BlockList into single BlockList.
          //
          LastBlock->Union.DataBlock = (EFI_PHYSICAL_ADDRESS)(UINTN)BlockListBuffer[Index];
          LastBlock->Length          = 0;
          LastBlock                  = TempBlock;
        }
      }
    } else {
      DEBUG ((DEBUG_ERROR, "ERROR: BlockListBuffer[Index](0x%lx) < MAX_ADDRESS\n", BlockListBuffer[Index]));
    }

    Index++;
  }

  if (HeadBlock != NULL) {
    *BlockDescriptorList = HeadBlock;
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

/**
  The function to coalesce a fragmented capsule in memory.

  Memory Map for coalesced capsule:
  MemBase +   ---->+---------------------------+<-----------+
  MemSize          | ------------------------- |            |
                   | |  Capsule [Num-1]      | |            |
                   | ------------------------- |            |
                   | |  ................     | |            |
                   | ------------------------- |            |
                   | |  Capsule [1]          | |            |
                   | ------------------------- |            |
                   | |  Capsule [0]          | |            |
                   | ------------------------- |            |
                   |    Capsule Image          |            |
CapsuleImageBase-->+---------------------------+
                   | ------------------------- |            |
                   | |  CapsuleOffset[Num-1] | |            |
                   | ------------------------- |            |
                   | |  ................     | |        CapsuleSize
                   | ------------------------- |            |
                   | |  CapsuleOffset[1]     | |            |
                   | ------------------------- |            |
                   | |  CapsuleOffset[0]     | |            |
                   |---------------------------|            |
                   | |  CapsuleNumber        | |            |
                   | ------------------------- |            |
                   | |  CapsuleAllImageSize  | |            |
                   | ------------------------- |            |
                   |    PrivateData            |            |
     DestPtr  ---->+---------------------------+<-----------+
                   |                           |            |
                   |     FreeMem               |        FreeMemSize
                   |                           |            |
   FreeMemBase --->+---------------------------+<-----------+
                   |    Terminator             |
                   +---------------------------+
                   |    BlockDescriptor n      |
                   +---------------------------+
                   |    .................      |
                   +---------------------------+
                   |    BlockDescriptor 1      |
                   +---------------------------+
                   |    BlockDescriptor 0      |
                   +---------------------------+
                   |    PrivateDataDesc 0      |
      MemBase ---->+---------------------------+<----- BlockList

  Caution: This function may receive untrusted input.
  The capsule data is external input, so this routine will do basic validation before
  coalesce capsule data into memory.

  @param PeiServices        General purpose services available to every PEIM.
  @param BlockListBuffer    Pointer to the buffer of Capsule Descriptor Variables.
  @param MemoryResource     Pointer to the buffer of memory resource descriptor.
  @param MemoryBase         Pointer to the base of a block of memory that we can walk
                            all over while trying to coalesce our buffers.
                            On output, this variable will hold the base address of
                            a coalesced capsule.
  @param MemorySize         Size of the memory region pointed to by MemoryBase.
                            On output, this variable will contain the size of the
                            coalesced capsule.

  @retval EFI_NOT_FOUND     If we could not find the capsule descriptors.

  @retval EFI_BUFFER_TOO_SMALL
                            If we could not coalesce the capsule in the memory
                            region provided to us.

  @retval EFI_SUCCESS       Processed the capsule successfully.
**/
EFI_STATUS
EFIAPI
CapsuleDataCoalesce (
  IN EFI_PEI_SERVICES            **PeiServices,
  IN EFI_PHYSICAL_ADDRESS        *BlockListBuffer,
  IN MEMORY_RESOURCE_DESCRIPTOR  *MemoryResource,
  IN OUT VOID                    **MemoryBase,
  IN OUT UINTN                   *MemorySize
  )
{
  VOID                           *NewCapsuleBase;
  VOID                           *CapsuleImageBase;
  UINTN                          CapsuleIndex;
  UINT8                          *FreeMemBase;
  UINT8                          *DestPtr;
  UINTN                          DestLength;
  UINT8                          *RelocPtr;
  UINTN                          CapsuleTimes;
  UINT64                         SizeLeft;
  UINT64                         CapsuleImageSize;
  UINTN                          CapsuleSize;
  UINTN                          CapsuleNumber;
  UINTN                          DescriptorsSize;
  UINTN                          FreeMemSize;
  UINTN                          NumDescriptors;
  BOOLEAN                        CapsuleBeginFlag;
  EFI_STATUS                     Status;
  EFI_CAPSULE_HEADER             *CapsuleHeader;
  EFI_CAPSULE_PEIM_PRIVATE_DATA  PrivateData;
  EFI_CAPSULE_PEIM_PRIVATE_DATA  *PrivateDataPtr;
  EFI_CAPSULE_BLOCK_DESCRIPTOR   *BlockList;
  EFI_CAPSULE_BLOCK_DESCRIPTOR   *CurrentBlockDesc;
  EFI_CAPSULE_BLOCK_DESCRIPTOR   *TempBlockDesc;
  EFI_CAPSULE_BLOCK_DESCRIPTOR   PrivateDataDesc[2];

  DEBUG ((DEBUG_INFO, "CapsuleDataCoalesce enter\n"));

  CapsuleIndex     = 0;
  SizeLeft         = 0;
  CapsuleTimes     = 0;
  CapsuleImageSize = 0;
  PrivateDataPtr   = NULL;
  CapsuleHeader    = NULL;
  CapsuleBeginFlag = TRUE;
  CapsuleSize      = 0;
  NumDescriptors   = 0;

  //
  // Build capsule descriptors list
  //
  Status = BuildCapsuleDescriptors (BlockListBuffer, MemoryResource, &BlockList);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  DEBUG_CODE (
    CapsuleTestPatternPreCoalesce (PeiServices, BlockList);
    );

  //
  // Get the size of our descriptors and the capsule size. GetCapsuleInfo()
  // returns the number of descriptors that actually point to data, so add
  // one for a terminator. Do that below.
  //
  Status = GetCapsuleInfo (BlockList, &NumDescriptors, &CapsuleSize, &CapsuleNumber);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  DEBUG ((DEBUG_INFO, "CapsuleSize - 0x%x\n", CapsuleSize));
  DEBUG ((DEBUG_INFO, "CapsuleNumber - 0x%x\n", CapsuleNumber));
  DEBUG ((DEBUG_INFO, "NumDescriptors - 0x%x\n", NumDescriptors));
  if ((CapsuleSize == 0) || (NumDescriptors == 0) || (CapsuleNumber == 0)) {
    return EFI_NOT_FOUND;
  }

  if (CapsuleNumber - 1 >= (MAX_ADDRESS - (sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA)  + sizeof (UINT64))) / sizeof (UINT64)) {
    DEBUG ((DEBUG_ERROR, "ERROR: CapsuleNumber - 0x%x\n", CapsuleNumber));
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Initialize our local copy of private data. When we're done, we'll create a
  // descriptor for it as well so that it can be put into free memory without
  // trashing anything.
  //
  PrivateData.Signature           = EFI_CAPSULE_PEIM_PRIVATE_DATA_SIGNATURE;
  PrivateData.CapsuleAllImageSize = (UINT64)CapsuleSize;
  PrivateData.CapsuleNumber       = (UINT64)CapsuleNumber;
  PrivateData.CapsuleOffset[0]    = 0;
  //
  // NOTE: Only data in sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) is valid, CapsuleOffset field is uninitialized at this moment.
  // The code sets partial length here for Descriptor.Length check, but later it will use full length to reserve those PrivateData region.
  //
  PrivateDataDesc[0].Union.DataBlock = (EFI_PHYSICAL_ADDRESS)(UINTN)&PrivateData;
  PrivateDataDesc[0].Length          = sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA);
  PrivateDataDesc[1].Union.DataBlock = (EFI_PHYSICAL_ADDRESS)(UINTN)BlockList;
  PrivateDataDesc[1].Length          = 0;
  //
  // Add PrivateDataDesc[0] in beginning, as it is new descriptor. PrivateDataDesc[1] is NOT needed.
  // In addition, one NULL terminator is added in the end. See RelocateBlockDescriptors().
  //
  NumDescriptors += 2;
  //
  // Sanity check
  //
  if (CapsuleSize >= (MAX_ADDRESS - (sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof (UINT64) + sizeof (UINT64)))) {
    DEBUG ((DEBUG_ERROR, "ERROR: CapsuleSize - 0x%x\n", CapsuleSize));
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Need add sizeof(UINT64) for PrivateData alignment
  //
  CapsuleSize += sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof (UINT64) + sizeof (UINT64);
  BlockList    = PrivateDataDesc;
  //
  // Sanity check
  //
  if (NumDescriptors >= (MAX_ADDRESS / sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR))) {
    DEBUG ((DEBUG_ERROR, "ERROR: NumDescriptors - 0x%x\n", NumDescriptors));
    return EFI_BUFFER_TOO_SMALL;
  }

  DescriptorsSize = NumDescriptors * sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
  //
  // Sanity check
  //
  if (DescriptorsSize >= (MAX_ADDRESS - CapsuleSize)) {
    DEBUG ((DEBUG_ERROR, "ERROR: DescriptorsSize - 0x%lx, CapsuleSize - 0x%lx\n", (UINT64)DescriptorsSize, (UINT64)CapsuleSize));
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Don't go below some min address. If the base is below it,
  // then move it up and adjust the size accordingly.
  //
  DEBUG ((DEBUG_INFO, "Capsule Memory range from 0x%8X to 0x%8X\n", (UINTN)*MemoryBase, (UINTN)*MemoryBase + *MemorySize));
  if ((UINTN)*MemoryBase < (UINTN)MIN_COALESCE_ADDR) {
    if (((UINTN)*MemoryBase + *MemorySize) < (UINTN)MIN_COALESCE_ADDR) {
      DEBUG ((DEBUG_ERROR, "ERROR: *MemoryBase + *MemorySize - 0x%x\n", (UINTN)*MemoryBase + *MemorySize));
      return EFI_BUFFER_TOO_SMALL;
    } else {
      *MemorySize = *MemorySize - ((UINTN)MIN_COALESCE_ADDR - (UINTN)*MemoryBase);
      *MemoryBase = (VOID *)(UINTN)MIN_COALESCE_ADDR;
    }
  }

  if (*MemorySize <= (CapsuleSize + DescriptorsSize)) {
    DEBUG ((DEBUG_ERROR, "ERROR: CapsuleSize + DescriptorsSize - 0x%x\n", CapsuleSize + DescriptorsSize));
    return EFI_BUFFER_TOO_SMALL;
  }

  FreeMemBase = *MemoryBase;
  FreeMemSize = *MemorySize;
  DEBUG ((DEBUG_INFO, "Capsule Free Memory from 0x%8X to 0x%8X\n", (UINTN)FreeMemBase, (UINTN)FreeMemBase + FreeMemSize));

  //
  // Relocate all the block descriptors to low memory to make further
  // processing easier.
  //
  BlockList = RelocateBlockDescriptors (PeiServices, BlockList, NumDescriptors, FreeMemBase, FreeMemSize);
  if (BlockList == NULL) {
    //
    // Not enough room to relocate the descriptors
    //
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Take the top of memory for the capsule. UINT64 align up.
  //
  DestPtr          = FreeMemBase + FreeMemSize - CapsuleSize;
  DestPtr          = (UINT8 *)(((UINTN)DestPtr + sizeof (UINT64) - 1) & ~(sizeof (UINT64) - 1));
  FreeMemBase      = (UINT8 *)BlockList + DescriptorsSize;
  FreeMemSize      = (UINTN)DestPtr - (UINTN)FreeMemBase;
  NewCapsuleBase   = (VOID *)DestPtr;
  CapsuleImageBase = (UINT8 *)NewCapsuleBase + sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof (UINT64);

  PrivateDataPtr = (EFI_CAPSULE_PEIM_PRIVATE_DATA *)NewCapsuleBase;

  //
  // Move all the blocks to the top (high) of memory.
  // Relocate all the obstructing blocks. Note that the block descriptors
  // were coalesced when they were relocated, so we can just ++ the pointer.
  //
  CurrentBlockDesc = BlockList;
  while ((CurrentBlockDesc->Length != 0) || (CurrentBlockDesc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS)(UINTN)NULL)) {
    if (CapsuleTimes == 0) {
      //
      // The first entry is the block descriptor for EFI_CAPSULE_PEIM_PRIVATE_DATA.
      // CapsuleOffset field is uninitialized at this time. No need copy it, but need to reserve for future use.
      //
      ASSERT (CurrentBlockDesc->Union.DataBlock == (UINT64)(UINTN)&PrivateData);
      DestLength = sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof (UINT64);
    } else {
      DestLength = (UINTN)CurrentBlockDesc->Length;
    }

    //
    // See if any of the remaining capsule blocks are in the way
    //
    TempBlockDesc = CurrentBlockDesc;
    while (TempBlockDesc->Length != 0) {
      //
      // Is this block in the way of where we want to copy the current descriptor to?
      //
      if (IsOverlapped (
            (UINT8 *)DestPtr,
            (UINTN)DestLength,
            (UINT8 *)(UINTN)TempBlockDesc->Union.DataBlock,
            (UINTN)TempBlockDesc->Length
            ))
      {
        //
        // Relocate the block
        //
        RelocPtr = FindFreeMem (BlockList, FreeMemBase, FreeMemSize, (UINTN)TempBlockDesc->Length);
        if (RelocPtr == NULL) {
          return EFI_BUFFER_TOO_SMALL;
        }

        CopyMem ((VOID *)RelocPtr, (VOID *)(UINTN)TempBlockDesc->Union.DataBlock, (UINTN)TempBlockDesc->Length);
        DEBUG ((
          DEBUG_INFO,
          "Capsule reloc data block from 0x%8X to 0x%8X with size 0x%8X\n",
          (UINTN)TempBlockDesc->Union.DataBlock,
          (UINTN)RelocPtr,
          (UINTN)TempBlockDesc->Length
          ));

        TempBlockDesc->Union.DataBlock = (EFI_PHYSICAL_ADDRESS)(UINTN)RelocPtr;
      }

      //
      // Next descriptor
      //
      TempBlockDesc++;
    }

    //
    // Ok, we made it through. Copy the block.
    // we just support greping one capsule from the lists of block descs list.
    //
    CapsuleTimes++;
    //
    // Skip the first block descriptor that filled with EFI_CAPSULE_PEIM_PRIVATE_DATA
    //
    if (CapsuleTimes > 1) {
      //
      // For every capsule entry point, check its header to determine whether to relocate it.
      // If it is invalid, skip it and move on to the next capsule. If it is valid, relocate it.
      //
      if (CapsuleBeginFlag) {
        CapsuleBeginFlag = FALSE;
        CapsuleHeader    = (EFI_CAPSULE_HEADER *)(UINTN)CurrentBlockDesc->Union.DataBlock;
        SizeLeft         = CapsuleHeader->CapsuleImageSize;

        //
        // No more check here is needed, because IsCapsuleCorrupted() already in ValidateCapsuleIntegrity()
        //
        ASSERT (CapsuleIndex < CapsuleNumber);

        //
        // Relocate this capsule
        //
        CapsuleImageSize += SizeLeft;
        //
        // Cache the begin offset of this capsule
        //
        ASSERT (PrivateDataPtr->Signature == EFI_CAPSULE_PEIM_PRIVATE_DATA_SIGNATURE);
        ASSERT ((UINTN)DestPtr >= (UINTN)CapsuleImageBase);
        PrivateDataPtr->CapsuleOffset[CapsuleIndex++] = (UINTN)DestPtr - (UINTN)CapsuleImageBase;
      }

      //
      // Below ASSERT is checked in ValidateCapsuleIntegrity()
      //
      ASSERT (CurrentBlockDesc->Length <= SizeLeft);

      CopyMem ((VOID *)DestPtr, (VOID *)(UINTN)(CurrentBlockDesc->Union.DataBlock), (UINTN)CurrentBlockDesc->Length);
      DEBUG ((
        DEBUG_INFO,
        "Capsule coalesce block no.0x%lX from 0x%lX to 0x%lX with size 0x%lX\n",
        (UINT64)CapsuleTimes,
        CurrentBlockDesc->Union.DataBlock,
        (UINT64)(UINTN)DestPtr,
        CurrentBlockDesc->Length
        ));
      DestPtr  += CurrentBlockDesc->Length;
      SizeLeft -= CurrentBlockDesc->Length;

      if (SizeLeft == 0) {
        //
        // Here is the end of the current capsule image.
        //
        CapsuleBeginFlag = TRUE;
      }
    } else {
      //
      // The first entry is the block descriptor for EFI_CAPSULE_PEIM_PRIVATE_DATA.
      // CapsuleOffset field is uninitialized at this time. No need copy it, but need to reserve for future use.
      //
      ASSERT (CurrentBlockDesc->Length == sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA));
      ASSERT ((UINTN)DestPtr == (UINTN)NewCapsuleBase);
      CopyMem ((VOID *)DestPtr, (VOID *)(UINTN)CurrentBlockDesc->Union.DataBlock, (UINTN)CurrentBlockDesc->Length);
      DestPtr += sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof (UINT64);
    }

    //
    // Walk through the block descriptor list.
    //
    CurrentBlockDesc++;
  }

  //
  // We return the base of memory we want reserved, and the size.
  // The memory peim should handle it appropriately from there.
  //
  *MemorySize = (UINTN)CapsuleSize;
  *MemoryBase = (VOID *)NewCapsuleBase;

  ASSERT (PrivateDataPtr->Signature == EFI_CAPSULE_PEIM_PRIVATE_DATA_SIGNATURE);
  ASSERT (PrivateDataPtr->CapsuleAllImageSize == CapsuleImageSize);
  ASSERT (PrivateDataPtr->CapsuleNumber == CapsuleIndex);

  return EFI_SUCCESS;
}
