[edk2-devel] [PATCH V3 24/29] OvmfPkg: Update PlatformPei to support TDX

Min Xu min.m.xu at intel.com
Mon Nov 1 13:16:13 UTC 2021


RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429

Intel TDX has its own requirement in InitializePlatform (PlatformPei).
1. Publish the ram region
  Host VMM pass the memory region to TDVF in TD Hob. These memory
  are accepted by TDVF before they're available for access. TDVF
  publish these memory information in the final hoblist for DXE.
2. Relocate mailbox
  At the beginning of system boot, a 4K-aligned, 4K-size memory (Td
  mailbox) is pre-allocated by host VMM. BSP & APs do the page accept
  together in that memory region.
  After that TDVF is designed to relocate the mailbox to a 4K-aligned,
  4K-size memory block which is allocated in the ACPI Nvs memory. APs
  are waken up and spin around the relocated mailbox waiting for
  further command.
3. Create PlatformInfoHob
  PlatformInfoHob contains the TDX specific information, for example,
  the relocated Mailbox address. gUefiOvmfPkgTdxPlatformGuid is the new
  GUID added in OvmfPkg.dec for this purpose.

Cc: Ard Biesheuvel <ardb+tianocore at kernel.org>
Cc: Jordan Justen <jordan.l.justen at intel.com>
Cc: Brijesh Singh <brijesh.singh at amd.com>
Cc: Erdem Aktas <erdemaktas at google.com>
Cc: James Bottomley <jejb at linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao at intel.com>
Cc: Tom Lendacky <thomas.lendacky at amd.com>
Cc: Gerd Hoffmann <kraxel at redhat.com>
Signed-off-by: Min Xu <min.m.xu at intel.com>
---
 OvmfPkg/OvmfPkg.dec                    |   1 +
 OvmfPkg/OvmfPkgX64.dsc                 |   2 +
 OvmfPkg/PlatformPei/FeatureControl.c   |   8 +-
 OvmfPkg/PlatformPei/IntelTdx.c         | 290 +++++++++++++++++++++++++
 OvmfPkg/PlatformPei/IntelTdxNull.c     |  49 +++++
 OvmfPkg/PlatformPei/MemDetect.c        |  57 +++--
 OvmfPkg/PlatformPei/Platform.c         |   1 +
 OvmfPkg/PlatformPei/Platform.h         |  28 +++
 OvmfPkg/PlatformPei/PlatformPei.inf    |  14 ++
 OvmfPkg/PlatformPei/X64/ApRunLoop.nasm |  83 +++++++
 10 files changed, 519 insertions(+), 14 deletions(-)
 create mode 100644 OvmfPkg/PlatformPei/IntelTdx.c
 create mode 100644 OvmfPkg/PlatformPei/IntelTdxNull.c
 create mode 100644 OvmfPkg/PlatformPei/X64/ApRunLoop.nasm

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index ccf8fc33ce27..e8cd126fc161 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -128,6 +128,7 @@
   gQemuKernelLoaderFsMediaGuid          = {0x1428f772, 0xb64a, 0x441e, {0xb8, 0xc3, 0x9e, 0xbd, 0xd7, 0xf8, 0x93, 0xc7}}
   gGrubFileGuid                         = {0xb5ae312c, 0xbc8a, 0x43b1, {0x9c, 0x62, 0xeb, 0xb8, 0x26, 0xdd, 0x5d, 0x07}}
   gConfidentialComputingSecretGuid      = {0xadf956ad, 0xe98c, 0x484c, {0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47}}
+  gUefiOvmfPkgTdxPlatformGuid           = {0xdec9b486, 0x1f16, 0x47c7, {0x8f, 0x68, 0xdf, 0x1a, 0x41, 0x88, 0x8b, 0xa5}}
 
 [Ppis]
   # PPI whose presence in the PPI database signals that the TPM base address
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 3eb29811d822..850953f20e35 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -664,6 +664,8 @@
   gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 !endif
 
