From 40b3d3882fc5f1c969a3def286fa07abea0e3be5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Tue, 14 Oct 2025 12:20:19 +0200 Subject: [PATCH 1/4] DasharoPayloadPkg: Populate root bridges info from HOB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On AMD server systems there are multiple PCI root bridges. The root bridge scanning in UEFI Payload is not sufficient to detect the memory and I/O apertures properly. For example, on Turin system, the I/O aperture on the first root bridge containing the FCH may not have any I/O resources detected on the PCI devices. This results in the I/O decoding to be disabled on the root bridge, effectively breaking the I/O-based serial ports, e.g. on Super I/Os and BMCs. Populate the root bridge info from CB_TAG_RB_INFO which contains data compatible with the Universal Payload PCI Root Bridges Info HOB. Make the PciHostBridgeLib pick the HOB up, if available, and populate proper root bridge apertures for AMD systems. Otherwise, fall back to root bridge scanning. Relevant coreboot patches: https://review.coreboot.org/c/coreboot/+/89486 https://review.coreboot.org/c/coreboot/+/89487 TEST=Boot UEFI Payload and see the serial console no longer breaks after PCI enumeration in UEFI Payload on Gigabyte MZ33-AR1. Signed-off-by: Michał Żygowski --- DasharoPayloadPkg/BlSupportPei/BlSupportPei.c | 2 + DasharoPayloadPkg/Include/Coreboot.h | 2 + .../Include/Library/BlParseLib.h | 12 ++++ .../Library/CbParseLib/CbParseLib.c | 51 +++++++++++++- .../Library/CbParseLib/CbParseLib.inf | 4 ++ .../Library/PciHostBridgeLib/PciHostBridge.h | 30 +++++++++ .../PciHostBridgeLib/PciHostBridgeLib.c | 48 ++++++++++++++ .../PciHostBridgeLib/PciHostBridgeLib.inf | 4 ++ .../PciHostBridgeLib/PciHostBridgeSupport.c | 66 +++++++++++++++++++ 9 files changed, 218 insertions(+), 1 deletion(-) diff --git a/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c b/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c index 00786a1834..ccefe4dc9e 100644 --- a/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c +++ b/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c @@ -714,6 +714,8 @@ BlPeiEntryPoint ( ); + ParseRootBridgeInfo (); + // // Parse memory info // diff --git a/DasharoPayloadPkg/Include/Coreboot.h b/DasharoPayloadPkg/Include/Coreboot.h index b3cd07f61e..7656140bb2 100644 --- a/DasharoPayloadPkg/Include/Coreboot.h +++ b/DasharoPayloadPkg/Include/Coreboot.h @@ -847,4 +847,6 @@ struct tcg_efi_spec_id_event { /* UINT8 vendor_info[vendor_info_size]; */ } __attribute__ ((packed)); +#define CB_TAG_RB_INFO 0x0048 + #endif // _COREBOOT_PEI_H_INCLUDED_ diff --git a/DasharoPayloadPkg/Include/Library/BlParseLib.h b/DasharoPayloadPkg/Include/Library/BlParseLib.h index 8b21180f6f..4ac44b39e8 100644 --- a/DasharoPayloadPkg/Include/Library/BlParseLib.h +++ b/DasharoPayloadPkg/Include/Library/BlParseLib.h @@ -267,4 +267,16 @@ ParseInfoString ( IN UINTN Id ); +/** + Find the RootBridge info. + @param SmmStoreInfo Pointer to the SMMSTORE_INFO structure + @retval RETURN_SUCCESS Successfully find the Smm store buffer information. + @retval RETURN_NOT_FOUND Failed to find the Smm store buffer information . +**/ +RETURN_STATUS +EFIAPI +ParseRootBridgeInfo ( + VOID + ); + #endif diff --git a/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c b/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c index cc86b90a5a..7e8af0d289 100644 --- a/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c +++ b/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c @@ -10,16 +10,20 @@ **/ #include +#include +#include +#include #include #include #include +#include #include #include #include #include #include #include - +#include /** Convert a packed value from cbuint64 to a UINT64 value. @@ -1166,3 +1170,48 @@ ParseInfoString ( return (CONST CHAR8 *)CbString->string; } + +/** + Find the RootBridge info. + @param SmmStoreInfo Pointer to the SMMSTORE_INFO structure + @retval RETURN_SUCCESS Successfully find the Smm store buffer information. + @retval RETURN_NOT_FOUND Failed to find the Smm store buffer information . +**/ +RETURN_STATUS +EFIAPI +ParseRootBridgeInfo ( + VOID + ) +{ + RETURN_STATUS Status; + UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *BlRootBridgesHob = NULL; + UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PldRootBridgesHob; + struct cb_cbmem_ref *CbMemRef; + + Status = RETURN_NOT_FOUND; + CbMemRef = FindCbTag (CB_TAG_RB_INFO); + + if (CbMemRef != NULL) { + BlRootBridgesHob = (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *)(UINTN)CbMemRef->cbmem_addr; + } + + if (BlRootBridgesHob != NULL) { + // + // Migrate bootloader root bridge info hob from bootloader to payload. + // + PldRootBridgesHob = BuildGuidHob ( + &gUniversalPayloadPciRootBridgeInfoGuid, + BlRootBridgesHob->Header.Length + ); + ASSERT (PldRootBridgesHob != NULL); + if (PldRootBridgesHob != NULL) { + CopyMem (PldRootBridgesHob, BlRootBridgesHob, BlRootBridgesHob->Header.Length); + DEBUG ((DEBUG_INFO, "Create PCI root bridge info guid hob\n")); + Status = RETURN_SUCCESS; + } else { + Status = RETURN_OUT_OF_RESOURCES; + } + } + + return Status; +} diff --git a/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.inf b/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.inf index 544c9423a6..2a736f4cef 100644 --- a/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.inf +++ b/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.inf @@ -35,7 +35,11 @@ DebugLib PcdLib PciLib + HobLib [Pcd] gDasharoPayloadPkgTokenSpaceGuid.PcdPayloadStackTop +[Guids] + gUniversalPayloadPciRootBridgeInfoGuid + diff --git a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h index c2961b3bee..8a75d27524 100644 --- a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h +++ b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h @@ -11,6 +11,8 @@ #ifndef _PCI_HOST_BRIDGE_H #define _PCI_HOST_BRIDGE_H +#include + typedef struct { ACPI_HID_DEVICE_PATH AcpiDevicePath; EFI_DEVICE_PATH_PROTOCOL EndDevicePath; @@ -77,4 +79,32 @@ InitRootBridge ( OUT PCI_ROOT_BRIDGE *RootBus ); +/** + Scan for all root bridges from Universal Payload PciRootBridgeInfoHob + + @param[in] PciRootBridgeInfo Pointer of Universal Payload PCI Root Bridge Info Hob + @param[out] NumberOfRootBridges Number of root bridges detected + + @retval Pointer to the allocated PCI_ROOT_BRIDGE structure array. + +**/ +PCI_ROOT_BRIDGE * +RetrieveRootBridgeInfoFromHob ( + IN UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo, + OUT UINTN *NumberOfRootBridges + ); + +/** + Initialize DevicePath for a PCI_ROOT_BRIDGE. + @param[in] HID HID for device path + @param[in] UID UID for device path + + @retval A pointer to the new created device patch. +**/ +EFI_DEVICE_PATH_PROTOCOL * +CreateRootBridgeDevicePath ( + IN UINT32 HID, + IN UINT32 UID + ); + #endif diff --git a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c index a6538aeafa..8e7a81145e 100644 --- a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c +++ b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -172,6 +173,30 @@ InitRootBridge ( return EFI_SUCCESS; } +/** + Initialize DevicePath for a PCI_ROOT_BRIDGE. + @param[in] HID HID for device path + @param[in] UID UID for device path + + @retval A pointer to the new created device patch. +**/ +EFI_DEVICE_PATH_PROTOCOL * +CreateRootBridgeDevicePath ( + IN UINT32 HID, + IN UINT32 UID + ) +{ + CB_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath; + + DevicePath = AllocateCopyPool ( + sizeof (mRootBridgeDevicePathTemplate), + &mRootBridgeDevicePathTemplate + ); + ASSERT (DevicePath != NULL); + DevicePath->AcpiDevicePath.HID = HID; + DevicePath->AcpiDevicePath.UID = UID; + return (EFI_DEVICE_PATH_PROTOCOL *)DevicePath; +} /** Return all the root bridge instances in an array. @@ -188,6 +213,29 @@ PciHostBridgeGetRootBridges ( UINTN *Count ) { + UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo; + EFI_HOB_GUID_TYPE *GuidHob; + UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader; + + // + // Find Universal Payload PCI Root Bridge Info hob + // + GuidHob = GetFirstGuidHob (&gUniversalPayloadPciRootBridgeInfoGuid); + if (GuidHob != NULL) { + GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob); + if ((sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) <= GET_GUID_HOB_DATA_SIZE (GuidHob)) && (GenericHeader->Length <= GET_GUID_HOB_DATA_SIZE (GuidHob))) { + if ((GenericHeader->Revision == UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION) && (GenericHeader->Length >= sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES))) { + // + // UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES structure is used when Revision equals to UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION + // + PciRootBridgeInfo = (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *)GET_GUID_HOB_DATA (GuidHob); + if (PciRootBridgeInfo->Count <= (GET_GUID_HOB_DATA_SIZE (GuidHob) - sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES)) / sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE)) { + return RetrieveRootBridgeInfoFromHob (PciRootBridgeInfo, Count); + } + } + } + } + return ScanForRootBridges (Count); } diff --git a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf index 1682493406..e29197bb84 100644 --- a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf +++ b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf @@ -40,3 +40,7 @@ MemoryAllocationLib PciLib DxeServicesTableLib + HobLib + +[Guids] + gUniversalPayloadPciRootBridgeInfoGuid diff --git a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c index 0e0520fe92..47a9a65524 100644 --- a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c +++ b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c @@ -568,3 +568,69 @@ ScanForRootBridges ( return RootBridges; } + +/** + Scan for all root bridges from Universal Payload PciRootBridgeInfoHob + + @param[in] PciRootBridgeInfo Pointer of Universal Payload PCI Root Bridge Info Hob + @param[out] NumberOfRootBridges Number of root bridges detected + + @retval Pointer to the allocated PCI_ROOT_BRIDGE structure array. + +**/ +PCI_ROOT_BRIDGE * +RetrieveRootBridgeInfoFromHob ( + IN UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo, + OUT UINTN *NumberOfRootBridges + ) +{ + PCI_ROOT_BRIDGE *PciRootBridges; + UINTN Size; + UINT8 Index; + + ASSERT (PciRootBridgeInfo != NULL); + ASSERT (NumberOfRootBridges != NULL); + if (PciRootBridgeInfo == NULL) { + return NULL; + } + + ASSERT (PciRootBridgeInfo->Count != 0); + + Size = PciRootBridgeInfo->Count * sizeof (PCI_ROOT_BRIDGE); + PciRootBridges = (PCI_ROOT_BRIDGE *)AllocatePool (Size); + ASSERT (PciRootBridges != NULL); + if (PciRootBridges == NULL) { + return NULL; + } + + ZeroMem (PciRootBridges, PciRootBridgeInfo->Count * sizeof (PCI_ROOT_BRIDGE)); + + // + // Create all root bridges with PciRootBridgeInfoHob + // + for (Index = 0; Index < PciRootBridgeInfo->Count; Index++) { + PciRootBridges[Index].Segment = PciRootBridgeInfo->RootBridge[Index].Segment; + PciRootBridges[Index].Supports = PciRootBridgeInfo->RootBridge[Index].Supports; + PciRootBridges[Index].Attributes = PciRootBridgeInfo->RootBridge[Index].Attributes; + PciRootBridges[Index].DmaAbove4G = PciRootBridgeInfo->RootBridge[Index].DmaAbove4G; + PciRootBridges[Index].NoExtendedConfigSpace = PciRootBridgeInfo->RootBridge[Index].NoExtendedConfigSpace; + PciRootBridges[Index].ResourceAssigned = PciRootBridgeInfo->ResourceAssigned; + PciRootBridges[Index].AllocationAttributes = PciRootBridgeInfo->RootBridge[Index].AllocationAttributes; + PciRootBridges[Index].DevicePath = CreateRootBridgeDevicePath (PciRootBridgeInfo->RootBridge[Index].HID, PciRootBridgeInfo->RootBridge[Index].UID); + CopyMem (&PciRootBridges[Index].Bus, &PciRootBridgeInfo->RootBridge[Index].Bus, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE)); + CopyMem (&PciRootBridges[Index].Io, &PciRootBridgeInfo->RootBridge[Index].Io, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE)); + CopyMem (&PciRootBridges[Index].Mem, &PciRootBridgeInfo->RootBridge[Index].Mem, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE)); + CopyMem (&PciRootBridges[Index].MemAbove4G, &PciRootBridgeInfo->RootBridge[Index].MemAbove4G, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE)); + CopyMem (&PciRootBridges[Index].PMem, &PciRootBridgeInfo->RootBridge[Index].PMem, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE)); + CopyMem (&PciRootBridges[Index].PMemAbove4G, &PciRootBridgeInfo->RootBridge[Index].PMemAbove4G, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE)); + } + + *NumberOfRootBridges = PciRootBridgeInfo->Count; + + // + // Now, this library only supports RootBridge that ResourceAssigned is True + // + ASSERT (PciRootBridgeInfo->ResourceAssigned); + + return PciRootBridges; +} From d0eca9872e5cd0496c8b7dfd36752ff75aee10c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Wed, 22 Oct 2025 15:16:02 +0200 Subject: [PATCH 2/4] DasharoPayloadPkg/BlSupportPei: Add missing tested attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mark the range 0x1000-0xa0000 as tested. It caused the payload to mark this range as reserved. As a result, Linux kernel could not allocate memory for real mode and panicked. Signed-off-by: Michał Żygowski --- DasharoPayloadPkg/BlSupportPei/BlSupportPei.c | 1 + 1 file changed, 1 insertion(+) diff --git a/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c b/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c index ccefe4dc9e..b3749ea442 100644 --- a/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c +++ b/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c @@ -689,6 +689,7 @@ BlPeiEntryPoint ( ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_TESTED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | From 13092191ba7b560388ea49a9402be2519bf57e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Wed, 5 Nov 2025 14:47:52 +0100 Subject: [PATCH 3/4] DasharoPayloadPkg/Library/CbParseLib: Handle memory map for AMD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There was a dirty hack for Intel platforms that read TOLUD register to determine the boundary between MMIO and DRAM. It caused problems on AMD platforms such as apu2, which does not have TOLUD register. As a result, regions which held reserved memory were incorrectly reported as RAM buffers or RAM itself and the OS allocated DMA there. It could be observed with many IO_PAGE_FAULTs occurring in the OS. See: Dasharo/dasharo-issues#1134 FWTS complains on ECAM MMCONF not being reserved in the memory map. So carve it out of the memory map and report it as reserved. Signed-off-by: Michał Żygowski --- DasharoPayloadPkg/Include/Coreboot.h | 15 +-- .../Library/CbParseLib/CbParseLib.c | 109 ++++++++++++++++-- .../Library/CbParseLib/CbParseLib.inf | 3 + 3 files changed, 109 insertions(+), 18 deletions(-) diff --git a/DasharoPayloadPkg/Include/Coreboot.h b/DasharoPayloadPkg/Include/Coreboot.h index 7656140bb2..82b5533e8a 100644 --- a/DasharoPayloadPkg/Include/Coreboot.h +++ b/DasharoPayloadPkg/Include/Coreboot.h @@ -111,13 +111,14 @@ struct cb_memory_range { UINT32 type; }; -#define CB_MEM_RAM 1 -#define CB_MEM_RESERVED 2 -#define CB_MEM_ACPI 3 -#define CB_MEM_NVS 4 -#define CB_MEM_UNUSABLE 5 -#define CB_MEM_VENDOR_RSVD 6 -#define CB_MEM_TABLE 16 +#define CB_MEM_RAM 1 +#define CB_MEM_RESERVED 2 +#define CB_MEM_ACPI 3 +#define CB_MEM_NVS 4 +#define CB_MEM_UNUSABLE 5 +#define CB_MEM_VENDOR_RSVD 6 +#define CB_MEM_TABLE 16 +#define CB_MEM_SOFT_RESERVED 0xefffffff struct cb_memory { UINT32 tag; diff --git a/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c b/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c index 7e8af0d289..d46fe41119 100644 --- a/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c +++ b/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -402,7 +403,10 @@ ParseCbMemTable ( return Status; } - +#define MSR_TOP_MEM 0xC001001A +#define MSR_TOM2 0xC001001D +#define TOLUD 0xBC +#define TOUUD 0xA8 /** Acquire the memory information from the coreboot table in memory. @@ -425,9 +429,28 @@ ParseMemoryInfo ( struct cb_memory_range *Range; UINTN Index; MEMROY_MAP_ENTRY MemoryMap; - UINT32 Tolud; + MEMROY_MAP_ENTRY NewMemoryMap; + UINT64 Tolud; + UINT64 Touud; + UINT64 PcieBase; + UINT64 PcieBaseEnd; + + PcieBase = PcdGet64(PcdPciExpressBaseAddress); + PcieBaseEnd = PcieBase + PcdGet64(PcdPciExpressBaseSize); + + Tolud = 0; + Touud = 0; + + if (PciRead16(PCI_LIB_ADDRESS(0, 0, 0, 0x00)) == 0x8086) /* Intel */ { + Tolud = PciRead32(PCI_LIB_ADDRESS(0, 0, 0, TOLUD)) & 0xFFF00000; + Touud = PciRead32(PCI_LIB_ADDRESS(0, 0, 0, TOUUD)) & 0xFFF00000; + Touud |= RShiftU64(PciRead32(PCI_LIB_ADDRESS(0, 0, 0, TOUUD + 4)), 32); + } else if (PciRead16(PCI_LIB_ADDRESS(0, 0, 0, 0x00)) == 0x1022) /* AMD */ { + Tolud = AsmReadMsr64(MSR_TOP_MEM); + Touud = AsmReadMsr64(MSR_TOM2); + } - Tolud = PciRead32(PCI_LIB_ADDRESS(0,0,0,0xbc)) & 0xFFF00000; + DEBUG ((DEBUG_INFO, "Tolud: %016lx\nTouud: %016lx\n", Tolud, Touud)); // // Get the coreboot memory table @@ -451,13 +474,46 @@ ParseMemoryInfo ( /* Only MMIO is marked reserved */ case CB_MEM_RESERVED: /* - * Reserved memory Below TOLUD can't be MMIO except legacy VGA which - * is reported elsewhere as reserved. + * Reserved memory Below TOLUD/TOUUD can't be MMIO except legacy VGA + * which is reported elsewhere as reserved. */ - if (MemoryMap.Base < Tolud) { - MemoryMap.Type = EFI_RESOURCE_MEMORY_RESERVED; - MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; + if (MemoryMap.Base >= BASE_4GB && Touud != 0) { + if (MemoryMap.Base < Touud) { + MemoryMap.Type = EFI_RESOURCE_MEMORY_RESERVED; + MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; + } else { + MemoryMap.Type = EFI_RESOURCE_MEMORY_MAPPED_IO; + MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; + } + } else if (MemoryMap.Base < BASE_4GB && Tolud != 0) { + if (MemoryMap.Base < Tolud) { + /* + * Special case, coreboot tables live near TOLUD. Check if range + * needs splitting for reserved memory and MMIO. + */ + if ((MemoryMap.Base + MemoryMap.Size) > Tolud) { + MemoryMap.Type = EFI_RESOURCE_MEMORY_RESERVED; + MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; + MemoryMap.Size = Tolud - MemoryMap.Base; + + DEBUG ((DEBUG_INFO, "%d. %016lx - %016lx [%02x]\n", + Index, MemoryMap.Base, MemoryMap.Base + MemoryMap.Size - 1, MemoryMap.Type)); + MemInfoCallback (&MemoryMap, Params); + + MemoryMap.Base = Tolud; + MemoryMap.Size = cb_unpack64(Range->size) - MemoryMap.Size; + MemoryMap.Type = EFI_RESOURCE_MEMORY_MAPPED_IO; + MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; + } else { + MemoryMap.Type = EFI_RESOURCE_MEMORY_RESERVED; + MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; + } + } else { + MemoryMap.Type = EFI_RESOURCE_MEMORY_MAPPED_IO; + MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; + } } else { + /* Fallback, if not Intel/AMD or TOLUD/TOUUD is zero, treat everything as MMIO */ MemoryMap.Type = EFI_RESOURCE_MEMORY_MAPPED_IO; MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; } @@ -473,6 +529,7 @@ ParseMemoryInfo ( /* ACPI/SMBIOS/CBMEM has it's own tag */ case CB_MEM_ACPI: case CB_MEM_TABLE: + case CB_MEM_SOFT_RESERVED: MemoryMap.Type = EFI_RESOURCE_MEMORY_RESERVED; MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; break; @@ -480,10 +537,40 @@ ParseMemoryInfo ( continue; } - DEBUG ((DEBUG_INFO, "%d. %016lx - %016lx [%02x]\n", - Index, MemoryMap.Base, MemoryMap.Base + MemoryMap.Size - 1, MemoryMap.Type)); + /* + * PCIe MMCONF must be reserved, so override the type and split the range if needed. + */ + if (MemoryMap.Base == PcieBase && (MemoryMap.Base + MemoryMap.Size) == PcieBaseEnd) { + /* Range exactly covers MMCONF, don't report it. It will be done later */ + continue; + } else if (MemoryMap.Base <= PcieBase && (MemoryMap.Base + MemoryMap.Size) >= PcieBaseEnd) { + /* Range overlaps MMCONF */ + if (MemoryMap.Base < PcieBase) { + NewMemoryMap.Base = MemoryMap.Base; + NewMemoryMap.Size = PcieBase - MemoryMap.Base; + NewMemoryMap.Type = MemoryMap.Type; + NewMemoryMap.Flag = MemoryMap.Flag; + + DEBUG ((DEBUG_INFO, "%d. %016lx - %016lx [%02x]\n", + Index, NewMemoryMap.Base, NewMemoryMap.Base + NewMemoryMap.Size - 1, NewMemoryMap.Type)); + + MemInfoCallback (&NewMemoryMap, Params); + } + if ((MemoryMap.Base + MemoryMap.Size) > PcieBaseEnd) { + MemoryMap.Size -= (PcieBaseEnd - MemoryMap.Base); + MemoryMap.Base = PcieBaseEnd; + + DEBUG ((DEBUG_INFO, "%d. %016lx - %016lx [%02x]\n", + Index, MemoryMap.Base, MemoryMap.Base + MemoryMap.Size - 1, MemoryMap.Type)); - MemInfoCallback (&MemoryMap, Params); + MemInfoCallback (&MemoryMap, Params); + } + } else { + DEBUG ((DEBUG_INFO, "%d. %016lx - %016lx [%02x]\n", + Index, MemoryMap.Base, MemoryMap.Base + MemoryMap.Size - 1, MemoryMap.Type)); + + MemInfoCallback (&MemoryMap, Params); + } } return RETURN_SUCCESS; diff --git a/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.inf b/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.inf index 2a736f4cef..fc2eaa950f 100644 --- a/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.inf +++ b/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.inf @@ -36,9 +36,12 @@ PcdLib PciLib HobLib + CpuLib [Pcd] gDasharoPayloadPkgTokenSpaceGuid.PcdPayloadStackTop + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseSize [Guids] gUniversalPayloadPciRootBridgeInfoGuid From c6c5fd8a8a14fb74f7e404aac85716c6cced31ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Wed, 5 Nov 2025 16:59:37 +0100 Subject: [PATCH 4/4] DasharoPayloadPkg/BlSupportPei/BlSupportPei.c: Reserve PCIe MMCONF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FWTS complains on MMCONF not being reseved in memory map. So reserve it. Signed-off-by: Michał Żygowski --- DasharoPayloadPkg/BlSupportPei/BlSupportPei.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c b/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c index b3749ea442..b8e303d10c 100644 --- a/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c +++ b/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c @@ -869,6 +869,21 @@ BlPeiEntryPoint ( DEBUG ((DEBUG_INFO, "Create acpi board info guid hob\n")); } + // + // Reserve MMCONF range + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_RESERVED, + ( + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_TESTED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE + ), + AcpiBoardInfo.PcieBaseAddress, + AcpiBoardInfo.PcieBaseSize + ); + // Build SEC Performance Data Hob Status = ParseTimestampTable(&Performance); if (!EFI_ERROR (Status)) {