]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: Refactor ProcessHobList
authorMin M Xu <min.m.xu@intel.com>
Fri, 3 Feb 2023 03:31:42 +0000 (11:31 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Sat, 4 Feb 2023 03:38:15 +0000 (03:38 +0000)
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>
OvmfPkg/Include/Library/PlatformInitLib.h
OvmfPkg/IntelTdx/Sec/SecMain.c
OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelper.c
OvmfPkg/Library/PlatformInitLib/IntelTdx.c
OvmfPkg/Library/PlatformInitLib/IntelTdxNull.c
OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
OvmfPkg/OvmfPkgX64.dsc
OvmfPkg/Sec/SecMain.c

index 051b3119119493d620386346adcaa84d38a98162..57b18b94d9b8908bb0aed30a544136086e649fa7 100644 (file)
@@ -210,23 +210,6 @@ PlatformMaxCpuCountInitialization (
   IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob\r
   );\r
 \r
-/**\r
-  In Tdx guest, some information need to be passed from host VMM to guest\r
-  firmware. For example, the memory resource, etc. These information are\r
-  prepared by host VMM and put in HobList which is described in TdxMetadata.\r
-\r
-  Information in HobList is treated as external input. From the security\r
-  perspective before it is consumed, it should be validated.\r
-\r
-  @retval   EFI_SUCCESS   Successfully process the hoblist\r
-  @retval   Others        Other error as indicated\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessTdxHobList (\r
-  VOID\r
-  );\r
-\r
 /**\r
   In Tdx guest, the system memory is passed in TdHob by host VMM. So\r
   the major task of PlatformTdxPublishRamRegions is to walk thru the\r
index ab01ec9ab19c796738d41a0eb2b5754b4c7d890c..41bd5c66ba29f8ec98b7a2b48a8a23e727e86bba 100644 (file)
@@ -24,7 +24,7 @@
 #include <Library/LocalApicLib.h>\r
 #include <Library/CpuExceptionHandlerLib.h>\r
 #include <IndustryStandard/Tdx.h>\r
-#include <Library/PlatformInitLib.h>\r
+#include <Library/TdxHelperLib.h>\r
 #include <Library/CcProbeLib.h>\r
 #include <Library/PeilessStartupLib.h>\r
 \r
@@ -67,7 +67,7 @@ SecCoreStartupWithStack (
     // first so that the memory is accepted. Otherwise access to the unaccepted\r
     // memory will trigger tripple fault.\r
     //\r
-    if (ProcessTdxHobList () != EFI_SUCCESS) {\r
+    if (TdxHelperProcessTdHob () != EFI_SUCCESS) {\r
       CpuDeadLoop ();\r
     }\r
   }\r
index 1929093f9110d59c362f6f141cf25f2a4775c27d..3372cee2f720a0bfe755a50ad9bf748a2e8cb1ed 100644 (file)
 #include <IndustryStandard/IntelTdx.h>\r
 #include <IndustryStandard/Tpm20.h>\r
 #include <Library/TdxLib.h>\r
+#include <Library/TdxMailboxLib.h>\r
+#include <Library/SynchronizationLib.h>\r
 #include <Pi/PrePiHob.h>\r
 #include <WorkArea.h>\r
 #include <ConfidentialComputingGuestAttr.h>\r
 #include <Library/TdxHelperLib.h>\r
 \r
+#define ALIGNED_2MB_MASK  0x1fffff\r
+#define MEGABYTE_SHIFT    20\r
+\r
+#define ACCEPT_CHUNK_SIZE  SIZE_32MB\r
+#define AP_STACK_SIZE      SIZE_16KB\r
+#define APS_STACK_SIZE(CpusNum)  (ALIGN_VALUE(CpusNum*AP_STACK_SIZE, SIZE_2MB))\r
+\r
 /**\r
   Build the GuidHob for tdx measurements which were done in SEC phase.\r
   The measurement values are stored in WorkArea.\r
@@ -34,6 +43,720 @@ InternalBuildGuidHobForTdxMeasurement (
   VOID\r
   );\r
 \r
+/**\r
+  This function will be called to accept pages. Only BSP accepts pages.\r
+\r
+  TDCALL(ACCEPT_PAGE) supports the accept page size of 4k and 2M. To\r
+  simplify the implementation, the Memory to be accpeted is splitted\r
+  into 3 parts:\r
+  -----------------  <-- StartAddress1 (not 2M aligned)\r
+  |  part 1       |      Length1 < 2M\r
+  |---------------|  <-- StartAddress2 (2M aligned)\r
+  |               |      Length2 = Integer multiples of 2M\r
+  |  part 2       |\r
+  |               |\r
+  |---------------|  <-- StartAddress3\r
+  |  part 3       |      Length3 < 2M\r
+  |---------------|\r
+\r
+  @param[in] PhysicalAddress   Start physical adress\r
+  @param[in] PhysicalEnd       End physical address\r
+\r
+  @retval    EFI_SUCCESS       Accept memory successfully\r
+  @retval    Others            Other errors as indicated\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+BspAcceptMemoryResourceRange (\r
+  IN EFI_PHYSICAL_ADDRESS  PhysicalAddress,\r
+  IN EFI_PHYSICAL_ADDRESS  PhysicalEnd\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      AcceptPageSize;\r
+  UINT64      StartAddress1;\r
+  UINT64      StartAddress2;\r
+  UINT64      StartAddress3;\r
+  UINT64      TotalLength;\r
+  UINT64      Length1;\r
+  UINT64      Length2;\r
+  UINT64      Length3;\r
+  UINT64      Pages;\r
+\r
+  AcceptPageSize = FixedPcdGet32 (PcdTdxAcceptPageSize);\r
+  TotalLength    = PhysicalEnd - PhysicalAddress;\r
+  StartAddress1  = 0;\r
+  StartAddress2  = 0;\r
+  StartAddress3  = 0;\r
+  Length1        = 0;\r
+  Length2        = 0;\r
+  Length3        = 0;\r
+\r
+  if (TotalLength == 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (ALIGN_VALUE (PhysicalAddress, SIZE_2MB) != PhysicalAddress) {\r
+    StartAddress1 = PhysicalAddress;\r
+    Length1       = ALIGN_VALUE (PhysicalAddress, SIZE_2MB) - PhysicalAddress;\r
+    if (Length1 >= TotalLength) {\r
+      Length1 = TotalLength;\r
+    }\r
+\r
+    PhysicalAddress += Length1;\r
+    TotalLength     -= Length1;\r
+  }\r
+\r
+  if (TotalLength > SIZE_2MB) {\r
+    StartAddress2    = PhysicalAddress;\r
+    Length2          = TotalLength & ~(UINT64)ALIGNED_2MB_MASK;\r
+    PhysicalAddress += Length2;\r
+    TotalLength     -= Length2;\r
+  }\r
+\r
+  if (TotalLength) {\r
+    StartAddress3 = PhysicalAddress;\r
+    Length3       = TotalLength;\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
+  if (Length1 > 0) {\r
+    Pages  = Length1 / SIZE_4KB;\r
+    Status = TdAcceptPages (StartAddress1, Pages, SIZE_4KB);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  if (Length2 > 0) {\r
+    Pages  = Length2 / AcceptPageSize;\r
+    Status = TdAcceptPages (StartAddress2, Pages, AcceptPageSize);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  if (Length3 > 0) {\r
+    Pages  = Length3 / SIZE_4KB;\r
+    Status = TdAcceptPages (StartAddress3, Pages, SIZE_4KB);\r
+    ASSERT (!EFI_ERROR (Status));\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+ * This function is called by BSP and APs to accept memory.\r
+ * Note:\r
+ * The input PhysicalStart/PhysicalEnd indicates the whole memory region\r
+ * to be accepted. BSP or AP only accepts one piece in the whole memory region.\r
+ *\r
+ * @param CpuIndex        vCPU index\r
+ * @param CpusNum         Total vCPU number of a Tdx guest\r
+ * @param PhysicalStart   Start address of a memory region which is to be accepted\r
+ * @param PhysicalEnd     End address of a memory region which is to be accepted\r
+ *\r
+ * @retval EFI_SUCCESS    Successfully accept the memory\r
+ * @retval Other          Other errors as indicated\r
+ */\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+BspApAcceptMemoryResourceRange (\r
+  UINT32                CpuIndex,\r
+  UINT32                CpusNum,\r
+  EFI_PHYSICAL_ADDRESS  PhysicalStart,\r
+  EFI_PHYSICAL_ADDRESS  PhysicalEnd\r
+  )\r
+{\r
+  UINT64                Status;\r
+  UINT64                Pages;\r
+  UINT64                Stride;\r
+  UINT64                AcceptPageSize;\r
+  EFI_PHYSICAL_ADDRESS  PhysicalAddress;\r
+\r
+  AcceptPageSize = (UINT64)(UINTN)FixedPcdGet32 (PcdTdxAcceptPageSize);\r
+\r
+  Status          = EFI_SUCCESS;\r
+  Stride          = (UINTN)CpusNum * ACCEPT_CHUNK_SIZE;\r
+  PhysicalAddress = PhysicalStart + ACCEPT_CHUNK_SIZE * (UINTN)CpuIndex;\r
+\r
+  while (!EFI_ERROR (Status) && PhysicalAddress < PhysicalEnd) {\r
+    Pages  = MIN (ACCEPT_CHUNK_SIZE, PhysicalEnd - PhysicalAddress) / AcceptPageSize;\r
+    Status = TdAcceptPages (PhysicalAddress, Pages, (UINT32)(UINTN)AcceptPageSize);\r
+    ASSERT (!EFI_ERROR (Status));\r
+    PhysicalAddress += Stride;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ * This function is called by APs to accept memory.\r
+ *\r
+ * @param CpuIndex        vCPU index of an AP\r
+ * @param PhysicalStart   Start address of a memory region which is to be accepted\r
+ * @param PhysicalEnd     End address of a memory region which is to be accepted\r
+ *\r
+ * @retval EFI_SUCCESS    Successfully accept the memory\r
+ * @retval Others         Other errors as indicated\r
+ */\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+ApAcceptMemoryResourceRange (\r
+  UINT32                CpuIndex,\r
+  EFI_PHYSICAL_ADDRESS  PhysicalStart,\r
+  EFI_PHYSICAL_ADDRESS  PhysicalEnd\r
+  )\r
+{\r
+  UINT64          Status;\r
+  TD_RETURN_DATA  TdReturnData;\r
+\r
+  Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);\r
+  if (Status != TDX_EXIT_REASON_SUCCESS) {\r
+    ASSERT (FALSE);\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if ((CpuIndex == 0) || (CpuIndex >= TdReturnData.TdInfo.NumVcpus)) {\r
+    ASSERT (FALSE);\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  return BspApAcceptMemoryResourceRange (CpuIndex, TdReturnData.TdInfo.NumVcpus, PhysicalStart, PhysicalEnd);\r
+}\r
+\r
+/**\r
+ * This function is called by BSP. It coordinates BSP/APs to accept memory together.\r
+ *\r
+ * @param PhysicalStart     Start address of a memory region which is to be accepted\r
+ * @param PhysicalEnd       End address of a memory region which is to be accepted\r
+ * @param APsStackAddress   APs stack address\r
+ * @param CpusNum           Total vCPU number of the Tdx guest\r
+ *\r
+ * @retval EFI_SUCCESS      Successfully accept the memory\r
+ * @retval Others           Other errors as indicated\r
+ */\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+MpAcceptMemoryResourceRange (\r
+  IN EFI_PHYSICAL_ADDRESS      PhysicalStart,\r
+  IN EFI_PHYSICAL_ADDRESS      PhysicalEnd,\r
+  IN OUT EFI_PHYSICAL_ADDRESS  APsStackAddress,\r
+  IN UINT32                    CpusNum\r
+  )\r
+{\r
+  UINT64      Length;\r
+  EFI_STATUS  Status;\r
+\r
+  Length = PhysicalEnd - PhysicalStart;\r
+\r
+  DEBUG ((DEBUG_INFO, "MpAccept : 0x%llx - 0x%llx (0x%llx)\n", PhysicalStart, PhysicalEnd, Length));\r
+\r
+  if (Length == 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // The start address is not 2M aligned. BSP first accept the part which is not 2M aligned.\r
+  //\r
+  if (ALIGN_VALUE (PhysicalStart, SIZE_2MB) != PhysicalStart) {\r
+    Length = MIN (ALIGN_VALUE (PhysicalStart, SIZE_2MB) - PhysicalStart, Length);\r
+    Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalStart + Length);\r
+    ASSERT (Status == EFI_SUCCESS);\r
+\r
+    PhysicalStart += Length;\r
+    Length         = PhysicalEnd - PhysicalStart;\r
+  }\r
+\r
+  if (Length == 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // BSP will accept the memory by itself if the memory is not big enough compared with a chunk.\r
+  //\r
+  if (Length <= ACCEPT_CHUNK_SIZE) {\r
+    return BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd);\r
+  }\r
+\r
+  //\r
+  // Now APs are asked to accept the memory together.\r
+  //\r
+  MpSerializeStart ();\r
+\r
+  MpSendWakeupCommand (\r
+    MpProtectedModeWakeupCommandAcceptPages,\r
+    (UINT64)(UINTN)ApAcceptMemoryResourceRange,\r
+    PhysicalStart,\r
+    PhysicalEnd,\r
+    APsStackAddress,\r
+    AP_STACK_SIZE\r
+    );\r
+\r
+  //\r
+  // Now BSP does its job.\r
+  //\r
+  BspApAcceptMemoryResourceRange (0, CpusNum, PhysicalStart, PhysicalEnd);\r
+\r
+  MpSerializeEnd ();\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  BSP accept a small piece of memory which will be used as APs stack.\r
+\r
+  @param[in] VmmHobList    The Hoblist pass the firmware\r
+  @param[in] APsStackSize  APs stack size\r
+  @param[out] PhysicalAddressEnd    The physical end address of accepted memory in phase-1\r
+\r
+  @retval  EFI_SUCCESS     Process the HobList successfully\r
+  @retval  Others          Other errors as indicated\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+AcceptMemoryForAPsStack (\r
+  IN CONST VOID             *VmmHobList,\r
+  IN UINT32                 APsStackSize,\r
+  OUT EFI_PHYSICAL_ADDRESS  *PhysicalAddressEnd\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_PEI_HOB_POINTERS  Hob;\r
+  EFI_PHYSICAL_ADDRESS  PhysicalEnd;\r
+  EFI_PHYSICAL_ADDRESS  PhysicalStart;\r
+  UINT64                ResourceLength;\r
+  BOOLEAN               MemoryRegionFound;\r
+\r
+  ASSERT (VmmHobList != NULL);\r
+\r
+  Status            = EFI_SUCCESS;\r
+  Hob.Raw           = (UINT8 *)VmmHobList;\r
+  MemoryRegionFound = FALSE;\r
+\r
+  DEBUG ((DEBUG_INFO, "AcceptMemoryForAPsStack with APsStackSize=0x%x\n", APsStackSize));\r
+\r
+  //\r
+  // Parse the HOB list until end of list or matching type is found.\r
+  //\r
+  while (!END_OF_HOB_LIST (Hob) && !MemoryRegionFound) {\r
+    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+      DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));\r
+\r
+      if (Hob.ResourceDescriptor->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {\r
+        ResourceLength = Hob.ResourceDescriptor->ResourceLength;\r
+        PhysicalStart  = Hob.ResourceDescriptor->PhysicalStart;\r
+        PhysicalEnd    = PhysicalStart + ResourceLength;\r
+\r
+        DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));\r
+        DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", PhysicalStart));\r
+        DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", ResourceLength));\r
+        DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));\r
+\r
+        if (ResourceLength >= APsStackSize) {\r
+          MemoryRegionFound = TRUE;\r
+          if (ResourceLength > ACCEPT_CHUNK_SIZE) {\r
+            PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + APsStackSize;\r
+          }\r
+        }\r
+\r
+        Status = BspAcceptMemoryResourceRange (\r
+                   Hob.ResourceDescriptor->PhysicalStart,\r
+                   PhysicalEnd\r
+                   );\r
+        if (EFI_ERROR (Status)) {\r
+          break;\r
+        }\r
+      }\r
+    }\r
+\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+  }\r
+\r
+  ASSERT (MemoryRegionFound);\r
+  *PhysicalAddressEnd = PhysicalEnd;\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  BSP and APs work togeter to accept memory which is under the address of 4G.\r
+\r
+  @param[in] VmmHobList           The Hoblist pass the firmware\r
+  @param[in] CpusNum              Number of vCPUs\r
+  @param[in] APsStackStartAddres  Start address of APs stack\r
+  @param[in] PhysicalAddressStart Start physical address which to be accepted\r
+\r
+  @retval  EFI_SUCCESS     Process the HobList successfully\r
+  @retval  Others          Other errors as indicated\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+AcceptMemory (\r
+  IN CONST VOID            *VmmHobList,\r
+  IN UINT32                CpusNum,\r
+  IN EFI_PHYSICAL_ADDRESS  APsStackStartAddress,\r
+  IN EFI_PHYSICAL_ADDRESS  PhysicalAddressStart\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_PEI_HOB_POINTERS  Hob;\r
+  EFI_PHYSICAL_ADDRESS  PhysicalStart;\r
+  EFI_PHYSICAL_ADDRESS  PhysicalEnd;\r
+  EFI_PHYSICAL_ADDRESS  AcceptMemoryEndAddress;\r
+\r
+  Status                 = EFI_SUCCESS;\r
+  AcceptMemoryEndAddress = BASE_4GB;\r
+\r
+  ASSERT (VmmHobList != NULL);\r
+  Hob.Raw = (UINT8 *)VmmHobList;\r
+\r
+  DEBUG ((DEBUG_INFO, "AcceptMemory under address of 4G\n"));\r
+\r
+  //\r
+  // Parse the HOB list until end of list or matching type is found.\r
+  //\r
+  while (!END_OF_HOB_LIST (Hob)) {\r
+    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+      if (Hob.ResourceDescriptor->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {\r
+        PhysicalStart = Hob.ResourceDescriptor->PhysicalStart;\r
+        PhysicalEnd   = PhysicalStart + Hob.ResourceDescriptor->ResourceLength;\r
+\r
+        if (PhysicalEnd <= PhysicalAddressStart) {\r
+          // this memory region has been accepted. Skipped it.\r
+          Hob.Raw = GET_NEXT_HOB (Hob);\r
+          continue;\r
+        }\r
+\r
+        if (PhysicalStart >= AcceptMemoryEndAddress) {\r
+          // this memory region is not to be accepted. And we're done.\r
+          break;\r
+        }\r
+\r
+        if (PhysicalStart >= PhysicalAddressStart) {\r
+          // this memory region has not been acceted.\r
+        } else if ((PhysicalStart < PhysicalAddressStart) && (PhysicalEnd > PhysicalAddressStart)) {\r
+          // part of the memory region has been accepted.\r
+          PhysicalStart = PhysicalAddressStart;\r
+        }\r
+\r
+        // then compare the PhysicalEnd with AcceptMemoryEndAddress\r
+        if (PhysicalEnd >= AcceptMemoryEndAddress) {\r
+          PhysicalEnd = AcceptMemoryEndAddress;\r
+        }\r
+\r
+        DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));\r
+        DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", Hob.ResourceDescriptor->PhysicalStart));\r
+        DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", Hob.ResourceDescriptor->ResourceLength));\r
+        DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));\r
+\r
+        // Now we're ready to accept memory [PhysicalStart, PhysicalEnd)\r
+        if (CpusNum == 1) {\r
+          Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd);\r
+        } else {\r
+          Status = MpAcceptMemoryResourceRange (\r
+                     PhysicalStart,\r
+                     PhysicalEnd,\r
+                     APsStackStartAddress,\r
+                     CpusNum\r
+                     );\r
+        }\r
+\r
+        if (EFI_ERROR (Status)) {\r
+          ASSERT (FALSE);\r
+          break;\r
+        }\r
+\r
+        if (PhysicalEnd == AcceptMemoryEndAddress) {\r
+          break;\r
+        }\r
+      }\r
+    }\r
+\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Check the value whether in the valid list.\r
+\r
+  @param[in] Value             A value\r
+  @param[in] ValidList         A pointer to valid list\r
+  @param[in] ValidListLength   Length of valid list\r
+\r
+  @retval  TRUE   The value is in valid list.\r
+  @retval  FALSE  The value is not in valid list.\r
+\r
+**/\r
+STATIC\r
+BOOLEAN\r
+EFIAPI\r
+IsInValidList (\r
+  IN UINT32  Value,\r
+  IN UINT32  *ValidList,\r
+  IN UINT32  ValidListLength\r
+  )\r
+{\r
+  UINT32  index;\r
+\r
+  if (ValidList == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  for (index = 0; index < ValidListLength; index++) {\r
+    if (ValidList[index] == Value) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Check the integrity of VMM Hob List.\r
+\r
+  @param[in] VmmHobList   A pointer to Hob List\r
+\r
+  @retval  TRUE     The Hob List is valid.\r
+  @retval  FALSE    The Hob List is invalid.\r
+\r
+**/\r
+STATIC\r
+BOOLEAN\r
+EFIAPI\r
+ValidateHobList (\r
+  IN CONST VOID  *VmmHobList\r
+  )\r
+{\r
+  EFI_PEI_HOB_POINTERS  Hob;\r
+  UINT32                EFI_BOOT_MODE_LIST[] = {\r
+    BOOT_WITH_FULL_CONFIGURATION,\r
+    BOOT_WITH_MINIMAL_CONFIGURATION,\r
+    BOOT_ASSUMING_NO_CONFIGURATION_CHANGES,\r
+    BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS,\r
+    BOOT_WITH_DEFAULT_SETTINGS,\r
+    BOOT_ON_S4_RESUME,\r
+    BOOT_ON_S5_RESUME,\r
+    BOOT_WITH_MFG_MODE_SETTINGS,\r
+    BOOT_ON_S2_RESUME,\r
+    BOOT_ON_S3_RESUME,\r
+    BOOT_ON_FLASH_UPDATE,\r
+    BOOT_IN_RECOVERY_MODE\r
+  };\r
+\r
+  UINT32  EFI_RESOURCE_TYPE_LIST[] = {\r
+    EFI_RESOURCE_SYSTEM_MEMORY,\r
+    EFI_RESOURCE_MEMORY_MAPPED_IO,\r
+    EFI_RESOURCE_IO,\r
+    EFI_RESOURCE_FIRMWARE_DEVICE,\r
+    EFI_RESOURCE_MEMORY_MAPPED_IO_PORT,\r
+    EFI_RESOURCE_MEMORY_RESERVED,\r
+    EFI_RESOURCE_IO_RESERVED,\r
+    BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED\r
+  };\r
+\r
+  if (VmmHobList == NULL) {\r
+    DEBUG ((DEBUG_ERROR, "HOB: HOB data pointer is NULL\n"));\r
+    return FALSE;\r
+  }\r
+\r
+  Hob.Raw = (UINT8 *)VmmHobList;\r
+\r
+  //\r
+  // Parse the HOB list until end of list or matching type is found.\r
+  //\r
+  while (!END_OF_HOB_LIST (Hob)) {\r
+    if (Hob.Header->Reserved != (UINT32)0) {\r
+      DEBUG ((DEBUG_ERROR, "HOB: Hob header Reserved filed should be zero\n"));\r
+      return FALSE;\r
+    }\r
+\r
+    if (Hob.Header->HobLength == 0) {\r
+      DEBUG ((DEBUG_ERROR, "HOB: Hob header LEANGTH should not be zero\n"));\r
+      return FALSE;\r
+    }\r
+\r
+    switch (Hob.Header->HobType) {\r
+      case EFI_HOB_TYPE_HANDOFF:\r
+        if (Hob.Header->HobLength != sizeof (EFI_HOB_HANDOFF_INFO_TABLE)) {\r
+          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_HANDOFF));\r
+          return FALSE;\r
+        }\r
+\r
+        if (IsInValidList (Hob.HandoffInformationTable->BootMode, EFI_BOOT_MODE_LIST, ARRAY_SIZE (EFI_BOOT_MODE_LIST)) == FALSE) {\r
+          DEBUG ((DEBUG_ERROR, "HOB: Unknow HandoffInformationTable BootMode type. Type: 0x%08x\n", Hob.HandoffInformationTable->BootMode));\r
+          return FALSE;\r
+        }\r
+\r
+        if ((Hob.HandoffInformationTable->EfiFreeMemoryTop % 4096) != 0) {\r
+          DEBUG ((DEBUG_ERROR, "HOB: HandoffInformationTable EfiFreeMemoryTop address must be 4-KB aligned to meet page restrictions of UEFI.\\r
+                               Address: 0x%016lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop));\r
+          return FALSE;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:\r
+        if (Hob.Header->HobLength != sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {\r
+          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_RESOURCE_DESCRIPTOR));\r
+          return FALSE;\r
+        }\r
+\r
+        if (IsInValidList (Hob.ResourceDescriptor->ResourceType, EFI_RESOURCE_TYPE_LIST, ARRAY_SIZE (EFI_RESOURCE_TYPE_LIST)) == FALSE) {\r
+          DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceType type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceType));\r
+          return FALSE;\r
+        }\r
+\r
+        if ((Hob.ResourceDescriptor->ResourceAttribute & (~(EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_TESTED |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_PERSISTENT |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_16_BIT_IO |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_32_BIT_IO |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_64_BIT_IO |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_PERSISTABLE |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE |\r
+                                                            EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE))) != 0)\r
+        {\r
+          DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceAttribute type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceAttribute));\r
+          return FALSE;\r
+        }\r
+\r
+        break;\r
+\r
+      // EFI_HOB_GUID_TYPE is variable length data, so skip check\r
+      case EFI_HOB_TYPE_GUID_EXTENSION:\r
+        break;\r
+\r
+      case EFI_HOB_TYPE_FV:\r
+        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME)) {\r
+          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV));\r
+          return FALSE;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_HOB_TYPE_FV2:\r
+        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME2)) {\r
+          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV2));\r
+          return FALSE;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_HOB_TYPE_FV3:\r
+        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME3)) {\r
+          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV3));\r
+          return FALSE;\r
+        }\r
+\r
+        break;\r
+\r
+      case EFI_HOB_TYPE_CPU:\r
+        if (Hob.Header->HobLength != sizeof (EFI_HOB_CPU)) {\r
+          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_CPU));\r
+          return FALSE;\r
+        }\r
+\r
+        for (UINT32 index = 0; index < 6; index++) {\r
+          if (Hob.Cpu->Reserved[index] != 0) {\r
+            DEBUG ((DEBUG_ERROR, "HOB: Cpu Reserved field will always be set to zero.\n"));\r
+            return FALSE;\r
+          }\r
+        }\r
+\r
+        break;\r
+\r
+      default:\r
+        DEBUG ((DEBUG_ERROR, "HOB: Hob type is not know. Type: 0x%04x\n", Hob.Header->HobType));\r
+        return FALSE;\r
+    }\r
+\r
+    // Get next HOB\r
+    Hob.Raw = (UINT8 *)(Hob.Raw + Hob.Header->HobLength);\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Processing the incoming HobList for the TDX\r
+\r
+  Firmware must parse list, and accept the pages of memory before their can be\r
+  use by the guest.\r
+\r
+  @param[in] VmmHobList    The Hoblist pass the firmware\r
+\r
+  @retval  EFI_SUCCESS     Process the HobList successfully\r
+  @retval  Others          Other errors as indicated\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+ProcessHobList (\r
+  IN CONST VOID  *VmmHobList\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  UINT32                CpusNum;\r
+  EFI_PHYSICAL_ADDRESS  PhysicalEnd;\r
+  EFI_PHYSICAL_ADDRESS  APsStackStartAddress;\r
+\r
+  CpusNum = GetCpusNum ();\r
+\r
+  //\r
+  // If there are mutli-vCPU in a TDX guest, accept memory is split into 2 phases.\r
+  // Phase-1 accepts a small piece of memory by BSP. This piece of memory\r
+  // is used to setup AP's stack.\r
+  // After that phase-2 accepts a big piece of memory by BSP/APs.\r
+  //\r
+  // TDVF supports 4K and 2M accept-page-size. The memory which can be accpeted\r
+  // in 2M accept-page-size must be 2M aligned and multiple 2M. So we align\r
+  // APsStackSize to 2M size aligned.\r
+  //\r
+  if (CpusNum > 1) {\r
+    Status = AcceptMemoryForAPsStack (VmmHobList, APS_STACK_SIZE (CpusNum), &PhysicalEnd);\r
+    ASSERT (Status == EFI_SUCCESS);\r
+    APsStackStartAddress = PhysicalEnd - APS_STACK_SIZE (CpusNum);\r
+  } else {\r
+    PhysicalEnd          = 0;\r
+    APsStackStartAddress = 0;\r
+  }\r
+\r
+  Status = AcceptMemory (VmmHobList, CpusNum, APsStackStartAddress, PhysicalEnd);\r
+  ASSERT (Status == EFI_SUCCESS);\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
   In Tdx guest, some information need to be passed from host VMM to guest\r
   firmware. For example, the memory resource, etc. These information are\r
@@ -49,7 +772,36 @@ TdxHelperProcessTdHob (
   VOID\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_STATUS      Status;\r
+  VOID            *TdHob;\r
+  TD_RETURN_DATA  TdReturnData;\r
+\r
+  TdHob  = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);\r
+  Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  DEBUG ((\r
+    DEBUG_INFO,\r
+    "Intel Tdx Started with (GPAW: %d, Cpus: %d)\n",\r
+    TdReturnData.TdInfo.Gpaw,\r
+    TdReturnData.TdInfo.NumVcpus\r
+    ));\r
+\r
+  //\r
+  // Validate HobList\r
+  //\r
+  if (ValidateHobList (TdHob) == FALSE) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Process Hoblist to accept memory\r
+  //\r
+  Status = ProcessHobList (TdHob);\r
+\r
+  return Status;\r
 }\r
 \r
 /**\r
index 6cb63139cba0da5858afe15ae36294053983227a..ada8592ddd5a5c7d3b461b2e3ea462ef4e59973f 100644 (file)
 #include <Library/MemoryAllocationLib.h>\r
 #include <IndustryStandard/Tdx.h>\r
 #include <IndustryStandard/IntelTdx.h>\r
-#include <IndustryStandard/QemuFwCfg.h>\r
-#include <Library/QemuFwCfgLib.h>\r
 #include <Library/PeiServicesLib.h>\r
-#include <Library/TdxLib.h>\r
-#include <Library/TdxMailboxLib.h>\r
-#include <Library/SynchronizationLib.h>\r
 #include <Pi/PrePiHob.h>\r
 #include <WorkArea.h>\r
 #include <ConfidentialComputingGuestAttr.h>\r
 \r
-#define ALIGNED_2MB_MASK  0x1fffff\r
-#define MEGABYTE_SHIFT    20\r
-\r
-#define ACCEPT_CHUNK_SIZE  SIZE_32MB\r
-#define AP_STACK_SIZE      SIZE_16KB\r
-#define APS_STACK_SIZE(CpusNum)  (ALIGN_VALUE(CpusNum*AP_STACK_SIZE, SIZE_2MB))\r
-\r
-/**\r
-  This function will be called to accept pages. Only BSP accepts pages.\r
-\r
-  TDCALL(ACCEPT_PAGE) supports the accept page size of 4k and 2M. To\r
-  simplify the implementation, the Memory to be accpeted is splitted\r
-  into 3 parts:\r
-  -----------------  <-- StartAddress1 (not 2M aligned)\r
-  |  part 1       |      Length1 < 2M\r
-  |---------------|  <-- StartAddress2 (2M aligned)\r
-  |               |      Length2 = Integer multiples of 2M\r
-  |  part 2       |\r
-  |               |\r
-  |---------------|  <-- StartAddress3\r
-  |  part 3       |      Length3 < 2M\r
-  |---------------|\r
-\r
-  @param[in] PhysicalAddress   Start physical adress\r
-  @param[in] PhysicalEnd       End physical address\r
-\r
-  @retval    EFI_SUCCESS       Accept memory successfully\r
-  @retval    Others            Other errors as indicated\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BspAcceptMemoryResourceRange (\r
-  IN EFI_PHYSICAL_ADDRESS  PhysicalAddress,\r
-  IN EFI_PHYSICAL_ADDRESS  PhysicalEnd\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINT32      AcceptPageSize;\r
-  UINT64      StartAddress1;\r
-  UINT64      StartAddress2;\r
-  UINT64      StartAddress3;\r
-  UINT64      TotalLength;\r
-  UINT64      Length1;\r
-  UINT64      Length2;\r
-  UINT64      Length3;\r
-  UINT64      Pages;\r
-\r
-  AcceptPageSize = FixedPcdGet32 (PcdTdxAcceptPageSize);\r
-  TotalLength    = PhysicalEnd - PhysicalAddress;\r
-  StartAddress1  = 0;\r
-  StartAddress2  = 0;\r
-  StartAddress3  = 0;\r
-  Length1        = 0;\r
-  Length2        = 0;\r
-  Length3        = 0;\r
-\r
-  if (TotalLength == 0) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (ALIGN_VALUE (PhysicalAddress, SIZE_2MB) != PhysicalAddress) {\r
-    StartAddress1 = PhysicalAddress;\r
-    Length1       = ALIGN_VALUE (PhysicalAddress, SIZE_2MB) - PhysicalAddress;\r
-    if (Length1 >= TotalLength) {\r
-      Length1 = TotalLength;\r
-    }\r
-\r
-    PhysicalAddress += Length1;\r
-    TotalLength     -= Length1;\r
-  }\r
-\r
-  if (TotalLength > SIZE_2MB) {\r
-    StartAddress2    = PhysicalAddress;\r
-    Length2          = TotalLength & ~(UINT64)ALIGNED_2MB_MASK;\r
-    PhysicalAddress += Length2;\r
-    TotalLength     -= Length2;\r
-  }\r
-\r
-  if (TotalLength) {\r
-    StartAddress3 = PhysicalAddress;\r
-    Length3       = TotalLength;\r
-  }\r
-\r
-  Status = EFI_SUCCESS;\r
-  if (Length1 > 0) {\r
-    Pages  = Length1 / SIZE_4KB;\r
-    Status = TdAcceptPages (StartAddress1, Pages, SIZE_4KB);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  if (Length2 > 0) {\r
-    Pages  = Length2 / AcceptPageSize;\r
-    Status = TdAcceptPages (StartAddress2, Pages, AcceptPageSize);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  if (Length3 > 0) {\r
-    Pages  = Length3 / SIZE_4KB;\r
-    Status = TdAcceptPages (StartAddress3, Pages, SIZE_4KB);\r
-    ASSERT (!EFI_ERROR (Status));\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
- * This function is called by BSP and APs to accept memory.\r
- * Note:\r
- * The input PhysicalStart/PhysicalEnd indicates the whole memory region\r
- * to be accepted. BSP or AP only accepts one piece in the whole memory region.\r
- *\r
- * @param CpuIndex        vCPU index\r
- * @param CpusNum         Total vCPU number of a Tdx guest\r
- * @param PhysicalStart   Start address of a memory region which is to be accepted\r
- * @param PhysicalEnd     End address of a memory region which is to be accepted\r
- *\r
- * @retval EFI_SUCCESS    Successfully accept the memory\r
- * @retval Other          Other errors as indicated\r
- */\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-BspApAcceptMemoryResourceRange (\r
-  UINT32                CpuIndex,\r
-  UINT32                CpusNum,\r
-  EFI_PHYSICAL_ADDRESS  PhysicalStart,\r
-  EFI_PHYSICAL_ADDRESS  PhysicalEnd\r
-  )\r
-{\r
-  UINT64                Status;\r
-  UINT64                Pages;\r
-  UINT64                Stride;\r
-  UINT64                AcceptPageSize;\r
-  EFI_PHYSICAL_ADDRESS  PhysicalAddress;\r
-\r
-  AcceptPageSize = (UINT64)(UINTN)FixedPcdGet32 (PcdTdxAcceptPageSize);\r
-\r
-  Status          = EFI_SUCCESS;\r
-  Stride          = (UINTN)CpusNum * ACCEPT_CHUNK_SIZE;\r
-  PhysicalAddress = PhysicalStart + ACCEPT_CHUNK_SIZE * (UINTN)CpuIndex;\r
-\r
-  while (!EFI_ERROR (Status) && PhysicalAddress < PhysicalEnd) {\r
-    Pages  = MIN (ACCEPT_CHUNK_SIZE, PhysicalEnd - PhysicalAddress) / AcceptPageSize;\r
-    Status = TdAcceptPages (PhysicalAddress, Pages, (UINT32)(UINTN)AcceptPageSize);\r
-    ASSERT (!EFI_ERROR (Status));\r
-    PhysicalAddress += Stride;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- * This function is called by APs to accept memory.\r
- *\r
- * @param CpuIndex        vCPU index of an AP\r
- * @param PhysicalStart   Start address of a memory region which is to be accepted\r
- * @param PhysicalEnd     End address of a memory region which is to be accepted\r
- *\r
- * @retval EFI_SUCCESS    Successfully accept the memory\r
- * @retval Others         Other errors as indicated\r
- */\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-ApAcceptMemoryResourceRange (\r
-  UINT32                CpuIndex,\r
-  EFI_PHYSICAL_ADDRESS  PhysicalStart,\r
-  EFI_PHYSICAL_ADDRESS  PhysicalEnd\r
-  )\r
-{\r
-  UINT64          Status;\r
-  TD_RETURN_DATA  TdReturnData;\r
-\r
-  Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);\r
-  if (Status != TDX_EXIT_REASON_SUCCESS) {\r
-    ASSERT (FALSE);\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  if ((CpuIndex == 0) || (CpuIndex >= TdReturnData.TdInfo.NumVcpus)) {\r
-    ASSERT (FALSE);\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  return BspApAcceptMemoryResourceRange (CpuIndex, TdReturnData.TdInfo.NumVcpus, PhysicalStart, PhysicalEnd);\r
-}\r
-\r
-/**\r
- * This function is called by BSP. It coordinates BSP/APs to accept memory together.\r
- *\r
- * @param PhysicalStart     Start address of a memory region which is to be accepted\r
- * @param PhysicalEnd       End address of a memory region which is to be accepted\r
- * @param APsStackAddress   APs stack address\r
- * @param CpusNum           Total vCPU number of the Tdx guest\r
- *\r
- * @retval EFI_SUCCESS      Successfully accept the memory\r
- * @retval Others           Other errors as indicated\r
- */\r
-EFI_STATUS\r
-EFIAPI\r
-MpAcceptMemoryResourceRange (\r
-  IN EFI_PHYSICAL_ADDRESS      PhysicalStart,\r
-  IN EFI_PHYSICAL_ADDRESS      PhysicalEnd,\r
-  IN OUT EFI_PHYSICAL_ADDRESS  APsStackAddress,\r
-  IN UINT32                    CpusNum\r
-  )\r
-{\r
-  UINT64      Length;\r
-  EFI_STATUS  Status;\r
-\r
-  Length = PhysicalEnd - PhysicalStart;\r
-\r
-  DEBUG ((DEBUG_INFO, "MpAccept : 0x%llx - 0x%llx (0x%llx)\n", PhysicalStart, PhysicalEnd, Length));\r
-\r
-  if (Length == 0) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // The start address is not 2M aligned. BSP first accept the part which is not 2M aligned.\r
-  //\r
-  if (ALIGN_VALUE (PhysicalStart, SIZE_2MB) != PhysicalStart) {\r
-    Length = MIN (ALIGN_VALUE (PhysicalStart, SIZE_2MB) - PhysicalStart, Length);\r
-    Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalStart + Length);\r
-    ASSERT (Status == EFI_SUCCESS);\r
-\r
-    PhysicalStart += Length;\r
-    Length         = PhysicalEnd - PhysicalStart;\r
-  }\r
-\r
-  if (Length == 0) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // BSP will accept the memory by itself if the memory is not big enough compared with a chunk.\r
-  //\r
-  if (Length <= ACCEPT_CHUNK_SIZE) {\r
-    return BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd);\r
-  }\r
-\r
-  //\r
-  // Now APs are asked to accept the memory together.\r
-  //\r
-  MpSerializeStart ();\r
-\r
-  MpSendWakeupCommand (\r
-    MpProtectedModeWakeupCommandAcceptPages,\r
-    (UINT64)(UINTN)ApAcceptMemoryResourceRange,\r
-    PhysicalStart,\r
-    PhysicalEnd,\r
-    APsStackAddress,\r
-    AP_STACK_SIZE\r
-    );\r
-\r
-  //\r
-  // Now BSP does its job.\r
-  //\r
-  BspApAcceptMemoryResourceRange (0, CpusNum, PhysicalStart, PhysicalEnd);\r
-\r
-  MpSerializeEnd ();\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  BSP accept a small piece of memory which will be used as APs stack.\r
-\r
-  @param[in] VmmHobList    The Hoblist pass the firmware\r
-  @param[in] APsStackSize  APs stack size\r
-  @param[out] PhysicalAddressEnd    The physical end address of accepted memory in phase-1\r
-\r
-  @retval  EFI_SUCCESS     Process the HobList successfully\r
-  @retval  Others          Other errors as indicated\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AcceptMemoryForAPsStack (\r
-  IN CONST VOID             *VmmHobList,\r
-  IN UINT32                 APsStackSize,\r
-  OUT EFI_PHYSICAL_ADDRESS  *PhysicalAddressEnd\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  EFI_PEI_HOB_POINTERS  Hob;\r
-  EFI_PHYSICAL_ADDRESS  PhysicalEnd;\r
-  EFI_PHYSICAL_ADDRESS  PhysicalStart;\r
-  UINT64                ResourceLength;\r
-  BOOLEAN               MemoryRegionFound;\r
-\r
-  ASSERT (VmmHobList != NULL);\r
-\r
-  Status            = EFI_SUCCESS;\r
-  Hob.Raw           = (UINT8 *)VmmHobList;\r
-  MemoryRegionFound = FALSE;\r
-\r
-  DEBUG ((DEBUG_INFO, "AcceptMemoryForAPsStack with APsStackSize=0x%x\n", APsStackSize));\r
-\r
-  //\r
-  // Parse the HOB list until end of list or matching type is found.\r
-  //\r
-  while (!END_OF_HOB_LIST (Hob) && !MemoryRegionFound) {\r
-    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
-      DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));\r
-\r
-      if (Hob.ResourceDescriptor->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {\r
-        ResourceLength = Hob.ResourceDescriptor->ResourceLength;\r
-        PhysicalStart  = Hob.ResourceDescriptor->PhysicalStart;\r
-        PhysicalEnd    = PhysicalStart + ResourceLength;\r
-\r
-        DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));\r
-        DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", PhysicalStart));\r
-        DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", ResourceLength));\r
-        DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));\r
-\r
-        if (ResourceLength >= APsStackSize) {\r
-          MemoryRegionFound = TRUE;\r
-          if (ResourceLength > ACCEPT_CHUNK_SIZE) {\r
-            PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + APsStackSize;\r
-          }\r
-        }\r
-\r
-        Status = BspAcceptMemoryResourceRange (\r
-                   Hob.ResourceDescriptor->PhysicalStart,\r
-                   PhysicalEnd\r
-                   );\r
-        if (EFI_ERROR (Status)) {\r
-          break;\r
-        }\r
-      }\r
-    }\r
-\r
-    Hob.Raw = GET_NEXT_HOB (Hob);\r
-  }\r
-\r
-  ASSERT (MemoryRegionFound);\r
-  *PhysicalAddressEnd = PhysicalEnd;\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  BSP and APs work togeter to accept memory which is under the address of 4G.\r
-\r
-  @param[in] VmmHobList           The Hoblist pass the firmware\r
-  @param[in] CpusNum              Number of vCPUs\r
-  @param[in] APsStackStartAddres  Start address of APs stack\r
-  @param[in] PhysicalAddressStart Start physical address which to be accepted\r
-\r
-  @retval  EFI_SUCCESS     Process the HobList successfully\r
-  @retval  Others          Other errors as indicated\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AcceptMemory (\r
-  IN CONST VOID            *VmmHobList,\r
-  IN UINT32                CpusNum,\r
-  IN EFI_PHYSICAL_ADDRESS  APsStackStartAddress,\r
-  IN EFI_PHYSICAL_ADDRESS  PhysicalAddressStart\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  EFI_PEI_HOB_POINTERS  Hob;\r
-  EFI_PHYSICAL_ADDRESS  PhysicalStart;\r
-  EFI_PHYSICAL_ADDRESS  PhysicalEnd;\r
-  EFI_PHYSICAL_ADDRESS  AcceptMemoryEndAddress;\r
-\r
-  Status                 = EFI_SUCCESS;\r
-  AcceptMemoryEndAddress = BASE_4GB;\r
-\r
-  ASSERT (VmmHobList != NULL);\r
-  Hob.Raw = (UINT8 *)VmmHobList;\r
-\r
-  DEBUG ((DEBUG_INFO, "AcceptMemory under address of 4G\n"));\r
-\r
-  //\r
-  // Parse the HOB list until end of list or matching type is found.\r
-  //\r
-  while (!END_OF_HOB_LIST (Hob)) {\r
-    if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
-      if (Hob.ResourceDescriptor->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {\r
-        PhysicalStart = Hob.ResourceDescriptor->PhysicalStart;\r
-        PhysicalEnd   = PhysicalStart + Hob.ResourceDescriptor->ResourceLength;\r
-\r
-        if (PhysicalEnd <= PhysicalAddressStart) {\r
-          // this memory region has been accepted. Skipped it.\r
-          Hob.Raw = GET_NEXT_HOB (Hob);\r
-          continue;\r
-        }\r
-\r
-        if (PhysicalStart >= AcceptMemoryEndAddress) {\r
-          // this memory region is not to be accepted. And we're done.\r
-          break;\r
-        }\r
-\r
-        if (PhysicalStart >= PhysicalAddressStart) {\r
-          // this memory region has not been acceted.\r
-        } else if ((PhysicalStart < PhysicalAddressStart) && (PhysicalEnd > PhysicalAddressStart)) {\r
-          // part of the memory region has been accepted.\r
-          PhysicalStart = PhysicalAddressStart;\r
-        }\r
-\r
-        // then compare the PhysicalEnd with AcceptMemoryEndAddress\r
-        if (PhysicalEnd >= AcceptMemoryEndAddress) {\r
-          PhysicalEnd = AcceptMemoryEndAddress;\r
-        }\r
-\r
-        DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));\r
-        DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", Hob.ResourceDescriptor->PhysicalStart));\r
-        DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", Hob.ResourceDescriptor->ResourceLength));\r
-        DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));\r
-\r
-        // Now we're ready to accept memory [PhysicalStart, PhysicalEnd)\r
-        if (CpusNum == 1) {\r
-          Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd);\r
-        } else {\r
-          Status = MpAcceptMemoryResourceRange (\r
-                     PhysicalStart,\r
-                     PhysicalEnd,\r
-                     APsStackStartAddress,\r
-                     CpusNum\r
-                     );\r
-        }\r
-\r
-        if (EFI_ERROR (Status)) {\r
-          ASSERT (FALSE);\r
-          break;\r
-        }\r
-\r
-        if (PhysicalEnd == AcceptMemoryEndAddress) {\r
-          break;\r
-        }\r
-      }\r
-    }\r
-\r
-    Hob.Raw = GET_NEXT_HOB (Hob);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Check the value whether in the valid list.\r
-\r
-  @param[in] Value             A value\r
-  @param[in] ValidList         A pointer to valid list\r
-  @param[in] ValidListLength   Length of valid list\r
-\r
-  @retval  TRUE   The value is in valid list.\r
-  @retval  FALSE  The value is not in valid list.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-IsInValidList (\r
-  IN UINT32  Value,\r
-  IN UINT32  *ValidList,\r
-  IN UINT32  ValidListLength\r
-  )\r
-{\r
-  UINT32  index;\r
-\r
-  if (ValidList == NULL) {\r
-    return FALSE;\r
-  }\r
-\r
-  for (index = 0; index < ValidListLength; index++) {\r
-    if (ValidList[index] == Value) {\r
-      return TRUE;\r
-    }\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Check the integrity of VMM Hob List.\r
-\r
-  @param[in] VmmHobList   A pointer to Hob List\r
-\r
-  @retval  TRUE     The Hob List is valid.\r
-  @retval  FALSE    The Hob List is invalid.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-ValidateHobList (\r
-  IN CONST VOID  *VmmHobList\r
-  )\r
-{\r
-  EFI_PEI_HOB_POINTERS  Hob;\r
-  UINT32                EFI_BOOT_MODE_LIST[] = {\r
-    BOOT_WITH_FULL_CONFIGURATION,\r
-    BOOT_WITH_MINIMAL_CONFIGURATION,\r
-    BOOT_ASSUMING_NO_CONFIGURATION_CHANGES,\r
-    BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS,\r
-    BOOT_WITH_DEFAULT_SETTINGS,\r
-    BOOT_ON_S4_RESUME,\r
-    BOOT_ON_S5_RESUME,\r
-    BOOT_WITH_MFG_MODE_SETTINGS,\r
-    BOOT_ON_S2_RESUME,\r
-    BOOT_ON_S3_RESUME,\r
-    BOOT_ON_FLASH_UPDATE,\r
-    BOOT_IN_RECOVERY_MODE\r
-  };\r
-\r
-  UINT32  EFI_RESOURCE_TYPE_LIST[] = {\r
-    EFI_RESOURCE_SYSTEM_MEMORY,\r
-    EFI_RESOURCE_MEMORY_MAPPED_IO,\r
-    EFI_RESOURCE_IO,\r
-    EFI_RESOURCE_FIRMWARE_DEVICE,\r
-    EFI_RESOURCE_MEMORY_MAPPED_IO_PORT,\r
-    EFI_RESOURCE_MEMORY_RESERVED,\r
-    EFI_RESOURCE_IO_RESERVED,\r
-    BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED\r
-  };\r
-\r
-  if (VmmHobList == NULL) {\r
-    DEBUG ((DEBUG_ERROR, "HOB: HOB data pointer is NULL\n"));\r
-    return FALSE;\r
-  }\r
-\r
-  Hob.Raw = (UINT8 *)VmmHobList;\r
-\r
-  //\r
-  // Parse the HOB list until end of list or matching type is found.\r
-  //\r
-  while (!END_OF_HOB_LIST (Hob)) {\r
-    if (Hob.Header->Reserved != (UINT32)0) {\r
-      DEBUG ((DEBUG_ERROR, "HOB: Hob header Reserved filed should be zero\n"));\r
-      return FALSE;\r
-    }\r
-\r
-    if (Hob.Header->HobLength == 0) {\r
-      DEBUG ((DEBUG_ERROR, "HOB: Hob header LEANGTH should not be zero\n"));\r
-      return FALSE;\r
-    }\r
-\r
-    switch (Hob.Header->HobType) {\r
-      case EFI_HOB_TYPE_HANDOFF:\r
-        if (Hob.Header->HobLength != sizeof (EFI_HOB_HANDOFF_INFO_TABLE)) {\r
-          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_HANDOFF));\r
-          return FALSE;\r
-        }\r
-\r
-        if (IsInValidList (Hob.HandoffInformationTable->BootMode, EFI_BOOT_MODE_LIST, ARRAY_SIZE (EFI_BOOT_MODE_LIST)) == FALSE) {\r
-          DEBUG ((DEBUG_ERROR, "HOB: Unknow HandoffInformationTable BootMode type. Type: 0x%08x\n", Hob.HandoffInformationTable->BootMode));\r
-          return FALSE;\r
-        }\r
-\r
-        if ((Hob.HandoffInformationTable->EfiFreeMemoryTop % 4096) != 0) {\r
-          DEBUG ((DEBUG_ERROR, "HOB: HandoffInformationTable EfiFreeMemoryTop address must be 4-KB aligned to meet page restrictions of UEFI.\\r
-                               Address: 0x%016lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop));\r
-          return FALSE;\r
-        }\r
-\r
-        break;\r
-\r
-      case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:\r
-        if (Hob.Header->HobLength != sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {\r
-          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_RESOURCE_DESCRIPTOR));\r
-          return FALSE;\r
-        }\r
-\r
-        if (IsInValidList (Hob.ResourceDescriptor->ResourceType, EFI_RESOURCE_TYPE_LIST, ARRAY_SIZE (EFI_RESOURCE_TYPE_LIST)) == FALSE) {\r
-          DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceType type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceType));\r
-          return FALSE;\r
-        }\r
-\r
-        if ((Hob.ResourceDescriptor->ResourceAttribute & (~(EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_TESTED |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_PERSISTENT |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_16_BIT_IO |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_32_BIT_IO |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_64_BIT_IO |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_PERSISTABLE |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE |\r
-                                                            EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE))) != 0)\r
-        {\r
-          DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceAttribute type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceAttribute));\r
-          return FALSE;\r
-        }\r
-\r
-        break;\r
-\r
-      // EFI_HOB_GUID_TYPE is variable length data, so skip check\r
-      case EFI_HOB_TYPE_GUID_EXTENSION:\r
-        break;\r
-\r
-      case EFI_HOB_TYPE_FV:\r
-        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME)) {\r
-          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV));\r
-          return FALSE;\r
-        }\r
-\r
-        break;\r
-\r
-      case EFI_HOB_TYPE_FV2:\r
-        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME2)) {\r
-          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV2));\r
-          return FALSE;\r
-        }\r
-\r
-        break;\r
-\r
-      case EFI_HOB_TYPE_FV3:\r
-        if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME3)) {\r
-          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV3));\r
-          return FALSE;\r
-        }\r
-\r
-        break;\r
-\r
-      case EFI_HOB_TYPE_CPU:\r
-        if (Hob.Header->HobLength != sizeof (EFI_HOB_CPU)) {\r
-          DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_CPU));\r
-          return FALSE;\r
-        }\r
-\r
-        for (UINT32 index = 0; index < 6; index++) {\r
-          if (Hob.Cpu->Reserved[index] != 0) {\r
-            DEBUG ((DEBUG_ERROR, "HOB: Cpu Reserved field will always be set to zero.\n"));\r
-            return FALSE;\r
-          }\r
-        }\r
-\r
-        break;\r
-\r
-      default:\r
-        DEBUG ((DEBUG_ERROR, "HOB: Hob type is not know. Type: 0x%04x\n", Hob.Header->HobType));\r
-        return FALSE;\r
-    }\r
-\r
-    // Get next HOB\r
-    Hob.Raw = (UINT8 *)(Hob.Raw + Hob.Header->HobLength);\r
-  }\r
-\r
-  return TRUE;\r
-}\r
-\r
-/**\r
-  Processing the incoming HobList for the TDX\r
-\r
-  Firmware must parse list, and accept the pages of memory before their can be\r
-  use by the guest.\r
-\r
-  @param[in] VmmHobList    The Hoblist pass the firmware\r
-\r
-  @retval  EFI_SUCCESS     Process the HobList successfully\r
-  @retval  Others          Other errors as indicated\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessHobList (\r
-  IN CONST VOID  *VmmHobList\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  UINT32                CpusNum;\r
-  EFI_PHYSICAL_ADDRESS  PhysicalEnd;\r
-  EFI_PHYSICAL_ADDRESS  APsStackStartAddress;\r
-\r
-  CpusNum = GetCpusNum ();\r
-\r
-  //\r
-  // If there are mutli-vCPU in a TDX guest, accept memory is split into 2 phases.\r
-  // Phase-1 accepts a small piece of memory by BSP. This piece of memory\r
-  // is used to setup AP's stack.\r
-  // After that phase-2 accepts a big piece of memory by BSP/APs.\r
-  //\r
-  // TDVF supports 4K and 2M accept-page-size. The memory which can be accpeted\r
-  // in 2M accept-page-size must be 2M aligned and multiple 2M. So we align\r
-  // APsStackSize to 2M size aligned.\r
-  //\r
-  if (CpusNum > 1) {\r
-    Status = AcceptMemoryForAPsStack (VmmHobList, APS_STACK_SIZE (CpusNum), &PhysicalEnd);\r
-    ASSERT (Status == EFI_SUCCESS);\r
-    APsStackStartAddress = PhysicalEnd - APS_STACK_SIZE (CpusNum);\r
-  } else {\r
-    PhysicalEnd          = 0;\r
-    APsStackStartAddress = 0;\r
-  }\r
-\r
-  Status = AcceptMemory (VmmHobList, CpusNum, APsStackStartAddress, PhysicalEnd);\r
-  ASSERT (Status == EFI_SUCCESS);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  In Tdx guest, some information need to be passed from host VMM to guest\r
-  firmware. For example, the memory resource, etc. These information are\r
-  prepared by host VMM and put in HobList which is described in TdxMetadata.\r
-\r
-  Information in HobList is treated as external input. From the security\r
-  perspective before it is consumed, it should be validated.\r
-\r
-  @retval   EFI_SUCCESS   Successfully process the hoblist\r
-  @retval   Others        Other error as indicated\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessTdxHobList (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS      Status;\r
-  VOID            *TdHob;\r
-  TD_RETURN_DATA  TdReturnData;\r
-\r
-  TdHob  = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);\r
-  Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  DEBUG ((\r
-    DEBUG_INFO,\r
-    "Intel Tdx Started with (GPAW: %d, Cpus: %d)\n",\r
-    TdReturnData.TdInfo.Gpaw,\r
-    TdReturnData.TdInfo.NumVcpus\r
-    ));\r
-\r
-  //\r
-  // Validate HobList\r
-  //\r
-  if (ValidateHobList (TdHob) == FALSE) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Process Hoblist to accept memory\r
-  //\r
-  Status = ProcessHobList (TdHob);\r
-\r
-  return Status;\r
-}\r
-\r
 /**\r
  * Build ResourceDescriptorHob for the unaccepted memory region.\r
  * This memory region may be splitted into 2 parts because of lazy accept.\r
index 3ebe582af8de448f8dcf93e533c00f46900b057f..7a7c2fb1f6f5eb961873bd4232ac92d836bd0b47 100644 (file)
@@ -9,26 +9,6 @@
 \r
 #include <PiPei.h>\r
 \r
-/**\r
-  In Tdx guest, some information need to be passed from host VMM to guest\r
-  firmware. For example, the memory resource, etc. These information are\r
-  prepared by host VMM and put in HobList which is described in TdxMetadata.\r
-\r
-  Information in HobList is treated as external input. From the security\r
-  perspective before it is consumed, it should be validated.\r
-\r
-  @retval   EFI_SUCCESS   Successfully process the hoblist\r
-  @retval   Others        Other error as indicated\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ProcessTdxHobList (\r
-  VOID\r
-  )\r
-{\r
-  return EFI_UNSUPPORTED;\r
-}\r
-\r
 /**\r
   In Tdx guest, the system memory is passed in TdHob by host VMM. So\r
   the major task of PlatformTdxPublishRamRegions is to walk thru the\r
index 140216979a54757480af035ffb48b6504a7d8a62..86a82ad3e084f5b8a2335a5c34e87faab622f221 100644 (file)
@@ -52,7 +52,6 @@
   PcdLib\r
   PciLib\r
   PeiHardwareInfoLib\r
-  TdxMailboxLib\r
 \r
 [LibraryClasses.X64]\r
   TdxLib\r
index 3f970a79a08affaeddb4f497bb180eca1b038315..d87013a4422c7ddad274502e080ff2607b081f84 100644 (file)
   OvmfPkg/Sec/SecMain.inf {\r
     <LibraryClasses>\r
       NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf\r
-      NULL|OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf\r
+      NULL|OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf\r
+      BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf\r
   }\r
 \r
   #\r
index 1167d22a68cc0e75268fd2f1a4cddfc993592ab2..a27dc9406b7080c13677bdd1acd3bd228b6ffc64 100644 (file)
@@ -29,7 +29,7 @@
 #include <Library/CpuExceptionHandlerLib.h>\r
 #include <Ppi/TemporaryRamSupport.h>\r
 #include <Ppi/MpInitLibDep.h>\r
-#include <Library/PlatformInitLib.h>\r
+#include <Library/TdxHelperLib.h>\r
 #include <Library/CcProbeLib.h>\r
 #include "AmdSev.h"\r
 \r
@@ -765,7 +765,7 @@ SecCoreStartupWithStack (
     // first so that the memory is accepted. Otherwise access to the unaccepted\r
     // memory will trigger tripple fault.\r
     //\r
-    if (ProcessTdxHobList () != EFI_SUCCESS) {\r
+    if (TdxHelperProcessTdHob () != EFI_SUCCESS) {\r
       CpuDeadLoop ();\r
     }\r
   }\r