public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Min Xu" <min.m.xu@intel.com>
To: devel@edk2.groups.io
Cc: Min Xu <min.m.xu@intel.com>,
	Ard Biesheuvel <ardb+tianocore@kernel.org>,
	Jordan Justen <jordan.l.justen@intel.com>,
	Brijesh Singh <brijesh.singh@amd.com>,
	Erdem Aktas <erdemaktas@google.com>,
	James Bottomley <jejb@linux.ibm.com>,
	Jiewen Yao <jiewen.yao@intel.com>,
	Tom Lendacky <thomas.lendacky@amd.com>
Subject: [PATCH V2 24/28] OvmfPkg: Add TdxDxe driver
Date: Tue,  5 Oct 2021 11:39:35 +0800	[thread overview]
Message-ID: <f9deaff2cc3246229e8fb9163089f41be4571639.1633401643.git.min.m.xu@intel.com> (raw)
In-Reply-To: <cover.1633401643.git.min.m.xu@intel.com>

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

TdxDxe driver is dispatched early in DXE, due to being list in APRIORI.
This module is responsible for below features:
 - Sets max logical cpus based on TDINFO
 - Sets PCI PCDs based on resource hobs

Besides above features, TdxDxe driver will update the ACPI MADT
Mutiprocessor Wakeup Table.

In TDX the guest firmware is designed to publish a multiprocessor-wakeup
structure to let the guest-bootstrap processor wake up guest-application
processors with a mailbox. The mailbox is memory that the guest firmware
can reserve so each guest virtual processor can have the guest OS send
a message to them. The address of the mailbox is recorded in the MADT
table. See [ACPI].

TdxDxe registers for protocol notification
(gQemuAcpiTableNotifyProtocolGuid) to call the AlterAcpiTable(), in
which MADT table is altered by the above Mailbox address. The protocol
will be installed in AcpiPlatformDxe when the MADT table provided by
Qemu is ready. This is to maintain the simplicity of the AcpiPlatformDxe.

AlterAcpiTable is the registered function which traverses the ACPI
table list to find the original MADT from Qemu. After the new MADT is
configured and installed, the original one will be uninstalled.

[ACPI] https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model
/ACPI_Software_Programming_Model.html#multiprocessor-wakeup-structure

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/Include/IndustryStandard/AcpiTdx.h  |  23 +++
 OvmfPkg/Include/IndustryStandard/IntelTdx.h |   5 +-
 OvmfPkg/OvmfPkg.dec                         |   4 +
 OvmfPkg/OvmfPkgX64.dsc                      |   2 +
 OvmfPkg/OvmfPkgX64.fdf                      |   3 +
 OvmfPkg/TdxDxe/TdxAcpiTable.c               | 207 ++++++++++++++++++++
 OvmfPkg/TdxDxe/TdxAcpiTable.h               |  38 ++++
 OvmfPkg/TdxDxe/TdxDxe.c                     | 207 ++++++++++++++++++++
 OvmfPkg/TdxDxe/TdxDxe.inf                   |  62 ++++++
 9 files changed, 548 insertions(+), 3 deletions(-)
 create mode 100644 OvmfPkg/Include/IndustryStandard/AcpiTdx.h
 create mode 100644 OvmfPkg/TdxDxe/TdxAcpiTable.c
 create mode 100644 OvmfPkg/TdxDxe/TdxAcpiTable.h
 create mode 100644 OvmfPkg/TdxDxe/TdxDxe.c
 create mode 100644 OvmfPkg/TdxDxe/TdxDxe.inf

diff --git a/OvmfPkg/Include/IndustryStandard/AcpiTdx.h b/OvmfPkg/Include/IndustryStandard/AcpiTdx.h
new file mode 100644
index 000000000000..9e2753bbe52a
--- /dev/null
+++ b/OvmfPkg/Include/IndustryStandard/AcpiTdx.h
@@ -0,0 +1,23 @@
+/** @file
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef ACPI_TDX_H_
+#define ACPI_TDX_H_
+
+#define ACPI_MADT_MPWK_STRUCT_TYPE  0x10
+
+#pragma pack(1)
+
+typedef struct {
+  UINT8                       Type;
+  UINT8                       Length;
+  UINT16                      MailBoxVersion;
+  UINT32                      Reserved2;
+  UINT64                      MailBoxAddress;
+} ACPI_MADT_MPWK_STRUCT;
+
+#pragma pack()
+#endif
diff --git a/OvmfPkg/Include/IndustryStandard/IntelTdx.h b/OvmfPkg/Include/IndustryStandard/IntelTdx.h
index 2370f18289a1..bb02970394d7 100644
--- a/OvmfPkg/Include/IndustryStandard/IntelTdx.h
+++ b/OvmfPkg/Include/IndustryStandard/IntelTdx.h
@@ -6,8 +6,8 @@
 
 **/
 
