The primary objective of this patch is to create SRAT, HMAT table at runtime based on configuration data found by discovering remote CXL Mem device. In SRAT table, the Localmemory, GICC structure information remain Static, but only configuration data about Remote memory node is updated at runtime. In HMAT the latency numbers are not tuned to actual performance values in current solution. After consolidating all structure data, SRAT and HMAT tables are installed.
This patch creates and registers notifier event in AcpiTableGenerator DXE, and the event depends on CXL protocol interface, so that remote memory node population in SRAT, HMAT tables can be performed after CXL device discovery and necessary configuration. While preparing SRAT table, CXL memory information (number of memory nodes, remote memory size) is fetched from CXL Dxe using CXLprotocol interfaces. If remote CXL memory is present then from the reserved Host address space an area equal to remote CXL memory size will be added to EFI System Memory space. The memory is EfiGcdMemoryTypeSystemMemory and has Normal memory attributes. In Single-Chip scenario, one of the primary use case, of having extended remote memory area and SRAT,HMAT table, is to avail CXL.Memory device as memory expander. Signed-off-by: Sayanta Pattanayak <sayanta.pattana...@arm.com> --- Platform/ARM/SgiPkg/SgiPlatform.dsc.inc | 7 + Platform/ARM/SgiPkg/SgiPlatform.fdf | 9 +- Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/AcpiTableGenerator.inf | 68 +++++ Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/AcpiTableGenerator.h | 39 +++ Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/AcpiTableGenerator.c | 106 +++++++ Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/HmatTableGenerator.c | 120 ++++++++ Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/SratTableGenerator.c | 312 ++++++++++++++++++++ 7 files changed, 660 insertions(+), 1 deletion(-) diff --git a/Platform/ARM/SgiPkg/SgiPlatform.dsc.inc b/Platform/ARM/SgiPkg/SgiPlatform.dsc.inc index 26b9a11a24..fbe5b0b705 100644 --- a/Platform/ARM/SgiPkg/SgiPlatform.dsc.inc +++ b/Platform/ARM/SgiPkg/SgiPlatform.dsc.inc @@ -310,6 +310,13 @@ # Platform/ARM/SgiPkg/Drivers/PlatformDxe/PlatformDxe.inf + # + # SRAT/HMAT Table generator + # +!if $(EDK2_ENABLE_REMOTE_CXL_MEM) == TRUE + Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/AcpiTableGenerator.inf +!endif + # # FAT filesystem + GPT/MBR partitioning # diff --git a/Platform/ARM/SgiPkg/SgiPlatform.fdf b/Platform/ARM/SgiPkg/SgiPlatform.fdf index 7e55214c20..b1a227f22e 100644 --- a/Platform/ARM/SgiPkg/SgiPlatform.fdf +++ b/Platform/ARM/SgiPkg/SgiPlatform.fdf @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2021, ARM Limited. All rights reserved. +# Copyright (c) 2018 - 2022, Arm Limited. All rights reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -194,6 +194,13 @@ READ_LOCK_STATUS = TRUE INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf + # + # SRAT/HMAT Table generator + # +!if $(EDK2_ENABLE_REMOTE_CXL_MEM) == TRUE + INF Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/AcpiTableGenerator.inf +!endif + # # Networking stack # diff --git a/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/AcpiTableGenerator.inf b/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/AcpiTableGenerator.inf new file mode 100644 index 0000000000..484e05f269 --- /dev/null +++ b/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/AcpiTableGenerator.inf @@ -0,0 +1,68 @@ +## @file +# ACPI table generator sources. +# +# SRAT, HMAT table generator sources prepare respective ACPI tables, that +# help OSPM to identify device domains, memory attributes etc. +# +# Copyright (c) 2023, Arm Limited. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = AcpiTableGeneratorLib + FILE_GUID = fd0e015b-bbbf-474c-8b68-9ea1b555f913 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = AcpiTableGeneratorEntryPoint + +[Sources.common] + AcpiTableGenerator.c + HmatTableGenerator.c + SratTableGenerator.c + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + Platform/ARM/Drivers/CxlDxe/CxlDxe.dec + Platform/ARM/SgiPkg/SgiPlatform.dec + + +[LibraryClasses] + ArmPlatformLib + BaseLib + DebugLib + DxeServicesTableLib + HobLib + IoLib + MemoryAllocationLib + UefiDriverEntryPoint + +[Protocols] + gEfiAcpiTableProtocolGuid ## CONSUMES + gCxlPlatformProtocolGuid ## CONSUMES + +[Depex] + TRUE + +[FixedPcd] + gArmPlatformTokenSpaceGuid.PcdClusterCount + gArmPlatformTokenSpaceGuid.PcdCoreCount + + gArmSgiTokenSpaceGuid.PcdChipCount + gArmSgiTokenSpaceGuid.PcdDramBlock2Base + gArmSgiTokenSpaceGuid.PcdDramBlock2Size + gArmSgiTokenSpaceGuid.PcdGicSize + gArmSgiTokenSpaceGuid.PcdNumLocalMemBlock + gArmSgiTokenSpaceGuid.PcdRemoteMemoryBase + gArmSgiTokenSpaceGuid.PcdRemoteMemorySize + + gArmTokenSpaceGuid.PcdMmBufferBase + gArmTokenSpaceGuid.PcdMmBufferSize + gArmTokenSpaceGuid.PcdSystemMemoryBase + gArmTokenSpaceGuid.PcdSystemMemorySize diff --git a/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/AcpiTableGenerator.h b/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/AcpiTableGenerator.h new file mode 100644 index 0000000000..d9f5b396aa --- /dev/null +++ b/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/AcpiTableGenerator.h @@ -0,0 +1,39 @@ +/** @file + Function declarations for AcpiTableGenerator. + + Function declarations are needed for creating ACPI tables at runtime. + Macros for Remote memory nodes. + + Copyright (c) 2023, Arm Limited. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef ACPI_TABLE_GENERATOR_H_ +#define ACPI_TABLE_GENERATOR_H_ + +#include <Library/AcpiLib.h> +#include <Library/AmlLib/AmlLib.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/IoLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Protocol/AcpiTable.h> +#include <Protocol/Cxl.h> +#include <SgiAcpiHeader.h> +#include <SgiPlatform.h> + +#define LOWER_BYTES_MASK 0xFFFFF000 +#define LOWER_BYTES_SHIFT 32 + +EFI_STATUS EFIAPI SratTableGenerator ( + EFI_ACPI_TABLE_PROTOCOL *mAcpiTableProtocol + ); + +EFI_STATUS EFIAPI HmatTableGenerator ( + EFI_ACPI_TABLE_PROTOCOL *mAcpiTableProtocol + ); + +#endif /* ACPI_TABLE_GENERATOR_H_ */ diff --git a/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/AcpiTableGenerator.c b/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/AcpiTableGenerator.c new file mode 100644 index 0000000000..3faacfde00 --- /dev/null +++ b/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/AcpiTableGenerator.c @@ -0,0 +1,106 @@ +/** @file + ACPI Table Generator Entrypoint. It invokes functions to + generate SRAT, HMAT tables. + + Copyright (c) 2023, Arm Limited. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "AcpiTableGenerator.h" + +VOID *mCxlProtocolRegistration; + +STATIC EFI_ACPI_TABLE_PROTOCOL *mAcpiTableProtocol = NULL; + +// Protocol event handler for creating SRAT, HMAT tables +VOID +EFIAPI +AcpiTableGenerator ( + IN EFI_EVENT Event, + IN VOID* Context + ) +{ + EFI_STATUS Status; + + Status = gBS->LocateProtocol ( + &gEfiAcpiTableProtocolGuid, + NULL, + (VOID **)&mAcpiTableProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to locate ACPI table protocol, status: %r\n", + __func__, + Status + )); + return; + } + + Status = SratTableGenerator (mAcpiTableProtocol); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to create SRAT table: %r\n", + __func__, + Status + )); + return; + } + + Status = HmatTableGenerator (mAcpiTableProtocol); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to create HMAT table: %r\n", + __func__, + Status + )); + return; + } + + gBS->CloseEvent (Event); + return; +} + +/** + Initialize function for the driver. + + Locate ACPI Table protocol and installs SRAT, HMAT tables. + + @param[in] ImageHandle Handle to image. + @param[in] SystemTable Pointer to System table. + + @retval EFI_SUCCESS On successful installation of SRAT, HMAT ACPI tables. + @retval Other Failure in installing ACPI tables. + +**/ +EFI_STATUS +EFIAPI +AcpiTableGeneratorEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT CxlProtocolEvent; + + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + AcpiTableGenerator, + NULL, + &CxlProtocolEvent + ); + + // + // Register for protocol notifications on this event + // + Status = gBS->RegisterProtocolNotify ( + &gCxlPlatformProtocolGuid, + CxlProtocolEvent, + &mCxlProtocolRegistration + ); + + return Status; +} diff --git a/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/HmatTableGenerator.c b/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/HmatTableGenerator.c new file mode 100644 index 0000000000..b21ac86e25 --- /dev/null +++ b/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/HmatTableGenerator.c @@ -0,0 +1,120 @@ +/** @file + Heterogeneous Memory Attribute Table (HMAT) Table Generator. + + The (HMAT) describes the memory attributes, such as bandwidth and latency + details, related to Memory Proximity Domains. The software is expected + to use this information as a hint for optimization, or when the system has + heterogeneous memory. + + Copyright (c) 2023, Arm Limited. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Specification Reference: + - ACPI 6.4, Chapter 5.2.27 Heterogeneous Memory Attribute Table (HMAT) +**/ + +#include "AcpiTableGenerator.h" + +#define CHIP_CNT 2 +#define INITATOR_PROXIMITY_DOMAIN_CNT 2 +#define TARGET_PROXIMITY_DOMAIN_CNT 2 + +/* HMAT Table */ +typedef struct InitiatorTargetProximityMatrix { + UINT32 InitatorProximityDomain[INITATOR_PROXIMITY_DOMAIN_CNT]; + UINT32 TargetProximityDomain[TARGET_PROXIMITY_DOMAIN_CNT]; + UINT16 MatrixEntry[INITATOR_PROXIMITY_DOMAIN_CNT * + TARGET_PROXIMITY_DOMAIN_CNT]; +} INITIATOR_TARGET_PROXIMITY_MATRIX; + +typedef struct { + EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER Header; + EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES + Proximity[CHIP_CNT]; + EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO + LatencyInfo; + INITIATOR_TARGET_PROXIMITY_MATRIX Matrix; +} EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE; + +EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE Hmat = { + // Header + { + ARM_ACPI_HEADER ( + EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE, + EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE, + EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_REVISION + ), + { + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE + }, + }, + + // Memory Proximity Domain + { + EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES_INIT ( + 1, 0x0, 0x0), + EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES_INIT ( + 1, 0x0, 0x1), + }, + + // Latency Info + EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO_INIT ( + 0, 0, 0, INITATOR_PROXIMITY_DOMAIN_CNT, TARGET_PROXIMITY_DOMAIN_CNT, 100), + { + {0, 1}, + {0, 1}, + { + // + // The latencies mentioned in this table are hypothetical values and + // represents typical latency between two chips. These values are + // applicable only for RD-N1-Edge dual-chip fixed virtual platform and + // should not be reused for other platforms. + // + 10, 20, + 20, 10, + } + } +}; + +/** + Installs the HMAT table. + + @param[in] mAcpiTableProtocol Handle to AcpiTableProtocol. + + @retval EFI_SUCCESS On successful installation of HMAT table. + @retval Other Failure in installing HMAT table. +**/ +EFI_STATUS +EFIAPI +HmatTableGenerator ( + IN EFI_ACPI_TABLE_PROTOCOL *mAcpiTableProtocol + ) +{ + EFI_STATUS Status; + UINTN AcpiTableHandle; + + Status = mAcpiTableProtocol->InstallAcpiTable ( + mAcpiTableProtocol, + &Hmat, + sizeof (Hmat), + &AcpiTableHandle + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: HMAT table installation failed, status: %r\n", + __func__, + Status + )); + } else { + DEBUG (( + DEBUG_INFO, + "Installed HMAT table \n" + )); + } + + return Status; +} diff --git a/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/SratTableGenerator.c b/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/SratTableGenerator.c new file mode 100644 index 0000000000..50a26b8fca --- /dev/null +++ b/Platform/ARM/SgiPkg/Library/AcpiTableGeneratorLib/SratTableGenerator.c @@ -0,0 +1,312 @@ +/** @file + SRAT Table Generator. + + SRAT table provides information that allows OSPM to associate devices such as + processors with system locality / proximity domains and clock domains. + + Copyright (c) 2023, Arm Limited. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Specification Reference: + - ACPI 6.4, Chapter 5.2.16 System Resource Affinity Table (SRAT) +**/ + +#include <Library/DxeServicesTableLib.h> +#include <Library/HobLib.h> +#include "AcpiTableGenerator.h" + +STATIC EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE *RemoteMemory; + +EFI_ACPI_6_4_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER SratHeader = { + ARM_ACPI_HEADER ( + EFI_ACPI_6_4_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE, + EFI_ACPI_6_4_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER, + EFI_ACPI_6_4_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION + ), + 0x00000001, + EFI_ACPI_RESERVED_QWORD +}; + +EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE Gicc[8] = { + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x00000000, 0x00000001, 0x00000000), + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x00000001, 0x00000001, 0x00000000), + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x00000002, 0x00000001, 0x00000000), + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x00000003, 0x00000001, 0x00000000), + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x00000004, 0x00000001, 0x00000000), + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x00000005, 0x00000001, 0x00000000), + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x00000006, 0x00000001, 0x00000000), + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x00000007, 0x00000001, 0x00000000), +#if ((CORE_COUNT * CLUSTER_COUNT) > 8) + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x00000008, 0x00000001, 0x00000000), + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x00000009, 0x00000001, 0x00000000), + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x0000000A, 0x00000001, 0x00000000), + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x0000000B, 0x00000001, 0x00000000), + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x0000000C, 0x00000001, 0x00000000), + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x0000000D, 0x00000001, 0x00000000), + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x0000000E, 0x00000001, 0x00000000), + EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE_INIT ( + 0x0, 0x0000000F, 0x00000001, 0x00000000), +#endif +}; + +EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE LocalMemory[3] = { + // Memory at 32-bit address space + EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE_INIT ( + 0x0, FixedPcdGet64 (PcdSystemMemoryBase), + FixedPcdGet64 (PcdSystemMemorySize), 0x00000001), + // Memory at 64-bit address space + EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE_INIT ( + 0x0, FixedPcdGet64 (PcdDramBlock2Base), + FixedPcdGet64 (PcdDramBlock2Size), 0x00000001), + // MmBuffer region + EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE_INIT ( + 0x0, FixedPcdGet64 (PcdMmBufferBase), + FixedPcdGet64 (PcdMmBufferSize), 0x00000001), +}; + +/** + Fetch the details of Remote Memory Node, using CXL protocol interfaces. + + By using CXL platform protocol interfaces, fetch number CXL remote memory + nodes and their corresponding configurations(Base address, length). + + @param[out] RemoteMemCount Number of Remote CXL memory nodes. + + @retval RemoteMem Remote memory configuraiton on successful fetching + of remote memory configuration. + @retval Zero Returns Zero on failure. +**/ +STATIC +REMOTE_MEMORY_CONFIG * +FetchRemoteCxlMem (OUT UINT32 *RemoteMemCount) +{ + EFI_STATUS Status; + CXL_PLATFORM_PROTOCOL *CxlProtocol; + REMOTE_MEMORY_CONFIG *RemoteMem; + UINT32 RemoteMemNumber; + + Status = gBS->LocateProtocol ( + &gCxlPlatformProtocolGuid, + NULL, + (VOID **)&CxlProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to locate CXL Protocol, status: %r\n", + __func__, + Status + )); + return 0; + } + + RemoteMemNumber = CxlProtocol->CxlGetRemoteMemCount (); + if (RemoteMemNumber) { + RemoteMem = (REMOTE_MEMORY_CONFIG *) AllocateZeroPool ( + sizeof (REMOTE_MEMORY_CONFIG) * + RemoteMemNumber + ); + if (RemoteMem == NULL) { + DEBUG ((DEBUG_WARN, "No memory for Remote Memory affinity structure:\n")); + return 0; + } + } else { + DEBUG ((DEBUG_INFO, "No Remote Memory node exists:\n")); + return 0; + } + + Status = CxlProtocol->CxlGetRemoteMem (RemoteMem, &RemoteMemNumber); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to get CXL Remote memory details: %r\n", + __func__, + Status + )); + FreePool(RemoteMem); + return 0; + } + + *RemoteMemCount = RemoteMemNumber; + + return RemoteMem; +} + +/** + Fetch the details of all Remote Memory Node, using CXL protocol interfaces. + Prepare SRAT table structure by combining LocalMemoryNode and + RemoteMemoryNode information. Thereafter installs the SRAT table. + + @param[in] mAcpiTableProtocol Handle to AcpiTableProtocol. + + @retval EFI_SUCCESS On successful installation of SRAT table. + @retval Other Failure in installing SRAT table. +**/ +EFI_STATUS +EFIAPI +SratTableGenerator ( + IN EFI_ACPI_TABLE_PROTOCOL *mAcpiTableProtocol + ) +{ + EFI_STATUS Status; + UINTN AcpiTableHandle; + UINTN MemoryNodeCount; + UINTN TableSize; + UINT8 Idx; + VOID *Srat, *SratDataNext; + REMOTE_MEMORY_CONFIG *RemoteMem; + UINT32 RemoteMemCount; + UINT64 HostPhysicalBase; + UINT64 MemDevicePhysicalBase; + + RemoteMem = FetchRemoteCxlMem (&RemoteMemCount); + + if (RemoteMemCount) { + RemoteMemory = AllocateZeroPool ( + sizeof (EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE) * + RemoteMemCount + ); + + if (RemoteMemory == NULL) { + DEBUG ((DEBUG_WARN, "No memory for Remote Memory affinity structure:\n")); + RemoteMemCount = 0; + } else { + HostPhysicalBase = FixedPcdGet64 (PcdRemoteMemoryBase); + + for (Idx = 0; Idx < RemoteMemCount; Idx++) { + RemoteMemory[Idx].Type = 1; + RemoteMemory[Idx].Length = + sizeof (EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE); + RemoteMemory[Idx].ProximityDomain = 1; + RemoteMemory[Idx].Reserved1 = EFI_ACPI_RESERVED_WORD; + + MemDevicePhysicalBase = HostPhysicalBase + RemoteMem[Idx].DpaAddress; + RemoteMemory[Idx].AddressBaseLow = + MemDevicePhysicalBase & LOWER_BYTES_MASK; + RemoteMemory[Idx].AddressBaseHigh = + MemDevicePhysicalBase >> LOWER_BYTES_SHIFT; + + RemoteMemory[Idx].LengthLow = + RemoteMem[Idx].DpaLength & LOWER_BYTES_MASK; + RemoteMemory[Idx].LengthHigh = + RemoteMem[Idx].DpaLength >> LOWER_BYTES_SHIFT; + + RemoteMemory[Idx].Reserved2 = EFI_ACPI_RESERVED_WORD; + RemoteMemory[Idx].Flags = 0x1; + RemoteMemory[Idx].Reserved3 = EFI_ACPI_RESERVED_WORD; + + HostPhysicalBase += RemoteMem[Idx].DpaLength; + } + + Status = gDS->AddMemorySpace ( + EfiGcdMemoryTypeSystemMemory, + FixedPcdGet64 (PcdRemoteMemoryBase), + (HostPhysicalBase - FixedPcdGet64 (PcdRemoteMemoryBase)), + EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB); + + Status = gDS->SetMemorySpaceAttributes ( + FixedPcdGet64 (PcdRemoteMemoryBase), + (HostPhysicalBase - FixedPcdGet64 (PcdRemoteMemoryBase)), + EFI_MEMORY_WB); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to set memory attributes: %r\n", + __func__, + Status + )); + FreePool (RemoteMem); + return 0; + } + } + + FreePool (RemoteMem); + } + + MemoryNodeCount = FixedPcdGet32 (PcdNumLocalMemBlock); + MemoryNodeCount += RemoteMemCount; + TableSize = sizeof (Gicc) + + sizeof (SratHeader) + + (MemoryNodeCount * + sizeof (EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE)); + + Srat = AllocatePool (TableSize); + + if (Srat == NULL) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to allocate memory for SRAT table\n", + __func__ + )); + + FreePool(RemoteMemory); + return EFI_OUT_OF_RESOURCES; + } + + CopyMem ( + Srat, + &SratHeader, + sizeof (SratHeader) + ); + + SratDataNext = ((char *)Srat + sizeof (SratHeader)); + CopyMem ( + SratDataNext, + Gicc, + sizeof (Gicc) + ); + + SratDataNext = ((char *)SratDataNext + sizeof (Gicc)); + CopyMem ( + SratDataNext, + LocalMemory, + sizeof (LocalMemory) + ); + + SratDataNext = ((char *)SratDataNext + sizeof (LocalMemory)); + if (RemoteMemCount) { + CopyMem ( + SratDataNext, + RemoteMemory, + sizeof (EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE) * + RemoteMemCount + ); + } + + ((EFI_ACPI_DESCRIPTION_HEADER *)Srat)->Length = TableSize; + + Status = mAcpiTableProtocol->InstallAcpiTable ( + mAcpiTableProtocol, + (EFI_ACPI_6_4_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *)Srat, + TableSize, + &AcpiTableHandle + ); + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: SRAT table installation failed, status: %r\n", + __func__, + Status + )); + } else { + DEBUG ((DEBUG_INFO, "Installed SRAT table \n")); + } + + return Status; +} -- 2.25.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#109490): https://edk2.groups.io/g/devel/message/109490 Mute This Topic: https://groups.io/mt/101872995/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-