From b8302ed483369ebe719b91e223eeb921ab48d8f0 Mon Sep 17 00:00:00 2001 From: John Starks Date: Fri, 15 May 2026 12:01:09 -0700 Subject: [PATCH 1/3] AcpiPlatform: use GUIDed HOBs for VMM-provided ACPI tables Instead of having a dedicated config blob type, PCD pair, and DXE installer function for each ACPI table the VMM can provide (MADT, SRAT, SLIT, PPTT, HMAT, MCFG, SSDT, IORT, ASPT), use a single generic path: PEI validates the embedded ACPI header and emits a GUIDed HOB; DXE iterates the HOB list and installs each table, suppressing the matching FV-resident default. The MADT installer is kept for the IGVM/TDX path, which needs to post-process the table (MP wakeup mailbox), but is now a no-op when the PCDs are unset. The IGVM SRAT is emitted as a HOB. The NFIT installer is unrelated (synthesized from BIOS device MMIO) and is unchanged. PciHostBridgeLib and PciSegmentInfoLib now read MCFG directly from the HOB list, removing PcdMcfgPtr/PcdMcfgSize. --- MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c | 662 ++++-------------- MsvmPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf | 22 +- MsvmPkg/Include/AcpiReplacementTable.h | 23 + .../PciHostBridgeLib/PciHostBridgeLib.c | 40 +- .../PciHostBridgeLib/PciHostBridgeLib.inf | 6 +- .../PciSegmentInfoLib/PciSegmentInfoLib.c | 38 +- .../PciSegmentInfoLib/PciSegmentInfoLib.inf | 7 +- MsvmPkg/MsvmPkg.dec | 5 + MsvmPkg/PlatformPei/Config.c | 201 +----- MsvmPkg/PlatformPei/IgvmConfig.c | 9 +- MsvmPkg/PlatformPei/Platform.c | 104 +-- MsvmPkg/PlatformPei/PlatformPei.inf | 19 +- 12 files changed, 287 insertions(+), 849 deletions(-) create mode 100644 MsvmPkg/Include/AcpiReplacementTable.h diff --git a/MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c b/MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c index 7c123103ce..9893be3229 100644 --- a/MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c +++ b/MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c @@ -12,12 +12,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include typedef EFI_STATUS (*INIT_ROUTINE)(EFI_ACPI_DESCRIPTION_HEADER*); @@ -82,6 +84,99 @@ Return Value: } +BOOLEAN +AcpiSignatureHasReplacementHob( + IN UINT32 Signature + ) +/*++ + +Routine Description: + + Checks whether a VMM-provided replacement table exists in the HOB list + for the given ACPI table signature. + +Arguments: + + Signature - The 4-byte ACPI table signature to look for. + +Return Value: + + TRUE if a replacement HOB exists, FALSE otherwise. + +--*/ +{ + EFI_PEI_HOB_POINTERS hob; + + hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); + while (hob.Raw != NULL) + { + EFI_ACPI_DESCRIPTION_HEADER *table = + (EFI_ACPI_DESCRIPTION_HEADER *) GET_GUID_HOB_DATA(hob.Guid); + + if (table->Signature == Signature) + { + return TRUE; + } + + hob.Raw = GetNextGuidHob(&gAcpiReplacementTableHobGuid, GET_NEXT_HOB(hob)); + } + + return FALSE; +} + + +EFI_STATUS +AcpiInstallReplacementTables( + IN EFI_ACPI_TABLE_PROTOCOL *AcpiTable + ) +/*++ + +Routine Description: + + Installs all VMM-provided ACPI replacement tables found in the HOB list. + +Arguments: + + AcpiTable - A pointer to the ACPI table protocol. + +Return Value: + + EFI_STATUS. + +--*/ +{ + EFI_PEI_HOB_POINTERS hob; + EFI_STATUS status; + UINTN tableHandle; + + hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); + while (hob.Raw != NULL) + { + EFI_ACPI_DESCRIPTION_HEADER *table = + (EFI_ACPI_DESCRIPTION_HEADER *) GET_GUID_HOB_DATA(hob.Guid); + + DEBUG((DEBUG_INFO, "Installing VMM-provided ACPI table: %.4a (0x%08x)\n", + (CHAR8 *)&table->Signature, table->Signature)); + + status = AcpiTable->InstallAcpiTable(AcpiTable, + table, + table->Length, + &tableHandle); + + if (EFI_ERROR(status)) + { + DEBUG((DEBUG_ERROR, "Failed to install VMM replacement table 0x%08x: %r\n", + table->Signature, status)); + return status; + } + + hob.Raw = GetNextGuidHob(&gAcpiReplacementTableHobGuid, GET_NEXT_HOB(hob)); + } + + return EFI_SUCCESS; +} + + EFI_STATUS LocateFvInstanceWithTables( OUT EFI_FIRMWARE_VOLUME2_PROTOCOL** Instance @@ -218,9 +313,17 @@ Return Value: // - // Get the MADT from the config blob parsed in PEI. + // Get the MADT from the IGVM config parsed in PEI. This is only set for + // hardware-isolated VMs (TDX); non-isolated VMs provide the MADT via the + // generic ACPI table HOB path instead. // madtSize = PcdGet32(PcdMadtSize); + + if (madtSize == 0) + { + return EFI_SUCCESS; + } + table = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) PcdGet64(PcdMadtPtr); FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR_IF_FALSE(table->Length == madtSize); @@ -325,195 +428,6 @@ Return Value: } -EFI_STATUS -AcpiInstallSratTable( - IN OUT EFI_ACPI_TABLE_PROTOCOL *AcpiTable - ) -/*++ - -Routine Description: - - Retrieves the SRAT table from the worker process and installs it. - -Arguments: - - AcpiTable - A pointer to the ACPI table protocol. - -Return Value: - - EFI_STATUS. - ---*/ -{ - EFI_STATUS status; - EFI_ACPI_DESCRIPTION_HEADER *table; - UINTN tableHandle; - UINT32 sratSize; - - // - // Get the SRAT from the config blob parsed in PEI. - // - sratSize = PcdGet32(PcdSratSize); - table = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) PcdGet64(PcdSratPtr); - - ASSERT(table->Length == sratSize); - - // - // Install it into the published tables. - // - status = AcpiTable->InstallAcpiTable(AcpiTable, - table, - table->Length, - &tableHandle); - - return status; -} - - -EFI_STATUS -AcpiInstallHmatTable( - IN OUT EFI_ACPI_TABLE_PROTOCOL *AcpiTable - ) -/*++ - -Routine Description: - - Retrieves the HMAT table from the worker process and installs it. - -Arguments: - - AcpiTable - A pointer to the ACPI table protocol. - -Return Value: - - EFI_STATUS. - ---*/ -{ - EFI_STATUS status; - EFI_ACPI_DESCRIPTION_HEADER *table; - UINTN tableHandle; - UINT32 tableSize; - - tableSize = PcdGet32(PcdHmatSize); - table = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) PcdGet64(PcdHmatPtr); - - if (tableSize == 0) - { - ASSERT(table == NULL); - DEBUG((EFI_D_INFO, "HMAT not installed.\n")); - return EFI_SUCCESS; - } - - ASSERT(table->Length == tableSize); - - status = AcpiTable->InstallAcpiTable(AcpiTable, - table, - table->Length, - &tableHandle); - - return status; -} - - -EFI_STATUS -AcpiInstallPpttTable( - IN OUT EFI_ACPI_TABLE_PROTOCOL *AcpiTable - ) -/*++ - -Routine Description: - - Retrieves the PPTT table from the worker process and installs it. - -Arguments: - - AcpiTable - A pointer to the ACPI table protocol. - -Return Value: - - EFI_STATUS. - ---*/ -{ - EFI_STATUS status; - EFI_ACPI_DESCRIPTION_HEADER *table; - UINTN tableHandle; - UINT32 tableSize; - - tableSize = PcdGet32(PcdPpttSize); - table = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) PcdGet64(PcdPpttPtr); - - if (tableSize == 0) - { - ASSERT(table == NULL); - DEBUG((EFI_D_INFO, "PPTT not installed.\n")); - return EFI_SUCCESS; - } - - ASSERT(table->Length == tableSize); - - status = AcpiTable->InstallAcpiTable(AcpiTable, - table, - table->Length, - &tableHandle); - - return status; -} - - -EFI_STATUS -AcpiInstallSlitTable( - IN OUT EFI_ACPI_TABLE_PROTOCOL *AcpiTable - ) -/*++ - -Routine Description: - - Retrieves the SLIT table from the worker process and installs it. - -Arguments: - - AcpiTable - A pointer to the ACPI table protocol. - -Return Value: - - EFI_STATUS. - ---*/ -{ - EFI_STATUS status; - EFI_ACPI_DESCRIPTION_HEADER *table; - UINTN tableHandle; - UINT32 slitSize; - - // - // Get the SLIT from the config blob parsed in PEI. - // - slitSize = PcdGet32(PcdSlitSize); - table = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) PcdGet64(PcdSlitPtr); - - if (slitSize == 0) - { - ASSERT(table == NULL); - DEBUG((EFI_D_INFO, "SLIT not installed.\n")); - return EFI_SUCCESS; - } - - ASSERT(table->Length == slitSize); - - // - // Install it into the published tables. - // - status = AcpiTable->InstallAcpiTable(AcpiTable, - table, - table->Length, - &tableHandle); - - return status; -} - - EFI_STATUS AcpiInstallNfitTable( IN OUT EFI_ACPI_TABLE_PROTOCOL *AcpiTable @@ -589,281 +503,6 @@ AcpiInstallNfitTable( } -EFI_STATUS -AcpiInstallConfigStructTable( - IN OUT EFI_ACPI_TABLE_PROTOCOL *AcpiTable - ) -/*++ - -Routine Description: - - Retrieves the config struct table if present and installs it. - -Arguments: - - AcpiTable - A pointer to the ACPI table protocol. - -Return Value: - - EFI_STATUS. - ---*/ -{ - EFI_STATUS status; - EFI_ACPI_DESCRIPTION_HEADER *table; - UINTN tableHandle; - UINT32 tableSize; - - // - // Get the table from the config blob parsed in PEI. It may not be present. - // - tableSize = PcdGet32(PcdAcpiTableSize); - - if (tableSize == 0) - { - return EFI_SUCCESS; - } - - table = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) PcdGet64(PcdAcpiTablePtr); - - ASSERT(table->Length == tableSize); - - // - // Install it into the published tables. - // - status = AcpiTable->InstallAcpiTable(AcpiTable, - table, - table->Length, - &tableHandle); - - return status; -} - - -#if defined(MDE_CPU_X64) -EFI_STATUS -AcpiInstallAsptTable( - IN OUT EFI_ACPI_TABLE_PROTOCOL *AcpiTable - ) -/*++ - -Routine Description: - - Retrieves the ASPT table from the worker process and installs it. - -Arguments: - - AcpiTable - A pointer to the ACPI table protocol. - -Return Value: - - EFI_STATUS. - ---*/ -{ - EFI_STATUS status; - EFI_ACPI_DESCRIPTION_HEADER *table; - UINTN tableHandle; - UINT32 asptSize; - - // - // Get the ASPT from the config blob parsed in PEI. - // - asptSize = PcdGet32(PcdAsptSize); - table = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) PcdGet64(PcdAsptPtr); - - if (asptSize == 0) - { - // - // The ASPT will not be provided if no compatible AMD Secure Processor - // is enabled. - // - return EFI_SUCCESS; - } - - ASSERT(table->Length == asptSize); - - // - // Install it into the published tables. - // - status = AcpiTable->InstallAcpiTable(AcpiTable, - table, - table->Length, - &tableHandle); - - return status; -} -#endif - - -EFI_STATUS -AcpiInstallMcfgTable( - EFI_ACPI_TABLE_PROTOCOL *AcpiTable - ) -/*++ - -Routine Description: - - Retrieves the MCFG table from the worker process and installs it. - -Arguments: - - AcpiTable - A pointer to the ACPI table protocol. - -Return Value: - - EFI_STATUS. - ---*/ -{ - EFI_STATUS status; - EFI_ACPI_DESCRIPTION_HEADER *table; - UINTN tableHandle; - UINT32 tableSize; - - // - // Get the table from the config blob parsed in PEI. It may not be present. - // - tableSize = PcdGet32(PcdMcfgSize); - - if (tableSize == 0) - { - return EFI_SUCCESS; - } - - table = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) PcdGet64(PcdMcfgPtr); - - if (table == NULL) - { - return EFI_NOT_FOUND; - } - - ASSERT(table->Length == tableSize); - - // - // Install it into the published tables. - // - status = AcpiTable->InstallAcpiTable(AcpiTable, - table, - table->Length, - &tableHandle); - - return status; -} - - -EFI_STATUS -AcpiInstallSsdtTable( - EFI_ACPI_TABLE_PROTOCOL *AcpiTable - ) -/*++ - -Routine Description: - - Retrieves the SSDT table from the worker process and installs it. - -Arguments: - - AcpiTable - A pointer to the ACPI table protocol. - -Return Value: - - EFI_STATUS. - ---*/ -{ - EFI_STATUS status; - EFI_ACPI_DESCRIPTION_HEADER *table; - UINTN tableHandle; - UINT32 tableSize; - - // - // Get the table from the config blob parsed in PEI. It may not be present. - // - tableSize = PcdGet32(PcdSsdtSize); - - if (tableSize == 0) - { - return EFI_SUCCESS; - } - - table = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) PcdGet64(PcdSsdtPtr); - - if (table == NULL) - { - return EFI_NOT_FOUND; - } - - ASSERT(table->Length == tableSize); - - // - // Install it into the published tables. - // - status = AcpiTable->InstallAcpiTable(AcpiTable, - table, - table->Length, - &tableHandle); - - return status; -} - - -EFI_STATUS -AcpiInstallIortTable( - EFI_ACPI_TABLE_PROTOCOL *AcpiTable - ) -/*++ - -Routine Description: - - Retrieves the IORT table from the worker process and installs it. - -Arguments: - - AcpiTable - A pointer to the ACPI table protocol. - -Return Value: - - EFI_STATUS. - ---*/ -{ - EFI_STATUS status; - EFI_ACPI_DESCRIPTION_HEADER *table; - UINTN tableHandle; - UINT32 tableSize; - - // - // Get the table from the config blob parsed in PEI. It may not be present. - // - tableSize = PcdGet32(PcdIortSize); - - if (tableSize == 0) - { - return EFI_SUCCESS; - } - - table = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) PcdGet64(PcdIortPtr); - - if (table == NULL) - { - return EFI_NOT_FOUND; - } - - ASSERT(table->Length == tableSize); - - // - // Install it into the published tables. - // - status = AcpiTable->InstallAcpiTable(AcpiTable, - table, - table->Length, - &tableHandle); - - return status; -} - - EFI_STATUS EFIAPI AcpiPlatformInitializeAcpiTables( @@ -944,6 +583,17 @@ Return Value: // ASSERT(size >= currentTable->Length); + // + // If the VMM provided a replacement for this table, skip the FV version. + // + if (AcpiSignatureHasReplacementHob(currentTable->Signature)) + { + DEBUG((DEBUG_INFO, "Skipping FV table %.4a (0x%08x): VMM replacement provided\n", + (CHAR8 *)¤tTable->Signature, currentTable->Signature)); + gBS->FreePool(currentTable); + continue; + } + status = RuntimeInitializeTableIfNecessary(currentTable); if (EFI_ERROR(status)) @@ -980,36 +630,18 @@ Return Value: } // - // Add the MADT table. - // - status = AcpiInstallMadtTable(acpiTable); - if (EFI_ERROR(status)) - { - goto Cleanup; - } - - // - // Add the SRAT table. - // - status = AcpiInstallSratTable(acpiTable); - if (EFI_ERROR(status)) - { - goto Cleanup; - } - - // - // Add the PPTT table. + // Install all VMM-provided replacement tables from HOBs. // - status = AcpiInstallPpttTable(acpiTable); + status = AcpiInstallReplacementTables(acpiTable); if (EFI_ERROR(status)) { goto Cleanup; } // - // Add the SLIT table. + // Add the MADT table. // - status = AcpiInstallSlitTable(acpiTable); + status = AcpiInstallMadtTable(acpiTable); if (EFI_ERROR(status)) { goto Cleanup; @@ -1024,62 +656,6 @@ Return Value: goto Cleanup; } -#if defined(MDE_CPU_X64) - // - // Add the ASPT table. - // - status = AcpiInstallAsptTable(acpiTable); - if (EFI_ERROR(status)) - { - goto Cleanup; - } -#endif - - // - // Add the dynamic config struct table if present. - // - status = AcpiInstallConfigStructTable(acpiTable); - if (EFI_ERROR(status)) - { - goto Cleanup; - } - - // - // Add the MCFG table if present. - // - status = AcpiInstallMcfgTable(acpiTable); - if (EFI_ERROR(status)) - { - goto Cleanup; - } - - // - // Add the SSDT table if present. - // - status = AcpiInstallSsdtTable(acpiTable); - if (EFI_ERROR(status)) - { - goto Cleanup; - } - - // - // Install the IORT table if present - // - status = AcpiInstallIortTable(acpiTable); - if (EFI_ERROR(status)) - { - goto Cleanup; - } - - // - // Add the HMAT table if present. - // - status = AcpiInstallHmatTable(acpiTable); - if (EFI_ERROR(status)) - { - goto Cleanup; - } - status = EFI_SUCCESS; Cleanup: diff --git a/MsvmPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/MsvmPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf index 02ee5827d4..ebe459e0fe 100644 --- a/MsvmPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf +++ b/MsvmPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf @@ -37,6 +37,7 @@ CrashLib DebugLib DxeServicesLib + HobLib IoLib IsolationLib PcdLib @@ -44,6 +45,9 @@ UefiDriverEntryPoint UefiLib +[Guids] + gAcpiReplacementTableHobGuid ## CONSUMES + [Protocols] gEfiAcpiTableProtocolGuid ## CONSUMES @@ -53,8 +57,6 @@ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdAcpiTablePtr ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdAcpiTableSize ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdBiosBaseAddress ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdCom1RegisterBase ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdCom1Vector ## CONSUMES @@ -73,34 +75,18 @@ gMsvmPkgTokenSpaceGuid.PcdLowPowerS0IdleEnabled ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdMadtPtr ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdMadtSize ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdMcfgPtr ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdMcfgSize ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdSsdtPtr ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdSsdtSize ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdIortPtr ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdIortSize ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdNvdimmCount ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdPpttPtr ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdPpttSize ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdProcessorCount ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdProcIdleEnabled ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdCxlMemoryEnabled ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdSerialControllersEnabled ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdSgxMemoryEnabled ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdSlitPtr ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdSlitSize ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdSratPtr ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdSratSize ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdHmatPtr ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdHmatSize ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdTpmEnabled ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdVirtualBatteryEnabled ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdWatchdogEnabled ## CONSUMES [Pcd.X64] gMsvmPkgTokenSpaceGuid.PcdAcpiMadtMpMailBoxAddress ## PRODUCES - gMsvmPkgTokenSpaceGuid.PcdAsptPtr ## CONSUMES - gMsvmPkgTokenSpaceGuid.PcdAsptSize ## CONSUMES [Depex] gEfiAcpiTableProtocolGuid diff --git a/MsvmPkg/Include/AcpiReplacementTable.h b/MsvmPkg/Include/AcpiReplacementTable.h new file mode 100644 index 0000000000..18a7f27214 --- /dev/null +++ b/MsvmPkg/Include/AcpiReplacementTable.h @@ -0,0 +1,23 @@ +/** @file + Shared definitions for VMM-provided ACPI table replacements passed via HOBs. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#pragma once + +#include + +// +// GUID used to identify ACPI replacement table HOBs. +// Each HOB with this GUID contains a complete ACPI table starting with +// EFI_ACPI_DESCRIPTION_HEADER. When an ACPI table from the firmware volume +// has the same signature as a replacement table HOB, the FV table is +// suppressed and the HOB-provided table is installed instead. +// +#define ACPI_REPLACEMENT_TABLE_HOB_GUID \ + { 0xa24aef4c, 0xa824, 0x48e9, { 0xb5, 0xb8, 0xbc, 0xd9, 0x6a, 0x59, 0x71, 0xaf } } + +extern EFI_GUID gAcpiReplacementTableHobGuid; diff --git a/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c index 7aa0e01cfc..a46e332403 100644 --- a/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c +++ b/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -1,8 +1,8 @@ /** @file Platform PCI Host Bridge Library for Hyper-V Gen2 VMs. - Reads MCFG + PcieBarApertures from config blob PCDs and returns - a PCI_ROOT_BRIDGE array for PciHostBridgeDxe. + Reads MCFG from the ACPI replacement table HOB + PcieBarApertures from + config blob PCDs and returns a PCI_ROOT_BRIDGE array for PciHostBridgeDxe. Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #include #include @@ -62,9 +64,6 @@ PciHostBridgeGetRootBridges ( OUT UINTN *Count ) { - UINT64 McfgPtr; - UINT32 McfgSize; - MCFG_TABLE_HEADER *McfgHdr; UINT32 McfgDataLen; UINT32 McfgEntryCount; MCFG_ALLOCATION_ENTRY *McfgEntries; @@ -80,24 +79,27 @@ PciHostBridgeGetRootBridges ( *Count = 0; // - // Read MCFG from PCD. + // Find MCFG table from HOB list. // - McfgPtr = PcdGet64 (PcdMcfgPtr); - McfgSize = PcdGet32 (PcdMcfgSize); - - DEBUG ((DEBUG_VERBOSE, "PCIe: PciHostBridgeLib McfgPtr=0x%lx McfgSize=%u\n", McfgPtr, McfgSize)); - - if (McfgPtr == 0 || McfgSize < sizeof (MCFG_TABLE_HEADER)) { - DEBUG ((DEBUG_INFO, "PCIe: No MCFG table, no root bridges\n")); - return NULL; + EFI_PEI_HOB_POINTERS hob; + MCFG_TABLE_HEADER *McfgHdr = NULL; + + hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); + while (hob.Raw != NULL) + { + EFI_ACPI_DESCRIPTION_HEADER *acpiHdr = (EFI_ACPI_DESCRIPTION_HEADER *)GET_GUID_HOB_DATA(hob.Guid); + if (acpiHdr->Signature == EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE) + { + McfgHdr = (MCFG_TABLE_HEADER *)acpiHdr; + break; + } + hob.Raw = GetNextGuidHob(&gAcpiReplacementTableHobGuid, GET_NEXT_HOB(hob)); } - McfgHdr = (MCFG_TABLE_HEADER *)(UINTN)McfgPtr; + DEBUG ((DEBUG_VERBOSE, "PCIe: PciHostBridgeLib McfgHdr=%p\n", McfgHdr)); - if (McfgHdr->Header.Length < sizeof (MCFG_TABLE_HEADER) || - McfgHdr->Header.Length > McfgSize) { - DEBUG ((DEBUG_ERROR, "PCIe: Invalid MCFG Length %u (PCD size %u)\n", - McfgHdr->Header.Length, McfgSize)); + if (McfgHdr == NULL || McfgHdr->Header.Length < sizeof(MCFG_TABLE_HEADER)) { + DEBUG ((DEBUG_INFO, "PCIe: No MCFG table, no root bridges\n")); return NULL; } diff --git a/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf index 31c3e5897e..9fe150e887 100644 --- a/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf +++ b/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf @@ -25,12 +25,14 @@ [LibraryClasses] BaseMemoryLib DebugLib + HobLib PcdLib MemoryAllocationLib DevicePathLib [Pcd] - gMsvmPkgTokenSpaceGuid.PcdMcfgPtr - gMsvmPkgTokenSpaceGuid.PcdMcfgSize gMsvmPkgTokenSpaceGuid.PcdPcieBarAperturesPtr gMsvmPkgTokenSpaceGuid.PcdPcieBarAperturesSize + +[Guids] + gAcpiReplacementTableHobGuid diff --git a/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.c b/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.c index 788a455e2f..ebb24e7626 100644 --- a/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.c +++ b/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.c @@ -1,7 +1,7 @@ /** @file Platform PCI Segment Info Library for Hyper-V Gen2 VMs. - Reads MCFG from config blob PCD and provides segment-to-ECAM-base + Reads MCFG from the ACPI replacement table HOB and provides segment-to-ECAM-base mapping for BasePciSegmentLibSegmentInfo. Copyright (c) Microsoft Corporation. @@ -11,11 +11,12 @@ #include #include #include +#include #include -#include #include #include #include +#include #include STATIC @@ -34,9 +35,6 @@ GetPciSegmentInfo ( OUT UINTN *Count ) { - UINT64 McfgPtr; - UINT32 McfgSize; - MCFG_TABLE_HEADER *McfgHdr; UINT32 DataLen; UINT32 EntryCount; MCFG_ALLOCATION_ENTRY *Entries; @@ -48,23 +46,25 @@ GetPciSegmentInfo ( } // - // Parse MCFG table from PCD (same data PlatformPei extracted from config blob). + // Find MCFG table from HOB list. // - McfgPtr = PcdGet64 (PcdMcfgPtr); - McfgSize = PcdGet32 (PcdMcfgSize); - - if (McfgPtr == 0 || McfgSize < sizeof (MCFG_TABLE_HEADER)) { - DEBUG ((DEBUG_INFO, "PCIe: PciSegmentInfoLib: No MCFG table\n")); - *Count = 0; - return NULL; + EFI_PEI_HOB_POINTERS hob; + MCFG_TABLE_HEADER *McfgHdr = NULL; + + hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); + while (hob.Raw != NULL) + { + EFI_ACPI_DESCRIPTION_HEADER *acpiHdr = (EFI_ACPI_DESCRIPTION_HEADER *)GET_GUID_HOB_DATA(hob.Guid); + if (acpiHdr->Signature == EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE) + { + McfgHdr = (MCFG_TABLE_HEADER *)acpiHdr; + break; + } + hob.Raw = GetNextGuidHob(&gAcpiReplacementTableHobGuid, GET_NEXT_HOB(hob)); } - McfgHdr = (MCFG_TABLE_HEADER *)(UINTN)McfgPtr; - - if (McfgHdr->Header.Length < sizeof (MCFG_TABLE_HEADER) || - McfgHdr->Header.Length > McfgSize) { - DEBUG ((DEBUG_ERROR, "PCIe: PciSegmentInfoLib: Invalid MCFG Length %u (PCD size %u)\n", - McfgHdr->Header.Length, McfgSize)); + if (McfgHdr == NULL || McfgHdr->Header.Length < sizeof(MCFG_TABLE_HEADER)) { + DEBUG ((DEBUG_INFO, "PCIe: PciSegmentInfoLib: No MCFG table in HOBs\n")); *Count = 0; return NULL; } diff --git a/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.inf b/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.inf index e7109bd4af..4c39c62947 100644 --- a/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.inf +++ b/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.inf @@ -24,9 +24,8 @@ [LibraryClasses] BaseMemoryLib DebugLib - PcdLib + HobLib MemoryAllocationLib -[Pcd] - gMsvmPkgTokenSpaceGuid.PcdMcfgPtr - gMsvmPkgTokenSpaceGuid.PcdMcfgSize +[Guids] + gAcpiReplacementTableHobGuid diff --git a/MsvmPkg/MsvmPkg.dec b/MsvmPkg/MsvmPkg.dec index b326956e97..c22cfb60f7 100644 --- a/MsvmPkg/MsvmPkg.dec +++ b/MsvmPkg/MsvmPkg.dec @@ -41,6 +41,11 @@ gSyntheticVmbfsClassGuid = {0xc376c1c3, 0xd276, 0x48d2, {0x90, 0xa9, 0xc0, 0x47, 0x48, 0x07, 0x2c, 0x60}} gSyntheticVpciClassGuid = {0x44c4f61d, 0x4444, 0x4400, {0x9d, 0x52, 0x80, 0x2e, 0x27, 0xed, 0xe1, 0x9f}} + # + # HOB GUID for VMM-provided ACPI table replacements + # + gAcpiReplacementTableHobGuid = {0xa24aef4c, 0xa824, 0x48e9, {0xb5, 0xb8, 0xbc, 0xd9, 0x6a, 0x59, 0x71, 0xaf}} + # # MsvmPkg specific events # diff --git a/MsvmPkg/PlatformPei/Config.c b/MsvmPkg/PlatformPei/Config.c index 6532196828..927c1e4773 100644 --- a/MsvmPkg/PlatformPei/Config.c +++ b/MsvmPkg/PlatformPei/Config.c @@ -27,7 +27,9 @@ #include #include #include +#include #include +#include #include "AllowNamelessAggregate.h" #include "AssignStruct.h" @@ -1164,36 +1166,33 @@ Return Value: // Tracking to see if the config blob has all the required structures. // #if defined(MDE_CPU_X64) - static const UINT64 AllStructuresFound = 0x1FF; + static const UINT64 AllStructuresFound = 0x7F; union { UINT64 AsUINT64; struct { UINT64 UefiConfigBiosInformation:1; - UINT64 UefiConfigMadt:1; - UINT64 UefiConfigSrat:1; UINT64 UefiConfigMemoryMap:1; UINT64 UefiConfigEntropy:1; UINT64 UefiConfigBiosGuid:1; UINT64 UefiConfigFlags:1; UINT64 UefiConfigProcessorInformation:1; UINT64 UefiConfigMmioRanges:1; - UINT64 Reserved:55; + UINT64 Reserved:57; }; } requiredStructures={0}; #elif defined(MDE_CPU_AARCH64) - static const UINT64 AllStructuresFound = 0xFF; + static const UINT64 AllStructuresFound = 0x7F; union { UINT64 AsUINT64; struct { UINT64 UefiConfigBiosInformation:1; - UINT64 UefiConfigSrat:1; UINT64 UefiConfigMemoryMap:1; UINT64 UefiConfigEntropy:1; UINT64 UefiConfigBiosGuid:1; UINT64 UefiConfigFlags:1; UINT64 UefiConfigProcessorInformation:1; UINT64 UefiConfigMmioRanges:1; - UINT64 Reserved:56; + UINT64 Reserved:57; }; } requiredStructures={0}; #endif @@ -1262,97 +1261,34 @@ Return Value: break; } case UefiConfigMadt: - { - UEFI_CONFIG_MADT * madtStructure = (UEFI_CONFIG_MADT*)header; - EFI_ACPI_DESCRIPTION_HEADER *madtHdr = (EFI_ACPI_DESCRIPTION_HEADER*)madtStructure->Madt; - - if (madtStructure->Header.Length < (sizeof(UEFI_CONFIG_HEADER) + sizeof(EFI_ACPI_DESCRIPTION_HEADER)) || - madtHdr->Signature != EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE || - madtHdr->Length >(madtStructure->Header.Length - sizeof(UEFI_CONFIG_HEADER))) - { - DEBUG((DEBUG_ERROR, "*** Malformed MADT\n")); - FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); - } - - PEI_FAIL_FAST_IF_FAILED(PcdSet64S(PcdMadtPtr, (UINT64)madtStructure->Madt)); - PEI_FAIL_FAST_IF_FAILED(PcdSet32S(PcdMadtSize, madtHdr->Length)); -#if defined(MDE_CPU_X64) - requiredStructures.UefiConfigMadt = 1; -#endif - break; - } case UefiConfigSrat: - { - UEFI_CONFIG_SRAT *sratStructure = (UEFI_CONFIG_SRAT*) header; - EFI_ACPI_DESCRIPTION_HEADER *sratHdr = (EFI_ACPI_DESCRIPTION_HEADER*) sratStructure->Srat; - - // - // NOTE: Because ARM GICC affinity structures are not aligned to 8 bytes, - // this structure may be padded. Thus, the table described by the ACPI header - // just needs to be less than the overall length. - // - if (sratStructure->Header.Length < (sizeof(UEFI_CONFIG_HEADER) + sizeof(EFI_ACPI_DESCRIPTION_HEADER)) || - sratHdr->Signature != EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE || - sratHdr->Length > (sratStructure->Header.Length - sizeof(UEFI_CONFIG_HEADER))) - { - DEBUG((DEBUG_ERROR, "*** Malformed SRAT\n")); - FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); - } - - PEI_FAIL_FAST_IF_FAILED(PcdSet64S(PcdSratPtr, (UINT64)sratStructure->Srat)); - PEI_FAIL_FAST_IF_FAILED(PcdSet32S(PcdSratSize, sratHdr->Length)); - requiredStructures.UefiConfigSrat = 1; - break; - } case UefiConfigSlit: - { - UEFI_CONFIG_SLIT *slitStructure = (UEFI_CONFIG_SLIT*) header; - EFI_ACPI_DESCRIPTION_HEADER *slitHdr = (EFI_ACPI_DESCRIPTION_HEADER*) slitStructure->Slit; - - if (slitStructure->Header.Length < (sizeof(UEFI_CONFIG_HEADER) + sizeof(EFI_ACPI_DESCRIPTION_HEADER)) || - slitHdr->Signature != EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE || - slitHdr->Length > (slitStructure->Header.Length - sizeof(UEFI_CONFIG_HEADER))) - { - DEBUG((DEBUG_ERROR, "*** Malformed SLIT\n")); - FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); - } - - PEI_FAIL_FAST_IF_FAILED(PcdSet64S(PcdSlitPtr, (UINT64)slitStructure->Slit)); - PEI_FAIL_FAST_IF_FAILED(PcdSet32S(PcdSlitSize, slitHdr->Length)); - break; - } case UefiConfigPptt: - { - UEFI_CONFIG_PPTT *ppttStructure = (UEFI_CONFIG_PPTT*) header; - EFI_ACPI_DESCRIPTION_HEADER *ppttHdr = (EFI_ACPI_DESCRIPTION_HEADER*) ppttStructure->Pptt; - - if (ppttStructure->Header.Length < (sizeof(UEFI_CONFIG_HEADER) + sizeof(EFI_ACPI_DESCRIPTION_HEADER)) || - ppttHdr->Signature != EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE || - ppttHdr->Length > (ppttStructure->Header.Length - sizeof(UEFI_CONFIG_HEADER))) - { - DEBUG((DEBUG_ERROR, "*** Malformed PPTT\n")); - FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); - } - - PEI_FAIL_FAST_IF_FAILED(PcdSet64S(PcdPpttPtr, (UINT64)ppttStructure->Pptt)); - PEI_FAIL_FAST_IF_FAILED(PcdSet32S(PcdPpttSize, ppttHdr->Length)); - break; - } case UefiConfigHmat: + case UefiConfigAcpiTable: +#if defined(MDE_CPU_X64) + case UefiConfigAspt: +#endif + case UefiConfigMcfg: + case UefiConfigSsdt: + case UefiConfigIort: { - UEFI_CONFIG_HMAT *hmatStructure = (UEFI_CONFIG_HMAT*) header; - EFI_ACPI_DESCRIPTION_HEADER *hmatHdr = (EFI_ACPI_DESCRIPTION_HEADER*) hmatStructure->Hmat; + UEFI_CONFIG_ACPI_TABLE *acpiTable = (UEFI_CONFIG_ACPI_TABLE*) header; + EFI_ACPI_DESCRIPTION_HEADER *acpiHeader = (EFI_ACPI_DESCRIPTION_HEADER*) acpiTable->AcpiTableData; - if (hmatStructure->Header.Length < (sizeof(UEFI_CONFIG_HEADER) + sizeof(EFI_ACPI_DESCRIPTION_HEADER)) || - hmatHdr->Signature != EFI_ACPI_6_5_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE || - hmatHdr->Length > (hmatStructure->Header.Length - sizeof(UEFI_CONFIG_HEADER))) + // + // Verify ACPI table header is completely within the config structure. + // + if (header->Length < (sizeof(UEFI_CONFIG_HEADER) + sizeof(EFI_ACPI_DESCRIPTION_HEADER)) || + acpiHeader->Length > (header->Length - sizeof(UEFI_CONFIG_HEADER))) { - DEBUG((DEBUG_ERROR, "*** Malformed HMAT\n")); + DEBUG((DEBUG_ERROR, "***ACPI table is not contained within config structure size.\n")); FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); } - PEI_FAIL_FAST_IF_FAILED(PcdSet64S(PcdHmatPtr, (UINT64)hmatStructure->Hmat)); - PEI_FAIL_FAST_IF_FAILED(PcdSet32S(PcdHmatSize, hmatHdr->Length)); + BuildGuidDataHob(&gAcpiReplacementTableHobGuid, + acpiTable->AcpiTableData, + acpiHeader->Length); break; } case UefiConfigMemoryMap: @@ -1624,25 +1560,6 @@ Return Value: requiredStructures.UefiConfigMmioRanges = 1; break; } - case UefiConfigAcpiTable: - { - UEFI_CONFIG_ACPI_TABLE *acpiTable = (UEFI_CONFIG_ACPI_TABLE*) header; - EFI_ACPI_DESCRIPTION_HEADER *acpiHeader = (EFI_ACPI_DESCRIPTION_HEADER*) acpiTable->AcpiTableData; - - // - // Verify ACPI table header is completely within the config structure. - // - if (acpiTable->Header.Length < (sizeof(UEFI_CONFIG_HEADER) + sizeof(EFI_ACPI_DESCRIPTION_HEADER)) || - acpiHeader->Length > (acpiTable->Header.Length - sizeof(UEFI_CONFIG_HEADER))) - { - DEBUG((DEBUG_ERROR, "***ACPI table is not contained within config structure size.\n")); - FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); - } - - PEI_FAIL_FAST_IF_FAILED(PcdSet64S(PcdAcpiTablePtr, (UINT64) acpiTable->AcpiTableData)); - PEI_FAIL_FAST_IF_FAILED(PcdSet32S(PcdAcpiTableSize, acpiHeader->Length)); - break; - } case UefiConfigNvdimmCount: { UEFI_CONFIG_NVDIMM_COUNT *cfg = (UEFI_CONFIG_NVDIMM_COUNT*) header; @@ -1656,25 +1573,6 @@ Return Value: PEI_FAIL_FAST_IF_FAILED(PcdSet32S(PcdNvmeNamespaceFilterId, 1)); break; } -#if defined(MDE_CPU_X64) - case UefiConfigAspt: - { - UEFI_CONFIG_AMD_ASPT *asptStructure = (UEFI_CONFIG_AMD_ASPT*) header; - EFI_ACPI_DESCRIPTION_HEADER *asptHdr = (EFI_ACPI_DESCRIPTION_HEADER*) asptStructure->Aspt; - - if (asptStructure->Header.Length < (sizeof(UEFI_CONFIG_HEADER) + sizeof(EFI_ACPI_DESCRIPTION_HEADER)) || - asptHdr->Signature != AMD_ACPI_ASPT_TABLE_SIGNATURE || - asptHdr->Length > (asptStructure->Header.Length - sizeof(UEFI_CONFIG_HEADER))) - { - DEBUG((DEBUG_ERROR, "***Malformed ASPT\n")); - FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); - } - - PEI_FAIL_FAST_IF_FAILED(PcdSet64S(PcdAsptPtr, (UINT64)asptStructure->Aspt)); - PEI_FAIL_FAST_IF_FAILED(PcdSet32S(PcdAsptSize, asptHdr->Length)); - break; - } -#endif #if defined(MDE_CPU_AARCH64) case UefiConfigGic: @@ -1685,57 +1583,6 @@ Return Value: break; } #endif - case UefiConfigMcfg: - { - UEFI_CONFIG_MCFG *mcfgStructure = (UEFI_CONFIG_MCFG*) header; - EFI_ACPI_DESCRIPTION_HEADER *mcfgHdr = (EFI_ACPI_DESCRIPTION_HEADER*) mcfgStructure->Mcfg; - - if (mcfgStructure->Header.Length < (sizeof(UEFI_CONFIG_HEADER) + sizeof(EFI_ACPI_DESCRIPTION_HEADER)) || - mcfgHdr->Signature != EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE || - mcfgHdr->Length > (mcfgStructure->Header.Length - sizeof(UEFI_CONFIG_HEADER))) - { - DEBUG((DEBUG_ERROR, "*** Malformed MCFG\n")); - FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); - } - - PEI_FAIL_FAST_IF_FAILED(PcdSet64S(PcdMcfgPtr, (UINT64)mcfgStructure->Mcfg)); - PEI_FAIL_FAST_IF_FAILED(PcdSet32S(PcdMcfgSize, mcfgHdr->Length)); - break; - } - case UefiConfigSsdt: - { - UEFI_CONFIG_SSDT *ssdtStructure = (UEFI_CONFIG_SSDT*) header; - EFI_ACPI_DESCRIPTION_HEADER *ssdtHdr = (EFI_ACPI_DESCRIPTION_HEADER*) ssdtStructure->Ssdt; - - if (ssdtStructure->Header.Length < (sizeof(UEFI_CONFIG_HEADER) + sizeof(EFI_ACPI_DESCRIPTION_HEADER)) || - ssdtHdr->Signature != EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE || - ssdtHdr->Length > (ssdtStructure->Header.Length - sizeof(UEFI_CONFIG_HEADER))) - { - DEBUG((DEBUG_ERROR, "*** Malformed SSDT\n")); - FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); - } - - PEI_FAIL_FAST_IF_FAILED(PcdSet64S(PcdSsdtPtr, (UINT64)ssdtStructure->Ssdt)); - PEI_FAIL_FAST_IF_FAILED(PcdSet32S(PcdSsdtSize, ssdtHdr->Length)); - break; - } - case UefiConfigIort: - { - UEFI_CONFIG_IORT *iortStructure = (UEFI_CONFIG_IORT*) header; - EFI_ACPI_DESCRIPTION_HEADER *iortHdr = (EFI_ACPI_DESCRIPTION_HEADER*) iortStructure->Iort; - - if (iortStructure->Header.Length < (sizeof(UEFI_CONFIG_HEADER) + sizeof(EFI_ACPI_DESCRIPTION_HEADER)) || - iortHdr->Signature != EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE || - iortHdr->Length > (iortStructure->Header.Length - sizeof(UEFI_CONFIG_HEADER))) - { - DEBUG((DEBUG_ERROR, "*** Malformed IORT\n")); - FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); - } - - PEI_FAIL_FAST_IF_FAILED(PcdSet64S(PcdIortPtr, (UINT64)iortStructure->Iort)); - PEI_FAIL_FAST_IF_FAILED(PcdSet32S(PcdIortSize, iortHdr->Length)); - break; - } case UefiConfigPcieBarApertures: { diff --git a/MsvmPkg/PlatformPei/IgvmConfig.c b/MsvmPkg/PlatformPei/IgvmConfig.c index d76e5bec63..5033caa526 100644 --- a/MsvmPkg/PlatformPei/IgvmConfig.c +++ b/MsvmPkg/PlatformPei/IgvmConfig.c @@ -17,11 +17,13 @@ #endif #include #include +#include #include #include #include #include #include +#include #include #include @@ -492,8 +494,11 @@ Return Value: FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); } - PEI_FAIL_FAST_IF_FAILED(PcdSet64S(PcdSratPtr, (UINT64)sratHdr)); - PEI_FAIL_FAST_IF_FAILED(PcdSet32S(PcdSratSize, sratHdr->Length)); + // + // Install the SRAT as a replacement table HOB so the generic DXE ACPI + // path picks it up. + // + BuildGuidDataHob(&gAcpiReplacementTableHobGuid, (VOID *)sratHdr, sratHdr->Length); // // Parse the command line to obtain debug parameters. diff --git a/MsvmPkg/PlatformPei/Platform.c b/MsvmPkg/PlatformPei/Platform.c index e513a8be37..29c112a84b 100644 --- a/MsvmPkg/PlatformPei/Platform.c +++ b/MsvmPkg/PlatformPei/Platform.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -763,60 +764,69 @@ Return Value: // in page tables for PciSegmentLib MMIO access, while keeping // non-enumerated ECAM ranges out of GCD entirely. // - UINT64 McfgPtr = PcdGet64(PcdMcfgPtr); - UINT32 McfgSize = PcdGet32(PcdMcfgSize); - if (McfgPtr != 0 && McfgSize >= sizeof(MCFG_TABLE_HEADER)) { - MCFG_TABLE_HEADER *McfgHdr = (MCFG_TABLE_HEADER *)(UINTN) McfgPtr; + MCFG_TABLE_HEADER *McfgHdr = NULL; + { + EFI_PEI_HOB_POINTERS hob; + hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); + while (hob.Raw != NULL) + { + EFI_ACPI_DESCRIPTION_HEADER *acpiHdr = (EFI_ACPI_DESCRIPTION_HEADER *)GET_GUID_HOB_DATA(hob.Guid); + if (acpiHdr->Signature == EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE) + { + McfgHdr = (MCFG_TABLE_HEADER *)acpiHdr; + break; + } + hob.Raw = GetNextGuidHob(&gAcpiReplacementTableHobGuid, GET_NEXT_HOB(hob)); + } + } - if (McfgHdr->Header.Length >= sizeof(MCFG_TABLE_HEADER) && - McfgHdr->Header.Length <= McfgSize) { - UINT32 McfgDataLen = McfgHdr->Header.Length - sizeof(MCFG_TABLE_HEADER); - UINT32 NumEntries = McfgDataLen / sizeof(MCFG_ALLOCATION_ENTRY); - MCFG_ALLOCATION_ENTRY *Entries = (MCFG_ALLOCATION_ENTRY *)(McfgHdr + 1); + if (McfgHdr != NULL && McfgHdr->Header.Length >= sizeof(MCFG_TABLE_HEADER)) { + UINT32 McfgDataLen = McfgHdr->Header.Length - sizeof(MCFG_TABLE_HEADER); + UINT32 NumEntries = McfgDataLen / sizeof(MCFG_ALLOCATION_ENTRY); + MCFG_ALLOCATION_ENTRY *Entries = (MCFG_ALLOCATION_ENTRY *)(McfgHdr + 1); - for (UINT32 i = 0; i < NumEntries; i++) { - if (Entries[i].EndBusNumber < Entries[i].StartBusNumber) { - continue; - } + for (UINT32 i = 0; i < NumEntries; i++) { + if (Entries[i].EndBusNumber < Entries[i].StartBusNumber) { + continue; + } - // - // Only create ECAM HOB if this segment has a matching - // PcieBarApertures entry. - // - BOOLEAN HasAperture = FALSE; - for (UINT32 j = 0; j < ApertureCount; j++) { - if (Apertures[j].Segment == Entries[i].PciSegmentGroupNumber) { - HasAperture = TRUE; - break; - } - } - if (!HasAperture) { - continue; + // + // Only create ECAM HOB if this segment has a matching + // PcieBarApertures entry. + // + BOOLEAN HasAperture = FALSE; + for (UINT32 j = 0; j < ApertureCount; j++) { + if (Apertures[j].Segment == Entries[i].PciSegmentGroupNumber) { + HasAperture = TRUE; + break; } + } + if (!HasAperture) { + continue; + } - UINT64 EcamBase = Entries[i].BaseAddress - + (UINT64)Entries[i].StartBusNumber * PCIE_ECAM_BYTES_PER_BUS; - UINT64 EcamSize = - (UINT64)(Entries[i].EndBusNumber - Entries[i].StartBusNumber + 1) - * PCIE_ECAM_BYTES_PER_BUS; - - if (EcamBase + EcamSize < EcamBase) { - DEBUG((DEBUG_ERROR, - "PCIe: ECAM overflow for segment %u: Base=%016lx Size=%016lx\n", - Entries[i].PciSegmentGroupNumber, EcamBase, EcamSize)); - continue; - } + UINT64 EcamBase = Entries[i].BaseAddress + + (UINT64)Entries[i].StartBusNumber * PCIE_ECAM_BYTES_PER_BUS; + UINT64 EcamSize = + (UINT64)(Entries[i].EndBusNumber - Entries[i].StartBusNumber + 1) + * PCIE_ECAM_BYTES_PER_BUS; + + if (EcamBase + EcamSize < EcamBase) { + DEBUG((DEBUG_ERROR, + "PCIe: ECAM overflow for segment %u: Base=%016lx Size=%016lx\n", + Entries[i].PciSegmentGroupNumber, EcamBase, EcamSize)); + continue; + } - HobAddMmioRange(EcamBase, EcamSize); + HobAddMmioRange(EcamBase, EcamSize); - // - // Also create a memory allocation HOB so the GCD marks this - // ECAM range as allocated during DxeCore init. This prevents - // other DXE drivers (e.g., VideoDxe) from accidentally - // allocating MMIO space that overlaps the ECAM region. - // - BuildMemoryAllocationHob(EcamBase, EcamSize, EfiMemoryMappedIO); - } + // + // Also create a memory allocation HOB so the GCD marks this + // ECAM range as allocated during DxeCore init. This prevents + // other DXE drivers (e.g., VideoDxe) from accidentally + // allocating MMIO space that overlaps the ECAM region. + // + BuildMemoryAllocationHob(EcamBase, EcamSize, EfiMemoryMappedIO); } } diff --git a/MsvmPkg/PlatformPei/PlatformPei.inf b/MsvmPkg/PlatformPei/PlatformPei.inf index 3fd7c92cc0..445c7839ec 100644 --- a/MsvmPkg/PlatformPei/PlatformPei.inf +++ b/MsvmPkg/PlatformPei/PlatformPei.inf @@ -71,6 +71,7 @@ ArmLib [Guids] + gAcpiReplacementTableHobGuid gAdvancedLoggerHobGuid gDxeMemoryProtectionSettingsGuid gEfiMemoryTypeInformationGuid @@ -91,22 +92,8 @@ gMsvmPkgTokenSpaceGuid.PcdDxeFvSize gMsvmPkgTokenSpaceGuid.PcdConfigBlobSize gMsvmPkgTokenSpaceGuid.PcdLegacyMemoryMap - gMsvmPkgTokenSpaceGuid.PcdIortPtr - gMsvmPkgTokenSpaceGuid.PcdIortSize gMsvmPkgTokenSpaceGuid.PcdMadtPtr gMsvmPkgTokenSpaceGuid.PcdMadtSize - gMsvmPkgTokenSpaceGuid.PcdMcfgPtr - gMsvmPkgTokenSpaceGuid.PcdMcfgSize - gMsvmPkgTokenSpaceGuid.PcdSratPtr - gMsvmPkgTokenSpaceGuid.PcdSratSize - gMsvmPkgTokenSpaceGuid.PcdSlitPtr - gMsvmPkgTokenSpaceGuid.PcdSlitSize - gMsvmPkgTokenSpaceGuid.PcdSsdtPtr - gMsvmPkgTokenSpaceGuid.PcdSsdtSize - gMsvmPkgTokenSpaceGuid.PcdPpttPtr - gMsvmPkgTokenSpaceGuid.PcdPpttSize - gMsvmPkgTokenSpaceGuid.PcdHmatPtr - gMsvmPkgTokenSpaceGuid.PcdHmatSize gMsvmPkgTokenSpaceGuid.PcdMemoryMapPtr gMsvmPkgTokenSpaceGuid.PcdMemoryMapSize gMsvmPkgTokenSpaceGuid.PcdEntropyPtr @@ -182,8 +169,6 @@ gMsvmPkgTokenSpaceGuid.PcdHighMmioGapBasePageNumber gMsvmPkgTokenSpaceGuid.PcdHighMmioGapSizeInPages gMsvmPkgTokenSpaceGuid.PcdBiosBaseAddress - gMsvmPkgTokenSpaceGuid.PcdAcpiTablePtr - gMsvmPkgTokenSpaceGuid.PcdAcpiTableSize gMsvmPkgTokenSpaceGuid.PcdNvdimmCount gMsvmPkgTokenSpaceGuid.PcdVpciInstanceFilterGuidPtr gMsvmPkgTokenSpaceGuid.PcdIsolationArchitecture @@ -210,8 +195,6 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable gEfiSecurityPkgTokenSpaceGuid.TcgMeasureBootStringsInPcr4 gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask - gMsvmPkgTokenSpaceGuid.PcdAsptPtr - gMsvmPkgTokenSpaceGuid.PcdAsptSize gMsvmPkgTokenSpaceGuid.PcdExcludeFvsFromMeasurements [Ppis] From a3941951fef7bb61efcc34fbbe377e2d5050f3f6 Mon Sep 17 00:00:00 2001 From: John Starks Date: Mon, 18 May 2026 13:47:10 -0700 Subject: [PATCH 2/3] AcpiReplacementTable: publish pointer+length HOBs instead of full tables Instead of copying entire ACPI tables into HOB heap with BuildGuidDataHob, publish a small ACPI_REPLACEMENT_TABLE_HOB_DATA struct containing only the table address and length. This avoids consuming scarce PEI heap space for large tables (SRAT, HMAT, etc.) since the underlying data already resides in persistent memory (config blob or IGVM parameter area). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c | 8 ++++++-- MsvmPkg/Include/AcpiReplacementTable.h | 17 +++++++++++++---- .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 3 ++- .../PciSegmentInfoLib/PciSegmentInfoLib.c | 3 ++- MsvmPkg/PlatformPei/Config.c | 11 ++++++++--- MsvmPkg/PlatformPei/IgvmConfig.c | 7 ++++++- MsvmPkg/PlatformPei/Platform.c | 3 ++- 7 files changed, 39 insertions(+), 13 deletions(-) diff --git a/MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c b/MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c index 9893be3229..54a8324141 100644 --- a/MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c +++ b/MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c @@ -110,8 +110,10 @@ Return Value: hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); while (hob.Raw != NULL) { + ACPI_REPLACEMENT_TABLE_HOB_DATA *hobData = + (ACPI_REPLACEMENT_TABLE_HOB_DATA *) GET_GUID_HOB_DATA(hob.Guid); EFI_ACPI_DESCRIPTION_HEADER *table = - (EFI_ACPI_DESCRIPTION_HEADER *) GET_GUID_HOB_DATA(hob.Guid); + (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) hobData->TableAddress; if (table->Signature == Signature) { @@ -152,8 +154,10 @@ Return Value: hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); while (hob.Raw != NULL) { + ACPI_REPLACEMENT_TABLE_HOB_DATA *hobData = + (ACPI_REPLACEMENT_TABLE_HOB_DATA *) GET_GUID_HOB_DATA(hob.Guid); EFI_ACPI_DESCRIPTION_HEADER *table = - (EFI_ACPI_DESCRIPTION_HEADER *) GET_GUID_HOB_DATA(hob.Guid); + (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) hobData->TableAddress; DEBUG((DEBUG_INFO, "Installing VMM-provided ACPI table: %.4a (0x%08x)\n", (CHAR8 *)&table->Signature, table->Signature)); diff --git a/MsvmPkg/Include/AcpiReplacementTable.h b/MsvmPkg/Include/AcpiReplacementTable.h index 18a7f27214..79292bf173 100644 --- a/MsvmPkg/Include/AcpiReplacementTable.h +++ b/MsvmPkg/Include/AcpiReplacementTable.h @@ -12,12 +12,21 @@ // // GUID used to identify ACPI replacement table HOBs. -// Each HOB with this GUID contains a complete ACPI table starting with -// EFI_ACPI_DESCRIPTION_HEADER. When an ACPI table from the firmware volume -// has the same signature as a replacement table HOB, the FV table is -// suppressed and the HOB-provided table is installed instead. +// Each HOB with this GUID contains an ACPI_REPLACEMENT_TABLE_HOB_DATA +// structure that points to a complete ACPI table (starting with +// EFI_ACPI_DESCRIPTION_HEADER) in persistent memory. When an ACPI table from +// the firmware volume has the same signature as a replacement table HOB, the +// FV table is suppressed and the HOB-referenced table is installed instead. // #define ACPI_REPLACEMENT_TABLE_HOB_GUID \ { 0xa24aef4c, 0xa824, 0x48e9, { 0xb5, 0xb8, 0xbc, 0xd9, 0x6a, 0x59, 0x71, 0xaf } } extern EFI_GUID gAcpiReplacementTableHobGuid; + +// +// HOB payload: pointer and length of an ACPI table in persistent memory. +// +typedef struct { + EFI_PHYSICAL_ADDRESS TableAddress; + UINT32 TableLength; +} ACPI_REPLACEMENT_TABLE_HOB_DATA; diff --git a/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c index a46e332403..3a99b4f3e5 100644 --- a/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c +++ b/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -87,7 +87,8 @@ PciHostBridgeGetRootBridges ( hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); while (hob.Raw != NULL) { - EFI_ACPI_DESCRIPTION_HEADER *acpiHdr = (EFI_ACPI_DESCRIPTION_HEADER *)GET_GUID_HOB_DATA(hob.Guid); + ACPI_REPLACEMENT_TABLE_HOB_DATA *hobData = (ACPI_REPLACEMENT_TABLE_HOB_DATA *)GET_GUID_HOB_DATA(hob.Guid); + EFI_ACPI_DESCRIPTION_HEADER *acpiHdr = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)hobData->TableAddress; if (acpiHdr->Signature == EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE) { McfgHdr = (MCFG_TABLE_HEADER *)acpiHdr; diff --git a/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.c b/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.c index ebb24e7626..e5c7c822a0 100644 --- a/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.c +++ b/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.c @@ -54,7 +54,8 @@ GetPciSegmentInfo ( hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); while (hob.Raw != NULL) { - EFI_ACPI_DESCRIPTION_HEADER *acpiHdr = (EFI_ACPI_DESCRIPTION_HEADER *)GET_GUID_HOB_DATA(hob.Guid); + ACPI_REPLACEMENT_TABLE_HOB_DATA *hobData = (ACPI_REPLACEMENT_TABLE_HOB_DATA *)GET_GUID_HOB_DATA(hob.Guid); + EFI_ACPI_DESCRIPTION_HEADER *acpiHdr = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)hobData->TableAddress; if (acpiHdr->Signature == EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE) { McfgHdr = (MCFG_TABLE_HEADER *)acpiHdr; diff --git a/MsvmPkg/PlatformPei/Config.c b/MsvmPkg/PlatformPei/Config.c index 927c1e4773..f4a74abfc0 100644 --- a/MsvmPkg/PlatformPei/Config.c +++ b/MsvmPkg/PlatformPei/Config.c @@ -1286,9 +1286,14 @@ Return Value: FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); } - BuildGuidDataHob(&gAcpiReplacementTableHobGuid, - acpiTable->AcpiTableData, - acpiHeader->Length); + { + ACPI_REPLACEMENT_TABLE_HOB_DATA hobData; + hobData.TableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)acpiTable->AcpiTableData; + hobData.TableLength = acpiHeader->Length; + BuildGuidDataHob(&gAcpiReplacementTableHobGuid, + &hobData, + sizeof(hobData)); + } break; } case UefiConfigMemoryMap: diff --git a/MsvmPkg/PlatformPei/IgvmConfig.c b/MsvmPkg/PlatformPei/IgvmConfig.c index 5033caa526..9abaee00f4 100644 --- a/MsvmPkg/PlatformPei/IgvmConfig.c +++ b/MsvmPkg/PlatformPei/IgvmConfig.c @@ -498,7 +498,12 @@ Return Value: // Install the SRAT as a replacement table HOB so the generic DXE ACPI // path picks it up. // - BuildGuidDataHob(&gAcpiReplacementTableHobGuid, (VOID *)sratHdr, sratHdr->Length); + { + ACPI_REPLACEMENT_TABLE_HOB_DATA hobData; + hobData.TableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)sratHdr; + hobData.TableLength = sratHdr->Length; + BuildGuidDataHob(&gAcpiReplacementTableHobGuid, &hobData, sizeof(hobData)); + } // // Parse the command line to obtain debug parameters. diff --git a/MsvmPkg/PlatformPei/Platform.c b/MsvmPkg/PlatformPei/Platform.c index 29c112a84b..1e1eeff1ff 100644 --- a/MsvmPkg/PlatformPei/Platform.c +++ b/MsvmPkg/PlatformPei/Platform.c @@ -770,7 +770,8 @@ Return Value: hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); while (hob.Raw != NULL) { - EFI_ACPI_DESCRIPTION_HEADER *acpiHdr = (EFI_ACPI_DESCRIPTION_HEADER *)GET_GUID_HOB_DATA(hob.Guid); + ACPI_REPLACEMENT_TABLE_HOB_DATA *hobData = (ACPI_REPLACEMENT_TABLE_HOB_DATA *)GET_GUID_HOB_DATA(hob.Guid); + EFI_ACPI_DESCRIPTION_HEADER *acpiHdr = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)hobData->TableAddress; if (acpiHdr->Signature == EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE) { McfgHdr = (MCFG_TABLE_HEADER *)acpiHdr; From 236b02d9c0989bd3f9e6881e6123cf117ea922ad Mon Sep 17 00:00:00 2001 From: John Starks Date: Mon, 18 May 2026 14:00:32 -0700 Subject: [PATCH 3/3] feedback --- MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c | 33 ++------- MsvmPkg/Include/AcpiReplacementTable.h | 69 ++++++++++++++++++- .../PciHostBridgeLib/PciHostBridgeLib.c | 17 +---- .../PciSegmentInfoLib/PciSegmentInfoLib.c | 17 +---- MsvmPkg/PlatformPei/Config.c | 3 +- MsvmPkg/PlatformPei/IgvmConfig.c | 3 +- MsvmPkg/PlatformPei/Platform.c | 18 +---- 7 files changed, 80 insertions(+), 80 deletions(-) diff --git a/MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c b/MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c index 54a8324141..e4ac37e86a 100644 --- a/MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c +++ b/MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c @@ -105,25 +105,7 @@ Return Value: --*/ { - EFI_PEI_HOB_POINTERS hob; - - hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); - while (hob.Raw != NULL) - { - ACPI_REPLACEMENT_TABLE_HOB_DATA *hobData = - (ACPI_REPLACEMENT_TABLE_HOB_DATA *) GET_GUID_HOB_DATA(hob.Guid); - EFI_ACPI_DESCRIPTION_HEADER *table = - (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) hobData->TableAddress; - - if (table->Signature == Signature) - { - return TRUE; - } - - hob.Raw = GetNextGuidHob(&gAcpiReplacementTableHobGuid, GET_NEXT_HOB(hob)); - } - - return FALSE; + return FindAcpiReplacementTable(Signature) != NULL; } @@ -147,17 +129,14 @@ Return Value: --*/ { - EFI_PEI_HOB_POINTERS hob; EFI_STATUS status; UINTN tableHandle; + VOID *hob; - hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); - while (hob.Raw != NULL) + hob = GetFirstAcpiReplacementTableHob(); + while (hob != NULL) { - ACPI_REPLACEMENT_TABLE_HOB_DATA *hobData = - (ACPI_REPLACEMENT_TABLE_HOB_DATA *) GET_GUID_HOB_DATA(hob.Guid); - EFI_ACPI_DESCRIPTION_HEADER *table = - (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) hobData->TableAddress; + EFI_ACPI_DESCRIPTION_HEADER *table = AcpiReplacementTableFromHob(hob); DEBUG((DEBUG_INFO, "Installing VMM-provided ACPI table: %.4a (0x%08x)\n", (CHAR8 *)&table->Signature, table->Signature)); @@ -174,7 +153,7 @@ Return Value: return status; } - hob.Raw = GetNextGuidHob(&gAcpiReplacementTableHobGuid, GET_NEXT_HOB(hob)); + hob = GetNextAcpiReplacementTableHob(hob); } return EFI_SUCCESS; diff --git a/MsvmPkg/Include/AcpiReplacementTable.h b/MsvmPkg/Include/AcpiReplacementTable.h index 79292bf173..82017466ce 100644 --- a/MsvmPkg/Include/AcpiReplacementTable.h +++ b/MsvmPkg/Include/AcpiReplacementTable.h @@ -9,6 +9,8 @@ #pragma once #include +#include +#include // // GUID used to identify ACPI replacement table HOBs. @@ -24,9 +26,70 @@ extern EFI_GUID gAcpiReplacementTableHobGuid; // -// HOB payload: pointer and length of an ACPI table in persistent memory. +// HOB payload: pointer to an ACPI table in persistent memory. // typedef struct { - EFI_PHYSICAL_ADDRESS TableAddress; - UINT32 TableLength; + EFI_ACPI_DESCRIPTION_HEADER *Table; } ACPI_REPLACEMENT_TABLE_HOB_DATA; + +// +// Helper: get the ACPI table header from a replacement table HOB. +// HobRaw must point to a valid GUIDed HOB with gAcpiReplacementTableHobGuid. +// +static inline EFI_ACPI_DESCRIPTION_HEADER * +AcpiReplacementTableFromHob( + IN VOID *HobRaw + ) +{ + EFI_HOB_GUID_TYPE *GuidHob = (EFI_HOB_GUID_TYPE *)HobRaw; + ACPI_REPLACEMENT_TABLE_HOB_DATA *Data = + (ACPI_REPLACEMENT_TABLE_HOB_DATA *)GET_GUID_HOB_DATA(GuidHob); + return Data->Table; +} + +// +// Helper: get the first replacement table HOB, returning the raw HOB pointer. +// Returns NULL if none exist. Use with AcpiReplacementTableFromHob() and +// GetNextAcpiReplacementTableHob() to iterate. +// +static inline VOID * +GetFirstAcpiReplacementTableHob( + VOID + ) +{ + return GetFirstGuidHob(&gAcpiReplacementTableHobGuid); +} + +// +// Helper: get the next replacement table HOB after CurrentHob. +// Returns NULL if no more exist. +// +static inline VOID * +GetNextAcpiReplacementTableHob( + IN VOID *CurrentHob + ) +{ + return GetNextGuidHob(&gAcpiReplacementTableHobGuid, GET_NEXT_HOB(CurrentHob)); +} + +// +// Helper: find the first replacement table matching a given ACPI signature. +// Returns the table header pointer, or NULL if not found. +// +static inline EFI_ACPI_DESCRIPTION_HEADER * +FindAcpiReplacementTable( + IN UINT32 Signature + ) +{ + VOID *Hob = GetFirstAcpiReplacementTableHob(); + while (Hob != NULL) + { + EFI_ACPI_DESCRIPTION_HEADER *Table = AcpiReplacementTableFromHob(Hob); + if (Table->Signature == Signature) + { + return Table; + } + Hob = GetNextAcpiReplacementTableHob(Hob); + } + return NULL; +} diff --git a/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c index 3a99b4f3e5..241d1c87fe 100644 --- a/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c +++ b/MsvmPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -81,21 +81,8 @@ PciHostBridgeGetRootBridges ( // // Find MCFG table from HOB list. // - EFI_PEI_HOB_POINTERS hob; - MCFG_TABLE_HEADER *McfgHdr = NULL; - - hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); - while (hob.Raw != NULL) - { - ACPI_REPLACEMENT_TABLE_HOB_DATA *hobData = (ACPI_REPLACEMENT_TABLE_HOB_DATA *)GET_GUID_HOB_DATA(hob.Guid); - EFI_ACPI_DESCRIPTION_HEADER *acpiHdr = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)hobData->TableAddress; - if (acpiHdr->Signature == EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE) - { - McfgHdr = (MCFG_TABLE_HEADER *)acpiHdr; - break; - } - hob.Raw = GetNextGuidHob(&gAcpiReplacementTableHobGuid, GET_NEXT_HOB(hob)); - } + MCFG_TABLE_HEADER *McfgHdr = (MCFG_TABLE_HEADER *)FindAcpiReplacementTable( + EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE); DEBUG ((DEBUG_VERBOSE, "PCIe: PciHostBridgeLib McfgHdr=%p\n", McfgHdr)); diff --git a/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.c b/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.c index e5c7c822a0..fb5be59c99 100644 --- a/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.c +++ b/MsvmPkg/Library/PciSegmentInfoLib/PciSegmentInfoLib.c @@ -48,21 +48,8 @@ GetPciSegmentInfo ( // // Find MCFG table from HOB list. // - EFI_PEI_HOB_POINTERS hob; - MCFG_TABLE_HEADER *McfgHdr = NULL; - - hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); - while (hob.Raw != NULL) - { - ACPI_REPLACEMENT_TABLE_HOB_DATA *hobData = (ACPI_REPLACEMENT_TABLE_HOB_DATA *)GET_GUID_HOB_DATA(hob.Guid); - EFI_ACPI_DESCRIPTION_HEADER *acpiHdr = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)hobData->TableAddress; - if (acpiHdr->Signature == EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE) - { - McfgHdr = (MCFG_TABLE_HEADER *)acpiHdr; - break; - } - hob.Raw = GetNextGuidHob(&gAcpiReplacementTableHobGuid, GET_NEXT_HOB(hob)); - } + MCFG_TABLE_HEADER *McfgHdr = (MCFG_TABLE_HEADER *)FindAcpiReplacementTable( + EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE); if (McfgHdr == NULL || McfgHdr->Header.Length < sizeof(MCFG_TABLE_HEADER)) { DEBUG ((DEBUG_INFO, "PCIe: PciSegmentInfoLib: No MCFG table in HOBs\n")); diff --git a/MsvmPkg/PlatformPei/Config.c b/MsvmPkg/PlatformPei/Config.c index f4a74abfc0..fbadf15987 100644 --- a/MsvmPkg/PlatformPei/Config.c +++ b/MsvmPkg/PlatformPei/Config.c @@ -1288,8 +1288,7 @@ Return Value: { ACPI_REPLACEMENT_TABLE_HOB_DATA hobData; - hobData.TableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)acpiTable->AcpiTableData; - hobData.TableLength = acpiHeader->Length; + hobData.Table = (EFI_ACPI_DESCRIPTION_HEADER *)acpiTable->AcpiTableData; BuildGuidDataHob(&gAcpiReplacementTableHobGuid, &hobData, sizeof(hobData)); diff --git a/MsvmPkg/PlatformPei/IgvmConfig.c b/MsvmPkg/PlatformPei/IgvmConfig.c index 9abaee00f4..2737be1e24 100644 --- a/MsvmPkg/PlatformPei/IgvmConfig.c +++ b/MsvmPkg/PlatformPei/IgvmConfig.c @@ -500,8 +500,7 @@ Return Value: // { ACPI_REPLACEMENT_TABLE_HOB_DATA hobData; - hobData.TableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)sratHdr; - hobData.TableLength = sratHdr->Length; + hobData.Table = sratHdr; BuildGuidDataHob(&gAcpiReplacementTableHobGuid, &hobData, sizeof(hobData)); } diff --git a/MsvmPkg/PlatformPei/Platform.c b/MsvmPkg/PlatformPei/Platform.c index 1e1eeff1ff..606a3a27ff 100644 --- a/MsvmPkg/PlatformPei/Platform.c +++ b/MsvmPkg/PlatformPei/Platform.c @@ -764,22 +764,8 @@ Return Value: // in page tables for PciSegmentLib MMIO access, while keeping // non-enumerated ECAM ranges out of GCD entirely. // - MCFG_TABLE_HEADER *McfgHdr = NULL; - { - EFI_PEI_HOB_POINTERS hob; - hob.Raw = GetFirstGuidHob(&gAcpiReplacementTableHobGuid); - while (hob.Raw != NULL) - { - ACPI_REPLACEMENT_TABLE_HOB_DATA *hobData = (ACPI_REPLACEMENT_TABLE_HOB_DATA *)GET_GUID_HOB_DATA(hob.Guid); - EFI_ACPI_DESCRIPTION_HEADER *acpiHdr = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)hobData->TableAddress; - if (acpiHdr->Signature == EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE) - { - McfgHdr = (MCFG_TABLE_HEADER *)acpiHdr; - break; - } - hob.Raw = GetNextGuidHob(&gAcpiReplacementTableHobGuid, GET_NEXT_HOB(hob)); - } - } + MCFG_TABLE_HEADER *McfgHdr = (MCFG_TABLE_HEADER *)FindAcpiReplacementTable( + EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE); if (McfgHdr != NULL && McfgHdr->Header.Length >= sizeof(MCFG_TABLE_HEADER)) { UINT32 McfgDataLen = McfgHdr->Header.Length - sizeof(MCFG_TABLE_HEADER);