mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-11-03 21:17:23 +01:00 
			
		
		
		
	OvmfPkg: Refactor ProcessHobList
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243 ProcessHobList once was implemented in PlatformInitLib and it walks thru TdHob list and accept un-accepted memories. This patch moves the codes to SecTdxHelperLib and rename ProcessHobList as TdxHelperProcessTdHob After TdxHelperProcessTdHob is introduced, below changes are applied: - Call TdxHelperProcessTdHob instead of ProcessHobList in SecMain.c (in both OvmfPkgX64/Sec and IntelTdx/Sec). - Delete the duplicated codes in PlatformInitLib Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Michael Roth <michael.roth@amd.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com>
This commit is contained in:
		
							parent
							
								
									852ae4cd80
								
							
						
					
					
						commit
						c0984d1ff2
					
				@ -210,23 +210,6 @@ PlatformMaxCpuCountInitialization (
 | 
				
			|||||||
  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
 | 
					  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
  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 HobList which is described in TdxMetadata.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Information in HobList is treated as external input. From the security
 | 
					 | 
				
			||||||
  perspective before it is consumed, it should be validated.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @retval   EFI_SUCCESS   Successfully process the hoblist
 | 
					 | 
				
			||||||
  @retval   Others        Other error as indicated
 | 
					 | 
				
			||||||
**/
 | 
					 | 
				
			||||||
EFI_STATUS
 | 
					 | 
				
			||||||
EFIAPI
 | 
					 | 
				
			||||||
ProcessTdxHobList (
 | 
					 | 
				
			||||||
  VOID
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
  In Tdx guest, the system memory is passed in TdHob by host VMM. So
 | 
					  In Tdx guest, the system memory is passed in TdHob by host VMM. So
 | 
				
			||||||
  the major task of PlatformTdxPublishRamRegions is to walk thru the
 | 
					  the major task of PlatformTdxPublishRamRegions is to walk thru the
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,7 @@
 | 
				
			|||||||
#include <Library/LocalApicLib.h>
 | 
					#include <Library/LocalApicLib.h>
 | 
				
			||||||
#include <Library/CpuExceptionHandlerLib.h>
 | 
					#include <Library/CpuExceptionHandlerLib.h>
 | 
				
			||||||
#include <IndustryStandard/Tdx.h>
 | 
					#include <IndustryStandard/Tdx.h>
 | 
				
			||||||
#include <Library/PlatformInitLib.h>
 | 
					#include <Library/TdxHelperLib.h>
 | 
				
			||||||
#include <Library/CcProbeLib.h>
 | 
					#include <Library/CcProbeLib.h>
 | 
				
			||||||
#include <Library/PeilessStartupLib.h>
 | 
					#include <Library/PeilessStartupLib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -67,7 +67,7 @@ SecCoreStartupWithStack (
 | 
				
			|||||||
    // first so that the memory is accepted. Otherwise access to the unaccepted
 | 
					    // first so that the memory is accepted. Otherwise access to the unaccepted
 | 
				
			||||||
    // memory will trigger tripple fault.
 | 
					    // memory will trigger tripple fault.
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
    if (ProcessTdxHobList () != EFI_SUCCESS) {
 | 
					    if (TdxHelperProcessTdHob () != EFI_SUCCESS) {
 | 
				
			||||||
      CpuDeadLoop ();
 | 
					      CpuDeadLoop ();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -17,11 +17,20 @@
 | 
				
			|||||||
#include <IndustryStandard/IntelTdx.h>
 | 
					#include <IndustryStandard/IntelTdx.h>
 | 
				
			||||||
#include <IndustryStandard/Tpm20.h>
 | 
					#include <IndustryStandard/Tpm20.h>
 | 
				
			||||||
#include <Library/TdxLib.h>
 | 
					#include <Library/TdxLib.h>
 | 
				
			||||||
 | 
					#include <Library/TdxMailboxLib.h>
 | 
				
			||||||
 | 
					#include <Library/SynchronizationLib.h>
 | 
				
			||||||
#include <Pi/PrePiHob.h>
 | 
					#include <Pi/PrePiHob.h>
 | 
				
			||||||
#include <WorkArea.h>
 | 
					#include <WorkArea.h>
 | 
				
			||||||
#include <ConfidentialComputingGuestAttr.h>
 | 
					#include <ConfidentialComputingGuestAttr.h>
 | 
				
			||||||
#include <Library/TdxHelperLib.h>
 | 
					#include <Library/TdxHelperLib.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.
 | 
					  Build the GuidHob for tdx measurements which were done in SEC phase.
 | 
				
			||||||
  The measurement values are stored in WorkArea.
 | 
					  The measurement values are stored in WorkArea.
 | 
				
			||||||
@ -34,6 +43,720 @@ InternalBuildGuidHobForTdxMeasurement (
 | 
				
			|||||||
  VOID
 | 
					  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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  AcceptPageSize = (UINT64)(UINTN)FixedPcdGet32 (PcdTdxAcceptPageSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Status          = EFI_SUCCESS;
 | 
				
			||||||
 | 
					  Stride          = (UINTN)CpusNum * ACCEPT_CHUNK_SIZE;
 | 
				
			||||||
 | 
					  PhysicalAddress = PhysicalStart + ACCEPT_CHUNK_SIZE * (UINTN)CpuIndex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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 == BZ3937_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 == BZ3937_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,
 | 
				
			||||||
 | 
					    BZ3937_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_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
 | 
					  In Tdx guest, some information need to be passed from host VMM to guest
 | 
				
			||||||
  firmware. For example, the memory resource, etc. These information are
 | 
					  firmware. For example, the memory resource, etc. These information are
 | 
				
			||||||
@ -49,7 +772,36 @@ TdxHelperProcessTdHob (
 | 
				
			|||||||
  VOID
 | 
					  VOID
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  return EFI_UNSUPPORTED;
 | 
					  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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 | 
				
			|||||||
@ -16,779 +16,11 @@
 | 
				
			|||||||
#include <Library/MemoryAllocationLib.h>
 | 
					#include <Library/MemoryAllocationLib.h>
 | 
				
			||||||
#include <IndustryStandard/Tdx.h>
 | 
					#include <IndustryStandard/Tdx.h>
 | 
				
			||||||
#include <IndustryStandard/IntelTdx.h>
 | 
					#include <IndustryStandard/IntelTdx.h>
 | 
				
			||||||
#include <IndustryStandard/QemuFwCfg.h>
 | 
					 | 
				
			||||||
#include <Library/QemuFwCfgLib.h>
 | 
					 | 
				
			||||||
#include <Library/PeiServicesLib.h>
 | 
					#include <Library/PeiServicesLib.h>
 | 
				
			||||||
#include <Library/TdxLib.h>
 | 
					 | 
				
			||||||
#include <Library/TdxMailboxLib.h>
 | 
					 | 
				
			||||||
#include <Library/SynchronizationLib.h>
 | 
					 | 
				
			||||||
#include <Pi/PrePiHob.h>
 | 
					#include <Pi/PrePiHob.h>
 | 
				
			||||||
#include <WorkArea.h>
 | 
					#include <WorkArea.h>
 | 
				
			||||||
#include <ConfidentialComputingGuestAttr.h>
 | 
					#include <ConfidentialComputingGuestAttr.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))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
  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
 | 
					 | 
				
			||||||
**/
 | 
					 | 
				
			||||||
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;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  AcceptPageSize = (UINT64)(UINTN)FixedPcdGet32 (PcdTdxAcceptPageSize);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Status          = EFI_SUCCESS;
 | 
					 | 
				
			||||||
  Stride          = (UINTN)CpusNum * ACCEPT_CHUNK_SIZE;
 | 
					 | 
				
			||||||
  PhysicalAddress = PhysicalStart + ACCEPT_CHUNK_SIZE * (UINTN)CpuIndex;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  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;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  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
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
**/
 | 
					 | 
				
			||||||
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 == BZ3937_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
 | 
					 | 
				
			||||||
**/
 | 
					 | 
				
			||||||
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 == BZ3937_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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**/
 | 
					 | 
				
			||||||
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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**/
 | 
					 | 
				
			||||||
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,
 | 
					 | 
				
			||||||
    BZ3937_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_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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**/
 | 
					 | 
				
			||||||
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 HobList which is described in TdxMetadata.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Information in HobList is treated as external input. From the security
 | 
					 | 
				
			||||||
  perspective before it is consumed, it should be validated.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @retval   EFI_SUCCESS   Successfully process the hoblist
 | 
					 | 
				
			||||||
  @retval   Others        Other error as indicated
 | 
					 | 
				
			||||||
**/
 | 
					 | 
				
			||||||
EFI_STATUS
 | 
					 | 
				
			||||||
EFIAPI
 | 
					 | 
				
			||||||
ProcessTdxHobList (
 | 
					 | 
				
			||||||
  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;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Build ResourceDescriptorHob for the unaccepted memory region.
 | 
					 * Build ResourceDescriptorHob for the unaccepted memory region.
 | 
				
			||||||
 * This memory region may be splitted into 2 parts because of lazy accept.
 | 
					 * This memory region may be splitted into 2 parts because of lazy accept.
 | 
				
			||||||
 | 
				
			|||||||
@ -9,26 +9,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <PiPei.h>
 | 
					#include <PiPei.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
  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 HobList which is described in TdxMetadata.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Information in HobList is treated as external input. From the security
 | 
					 | 
				
			||||||
  perspective before it is consumed, it should be validated.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @retval   EFI_SUCCESS   Successfully process the hoblist
 | 
					 | 
				
			||||||
  @retval   Others        Other error as indicated
 | 
					 | 
				
			||||||
**/
 | 
					 | 
				
			||||||
EFI_STATUS
 | 
					 | 
				
			||||||
EFIAPI
 | 
					 | 
				
			||||||
ProcessTdxHobList (
 | 
					 | 
				
			||||||
  VOID
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return EFI_UNSUPPORTED;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
  In Tdx guest, the system memory is passed in TdHob by host VMM. So
 | 
					  In Tdx guest, the system memory is passed in TdHob by host VMM. So
 | 
				
			||||||
  the major task of PlatformTdxPublishRamRegions is to walk thru the
 | 
					  the major task of PlatformTdxPublishRamRegions is to walk thru the
 | 
				
			||||||
 | 
				
			|||||||
@ -52,7 +52,6 @@
 | 
				
			|||||||
  PcdLib
 | 
					  PcdLib
 | 
				
			||||||
  PciLib
 | 
					  PciLib
 | 
				
			||||||
  PeiHardwareInfoLib
 | 
					  PeiHardwareInfoLib
 | 
				
			||||||
  TdxMailboxLib
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
[LibraryClasses.X64]
 | 
					[LibraryClasses.X64]
 | 
				
			||||||
  TdxLib
 | 
					  TdxLib
 | 
				
			||||||
 | 
				
			|||||||
@ -724,7 +724,8 @@
 | 
				
			|||||||
  OvmfPkg/Sec/SecMain.inf {
 | 
					  OvmfPkg/Sec/SecMain.inf {
 | 
				
			||||||
    <LibraryClasses>
 | 
					    <LibraryClasses>
 | 
				
			||||||
      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
 | 
					      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
 | 
				
			||||||
      NULL|OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
 | 
					      NULL|OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf
 | 
				
			||||||
 | 
					      BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #
 | 
					  #
 | 
				
			||||||
 | 
				
			|||||||
@ -29,7 +29,7 @@
 | 
				
			|||||||
#include <Library/CpuExceptionHandlerLib.h>
 | 
					#include <Library/CpuExceptionHandlerLib.h>
 | 
				
			||||||
#include <Ppi/TemporaryRamSupport.h>
 | 
					#include <Ppi/TemporaryRamSupport.h>
 | 
				
			||||||
#include <Ppi/MpInitLibDep.h>
 | 
					#include <Ppi/MpInitLibDep.h>
 | 
				
			||||||
#include <Library/PlatformInitLib.h>
 | 
					#include <Library/TdxHelperLib.h>
 | 
				
			||||||
#include <Library/CcProbeLib.h>
 | 
					#include <Library/CcProbeLib.h>
 | 
				
			||||||
#include "AmdSev.h"
 | 
					#include "AmdSev.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -765,7 +765,7 @@ SecCoreStartupWithStack (
 | 
				
			|||||||
    // first so that the memory is accepted. Otherwise access to the unaccepted
 | 
					    // first so that the memory is accepted. Otherwise access to the unaccepted
 | 
				
			||||||
    // memory will trigger tripple fault.
 | 
					    // memory will trigger tripple fault.
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
    if (ProcessTdxHobList () != EFI_SUCCESS) {
 | 
					    if (TdxHelperProcessTdHob () != EFI_SUCCESS) {
 | 
				
			||||||
      CpuDeadLoop ();
 | 
					      CpuDeadLoop ();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user