diff options
author | Felix Held <felix-coreboot@felixheld.de> | 2023-08-08 21:38:07 +0200 |
---|---|---|
committer | Martin L Roth <gaumless@gmail.com> | 2023-08-13 02:40:28 +0000 |
commit | 55822d9587ef30f82756c313fd8d5e0c2293e82f (patch) | |
tree | bbcc93475bf64d7d5362ee0b62aadaae8db4c447 | |
parent | 9ab161d7a1c07fd2dc304b33d06a98c98debb61a (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>
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; } |