aopen/dxplplusu intel/e7505: Move to EARLY_CBMEM_INIT

With implementation of LATE_CBMEM_INIT, top-of-low-memory
TOLM was adjusted late in ramstage. We do not allow that with
EARLY_CBMEM_INIT so the previous maximum of 1024 MiB of MMIO
space is now used with statically set TOLM.

Also remove support code for the obsolete LATE_CBMEM_INIT
this northbridge used.

Change-Id: Ib3094903d7614d2212fbe1870248962fbc92e412
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/26585
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
diff --git a/src/cpu/intel/car/romstage.c b/src/cpu/intel/car/romstage.c
index 03a94ee..37e3942 100644
--- a/src/cpu/intel/car/romstage.c
+++ b/src/cpu/intel/car/romstage.c
@@ -63,26 +63,3 @@
 	/* Load the ramstage. */
 	run_ramstage();
 }
-
-#if IS_ENABLED(CONFIG_LATE_CBMEM_INIT)
-/* setup_stack_and_mtrrs() determines the stack to use after
- * cache-as-ram is torn down as well as the MTRR settings to use. */
-void *setup_stack_and_mtrrs(void)
-{
-	struct postcar_frame pcf;
-
-	postcar_frame_init_lowmem(&pcf);
-
-	/* Cache the ROM as WP just below 4GiB. */
-	postcar_frame_add_mtrr(&pcf, CACHE_ROM_BASE, CACHE_ROM_SIZE,
-		MTRR_TYPE_WRPROT);
-
-	/* Cache RAM as WB from 0 -> CACHE_TMP_RAMTOP. */
-	postcar_frame_add_mtrr(&pcf, 0, CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK);
-
-	/* Save the number of MTRRs to setup. Return the stack location
-	 * pointing to the number of MTRRs.
-	 */
-	return postcar_commit_mtrrs(&pcf);
-}
-#endif /* CONFIG_LATE_CBMEM_INIT */
diff --git a/src/mainboard/aopen/dxplplusu/romstage.c b/src/mainboard/aopen/dxplplusu/romstage.c
index f79d3d3..6ea1261 100644
--- a/src/mainboard/aopen/dxplplusu/romstage.c
+++ b/src/mainboard/aopen/dxplplusu/romstage.c
@@ -18,6 +18,7 @@
 #include <arch/io.h>
 #include <arch/cpu.h>
 #include <stdlib.h>
+#include <cbmem.h>
 #include <console/console.h>
 #include <cpu/x86/bist.h>
 #include <cpu/intel/romstage.h>
@@ -77,4 +78,6 @@
 	}
 
 	printk(BIOS_DEBUG, "SDRAM is up.\n");
+
+	cbmem_recovery(0);
 }
diff --git a/src/northbridge/intel/e7505/Kconfig b/src/northbridge/intel/e7505/Kconfig
index 702ba1c..bf35a6d 100644
--- a/src/northbridge/intel/e7505/Kconfig
+++ b/src/northbridge/intel/e7505/Kconfig
@@ -22,7 +22,6 @@
 	def_bool y
 	select NO_MMCONF_SUPPORT
 	select HAVE_DEBUG_RAM_SETUP
-	select LATE_CBMEM_INIT
 
 config HW_SCRUBBER
 	bool
diff --git a/src/northbridge/intel/e7505/Makefile.inc b/src/northbridge/intel/e7505/Makefile.inc
index 89a5b8c..57c870f 100644
--- a/src/northbridge/intel/e7505/Makefile.inc
+++ b/src/northbridge/intel/e7505/Makefile.inc
@@ -1,7 +1,9 @@
 ifeq ($(CONFIG_NORTHBRIDGE_INTEL_E7505),y)
 
 ramstage-y += northbridge.c
+ramstage-y += memmap.c
+
 romstage-y += raminit.c
 romstage-y += debug.c
-
+romstage-y += memmap.c
 endif
