/** @file
  TdxHelper Functions which are used in SEC phase

  Copyright (c) 2022 - 2023, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <PiPei.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/BaseCryptLib.h>
#include <Library/BaseMemoryLib.h>
#include <IndustryStandard/Tdx.h>
#include <IndustryStandard/IntelTdx.h>
#include <IndustryStandard/Tpm20.h>
#include <Library/TdxLib.h>
#include <Library/TdxMailboxLib.h>
#include <Library/SynchronizationLib.h>
#include <Pi/PiHob.h>
#include <WorkArea.h>
#include <ConfidentialComputingGuestAttr.h>
#include <Library/TdxHelperLib.h>
#include <Library/TdxMeasurementLib.h>

#define ALIGNED_2MB_MASK  0x1fffff
#define MEGABYTE_SHIFT    20

#define ACCEPT_CHUNK_SIZE  SIZE_32MB
#define AP_STACK_SIZE      SIZE_16KB
#define APS_STACK_SIZE(CpusNum)  (ALIGN_VALUE(CpusNum*AP_STACK_SIZE, SIZE_2MB))

/**
  Build the GuidHob for tdx measurements which were done in SEC phase.
  The measurement values are stored in WorkArea.

  @retval EFI_SUCCESS  The GuidHob is built successfully
  @retval Others       Other errors as indicated
**/
EFI_STATUS
InternalBuildGuidHobForTdxMeasurement (
  VOID
  );