+  gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr|0
+
   # IPv4 and IPv6 PXE Boot support.
   gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
   gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
diff --git a/OvmfPkg/PlatformPei/FeatureControl.c b/OvmfPkg/PlatformPei/FeatureControl.c
index dccf9505dd7b..cf1a25722704 100644
--- a/OvmfPkg/PlatformPei/FeatureControl.c
+++ b/OvmfPkg/PlatformPei/FeatureControl.c
@@ -12,6 +12,8 @@
 #include <Library/QemuFwCfgLib.h>
 #include <Ppi/MpServices.h>
 #include <Register/ArchitecturalMsr.h>
+#include <Library/TdxLib.h>
+#include <IndustryStandard/Tdx.h>
 
 #include "Platform.h"
 
@@ -37,7 +39,11 @@ WriteFeatureControl (
   IN OUT VOID *WorkSpace
   )
 {
-  AsmWriteMsr64 (MSR_IA32_FEATURE_CONTROL, mFeatureControlValue);
+  if (PlatformPeiIsTdxGuest ()) {
+    TdVmCall (TDVMCALL_WRMSR, (UINT64) MSR_IA32_FEATURE_CONTROL, mFeatureControlValue, 0, 0, 0);
+  } else {
+    AsmWriteMsr64 (MSR_IA32_FEATURE_CONTROL, mFeatureControlValue);
+  }
 }
 
 /**
diff --git a/OvmfPkg/PlatformPei/IntelTdx.c b/OvmfPkg/PlatformPei/IntelTdx.c
new file mode 100644
index 000000000000..3ca5161a0c44
--- /dev/null
+++ b/OvmfPkg/PlatformPei/IntelTdx.c
@@ -0,0 +1,290 @@
+/** @file
+  Initialize Intel TDX support.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/TdxMailboxLib.h>
+#include <IndustryStandard/Tdx.h>
+#include <IndustryStandard/IntelTdx.h>
+#include <IndustryStandard/QemuFwCfg.h>
+#include <Library/QemuFwCfgLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/TdxLib.h>
+#include <WorkArea.h>
+#include <ConfidentialComputingGuestAttr.h>
+#include "Platform.h"
+
+/**
+  Check if it is Tdx guest
+
+  @retval    TRUE   It is Tdx guest
+  @retval    FALSE  It is not Tdx guest
+**/
+BOOLEAN
+PlatformPeiIsTdxGuest (
+  VOID
+  )
+{
+  CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER   *CcWorkAreaHeader;
+
+  CcWorkAreaHeader = (CONFIDENTIAL_COMPUTING_WORK_AREA_HEADER *) FixedPcdGet32 (PcdOvmfWorkAreaBase);
+  return (CcWorkAreaHeader != NULL && CcWorkAreaHeader->GuestType == GUEST_TYPE_INTEL_TDX);
+}
+
+
+VOID
+EFIAPI
+DEBUG_HOBLIST (
+  IN CONST VOID             *HobStart
+  )
+{
+  EFI_PEI_HOB_POINTERS  Hob;
+  Hob.Raw = (UINT8 *) HobStart;
+  //
+  // Parse the HOB list until end of list or matching type is found.
+  //
+  while (!END_OF_HOB_LIST (Hob)) {
+    DEBUG ((DEBUG_INFO, "HOB(%p) : %x %x\n", Hob, Hob.Header->HobType, Hob.Header->HobLength));
+    switch (Hob.Header->HobType) {
+    case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
+      DEBUG ((DEBUG_INFO, "\t: %x %x %llx %llx\n",
+        Hob.ResourceDescriptor->ResourceType,
+        Hob.ResourceDescriptor->ResourceAttribute,
+        Hob.ResourceDescriptor->PhysicalStart,
+        Hob.ResourceDescriptor->ResourceLength));
+
+      break;
+    case EFI_HOB_TYPE_MEMORY_ALLOCATION:
+      DEBUG ((DEBUG_INFO, "\t: %llx %llx %x\n",
+        Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress,
+        Hob.MemoryAllocation->AllocDescriptor.MemoryLength,
+        Hob.MemoryAllocation->AllocDescriptor.MemoryType));
+      break;
+    default:
+      break;
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+}
+
+/**
+  Transfer the incoming HobList for the TD to the final HobList for Dxe.
+  The Hobs transferred in this function are ResourceDescriptor hob and
+  MemoryAllocation hob.
+
+  @param[in] VmmHobList    The Hoblist pass the firmware
+
+**/
+VOID
+EFIAPI
+TransferTdxHobList (
+  VOID
+  )
+{
+  EFI_PEI_HOB_POINTERS        Hob;
+  EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute;
+
+  //
+  // PcdOvmfSecGhcbBase is used as the TD_HOB in Tdx guest.
+  //
+  Hob.Raw = (UINT8 *) (UINTN) PcdGet32 (PcdOvmfSecGhcbBase);
+  while (!END_OF_HOB_LIST (Hob)) {
+    switch (Hob.Header->HobType) {
+    case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
+      ResourceAttribute = Hob.ResourceDescriptor->ResourceAttribute;
+
+      BuildResourceDescriptorHob (
+        Hob.ResourceDescriptor->ResourceType,
+        ResourceAttribute,
+        Hob.ResourceDescriptor->PhysicalStart,
+        Hob.ResourceDescriptor->ResourceLength);
+      break;
+    case EFI_HOB_TYPE_MEMORY_ALLOCATION:
+      BuildMemoryAllocationHob (
+        Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress,
+        Hob.MemoryAllocation->AllocDescriptor.MemoryLength,
+        Hob.MemoryAllocation->AllocDescriptor.MemoryType);
+      break;
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+  DEBUG_HOBLIST (GetHobList ());
+}
+
+/**
+
+  Publish memory regions in Intel TDX guest.
+
+**/
+VOID
+TdxPublishRamRegions (
+  VOID
+  )
+{
+  TransferTdxHobList ();
+
+  //
+  // The memory region defined by PcdOvmfSecGhcbBackupBase is pre-allocated by
+  // host VMM and used as the td mailbox at the beginning of system boot.
+  //
+  BuildMemoryAllocationHob (
+    PcdGet32 (PcdOvmfSecGhcbBackupBase),
+    PcdGet32 (PcdOvmfSecGhcbBackupSize),
+    EfiACPIMemoryNVS
+    );
+}
+
+/**
+  This function check the system status from QEMU via fw_cfg.
+  If the system status from QEMU is retrieved, its value is set
+  into PlatformInfoHob.
+
+  @param[in]  PlatformInfoHob   The data structure of PlatformInfo hob
+**/
+VOID
+EFIAPI
+CheckSystemStatsForOverride (
+  IN EFI_HOB_PLATFORM_INFO    * PlatformInfoHob
+  )
+{
+  EFI_STATUS              Status;
+  FIRMWARE_CONFIG_ITEM    FwCfgItem;
+  UINTN                   FwCfgSize;
+
+  //
+  // check for overrides
+  //
+  Status = QemuFwCfgFindFile ("etc/system-states", &FwCfgItem, &FwCfgSize);
+  if (Status != RETURN_SUCCESS || FwCfgSize != sizeof PlatformInfoHob->SystemStates) {
+    DEBUG ((DEBUG_INFO, "ACPI using S3/S4 defaults\n"));
+    return;
+  }
+
+  QemuFwCfgSelectItem (FwCfgItem);
+  QemuFwCfgReadBytes (sizeof (PlatformInfoHob->SystemStates), PlatformInfoHob->SystemStates);
+}
+
+/**
+  At the beginning of system boot, a 4K-aligned, 4K-size memory (Td mailbox) is
+  pre-allocated by host VMM. BSP & APs do the page accept together in that memory
+  region.
+
+  After that TDVF is designed to relocate the mailbox to a 4K-aligned, 4K-size
+  memory block which is allocated in the ACPI Nvs memory. APs are waken up and
+  spin around the relocated mailbox for further command.
+
+  @return   UINT64    Address of the relocated mailbox
+**/
+UINT64
+EFIAPI
+TdxRelocateMailbox (
+  VOID
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PHYSICAL_ADDRESS        Address;
+  VOID                        *ApLoopFunc = NULL;
+  UINT32                      RelocationPages;
+  MP_RELOCATION_MAP           RelocationMap;
+  MP_WAKEUP_MAILBOX           *RelocatedMailBox;
+
+  //
+  // Get information needed to setup aps running in their
+  // run loop in allocated acpi reserved memory
+  // Add another page for mailbox
+  //
+  AsmGetRelocationMap (&RelocationMap);
+  RelocationPages  = EFI_SIZE_TO_PAGES ((UINT32)RelocationMap.RelocateApLoopFuncSize) + 1;
+
+  Status = PeiServicesAllocatePages (EfiACPIMemoryNVS, RelocationPages, &Address);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to allocate pages to relocate Td mailbox. %r\n", Status));
+    ASSERT (FALSE);
+    return 0;
+  }
+
+  ApLoopFunc = (VOID *) ((UINTN) Address + EFI_PAGE_SIZE);
+
+  CopyMem (
+    ApLoopFunc,
+    RelocationMap.RelocateApLoopFuncAddress,
+    RelocationMap.RelocateApLoopFuncSize
+    );
+
+  DEBUG ((DEBUG_INFO, "Ap Relocation: mailbox %llx, loop %p\n",
+    Address, ApLoopFunc));
+
+  //
+  // Initialize mailbox
+  //
+  RelocatedMailBox = (MP_WAKEUP_MAILBOX *)Address;
+  RelocatedMailBox->Command = MpProtectedModeWakeupCommandNoop;
+  RelocatedMailBox->ApicId = MP_CPU_PROTECTED_MODE_MAILBOX_APICID_INVALID;
+  RelocatedMailBox->WakeUpVector = 0;
+
+  //
+  // Wakup APs and have been move to the finalized run loop
+  // They will spin until guest OS wakes them
+  //
+  MpSerializeStart ();
+
+  MpSendWakeupCommand (
+    MpProtectedModeWakeupCommandWakeup,
+    (UINT64)ApLoopFunc,
+    (UINT64)RelocatedMailBox,
+    0,
+    0,
+    0);
+
+  return (UINT64)RelocatedMailBox;
+}
+
+/**
+
+  This Function checks if TDX is available, if present then it sets
+  the dynamic PcdTdxIsEnabled and PcdIa32EferChangeAllowed.
+
+  It relocates the td mailbox and create the PlatformInfo Hob which includes
+  the TDX specific information which will be consumed in DXE phase.
+
+  **/
+VOID
+IntelTdxInitialize (
+  VOID
+  )
+{
+  EFI_HOB_PLATFORM_INFO       PlatformInfoHob;
+  RETURN_STATUS               PcdStatus;
+
+  if (!PlatformPeiIsTdxGuest ()) {
+    return;
+  }
+
+  PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrIntelTdx);
+  ASSERT_RETURN_ERROR (PcdStatus);
+
+  PcdStatus = PcdSetBoolS (PcdIa32EferChangeAllowed, FALSE);
+  ASSERT_RETURN_ERROR (PcdStatus);
+
+  PcdStatus = PcdSet64S (PcdTdxSharedBitMask, TdSharedPageMask ());
+  ASSERT_RETURN_ERROR (PcdStatus);
+
+  ZeroMem (&PlatformInfoHob, sizeof (PlatformInfoHob));
+  PlatformInfoHob.HostBridgePciDevId = mHostBridgeDevId;
+
+  PlatformInfoHob.RelocatedMailBox = TdxRelocateMailbox ();
+
+  CheckSystemStatsForOverride (&PlatformInfoHob);
+
+  BuildGuidDataHob (&gUefiOvmfPkgTdxPlatformGuid, &PlatformInfoHob, sizeof (EFI_HOB_PLATFORM_INFO));
+}
diff --git a/OvmfPkg/PlatformPei/IntelTdxNull.c b/OvmfPkg/PlatformPei/IntelTdxNull.c
new file mode 100644
index 000000000000..35a079d82f66
--- /dev/null
+++ b/OvmfPkg/PlatformPei/IntelTdxNull.c
@@ -0,0 +1,49 @@
+/** @file
+  Main SEC phase code. Handles initial TDX Hob List Processing
+
+  Copyright (c) 2008, Intel Corporation. All rights reserved.<BR>
+  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/IntelTdx.h>
+
+/**
+  Check if it is Tdx guest
+
+  @retval    TRUE   It is Tdx guest
+  @retval    FALSE  It is not Tdx guest
+**/
+BOOLEAN
+PlatformPeiIsTdxGuest (
+  VOID
+  )
+{
+  return FALSE;
+}
+
+VOID
+TdxPublishRamRegions (
+  VOID
+  )
+{
+}
+
+VOID
+IntelTdxInitialize (
+  VOID
+  )
+{
+}
+
+VOID
+AsmGetRelocationMap (
+  OUT MP_RELOCATION_MAP    *AddressMap
+  )
+{
+}
diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index d736b85e0d90..1724bd9638df 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -35,6 +35,7 @@ Module Name:
 #include <Library/MtrrLib.h>
 #include <Library/QemuFwCfgLib.h>
 #include <Library/QemuFwCfgSimpleParserLib.h>
+#include <Library/TdxLib.h>
 
 #include "Platform.h"
 #include "Cmos.h"
@@ -488,6 +489,7 @@ AddressWidthInitialization (
   )
 {
   UINT64 FirstNonAddress;
+  UINT64 TdxSharedPageMask;
 
   //
   // As guest-physical memory size grows, the permanent PEI RAM requirements
@@ -515,7 +517,17 @@ AddressWidthInitialization (
   if (mPhysMemAddressWidth <= 36) {
     mPhysMemAddressWidth = 36;
   }
-  ASSERT (mPhysMemAddressWidth <= 48);
+
+  if (PlatformPeiIsTdxGuest ()) {
+    TdxSharedPageMask = TdSharedPageMask ();
+    if (TdxSharedPageMask == (1ULL << 47)) {
+      mPhysMemAddressWidth = 48;
+    } else {
+      mPhysMemAddressWidth = 52;
+    }
+  }
+
+  ASSERT (mPhysMemAddressWidth <= 52);
 }
 
 
@@ -532,8 +544,10 @@ GetPeiMemoryCap (
   UINT32  RegEax;
   UINT32  RegEdx;
   UINT32  Pml4Entries;
+  UINT32  Pml5Entries;
   UINT32  PdpEntries;
   UINTN   TotalPages;
+  UINT8   PhysicalAddressBits;
 
   //
   // If DXE is 32-bit, then just return the traditional 64 MB cap.
@@ -561,20 +575,33 @@ GetPeiMemoryCap (
     }
   }
 
-  if (mPhysMemAddressWidth <= 39) {
-    Pml4Entries = 1;
-    PdpEntries = 1 << (mPhysMemAddressWidth - 30);
-    ASSERT (PdpEntries <= 0x200);
+  PhysicalAddressBits = mPhysMemAddressWidth;
+  Pml5Entries = 1;
+
+  if (PhysicalAddressBits > 48) {
+    Pml5Entries = (UINT32) LShiftU64 (1, PhysicalAddressBits - 48);
+    PhysicalAddressBits = 48;
+  }
+
+  Pml4Entries = 1;
+  if (PhysicalAddressBits > 39) {
+    Pml4Entries = (UINT32) LShiftU64 (1, PhysicalAddressBits - 39);
+    PhysicalAddressBits = 39;
+  }
+
+  PdpEntries = 1;
+  ASSERT (PhysicalAddressBits > 30);
+  PdpEntries = (UINT32) LShiftU64 (1, PhysicalAddressBits - 30);
+
+  //
+  // Pre-allocate big pages to avoid later allocations.
+  //
+  if (!Page1GSupport) {
+    TotalPages = ((PdpEntries + 1) * Pml4Entries + 1) * Pml5Entries + 1;
   } else {
-    Pml4Entries = 1 << (mPhysMemAddressWidth - 39);
-    ASSERT (Pml4Entries <= 0x200);
-    PdpEntries = 512;
+    TotalPages = (Pml4Entries + 1) * Pml5Entries + 1;
   }
 
-  TotalPages = Page1GSupport ? Pml4Entries + 1 :
-                               (PdpEntries + 1) * Pml4Entries + 1;
-  ASSERT (TotalPages <= 0x40201);
-
   //
   // Add 64 MB for miscellaneous allocations. Note that for
   // mPhysMemAddressWidth values close to 36, the cap will actually be
@@ -819,7 +846,11 @@ InitializeRamRegions (
   VOID
   )
 {
-  QemuInitializeRam ();
+  if (PlatformPeiIsTdxGuest ()) {
+    TdxPublishRamRegions ();
+  } else {
+    QemuInitializeRam ();
+  }
 
   if (mS3Supported && mBootMode != BOOT_ON_S3_RESUME) {
     //
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index df2d9ad015aa..7b3d187eea43 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -756,6 +756,7 @@ InitializePlatform (
 
   InstallClearCacheCallback ();
   AmdSevInitialize ();
+  IntelTdxInitialize ();
   MiscInitialization ();
   InstallFeatureControlCallback ();
 
diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h
index 8b1d270c2b0b..bf12b52d153e 100644
--- a/OvmfPkg/PlatformPei/Platform.h
+++ b/OvmfPkg/PlatformPei/Platform.h
@@ -10,6 +10,7 @@
 #define _PLATFORM_PEI_H_INCLUDED_
 
 #include <IndustryStandard/E820.h>
+#include <IndustryStandard/IntelTdx.h>
 
 VOID
 AddIoMemoryBaseSizeHob (
@@ -102,6 +103,33 @@ AmdSevInitialize (
   VOID
   );
 
+VOID
+TdxPublishRamRegions (
+  VOID
+  );
+
+VOID
+AsmGetRelocationMap (
+  OUT MP_RELOCATION_MAP    *AddressMap
+  );
+
+
+VOID
+IntelTdxInitialize (
+  VOID
+  );
+
+/**
+  Check if it is Tdx guest
+
+  @retval    TRUE   It is Tdx guest
+  @retval    FALSE  It is not Tdx guest
+**/
+BOOLEAN
+PlatformPeiIsTdxGuest (
+  VOID
+  );
+
 extern EFI_BOOT_MODE mBootMode;
 
 extern BOOLEAN mS3Supported;
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 67eb7aa7166b..9bddf14edc9b 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -34,6 +34,13 @@
   Platform.c
   Platform.h
 
+[Sources.IA32, Sources.EBC]
+  IntelTdxNull.c
+
+[Sources.X64]
+  IntelTdx.c
+  X64/ApRunLoop.nasm
+
 [Packages]
   EmbeddedPkg/EmbeddedPkg.dec
   MdePkg/MdePkg.dec
@@ -44,6 +51,7 @@
 
 [Guids]
   gEfiMemoryTypeInformationGuid
+  gUefiOvmfPkgTdxPlatformGuid
 
 [LibraryClasses]
   BaseLib
@@ -62,6 +70,9 @@
   MtrrLib
   MemEncryptSevLib
   PcdLib
+  TdxMailboxLib
+  TdxLib
+  MemoryAllocationLib
 
 [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
@@ -106,6 +117,9 @@
   gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
   gUefiCpuPkgTokenSpaceGuid.PcdSevEsIsEnabled
+  gEfiMdeModulePkgTokenSpaceGuid.PcdIa32EferChangeAllowed
+  gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTdxSharedBitMask
 
 [FixedPcd]
   gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
diff --git a/OvmfPkg/PlatformPei/X64/ApRunLoop.nasm b/OvmfPkg/PlatformPei/X64/ApRunLoop.nasm
new file mode 100644
index 000000000000..adf4f03c3a9e
--- /dev/null
+++ b/OvmfPkg/PlatformPei/X64/ApRunLoop.nasm
@@ -0,0 +1,83 @@
+;------------------------------------------------------------------------------ ;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;   ApRunLoop.nasm
+;
+; Abstract:
+;
+;   This is the assembly code for run loop for APs in the guest TD
+;
+;-------------------------------------------------------------------------------
+
+%include "TdxCommondefs.inc"
+
+DEFAULT REL
+
+SECTION .text
+
+BITS 64
+
+%macro  tdcall  0
+  db  0x66, 0x0f, 0x01, 0xcc
+%endmacro
+
+;
+; Relocated Ap Mailbox loop
+;
+; @param[in]  RBX:  Relocated mailbox address
+; @param[in]  RBP:  vCpuId
+;
+; @return     None  This routine does not return
+;
+global ASM_PFX(AsmRelocateApMailBoxLoop)
+ASM_PFX(AsmRelocateApMailBoxLoop):
+AsmRelocateApMailBoxLoopStart:
+
+    ;
+    ; TdCall[TDINFO] to get the vCpuId
+    ;
+    ;mov     rax, 1
+    ;tdcall
+    ;
+    ; R8  [31:0]  NUM_VCPUS
+    ;     [63:32] MAX_VCPUS
+    ; R9  [31:0]  VCPU_INDEX
+    ;
+
+    mov       r8, rbp
+MailBoxLoop:
+    ; Spin until command set
+    cmp        dword [rbx + CommandOffset], MpProtectedModeWakeupCommandNoop
+    je         MailBoxLoop
+    ; Determine if this is a broadcast or directly for my apic-id, if not, ignore
+    cmp        dword [rbx + ApicidOffset], MailboxApicidBroadcast
+    je         MailBoxProcessCommand
+    cmp        dword [rbx + ApicidOffset], r8d
+    jne        MailBoxLoop
+MailBoxProcessCommand:
+    cmp        dword [rbx + CommandOffset], MpProtectedModeWakeupCommandWakeup
+    je         MailBoxWakeUp
+    cmp        dword [rbx + CommandOffset], MpProtectedModeWakeupCommandSleep
+    je         MailBoxSleep
+    ; Don't support this command, so ignore
+    jmp        MailBoxLoop
+MailBoxWakeUp:
+    mov       rax, [rbx + WakeupVectorOffset]
+    jmp       rax
+MailBoxSleep:
+    jmp       $
+BITS 64
+AsmRelocateApMailBoxLoopEnd:
+
+;-------------------------------------------------------------------------------------
+;  AsmGetRelocationMap (&RelocationMap);
+;-------------------------------------------------------------------------------------
+global ASM_PFX(AsmGetRelocationMap)
+ASM_PFX(AsmGetRelocationMap):
+    lea        rax, [ASM_PFX(AsmRelocateApMailBoxLoopStart)]
+    mov        qword [rcx], rax
+    mov        qword [rcx +  8h], AsmRelocateApMailBoxLoopEnd - AsmRelocateApMailBoxLoopStart
+    ret
-- 
2.29.2.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#82979): https://edk2.groups.io/g/devel/message/82979
Mute This Topic: https://groups.io/mt/86739890/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list