gEfiLegacyInterruptProtocolGuid = {0x31ce593d, 0x108a, 0x485d, {0xad, 0xb2, 0x78, 0xf2, 0x1f, 0x29, 0x66, 0xbe}}\r
gEfiVgaMiniPortProtocolGuid = {0xc7735a2f, 0x88f5, 0x4882, {0xae, 0x63, 0xfa, 0xac, 0x8c, 0x8b, 0x86, 0xb3}}\r
gOvmfLoadedX86LinuxKernelProtocolGuid = {0xa3edc05d, 0xb618, 0x4ff6, {0x95, 0x52, 0x76, 0xd7, 0x88, 0x63, 0x43, 0xc8}}\r
+ gQemuAcpiTableNotifyProtocolGuid = {0x928939b2, 0x4235, 0x462f, {0x95, 0x80, 0xf6, 0xa2, 0xb2, 0xc2, 0x1a, 0x4f}}\r
\r
[PcdsFixedAtBuild]\r
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|0x0|UINT32|0\r
}\r
OvmfPkg/IoMmuDxe/IoMmuDxe.inf\r
\r
+ OvmfPkg/TdxDxe/TdxDxe.inf\r
+\r
!if $(SMM_REQUIRE) == TRUE\r
OvmfPkg/SmmAccess/SmmAccess2Dxe.inf\r
OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf\r
APRIORI DXE {\r
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf\r
INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf\r
+ INF OvmfPkg/TdxDxe/TdxDxe.inf\r
INF OvmfPkg/AmdSevDxe/AmdSevDxe.inf\r
!if $(SMM_REQUIRE) == FALSE\r
INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf\r
\r
INF MdeModulePkg/Logo/LogoDxe.inf\r
\r
+INF OvmfPkg/TdxDxe/TdxDxe.inf\r
+\r
#\r
# Network modules\r
#\r
--- /dev/null
+/** @file\r
+ OVMF ACPI QEMU support\r
+\r
+ Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>\r
+\r
+ Copyright (C) 2012-2014, Red Hat, Inc.\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/QemuFwCfgLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/OrderedCollectionLib.h>\r
+#include <Library/TdxLib.h>\r
+#include <IndustryStandard/Acpi.h>\r
+#include <Protocol/AcpiSystemDescriptionTable.h>\r
+#include <Protocol/AcpiTable.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/TdxMailboxLib.h>\r
+#include <Protocol/Cpu.h>\r
+#include <Uefi.h>\r
+#include <TdxAcpiTable.h>\r
+\r
+/**\r
+ At the beginning of system boot, a 4K-aligned, 4K-size memory (Td mailbox) is\r
+ pre-allocated by host VMM. BSP & APs do the page accept together in that memory\r
+ region.\r
+\r
+ After that TDVF is designed to relocate the mailbox to a 4K-aligned, 4K-size\r
+ memory block which is allocated in the ACPI Nvs memory. APs are waken up and\r
+ spin around the relocated mailbox for further command.\r
+\r
+ @return EFI_PHYSICAL_ADDRESS Address of the relocated mailbox\r
+**/\r
+EFI_PHYSICAL_ADDRESS\r
+EFIAPI\r
+RelocateMailbox (\r
+ VOID\r
+ )\r
+{\r
+ EFI_PHYSICAL_ADDRESS Address;\r
+ VOID *ApLoopFunc;\r
+ UINT32 RelocationPages;\r
+ MP_RELOCATION_MAP RelocationMap;\r
+ MP_WAKEUP_MAILBOX *RelocatedMailBox;\r
+ EFI_STATUS Status;\r
+\r
+ Address = 0;\r
+ ApLoopFunc = NULL;\r
+ ZeroMem (&RelocationMap, sizeof (RelocationMap));\r
+\r
+ //\r
+ // Get information needed to setup aps running in their\r
+ // run loop in allocated acpi reserved memory\r
+ // Add another page for mailbox\r
+ //\r
+ AsmGetRelocationMap (&RelocationMap);\r
+ if ((RelocationMap.RelocateApLoopFuncAddress == 0) || (RelocationMap.RelocateApLoopFuncSize == 0)) {\r
+ DEBUG ((DEBUG_ERROR, "Failed to get the RelocationMap.\n"));\r
+ return 0;\r
+ }\r
+\r
+ RelocationPages = EFI_SIZE_TO_PAGES ((UINT32)RelocationMap.RelocateApLoopFuncSize) + 1;\r
+\r
+ Status = gBS->AllocatePages (AllocateAnyPages, EfiACPIMemoryNVS, RelocationPages, &Address);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Failed to allocate pages for MailboxRelocation. %r\n", Status));\r
+ return 0;\r
+ }\r
+\r
+ ZeroMem ((VOID *)Address, EFI_PAGES_TO_SIZE (RelocationPages));\r
+\r
+ ApLoopFunc = (VOID *)((UINTN)Address + EFI_PAGE_SIZE);\r
+\r
+ CopyMem (\r
+ ApLoopFunc,\r
+ RelocationMap.RelocateApLoopFuncAddress,\r
+ RelocationMap.RelocateApLoopFuncSize\r
+ );\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "Ap Relocation: mailbox %llx, loop %p\n",\r
+ Address,\r
+ ApLoopFunc\r
+ ));\r
+\r
+ //\r
+ // Initialize mailbox\r
+ //\r
+ RelocatedMailBox = (MP_WAKEUP_MAILBOX *)Address;\r
+ RelocatedMailBox->Command = MpProtectedModeWakeupCommandNoop;\r
+ RelocatedMailBox->ApicId = MP_CPU_PROTECTED_MODE_MAILBOX_APICID_INVALID;\r
+ RelocatedMailBox->WakeUpVector = 0;\r
+\r
+ //\r
+ // Wakup APs and have been move to the finalized run loop\r
+ // They will spin until guest OS wakes them\r
+ //\r
+ MpSerializeStart ();\r
+\r
+ MpSendWakeupCommand (\r
+ MpProtectedModeWakeupCommandWakeup,\r
+ (UINT64)ApLoopFunc,\r
+ (UINT64)RelocatedMailBox,\r
+ 0,\r
+ 0,\r
+ 0\r
+ );\r
+\r
+ return Address;\r
+}\r
+\r
+/**\r
+ Alter the MADT when ACPI Table from QEMU is available.\r
+\r
+ @param[in] Event Event whose notification function is being invoked\r
+ @param[in] Context Pointer to the notification function's context\r
+**/\r
+VOID\r
+EFIAPI\r
+AlterAcpiTable (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_ACPI_SDT_PROTOCOL *AcpiSdtProtocol;\r
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ EFI_ACPI_SDT_HEADER *Table;\r
+ EFI_ACPI_TABLE_VERSION Version;\r
+ UINTN OriginalTableKey;\r
+ UINTN NewTableKey;\r
+ UINT8 *NewMadtTable;\r
+ UINTN NewMadtTableLength;\r
+ EFI_PHYSICAL_ADDRESS RelocateMailboxAddress;\r
+ EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP_STRUCTURE *MadtMpWk;\r
+ EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtHeader;\r
+\r
+ Index = 0;\r
+ NewMadtTable = NULL;\r
+ MadtHeader = NULL;\r
+\r
+ Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (void **)&AcpiSdtProtocol);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Unable to locate ACPI SDT protocol.\n"));\r
+ return;\r
+ }\r
+\r
+ RelocateMailboxAddress = RelocateMailbox ();\r
+ if (RelocateMailboxAddress == 0) {\r
+ ASSERT (FALSE);\r
+ DEBUG ((DEBUG_ERROR, "Failed to relocate Td mailbox\n"));\r
+ return;\r
+ }\r
+\r
+ do {\r
+ Status = AcpiSdtProtocol->GetAcpiTable (Index, &Table, &Version, &OriginalTableKey);\r
+\r
+ if (!EFI_ERROR (Status) && (Table->Signature == EFI_ACPI_1_0_APIC_SIGNATURE)) {\r
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (void **)&AcpiTableProtocol);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Unable to locate ACPI Table protocol.\n"));\r
+ break;\r
+ }\r
+\r
+ NewMadtTableLength = Table->Length + sizeof (EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP_STRUCTURE);\r
+ NewMadtTable = AllocatePool (NewMadtTableLength);\r
+ if (NewMadtTable == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "%a: OUT_OF_SOURCES error.\n", __FUNCTION__));\r
+ break;\r
+ }\r
+\r
+ CopyMem (NewMadtTable, (UINT8 *)Table, Table->Length);\r
+ MadtHeader = (EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)NewMadtTable;\r
+ MadtHeader->Header.Length = (UINT32)NewMadtTableLength;\r
+\r
+ MadtMpWk = (EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP_STRUCTURE *)(NewMadtTable + Table->Length);\r
+ MadtMpWk->Type = EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP;\r
+ MadtMpWk->Length = sizeof (EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP_STRUCTURE);\r
+ MadtMpWk->MailBoxVersion = 1;\r
+ MadtMpWk->Reserved = 0;\r
+ MadtMpWk->MailBoxAddress = RelocateMailboxAddress;\r
+\r
+ Status = AcpiTableProtocol->InstallAcpiTable (AcpiTableProtocol, NewMadtTable, NewMadtTableLength, &NewTableKey);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Failed to install new MADT table. %r\n", Status));\r
+ break;\r
+ }\r
+\r
+ Status = AcpiTableProtocol->UninstallAcpiTable (AcpiTableProtocol, OriginalTableKey);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Uninstall old MADT table error.\n"));\r
+ }\r
+\r
+ break;\r
+ }\r
+\r
+ Index++;\r
+ } while (!EFI_ERROR (Status));\r
+\r
+ if (NewMadtTable != NULL) {\r
+ FreePool (NewMadtTable);\r
+ }\r
+}\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef TDX_ACPI_TABLE_H_\r
+#define TDX_ACPI_TABLE_H_\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/AcpiTable.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
+#include <Protocol/PciIo.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <IndustryStandard/IntelTdx.h>\r
+#include <IndustryStandard/Acpi.h>\r
+\r
+VOID\r
+EFIAPI\r
+AsmGetRelocationMap (\r
+ OUT MP_RELOCATION_MAP *AddressMap\r
+ );\r
+\r
+/**\r
+ At the beginning of system boot, a 4K-aligned, 4K-size memory (Td mailbox) is\r
+ pre-allocated by host VMM. BSP & APs do the page accept together in that memory\r
+ region.\r
+\r
+ After that TDVF is designed to relocate the mailbox to a 4K-aligned, 4K-size\r
+ memory block which is allocated in the ACPI Nvs memory. APs are waken up and\r
+ spin around the relocated mailbox for further command.\r
+\r
+ @return EFI_PHYSICAL_ADDRESS Address of the relocated mailbox\r
+**/\r
+EFI_PHYSICAL_ADDRESS\r
+EFIAPI\r
+RelocateMailbox (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Alter the MADT when ACPI Table from QEMU is available.\r
+\r
+ @param[in] Event Event whose notification function is being invoked\r
+ @param[in] Context Pointer to the notification function's context\r
+**/\r
+VOID\r
+EFIAPI\r
+AlterAcpiTable (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ );\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+\r
+ TDX Dxe driver. This driver is dispatched early in DXE, due to being list\r
+ in APRIORI.\r
+\r
+ This module is responsible for:\r
+ - Sets max logical cpus based on TDINFO\r
+ - Sets PCI PCDs based on resource hobs\r
+ - Alter MATD table to record address of Mailbox\r
+\r
+ Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Protocol/Cpu.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <IndustryStandard/Tdx.h>\r
+#include <Library/PlatformInitLib.h>\r
+#include <Library/TdxLib.h>\r
+#include <TdxAcpiTable.h>\r
+#include <Library/MemEncryptTdxLib.h>\r
+\r
+/**\r
+ Location of resource hob matching type and starting address\r
+\r
+ @param[in] Type The type of resource hob to locate.\r
+\r
+ @param[in] Start The resource hob must at least begin at address.\r
+\r
+ @retval pointer to resource Return pointer to a resource hob that matches or NULL.\r
+**/\r
+STATIC\r
+EFI_HOB_RESOURCE_DESCRIPTOR *\r
+GetResourceDescriptor (\r
+ EFI_RESOURCE_TYPE Type,\r
+ EFI_PHYSICAL_ADDRESS Start,\r
+ EFI_PHYSICAL_ADDRESS End\r
+ )\r
+{\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResourceDescriptor = NULL;\r
+\r
+ Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);\r
+ while (Hob.Raw != NULL) {\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a:%d: resource type 0x%x %llx %llx\n",\r
+ __func__,\r
+ __LINE__,\r
+ Hob.ResourceDescriptor->ResourceType,\r
+ Hob.ResourceDescriptor->PhysicalStart,\r
+ Hob.ResourceDescriptor->ResourceLength\r
+ ));\r
+\r
+ if ((Hob.ResourceDescriptor->ResourceType == Type) &&\r
+ (Hob.ResourceDescriptor->PhysicalStart >= Start) &&\r
+ ((Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength) < End))\r
+ {\r
+ ResourceDescriptor = Hob.ResourceDescriptor;\r
+ break;\r
+ }\r
+\r
+ Hob.Raw = GET_NEXT_HOB (Hob);\r
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);\r
+ }\r
+\r
+ return ResourceDescriptor;\r
+}\r
+\r
+/**\r
+ Location of resource hob matching type and highest address below end\r
+\r
+ @param[in] Type The type of resource hob to locate.\r
+\r
+ @param[in] End The resource hob return is the closest to the End address\r
+\r
+ @retval pointer to resource Return pointer to a resource hob that matches or NULL.\r
+**/\r
+STATIC\r
+EFI_HOB_RESOURCE_DESCRIPTOR *\r
+GetHighestResourceDescriptor (\r
+ EFI_RESOURCE_TYPE Type,\r
+ EFI_PHYSICAL_ADDRESS End\r
+ )\r
+{\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResourceDescriptor = NULL;\r
+\r
+ Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);\r
+ while (Hob.Raw != NULL) {\r
+ if ((Hob.ResourceDescriptor->ResourceType == Type) &&\r
+ (Hob.ResourceDescriptor->PhysicalStart < End))\r
+ {\r
+ if (!ResourceDescriptor ||\r
+ (ResourceDescriptor->PhysicalStart < Hob.ResourceDescriptor->PhysicalStart))\r
+ {\r
+ ResourceDescriptor = Hob.ResourceDescriptor;\r
+ }\r
+ }\r
+\r
+ Hob.Raw = GET_NEXT_HOB (Hob);\r
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);\r
+ }\r
+\r
+ return ResourceDescriptor;\r
+}\r
+\r
+/**\r
+ Set the shared bit for mmio region in Tdx guest.\r
+\r
+ In Tdx guest there are 2 ways to access mmio, TdVmcall or direct access.\r
+ For direct access, the shared bit of the PageTableEntry should be set.\r
+ The mmio region information is retrieved from hob list.\r
+\r
+ @retval EFI_SUCCESS The shared bit is set successfully.\r
+ @retval EFI_UNSUPPORTED Setting the shared bit of memory region\r
+ is not supported\r
+**/\r
+EFI_STATUS\r
+SetMmioSharedBit (\r
+ VOID\r
+ )\r
+{\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+\r
+ Hob.Raw = (UINT8 *)GetHobList ();\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
+ && (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_MAPPED_IO))\r
+ {\r
+ MemEncryptTdxSetPageSharedBit (\r
+ 0,\r
+ Hob.ResourceDescriptor->PhysicalStart,\r
+ EFI_SIZE_TO_PAGES (Hob.ResourceDescriptor->ResourceLength)\r
+ );\r
+ }\r
+\r
+ Hob.Raw = GET_NEXT_HOB (Hob);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+TdxDxeEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ RETURN_STATUS PcdStatus;\r
+ EFI_HOB_RESOURCE_DESCRIPTOR *Res = NULL;\r
+ EFI_HOB_RESOURCE_DESCRIPTOR *MemRes = NULL;\r
+ EFI_HOB_PLATFORM_INFO *PlatformInfo = NULL;\r
+ EFI_HOB_GUID_TYPE *GuidHob;\r
+ UINT32 CpuMaxLogicalProcessorNumber;\r
+ TD_RETURN_DATA TdReturnData;\r
+ EFI_EVENT QemuAcpiTableEvent;\r
+ void *Registration;\r
+\r
+ GuidHob = GetFirstGuidHob (&gUefiOvmfPkgPlatformInfoGuid);\r
+\r
+ if (GuidHob == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Both Td and Non-Td guest have PlatformInfoHob which contains the HostBridgePciDevId\r
+ //\r
+ PlatformInfo = (EFI_HOB_PLATFORM_INFO *)GET_GUID_HOB_DATA (GuidHob);\r
+ ASSERT (PlatformInfo->HostBridgeDevId != 0);\r
+ PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, PlatformInfo->HostBridgeDevId);\r
+ ASSERT_RETURN_ERROR (PcdStatus);\r
+\r
+ if (!TdIsEnabled ()) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ SetMmioSharedBit ();\r
+\r
+ //\r
+ // Call TDINFO to get actual number of cpus in domain\r
+ //\r
+ Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);\r
+ ASSERT (Status == EFI_SUCCESS);\r
+\r
+ CpuMaxLogicalProcessorNumber = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);\r
+\r
+ //\r
+ // Adjust PcdCpuMaxLogicalProcessorNumber, if needed. If firmware is configured for\r
+ // more than number of reported cpus, update.\r
+ //\r
+ if (CpuMaxLogicalProcessorNumber > TdReturnData.TdInfo.NumVcpus) {\r
+ PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, TdReturnData.TdInfo.NumVcpus);\r
+ ASSERT_RETURN_ERROR (PcdStatus);\r
+ }\r
+\r
+ //\r
+ // Register for protocol notifications to call the AlterAcpiTable(),\r
+ // the protocol will be installed in AcpiPlatformDxe when the ACPI\r
+ // table provided by Qemu is ready.\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_CALLBACK,\r
+ AlterAcpiTable,\r
+ NULL,\r
+ &QemuAcpiTableEvent\r
+ );\r
+\r
+ Status = gBS->RegisterProtocolNotify (\r
+ &gQemuAcpiTableNotifyProtocolGuid,\r
+ QemuAcpiTableEvent,\r
+ &Registration\r
+ );\r
+\r
+ #define INIT_PCDSET(NAME, RES) do {\\r
+ PcdStatus = PcdSet64S (NAME##Base, (RES)->PhysicalStart); \\r
+ ASSERT_RETURN_ERROR (PcdStatus); \\r
+ PcdStatus = PcdSet64S (NAME##Size, (RES)->ResourceLength); \\r
+ ASSERT_RETURN_ERROR (PcdStatus); \\r
+} while(0)\r
+\r
+ if (PlatformInfo) {\r
+ PcdSet16S (PcdOvmfHostBridgePciDevId, PlatformInfo->HostBridgeDevId);\r
+\r
+ if ((Res = GetResourceDescriptor (EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_PHYSICAL_ADDRESS)0x100000000, (EFI_PHYSICAL_ADDRESS)-1)) != NULL) {\r
+ INIT_PCDSET (PcdPciMmio64, Res);\r
+ }\r
+\r
+ if ((Res = GetResourceDescriptor (EFI_RESOURCE_IO, 0, 0x10001)) != NULL) {\r
+ INIT_PCDSET (PcdPciIo, Res);\r
+ }\r
+\r
+ //\r
+ // To find low mmio, first find top of low memory, and then search for io space.\r
+ //\r
+ if ((MemRes = GetHighestResourceDescriptor (EFI_RESOURCE_SYSTEM_MEMORY, 0xffc00000)) != NULL) {\r
+ if ((Res = GetResourceDescriptor (EFI_RESOURCE_MEMORY_MAPPED_IO, MemRes->PhysicalStart, 0x100000000)) != NULL) {\r
+ INIT_PCDSET (PcdPciMmio32, Res);\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+#/** @file\r
+#\r
+# Driver clears the encryption attribute from MMIO regions when TDX is enabled\r
+#\r
+# Copyright (c) 2017, AMD Inc. All rights reserved.<BR>\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+#**/\r
+\r
+[Defines]\r
+ INF_VERSION = 1.25\r
+ BASE_NAME = TdxDxe\r
+ FILE_GUID = E750224E-7BCE-40AF-B5BB-47E3611EB5C2\r
+ MODULE_TYPE = DXE_DRIVER\r
+ VERSION_STRING = 1.0\r
+ ENTRY_POINT = TdxDxeEntryPoint\r
+\r
+[Sources]\r
+ TdxDxe.c\r
+ TdxAcpiTable.c\r
+ X64/ApRunLoop.nasm\r
+\r
+[Packages]\r
+ MdeModulePkg/MdeModulePkg.dec\r
+ MdePkg/MdePkg.dec\r
+ UefiCpuPkg/UefiCpuPkg.dec\r
+ OvmfPkg/OvmfPkg.dec\r
+\r
+[LibraryClasses]\r
+ BaseLib\r
+ BaseMemoryLib\r
+ DebugLib\r
+ DxeServicesTableLib\r
+ MemoryAllocationLib\r
+ PcdLib\r
+ UefiDriverEntryPoint\r
+ TdxLib\r
+ HobLib\r
+ TdxMailboxLib\r
+ MemEncryptTdxLib\r
+\r
+[Depex]\r
+ TRUE\r
+\r
+[Guids]\r
+ gUefiOvmfPkgPlatformInfoGuid ## CONSUMES\r
+\r
+[Protocols]\r
+ gQemuAcpiTableNotifyProtocolGuid ## CONSUMES\r
+ gEfiAcpiSdtProtocolGuid ## CONSUMES\r
+ gEfiAcpiTableProtocolGuid ## CONSUMES\r
+\r
+[Pcd]\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId\r
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber\r
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress\r
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress\r
--- /dev/null
+;------------------------------------------------------------------------------ ;\r
+; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;\r
+; Module Name:\r
+;\r
+; ApRunLoop.nasm\r
+;\r
+; Abstract:\r
+;\r
+; This is the assembly code for run loop for APs in the guest TD\r
+;\r
+;-------------------------------------------------------------------------------\r
+\r
+%include "TdxCommondefs.inc"\r
+\r
+DEFAULT REL\r
+\r
+SECTION .text\r
+\r
+BITS 64\r
+\r
+%define TDVMCALL_EXPOSE_REGS_MASK 0xffec\r
+%define TDVMCALL 0x0\r
+%define EXIT_REASON_CPUID 0xa\r
+\r
+%macro tdcall 0\r
+ db 0x66, 0x0f, 0x01, 0xcc\r
+%endmacro\r
+\r
+;\r
+; Relocated Ap Mailbox loop\r
+;\r
+; @param[in] RBX: Relocated mailbox address\r
+; @param[in] RBP: vCpuId\r
+;\r
+; @return None This routine does not return\r
+;\r
+global ASM_PFX(AsmRelocateApMailBoxLoop)\r
+ASM_PFX(AsmRelocateApMailBoxLoop):\r
+AsmRelocateApMailBoxLoopStart:\r
+\r
+ mov rax, TDVMCALL\r
+ mov rcx, TDVMCALL_EXPOSE_REGS_MASK\r
+ mov r11, EXIT_REASON_CPUID\r
+ mov r12, 0xb\r
+ tdcall\r
+ test rax, rax\r
+ jnz Panic\r
+ mov r8, r15\r
+\r
+MailBoxLoop:\r
+ ; Spin until command set\r
+ cmp dword [rbx + CommandOffset], MpProtectedModeWakeupCommandNoop\r
+ je MailBoxLoop\r
+ ; Determine if this is a broadcast or directly for my apic-id, if not, ignore\r
+ cmp dword [rbx + ApicidOffset], MailboxApicidBroadcast\r
+ je MailBoxProcessCommand\r
+ cmp dword [rbx + ApicidOffset], r8d\r
+ jne MailBoxLoop\r
+MailBoxProcessCommand:\r
+ cmp dword [rbx + CommandOffset], MpProtectedModeWakeupCommandWakeup\r
+ je MailBoxWakeUp\r
+ cmp dword [rbx + CommandOffset], MpProtectedModeWakeupCommandSleep\r
+ je MailBoxSleep\r
+ ; Don't support this command, so ignore\r
+ jmp MailBoxLoop\r
+MailBoxWakeUp:\r
+ mov rax, [rbx + WakeupVectorOffset]\r
+ ; OS sends a wakeup command for a given APIC ID, firmware is supposed to reset\r
+ ; the command field back to zero as acknowledgement.\r
+ mov qword [rbx + WakeupVectorOffset], 0\r
+ jmp rax\r
+MailBoxSleep:\r
+ jmp $\r
+Panic:\r
+ ud2\r
+BITS 64\r
+AsmRelocateApMailBoxLoopEnd:\r
+\r
+;-------------------------------------------------------------------------------------\r
+; AsmGetRelocationMap (&RelocationMap);\r
+;-------------------------------------------------------------------------------------\r
+global ASM_PFX(AsmGetRelocationMap)\r
+ASM_PFX(AsmGetRelocationMap):\r
+ lea rax, [ASM_PFX(AsmRelocateApMailBoxLoopStart)]\r
+ mov qword [rcx], rax\r
+ mov qword [rcx + 8h], AsmRelocateApMailBoxLoopEnd - AsmRelocateApMailBoxLoopStart\r
+ ret\r
+\r