/**
  This function will be called to accept pages. Only BSP accepts pages.

  TDCALL(ACCEPT_PAGE) supports the accept page size of 4k and 2M. To
  simplify the implementation, the Memory to be accpeted is splitted
  into 3 parts:
  -----------------  <-- StartAddress1 (not 2M aligned)
  |  part 1       |      Length1 < 2M
  |---------------|  <-- StartAddress2 (2M aligned)
  |               |      Length2 = Integer multiples of 2M
  |  part 2       |
  |               |
  |---------------|  <-- StartAddress3
  |  part 3       |      Length3 < 2M
  |---------------|

  @param[in] PhysicalAddress   Start physical adress
  @param[in] PhysicalEnd       End physical address

  @retval    EFI_SUCCESS       Accept memory successfully
  @retval    Others            Other errors as indicated
**/
STATIC
EFI_STATUS
EFIAPI
BspAcceptMemoryResourceRange (
  IN EFI_PHYSICAL_ADDRESS  PhysicalAddress,
  IN EFI_PHYSICAL_ADDRESS  PhysicalEnd
  )
{
  EFI_STATUS  Status;
  UINT32      AcceptPageSize;
  UINT64      StartAddress1;
  UINT64      StartAddress2;
  UINT64      StartAddress3;
  UINT64      TotalLength;
  UINT64      Length1;
  UINT64      Length2;
  UINT64      Length3;
  UINT64      Pages;

  AcceptPageSize = FixedPcdGet32 (PcdTdxAcceptPageSize);
  TotalLength    = PhysicalEnd - PhysicalAddress;
  StartAddress1  = 0;
  StartAddress2  = 0;
  StartAddress3  = 0;
  Length1        = 0;
  Length2        = 0;
  Length3        = 0;

  if (TotalLength == 0) {
    return EFI_SUCCESS;
  }

  if (ALIGN_VALUE (PhysicalAddress, SIZE_2MB) != PhysicalAddress) {
    StartAddress1 = PhysicalAddress;
    Length1       = ALIGN_VALUE (PhysicalAddress, SIZE_2MB) - PhysicalAddress;
    if (Length1 >= TotalLength) {
      Length1 = TotalLength;
    }

    PhysicalAddress += Length1;
    TotalLength     -= Length1;
  }

  if (TotalLength > SIZE_2MB) {
    StartAddress2    = PhysicalAddress;
    Length2          = TotalLength & ~(UINT64)ALIGNED_2MB_MASK;
    PhysicalAddress += Length2;
    TotalLength     -= Length2;
  }

  if (TotalLength) {
    StartAddress3 = PhysicalAddress;
    Length3       = TotalLength;
  }

  Status = EFI_SUCCESS;
  if (Length1 > 0) {
    Pages  = Length1 / SIZE_4KB;
    Status = TdAcceptPages (StartAddress1, Pages, SIZE_4KB);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  if (Length2 > 0) {
    Pages  = Length2 / AcceptPageSize;
    Status = TdAcceptPages (StartAddress2, Pages, AcceptPageSize);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  if (Length3 > 0) {
    Pages  = Length3 / SIZE_4KB;
    Status = TdAcceptPages (StartAddress3, Pages, SIZE_4KB);
    ASSERT (!EFI_ERROR (Status));
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return Status;
}

/**
 * This function is called by BSP and APs to accept memory.
 * Note:
 * The input PhysicalStart/PhysicalEnd indicates the whole memory region
 * to be accepted. BSP or AP only accepts one piece in the whole memory region.
 *
 * @param CpuIndex        vCPU index
 * @param CpusNum         Total vCPU number of a Tdx guest
 * @param PhysicalStart   Start address of a memory region which is to be accepted
 * @param PhysicalEnd     End address of a memory region which is to be accepted
 *
 * @retval EFI_SUCCESS    Successfully accept the memory
 * @retval Other          Other errors as indicated
 */
STATIC
EFI_STATUS
EFIAPI
BspApAcceptMemoryResourceRange (
  UINT32                CpuIndex,
  UINT32                CpusNum,
  EFI_PHYSICAL_ADDRESS  PhysicalStart,
  EFI_PHYSICAL_ADDRESS  PhysicalEnd
  )
{
  UINT64                Status;
  UINT64                Pages;
  UINT64                Stride;
  UINT64                AcceptPageSize;
  EFI_PHYSICAL_ADDRESS  PhysicalAddress;
  UINT64                TotalSize;
  UINT64                ProcessedSize;
  UINT64                RemainderSize;
  UINT64                RemainderPages;
  UINT64                RemainderStart;

  AcceptPageSize = (UINT64)(UINTN)FixedPcdGet32 (PcdTdxAcceptPageSize);

  Status          = EFI_SUCCESS;
  Stride          = (UINTN)CpusNum * ACCEPT_CHUNK_SIZE;
  PhysicalAddress = PhysicalStart + ACCEPT_CHUNK_SIZE * (UINTN)CpuIndex;
  TotalSize       = PhysicalEnd - PhysicalStart;

  while (!EFI_ERROR (Status) && PhysicalAddress < PhysicalEnd) {
    Pages  = MIN (ACCEPT_CHUNK_SIZE, PhysicalEnd - PhysicalAddress) / AcceptPageSize;
    Status = TdAcceptPages (PhysicalAddress, Pages, (UINT32)(UINTN)AcceptPageSize);
    ASSERT (!EFI_ERROR (Status));
    PhysicalAddress += Stride;
  }

  if (CpuIndex == 0) {
    ProcessedSize = (TotalSize / AcceptPageSize) * AcceptPageSize;

    RemainderStart = PhysicalStart + ProcessedSize;
    RemainderSize  = TotalSize % AcceptPageSize;
    if (RemainderSize > 0) {
      RemainderPages = RemainderSize / SIZE_4KB;
      if (RemainderPages > 0) {
        Status = TdAcceptPages (
                   RemainderStart,
                   RemainderPages,
                   SIZE_4KB
                   );
        ASSERT (!EFI_ERROR (Status));
        if (EFI_ERROR (Status)) {
          return Status;
        }
      }
    }
  }

  return EFI_SUCCESS;
}

/**
 * This function is called by APs to accept memory.
 *
 * @param CpuIndex        vCPU index of an AP
 * @param PhysicalStart   Start address of a memory region which is to be accepted
 * @param PhysicalEnd     End address of a memory region which is to be accepted
 *
 * @retval EFI_SUCCESS    Successfully accept the memory
 * @retval Others         Other errors as indicated
 */
STATIC
EFI_STATUS
EFIAPI
ApAcceptMemoryResourceRange (
  UINT32                CpuIndex,
  EFI_PHYSICAL_ADDRESS  PhysicalStart,
  EFI_PHYSICAL_ADDRESS  PhysicalEnd
  )
{
  UINT64          Status;
  TD_RETURN_DATA  TdReturnData;

  Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
  if (Status != TDX_EXIT_REASON_SUCCESS) {
    ASSERT (FALSE);
    return EFI_ABORTED;
  }

  if ((CpuIndex == 0) || (CpuIndex >= TdReturnData.TdInfo.NumVcpus)) {
    ASSERT (FALSE);
    return EFI_ABORTED;
  }

  return BspApAcceptMemoryResourceRange (CpuIndex, TdReturnData.TdInfo.NumVcpus, PhysicalStart, PhysicalEnd);
}

/**
 * This function is called by BSP. It coordinates BSP/APs to accept memory together.
 *
 * @param PhysicalStart     Start address of a memory region which is to be accepted
 * @param PhysicalEnd       End address of a memory region which is to be accepted
 * @param APsStackAddress   APs stack address
 * @param CpusNum           Total vCPU number of the Tdx guest
 *
 * @retval EFI_SUCCESS      Successfully accept the memory
 * @retval Others           Other errors as indicated
 */
STATIC
EFI_STATUS
EFIAPI
MpAcceptMemoryResourceRange (
  IN EFI_PHYSICAL_ADDRESS      PhysicalStart,
  IN EFI_PHYSICAL_ADDRESS      PhysicalEnd,
  IN OUT EFI_PHYSICAL_ADDRESS  APsStackAddress,
  IN UINT32                    CpusNum
  )
{
  UINT64      Length;
  EFI_STATUS  Status;

  Length = PhysicalEnd - PhysicalStart;

  DEBUG ((DEBUG_INFO, "MpAccept : 0x%llx - 0x%llx (0x%llx)\n", PhysicalStart, PhysicalEnd, Length));

  if (Length == 0) {
    return EFI_SUCCESS;
  }

  //
  // The start address is not 2M aligned. BSP first accept the part which is not 2M aligned.
  //
  if (ALIGN_VALUE (PhysicalStart, SIZE_2MB) != PhysicalStart) {
    Length = MIN (ALIGN_VALUE (PhysicalStart, SIZE_2MB) - PhysicalStart, Length);
    Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalStart + Length);
    ASSERT (Status == EFI_SUCCESS);

    PhysicalStart += Length;
    Length         = PhysicalEnd - PhysicalStart;
  }

  if (Length == 0) {
    return EFI_SUCCESS;
  }

  //
  // BSP will accept the memory by itself if the memory is not big enough compared with a chunk.
  //
  if (Length <= ACCEPT_CHUNK_SIZE) {
    return BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd);
  }

  //
  // Now APs are asked to accept the memory together.
  //
  MpSerializeStart ();

  MpSendWakeupCommand (
    MpProtectedModeWakeupCommandAcceptPages,
    (UINT64)(UINTN)ApAcceptMemoryResourceRange,
    PhysicalStart,
    PhysicalEnd,
    APsStackAddress,
    AP_STACK_SIZE
    );

  //
  // Now BSP does its job.
  //
  BspApAcceptMemoryResourceRange (0, CpusNum, PhysicalStart, PhysicalEnd);

  MpSerializeEnd ();

  return EFI_SUCCESS;
}

/**
  BSP accept a small piece of memory which will be used as APs stack.

  @param[in] VmmHobList    The Hoblist pass the firmware
  @param[in] APsStackSize  APs stack size
  @param[out] PhysicalAddressEnd    The physical end address of accepted memory in phase-1

  @retval  EFI_SUCCESS     Process the HobList successfully
  @retval  Others          Other errors as indicated
**/
STATIC
EFI_STATUS
EFIAPI
AcceptMemoryForAPsStack (
  IN CONST VOID             *VmmHobList,
  IN UINT32                 APsStackSize,
  OUT EFI_PHYSICAL_ADDRESS  *PhysicalAddressEnd
  )
{
  EFI_STATUS            Status;
  EFI_PEI_HOB_POINTERS  Hob;
  EFI_PHYSICAL_ADDRESS  PhysicalEnd;
  EFI_PHYSICAL_ADDRESS  PhysicalStart;
  UINT64                ResourceLength;
  BOOLEAN               MemoryRegionFound;

  ASSERT (VmmHobList != NULL);

  Status            = EFI_SUCCESS;
  Hob.Raw           = (UINT8 *)VmmHobList;
  MemoryRegionFound = FALSE;

  DEBUG ((DEBUG_INFO, "AcceptMemoryForAPsStack with APsStackSize=0x%x\n", APsStackSize));

  //
  // Parse the HOB list until end of list or matching type is found.
  //
  while (!END_OF_HOB_LIST (Hob) && !MemoryRegionFound) {
    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
      DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));

      if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_UNACCEPTED) {
        ResourceLength = Hob.ResourceDescriptor->ResourceLength;
        PhysicalStart  = Hob.ResourceDescriptor->PhysicalStart;
        PhysicalEnd    = PhysicalStart + ResourceLength;

        DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
        DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", PhysicalStart));
        DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", ResourceLength));
        DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));

        if (ResourceLength >= APsStackSize) {
          MemoryRegionFound = TRUE;
          if (ResourceLength > ACCEPT_CHUNK_SIZE) {
            PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + APsStackSize;
          }
        }

        Status = BspAcceptMemoryResourceRange (
                   Hob.ResourceDescriptor->PhysicalStart,
                   PhysicalEnd
                   );
        if (EFI_ERROR (Status)) {
          break;
        }
      }
    }

    Hob.Raw = GET_NEXT_HOB (Hob);
  }

  ASSERT (MemoryRegionFound);
  *PhysicalAddressEnd = PhysicalEnd;

  return Status;
}

