nb/intel/sandybridge: Reserve CAR region with !NATIVE_RAMINIT

Fail builds if MRC blobs pool heap would get corrupted
by CAR relocatable data from coreboot proper.

Add runtime logging how much pool was required.

Change-Id: Ibc771b592b35d77be81fce87769314fe6bb84c87
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/31150
Reviewed-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/arch/x86/car.ld b/src/arch/x86/car.ld
index 2d835a3..4360830 100644
--- a/src/arch/x86/car.ld
+++ b/src/arch/x86/car.ld
@@ -85,6 +85,14 @@
 	_car_global_end = .;
 	_car_relocatable_data_end = .;
 
+#if IS_ENABLED(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) && \
+    !IS_ENABLED(CONFIG_USE_NATIVE_RAMINIT)
+	. = ABSOLUTE(0xff7e1000);
+	_mrc_pool = .;
+	. += 0x5000;
+	_emrc_pool = .;
+#endif
+
 #if !IS_ENABLED(CONFIG_C_ENVIRONMENT_BOOTBLOCK)
 	_car_stack_start = .;
 	_car_stack_end = _car_region_end;
diff --git a/src/northbridge/intel/sandybridge/raminit_mrc.c b/src/northbridge/intel/sandybridge/raminit_mrc.c
index 6142388..853fdb8 100644
--- a/src/northbridge/intel/sandybridge/raminit_mrc.c
+++ b/src/northbridge/intel/sandybridge/raminit_mrc.c
@@ -25,6 +25,7 @@
 #include <ip_checksum.h>
 #include <pc80/mc146818rtc.h>
 #include <device/pci_def.h>
+#include <lib.h>
 #include <mrc_cache.h>
 #include <halt.h>
 #include <timestamp.h>
@@ -262,10 +263,23 @@
 	report_memory_config();
 }
 
+/* These are the location and structure of MRC_VAR data in CAR. */
+#define DCACHE_RAM_MRC_VAR_BASE \
+	(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)
+
+struct mrc_var_data {
+	u32 acpi_timer_flag;
+	u32 pool_used;
+	u32 pool_base;
+	u32 tx_byte;
+	u32 reserved[4];
+} __packed;
+
 void perform_raminit(int s3resume)
 {
 	int cbmem_was_initted;
 	struct pei_data pei_data;
+	struct mrc_var_data *mrc_var;
 
 	/* Prepare USB controller early in S3 resume */
 	if (!mainboard_should_reset_usb(s3resume))
@@ -277,6 +291,18 @@
 	pei_data.boot_mode = s3resume ? 2 : 0;
 	timestamp_add_now(TS_BEFORE_INITRAM);
 	sdram_initialize(&pei_data);
+
+	mrc_var = (void *)DCACHE_RAM_MRC_VAR_BASE;
+	/* Sanity check mrc_var location by verifying a known field. */
+	if (mrc_var->tx_byte == (uintptr_t)pei_data.tx_byte) {
+		printk(BIOS_DEBUG, "MRC_VAR pool occupied [%08x,%08x]\n",
+		       mrc_var->pool_base,
+		       mrc_var->pool_base + mrc_var->pool_used);
+	} else {
+		printk(BIOS_ERR, "Could not parse MRC_VAR data\n");
+		hexdump32(BIOS_ERR, mrc_var, sizeof(*mrc_var)/sizeof(u32));
+	}
+
 	cbmem_was_initted = !cbmem_recovery(s3resume);
 	if (!s3resume)
 		save_mrc_data(&pei_data);