[coreboot-gerrit] New patch to review for coreboot: WIP: sandy/ivy: Treat native init as first class citizen

Alexandru Gagniuc (mr.nuke.me@gmail.com) gerrit at coreboot.org
Sat Oct 3 19:25:15 CET 2015


Alexandru Gagniuc (mr.nuke.me at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11788

-gerrit

commit 4079a43a2a8b3c3b567124c05c7a2961413ab677
Author: Alexandru Gagniuc <mr.nuke.me at gmail.com>
Date:   Mon Sep 28 21:39:12 2015 -0700

    WIP: sandy/ivy: Treat native init as first class citizen
    
    The MRC path becomes a second-class citizen and gets the _MRC suffix,
    while the native path becomes suffixless.
    
    Change-Id: Ic86cee5e00bf7f598716d3d15d1ea81ca673932f
    Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
---
 src/Kconfig                                     |   8 +-
 src/cpu/intel/Makefile.inc                      |   4 +-
 src/northbridge/intel/sandybridge/Kconfig       |  10 +-
 src/northbridge/intel/sandybridge/Makefile.inc  |   6 +-
 src/northbridge/intel/sandybridge/raminit.c     | 293 ------------------------
 src/northbridge/intel/sandybridge/raminit_mrc.c | 293 ++++++++++++++++++++++++
 src/southbridge/intel/bd82x6x/Makefile.inc      |   4 +-
 7 files changed, 309 insertions(+), 309 deletions(-)

diff --git a/src/Kconfig b/src/Kconfig
index 2c75750..5ea6b9d 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -246,8 +246,8 @@ config CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM
 
 config FLASHMAP_OFFSET
 	hex "Flash Map Offset"
-	default 0x00670000 if NORTHBRIDGE_INTEL_SANDYBRIDGE
-	default 0x00610000 if NORTHBRIDGE_INTEL_IVYBRIDGE
+	default 0x00670000 if NORTHBRIDGE_INTEL_SANDYBRIDGE_MRC
+	default 0x00610000 if NORTHBRIDGE_INTEL_IVYBRIDGE_MRC
 	default CBFS_SIZE if !ARCH_X86
 	default 0
 	help
@@ -337,8 +337,8 @@ source "src/mainboard/Kconfig"
 config CBFS_SIZE
 	hex "Size of CBFS filesystem in ROM"
 	default 0x100000 if HAVE_INTEL_FIRMWARE || \
-	  NORTHBRIDGE_INTEL_GM45 || NORTHBRIDGE_INTEL_SANDYBRIDGE || \
-	  NORTHBRIDGE_INTEL_IVYBRIDGE || NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE || \
+	  NORTHBRIDGE_INTEL_GM45 || NORTHBRIDGE_INTEL_SANDYBRIDGE_MRC || \
+	  NORTHBRIDGE_INTEL_IVYBRIDGE_MRC || NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE || \
 	  NORTHBRIDGE_INTEL_SANDYBRIDGE_NATIVE || \
 	  NORTHBRIDGE_INTEL_NEHALEM || SOC_INTEL_BRASWELL || \
 	  SOC_INTEL_BROADWELL
diff --git a/src/cpu/intel/Makefile.inc b/src/cpu/intel/Makefile.inc
index 51451e9..e6a2d6a 100644
--- a/src/cpu/intel/Makefile.inc
+++ b/src/cpu/intel/Makefile.inc
@@ -17,9 +17,9 @@ subdirs-$(CONFIG_CPU_INTEL_SOCKET_PGA370) += socket_PGA370
 subdirs-$(CONFIG_CPU_INTEL_SOCKET_RPGA988B) += socket_rPGA988B
 subdirs-$(CONFIG_CPU_INTEL_SOCKET_RPGA989) += socket_rPGA989
 subdirs-$(CONFIG_NORTHBRIDGE_INTEL_NEHALEM) += model_2065x
-subdirs-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += model_206ax
+subdirs-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE_MRC) += model_206ax
 subdirs-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE_NATIVE) += model_206ax
-subdirs-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += model_206ax
+subdirs-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE_MRC) += model_206ax
 subdirs-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE) += model_206ax
 subdirs-$(CONFIG_NORTHBRIDGE_INTEL_HASWELL) += haswell
 subdirs-$(CONFIG_NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE) += fsp_model_206ax