/**
  BSP and APs work togeter to accept memory which is under the address of 4G.

  @param[in] VmmHobList           The Hoblist pass the firmware
  @param[in] CpusNum              Number of vCPUs
  @param[in] APsStackStartAddres  Start address of APs stack
  @param[in] PhysicalAddressStart Start physical address which to be accepted

  @retval  EFI_SUCCESS     Process the HobList successfully
  @retval  Others          Other errors as indicated
**/
STATIC
EFI_STATUS
EFIAPI
AcceptMemory (
  IN CONST VOID            *VmmHobList,
  IN UINT32                CpusNum,
  IN EFI_PHYSICAL_ADDRESS  APsStackStartAddress,
  IN EFI_PHYSICAL_ADDRESS  PhysicalAddressStart
  )
{
  EFI_STATUS            Status;
  EFI_PEI_HOB_POINTERS  Hob;
  EFI_PHYSICAL_ADDRESS  PhysicalStart;
  EFI_PHYSICAL_ADDRESS  PhysicalEnd;
  EFI_PHYSICAL_ADDRESS  AcceptMemoryEndAddress;

  Status                 = EFI_SUCCESS;
  AcceptMemoryEndAddress = BASE_4GB;

  ASSERT (VmmHobList != NULL);
  Hob.Raw = (UINT8 *)VmmHobList;

  DEBUG ((DEBUG_INFO, "AcceptMemory under address of 4G\n"));

  //
  // Parse the HOB list until end of list or matching type is found.
  //
  while (!END_OF_HOB_LIST (Hob)) {
    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
      if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_UNACCEPTED) {
        PhysicalStart = Hob.ResourceDescriptor->PhysicalStart;
        PhysicalEnd   = PhysicalStart + Hob.ResourceDescriptor->ResourceLength;

        if (PhysicalEnd <= PhysicalAddressStart) {
          // this memory region has been accepted. Skipped it.
          Hob.Raw = GET_NEXT_HOB (Hob);
          continue;
        }

        if (PhysicalStart >= AcceptMemoryEndAddress) {
          // this memory region is not to be accepted. And we're done.
          break;
        }

        if (PhysicalStart >= PhysicalAddressStart) {
          // this memory region has not been acceted.
        } else if ((PhysicalStart < PhysicalAddressStart) && (PhysicalEnd > PhysicalAddressStart)) {
          // part of the memory region has been accepted.
          PhysicalStart = PhysicalAddressStart;
        }

        // then compare the PhysicalEnd with AcceptMemoryEndAddress
        if (PhysicalEnd >= AcceptMemoryEndAddress) {
          PhysicalEnd = AcceptMemoryEndAddress;
        }

        DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
        DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", Hob.ResourceDescriptor->PhysicalStart));
        DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", Hob.ResourceDescriptor->ResourceLength));
        DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));

        // Now we're ready to accept memory [PhysicalStart, PhysicalEnd)
        if (CpusNum == 1) {
          Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd);
        } else {
          Status = MpAcceptMemoryResourceRange (
                     PhysicalStart,
                     PhysicalEnd,
                     APsStackStartAddress,
                     CpusNum
                     );
        }

        if (EFI_ERROR (Status)) {
          ASSERT (FALSE);
          break;
        }

        if (PhysicalEnd == AcceptMemoryEndAddress) {
          break;
        }
      }
    }

    Hob.Raw = GET_NEXT_HOB (Hob);
  }

  return Status;
}

