<p>Arthur Heymans has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/22914">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">nb/intel/x4x/raminit: Fix programming dual channel registers<br><br>Some things in programming registers related to dual channel<br>interleaved operation were wrong.<br><br>This also adds some code that could in the future be used when me is<br>active and claims some memory for its UMA.<br><br>This fixes memtest86+ failing with some assymetric DIMM configuration.<br><br>TESTED on DG43GT: memtest86+ now succeeds on many more different DIMM<br>configuration setups (would instantly fail at addresses above 4G on<br>many configurations).<br><br>Change-Id: If84099d27100e57437bf214dc4cf975f67c2ea1f<br>Signed-off-by: Arthur Heymans <arthur@aheymans.xyz><br>---<br>M src/northbridge/intel/x4x/raminit_ddr2.c<br>1 file changed, 51 insertions(+), 27 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/14/22914/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/northbridge/intel/x4x/raminit_ddr2.c b/src/northbridge/intel/x4x/raminit_ddr2.c<br>index 6254323..c7e5ed7 100644<br>--- a/src/northbridge/intel/x4x/raminit_ddr2.c<br>+++ b/src/northbridge/intel/x4x/raminit_ddr2.c<br>@@ -1168,8 +1168,8 @@<br>         u32 dra0;<br>     u32 dra1;<br>     u16 totalmemorymb;<br>-   u32 size, offset;<br>-    u32 size0, size1;<br>+    u32 dual_channel_size, single_channel_size, single_channel_offset;<br>+   u32 size_ch0, size_ch1, size_me;<br>      u8 dratab[2][2][2][4] = {<br>     {<br>             {<br>@@ -1256,47 +1256,71 @@<br>            s->channel_capacity[0], s->channel_capacity[1], totalmemorymb);<br> <br>      /* Populated channel sizes in MiB */<br>- size0 = s->channel_capacity[0];<br>-   size1 = s->channel_capacity[1];<br>+   size_ch0 = s->channel_capacity[0];<br>+        size_ch1 = s->channel_capacity[1];<br>+        size_me = ME_UMA_SIZEMB;<br> <br>   MCHBAR8(0x111) = MCHBAR8(0x111) & ~0x2;<br>   MCHBAR8(0x111) = MCHBAR8(0x111) | (1 << 4);<br> <br>- /* Set ME UMA size in MiB */<br>- MCHBAR16(0x100) = ME_UMA_SIZEMB;<br>-<br>-  /* Set ME UMA Present bit */<br>- MCHBAR32(0x111) = MCHBAR32(0x111) | 1;<br>-<br>-    size = MIN(size0 - ME_UMA_SIZEMB, size1) * 2;<br>-<br>-     MCHBAR16(0x104) = size;<br>-      MCHBAR16(0x102) = size0 + size1 - size;<br>+      if (size_me == 0) {<br>+          dual_channel_size = MIN(size_ch0, size_ch1) * 2;<br>+     } else {<br>+             if (size_ch0 == 0) {<br>+                 /* ME needs ram on CH0 */<br>+                    size_me = 0;<br>+                 /* TOTEST: bailout? */<br>+               } else {<br>+                     /* Set ME UMA size in MiB */<br>+                 MCHBAR16(0x100) = size_me;<br>+                   /* Set ME UMA Present bit */<br>+                 MCHBAR32(0x111) = MCHBAR32(0x111) | 1;<br>+               }<br>+            dual_channel_size = MIN(size_ch0 - size_me, size_ch1) * 2;<br>+   }<br>+    MCHBAR16(0x104) = dual_channel_size;<br>+ single_channel_size = size_ch0 + size_ch1 - dual_channel_size;<br>+       MCHBAR16(0x102) = single_channel_size;<br> <br>     map = 0;<br>-     if (size0 == 0)<br>+      if (size_ch0 == 0)<br>            map = 0;<br>-     else if (size1 == 0)<br>+ else if (size_ch1 == 0)<br>               map |= 0x20;<br>  else<br>          map |= 0x40;<br> <br>-      if (size == 0)<br>+       if (dual_channel_size == 0)<br>           map |= 0x18;<br>+ if (size_me == 0) {<br>+          if (size_ch0 <= size_ch1)<br>+                 map |= 0x05;<br>+         else<br>+                 map |= 0x04;<br>+ } else {<br>+             map |= 0x04;<br>+ }<br> <br>- if (size0 - ME_UMA_SIZEMB >= size1)<br>-               map |= 0x4;<br>   MCHBAR8(0x110) = map;<br>         MCHBAR16(0x10e) = 0;<br> <br>-      if (size1 != 0)<br>-              offset = 0;<br>-  else if ((size0 > size1) && ((map & 0x7) == 0x4))<br>-             offset = size/2 + (size0 + size1 - size);<br>-    else<br>-         offset = size/2 + ME_UMA_SIZEMB;<br>-     MCHBAR16(0x108) = offset;<br>-    MCHBAR16(0x10a) = size/2;<br>+    if (size_me == 0) {<br>+          if (size_ch0 > size_ch1)<br>+                  single_channel_offset = dual_channel_size / 2<br>+                                + single_channel_size;<br>+               else<br>+                 single_channel_offset = dual_channel_size / 2;<br>+       } else {<br>+             if ((size_ch0 > size_ch1) && ((map & 0x7) == 4))<br>+                      single_channel_offset = dual_channel_size / 2<br>+                                + single_channel_size;<br>+               else<br>+                 single_channel_offset = dual_channel_size / 2<br>+                                + size_me;<br>+   }<br>+<br>+ MCHBAR16(0x108) = single_channel_offset;<br>+     MCHBAR16(0x10a) = dual_channel_size / 2;<br> }<br> <br> static void mmap_ddr2(struct sysinfo *s)<br></pre><p>To view, visit <a href="https://review.coreboot.org/22914">change 22914</a>. To unsubscribe, 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/22914"/><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: If84099d27100e57437bf214dc4cf975f67c2ea1f </div>
<div style="display:none"> Gerrit-Change-Number: 22914 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Arthur Heymans <arthur@aheymans.xyz> </div>