<p>Marc Jones has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/23819">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/amd/stoneyridge: Refactor northbridge RAM resource allocator<br><br>The resource allocator was overly complicated due to porting<br>from a multi-node resource allocator. It had some assumptions<br>about the UMA memory and where it would be located. The<br>refactored allocations account for UMA being reserved above 4GiB.<br><br>TEST=Check CBMEM table has correct RAM regions.<br><br>Change-Id: I722ded9fb877ec756c3af11fcb5fea587ac0ba8e<br>Signed-off-by: Marc Jones <marcj303@gmail.com><br>---<br>M src/soc/amd/stoneyridge/northbridge.c<br>1 file changed, 50 insertions(+), 126 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/19/23819/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/soc/amd/stoneyridge/northbridge.c b/src/soc/amd/stoneyridge/northbridge.c</span><br><span>index 2449077..98f7ea1 100644</span><br><span>--- a/src/soc/amd/stoneyridge/northbridge.c</span><br><span>+++ b/src/soc/amd/stoneyridge/northbridge.c</span><br><span>@@ -40,35 +40,6 @@</span><br><span> #include <stdlib.h></span><br><span> #include <string.h></span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-typedef struct dram_base_mask {</span><br><span style="color: hsl(0, 100%, 40%);">- u32 base; /* [47:27] at [28:8] */</span><br><span style="color: hsl(0, 100%, 40%);">- u32 mask; /* [47:27] at [28:8] and enable at bit 0 */</span><br><span style="color: hsl(0, 100%, 40%);">-} dram_base_mask_t;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static dram_base_mask_t get_dram_base_mask(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- device_t dev = dev_find_slot(0, ADDR_DEVFN);</span><br><span style="color: hsl(0, 100%, 40%);">- dram_base_mask_t d;</span><br><span style="color: hsl(0, 100%, 40%);">- u32 temp;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* [39:24] at [31:16] */</span><br><span style="color: hsl(0, 100%, 40%);">- temp = pci_read_config32(dev, 0x44);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* mask out DramMask [26:24] too */</span><br><span style="color: hsl(0, 100%, 40%);">- d.mask = ((temp & 0xfff80000) >> (8 + 3));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* [47:40] at [7:0] */</span><br><span style="color: hsl(0, 100%, 40%);">- temp = pci_read_config32(dev, 0x144) & 0xff;</span><br><span style="color: hsl(0, 100%, 40%);">- d.mask |= temp << 21;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- temp = pci_read_config32(dev, 0x40);</span><br><span style="color: hsl(0, 100%, 40%);">- d.mask |= (temp & 1); /* enable bit */</span><br><span style="color: hsl(0, 100%, 40%);">- d.base = ((temp & 0xfff80000) >> (8 + 3));</span><br><span style="color: hsl(0, 100%, 40%);">- temp = pci_read_config32(dev, 0x140) & 0xff;</span><br><span style="color: hsl(0, 100%, 40%);">- d.base |= temp << 21;</span><br><span style="color: hsl(0, 100%, 40%);">- return d;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> static void set_io_addr_reg(device_t dev, u32 nodeid, u32 linkn, u32 reg,</span><br><span> u32 io_min, u32 io_max)</span><br><span> {</span><br><span>@@ -433,109 +404,62 @@</span><br><span> </span><br><span> void domain_set_resources(device_t dev)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- unsigned long mmio_basek;</span><br><span style="color: hsl(0, 100%, 40%);">- u32 pci_tolm;</span><br><span style="color: hsl(0, 100%, 40%);">- u32 hole;</span><br><span style="color: hsl(0, 100%, 40%);">- int idx;</span><br><span style="color: hsl(0, 100%, 40%);">- struct bus *link;</span><br><span style="color: hsl(0, 100%, 40%);">- void *tseg_base;</span><br><span style="color: hsl(0, 100%, 40%);">- size_t tseg_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t uma_base = get_uma_base();</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t uma_size = get_uma_size();</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t mem_useable = (uint32_t)cbmem_top();</span><br><span style="color: hsl(120, 100%, 40%);">+ msr_t tom = rdmsr(TOP_MEM);</span><br><span style="color: hsl(120, 100%, 40%);">+ msr_t high_tom = rdmsr(TOP_MEM2);</span><br><span style="color: hsl(120, 100%, 40%);">+ uint64_t high_mem_useable = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int idx = 0x10;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- pci_tolm = 0xffffffffUL;</span><br><span style="color: hsl(0, 100%, 40%);">- for (link = dev->link_list ; link ; link = link->next)</span><br><span style="color: hsl(0, 100%, 40%);">- pci_tolm = find_pci_tolm(link);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 0x0 - 0x9ffff */</span><br><span style="color: hsl(120, 100%, 40%);">+ ram_resource(dev, idx, 0, 0xa0000 / KiB);</span><br><span style="color: hsl(120, 100%, 40%);">+ idx += 0x10;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* Start with alignment supportable in variable MTRR */</span><br><span style="color: hsl(0, 100%, 40%);">- mmio_basek = ALIGN_DOWN(pci_tolm, 4 * KiB) / KiB;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /*</span><br><span style="color: hsl(0, 100%, 40%);">- * AGESA may have programmed the memory hole and rounded down to a</span><br><span style="color: hsl(0, 100%, 40%);">- * 128MB boundary. If we find it's valid, adjust mmio_basek downward</span><br><span style="color: hsl(0, 100%, 40%);">- * to the hole bottom. D18F1xF0[DramHoleBase] is granular to 16MB.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">- hole = pci_read_config32(dev_find_slot(0, ADDR_DEVFN), D18F1_DRAM_HOLE);</span><br><span style="color: hsl(0, 100%, 40%);">- if (hole & DRAM_HOLE_VALID)</span><br><span style="color: hsl(0, 100%, 40%);">- mmio_basek = min(mmio_basek, ALIGN_DOWN(hole, 16 * MiB) / KiB);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- idx = 0x10;</span><br><span style="color: hsl(0, 100%, 40%);">- dram_base_mask_t d;</span><br><span style="color: hsl(0, 100%, 40%);">- resource_t basek, limitk, sizek; /* 4 1T */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- d = get_dram_base_mask();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if ((d.mask & 1)) { /* if enabled... */</span><br><span style="color: hsl(0, 100%, 40%);">- /* could overflow, we may lose 6 bit here */</span><br><span style="color: hsl(0, 100%, 40%);">- basek = ((resource_t)(d.base & 0x1fffff00)) << 9;</span><br><span style="color: hsl(0, 100%, 40%);">- limitk = ((resource_t)(((d.mask & ~1) + 0x000ff)</span><br><span style="color: hsl(0, 100%, 40%);">- & 0x1fffff00)) << 9;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- sizek = limitk - basek;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* see if we need a hole from 0xa0000 to 0xbffff */</span><br><span style="color: hsl(0, 100%, 40%);">- if ((basek < ((8 * 64) + (8 * 16))) && (sizek > ((8 * 64) +</span><br><span style="color: hsl(0, 100%, 40%);">- (16 * 16)))) {</span><br><span style="color: hsl(0, 100%, 40%);">- ram_resource(dev, idx, basek,</span><br><span style="color: hsl(0, 100%, 40%);">- ((8 * 64) + (8 * 16)) - basek);</span><br><span style="color: hsl(0, 100%, 40%);">- idx += 0x10;</span><br><span style="color: hsl(0, 100%, 40%);">- basek = (8 * 64) + (16 * 16);</span><br><span style="color: hsl(0, 100%, 40%);">- sizek = limitk - ((8 * 64) + (16 * 16));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* split the region to accommodate pci memory space */</span><br><span style="color: hsl(0, 100%, 40%);">- if ((basek < 4 * 1024 * 1024) && (limitk > mmio_basek)) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (basek <= mmio_basek) {</span><br><span style="color: hsl(0, 100%, 40%);">- unsigned int pre_sizek;</span><br><span style="color: hsl(0, 100%, 40%);">- pre_sizek = mmio_basek - basek;</span><br><span style="color: hsl(0, 100%, 40%);">- if (pre_sizek > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- ram_resource(dev, idx, basek,</span><br><span style="color: hsl(0, 100%, 40%);">- pre_sizek);</span><br><span style="color: hsl(0, 100%, 40%);">- idx += 0x10;</span><br><span style="color: hsl(0, 100%, 40%);">- sizek -= pre_sizek;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- basek = mmio_basek;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if ((basek + sizek) <= 4 * 1024 * 1024) {</span><br><span style="color: hsl(0, 100%, 40%);">- sizek = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- uint64_t topmem2 = bsp_topmem2();</span><br><span style="color: hsl(0, 100%, 40%);">- basek = 4 * 1024 * 1024;</span><br><span style="color: hsl(0, 100%, 40%);">- sizek = topmem2 / 1024 - basek;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ram_resource(dev, idx, basek, sizek);</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "node 0: mmio_basek=%08lx, basek=%08llx,"</span><br><span style="color: hsl(0, 100%, 40%);">- " limitk=%08llx\n", mmio_basek, basek, limitk);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* UMA is not set up yet, but infer the base & size to make cacheable */</span><br><span style="color: hsl(0, 100%, 40%);">- uint32_t uma_base = restore_top_of_low_cacheable();</span><br><span style="color: hsl(0, 100%, 40%);">- if (uma_base != bsp_topmem()) {</span><br><span style="color: hsl(0, 100%, 40%);">- uint32_t uma_size = bsp_topmem() - uma_base;</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_INFO, "%s: uma size 0x%08x, memory start 0x%08x\n",</span><br><span style="color: hsl(0, 100%, 40%);">- __func__, uma_size, uma_base);</span><br><span style="color: hsl(0, 100%, 40%);">- reserved_ram_resource(dev, 7, uma_base / KiB, uma_size / KiB);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (link = dev->link_list ; link ; link = link->next)</span><br><span style="color: hsl(0, 100%, 40%);">- if (link->children)</span><br><span style="color: hsl(0, 100%, 40%);">- assign_resources(link);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /*</span><br><span style="color: hsl(0, 100%, 40%);">- * Reserve everything between A segment and 1MB:</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * 0xa0000 - 0xbffff: legacy VGA</span><br><span style="color: hsl(0, 100%, 40%);">- * 0xc0000 - 0xfffff: RAM</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 0xa0000 - 0xbffff: legacy VGA */</span><br><span> mmio_resource(dev, 0xa0000, 0xa0000 / KiB, 0x20000 / KiB);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 0xc0000 - 0xfffff: Option ROM */</span><br><span> reserved_ram_resource(dev, 0xc0000, 0xc0000 / KiB, 0x40000 / KiB);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* Reserve TSEG */</span><br><span style="color: hsl(0, 100%, 40%);">- smm_region_info(&tseg_base, &tseg_size);</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * 0x100000 - lower top useable RAM</span><br><span style="color: hsl(120, 100%, 40%);">+ * cbmem_top() accounts for low UMA and TSEG if they are used.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ ram_resource(dev, idx, 0x100000 / KiB, (mem_useable - 0x100000) / KiB);</span><br><span> idx += 0x10;</span><br><span style="color: hsl(0, 100%, 40%);">- reserved_ram_resource(dev, idx, (unsigned long)tseg_base/KiB,</span><br><span style="color: hsl(0, 100%, 40%);">- tseg_size/KiB);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Lower top useable RAM - Lower top RAM (pci mmio hole) */</span><br><span style="color: hsl(120, 100%, 40%);">+ reserved_ram_resource(dev, idx, mem_useable / KiB,</span><br><span style="color: hsl(120, 100%, 40%);">+ (tom.lo - mem_useable) / KiB);</span><br><span style="color: hsl(120, 100%, 40%);">+ idx += 0x10;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* If there is memory above 4GB */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (high_tom.hi) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 4GB - > high top useable */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (uma_base >= (4ull * GiB))</span><br><span style="color: hsl(120, 100%, 40%);">+ high_mem_useable = uma_base;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ high_mem_useable = ((uint64_t)high_tom.lo |</span><br><span style="color: hsl(120, 100%, 40%);">+ ((uint64_t)high_tom.hi << 32));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ram_resource(dev, idx, (4ull * GiB) / KiB,</span><br><span style="color: hsl(120, 100%, 40%);">+ ((high_mem_useable - (4ull * GiB)) / KiB));</span><br><span style="color: hsl(120, 100%, 40%);">+ idx += 0x10;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* High top useable RAM - high top RAM*/</span><br><span style="color: hsl(120, 100%, 40%);">+ if (uma_base >= (4ull * GiB)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ reserved_ram_resource(dev, 7, uma_base / KiB,</span><br><span style="color: hsl(120, 100%, 40%);">+ uma_size / KiB);</span><br><span style="color: hsl(120, 100%, 40%);">+ idx += 0x10;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Sanity check that something isn't misaligned on the end */</span><br><span style="color: hsl(120, 100%, 40%);">+ assert((uma_base + uma_size) == ((uint64_t)high_tom.lo |</span><br><span style="color: hsl(120, 100%, 40%);">+ ((uint64_t)high_tom.hi << 32)));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ assign_resources(dev->link_list);</span><br><span> }</span><br><span> </span><br><span> /*********************************************************************</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/23819">change 23819</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/23819"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I722ded9fb877ec756c3af11fcb5fea587ac0ba8e </div>
<div style="display:none"> Gerrit-Change-Number: 23819 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Marc Jones <marc@marcjonesconsulting.com> </div>