From a81ed7108c43dfcc3c294f09c2ce0ed012bd0d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sat, 23 Nov 2024 11:33:13 +0100 Subject: [PATCH] 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: https://github.com/Dasharo/dasharo-issues/issues/1134 Signed-off-by: Michał Żygowski --- .../Library/CbParseLib/CbParseLib.c | 46 +++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c b/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c index d51a2473d8..6a89c29a92 100644 --- a/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c +++ b/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c @@ -362,7 +362,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. @@ -385,9 +388,20 @@ ParseMemoryInfo ( struct cb_memory_range *Range; UINTN Index; MEMROY_MAP_ENTRY MemoryMap; - UINT32 Tolud; - - Tolud = PciRead32(PCI_LIB_ADDRESS(0,0,0,0xbc)) & 0xFFF00000; + UINT64 Tolud; + UINT64 Touud; + + 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); + } // // Get the coreboot memory table @@ -411,13 +425,27 @@ 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) { + 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; }