From 5ed9fe94972e8383edd7929ccce4d9b73823a362 Mon Sep 17 00:00:00 2001 From: Shuo Liu Date: Tue, 26 Mar 2024 21:27:52 +0800 Subject: soc/intel/xeon_sp: Add device to proximity domain map utils In NUMA architecture, all devices (cpu, memory and PCI device) belong to specific proximity domain. Add utils to map device instance to their proximity domain. Proximity domain ID is the index assigned at the creation of proximity domains. There is no hard relationship between proximity domain ID and the device identities (e.g. socket ID). Hence we need the map utils to explicitly link them. For now the Sub-NUMA config isn't taken into account. TEST=Build and boot on intel/archercity CRB Change-Id: Icd14a98823491ccfc38473e44a26dddfbbcaa7c0 Signed-off-by: Shuo Liu Co-authored-by: Ziang Wang Co-authored-by: Gang Chen Reviewed-on: https://review.coreboot.org/c/coreboot/+/81440 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- src/soc/intel/xeon_sp/include/soc/numa.h | 7 ++++++ src/soc/intel/xeon_sp/numa.c | 41 ++++++++++++++++++++++++++++++++ src/soc/intel/xeon_sp/spr/soc_acpi.c | 1 + src/soc/intel/xeon_sp/uncore_acpi.c | 17 ++++++------- src/soc/intel/xeon_sp/uncore_acpi_cxl.c | 4 +++- 5 files changed, 59 insertions(+), 11 deletions(-) diff --git a/src/soc/intel/xeon_sp/include/soc/numa.h b/src/soc/intel/xeon_sp/include/soc/numa.h index aba3f0926b..3e495e28c8 100644 --- a/src/soc/intel/xeon_sp/include/soc/numa.h +++ b/src/soc/intel/xeon_sp/include/soc/numa.h @@ -7,8 +7,11 @@ #ifndef NUMA_H #define NUMA_H +#include #include +#define XEONSP_INVALID_PD_INDEX UINT32_MAX + enum proximity_domain_type { PD_TYPE_PROCESSOR, /* @@ -16,6 +19,7 @@ enum proximity_domain_type { * Generic Initiator domain is a CXL memory device. */ PD_TYPE_GENERIC_INITIATOR, + PD_TYPE_MAX }; /* @@ -62,4 +66,7 @@ void fill_pds(void); */ uint32_t get_generic_initiator_mem_size(void); +uint32_t memory_to_pd(const struct SystemMemoryMapElement *mem); +uint32_t device_to_pd(const struct device *dev); + #endif /* NUMA_H */ diff --git a/src/soc/intel/xeon_sp/numa.c b/src/soc/intel/xeon_sp/numa.c index 0186865e86..1f19b6e7bc 100644 --- a/src/soc/intel/xeon_sp/numa.c +++ b/src/soc/intel/xeon_sp/numa.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -117,3 +118,43 @@ uint32_t get_generic_initiator_mem_size(void) return size; } + +static uint32_t socket_to_pd(uint8_t socket) +{ + for (uint8_t i = 0; i < pds.num_pds; i++) { + if (pds.pds[i].pd_type != PD_TYPE_PROCESSOR) + continue; + if (pds.pds[i].socket_bitmap == (1 << socket)) + return i; + } + + printk(BIOS_ERR, "%s: could not find proximity domain for socket %d.\n", + __func__, socket); + + return XEONSP_INVALID_PD_INDEX; +} + +uint32_t device_to_pd(const struct device *dev) +{ + /* first to see if the dev is bound to specific pd */ + for (int i = 0; i < pds.num_pds; i++) + if (pds.pds[i].dev == dev) + return i; + + if (dev->path.type == DEVICE_PATH_APIC) + return socket_to_pd(dev->path.apic.package_id); + + if ((dev->path.type == DEVICE_PATH_DOMAIN) || + (dev->path.type == DEVICE_PATH_PCI)) + return socket_to_pd(iio_pci_domain_socket_from_dev(dev)); + + printk(BIOS_ERR, "%s: could not find proximity domain for device %s.\n", + __func__, dev_path(dev)); + + return XEONSP_INVALID_PD_INDEX; +} + +uint32_t memory_to_pd(const struct SystemMemoryMapElement *mem) +{ + return socket_to_pd(mem->SocketId); +} diff --git a/src/soc/intel/xeon_sp/spr/soc_acpi.c b/src/soc/intel/xeon_sp/spr/soc_acpi.c index 1249b8ff04..f7e543ce7c 100644 --- a/src/soc/intel/xeon_sp/spr/soc_acpi.c +++ b/src/soc/intel/xeon_sp/spr/soc_acpi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/src/soc/intel/xeon_sp/uncore_acpi.c b/src/soc/intel/xeon_sp/uncore_acpi.c index bcfb4da92d..c9e8ccb7f9 100644 --- a/src/soc/intel/xeon_sp/uncore_acpi.c +++ b/src/soc/intel/xeon_sp/uncore_acpi.c @@ -60,16 +60,16 @@ unsigned long acpi_create_srat_lapics(unsigned long current) if (is_x2apic_mode()) { printk(BIOS_DEBUG, "SRAT: x2apic cpu_index=%04x, node_id=%02x, apic_id=%08x\n", - i, cpu->path.apic.node_id, cpu->path.apic.apic_id); + i, device_to_pd(cpu), cpu->path.apic.apic_id); current += acpi_create_srat_x2apic((acpi_srat_x2apic_t *)current, - cpu->path.apic.node_id, cpu->path.apic.apic_id); + device_to_pd(cpu), cpu->path.apic.apic_id); } else { printk(BIOS_DEBUG, "SRAT: lapic cpu_index=%02x, node_id=%02x, apic_id=%02x\n", - i, cpu->path.apic.node_id, cpu->path.apic.apic_id); + i, device_to_pd(cpu), cpu->path.apic.apic_id); current += acpi_create_srat_lapic((acpi_srat_lapic_t *)current, - cpu->path.apic.node_id, cpu->path.apic.apic_id); + device_to_pd(cpu), cpu->path.apic.apic_id); } } return current; @@ -129,7 +129,7 @@ static unsigned int get_srat_memory_entries(acpi_srat_mem_t *srat_mem) srat_mem[mmap_index].base_address_high = (uint32_t)(addr >> 32); srat_mem[mmap_index].length_low = (uint32_t)(size & 0xffffffff); srat_mem[mmap_index].length_high = (uint32_t)(size >> 32); - srat_mem[mmap_index].proximity_domain = mem_element->SocketId; + srat_mem[mmap_index].proximity_domain = memory_to_pd(mem_element); srat_mem[mmap_index].flags = ACPI_SRAT_MEMORY_ENABLED; if (is_memtype_non_volatile(mem_element->Type)) srat_mem[mmap_index].flags |= ACPI_SRAT_MEMORY_NONVOLATILE; @@ -445,7 +445,6 @@ static unsigned long acpi_create_rhsa(unsigned long current) { struct device *dev = NULL; struct resource *resource; - int socket; while ((dev = dev_find_device(PCI_VID_INTEL, MMAP_VTD_CFG_REG_DEVID, dev))) { /* See if there is a resource with the appropriate index. */ @@ -453,11 +452,9 @@ static unsigned long acpi_create_rhsa(unsigned long current) if (!resource) continue; - socket = iio_pci_domain_socket_from_dev(dev); - printk(BIOS_DEBUG, "[Remapping Hardware Static Affinity] Base Address: %p, " - "Proximity Domain: 0x%x\n", res2mmio(resource, 0, 0), socket); - current += acpi_create_dmar_rhsa(current, (uintptr_t)res2mmio(resource, 0, 0), socket); + "Proximity Domain: 0x%x\n", res2mmio(resource, 0, 0), device_to_pd(dev)); + current += acpi_create_dmar_rhsa(current, (uintptr_t)res2mmio(resource, 0, 0), device_to_pd(dev)); } return current; diff --git a/src/soc/intel/xeon_sp/uncore_acpi_cxl.c b/src/soc/intel/xeon_sp/uncore_acpi_cxl.c index 40a5f12496..6e1fa71f93 100644 --- a/src/soc/intel/xeon_sp/uncore_acpi_cxl.c +++ b/src/soc/intel/xeon_sp/uncore_acpi_cxl.c @@ -13,7 +13,9 @@ unsigned long cxl_fill_srat(unsigned long current) * are after processor domains. */ uint32_t base, size; - for (uint8_t i = soc_get_num_cpus(); i < pds.num_pds; i++) { + for (uint8_t i = 0; i < pds.num_pds; i++) { + if (pds.pds[i].pd_type != PD_TYPE_GENERIC_INITIATOR) + continue; if (!pds.pds[i].dev) continue; -- cgit v1.2.3