[coreboot-gerrit] Change in coreboot[master]: soc/amd/stoneyridge: Refactor northbridge RAM resource allocator

Marc Jones (Code Review) gerrit at coreboot.org
Mon Feb 19 21:26:35 CET 2018


Marc Jones has uploaded this change for review. ( https://review.coreboot.org/23819


Change subject: soc/amd/stoneyridge: Refactor northbridge RAM resource allocator
......................................................................

soc/amd/stoneyridge: Refactor northbridge RAM resource allocator

The resource allocator was overly complicated due to porting
from a multi-node resource allocator. It had some assumptions
about the UMA memory and where it would be located. The
refactored allocations account for UMA being reserved above 4GiB.

TEST=Check CBMEM table has correct RAM regions.

Change-Id: I722ded9fb877ec756c3af11fcb5fea587ac0ba8e
Signed-off-by: Marc Jones <marcj303 at gmail.com>
---
M src/soc/amd/stoneyridge/northbridge.c
1 file changed, 50 insertions(+), 126 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/19/23819/1

diff --git a/src/soc/amd/stoneyridge/northbridge.c b/src/soc/amd/stoneyridge/northbridge.c
index 2449077..98f7ea1 100644
--- a/src/soc/amd/stoneyridge/northbridge.c
+++ b/src/soc/amd/stoneyridge/northbridge.c
@@ -40,35 +40,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-typedef struct dram_base_mask {
-	u32 base; /* [47:27] at [28:8] */
-	u32 mask; /* [47:27] at [28:8] and enable at bit 0 */
-} dram_base_mask_t;
-
-static dram_base_mask_t get_dram_base_mask(void)
-{
-	device_t dev = dev_find_slot(0, ADDR_DEVFN);
-	dram_base_mask_t d;
-	u32 temp;
-
-	/* [39:24] at [31:16] */
-	temp = pci_read_config32(dev, 0x44);
-
-	/* mask out  DramMask [26:24] too */
-	d.mask = ((temp & 0xfff80000) >> (8 + 3));
-
-	/* [47:40] at [7:0] */
-	temp = pci_read_config32(dev, 0x144) & 0xff;
-	d.mask |= temp << 21;
-
-	temp = pci_read_config32(dev, 0x40);
-	d.mask |= (temp & 1); /* enable bit */
-	d.base = ((temp & 0xfff80000) >> (8 + 3));
-	temp = pci_read_config32(dev, 0x140) & 0xff;
-	d.base |= temp << 21;
-	return d;
-}
-
 static void set_io_addr_reg(device_t dev, u32 nodeid, u32 linkn, u32 reg,
 			u32 io_min, u32 io_max)
 {
@@ -433,109 +404,62 @@
 
 void domain_set_resources(device_t dev)
 {
-	unsigned long mmio_basek;
-	u32 pci_tolm;
-	u32 hole;
-	int idx;
-	struct bus *link;
-	void *tseg_base;
-	size_t tseg_size;
+	uint64_t uma_base = get_uma_base();
+	uint32_t uma_size = get_uma_size();
+	uint32_t mem_useable = (uint32_t)cbmem_top();
+	msr_t tom = rdmsr(TOP_MEM);
+	msr_t high_tom = rdmsr(TOP_MEM2);
+	uint64_t high_mem_useable = 0;
+	int idx = 0x10;
 
-	pci_tolm = 0xffffffffUL;
-	for (link = dev->link_list ; link ; link = link->next)
-		pci_tolm = find_pci_tolm(link);
+	/* 0x0 - 0x9ffff */
+	ram_resource(dev, idx, 0, 0xa0000 / KiB);
+	idx += 0x10;
 
-	/* Start with alignment supportable in variable MTRR */
-	mmio_basek = ALIGN_DOWN(pci_tolm, 4 * KiB) / KiB;
-
-	/*
-	 * AGESA may have programmed the memory hole and rounded down to a
-	 * 128MB boundary.  If we find it's valid, adjust mmio_basek downward
-	 * to the hole bottom.  D18F1xF0[DramHoleBase] is granular to 16MB.
-	 */
-	hole = pci_read_config32(dev_find_slot(0, ADDR_DEVFN), D18F1_DRAM_HOLE);
-	if (hole & DRAM_HOLE_VALID)
-		mmio_basek = min(mmio_basek, ALIGN_DOWN(hole, 16 * MiB) / KiB);
-
-	idx = 0x10;
-	dram_base_mask_t d;
-	resource_t basek, limitk, sizek; /* 4 1T */
-
-	d = get_dram_base_mask();
-
-	if ((d.mask & 1)) { /* if enabled... */
-		/*  could overflow, we may lose 6 bit here */
-		basek = ((resource_t)(d.base & 0x1fffff00)) << 9;
-		limitk = ((resource_t)(((d.mask & ~1) + 0x000ff)
-							& 0x1fffff00)) << 9;
-
-		sizek = limitk - basek;
-
-		/* see if we need a hole from 0xa0000 to 0xbffff */
-		if ((basek < ((8 * 64) + (8 * 16))) && (sizek > ((8 * 64) +
-								(16 * 16)))) {
-			ram_resource(dev, idx, basek,
-					((8 * 64) + (8 * 16)) - basek);
-			idx += 0x10;
-			basek = (8 * 64) + (16 * 16);
-			sizek = limitk - ((8 * 64) + (16 * 16));
-
-		}
-
-		/* split the region to accommodate pci memory space */
-		if ((basek < 4 * 1024 * 1024) && (limitk > mmio_basek)) {
-			if (basek <= mmio_basek) {
-				unsigned int pre_sizek;
-				pre_sizek = mmio_basek - basek;
-				if (pre_sizek > 0) {
-					ram_resource(dev, idx, basek,
-								pre_sizek);
-					idx += 0x10;
-					sizek -= pre_sizek;
-				}
-				basek = mmio_basek;
-			}
-			if ((basek + sizek) <= 4 * 1024 * 1024) {
-				sizek = 0;
-			} else {
-				uint64_t topmem2 = bsp_topmem2();
-				basek = 4 * 1024 * 1024;
-				sizek = topmem2 / 1024 - basek;
-			}
-		}
-
-		ram_resource(dev, idx, basek, sizek);
-		printk(BIOS_DEBUG, "node 0: mmio_basek=%08lx, basek=%08llx,"
-				" limitk=%08llx\n", mmio_basek, basek, limitk);
-	}
-
-	/* UMA is not set up yet, but infer the base & size to make cacheable */
-	uint32_t uma_base = restore_top_of_low_cacheable();
-	if (uma_base != bsp_topmem()) {
-		uint32_t uma_size = bsp_topmem() - uma_base;
-		printk(BIOS_INFO, "%s: uma size 0x%08x, memory start 0x%08x\n",
-				__func__, uma_size, uma_base);
-		reserved_ram_resource(dev, 7, uma_base / KiB, uma_size / KiB);
-	}
-
-	for (link = dev->link_list ; link ; link = link->next)
-		if (link->children)
-			assign_resources(link);
-
-	/*
-	 * Reserve everything between A segment and 1MB:
-	 *
-	 * 0xa0000 - 0xbffff: legacy VGA
-	 * 0xc0000 - 0xfffff: RAM
-	 */
+	/* 0xa0000 - 0xbffff: legacy VGA */
 	mmio_resource(dev, 0xa0000, 0xa0000 / KiB, 0x20000 / KiB);
+
+	/* 0xc0000 - 0xfffff: Option ROM */
 	reserved_ram_resource(dev, 0xc0000, 0xc0000 / KiB, 0x40000 / KiB);
 
-	/* Reserve TSEG */
-	smm_region_info(&tseg_base, &tseg_size);
+	/*
+	 * 0x100000 - lower top useable RAM
+	 * cbmem_top() accounts for low UMA and TSEG if they are used.
+	 */
+	ram_resource(dev, idx, 0x100000 / KiB, (mem_useable - 0x100000) / KiB);
 	idx += 0x10;
-	reserved_ram_resource(dev, idx, (unsigned long)tseg_base/KiB,
-					tseg_size/KiB);
+
+	/* Lower top useable RAM - Lower top RAM (pci mmio hole) */
+	reserved_ram_resource(dev, idx, mem_useable / KiB,
+					(tom.lo - mem_useable) / KiB);
+	idx += 0x10;
+
+	/* If there is memory above 4GB */
+	if (high_tom.hi) {
+		/* 4GB - > high top useable */
+		if (uma_base >= (4ull * GiB))
+			high_mem_useable = uma_base;
+		else
+			high_mem_useable = ((uint64_t)high_tom.lo |
+						((uint64_t)high_tom.hi << 32));
+
+		ram_resource(dev, idx, (4ull * GiB) / KiB,
+				((high_mem_useable - (4ull * GiB)) / KiB));
+		idx += 0x10;
+
+		/* High top useable RAM - high top RAM*/
+		if (uma_base >= (4ull * GiB)) {
+			reserved_ram_resource(dev, 7, uma_base / KiB,
+						uma_size / KiB);
+			idx += 0x10;
+		}
+
+		/* Sanity check that something isn't misaligned on the end */
+		assert((uma_base + uma_size) == ((uint64_t)high_tom.lo |
+						((uint64_t)high_tom.hi << 32)));
+	}
+
+	assign_resources(dev->link_list);
 }
 
 /*********************************************************************

-- 
To view, visit https://review.coreboot.org/23819
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I722ded9fb877ec756c3af11fcb5fea587ac0ba8e
Gerrit-Change-Number: 23819
Gerrit-PatchSet: 1
Gerrit-Owner: Marc Jones <marc at marcjonesconsulting.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20180219/53dae47c/attachment-0001.html>


More information about the coreboot-gerrit mailing list