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>
This commit is contained in:
parent
9ab161d7a1
commit
55822d9587
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue