[coreboot-gerrit] Patch set updated for coreboot: nb/intel/x4x: Fix memory hole with both channels populated

Damien Zammit (damien@zamaudio.com) gerrit at coreboot.org
Fri Jan 22 12:36:45 CET 2016


Damien Zammit (damien at zamaudio.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13125

-gerrit

commit 6b4016f555f10c453f05e5bb604c116de744089a
Author: Damien Zammit <damien at zamaudio.com>
Date:   Fri Jan 22 18:56:23 2016 +1100

    nb/intel/x4x: Fix memory hole with both channels populated
    
    Previously, 0xa0000000 to 0xc0000000 needed to be reserved as
    a non-usable memory hole because it would hang on memory i/o.
    
    Memtest86+ now passes with no errors on both channels populated.
    Tested on GA-G41M-ES2L with 2x2GiB sticks of ram.
    
    Change-Id: Ib52a63a80f5f69c16841f10ddb896ab3c7d30462
    Signed-off-by: Damien Zammit <damien at zamaudio.com>
---
 src/northbridge/intel/x4x/northbridge.c  | 25 ++++++++-------
 src/northbridge/intel/x4x/raminit_ddr2.c | 54 ++++++++++++++++++++++----------
 2 files changed, 51 insertions(+), 28 deletions(-)

diff --git a/src/northbridge/intel/x4x/northbridge.c b/src/northbridge/intel/x4x/northbridge.c
index c5a8968..9486841 100644
--- a/src/northbridge/intel/x4x/northbridge.c
+++ b/src/northbridge/intel/x4x/northbridge.c
@@ -28,13 +28,14 @@
 #include <arch/acpi.h>
 #include <northbridge/intel/x4x/chip.h>
 #include <northbridge/intel/x4x/x4x.h>
+#include <cbmem.h>
 
-/* Reserve segments A and B:
+/* Reserve segments A up to 1MB
  *
- * 0xa0000 - 0xbffff: legacy VGA
+ * 0xa0000 - 0xfffff
  */
 static const int legacy_hole_base_k = 0xa0000 / 1024;
-static const int legacy_hole_size_k = 128;
+static const int legacy_hole_size_k = 128 * 3;
 
 static void mch_domain_read_resources(device_t dev)
 {
@@ -44,7 +45,7 @@ static void mch_domain_read_resources(device_t dev)
 	u32 uma_sizek = 0;
 
 	/* 1024KiB TSEG */
-	tsegk = 1 << 10;
+	tsegk = 1024;
 
 	pci_domain_read_resources(dev);
 
@@ -83,9 +84,8 @@ static void mch_domain_read_resources(device_t dev)
 	printk(BIOS_INFO, "Available memory below 4GB: %uM\n", usable_tomk >> 10);
 
 	/* Report the memory regions */
-	ram_resource(dev, 3, 0, legacy_hole_base_k);
-	ram_resource(dev, 4, legacy_hole_base_k + legacy_hole_size_k,
-		     (usable_tomk - (legacy_hole_base_k + legacy_hole_size_k)));
+	ram_resource(dev, 3, 0, 640);
+	ram_resource(dev, 4, 1024, (usable_tomk - 1024));
 
 	/*
 	 * If >= 4GB installed then memory from TOLUD to 4GB
@@ -102,15 +102,18 @@ static void mch_domain_read_resources(device_t dev)
 	       "size=0x%08x\n", usable_tomk << 10, uma_sizek << 10);
 	fixed_mem_resource(dev, 6, usable_tomk, uma_sizek, IORESOURCE_RESERVE);
 
-	/* Some strange hole, reserve it */
-	//fixed_mem_resource(dev, 7, usable_tomk - (0x02000000 >> 10), 0x02000000 >> 10, IORESOURCE_RESERVE);
+	/* Don't use memory near 4GB, reserve it */
+	fixed_mem_resource(dev, 7, 0xf0000000 >> 10, 0x10000000 >> 10,
+			IORESOURCE_RESERVE);
 
 	if (decode_pciebar(&pcie_config_base, &pcie_config_size)) {
 		printk(BIOS_DEBUG, "Adding PCIe config bar base=0x%08x "
 		       "size=0x%x\n", pcie_config_base, pcie_config_size);
-		fixed_mem_resource(dev, 7, pcie_config_base >> 10,
+		fixed_mem_resource(dev, 8, pcie_config_base >> 10,
 			pcie_config_size >> 10, IORESOURCE_RESERVE);
 	}
+
+	set_top_of_ram(usable_tomk * 1024);
 }
 
 static void mch_domain_set_resources(device_t dev)
@@ -118,7 +121,7 @@ static void mch_domain_set_resources(device_t dev)
 	struct resource *resource;
 	int i;
 
-	for (i = 3; i < 8; ++i) {
+	for (i = 3; i < 9; ++i) {
 		/* Report read resources. */
 		resource = probe_resource(dev, i);
 		if (resource)
diff --git a/src/northbridge/intel/x4x/raminit_ddr2.c b/src/northbridge/intel/x4x/raminit_ddr2.c
index d77c2c4..02606c6 100644
--- a/src/northbridge/intel/x4x/raminit_ddr2.c
+++ b/src/northbridge/intel/x4x/raminit_ddr2.c
@@ -23,6 +23,8 @@
 #include "iomap.h"
 #include "x4x.h"
 
+#define ME_UMA_SIZE 0
+
 static inline void barrier(void)
 {
 	asm volatile("mfence":::);
@@ -1465,7 +1467,8 @@ static void dradrb_ddr2(struct sysinfo *s)
 	u32 dra0;
 	u32 dra1;
 	u16 totalmemorymb;
-	u16 size, offset;
+	u32 size, offset;
+	u32 size0, size1;
 	u8 dratab[2][2][2][4] = {
 	{
 		{
@@ -1562,41 +1565,57 @@ static void dradrb_ddr2(struct sysinfo *s)
 		MCHBAR16(0x606 + 2*msbpos(rankpop1)) = c0drb + c1drb;
 	}
 
-	MCHBAR8(0x111) = MCHBAR8(0x111) | 0x2;
-	MCHBAR16(0x104) = 0;
-	size = s->channel_capacity[0] + s->channel_capacity[1];
-	MCHBAR16(0x102) = size;
+	size0 = s->channel_capacity[0];
+	size1 = s->channel_capacity[1];
+
+	MCHBAR8(0x111) = MCHBAR8(0x111) & ~0x2;
+	MCHBAR8(0x111) = MCHBAR8(0x111) | (1 << 4);
+
+	/* Set ME UMA size in MiB */
+	MCHBAR16(0x100) = ME_UMA_SIZE;
+
+	/* Set ME UMA Present bit */
+	MCHBAR32(0x111) = MCHBAR32(0x111) | 1;
+
+	size = MIN(size0 - ME_UMA_SIZE, size1) * 2;
+
+	MCHBAR16(0x104) = size;
+	MCHBAR16(0x102) = size0 + size1 - size;
+
 	map = 0;
-	if (s->channel_capacity[0] == 0) {
+	if (size0 == 0) {
 		map = 0;
-	} else if (s->channel_capacity[1] == 0) {
+	} else if (size1 == 0) {
 		map |= 0x20;
 	} else {
 		map |= 0x40;
 	}
-	map |= 0x18;
-	if (s->channel_capacity[0] <= s->channel_capacity[1]) {
-		map |= 0x5;
-	} else if (s->channel_capacity[0] > s->channel_capacity[1]) {
+	if (size == 0) {
+		map |= 0x18;
+	}
+
+	if (size0 - ME_UMA_SIZE >= size1) {
 		map |= 0x4;
 	}
 	MCHBAR8(0x110) = map;
 	MCHBAR16(0x10e) = 0;
-	if (s->channel_capacity[1] != 0) {
+
+	if (size1 != 0) {
 		offset = 0;
-	} else if (s->channel_capacity[0] > s->channel_capacity[1]) {
-		offset = size;
+	} else if ((size0 > size1) && ((map & 0x7) == 0x4)) {
+		offset = size/2 + (size0 + size1 - size);
 	} else {
-		offset = 0;
+		offset = size/2 + ME_UMA_SIZE;
 	}
 	MCHBAR16(0x108) = offset;
-	MCHBAR16(0x10a) = 0;
+	MCHBAR16(0x10a) = size/2;
 }
 
 static void mmap_ddr2(struct sysinfo *s)
 {
 	u32 gfxsize, gttsize, tsegsize, mmiosize, tom, tolud, touud, gfxbase, gttbase, tsegbase;
 	u16 ggc;
+	u16 mesize;
 	u16 ggc2uma[] = { 0, 0, 0, 0, 0, 32, 48, 64, 128, 256, 96, 160, 224, 352 };
 	u8 ggc2gtt[] = { 0, 1, 0, 2, 0, 0, 0, 0, 0, 2, 3, 4};
 
@@ -1605,7 +1624,8 @@ static void mmap_ddr2(struct sysinfo *s)
 	gttsize = ggc2gtt[(ggc & 0xf00) >> 8];
 	tsegsize = 1; // 1MB TSEG
 	mmiosize = 0x400; // 1GB MMIO
-	tom = s->channel_capacity[0] + s->channel_capacity[1];
+	mesize = ME_UMA_SIZE;
+	tom = s->channel_capacity[0] + s->channel_capacity[1] - mesize;
 	tolud = MIN(0x1000 - mmiosize, tom);
 	touud = tom;
 	gfxbase = tolud - gfxsize;



More information about the coreboot-gerrit mailing list