diff --git a/src/northbridge/intel/e7505/memmap.c b/src/northbridge/intel/e7505/memmap.c
new file mode 100644
index 0000000..4a80608
--- /dev/null
+++ b/src/northbridge/intel/e7505/memmap.c
@@ -0,0 +1,66 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+// Use simple device model for this file even in ramstage
+#define __SIMPLE_DEVICE__
+
+#include <arch/io.h>
+#include <arch/cpu.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <cpu/intel/romstage.h>
+#include <cpu/x86/mtrr.h>
+#include <program_loading.h>
+#include "e7505.h"
+
+void *cbmem_top(void)
+{
+	pci_devfn_t mch = PCI_DEV(0, 0, 0);
+	uintptr_t tolm;
+
+	/* This is at 128 MiB boundary. */
+	tolm = pci_read_config16(mch, TOLM) >> 11;
+	tolm <<= 27;
+
+	return (void *)tolm;
+}
+
+#define ROMSTAGE_RAM_STACK_SIZE 0x5000
+
+/* setup_stack_and_mtrrs() determines the stack to use after
+ * cache-as-ram is torn down as well as the MTRR settings to use. */
+void *setup_stack_and_mtrrs(void)
+{
+	struct postcar_frame pcf;
+	uintptr_t top_of_ram;
+
+	if (postcar_frame_init(&pcf, ROMSTAGE_RAM_STACK_SIZE))
+		die("Unable to initialize postcar frame.\n");
+
+	/* Cache the ROM as WP just below 4GiB. */
+	postcar_frame_add_mtrr(&pcf, CACHE_ROM_BASE, CACHE_ROM_SIZE,
+		MTRR_TYPE_WRPROT);
+
+	/* Cache RAM as WB from 0 -> CACHE_TMP_RAMTOP. */
+	postcar_frame_add_mtrr(&pcf, 0, CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK);
+
+	/* Cache CBMEM region as WB. */
+	top_of_ram = (uintptr_t)cbmem_top();
+	postcar_frame_add_mtrr(&pcf, top_of_ram - 8*MiB, 8*MiB,
+		MTRR_TYPE_WRBACK);
+
+	/* Save the number of MTRRs to setup. Return the stack location
+	 * pointing to the number of MTRRs.
+	 */
+	return postcar_commit_mtrrs(&pcf);
+}
diff --git a/src/northbridge/intel/e7505/northbridge.c b/src/northbridge/intel/e7505/northbridge.c
index ea8b459..6d351a3 100644
--- a/src/northbridge/intel/e7505/northbridge.c
+++ b/src/northbridge/intel/e7505/northbridge.c
@@ -31,84 +31,43 @@
 
 static void mch_domain_read_resources(struct device *dev)
 {
+	int idx;
+	unsigned long tomk, tolmk;
+	unsigned long remapbasek, remaplimitk;
+	const unsigned long basek_4G = 4 * (GiB / KiB);
 	struct device *mc_dev;
-	uint32_t pci_tolm;
 
 	pci_domain_read_resources(dev);
 
-	pci_tolm = find_pci_tolm(dev->link_list);
-	mc_dev = dev->link_list->children;
-	if (mc_dev) {
-		/* Figure out which areas are/should be occupied by RAM.
-		 * This is all computed in kilobytes and converted to/from
-		 * the memory controller right at the edges.
-		 * Having different variables in different units is
-		 * too confusing to get right.  Kilobytes are good up to
-		 * 4 Terabytes of RAM...
-		 */
-		uint16_t tolm_r, remapbase_r, remaplimit_r;
-		unsigned long tomk, tolmk;
-		unsigned long remapbasek, remaplimitk;
-		int idx;
+	mc_dev = dev_find_slot(0, PCI_DEVFN(0x0, 0));
+	if (!mc_dev)
+		die("Could not find MCH device\n");
 
-		/* Get the value of the highest DRB. This tells the end of
-		 * the physical memory.  The units are ticks of 64MB
-		 * i.e. 1 means 64MB.
-		 */
-		tomk = ((unsigned long)pci_read_config8(mc_dev, DRB_ROW_7)) << 16;
-		/* Compute the top of Low memory */
-		tolmk = pci_tolm >> 10;
-		if (tolmk >= tomk) {
-			/* The PCI hole does not overlap memory
-			 * we won't use the remap window.
-			 */
-			tolmk = tomk;
-			remapbasek   = 0x3ff << 16;
-			remaplimitk  = 0 << 16;
-		}
-		else {
-			/* The PCI memory hole overlaps memory
-			 * setup the remap window.
-			 */
-			/* Find the bottom of the remap window
-			 * is it above 4G?
-			 */
-			remapbasek = 4*1024*1024;
-			if (tomk > remapbasek) {
-				remapbasek = tomk;
-			}
-			/* Find the limit of the remap window */
-			remaplimitk = (remapbasek + (4*1024*1024 - tolmk) - (1 << 16));
-		}
-		/* Write the RAM configuration registers,
-		 * preserving the reserved bits.
-		 */
-		tolm_r = pci_read_config16(mc_dev, TOLM);
-		tolm_r = ((tolmk >> 17) << 11) | (tolm_r & 0x7ff);
-		pci_write_config16(mc_dev, TOLM, tolm_r);
+	tolmk = pci_read_config16(mc_dev, TOLM) >> 11;
+	tolmk <<= 17;
 
-		remapbase_r = pci_read_config16(mc_dev, REMAPBASE);
-		remapbase_r = (remapbasek >> 16) | (remapbase_r & 0xfc00);
-		pci_write_config16(mc_dev, REMAPBASE, remapbase_r);
+	tomk = pci_read_config8(mc_dev, DRB_ROW_7);
+	tomk <<= 16;
 
-		remaplimit_r = pci_read_config16(mc_dev, REMAPLIMIT);
-		remaplimit_r = (remaplimitk >> 16) | (remaplimit_r & 0xfc00);
-		pci_write_config16(mc_dev, REMAPLIMIT, remaplimit_r);
+	/* Remapped region with a 64 MiB granularity in register
+	   definition. Limit is inclusive, so add one. */
+	remapbasek = pci_read_config16(mc_dev, REMAPBASE) & 0x3ff;
+	remapbasek <<= 16;
 
-		/* Report the memory regions */
-		idx = 10;
-		ram_resource(dev, idx++, 0, 640);
-		ram_resource(dev, idx++, 768, tolmk - 768);
-		if (tomk > 4*1024*1024) {
-			ram_resource(dev, idx++, 4096*1024, tomk - 4*1024*1024);
-		}
-		if (remaplimitk >= remapbasek) {
-			ram_resource(dev, idx++, remapbasek,
-				(remaplimitk + 64*1024) - remapbasek);
-		}
+	remaplimitk = pci_read_config16(mc_dev, REMAPLIMIT) & 0x3ff;
+	remaplimitk += 1;
+	remaplimitk <<= 16;
 
-		set_late_cbmem_top(tolmk * 1024);
-	}
+	/* Report the memory regions */
+	idx = 10;
+	ram_resource(dev, idx++, 0, 640);
+	ram_resource(dev, idx++, 768, tolmk - 768);
+
+	if (tomk > basek_4G)
+		ram_resource(dev, idx++, basek_4G, tomk - basek_4G);
+
+	if (remaplimitk > remapbasek)
+		ram_resource(dev, idx++, remapbasek, remaplimitk - remapbasek);
 }
 
 static void mch_domain_set_resources(struct device *dev)