/**
  Check the value whether in the valid list.

  @param[in] Value             A value
  @param[in] ValidList         A pointer to valid list
  @param[in] ValidListLength   Length of valid list

  @retval  TRUE   The value is in valid list.
  @retval  FALSE  The value is not in valid list.

**/
STATIC
BOOLEAN
EFIAPI
IsInValidList (
  IN UINT32  Value,
  IN UINT32  *ValidList,
  IN UINT32  ValidListLength
  )
{
  UINT32  index;

  if (ValidList == NULL) {
    return FALSE;
  }

  for (index = 0; index < ValidListLength; index++) {
    if (ValidList[index] == Value) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Check the integrity of VMM Hob List.

  @param[in] VmmHobList   A pointer to Hob List

  @retval  TRUE     The Hob List is valid.
  @retval  FALSE    The Hob List is invalid.

**/
STATIC
BOOLEAN
EFIAPI
ValidateHobList (
  IN CONST VOID  *VmmHobList
  )
{
  EFI_PEI_HOB_POINTERS  Hob;
  UINT32                EFI_BOOT_MODE_LIST[] = {
    BOOT_WITH_FULL_CONFIGURATION,
    BOOT_WITH_MINIMAL_CONFIGURATION,
    BOOT_ASSUMING_NO_CONFIGURATION_CHANGES,
    BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS,
    BOOT_WITH_DEFAULT_SETTINGS,
    BOOT_ON_S4_RESUME,
    BOOT_ON_S5_RESUME,
    BOOT_WITH_MFG_MODE_SETTINGS,
    BOOT_ON_S2_RESUME,
    BOOT_ON_S3_RESUME,
    BOOT_ON_FLASH_UPDATE,
    BOOT_IN_RECOVERY_MODE
  };

  UINT32  EFI_RESOURCE_TYPE_LIST[] = {
    EFI_RESOURCE_SYSTEM_MEMORY,
    EFI_RESOURCE_MEMORY_MAPPED_IO,
    EFI_RESOURCE_IO,
    EFI_RESOURCE_FIRMWARE_DEVICE,
    EFI_RESOURCE_MEMORY_MAPPED_IO_PORT,
    EFI_RESOURCE_MEMORY_RESERVED,
    EFI_RESOURCE_IO_RESERVED,
    EFI_RESOURCE_MEMORY_UNACCEPTED
  };

  if (VmmHobList == NULL) {
    DEBUG ((DEBUG_ERROR, "HOB: HOB data pointer is NULL\n"));
    return FALSE;
  }

  Hob.Raw = (UINT8 *)VmmHobList;

  //
  // Parse the HOB list until end of list or matching type is found.
  //
  while (!END_OF_HOB_LIST (Hob)) {
    if (Hob.Header->Reserved != (UINT32)0) {
      DEBUG ((DEBUG_ERROR, "HOB: Hob header Reserved filed should be zero\n"));
      return FALSE;
    }

    if (Hob.Header->HobLength == 0) {
      DEBUG ((DEBUG_ERROR, "HOB: Hob header LEANGTH should not be zero\n"));
      return FALSE;
    }

    switch (Hob.Header->HobType) {
      case EFI_HOB_TYPE_HANDOFF:
        if (Hob.Header->HobLength != sizeof (EFI_HOB_HANDOFF_INFO_TABLE)) {
          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_HANDOFF));
          return FALSE;
        }

        if (IsInValidList (Hob.HandoffInformationTable->BootMode, EFI_BOOT_MODE_LIST, ARRAY_SIZE (EFI_BOOT_MODE_LIST)) == FALSE) {
          DEBUG ((DEBUG_ERROR, "HOB: Unknow HandoffInformationTable BootMode type. Type: 0x%08x\n", Hob.HandoffInformationTable->BootMode));
          return FALSE;
        }

        if ((Hob.HandoffInformationTable->EfiFreeMemoryTop % 4096) != 0) {
          DEBUG ((DEBUG_ERROR, "HOB: HandoffInformationTable EfiFreeMemoryTop address must be 4-KB aligned to meet page restrictions of UEFI.\
                               Address: 0x%016lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop));
          return FALSE;
        }

        break;

      case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
        if (Hob.Header->HobLength != sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {
          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_RESOURCE_DESCRIPTOR));
          return FALSE;
        }

        if (IsInValidList (Hob.ResourceDescriptor->ResourceType, EFI_RESOURCE_TYPE_LIST, ARRAY_SIZE (EFI_RESOURCE_TYPE_LIST)) == FALSE) {
          DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceType type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceType));
          return FALSE;
        }

        if ((Hob.ResourceDescriptor->ResourceAttribute & (~(EFI_RESOURCE_ATTRIBUTE_PRESENT |
                                                            EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
                                                            EFI_RESOURCE_ATTRIBUTE_TESTED |
                                                            EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |
                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |
                                                            EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED |
                                                            EFI_RESOURCE_ATTRIBUTE_PERSISTENT |
                                                            EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC |
                                                            EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC |
                                                            EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 |
                                                            EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 |
                                                            EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
                                                            EFI_RESOURCE_ATTRIBUTE_16_BIT_IO |
                                                            EFI_RESOURCE_ATTRIBUTE_32_BIT_IO |
                                                            EFI_RESOURCE_ATTRIBUTE_64_BIT_IO |
                                                            EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED |
                                                            EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE |
                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE |
                                                            EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE |
                                                            EFI_RESOURCE_ATTRIBUTE_PERSISTABLE |
                                                            EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED |
                                                            EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE |
                                                            EFI_RESOURCE_ATTRIBUTE_ENCRYPTED|
                                                            EFI_RESOURCE_ATTRIBUTE_SPECIAL_PURPOSE |
                                                            EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE))) != 0)
        {
          DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceAttribute type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceAttribute));
          return FALSE;
        }

        break;

      // EFI_HOB_GUID_TYPE is variable length data, so skip check
      case EFI_HOB_TYPE_GUID_EXTENSION:
        break;

      case EFI_HOB_TYPE_FV:
        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME)) {
          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV));
          return FALSE;
        }

        break;

      case EFI_HOB_TYPE_FV2:
        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME2)) {
          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV2));
          return FALSE;
        }

        break;

      case EFI_HOB_TYPE_FV3:
        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME3)) {
          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV3));
          return FALSE;
        }

        break;

      case EFI_HOB_TYPE_CPU:
        if (Hob.Header->HobLength != sizeof (EFI_HOB_CPU)) {
          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_CPU));
          return FALSE;
        }

        for (UINT32 index = 0; index < 6; index++) {
          if (Hob.Cpu->Reserved[index] != 0) {
            DEBUG ((DEBUG_ERROR, "HOB: Cpu Reserved field will always be set to zero.\n"));
            return FALSE;
          }
        }

        break;

      default:
        DEBUG ((DEBUG_ERROR, "HOB: Hob type is not know. Type: 0x%04x\n", Hob.Header->HobType));
        return FALSE;
    }

    // Get next HOB
    Hob.Raw = (UINT8 *)(Hob.Raw + Hob.Header->HobLength);
  }

  return TRUE;
}

