diff --git a/MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c b/MsvmPkg/AcpiPlatformDxe/AcpiPlatform.c index 7c123103ce..e4ac37e86a 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,82 @@ 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. + +--*/ +{ + return FindAcpiReplacementTable(Signature) != NULL; +} + + +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_STATUS status; + UINTN tableHandle; + VOID *hob; + + hob = GetFirstAcpiReplacementTableHob(); + while (hob != NULL) + { + EFI_ACPI_DESCRIPTION_HEADER *table = AcpiReplacementTableFromHob(hob); + + 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 = GetNextAcpiReplacementTableHob(hob); + } + + return EFI_SUCCESS; +} + + EFI_STATUS LocateFvInstanceWithTables( OUT EFI_FIRMWARE_VOLUME2_PROTOCOL** Instance @@ -218,9 +296,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 +411,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 +486,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 +566,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 +613,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 +639,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..82017466ce --- /dev/null +++ b/MsvmPkg/Include/AcpiReplacementTable.h @@ -0,0 +1,95 @@ +/** @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 +#include +#include + +// +// GUID used to identify ACPI replacement table HOBs. +// 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 to an ACPI table in persistent memory. +// +typedef struct { + 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 7aa0e01cfc..241d1c87fe 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,27 +79,18 @@ PciHostBridgeGetRootBridges ( *Count = 0; // - // Read MCFG from PCD. + // Find MCFG table from HOB list. // - McfgPtr = PcdGet64 (PcdMcfgPtr); - McfgSize = PcdGet32 (PcdMcfgSize); + 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 McfgPtr=0x%lx McfgSize=%u\n", McfgPtr, McfgSize)); + DEBUG ((DEBUG_VERBOSE, "PCIe: PciHostBridgeLib McfgHdr=%p\n", McfgHdr)); - if (McfgPtr == 0 || McfgSize < sizeof (MCFG_TABLE_HEADER)) { + if (McfgHdr == NULL || McfgHdr->Header.Length < sizeof(MCFG_TABLE_HEADER)) { DEBUG ((DEBUG_INFO, "PCIe: No MCFG table, no root bridges\n")); return NULL; } - McfgHdr = (MCFG_TABLE_HEADER *)(UINTN)McfgPtr; - - 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)); - return NULL; - } - McfgDataLen = McfgHdr->Header.Length - sizeof (MCFG_TABLE_HEADER); McfgEntryCount = McfgDataLen / sizeof (MCFG_ALLOCATION_ENTRY); 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..fb5be59c99 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,13 @@ 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); + MCFG_TABLE_HEADER *McfgHdr = (MCFG_TABLE_HEADER *)FindAcpiReplacementTable( + EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE); - if (McfgPtr == 0 || McfgSize < sizeof (MCFG_TABLE_HEADER)) { - DEBUG ((DEBUG_INFO, "PCIe: PciSegmentInfoLib: No MCFG table\n")); - *Count = 0; - return NULL; - } - - 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..fbadf15987 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,38 @@ 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)); + case UefiConfigSrat: + case UefiConfigSlit: + case UefiConfigPptt: + case UefiConfigHmat: + case UefiConfigAcpiTable: #if defined(MDE_CPU_X64) - requiredStructures.UefiConfigMadt = 1; + case UefiConfigAspt: #endif - break; - } - case UefiConfigSrat: + case UefiConfigMcfg: + case UefiConfigSsdt: + case UefiConfigIort: { - UEFI_CONFIG_SRAT *sratStructure = (UEFI_CONFIG_SRAT*) header; - EFI_ACPI_DESCRIPTION_HEADER *sratHdr = (EFI_ACPI_DESCRIPTION_HEADER*) sratStructure->Srat; + UEFI_CONFIG_ACPI_TABLE *acpiTable = (UEFI_CONFIG_ACPI_TABLE*) header; + EFI_ACPI_DESCRIPTION_HEADER *acpiHeader = (EFI_ACPI_DESCRIPTION_HEADER*) acpiTable->AcpiTableData; // - // 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. + // Verify ACPI table header is completely within the config structure. // - 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))) + if (header->Length < (sizeof(UEFI_CONFIG_HEADER) + sizeof(EFI_ACPI_DESCRIPTION_HEADER)) || + acpiHeader->Length > (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")); + DEBUG((DEBUG_ERROR, "***ACPI table is not contained within config structure size.\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: - { - UEFI_CONFIG_HMAT *hmatStructure = (UEFI_CONFIG_HMAT*) header; - EFI_ACPI_DESCRIPTION_HEADER *hmatHdr = (EFI_ACPI_DESCRIPTION_HEADER*) hmatStructure->Hmat; - - 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))) { - DEBUG((DEBUG_ERROR, "*** Malformed HMAT\n")); - FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); + ACPI_REPLACEMENT_TABLE_HOB_DATA hobData; + hobData.Table = (EFI_ACPI_DESCRIPTION_HEADER *)acpiTable->AcpiTableData; + BuildGuidDataHob(&gAcpiReplacementTableHobGuid, + &hobData, + sizeof(hobData)); } - - PEI_FAIL_FAST_IF_FAILED(PcdSet64S(PcdHmatPtr, (UINT64)hmatStructure->Hmat)); - PEI_FAIL_FAST_IF_FAILED(PcdSet32S(PcdHmatSize, hmatHdr->Length)); break; } case UefiConfigMemoryMap: @@ -1624,25 +1564,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 +1577,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 +1587,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..2737be1e24 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,15 @@ 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. + // + { + ACPI_REPLACEMENT_TABLE_HOB_DATA hobData; + hobData.Table = sratHdr; + 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 e513a8be37..606a3a27ff 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,56 @@ 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 = (MCFG_TABLE_HEADER *)FindAcpiReplacementTable( + EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE); - 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]