Attention is currently required from: Arthur Heymans, Christian Walter, Johnny Lin, Jonathan Zhang, Lean Sheng Tan, Patrick Rudolph, Tim Chu.
Shuo Liu has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/81570?usp=email )
Change subject: soc/intel/xeon_sp: Add soc_add_stack_mmios ......................................................................
soc/intel/xeon_sp: Add soc_add_stack_mmios
IIO stacks will reserve some non-domain owned resources, e.g. unused IOAT MMIOs (CPM1 and HQM1). These resources are within stack MMIO range but outside domain MMIO range. They needs to be reserved explicitly so that covered by MTRR UC policy.
Besides MTRR correctness, another benefit is less MTRR entries due to less segmented MTRR regions.
Change-Id: Ib2a8063d8bee8fb4b5578e84ba8f9951815ffbf3 Signed-off-by: Shuo Liu shuo.liu@intel.com --- M src/soc/intel/xeon_sp/chip_common.c M src/soc/intel/xeon_sp/chip_gen1.c M src/soc/intel/xeon_sp/chip_gen6.c M src/soc/intel/xeon_sp/include/soc/chip_common.h M src/soc/intel/xeon_sp/include/soc/util.h M src/soc/intel/xeon_sp/uncore.c 6 files changed, 87 insertions(+), 13 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/70/81570/1
diff --git a/src/soc/intel/xeon_sp/chip_common.c b/src/soc/intel/xeon_sp/chip_common.c index 8f5c024..4d6e3a8 100644 --- a/src/soc/intel/xeon_sp/chip_common.c +++ b/src/soc/intel/xeon_sp/chip_common.c @@ -125,6 +125,21 @@ return dev; }
+struct device *dev_find_all_domains_on_stack(uint8_t socket, uint8_t stack, struct device *from) +{ + if (!from) + from = all_devices; + else + from = from->next; + + while (from && (from->path.type != DEVICE_PATH_DOMAIN) && + (iio_pci_domain_socket_from_dev(from) != socket) && + (iio_pci_domain_stack_from_dev(from) != stack)) + from = from->next; + + return from; +} + /** * Returns the socket ID where the specified device is connected to. * This is an integer in the range [0, CONFIG_MAX_SOCKET). @@ -263,3 +278,64 @@
return strstr(dev->name, DOMAIN_TYPE_CXL); } + +const xSTACK_RES *domain_to_stack_res(const struct device *dev) +{ + assert(dev->path.type == DEVICE_PATH_DOMAIN); + const union xeon_domain_path dn = { + .domain_path = dev->path.domain.domain + }; + + const IIO_UDS *hob = get_iio_uds(); + assert(hob != NULL); + + return &hob->PlatformData.IIO_resource[dn.socket].StackRes[dn.stack]; +} + +int soc_add_stack_mmios(struct device *dev, int start_index) +{ + const struct device *domain = dev_get_domain(dev); + if (!domain) + return 0; + + const xSTACK_RES *sr = domain_to_stack_res(domain); + if (!is_enabled_stack_res(sr)) + return 0; + + int index = start_index; + + struct memranges mmio32, mmio64; + memranges_init_empty(&mmio32, NULL, 0); + if (sr->Mmio32Base <= sr->Mmio32Limit) + memranges_insert(&mmio32, sr->Mmio32Base, + sr->Mmio32Limit - sr->Mmio32Base + 1, 0); + memranges_init_empty(&mmio64, NULL, 0); + if (sr->Mmio64Base <= sr->Mmio64Limit) + memranges_insert(&mmio64, sr->Mmio64Base, + sr->Mmio64Limit - sr->Mmio64Base + 1, 0); + + union xeon_domain_path dn; + dn.domain_path = domain->path.domain.domain; + struct device *d = NULL; + while ((d = dev_find_all_domains_on_stack(dn.socket, dn.stack, d))) { + struct resource *res; + for (res = d->resource_list; res; res = res->next) { + if ((res->flags & IORESOURCE_MEM) && + (res->base >= sr->Mmio32Base && + res->limit <= sr->Mmio32Limit)) + memranges_create_hole(&mmio32, res->base, res->size); + else if ((res->flags & IORESOURCE_MEM) && + (res->base >= sr->Mmio64Base && + res->limit <= sr->Mmio64Limit)) + memranges_create_hole(&mmio64, res->base, res->size); + } + } + + struct range_entry *cur; + for (cur = mmio32.entries; cur != NULL; cur = cur->next) + mmio_from_to(dev, index++, cur->begin, cur->end + 1); + for (cur = mmio64.entries; cur != NULL; cur = cur->next) + mmio_from_to(dev, index++, cur->begin, cur->end + 1); + + return index - start_index; +} diff --git a/src/soc/intel/xeon_sp/chip_gen1.c b/src/soc/intel/xeon_sp/chip_gen1.c index ce95c13..c574b7f 100644 --- a/src/soc/intel/xeon_sp/chip_gen1.c +++ b/src/soc/intel/xeon_sp/chip_gen1.c @@ -14,19 +14,6 @@ #include <soc/util.h> #include <stdlib.h>
-static const STACK_RES *domain_to_stack_res(const struct device *dev) -{ - assert(dev->path.type == DEVICE_PATH_DOMAIN); - const union xeon_domain_path dn = { - .domain_path = dev->path.domain.domain - }; - - const IIO_UDS *hob = get_iio_uds(); - assert(hob != NULL); - - return &hob->PlatformData.IIO_resource[dn.socket].StackRes[dn.stack]; -} - static void iio_pci_domain_read_resources(struct device *dev) { struct resource *res; diff --git a/src/soc/intel/xeon_sp/chip_gen6.c b/src/soc/intel/xeon_sp/chip_gen6.c index 5873913..17a9383 100644 --- a/src/soc/intel/xeon_sp/chip_gen6.c +++ b/src/soc/intel/xeon_sp/chip_gen6.c @@ -6,6 +6,7 @@ #include <drivers/ocp/include/vpd.h> #include <device/pci.h> #include <intelblocks/acpi.h> +#include <memrange.h> #include <post.h> #include <soc/acpi.h> #include <soc/chip_common.h> diff --git a/src/soc/intel/xeon_sp/include/soc/chip_common.h b/src/soc/intel/xeon_sp/include/soc/chip_common.h index 798398a..44845ce 100644 --- a/src/soc/intel/xeon_sp/include/soc/chip_common.h +++ b/src/soc/intel/xeon_sp/include/soc/chip_common.h @@ -70,6 +70,7 @@ u16 vendor, u16 device, struct device *from); struct device *dev_find_all_devices_on_domain(struct device *domain, u16 vendor, u16 device, struct device *from); +struct device *dev_find_all_domains_on_stack(uint8_t socket, uint8_t stack, struct device *from);
int iio_pci_domain_socket_from_dev(const struct device *dev); int iio_pci_domain_stack_from_dev(const struct device *dev); @@ -89,6 +90,8 @@ #define is_dev_on_domain0(dev) (is_domain0(dev_get_domain(dev))) #define is_stack0(socket, stack) (socket == 0 && stack == IioStack0)
+const xSTACK_RES *domain_to_stack_res(const struct device *dev); + enum { TOHM_REG, MMIOL_REG, @@ -108,6 +111,7 @@ };
int soc_add_dram_resources(struct device *dev, uint64_t mc_values[], int start_index); +int soc_add_stack_mmios(struct device *dev, int start_index);
void soc_pci_domain_fill_ssdt(const struct device *domain);
diff --git a/src/soc/intel/xeon_sp/include/soc/util.h b/src/soc/intel/xeon_sp/include/soc/util.h index e694af3..53982f1 100644 --- a/src/soc/intel/xeon_sp/include/soc/util.h +++ b/src/soc/intel/xeon_sp/include/soc/util.h @@ -27,6 +27,10 @@ bool is_ubox_stack_res(const xSTACK_RES *res); bool is_ioat_iio_stack_res(const xSTACK_RES *res); bool is_iio_cxl_stack_res(const xSTACK_RES *res); +#define is_enabled_stack_res(res) (is_pcie_iio_stack_res(res) ||\ + is_ubox_stack_res(res) || is_ioat_iio_stack_res(res) ||\ + is_iio_cxl_stack_res(res)) + void bios_done_msr(void *unused); union p2sb_bdf soc_get_hpet_bdf(void); union p2sb_bdf soc_get_ioapic_bdf(void); diff --git a/src/soc/intel/xeon_sp/uncore.c b/src/soc/intel/xeon_sp/uncore.c index c700816..5f1ebf7 100644 --- a/src/soc/intel/xeon_sp/uncore.c +++ b/src/soc/intel/xeon_sp/uncore.c @@ -197,6 +197,8 @@ LOG_RESOURCE("vtd_bar", dev, res); }
+ index += soc_add_stack_mmios(dev, index); + /* Only add dram resources once. */ if (dev->upstream->secondary != 0 || dev->upstream->segment_group != 0) return;