/**
  Processing the incoming HobList for the TDX

  Firmware must parse list, and accept the pages of memory before their can be
  use by the guest.

  @param[in] VmmHobList    The Hoblist pass the firmware

  @retval  EFI_SUCCESS     Process the HobList successfully
  @retval  Others          Other errors as indicated

**/
STATIC
EFI_STATUS
EFIAPI
ProcessHobList (
  IN CONST VOID  *VmmHobList
  )
{
  EFI_STATUS            Status;
  UINT32                CpusNum;
  EFI_PHYSICAL_ADDRESS  PhysicalEnd;
  EFI_PHYSICAL_ADDRESS  APsStackStartAddress;

  CpusNum = GetCpusNum ();

  //
  // If there are mutli-vCPU in a TDX guest, accept memory is split into 2 phases.
  // Phase-1 accepts a small piece of memory by BSP. This piece of memory
  // is used to setup AP's stack.
  // After that phase-2 accepts a big piece of memory by BSP/APs.
  //
  // TDVF supports 4K and 2M accept-page-size. The memory which can be accpeted
  // in 2M accept-page-size must be 2M aligned and multiple 2M. So we align
  // APsStackSize to 2M size aligned.
  //
  if (CpusNum > 1) {
    Status = AcceptMemoryForAPsStack (VmmHobList, APS_STACK_SIZE (CpusNum), &PhysicalEnd);
    ASSERT (Status == EFI_SUCCESS);
    APsStackStartAddress = PhysicalEnd - APS_STACK_SIZE (CpusNum);
  } else {
    PhysicalEnd          = 0;
    APsStackStartAddress = 0;
  }

  Status = AcceptMemory (VmmHobList, CpusNum, APsStackStartAddress, PhysicalEnd);
  ASSERT (Status == EFI_SUCCESS);

  return Status;
}

