<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>