diff --git a/src/northbridge/intel/e7505/raminit.c b/src/northbridge/intel/e7505/raminit.c
index f3a2520..7464a72 100644
--- a/src/northbridge/intel/e7505/raminit.c
+++ b/src/northbridge/intel/e7505/raminit.c
@@ -30,8 +30,8 @@
 #include <arch/cpu.h>
 #include <lib.h>
 #include <stdlib.h>
+#include <commonlib/helpers.h>
 #include <console/console.h>
-
 #include <cpu/x86/mtrr.h>
 #include <cpu/x86/cache.h>
 #include <cpu/x86/msr.h>
@@ -850,6 +850,12 @@
 {
 	int i;
 	uint8_t total_dram_64M_multiple = 0;
+	uint64_t tolm, tom;
+	uint16_t reg;
+
+	/* Start with disabled remap range. */
+	uint16_t remapbase_r = 0x3ff;
+	uint16_t remaplimit_r = 0;
 
 	// Configure the E7501's DRAM row boundaries
 	// Start by zeroing out the temporary initial configuration
@@ -879,71 +885,37 @@
 		    configure_dimm_row_boundaries(sz, total_dram_64M_multiple, i);
 	}
 
-	// Configure the Top Of Low Memory (TOLM) in the E7501
-	// This address must be a multiple of 128 MB that is less than 4 GB.
-	// NOTE: 16-bit wide TOLM register stores only the highest 5 bits of a 32-bit address
-	//               in the highest 5 bits.
+	tom = total_dram_64M_multiple * 64ULL * MiB;
 