/**
  In Tdx guest, some information need to be passed from host VMM to guest
  firmware. For example, the memory resource, etc. These information are
  prepared by host VMM and put in TdHob which is described in TdxMetadata.
  TDVF processes the TdHob to accept memories.

  @retval   EFI_SUCCESS   Successfully process the TdHob
  @retval   Others        Other error as indicated
**/
EFI_STATUS
EFIAPI
TdxHelperProcessTdHob (
  VOID
  )
{
  EFI_STATUS      Status;
  VOID            *TdHob;
  TD_RETURN_DATA  TdReturnData;

  TdHob  = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
  Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  DEBUG ((
    DEBUG_INFO,
    "Intel Tdx Started with (GPAW: %d, Cpus: %d)\n",
    TdReturnData.TdInfo.Gpaw,
    TdReturnData.TdInfo.NumVcpus
    ));

  //
  // Validate HobList
  //
  if (ValidateHobList (TdHob) == FALSE) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Process Hoblist to accept memory
  //
  Status = ProcessHobList (TdHob);

  return Status;
}

/**
  In Tdx guest, TdHob is passed from host VMM to guest firmware and it contains
  the information of the memory resource. From the security perspective before
  it is consumed, it should be measured and extended.
 *
 * @retval EFI_SUCCESS Successfully measure the TdHob
 * @retval Others      Other error as indicated
 */
