* [edk2-devel] [PATCH v2 1/1] SbsaQemu: AcpiDxe: Create SRAT table at runtime
2024-02-20 7:47 [edk2-devel] [PATCH v2 0/1] Add support for generating SRAT tables Xiong Yining
@ 2024-02-20 7:47 ` Xiong Yining
2024-03-26 14:07 ` Marcin Juszkiewicz
0 siblings, 1 reply; 3+ messages in thread
From: Xiong Yining @ 2024-02-20 7:47 UTC (permalink / raw)
To: devel
Cc: quic_llindhol, ardb+tianocore, graeme, marcin.juszkiewicz,
chenbaozi, Xiong Yining
Add support to create SRAT(System resource affinity table) for
sbsa platform at runtime.
Signed-off-by: Xiong Yining <xiongyining1480@phytium.com.cn>
Signed-off-by: Chen Baozi <chenbaozi@phytium.com.cn>
Reviewed-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
---
.../Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.h | 27 ++++++
.../Include/Library/SbsaQemuHardwareInfoLib.h | 11 +++
.../Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c | 92 +++++++++++++++++++
.../SbsaQemuHardwareInfoLib.c | 36 ++++++++
4 files changed, 166 insertions(+)
diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.h b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.h
index 7595df4c8a2d..83a085cd86f4 100644
--- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.h
+++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.h
@@ -63,4 +63,31 @@ typedef struct {
#define GTDT_WDTIMER_FLAGS (GTDT_WDTIMER_ACTIVE_HIGH | GTDT_WDTIMER_LEVEL_TRIGGERED)
+#define SBSAQEMU_ACPI_MEMORY_AFFINITY_STRUCTURE_INIT( \
+ ProximityDomain, Base, Length, Flags) \
+ { \
+ 1, /* Type */ \
+ sizeof (EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE), /* Length */ \
+ ProximityDomain, /* Proximity Domain */ \
+ 0, /* Reserved */ \
+ (Base) & 0xffffffff, /* Base Address Low */ \
+ ((Base) >> 32) & 0xffffffff , /* Base Address High */ \
+ (Length) & 0xffffffff, /* Length Low */ \
+ ((Length) >> 32) & 0xffffffff, /* Length High */ \
+ 0, /* Reserved */ \
+ Flags, /* Flags */ \
+ 0 /* Reserved */ \
+ }
+
+#define SBSAQEMU_ACPI_GICC_AFFINITY_STRUCTURE_INIT( \
+ ProximityDomain, ACPIProcessorUID, Flags, ClockDomain) \
+ { \
+ 3, /* Type */ \
+ sizeof (EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE), /* Length */ \
+ ProximityDomain, /* Proximity Domain */ \
+ ACPIProcessorUID, /* ACPI Processor UID */ \
+ Flags, /* Flags */ \
+ ClockDomain /* Clock Domain */ \
+ }
+
#endif
diff --git a/Silicon/Qemu/SbsaQemu/Include/Library/SbsaQemuHardwareInfoLib.h b/Silicon/Qemu/SbsaQemu/Include/Library/SbsaQemuHardwareInfoLib.h
index 0b71a3f7e6eb..831efe2e8d1d 100644
--- a/Silicon/Qemu/SbsaQemu/Include/Library/SbsaQemuHardwareInfoLib.h
+++ b/Silicon/Qemu/SbsaQemu/Include/Library/SbsaQemuHardwareInfoLib.h
@@ -70,4 +70,15 @@ SbsaQemuGetMemInfo (
IN UINTN MemoryId
);
+/**
+ Get the number of numa node from device tree passed by Qemu.
+
+ @retval the number of numa node.
+**/
+UINT64
+SbsaQemuGetNumaNodeCount (
+ VOID
+ );
+
+
#endif /* SBSA_QEMU_HARDWARE_INFO_ */
diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c
index 03f7a34977a0..2685d4b00426 100644
--- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c
+++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c
@@ -682,6 +682,91 @@ AddGtdtTable (
return Status;
}
+/*
+ * A function that adds the SRAT ACPI table.
+ */
+EFI_STATUS
+AddSratTable (
+ IN EFI_ACPI_TABLE_PROTOCOL *AcpiTable
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *New;
+ EFI_PHYSICAL_ADDRESS PageAddress;
+ UINTN TableHandle;
+ UINT32 TableSize;
+ UINT32 Index;
+ UINT32 NodeId;
+ UINT32 NumMemNodes;
+ MemoryInfo MemInfo;
+ UINT32 NumCores = PcdGet32 (PcdCoreCount);
+
+ // Initialize SRAT ACPI Header
+ EFI_ACPI_6_4_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER Header = {
+ SBSAQEMU_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),
+ 1, 0 };
+
+ NumMemNodes = SbsaQemuGetMemNodeCount();
+
+ // Calculate the new table size based on the number of cores
+ TableSize = sizeof (EFI_ACPI_6_4_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER) +
+ (sizeof (EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE) * NumMemNodes ) +
+ (sizeof (EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE) * NumCores);
+
+ Status = gBS->AllocatePages (
+ AllocateAnyPages,
+ EfiACPIReclaimMemory,
+ EFI_SIZE_TO_PAGES (TableSize),
+ &PageAddress
+ );
+
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to allocate pages for SRAT table\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ New = (UINT8 *)(UINTN) PageAddress;
+ ZeroMem (New, TableSize);
+
+ // Add the ACPI Description table header
+ CopyMem (New, &Header, sizeof (EFI_ACPI_6_4_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER));
+ ((EFI_ACPI_DESCRIPTION_HEADER*) New)->Length = TableSize;
+ New += sizeof (EFI_ACPI_6_4_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER);
+
+ // Add memory structures
+ for (Index = 0; Index < NumMemNodes ; Index++) {
+ MemInfo = SbsaQemuGetMemInfo (Index);
+ EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE memory = SBSAQEMU_ACPI_MEMORY_AFFINITY_STRUCTURE_INIT (MemInfo.NodeId, MemInfo.AddressBase, MemInfo.AddressSize, 1);
+ CopyMem (New, &memory, sizeof (EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE));
+ New += sizeof (EFI_ACPI_6_4_MEMORY_AFFINITY_STRUCTURE);
+ }
+
+ // Add processor structures for the cores
+ for (Index = 0; Index < NumCores; Index++) {
+ NodeId = SbsaQemuGetCpuNumaNode(Index);
+ EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE gicc = SBSAQEMU_ACPI_GICC_AFFINITY_STRUCTURE_INIT(NodeId, Index, 1, 0);
+ CopyMem (New, &gicc, sizeof (EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE));
+ New += sizeof (EFI_ACPI_6_4_GICC_AFFINITY_STRUCTURE);
+ }
+
+ // Perform Checksum
+ AcpiPlatformChecksum ((UINT8*) PageAddress, TableSize);
+
+ Status = AcpiTable->InstallAcpiTable (
+ AcpiTable,
+ (EFI_ACPI_COMMON_HEADER *)PageAddress,
+ TableSize,
+ &TableHandle
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to install SRAT table\n"));
+ }
+
+ return Status;
+}
+
/*
* A function to disable XHCI node on Platform Version lower than 0.3
*/
@@ -793,6 +878,13 @@ InitializeSbsaQemuAcpiDxe (
DEBUG ((DEBUG_ERROR, "Failed to add PPTT table\n"));
}
+ if (SbsaQemuGetNumaNodeCount() > 0){
+ Status = AddSratTable (AcpiTable);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to add SRAT table\n"));
+ }
+ }
+
Status = AddGtdtTable (AcpiTable);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Failed to add GTDT table\n"));
diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuHardwareInfoLib/SbsaQemuHardwareInfoLib.c b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuHardwareInfoLib/SbsaQemuHardwareInfoLib.c
index 03e33c544ee0..04a8a076ab64 100644
--- a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuHardwareInfoLib/SbsaQemuHardwareInfoLib.c
+++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuHardwareInfoLib/SbsaQemuHardwareInfoLib.c
@@ -352,3 +352,39 @@ SbsaQemuGetMemInfo (
return MemInfo;
}
+
+UINT64
+SbsaQemuGetNumaNodeCount (
+ VOID
+)
+{
+ UINT64 Arg;
+ UINT32 Index;
+ UINT32 NumNumaCount;
+ UINT32 NumMemCount;
+ UINT32 NumCores = PcdGet32 (PcdCoreCount);
+ MemoryInfo MemInfo;
+
+ NumNumaCount = 0;
+ NumMemCount = SbsaQemuGetMemNodeCount();
+
+ if (NumCores > 0){
+ for (Index = 0; Index < NumCores; Index ++){
+ Arg = SbsaQemuGetCpuNumaNode(Index);
+ if (NumNumaCount == 0 || NumNumaCount < (Arg + 1)){
+ NumNumaCount = Arg + 1;
+ }
+ }
+ }
+
+ if (NumMemCount > 0){
+ for (Index = 0; Index < NumMemCount; Index ++){
+ MemInfo = SbsaQemuGetMemInfo(Index);
+ if (NumNumaCount == 0 || NumNumaCount < (MemInfo.NodeId + 1)){
+ NumNumaCount = MemInfo.NodeId + 1;
+ }
+ }
+ }
+
+ return NumNumaCount;
+}
--
2.34.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115640): https://edk2.groups.io/g/devel/message/115640
Mute This Topic: https://groups.io/mt/104463805/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 3+ messages in thread