[coreboot-gerrit] Patch set updated for coreboot: 3fe47a1 amdk8: Increase limits for MMIO

Nico Huber (nico.huber@secunet.com) gerrit at coreboot.org
Tue Apr 9 17:32:55 CEST 2013


Nico Huber (nico.huber at 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 at 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 at secunet.com>
    Signed-off-by: Patrick Georgi <patrick.georgi at 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);



More information about the coreboot-gerrit mailing list