-#ifndef _OVMF_INTEL_TDX__H_
-#define _OVMF_INTEL_TDX__H_
+#ifndef OVMF_INTEL_TDX_H_
+#define OVMF_INTEL_TDX_H_
 
 #include <PiPei.h>
 #include <Library/BaseLib.h>
@@ -52,7 +52,6 @@ typedef enum {
     UINT8                   Pad3[0xf8];
   } MP_WAKEUP_MAILBOX;
 
-
 //
 // AP relocation code information including code address and size,
 // this structure will be shared be C code and assembly code.
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index b489c69a736e..cc5087da6aa2 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -153,6 +153,7 @@
   gEfiLegacyInterruptProtocolGuid       = {0x31ce593d, 0x108a, 0x485d, {0xad, 0xb2, 0x78, 0xf2, 0x1f, 0x29, 0x66, 0xbe}}
   gEfiVgaMiniPortProtocolGuid           = {0xc7735a2f, 0x88f5, 0x4882, {0xae, 0x63, 0xfa, 0xac, 0x8c, 0x8b, 0x86, 0xb3}}
   gOvmfLoadedX86LinuxKernelProtocolGuid = {0xa3edc05d, 0xb618, 0x4ff6, {0x95, 0x52, 0x76, 0xd7, 0x88, 0x63, 0x43, 0xc8}}
+  gQemuAcpiTableNotifyProtocolGuid      = {0x928939b2, 0x4235, 0x462f, {0x95, 0x80, 0xf6, 0xa2, 0xb2, 0xc2, 0x1a, 0x4f}}
 
 [PcdsFixedAtBuild]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|0x0|UINT32|0
@@ -403,6 +404,9 @@
   #  instance in PiSmmCpuDxeSmm, and CpuHotplugSmm.
   gUefiOvmfPkgTokenSpaceGuid.PcdCpuHotEjectDataAddress|0|UINT64|0x46
 
+  ## TDX relocated Mailbox base address
+  gUefiOvmfPkgTokenSpaceGuid.PcdTdRelocatedMailboxBase|0|UINT64|0x60
+
 [PcdsFeatureFlag]
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE|BOOLEAN|0x1c
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|FALSE|BOOLEAN|0x1d
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 12ebde74433d..2c4a6613b1ea 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -977,6 +977,8 @@
   OvmfPkg/AmdSevDxe/AmdSevDxe.inf
   OvmfPkg/IoMmuDxe/IoMmuDxe.inf
 