-	// We set TOLM to the smaller of 0xC0000000 (3 GB) or the total DRAM in the system.
-	// This reserves addresses from 0xC0000000 - 0xFFFFFFFF for non-DRAM purposes
-	// such as flash and memory-mapped I/O.
+	/* Reserve MMIO space. */
+	tolm = 4ULL * GiB - 1 * GiB;
+	tolm = MIN(tolm, tom);
 
-	// If there is more than 3 GB of DRAM, we define a remap window which
-	// makes the DRAM "behind" the reserved region available above the top of physical
-	// memory.
+	/* The PCI memory hole overlaps memory setup the remap window. */
+	if (tolm < tom) {
+		uint64_t remapbase = MAX(tom, 4ULL * GiB);
+		uint64_t remaplimit = remapbase + (4ULL * GiB - tolm);
 
-	// NOTE: 0xC0000000 / (64 MB) == 0x30
+		remapbase_r = remapbase / (64 * MiB);
+		remaplimit_r = remaplimit / (64 * MiB);
 
-	if (total_dram_64M_multiple <= 0x30) {
-
-		// <= 3 GB total RAM
-
-		/* I should really adjust all of this in C after I have resources
-		 * to all of the pci devices.
-		 */
-
-		// Round up to 128MB granularity
-		// SJM: Is "missing" 64 MB of memory a potential issue? Should this round down?
-
-		uint8_t total_dram_128M_multiple =
-		    (total_dram_64M_multiple + 1) >> 1;
-
-		// Convert to high 16 bits of address
-		uint16_t top_of_low_memory =
-		    total_dram_128M_multiple << 11;
-
-		pci_write_config16(MCHDEV, TOLM,
-				   top_of_low_memory);
-
-	} else {
-
-		// > 3 GB total RAM
-
-		// Set defaults for > 4 GB DRAM, i.e. remap a 1 GB (= 0x10 * 64 MB) range of memory
-		uint16_t remap_base = total_dram_64M_multiple;	// A[25:0] == 0
-		uint16_t remap_limit = total_dram_64M_multiple + 0x10 - 1;	// A[25:0] == 0xF
-
-		// Put TOLM at 3 GB
-
-		pci_write_config16(MCHDEV, TOLM, 0xc000);
-
-		// Define a remap window to make the RAM that would appear from 3 GB - 4 GB
-		// visible just beyond 4 GB or the end of physical memory, whichever is larger
-		// NOTE: 16-bit wide REMAP registers store only the highest 10 bits of a 36-bit address,
-		//               (i.e. a multiple of 64 MB) in the lowest 10 bits.
-		// NOTE: 0x100000000 / (64 MB) == 0x40
-
-		if (total_dram_64M_multiple < 0x40) {
-			remap_base = 0x40;	// 0x100000000
-			remap_limit =
-			    0x40 + (total_dram_64M_multiple - 0x30) - 1;
-		}
-
-		pci_write_config16(MCHDEV, REMAPBASE,
-				   remap_base);
-		pci_write_config16(MCHDEV, REMAPLIMIT,
-				   remap_limit);
+		/* Limit register is inclusive. */
+		remaplimit_r -= 1;
 	}
+
+	/* Write the RAM configuration registers,
+	   preserving the reserved bits. */
+	reg = pci_read_config16(MCHDEV, TOLM) & 0x7ff;
+	reg |= (tolm / (128 * MiB)) << 11;
+	pci_write_config16(MCHDEV, TOLM, reg);
+
+	reg = pci_read_config16(MCHDEV, REMAPBASE) & 0xfc00;
+	reg |= remapbase_r;
+	pci_write_config16(MCHDEV, REMAPBASE, reg);
+
+	reg = pci_read_config16(MCHDEV, REMAPLIMIT) & 0xfc00;
+	reg |= remaplimit_r;
+	pci_write_config16(MCHDEV, REMAPLIMIT, reg);
 }
 
 /**
@@ -1904,12 +1876,6 @@
 	sdram_enable(memctrl);
 }
 
-uintptr_t restore_top_of_low_cacheable(void)
-{
-	u32 tolm = (pci_read_config16(MCHDEV, TOLM) & ~0x7ff) << 16;
-	return tolm;
-}
-
 /**
  * Scrub and reset error counts for ECC dimms.
  *