diff --git a/src/northbridge/intel/sandybridge/Kconfig b/src/northbridge/intel/sandybridge/Kconfig
index 093224f..f8a6263 100644
--- a/src/northbridge/intel/sandybridge/Kconfig
+++ b/src/northbridge/intel/sandybridge/Kconfig
@@ -17,7 +17,7 @@
 ## Foundation, Inc.
 ##
 
-config NORTHBRIDGE_INTEL_SANDYBRIDGE
+config NORTHBRIDGE_INTEL_SANDYBRIDGE_MRC
 	bool
 	select MMCONF_SUPPORT
 	select MMCONF_SUPPORT_DEFAULT
@@ -32,7 +32,7 @@ config NORTHBRIDGE_INTEL_SANDYBRIDGE_NATIVE
 	select HAVE_DEBUG_RAM_SETUP
 	select INTEL_GMA_ACPI
 
-config NORTHBRIDGE_INTEL_IVYBRIDGE
+config NORTHBRIDGE_INTEL_IVYBRIDGE_MRC
 	bool
 	select MMCONF_SUPPORT
 	select MMCONF_SUPPORT_DEFAULT
@@ -47,7 +47,7 @@ config NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE
 	select HAVE_DEBUG_RAM_SETUP
 	select INTEL_GMA_ACPI
 
-if NORTHBRIDGE_INTEL_SANDYBRIDGE || NORTHBRIDGE_INTEL_IVYBRIDGE || NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE || NORTHBRIDGE_INTEL_SANDYBRIDGE_NATIVE
+if NORTHBRIDGE_INTEL_SANDYBRIDGE_MRC || NORTHBRIDGE_INTEL_IVYBRIDGE_MRC || NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE || NORTHBRIDGE_INTEL_SANDYBRIDGE_NATIVE
 
 config VGA_BIOS_ID
 	string
@@ -72,8 +72,8 @@ config MRC_CACHE_SIZE
 
 config DCACHE_RAM_BASE
 	hex
-	default 0xff7e0000 if NORTHBRIDGE_INTEL_IVYBRIDGE
-	default 0xff7e0000 if NORTHBRIDGE_INTEL_SANDYBRIDGE
+	default 0xff7e0000 if NORTHBRIDGE_INTEL_IVYBRIDGE_MRC
+	default 0xff7e0000 if NORTHBRIDGE_INTEL_SANDYBRIDGE_MRC
 	default 0xfefe0000 if NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE
 	default 0xfefe0000 if NORTHBRIDGE_INTEL_SANDYBRIDGE_NATIVE
 
diff --git a/src/northbridge/intel/sandybridge/Makefile.inc b/src/northbridge/intel/sandybridge/Makefile.inc
index 52fe23c..fee9457 100644
--- a/src/northbridge/intel/sandybridge/Makefile.inc
+++ b/src/northbridge/intel/sandybridge/Makefile.inc
@@ -17,7 +17,7 @@
 # Foundation, Inc.
 #
 
-ifeq ($(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE_NATIVE)$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE)$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE)$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE),y)
+ifeq ($(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE_NATIVE)$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE_MRC)$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE)$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE_MRC),y)
 
 ramstage-y += ram_calc.c
 ramstage-y += northbridge.c
@@ -29,8 +29,8 @@ ramstage-y += acpi.c
 ramstage-y += mrccache.c
 
 romstage-y += ram_calc.c
-romstage-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += raminit.c
-romstage-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += raminit.c
+romstage-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE_MRC) += raminit_mrc.c
+romstage-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE_MRC) += raminit_mrc.c
 romstage-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE) += raminit_native.c
 romstage-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE) += romstage_native.c
 romstage-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE) += ../../../device/dram/ddr3.c
diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c
deleted file mode 100644
index 053a487..0000000
--- a/src/northbridge/intel/sandybridge/raminit.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011 Google Inc.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#include <console/console.h>
-#include <console/usb.h>
-#include <bootmode.h>
-#include <string.h>
-#include <arch/io.h>
-#include <cbmem.h>
-#include <arch/cbfs.h>
-#include <cbfs.h>
-#include <ip_checksum.h>
-#include <pc80/mc146818rtc.h>
-#include <device/pci_def.h>
-#include <halt.h>
-#include "raminit.h"
-#include "pei_data.h"
-#include "sandybridge.h"
-
-/* Management Engine is in the southbridge */
-#include "southbridge/intel/bd82x6x/me.h"
-
-/*
- * MRC scrambler seed offsets should be reserved in
- * mainboard cmos.layout and not covered by checksum.
- */
-#if CONFIG_USE_OPTION_TABLE
-#include "option_table.h"
-#define CMOS_OFFSET_MRC_SEED     (CMOS_VSTART_mrc_scrambler_seed >> 3)
-#define CMOS_OFFSET_MRC_SEED_S3  (CMOS_VSTART_mrc_scrambler_seed_s3 >> 3)
-#define CMOS_OFFSET_MRC_SEED_CHK (CMOS_VSTART_mrc_scrambler_seed_chk >> 3)
-#else
-#define CMOS_OFFSET_MRC_SEED     152
-#define CMOS_OFFSET_MRC_SEED_S3  156
-#define CMOS_OFFSET_MRC_SEED_CHK 160
-#endif
-
-void save_mrc_data(struct pei_data *pei_data)
-{
-	u16 c1, c2, checksum;
-	struct mrc_data_container *mrcdata;
-	int output_len = ALIGN(pei_data->mrc_output_len, 16);
-
-	/* Save the MRC S3 restore data to cbmem */
-	mrcdata = cbmem_add
-		(CBMEM_ID_MRCDATA,
-		 output_len + sizeof(struct mrc_data_container));
-
-	if (mrcdata != NULL) {
-		printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%u bytes)\n",
-			pei_data->mrc_output, mrcdata, output_len);
-
-		mrcdata->mrc_signature = MRC_DATA_SIGNATURE;
-		mrcdata->mrc_data_size = output_len;
-		mrcdata->reserved = 0;
-		memcpy(mrcdata->mrc_data, pei_data->mrc_output,
-			pei_data->mrc_output_len);
-
-		/* Zero the unused space in aligned buffer. */
-		if (output_len > pei_data->mrc_output_len)
-			memset(mrcdata->mrc_data+pei_data->mrc_output_len, 0,
-			output_len - pei_data->mrc_output_len);
-
-		mrcdata->mrc_checksum = compute_ip_checksum(mrcdata->mrc_data,
-						mrcdata->mrc_data_size);
-	}
-
-	/* Save the MRC seed values to CMOS */
-	cmos_write32(CMOS_OFFSET_MRC_SEED, pei_data->scrambler_seed);
-	printk(BIOS_DEBUG, "Save scrambler seed    0x%08x to CMOS 0x%02x\n",
-	       pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED);
-
-	cmos_write32(CMOS_OFFSET_MRC_SEED_S3, pei_data->scrambler_seed_s3);
-	printk(BIOS_DEBUG, "Save s3 scrambler seed 0x%08x to CMOS 0x%02x\n",
-	       pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3);
-
-	/* Save a simple checksum of the seed values */
-	c1 = compute_ip_checksum((u8*)&pei_data->scrambler_seed,
-				 sizeof(u32));
-	c2 = compute_ip_checksum((u8*)&pei_data->scrambler_seed_s3,
-				 sizeof(u32));
-	checksum = add_ip_checksums(sizeof(u32), c1, c2);
-
-	cmos_write(checksum & 0xff, CMOS_OFFSET_MRC_SEED_CHK);
-	cmos_write((checksum >> 8) & 0xff, CMOS_OFFSET_MRC_SEED_CHK+1);
-}
-
-static void prepare_mrc_cache(struct pei_data *pei_data)
-{
-	struct mrc_data_container *mrc_cache;
-	u16 c1, c2, checksum, seed_checksum;
-
-	// preset just in case there is an error
-	pei_data->mrc_input = NULL;
-	pei_data->mrc_input_len = 0;
-
-	/* Read scrambler seeds from CMOS */
-	pei_data->scrambler_seed = cmos_read32(CMOS_OFFSET_MRC_SEED);
-	printk(BIOS_DEBUG, "Read scrambler seed    0x%08x from CMOS 0x%02x\n",
-	       pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED);
-
-	pei_data->scrambler_seed_s3 = cmos_read32(CMOS_OFFSET_MRC_SEED_S3);
-	printk(BIOS_DEBUG, "Read S3 scrambler seed 0x%08x from CMOS 0x%02x\n",
-	       pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3);
-
-	/* Compute seed checksum and compare */
-	c1 = compute_ip_checksum((u8*)&pei_data->scrambler_seed,
-				 sizeof(u32));
-	c2 = compute_ip_checksum((u8*)&pei_data->scrambler_seed_s3,
-				 sizeof(u32));
-	checksum = add_ip_checksums(sizeof(u32), c1, c2);
-
-	seed_checksum = cmos_read(CMOS_OFFSET_MRC_SEED_CHK);
-	seed_checksum |= cmos_read(CMOS_OFFSET_MRC_SEED_CHK+1) << 8;
-
-	if (checksum != seed_checksum) {
-		printk(BIOS_ERR, "%s: invalid seed checksum\n", __func__);
-		pei_data->scrambler_seed = 0;
-		pei_data->scrambler_seed_s3 = 0;
-		return;
-	}
-
-	if ((mrc_cache = find_current_mrc_cache()) == NULL) {
-		/* error message printed in find_current_mrc_cache */
-		return;
-	}
-
-	pei_data->mrc_input = mrc_cache->mrc_data;
-	pei_data->mrc_input_len = mrc_cache->mrc_data_size;
-
-	printk(BIOS_DEBUG, "%s: at %p, size %x checksum %04x\n",
-	       __func__, pei_data->mrc_input,
-	       pei_data->mrc_input_len, mrc_cache->mrc_checksum);
-}
-
-static const char* ecc_decoder[] = {
-	"inactive",
-	"active on IO",
-	"disabled on IO",
-	"active"
-};
-
-/*
- * Dump in the log memory controller configuration as read from the memory
- * controller registers.
- */
-static void report_memory_config(void)
-{
-	u32 addr_decoder_common, addr_decode_ch[2];
-	int i;
-
-	addr_decoder_common = MCHBAR32(0x5000);
-	addr_decode_ch[0] = MCHBAR32(0x5004);
-	addr_decode_ch[1] = MCHBAR32(0x5008);
-
-	printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n",
-	       (MCHBAR32(0x5e04) * 13333 * 2 + 50)/100);
-	printk(BIOS_DEBUG, "memcfg channel assignment: A: %d, B % d, C % d\n",
-	       addr_decoder_common & 3,
-	       (addr_decoder_common >> 2) & 3,
-	       (addr_decoder_common >> 4) & 3);
-
-	for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) {
-		u32 ch_conf = addr_decode_ch[i];
-		printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n",
-		       i, ch_conf);
-		printk(BIOS_DEBUG, "   ECC %s\n",
-		       ecc_decoder[(ch_conf >> 24) & 3]);
-		printk(BIOS_DEBUG, "   enhanced interleave mode %s\n",
-		       ((ch_conf >> 22) & 1) ? "on" : "off");
-		printk(BIOS_DEBUG, "   rank interleave %s\n",
-		       ((ch_conf >> 21) & 1) ? "on" : "off");
-		printk(BIOS_DEBUG, "   DIMMA %d MB width x%d %s rank%s\n",
-		       ((ch_conf >> 0) & 0xff) * 256,
-		       ((ch_conf >> 19) & 1) ? 16 : 8,
-		       ((ch_conf >> 17) & 1) ? "dual" : "single",
-		       ((ch_conf >> 16) & 1) ? "" : ", selected");
-		printk(BIOS_DEBUG, "   DIMMB %d MB width x%d %s rank%s\n",
-		       ((ch_conf >> 8) & 0xff) * 256,
-		       ((ch_conf >> 20) & 1) ? 16 : 8,
-		       ((ch_conf >> 18) & 1) ? "dual" : "single",
-		       ((ch_conf >> 16) & 1) ? ", selected" : "");
-	}
-}
-
-static void post_system_agent_init(struct pei_data *pei_data)
-{
-	/* If PCIe init is skipped, set the PEG clock gating */
-	if (!pei_data->pcie_init)
-		MCHBAR32(0x7010) = MCHBAR32(0x7010) | 0x01;
-}
-
-/**
- * Find PEI executable in coreboot filesystem and execute it.
- *
- * @param pei_data: configuration data for UEFI PEI reference code
- */
-void sdram_initialize(struct pei_data *pei_data)
-{
-	struct sys_info sysinfo;
-	int (*entry) (struct pei_data *pei_data) __attribute__ ((regparm(1)));
-
-	report_platform_info();
-
-	/* Wait for ME to be ready */
-	intel_early_me_init();
-	intel_early_me_uma_size();
-
-	printk(BIOS_DEBUG, "Starting UEFI PEI System Agent\n");
-
-	memset(&sysinfo, 0, sizeof(sysinfo));
-
-	sysinfo.boot_path = pei_data->boot_mode;
-
-	/*
-	 * Do not pass MRC data in for recovery mode boot,
-	 * Always pass it in for S3 resume.
-	 */
-	if (!recovery_mode_enabled() || pei_data->boot_mode == 2)
-		prepare_mrc_cache(pei_data);
-
-	/* If MRC data is not found we cannot continue S3 resume. */
-	if (pei_data->boot_mode == 2 && !pei_data->mrc_input) {
-		printk(BIOS_DEBUG, "Giving up in sdram_initialize: No MRC data\n");
-		outb(0x6, 0xcf9);
-		halt();
-	}
-
-	/* Pass console handler in pei_data */
-	pei_data->tx_byte = do_putchar;
-
-	/* Locate and call UEFI System Agent binary. */
-	entry = cbfs_boot_map_with_leak("mrc.bin", CBFS_TYPE_MRC, NULL);
-	if (entry) {
-		int rv;
-		rv = entry (pei_data);
-		if (rv) {
-			switch (rv) {
-			case -1:
-				printk(BIOS_ERR, "PEI version mismatch.\n");
-				break;
-			case -2:
-				printk(BIOS_ERR, "Invalid memory frequency.\n");
-				break;
-			default:
-				printk(BIOS_ERR, "MRC returned %x.\n", rv);
-			}
-			die("Nonzero MRC return value.\n");
-		}
-	} else {
-		die("UEFI PEI System Agent not found.\n");
-	}
-
-#if CONFIG_USBDEBUG_IN_ROMSTAGE
-	/* mrc.bin reconfigures USB, so reinit it to have debug */
-	usbdebug_init();
-#endif
-
-	/* For reference print the System Agent version
-	 * after executing the UEFI PEI stage.
-	 */
-	u32 version = MCHBAR32(0x5034);
-	printk(BIOS_DEBUG, "System Agent Version %d.%d.%d Build %d\n",
-		version >> 24 , (version >> 16) & 0xff,
-		(version >> 8) & 0xff, version & 0xff);
-
-	/* Send ME init done for SandyBridge here.  This is done
-	 * inside the SystemAgent binary on IvyBridge. */
-	if (BASE_REV_SNB ==
-	    (pci_read_config16(PCI_CPU_DEVICE, PCI_DEVICE_ID) & BASE_REV_MASK))
-		intel_early_me_init_done(ME_INIT_STATUS_SUCCESS);
-	else
-		intel_early_me_status();
-
-	post_system_agent_init(pei_data);
-	report_memory_config();
-}
diff --git a/src/northbridge/intel/sandybridge/raminit_mrc.c b/src/northbridge/intel/sandybridge/raminit_mrc.c
new file mode 100644
index 0000000..053a487
--- /dev/null
+++ b/src/northbridge/intel/sandybridge/raminit_mrc.c
@@ -0,0 +1,293 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Google Inc.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#include <console/console.h>
+#include <console/usb.h>
+#include <bootmode.h>
+#include <string.h>
+#include <arch/io.h>
+#include <cbmem.h>
+#include <arch/cbfs.h>
+#include <cbfs.h>
+#include <ip_checksum.h>
+#include <pc80/mc146818rtc.h>
+#include <device/pci_def.h>
+#include <halt.h>
+#include "raminit.h"
+#include "pei_data.h"
+#include "sandybridge.h"
+
+/* Management Engine is in the southbridge */
+#include "southbridge/intel/bd82x6x/me.h"
+
+/*
+ * MRC scrambler seed offsets should be reserved in
+ * mainboard cmos.layout and not covered by checksum.
+ */
+#if CONFIG_USE_OPTION_TABLE
+#include "option_table.h"
+#define CMOS_OFFSET_MRC_SEED     (CMOS_VSTART_mrc_scrambler_seed >> 3)
+#define CMOS_OFFSET_MRC_SEED_S3  (CMOS_VSTART_mrc_scrambler_seed_s3 >> 3)
+#define CMOS_OFFSET_MRC_SEED_CHK (CMOS_VSTART_mrc_scrambler_seed_chk >> 3)
+#else
+#define CMOS_OFFSET_MRC_SEED     152
+#define CMOS_OFFSET_MRC_SEED_S3  156
+#define CMOS_OFFSET_MRC_SEED_CHK 160
+#endif
+
+void save_mrc_data(struct pei_data *pei_data)
+{
+	u16 c1, c2, checksum;
+	struct mrc_data_container *mrcdata;
+	int output_len = ALIGN(pei_data->mrc_output_len, 16);
+
+	/* Save the MRC S3 restore data to cbmem */
+	mrcdata = cbmem_add
+		(CBMEM_ID_MRCDATA,
+		 output_len + sizeof(struct mrc_data_container));
+
+	if (mrcdata != NULL) {
+		printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%u bytes)\n",
+			pei_data->mrc_output, mrcdata, output_len);
+
+		mrcdata->mrc_signature = MRC_DATA_SIGNATURE;
+		mrcdata->mrc_data_size = output_len;
+		mrcdata->reserved = 0;
+		memcpy(mrcdata->mrc_data, pei_data->mrc_output,
+			pei_data->mrc_output_len);
+
+		/* Zero the unused space in aligned buffer. */
+		if (output_len > pei_data->mrc_output_len)
+			memset(mrcdata->mrc_data+pei_data->mrc_output_len, 0,
+			output_len - pei_data->mrc_output_len);
+
+		mrcdata->mrc_checksum = compute_ip_checksum(mrcdata->mrc_data,
+						mrcdata->mrc_data_size);
+	}
+
+	/* Save the MRC seed values to CMOS */
+	cmos_write32(CMOS_OFFSET_MRC_SEED, pei_data->scrambler_seed);
+	printk(BIOS_DEBUG, "Save scrambler seed    0x%08x to CMOS 0x%02x\n",
+	       pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED);
+
+	cmos_write32(CMOS_OFFSET_MRC_SEED_S3, pei_data->scrambler_seed_s3);
+	printk(BIOS_DEBUG, "Save s3 scrambler seed 0x%08x to CMOS 0x%02x\n",
+	       pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3);
+
+	/* Save a simple checksum of the seed values */
+	c1 = compute_ip_checksum((u8*)&pei_data->scrambler_seed,
+				 sizeof(u32));
+	c2 = compute_ip_checksum((u8*)&pei_data->scrambler_seed_s3,
+				 sizeof(u32));
+	checksum = add_ip_checksums(sizeof(u32), c1, c2);
+
+	cmos_write(checksum & 0xff, CMOS_OFFSET_MRC_SEED_CHK);
+	cmos_write((checksum >> 8) & 0xff, CMOS_OFFSET_MRC_SEED_CHK+1);
+}
+
+static void prepare_mrc_cache(struct pei_data *pei_data)
+{
+	struct mrc_data_container *mrc_cache;
+	u16 c1, c2, checksum, seed_checksum;
+
+	// preset just in case there is an error
+	pei_data->mrc_input = NULL;
+	pei_data->mrc_input_len = 0;
+
+	/* Read scrambler seeds from CMOS */
+	pei_data->scrambler_seed = cmos_read32(CMOS_OFFSET_MRC_SEED);
+	printk(BIOS_DEBUG, "Read scrambler seed    0x%08x from CMOS 0x%02x\n",
+	       pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED);
+
+	pei_data->scrambler_seed_s3 = cmos_read32(CMOS_OFFSET_MRC_SEED_S3);
+	printk(BIOS_DEBUG, "Read S3 scrambler seed 0x%08x from CMOS 0x%02x\n",
+	       pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3);
+
+	/* Compute seed checksum and compare */
+	c1 = compute_ip_checksum((u8*)&pei_data->scrambler_seed,
+				 sizeof(u32));
+	c2 = compute_ip_checksum((u8*)&pei_data->scrambler_seed_s3,
+				 sizeof(u32));
+	checksum = add_ip_checksums(sizeof(u32), c1, c2);
+
+	seed_checksum = cmos_read(CMOS_OFFSET_MRC_SEED_CHK);
+	seed_checksum |= cmos_read(CMOS_OFFSET_MRC_SEED_CHK+1) << 8;
+
+	if (checksum != seed_checksum) {
+		printk(BIOS_ERR, "%s: invalid seed checksum\n", __func__);
+		pei_data->scrambler_seed = 0;
+		pei_data->scrambler_seed_s3 = 0;
+		return;
+	}
+
+	if ((mrc_cache = find_current_mrc_cache()) == NULL) {
+		/* error message printed in find_current_mrc_cache */
+		return;
+	}
+
+	pei_data->mrc_input = mrc_cache->mrc_data;
+	pei_data->mrc_input_len = mrc_cache->mrc_data_size;
+
+	printk(BIOS_DEBUG, "%s: at %p, size %x checksum %04x\n",
+	       __func__, pei_data->mrc_input,
+	       pei_data->mrc_input_len, mrc_cache->mrc_checksum);
+}
+
+static const char* ecc_decoder[] = {
+	"inactive",
+	"active on IO",
+	"disabled on IO",
+	"active"
+};
+
+/*
+ * Dump in the log memory controller configuration as read from the memory
+ * controller registers.
+ */
+static void report_memory_config(void)
+{
+	u32 addr_decoder_common, addr_decode_ch[2];
+	int i;
+
+	addr_decoder_common = MCHBAR32(0x5000);
+	addr_decode_ch[0] = MCHBAR32(0x5004);
+	addr_decode_ch[1] = MCHBAR32(0x5008);
+
+	printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n",
+	       (MCHBAR32(0x5e04) * 13333 * 2 + 50)/100);
+	printk(BIOS_DEBUG, "memcfg channel assignment: A: %d, B % d, C % d\n",
+	       addr_decoder_common & 3,
+	       (addr_decoder_common >> 2) & 3,
+	       (addr_decoder_common >> 4) & 3);
+
+	for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) {
+		u32 ch_conf = addr_decode_ch[i];
+		printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n",
+		       i, ch_conf);
+		printk(BIOS_DEBUG, "   ECC %s\n",
+		       ecc_decoder[(ch_conf >> 24) & 3]);
+		printk(BIOS_DEBUG, "   enhanced interleave mode %s\n",
+		       ((ch_conf >> 22) & 1) ? "on" : "off");
+		printk(BIOS_DEBUG, "   rank interleave %s\n",
+		       ((ch_conf >> 21) & 1) ? "on" : "off");
+		printk(BIOS_DEBUG, "   DIMMA %d MB width x%d %s rank%s\n",
+		       ((ch_conf >> 0) & 0xff) * 256,
+		       ((ch_conf >> 19) & 1) ? 16 : 8,
+		       ((ch_conf >> 17) & 1) ? "dual" : "single",
+		       ((ch_conf >> 16) & 1) ? "" : ", selected");
+		printk(BIOS_DEBUG, "   DIMMB %d MB width x%d %s rank%s\n",
+		       ((ch_conf >> 8) & 0xff) * 256,
+		       ((ch_conf >> 20) & 1) ? 16 : 8,
+		       ((ch_conf >> 18) & 1) ? "dual" : "single",
+		       ((ch_conf >> 16) & 1) ? ", selected" : "");
+	}
+}
+
+static void post_system_agent_init(struct pei_data *pei_data)
+{
+	/* If PCIe init is skipped, set the PEG clock gating */
+	if (!pei_data->pcie_init)
+		MCHBAR32(0x7010) = MCHBAR32(0x7010) | 0x01;
+}
+
+/**
+ * Find PEI executable in coreboot filesystem and execute it.
+ *
+ * @param pei_data: configuration data for UEFI PEI reference code
+ */
+void sdram_initialize(struct pei_data *pei_data)
+{
+	struct sys_info sysinfo;
+	int (*entry) (struct pei_data *pei_data) __attribute__ ((regparm(1)));
+
+	report_platform_info();
+
+	/* Wait for ME to be ready */
+	intel_early_me_init();
+	intel_early_me_uma_size();
+
+	printk(BIOS_DEBUG, "Starting UEFI PEI System Agent\n");
+
+	memset(&sysinfo, 0, sizeof(sysinfo));
+
+	sysinfo.boot_path = pei_data->boot_mode;
+
+	/*
+	 * Do not pass MRC data in for recovery mode boot,
+	 * Always pass it in for S3 resume.
+	 */
+	if (!recovery_mode_enabled() || pei_data->boot_mode == 2)
+		prepare_mrc_cache(pei_data);
+
+	/* If MRC data is not found we cannot continue S3 resume. */
+	if (pei_data->boot_mode == 2 && !pei_data->mrc_input) {
+		printk(BIOS_DEBUG, "Giving up in sdram_initialize: No MRC data\n");
+		outb(0x6, 0xcf9);
+		halt();
+	}
+
+	/* Pass console handler in pei_data */
+	pei_data->tx_byte = do_putchar;
+
+	/* Locate and call UEFI System Agent binary. */
+	entry = cbfs_boot_map_with_leak("mrc.bin", CBFS_TYPE_MRC, NULL);
+	if (entry) {
+		int rv;
+		rv = entry (pei_data);
+		if (rv) {
+			switch (rv) {
+			case -1:
+				printk(BIOS_ERR, "PEI version mismatch.\n");
+				break;
+			case -2:
+				printk(BIOS_ERR, "Invalid memory frequency.\n");
+				break;
+			default:
+				printk(BIOS_ERR, "MRC returned %x.\n", rv);
+			}
+			die("Nonzero MRC return value.\n");
+		}
+	} else {
+		die("UEFI PEI System Agent not found.\n");
+	}
+
+#if CONFIG_USBDEBUG_IN_ROMSTAGE
+	/* mrc.bin reconfigures USB, so reinit it to have debug */
+	usbdebug_init();
+#endif
+
+	/* For reference print the System Agent version
+	 * after executing the UEFI PEI stage.
+	 */
+	u32 version = MCHBAR32(0x5034);
+	printk(BIOS_DEBUG, "System Agent Version %d.%d.%d Build %d\n",
+		version >> 24 , (version >> 16) & 0xff,
+		(version >> 8) & 0xff, version & 0xff);
+
+	/* Send ME init done for SandyBridge here.  This is done
+	 * inside the SystemAgent binary on IvyBridge. */
+	if (BASE_REV_SNB ==
+	    (pci_read_config16(PCI_CPU_DEVICE, PCI_DEVICE_ID) & BASE_REV_MASK))
+		intel_early_me_init_done(ME_INIT_STATUS_SUCCESS);
+	else
+		intel_early_me_status();
+
+	post_system_agent_init(pei_data);
+	report_memory_config();
+}
diff --git a/src/southbridge/intel/bd82x6x/Makefile.inc b/src/southbridge/intel/bd82x6x/Makefile.inc
index a1256df..1e7225d 100644
--- a/src/southbridge/intel/bd82x6x/Makefile.inc
+++ b/src/southbridge/intel/bd82x6x/Makefile.inc
@@ -50,8 +50,8 @@ romstage-y += reset.c
 romstage-y += early_spi.c early_pch.c
 romstage-y += early_rcba.c
 
-romstage-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += early_me.c early_usb.c
-romstage-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += early_me.c early_usb.c
+romstage-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE_MRC) += early_me.c early_usb.c
+romstage-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE_MRC) += early_me.c early_usb.c
 romstage-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE_NATIVE) += early_thermal.c early_pch_native.c early_me_native.c early_usb_native.c
 romstage-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE_NATIVE) += early_thermal.c early_pch_native.c early_me_native.c early_usb_native.c
 



More information about the coreboot-gerrit mailing list