EFI_STATUS
EFIAPI
TdxHelperMeasureTdHob (
  VOID
  )
{
  EFI_PEI_HOB_POINTERS  Hob;
  EFI_STATUS            Status;
  UINT8                 Digest[SHA384_DIGEST_SIZE];
  OVMF_WORK_AREA        *WorkArea;
  VOID                  *TdHob;

  TdHob   = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
  Hob.Raw = (UINT8 *)TdHob;

  //
  // Walk thru the TdHob list until end of list.
  //
  while (!END_OF_HOB_LIST (Hob)) {
    Hob.Raw = GET_NEXT_HOB (Hob);
  }

  Status = TdxMeasurementHashAndExtendToRtmr (
             0,
             (UINT8 *)TdHob,
             (UINTN)((UINT8 *)Hob.Raw - (UINT8 *)TdHob),
             Digest,
             SHA384_DIGEST_SIZE
             );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // This function is called in SEC phase and at that moment the Hob service
  // is not available. So the TdHob measurement value is stored in workarea.
  //
  WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
  if (WorkArea == NULL) {
    return EFI_DEVICE_ERROR;
  }

  WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.MeasurementsBitmap |= TDX_MEASUREMENT_TDHOB_BITMASK;
  CopyMem (WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.TdHobHashValue, Digest, SHA384_DIGEST_SIZE);

  return EFI_SUCCESS;
}