+  OvmfPkg/TdxDxe/TdxDxe.inf
+
 !if $(SMM_REQUIRE) == TRUE
   OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
   OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index b6cc3cabdd69..bbd9303ab14f 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -214,6 +214,7 @@ READ_LOCK_STATUS   = TRUE
 APRIORI DXE {
   INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
   INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+  INF  OvmfPkg/TdxDxe/TdxDxe.inf
   INF  OvmfPkg/AmdSevDxe/AmdSevDxe.inf
 !if $(SMM_REQUIRE) == FALSE
   INF  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
@@ -319,6 +320,8 @@ INF  ShellPkg/Application/Shell/Shell.inf
 
 INF MdeModulePkg/Logo/LogoDxe.inf
 
+INF OvmfPkg/TdxDxe/TdxDxe.inf
+
 #
 # Network modules
 #
diff --git a/OvmfPkg/TdxDxe/TdxAcpiTable.c b/OvmfPkg/TdxDxe/TdxAcpiTable.c
new file mode 100644
index 000000000000..249dbbb9128f
--- /dev/null
+++ b/OvmfPkg/TdxDxe/TdxAcpiTable.c
@@ -0,0 +1,207 @@
+/** @file
+  OVMF ACPI QEMU support
+
+  Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+
+  Copyright (C) 2012-2014, Red Hat, Inc.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/QemuFwCfgLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/OrderedCollectionLib.h>
+#include <Library/TdxLib.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/AcpiTdx.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/AcpiTable.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Protocol/Cpu.h>
+#include <Uefi.h>
+#include <TdxAcpiTable.h>
+
+STATIC
+EFI_STATUS
+EFIAPI
+QemuInstallAcpiMadtTable (
+  IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol,
+  IN   VOID                          *AcpiTableBuffer,
+  IN   UINTN                         AcpiTableBufferSize,
+  OUT  UINTN                         *TableKey
+  )
+{
+  UINTN                                               CpuCount;
+  UINTN                                               NewBufferSize;
+  EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt;
+  EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE         *LocalApic;
+  EFI_ACPI_1_0_IO_APIC_STRUCTURE                      *IoApic;
+  EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE    *Iso;
+  EFI_ACPI_1_0_LOCAL_APIC_NMI_STRUCTURE               *LocalApicNmi;
+  VOID                                                *Ptr;
+  UINTN                                               Loop;
+  EFI_STATUS                                          Status;
+  ACPI_MADT_MPWK_STRUCT                               *MadtMpWk;
+
+  ASSERT (AcpiTableBufferSize >= sizeof (EFI_ACPI_DESCRIPTION_HEADER));
+
+  CpuCount = TdVCpuNum();
+
+  ASSERT (CpuCount >= 1);
+
+#define NUM_8259_IRQS                   16
+  NewBufferSize = 1                     * sizeof (*Madt) +
+                  CpuCount              * sizeof (*LocalApic) +
+                  1                     * sizeof (*IoApic) +
+                  NUM_8259_IRQS         * sizeof (*Iso) +
+                  1                     * sizeof (*LocalApicNmi);
+
+  NewBufferSize += sizeof(ACPI_MADT_MPWK_STRUCT);
+
+  Madt = AllocatePool (NewBufferSize);
+  if (Madt == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  CopyMem (&(Madt->Header), AcpiTableBuffer, sizeof (EFI_ACPI_DESCRIPTION_HEADER));
+  Madt->Header.Length    = (UINT32) NewBufferSize;
+  Madt->LocalApicAddress = PcdGet32 (PcdCpuLocalApicBaseAddress);
+  Madt->Flags            = EFI_ACPI_1_0_PCAT_COMPAT;
+  Ptr = Madt + 1;
+
+  LocalApic = Ptr;
+  for (Loop = 0; Loop < CpuCount; ++Loop) {
+    LocalApic->Type            = EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC;
+    LocalApic->Length          = sizeof (*LocalApic);
+    LocalApic->AcpiProcessorId = (UINT8) Loop;
+    LocalApic->ApicId          = (UINT8) Loop;
+    LocalApic->Flags           = 1; // enabled
+    ++LocalApic;
+  }
+  Ptr = LocalApic;
+
+  IoApic = Ptr;
+  IoApic->Type             = EFI_ACPI_1_0_IO_APIC;
+  IoApic->Length           = sizeof (*IoApic);
+  IoApic->IoApicId         = (UINT8) CpuCount;
+  IoApic->Reserved         = EFI_ACPI_RESERVED_BYTE;
+  IoApic->IoApicAddress    = 0xFEC00000;
+  IoApic->SystemVectorBase = 0x00000000;
+  Ptr = IoApic + 1;
+
+  //
+  // IRQ0 (8254 Timer) => IRQ2 (PIC) Interrupt Source Override Structure
+  //
+  Iso = Ptr;
+  Iso->Type                        = EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE;
+  Iso->Length                      = sizeof (*Iso);
+  Iso->Bus                         = 0x00;    // ISA
+  Iso->Source                      = 0x00;    // IRQ0
+  Iso->GlobalSystemInterruptVector = 0x00000002;
+  Iso->Flags                       = 0x0005;  // Edge-triggered, Active High
+  ++Iso;
+
+  for (Loop = 1; Loop < NUM_8259_IRQS; ++Loop) {
+    Iso->Type                        = EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE;
+    Iso->Length                      = sizeof (*Iso);
+    Iso->Bus                         = 0x00; // ISA
+    Iso->Source                      = (UINT8) Loop;
+    Iso->GlobalSystemInterruptVector = (UINT32) Loop;
+    Iso->Flags                       = 0x0005; // Edge-triggered, Active High
+    ++Iso;
+  }
+  Ptr = Iso;
+
+  LocalApicNmi = Ptr;
+  LocalApicNmi->Type            = EFI_ACPI_1_0_LOCAL_APIC_NMI;
+  LocalApicNmi->Length          = sizeof (*LocalApicNmi);
+  LocalApicNmi->AcpiProcessorId = 0xFF; // applies to all processors
+  //
+  // polarity and trigger mode of the APIC I/O input signals conform to the
+  // specifications of the bus
+  //
+  LocalApicNmi->Flags           = 0x0000;
+  //
+  // Local APIC interrupt input LINTn to which NMI is connected.
+  //
+  LocalApicNmi->LocalApicInti   = 0x01;
+  Ptr = LocalApicNmi + 1;
+
+  MadtMpWk = Ptr;
+  MadtMpWk->Type = ACPI_MADT_MPWK_STRUCT_TYPE;
+  MadtMpWk->Length = sizeof(ACPI_MADT_MPWK_STRUCT);
+  MadtMpWk->MailBoxVersion = 1;
+  MadtMpWk->Reserved2 = 0;
+  MadtMpWk->MailBoxAddress = PcdGet64 (PcdTdRelocatedMailboxBase);
+  Ptr = MadtMpWk + 1;
+
+  ASSERT ((UINTN) ((UINT8 *)Ptr - (UINT8 *)Madt) == NewBufferSize);
+  Status = AcpiProtocol->InstallAcpiTable (AcpiProtocol, Madt, NewBufferSize, TableKey);
+
+  FreePool (Madt);
+
+  return Status;
+}
+
+/**
+  Alter the MADT when ACPI Table from QEMU is available.
+
+  @param[in]  Event     Event whose notification function is being invoked
+  @param[in]  Context   Pointer to the notification function's context
+**/
+VOID
+EFIAPI
+AlterAcpiTable (
+  IN EFI_EVENT                      Event,
+  IN VOID*                          Context
+  )
+{
+  EFI_ACPI_SDT_PROTOCOL          *AcpiSdtTable;
+  EFI_ACPI_TABLE_PROTOCOL        *AcpiTable;
+  EFI_STATUS                     Status;
+  UINTN                          Index;
+  EFI_ACPI_SDT_HEADER            *Table;
+  EFI_ACPI_TABLE_VERSION         Version;
+  UINTN                          OriginalTableKey;
+  UINTN                          UpdatedTableKey;
+
+  Index = 0;
+
+  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (void **) &AcpiSdtTable);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Unable to locate ACPI SDT protocol.\n"));
+    return;
+  }
+
+  do {
+    Status = AcpiSdtTable->GetAcpiTable (Index, &Table, &Version, &OriginalTableKey);
+
+    if (!EFI_ERROR (Status) && Table->Signature == EFI_ACPI_1_0_APIC_SIGNATURE) {
+      Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (void **) &AcpiTable);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "Unable to locate ACPI Table protocol.\n"));
+        return;
+      }
+
+      //
+      // The altered MADT should be rebuilt and installed before uninstall the
+      // original one, because unintall table will free the memory which will be
+      // copied in QemuInstallAcpiMadtTable().
+      //
+      QemuInstallAcpiMadtTable (AcpiTable, Table, Table->Length, &UpdatedTableKey);
+      Status = AcpiTable->UninstallAcpiTable (AcpiTable, OriginalTableKey);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "Uninstall MADT table error.\n"));
+      }
+      break;
+    }
+    Index ++;
+  } while (!EFI_ERROR (Status));
+}
diff --git a/OvmfPkg/TdxDxe/TdxAcpiTable.h b/OvmfPkg/TdxDxe/TdxAcpiTable.h
new file mode 100644
index 000000000000..36aaab9d1f41
--- /dev/null
+++ b/OvmfPkg/TdxDxe/TdxAcpiTable.h
@@ -0,0 +1,38 @@
+/** @file
+  Sample ACPI Platform Driver
+
+  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _TDX_QEMU_ACPI_H_INCLUDED_
+#define _TDX_QEMU_ACPI_H_INCLUDED_
+
+#include <PiDxe.h>
+
+#include <Protocol/AcpiTable.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/PciIo.h>
+
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include <IndustryStandard/Acpi.h>
+
+/**
+  Alter the MADT when ACPI Table from QEMU is available.
+
+  @param[in]  Event     Event whose notification function is being invoked
+  @param[in]  Context   Pointer to the notification function's context
+**/
+VOID
+EFIAPI
+AlterAcpiTable (
+  IN EFI_EVENT                      Event,
+  IN VOID*                          Context
+  );
+
+#endif
diff --git a/OvmfPkg/TdxDxe/TdxDxe.c b/OvmfPkg/TdxDxe/TdxDxe.c
new file mode 100644
index 000000000000..eecad8f6e050
--- /dev/null
+++ b/OvmfPkg/TdxDxe/TdxDxe.c
@@ -0,0 +1,207 @@
+/** @file
+
+  TDX Dxe driver. This driver is dispatched early in DXE, due to being list
+  in APRIORI.
+
+  This module is responsible for:
+    - Sets max logical cpus based on TDINFO
+    - Sets PCI PCDs based on resource hobs
+    - Alter MATD table to record address of Mailbox
+
+  Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+#include <Library/HobLib.h>
+#include <Protocol/Cpu.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <IndustryStandard/Tdx.h>
+#include <IndustryStandard/IntelTdx.h>
+#include <Library/TdxLib.h>
+#include <TdxAcpiTable.h>
+
+/**
+  Location of resource hob matching type and starting address
+
+  @param[in]  Type             The type of resource hob to locate.
+
+  @param[in]  Start            The resource hob must at least begin at address.
+
+  @retval pointer to resource  Return pointer to a resource hob that matches or NULL.
+**/
+STATIC
+EFI_HOB_RESOURCE_DESCRIPTOR *
+GetResourceDescriptor(
+  EFI_RESOURCE_TYPE     Type,
+  EFI_PHYSICAL_ADDRESS  Start,
+  EFI_PHYSICAL_ADDRESS  End
+ )
+{
+  EFI_PEI_HOB_POINTERS          Hob;
+  EFI_HOB_RESOURCE_DESCRIPTOR   *ResourceDescriptor = NULL;
+
+  Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+  while (Hob.Raw != NULL) {
+
+      DEBUG ((DEBUG_INFO, "%a:%d: resource type 0x%x %llx %llx\n",
+        __func__, __LINE__,
+        Hob.ResourceDescriptor->ResourceType,
+        Hob.ResourceDescriptor->PhysicalStart,
+        Hob.ResourceDescriptor->ResourceLength));
+
+    if ((Hob.ResourceDescriptor->ResourceType == Type) &&
+      (Hob.ResourceDescriptor->PhysicalStart >= Start) &&
+      ((Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength) < End)) {
+      ResourceDescriptor = Hob.ResourceDescriptor;
+      break;
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+    Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
+  }
+
+  return ResourceDescriptor;
+}
+
+/**
+  Location of resource hob matching type and highest address below end
+
+  @param[in]  Type             The type of resource hob to locate.
+
+  @param[in]  End              The resource hob return is the closest to the End address
+
+  @retval pointer to resource  Return pointer to a resource hob that matches or NULL.
+**/
+STATIC
+EFI_HOB_RESOURCE_DESCRIPTOR *
+GetHighestResourceDescriptor(
+  EFI_RESOURCE_TYPE     Type,
+  EFI_PHYSICAL_ADDRESS  End
+ )
+{
+  EFI_PEI_HOB_POINTERS          Hob;
+  EFI_HOB_RESOURCE_DESCRIPTOR   *ResourceDescriptor = NULL;
+
+  Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+  while (Hob.Raw != NULL) {
+    if ((Hob.ResourceDescriptor->ResourceType == Type) &&
+      (Hob.ResourceDescriptor->PhysicalStart < End)) {
+      if (!ResourceDescriptor ||
+        (ResourceDescriptor->PhysicalStart < Hob.ResourceDescriptor->PhysicalStart)) {
+        ResourceDescriptor = Hob.ResourceDescriptor;
+      }
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+    Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
+  }
+
+  return ResourceDescriptor;
+}
+
+EFI_STATUS
+EFIAPI
+TdxDxeEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+
+  EFI_STATUS                    Status;
+  RETURN_STATUS                 PcdStatus;
+  EFI_HOB_RESOURCE_DESCRIPTOR   *Res = NULL;
+  EFI_HOB_RESOURCE_DESCRIPTOR   *MemRes = NULL;
+  EFI_HOB_PLATFORM_INFO         *PlatformInfo = NULL;
+  EFI_HOB_GUID_TYPE             *GuidHob;
+  UINT32                        CpuMaxLogicalProcessorNumber;
+  TD_RETURN_DATA                TdReturnData;
+  EFI_EVENT                     QemuAcpiTableEvent;
+  void                          *Registration;
+
+  GuidHob = GetFirstGuidHob (&gUefiOvmfPkgTdxPlatformGuid);
+
+  if(GuidHob == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  PlatformInfo = (EFI_HOB_PLATFORM_INFO *) GET_GUID_HOB_DATA (GuidHob);
+
+  //
+  // Call TDINFO to get actual number of cpus in domain
+  //
+  Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
+  ASSERT(Status == EFI_SUCCESS);
+
+  CpuMaxLogicalProcessorNumber = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
+
+  //
+  // Adjust PcdCpuMaxLogicalProcessorNumber, if needed. If firmware is configured for
+  // more than number of reported cpus, update.
+  //
+  if (CpuMaxLogicalProcessorNumber > TdReturnData.TdInfo.NumVcpus) {
+    PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, TdReturnData.TdInfo.NumVcpus);
+    ASSERT_RETURN_ERROR(PcdStatus);
+  }
+
+  //
+  // Register for protocol notifications to call the AlterAcpiTable(),
+  // the protocol will be installed in AcpiPlatformDxe when the ACPI
+  // table provided by Qemu is ready.
+  //
+  Status = gBS->CreateEvent (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  AlterAcpiTable,
+                  NULL,
+                  &QemuAcpiTableEvent
+                  );
+
+  Status = gBS->RegisterProtocolNotify (
+                  &gQemuAcpiTableNotifyProtocolGuid,
+                  QemuAcpiTableEvent,
+                  &Registration
+                  );
+
+#define INIT_PCDSET(NAME, RES) do { \
+  PcdStatus = PcdSet64S (NAME##Base, (RES)->PhysicalStart); \
+  ASSERT_RETURN_ERROR (PcdStatus); \
+  PcdStatus = PcdSet64S (NAME##Size, (RES)->ResourceLength); \
+  ASSERT_RETURN_ERROR (PcdStatus); \
+} while(0)
+
+  if (PlatformInfo) {
+    PcdSet16S (PcdOvmfHostBridgePciDevId, PlatformInfo->HostBridgePciDevId);
+
+    if ((Res = GetResourceDescriptor(EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_PHYSICAL_ADDRESS)0x100000000, (EFI_PHYSICAL_ADDRESS)-1)) != NULL) {
+      INIT_PCDSET(PcdPciMmio64, Res);
+    }
+
+    if ((Res = GetResourceDescriptor(EFI_RESOURCE_IO, 0, 0x10001)) != NULL) {
+      INIT_PCDSET(PcdPciIo, Res);
+    }
+
+    //
+    // To find low mmio, first find top of low memory, and then search for io space.
+    //
+    if ((MemRes = GetHighestResourceDescriptor(EFI_RESOURCE_SYSTEM_MEMORY, 0xffc00000)) != NULL) {
+      if ((Res = GetResourceDescriptor(EFI_RESOURCE_MEMORY_MAPPED_IO, MemRes->PhysicalStart, 0x100000000)) != NULL) {
+        INIT_PCDSET(PcdPciMmio32, Res);
+      }
+    }
+    //
+    // Set initial protected mode reset address to our initial mailbox
+    // After DXE, will update address before exiting
+    //
+    PcdStatus = PcdSet64S (PcdTdRelocatedMailboxBase, PlatformInfo->RelocatedMailBox);
+    ASSERT_RETURN_ERROR(PcdStatus);
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/TdxDxe/TdxDxe.inf b/OvmfPkg/TdxDxe/TdxDxe.inf
new file mode 100644
index 000000000000..b77c6e5e9252
--- /dev/null
+++ b/OvmfPkg/TdxDxe/TdxDxe.inf
@@ -0,0 +1,62 @@
+#/** @file
+#
+#  Driver clears the encryption attribute from MMIO regions when TDX is enabled
+#
+#  Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 1.25
+  BASE_NAME                      = TdxDxe
+  FILE_GUID                      = E750224E-7BCE-40AF-B5BB-47E3611EB5C2
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = TdxDxeEntryPoint
+
+[Sources]
+  TdxDxe.c
+  TdxAcpiTable.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DxeServicesTableLib
+  MemoryAllocationLib
+  PcdLib
+  UefiDriverEntryPoint
+  TdxLib
+  HobLib
+
+[Depex]
+  TRUE
+
+[Guids]
+  gUefiOvmfPkgTdxPlatformGuid                      ## CONSUMES
+
+[Protocols]
+  gQemuAcpiTableNotifyProtocolGuid                 ## CONSUMES
+  gEfiAcpiSdtProtocolGuid                          ## CONSUMES
+  gEfiAcpiTableProtocolGuid                        ## CONSUMES
+
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
+  gUefiOvmfPkgTokenSpaceGuid.PcdTdRelocatedMailboxBase
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
-- 
2.29.2.windows.2


  parent reply	other threads:[~2021-10-05  3:41 UTC|newest]

Thread overview: 91+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-05  3:39 [PATCH V2 00/28] Enable Intel TDX in OvmfPkg (Config-A) Min Xu
2021-10-05  3:39 ` [PATCH V2 01/28] OvmfPkg: Copy Main.asm from UefiCpuPkg to OvmfPkg's ResetVector Min Xu
2021-10-05  3:39 ` [PATCH V2 02/28] OvmfPkg: Enable TDX in ResetVector Min Xu
2021-10-05  3:39 ` [PATCH V2 03/28] OvmfPkg: Merge TEMP_MEM entries in Tdx metadata Min Xu
2021-10-05  3:39 ` [PATCH V2 04/28] MdePkg: Add Tdx.h Min Xu
2021-10-12  7:48   ` [edk2-devel] " Gerd Hoffmann
2021-10-05  3:39 ` [PATCH V2 05/28] MdePkg: Add TdxLib to wrap Tdx operations Min Xu
2021-10-12  8:22   ` [edk2-devel] " Gerd Hoffmann
2021-10-13 12:13     ` Min Xu
2021-10-14  5:30       ` Gerd Hoffmann
2021-10-22  2:06         ` Min Xu
2021-10-05  3:39 ` [PATCH V2 06/28] MdePkg: Update BaseIoLibIntrinsicSev to support Tdx Min Xu
2021-10-12 10:05   ` [edk2-devel] " Gerd Hoffmann
2021-10-13 13:40     ` Min Xu
2021-10-14  5:37       ` Gerd Hoffmann
2021-10-14  6:24         ` Min Xu
2021-10-14  9:03           ` Gerd Hoffmann
2021-10-22  5:23         ` Min Xu
2021-10-05  3:39 ` [PATCH V2 07/28] UefiCpuPkg: Support TDX in BaseXApicX2ApicLib Min Xu
2021-10-12 10:15   ` [edk2-devel] " Gerd Hoffmann
2021-10-13 14:06     ` Min Xu
2021-10-13  5:30   ` Ni, Ray
2021-10-14  7:58     ` Min Xu
2021-10-05  3:39 ` [PATCH V2 08/28] UefiCpuPkg: Add VmTdExitLibNull Min Xu
2021-10-05  3:39 ` [PATCH V2 09/28] UefiPayloadPkg: Prepare UefiPayloadPkg to use the VmTdExitLib library Min Xu
2021-10-05  3:39 ` [PATCH V2 10/28] OvmfPkg: Prepare OvmfPkg " Min Xu
2021-10-05  3:39 ` [PATCH V2 11/28] OvmfPkg: Implement library support for VmTdExitLib in Ovmf Min Xu
2021-10-05  3:39 ` [PATCH V2 12/28] UefiCpuPkg/CpuExceptionHandler: Add base support for the #VE exception Min Xu
2021-10-12 10:27   ` [edk2-devel] " Gerd Hoffmann
2021-10-26  5:06     ` Min Xu
2021-10-26  6:11       ` Gerd Hoffmann
2021-10-26  8:23         ` Min Xu
2021-10-26 10:24           ` Gerd Hoffmann
2021-10-26 12:09             ` Min Xu
2021-10-27  7:19               ` Gerd Hoffmann
2021-10-28  1:59                 ` Yao, Jiewen
2021-10-28 15:35                   ` Brijesh Singh
2021-10-28 15:52                     ` Yao, Jiewen
2021-10-28 18:28                       ` Lendacky, Thomas
2021-10-29  0:17                         ` Yao, Jiewen
2021-10-29  4:52                           ` Gerd Hoffmann
2021-10-29  7:51                             ` Min Xu
2021-10-29 11:40                               ` Gerd Hoffmann
2021-11-01 13:54                           ` Sami Mujawar
2021-11-01 13:57                             ` Yao, Jiewen
     [not found]                         ` <16B2583BF2C9DB9C.5572@groups.io>
2021-10-29  0:20                           ` Yao, Jiewen
2021-10-29  0:25                             ` Brijesh Singh
     [not found]                 ` <16B20F4407499229.28171@groups.io>
2021-10-28  2:07                   ` Yao, Jiewen
2021-10-28  8:24                     ` Gerd Hoffmann
2021-10-05  3:39 ` [PATCH V2 13/28] UefiCpuPkg: Enable Tdx support in MpInitLib Min Xu
2021-10-12 10:31   ` [edk2-devel] " Gerd Hoffmann
2021-10-14  0:27     ` Min Xu
2021-10-14  6:04       ` Gerd Hoffmann
2021-10-14  6:31         ` Min Xu
2021-10-14  6:56           ` Gerd Hoffmann
2021-10-13  6:01   ` Ni, Ray
2021-10-14  8:22     ` Min Xu
2021-10-05  3:39 ` [PATCH V2 14/28] OvmfPkg: Update SecEntry.nasm to support Tdx Min Xu
2021-10-12 10:38   ` [edk2-devel] " Gerd Hoffmann
2021-10-14  0:55     ` Min Xu
2021-10-14  6:51       ` Gerd Hoffmann
2021-10-05  3:39 ` [PATCH V2 15/28] OvmfPkg: Add IntelTdx.h in OvmfPkg/Include/IndustryStandard Min Xu
2021-10-05  3:39 ` [PATCH V2 16/28] OvmfPkg: Add TdxMailboxLib Min Xu
2021-10-05  3:39 ` [PATCH V2 17/28] MdePkg: Add EFI_RESOURCE_ATTRIBUTE_ENCRYPTED in PiHob.h Min Xu
2021-10-05  3:39 ` [PATCH V2 18/28] OvmfPkg: Enable Tdx in SecMain.c Min Xu
2021-10-05  3:39 ` [PATCH V2 19/28] OvmfPkg: Check Tdx in QemuFwCfgPei to avoid DMA operation Min Xu
2021-10-05  3:39 ` [PATCH V2 20/28] MdeModulePkg: EFER should not be changed in TDX Min Xu
2021-10-05  3:39 ` [PATCH V2 21/28] OvmfPkg: Update PlatformPei to support TDX Min Xu
2021-10-13  4:49   ` [edk2-devel] " Gerd Hoffmann
2021-10-15  1:31     ` Yao, Jiewen
2021-10-15  5:45       ` Gerd Hoffmann
2021-10-15  6:41         ` Yao, Jiewen
2021-10-05  3:39 ` [PATCH V2 22/28] UefiCpuPkg: Define ConfidentialComputingGuestAttr (Temp) Min Xu
2021-10-05  3:39 ` [PATCH V2 23/28] OvmfPkg: Update AcpiPlatformDxe to alter MADT table Min Xu
2021-10-05  3:39 ` Min Xu [this message]
2021-10-12 11:50   ` [edk2-devel] [PATCH V2 24/28] OvmfPkg: Add TdxDxe driver Gerd Hoffmann
2021-10-18  8:38     ` Min Xu
2021-10-05  3:39 ` [PATCH V2 25/28] OvmfPkg/BaseMemEncryptTdxLib: Add TDX helper library Min Xu
2021-10-12 12:13   ` [edk2-devel] " Gerd Hoffmann
2021-10-05  3:39 ` [PATCH V2 26/28] OvmfPkg/QemuFwCfgLib: Support Tdx in QemuFwCfgDxe Min Xu
2021-10-05  3:39 ` [PATCH V2 27/28] OvmfPkg: Update IoMmuDxe to support TDX Min Xu
2021-10-12 12:15   ` [edk2-devel] " Gerd Hoffmann
2021-10-14  2:11     ` Min Xu
2021-10-05  3:39 ` [PATCH V2 28/28] OvmfPkg: Add LocalApicTimerDxe Min Xu
2021-10-12 13:02   ` [edk2-devel] " Gerd Hoffmann
2021-10-14  5:20     ` Min Xu
2021-10-15  1:21       ` Yao, Jiewen
2021-10-25  7:37     ` Min Xu
2021-10-25 11:27       ` Gerd Hoffmann
2021-10-26  1:29         ` Min Xu
2021-10-26  5:50           ` Gerd Hoffmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f9deaff2cc3246229e8fb9163089f41be4571639.1633401643.git.min.m.xu@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox