Nico Huber (nico.huber@secunet.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2662
-gerrit
commit 3fe47a16f7e080596bfb936dce6bbb8ceafe5bd7 Author: Patrick Georgi patrick.georgi@secunet.com Date: Tue Apr 9 15:29:42 2013 +0200
amdk8: Increase limits for MMIO
The chipset requires configuration of the MMIO region on the HyperTransport layer, so requests are forwarded appropriately.
Until now, we configured exactly the region used by our device allocator, which is a problem if the operating system requires more space for its own allocation (eg. for hot-plug devices).
This change expands the HT-configured MMIO region to cover the whole space it uses itself (as it used to) plus the neighboring unused address space.
ACPI still registers a way too large area, which can confuse the OS, since it assigns legal addresses which are then not forwarded to the device, but that's for a separate change.
Tests were done on a siemens/sitemp_g1p1.
Change-Id: Ib63c05484739d84198a9f10352be2055c6f14385 Signed-off-by: Nico Huber nico.huber@secunet.com Signed-off-by: Patrick Georgi patrick.georgi@secunet.com --- src/northbridge/amd/amdk8/northbridge.c | 64 +++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+)
diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c index 5c1d97a..eaf3a40 100644 --- a/src/northbridge/amd/amdk8/northbridge.c +++ b/src/northbridge/amd/amdk8/northbridge.c @@ -525,12 +525,48 @@ static void amdk8_create_vga_resource(device_t dev, unsigned nodeid) IORESOURCE_ASSIGNED; }
+/* + * Sets /start/ to the nearest resource end below /start/ + * and /end/ to the nearest resource base above /end/. + */ +static void amdk8_find_wider_pcimem_limits(resource_t *const start, + resource_t *const end) +{ + const uint32_t topmem = (uint32_t)bsp_topmem(); + const resource_t limit_4g = 0x100000000ULL; + + resource_t highest_below = topmem, lowest_above = limit_4g; + + struct device *dev; + struct resource *res; + + for (dev = all_devices; dev; dev = dev->next) { + for (res = dev->resource_list; res; res = res->next) { + if (!(res->flags & IORESOURCE_MEM) || !res->size) + continue; + const resource_t res_end = resource_end(res); + if (highest_below < res_end && res_end <= *start) + highest_below = res_end; + if (*end <= res->base && res->base < lowest_above) + lowest_above = res->base; + } + } + *start = highest_below; + *end = lowest_above; +} + static void amdk8_set_resources(device_t dev) { unsigned nodeid; struct bus *bus; struct resource *res;
+ const uint32_t topmem = (uint32_t)bsp_topmem(); + const resource_t limit_4g = 0x100000000ULL; + + resource_t mem_lowest_start = limit_4g, mem_highest_end = topmem; + struct resource *mem_lowest = NULL, *mem_highest = NULL; + /* Find the nodeid */ nodeid = amdk8_nodeid(dev);
@@ -559,6 +595,34 @@ static void amdk8_set_resources(device_t dev) res->index = index;
amdk8_set_resource(dev, res, nodeid); + + if (IOINDEX_LINK(res->index) == 0 && + res->flags & IORESOURCE_MEM) { + if (topmem <= res->base && + res->base < mem_lowest_start) { + mem_lowest = res; + mem_lowest_start = res->base; + } + const resource_t res_end = res->base + res->size; + if (mem_highest_end < res_end && res_end <= limit_4g) { + mem_highest = res; + mem_highest_end = res_end; + } + } + } + + amdk8_find_wider_pcimem_limits(&mem_lowest_start, &mem_highest_end); + if (mem_lowest && mem_lowest_start < mem_lowest->base) { + mem_lowest->size += mem_lowest->base - mem_lowest_start; + mem_lowest->base = mem_lowest_start; + mem_lowest->flags &= ~IORESOURCE_STORED; + amdk8_set_resource(dev, mem_lowest, nodeid); + } + if (mem_highest && (mem_highest->base + mem_highest->size) + < mem_highest_end) { + mem_highest->size = mem_highest_end - mem_highest->base; + mem_highest->flags &= ~IORESOURCE_STORED; + amdk8_set_resource(dev, mem_highest, nodeid); }
compact_resources(dev);