/**
 * In Tdx guest, Configuration FV (CFV) is treated as external input because it
 * may contain the data provided by VMM. From the sucurity perspective Cfv image
 * should be measured before it is consumed.
 *
 * @retval EFI_SUCCESS Successfully measure the CFV image
 * @retval Others      Other error as indicated
 */
EFI_STATUS
EFIAPI
TdxHelperMeasureCfvImage (
  VOID
  )
{
  EFI_STATUS      Status;
  UINT8           Digest[SHA384_DIGEST_SIZE];
  OVMF_WORK_AREA  *WorkArea;

  Status = TdxMeasurementHashAndExtendToRtmr (
             0,
             (UINT8 *)(UINTN)PcdGet32 (PcdOvmfFlashNvStorageVariableBase),
             (UINT64)PcdGet32 (PcdCfvRawDataSize),
             Digest,
             SHA384_DIGEST_SIZE
             );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // This function is called in SEC phase and at that moment the Hob service
  // is not available. So CfvImage measurement value is stored in workarea.
  //
  WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
  if (WorkArea == NULL) {
    return EFI_DEVICE_ERROR;
  }

  WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.MeasurementsBitmap |= TDX_MEASUREMENT_CFVIMG_BITMASK;
  CopyMem (WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.CfvImgHashValue, Digest, SHA384_DIGEST_SIZE);

  return EFI_SUCCESS;
}

/**
  Build the GuidHob for tdx measurements which were done in SEC phase.
  The measurement values are stored in WorkArea.

  @retval EFI_SUCCESS  The GuidHob is built successfully
  @retval Others       Other errors as indicated
**/
EFI_STATUS
EFIAPI
TdxHelperBuildGuidHobForTdxMeasurement (
  VOID
  )
{
 #ifdef TDX_PEI_LESS_BOOT
  return InternalBuildGuidHobForTdxMeasurement ();
 #else
  return EFI_UNSUPPORTED;
 #endif
}
