/** @file
  Initialize Intel TDX support.

  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Base.h>
#include <PiPei.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <IndustryStandard/Tdx.h>
#include <IndustryStandard/IntelTdx.h>
#include <Library/PeiServicesLib.h>
#include <Pi/PiHob.h>
#include <WorkArea.h>
#include <ConfidentialComputingGuestAttr.h>

/**
 * Build ResourceDescriptorHob for the unaccepted memory region.
 * This memory region may be splitted into 2 parts because of lazy accept.
 *
 * @param Hob     Point to the EFI_HOB_RESOURCE_DESCRIPTOR
 * @return VOID
 */
VOID
BuildResourceDescriptorHobForUnacceptedMemory (
  IN EFI_HOB_RESOURCE_DESCRIPTOR  *Hob
  )
{
  EFI_PHYSICAL_ADDRESS         PhysicalStart;
  EFI_PHYSICAL_ADDRESS         PhysicalEnd;
  UINT64                       ResourceLength;
  EFI_RESOURCE_TYPE            ResourceType;
  EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute;
  UINT64                       MaxAcceptedMemoryAddress;

  ASSERT (Hob->ResourceType == EFI_RESOURCE_MEMORY_UNACCEPTED);

  ResourceType      = EFI_RESOURCE_MEMORY_UNACCEPTED;
  ResourceAttribute = Hob->ResourceAttribute;
  PhysicalStart     = Hob->PhysicalStart;
  ResourceLength    = Hob->ResourceLength;
  PhysicalEnd       = PhysicalStart + ResourceLength;

  //
  // In the first stage of lazy-accept, all the memory under 4G will be accepted.
  // The memory above 4G will not be accepted.
  //
  MaxAcceptedMemoryAddress = BASE_4GB;

  if (PhysicalEnd <= MaxAcceptedMemoryAddress) {
    //
    // This memory region has been accepted.
    //
    ResourceType       = EFI_RESOURCE_SYSTEM_MEMORY;
    ResourceAttribute |= (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED);
  } else if (PhysicalStart >= MaxAcceptedMemoryAddress) {
    //
    // This memory region hasn't been accepted.
    // So keep the ResourceType and ResourceAttribute unchange.
    //
  }

  BuildResourceDescriptorHob (
    ResourceType,
    ResourceAttribute,
    PhysicalStart,
    ResourceLength
    );
}

/**
  Transfer the incoming HobList for the TD to the final HobList for Dxe.
  The Hobs transferred in this function are ResourceDescriptor hob and
  MemoryAllocation hob.

  @param[in] VmmHobList    The Hoblist pass the firmware

**/
VOID
EFIAPI
TransferTdxHobList (
  VOID
  )
{
  EFI_PEI_HOB_POINTERS         Hob;
  EFI_RESOURCE_TYPE            ResourceType;
  EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute;
  VOID                         *GuidedData;

  //
  // PcdOvmfSecGhcbBase is used as the TD_HOB in Tdx guest.
  //
  Hob.Raw = (UINT8 *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
  while (!END_OF_HOB_LIST (Hob)) {
    switch (Hob.Header->HobType) {
      case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
        ResourceType      = Hob.ResourceDescriptor->ResourceType;
        ResourceAttribute = Hob.ResourceDescriptor->ResourceAttribute;

        if (ResourceType == EFI_RESOURCE_MEMORY_UNACCEPTED) {
          BuildResourceDescriptorHobForUnacceptedMemory (Hob.ResourceDescriptor);
        } else {
          BuildResourceDescriptorHob (
            ResourceType,
            ResourceAttribute,
            Hob.ResourceDescriptor->PhysicalStart,
            Hob.ResourceDescriptor->ResourceLength
            );
        }

        break;
      case EFI_HOB_TYPE_MEMORY_ALLOCATION:
        BuildMemoryAllocationHob (
          Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress,
          Hob.MemoryAllocation->AllocDescriptor.MemoryLength,
          Hob.MemoryAllocation->AllocDescriptor.MemoryType
          );
        break;
      case EFI_HOB_TYPE_GUID_EXTENSION:
        GuidedData = (VOID *)(&Hob.Guid->Name + 1);
        BuildGuidDataHob (&Hob.Guid->Name, GuidedData, Hob.Guid->Header.HobLength - sizeof (EFI_HOB_GUID_TYPE));
        break;
    }

    Hob.Raw = GET_NEXT_HOB (Hob);
  }
}

/**
  In Tdx guest, the system memory is passed in TdHob by host VMM. So
  the major task of PlatformTdxPublishRamRegions is to walk thru the
  TdHob list and transfer the ResourceDescriptorHob and MemoryAllocationHob
  to the hobs in DXE phase.

  MemoryAllocationHob should also be created for Mailbox and Ovmf work area.
**/
VOID
EFIAPI
PlatformTdxPublishRamRegions (
  VOID
  )
{
  if (!TdIsEnabled ()) {
    return;
  }

  TransferTdxHobList ();

  //
  // Reserve the initial page tables built by the reset vector code.
  //
  // Since this memory range will be used by APs on Mailbox
  // wakeup, it must be reserved as ACPI NVS.
  //
  BuildMemoryAllocationHob (
    (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecPageTablesBase),
    (UINT64)(UINTN)PcdGet32 (PcdOvmfSecPageTablesSize),
    EfiACPIMemoryNVS
    );

  //
  // The memory region defined by PcdOvmfSecGhcbBackupBase is pre-allocated by
  // host VMM and used as the td mailbox at the beginning of system boot.
  //
  BuildMemoryAllocationHob (
    FixedPcdGet32 (PcdOvmfSecGhcbBackupBase),
    FixedPcdGet32 (PcdOvmfSecGhcbBackupSize),
    EfiACPIMemoryNVS
    );

  if (FixedPcdGet32 (PcdOvmfWorkAreaSize) != 0) {
    //
    // Reserve the work area.
    //
    // Since this memory range will be used by the Reset Vector on S3
    // resume, it must be reserved as ACPI NVS.
    //
    // If S3 is unsupported, then various drivers might still write to the
    // work area. We ought to prevent DXE from serving allocation requests
    // such that they would overlap the work area.
    //
    // Since this memory range will be used by the Reset Vector on Maibox
    // wakeup again, it must be reserved as ACPI NVS.
    //
    BuildMemoryAllocationHob (
      (EFI_PHYSICAL_ADDRESS)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaBase),
      (UINT64)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaSize),
      EfiACPIMemoryNVS
      );
  }
}
