summaryrefslogtreecommitdiff
path: root/src/soc/amd/common/block
diff options
context:
space:
mode:
authorFelix Held <felix-coreboot@felixheld.de>2023-08-08 21:38:07 +0200
committerMartin L Roth <gaumless@gmail.com>2023-08-13 02:40:28 +0000
commit55822d9587ef30f82756c313fd8d5e0c2293e82f (patch)
treebbcc93475bf64d7d5362ee0b62aadaae8db4c447 /src/soc/amd/common/block
parent9ab161d7a1c07fd2dc304b33d06a98c98debb61a (diff)
soc/amd/common/data_fabric: handle multiple PCI root domains
In the case of SoCs hat have more than one PCI root, we need to check to which PCI root the PCI bus number, IO and MMIO regions configured in the data fabric registers get routed to and only tell the resource allocator about the resources that get routed to the current PCI root domain. For this the numbers of the domains need to match the PCI root's destination data fabric ID. Signed-off-by: Felix Held <felix-coreboot@felixheld.de> Change-Id: Ib6a6412f733d321044678d2b064c33418a53861c Reviewed-on: https://review.coreboot.org/c/coreboot/+/77113 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin L Roth <gaumless@gmail.com>
Diffstat (limited to 'src/soc/amd/common/block')
-rw-r--r--src/soc/amd/common/block/data_fabric/Kconfig16
-rw-r--r--src/soc/amd/common/block/data_fabric/domain.c12
-rw-r--r--src/soc/amd/common/block/data_fabric/pci_segment_multi.c8
-rw-r--r--src/soc/amd/common/block/data_fabric/pci_segment_single.c9
4 files changed, 37 insertions, 8 deletions
diff --git a/src/soc/amd/common/block/data_fabric/Kconfig b/src/soc/amd/common/block/data_fabric/Kconfig
index ba771c6dce..699c8888e5 100644
--- a/src/soc/amd/common/block/data_fabric/Kconfig
+++ b/src/soc/amd/common/block/data_fabric/Kconfig
@@ -14,6 +14,22 @@ config SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN
fabric registers so that it knows in which regions it can properly
allocate the non-fixed MMIO devices.
+config SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN_MULTI_PCI_ROOT
+ bool
+ depends on SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN
+ help
+ On AMD SoCs with more than one PCI root, make sure to only report the
+ PCI bus number, IO, and MMIO resources that get decoded to a specific
+ PCI root in the corresponding coreboot domain. This will make sure
+ that the allocation the resoucre allocator calculates will be decoded
+ correctly to the PCI roots. In order for coreboot to know the correct
+ mapping, the coreboot domain numbers must be set to the corresponding
+ data fabric destination ID. On AMD systems with only one PCI root,
+ this isn't needed and even though selecting this option works when
+ the coreboot domain numbers are set up correctly, some link-time
+ optimizations won't be possible, so it's preferable to only select
+ this option on SoCs with multiple PCI roots.
+
config SOC_AMD_COMMON_BLOCK_DATA_FABRIC_MULTI_PCI_SEGMENT
bool
depends on SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN
diff --git a/src/soc/amd/common/block/data_fabric/domain.c b/src/soc/amd/common/block/data_fabric/domain.c
index d693879ce6..39243514cc 100644
--- a/src/soc/amd/common/block/data_fabric/domain.c
+++ b/src/soc/amd/common/block/data_fabric/domain.c
@@ -113,8 +113,10 @@ static void add_data_fabric_mmio_regions(struct device *domain, unsigned int *id
if (ctrl.np)
continue;
- /* TODO: Systems with more than one PCI root need to check to which PCI root
- the MMIO range gets decoded to. */
+ /* Only look at MMIO regions that are decoded to the right PCI root */
+ if (CONFIG(SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN_MULTI_PCI_ROOT) &&
+ ctrl.dst_fabric_id != domain->path.domain.domain)
+ continue;
data_fabric_get_mmio_base_size(i, &mmio_base, &mmio_limit);
@@ -168,8 +170,10 @@ static void add_data_fabric_io_regions(struct device *domain, unsigned int *idx)
limit_reg.raw = data_fabric_broadcast_read32(DF_IO_LIMIT(i));
- /* TODO: Systems with more than one PCI root need to check to which PCI root
- the IO range gets decoded to. */
+ /* Only look at IO regions that are decoded to the right PCI root */
+ if (CONFIG(SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN_MULTI_PCI_ROOT) &&
+ limit_reg.dst_fabric_id != domain->path.domain.domain)
+ continue;
io_base = base_reg.io_base << DF_IO_ADDR_SHIFT;
io_limit = ((limit_reg.io_limit + 1) << DF_IO_ADDR_SHIFT) - 1;
diff --git a/src/soc/amd/common/block/data_fabric/pci_segment_multi.c b/src/soc/amd/common/block/data_fabric/pci_segment_multi.c
index 67822216cd..a474ed94bf 100644
--- a/src/soc/amd/common/block/data_fabric/pci_segment_multi.c
+++ b/src/soc/amd/common/block/data_fabric/pci_segment_multi.c
@@ -15,8 +15,10 @@ enum cb_err data_fabric_get_pci_bus_numbers(struct device *domain, uint8_t *firs
pci_bus_base.raw = data_fabric_broadcast_read32(DF_PCI_CFG_BASE(i));
pci_bus_limit.raw = data_fabric_broadcast_read32(DF_PCI_CFG_LIMIT(i));
- /* TODO: Systems with more than one PCI root need to check to which PCI root
- the PCI bus number range gets decoded to. */
+ if (CONFIG(SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN_MULTI_PCI_ROOT) &&
+ pci_bus_limit.dst_fabric_id != domain->path.domain.domain)
+ continue;
+
if (pci_bus_base.we && pci_bus_base.re) {
/* TODO: Implement support for multiple PCI segments in coreboot */
if (pci_bus_base.segment_num) {
@@ -31,5 +33,7 @@ enum cb_err data_fabric_get_pci_bus_numbers(struct device *domain, uint8_t *firs
}
}
+ printk(BIOS_ERR, "No valid DF PCI CFG register pair found for domain %x.\n",
+ domain->path.domain.domain);
return CB_ERR;
}
diff --git a/src/soc/amd/common/block/data_fabric/pci_segment_single.c b/src/soc/amd/common/block/data_fabric/pci_segment_single.c
index 5f2152b668..d4e1580805 100644
--- a/src/soc/amd/common/block/data_fabric/pci_segment_single.c
+++ b/src/soc/amd/common/block/data_fabric/pci_segment_single.c
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <amdblocks/data_fabric.h>
+#include <console/console.h>
#include <device/device.h>
#include <types.h>
@@ -12,8 +13,10 @@ enum cb_err data_fabric_get_pci_bus_numbers(struct device *domain, uint8_t *firs
for (unsigned int i = 0; i < DF_PCI_CFG_MAP_COUNT; i++) {
pci_bus_map.raw = data_fabric_broadcast_read32(DF_PCI_CFG_MAP(i));
- /* TODO: Systems with more than one PCI root need to check to which PCI root
- the PCI bus number range gets decoded to. */
+ if (CONFIG(SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN_MULTI_PCI_ROOT) &&
+ pci_bus_map.dst_fabric_id != domain->path.domain.domain)
+ continue;
+
if (pci_bus_map.we && pci_bus_map.re) {
*first_bus = pci_bus_map.bus_num_base;
*last_bus = pci_bus_map.bus_num_limit;
@@ -21,5 +24,7 @@ enum cb_err data_fabric_get_pci_bus_numbers(struct device *domain, uint8_t *firs
}
}
+ printk(BIOS_ERR, "No valid DF PCI CFG register found for domain %x.\n",
+ domain->path.domain.domain);
return CB_ERR;
}