[coreboot-gerrit] Patch set updated for coreboot: Intel Common SOC: Add romstage support

Leroy P Leahy (leroy.p.leahy@intel.com) gerrit at coreboot.org
Tue Jun 23 00:30:45 CEST 2015


Leroy P Leahy (leroy.p.leahy at intel.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/10050

-gerrit

commit fb225874be70ed36dfa8dc5d444e424f929741b5
Author: Lee Leahy <leroy.p.leahy at intel.com>
Date:   Mon Apr 20 15:24:54 2015 -0700

    Intel Common SOC: Add romstage support
    
    Provide a common romstage implementation for the Intel SOCs.
    
    BRANCH=none
    BUG=None
    TEST=Build for Braswell
    
    Change-Id: I80f5f8f0f36e9023117b07d4af5c806fff8157b6
    Signed-off-by: Lee Leahy <leroy.p.leahy at intel.com>
---
 src/soc/intel/common/Kconfig        |  62 +++++
 src/soc/intel/common/Makefile.inc   |  15 +-
 src/soc/intel/common/fsp_ramstage.c | 343 +++++++++++++++++++++++++++
 src/soc/intel/common/gma.h          | 176 ++++++++++++++
 src/soc/intel/common/hda_verb.c     |   2 +-
 src/soc/intel/common/memmap.h       |  33 +++
 src/soc/intel/common/mrc_cache.c    |   4 +-
 src/soc/intel/common/raminit.c      | 320 ++++++++++++++++++++++++++
 src/soc/intel/common/ramstage.h     |  39 ++++
 src/soc/intel/common/romstage.c     | 447 ++++++++++++++++++++++++++++++++++++
 src/soc/intel/common/romstage.h     | 103 +++++++++
 src/soc/intel/common/stack.c        | 183 +++++++++++++++
 src/soc/intel/common/stack.h        |  35 +++
 src/soc/intel/common/stage_cache.c  |  39 ++++
 src/soc/intel/common/util.c         | 274 ++++++++++++++++++++++
 src/soc/intel/common/util.h         |  31 +++
 src/soc/intel/common/vbt.c          |  47 ++++
 17 files changed, 2147 insertions(+), 6 deletions(-)

diff --git a/src/soc/intel/common/Kconfig b/src/soc/intel/common/Kconfig
index 8b5cef3..7b88d55 100644
--- a/src/soc/intel/common/Kconfig
+++ b/src/soc/intel/common/Kconfig
@@ -3,30 +3,92 @@ config SOC_INTEL_COMMON
 	help
 	  common code for Intel SOCs
 
+if SOC_INTEL_COMMON
+
 if HAVE_MRC
 
 config CACHE_MRC_SETTINGS
 	bool "Save cached MRC settings"
 	default n
+	help
+	  If CONFIG_USE_FMAP is enabled, it is assumed that a flashmap
+	  containing an RW_MRC_CACHE entry that specifies the location and size
+	  of the cache will be added to the image and present at runtime.
 
 if CACHE_MRC_SETTINGS
 
 config MRC_SETTINGS_CACHE_BASE
 	hex
+	depends on !USE_FMAP
 	default 0xffb00000
 
 config MRC_SETTINGS_CACHE_SIZE
 	hex
+	depends on !USE_FMAP
 	default 0x10000
 
 config MRC_SETTINGS_PROTECT
 	bool "Enable protection on MRC settings"
+	depends on !USE_FMAP
 	default n
 
 endif # CACHE_MRC_SETTINGS
 
 endif # HAVE_MRC
 
+config CHIPSET_RESERVED_MEM_BYTES
+	hex "Size in bytes of chipset reserved memory area"
+	default 0
+	help
+          If insufficient documentation is available to determine the size of
+	  the chipset reserved memory area by walking the chipset registers,
+	  the CHIPSET_RESERVED_MEM_BYTES may be used as a workaround to account
+	  for the missing pieces of memory.  The value specified in bytes is:
+
+	  value = TSEG base - top of low usable memory - (any sizes determined
+	  by reading chipset registers)
+
+config DISPLAY_MTRRS
+	bool "MTRRs: Display the MTRR settings
+	default n
+
+config DISPLAY_SMM_MEMORY_MAP
+	bool "SMM: Display the SMM memory map"
+	default n
+
+config FSP_CACHE_SIZE
+	hex "FSP Cache Size in bytes"
+	default 0
+	help
+	  Size of the region in SMM used to cache the FSP binary. This region
+	  size value is used to split the SMM_RESERVED_SIZE config value
+	  into a region specifically for FSP.  The remaining region is for
+	  ramstage.
+
+config SOC_INTEL_COMMON_FSP_RAM_INIT
+	bool "FSP: Use the common raminit.c module"
+	default n
+	depends on PLATFORM_USES_FSP1_1
+
+config SOC_INTEL_COMMON_FSP_ROMSTAGE
+	bool
+	default n
+
 config SOC_INTEL_COMMON_RESET
 	bool
 	default n
+
+config SOC_INTEL_COMMON_STACK
+	bool
+	default n
+
+config SOC_INTEL_COMMON_STAGE_CACHE
+	bool
+	default n
+
+config ROMSTAGE_RAM_STACK_SIZE
+	hex "Size of the romstage RAM stack in bytes"
+	default 0x5000
+	depends on SOC_INTEL_COMMON_STACK
+
+endif # SOC_INTEL_COMMON
diff --git a/src/soc/intel/common/Makefile.inc b/src/soc/intel/common/Makefile.inc
index 6d40aa7..76854ad 100644
--- a/src/soc/intel/common/Makefile.inc
+++ b/src/soc/intel/common/Makefile.inc
@@ -1,10 +1,19 @@
 ifeq ($(CONFIG_SOC_INTEL_COMMON),y)
 
+romstage-$(CONFIG_CACHE_MRC_SETTINGS) += mrc_cache.c
+romstage-$(CONFIG_SOC_INTEL_COMMON_FSP_RAM_INIT) += raminit.c
+romstage-$(CONFIG_SOC_INTEL_COMMON_RESET) += reset.c
+romstage-$(CONFIG_SOC_INTEL_COMMON_FSP_ROMSTAGE) += romstage.c
+romstage-$(CONFIG_SOC_INTEL_COMMON_STACK) += stack.c
+romstage-$(CONFIG_SOC_INTEL_COMMON_STAGE_CACHE) += stage_cache.c
+romstage-$(CONFIG_PLATFORM_USES_FSP1_1) += util.c
+
+ramstage-$(CONFIG_PLATFORM_USES_FSP1_1) += fsp_ramstage.c
 ramstage-y += hda_verb.c
-ramstage-$(CONFIG_CACHE_MRC_SETTINGS) += nvm.c
 ramstage-$(CONFIG_CACHE_MRC_SETTINGS) += mrc_cache.c
-romstage-$(CONFIG_CACHE_MRC_SETTINGS) += mrc_cache.c
+ramstage-$(CONFIG_CACHE_MRC_SETTINGS) += nvm.c
 ramstage-$(CONFIG_SOC_INTEL_COMMON_RESET) += reset.c
-romstage-$(CONFIG_SOC_INTEL_COMMON_RESET) += reset.c
+ramstage-$(CONFIG_PLATFORM_USES_FSP1_1) += util.c
+ramstage-$(CONFIG_GOP_SUPPORT) += vbt.c
 
 endif
diff --git a/src/soc/intel/common/fsp_ramstage.c b/src/soc/intel/common/fsp_ramstage.c
new file mode 100644
index 0000000..b85591d
--- /dev/null
+++ b/src/soc/intel/common/fsp_ramstage.c
@@ -0,0 +1,343 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright (C) 2015 Intel Corporation.
+ *
+ * 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 <cbmem.h>
+#include <cbfs.h>
+#include <console/console.h>
+#include <fsp_util.h>
+#include <lib.h>
+#include <romstage_handoff.h>
+#include <soc/intel/common/memmap.h>
+#include <soc/intel/common/ramstage.h>
+#include <stage_cache.h>
+#include <timestamp.h>
+
+/* SOC initialization after FSP silicon init */
+__attribute__((weak)) void soc_after_silicon_init(void)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+}
+
+/*
+ * SMM Memory Map:
+ *
+ * +--------------------------+ smm_region_size() ----.
+ * |     FSP Cache            | CONFIG_FSP_CACHE_SIZE |
+ * +--------------------------+                       |
+ * |     SMM Ramstage Cache   |                       + CONFIG_SMM_RESERVED_SIZE
+ * +--------------------------+  ---------------------'
+ * |     SMM Code             |
+ * +--------------------------+ smm_base
+ *
+ */
+
+void stage_cache_external_region(void **base, size_t *size)
+{
+	size_t cache_size;
+	u8 *cache_base;
+
+	/* Determine the location of the ramstage cache */
+	smm_region((void **)&cache_base, &cache_size);
+	*size = CONFIG_SMM_RESERVED_SIZE - CONFIG_FSP_CACHE_SIZE;
+	*base = &cache_base[cache_size - CONFIG_SMM_RESERVED_SIZE];
+}
+
+static void *smm_fsp_cache_base(size_t *size)
+{
+	size_t cache_size;
+	u8 *cache_base;
+
+	/* Determine the location of the FSP cache */
+	stage_cache_external_region((void **)&cache_base, &cache_size);
+	*size = CONFIG_FSP_CACHE_SIZE;
+	return &cache_base[cache_size];
+}
+
+/* Display SMM memory map */
+static void smm_memory_map(void)
+{
+	u8 *smm_base;
+	size_t smm_bytes;
+	size_t smm_code_bytes;
+	u8 *fsp_cache;
+	size_t fsp_cache_bytes;
+	u8 *ramstage_cache;
+	size_t ramstage_cache_bytes;
+	u8 *smm_reserved;
+	size_t smm_reserved_bytes;
+
+	/* Locate the SMM regions */
+	smm_region((void **)&smm_base, &smm_bytes);
+	fsp_cache = smm_fsp_cache_base(&fsp_cache_bytes);
+	stage_cache_external_region((void **)&ramstage_cache, &ramstage_cache_bytes);
+	smm_code_bytes = ramstage_cache - smm_base;
+	smm_reserved = fsp_cache + fsp_cache_bytes;
+	smm_reserved_bytes = smm_bytes - fsp_cache_bytes - ramstage_cache_bytes
+		- smm_code_bytes;
+
+	/* Display the SMM regions */
+	printk(BIOS_SPEW, "\nLocation          SMM Memory Map        Offset\n");
+	if (smm_reserved_bytes) {
+		printk(BIOS_SPEW, "0x%p +--------------------------+ 0x%08x\n",
+			&smm_reserved[smm_reserved_bytes], (u32)smm_bytes);
+		printk(BIOS_SPEW, "           |   Other reserved region  |\n");
+	}
+	printk(BIOS_SPEW, "0x%p +--------------------------+ 0x%08x\n",
+		smm_reserved, (u32)(smm_reserved - smm_base));
+	printk(BIOS_SPEW, "           |   FSP binary cache       |\n");
+	printk(BIOS_SPEW, "0x%p +--------------------------+ 0x%08x\n",
+		fsp_cache, (u32)(fsp_cache - smm_base));
+	printk(BIOS_SPEW, "           |   ramstage cache         |\n");
+	printk(BIOS_SPEW, "0x%p +--------------------------+ 0x%08x\n",
+		ramstage_cache, (u32)(ramstage_cache - smm_base));
+	printk(BIOS_SPEW, "           |   SMM code               |\n");
+	printk(BIOS_SPEW, "0x%p +--------------------------+ 0x%08x\n",
+		smm_base, 0);
+	printk(BIOS_ERR, "\nCONFIG_FSP_CACHE_SIZE: 0x%08x bytes\n\n",
+		CONFIG_FSP_CACHE_SIZE);
+}
+
+struct smm_fsp_cache_header {
+	void *start;
+	size_t size;
+	FSP_INFO_HEADER *fih;
+};
+
+/* SoC implementation for caching support code. */
+static void soc_save_support_code(void *start, size_t size,
+	FSP_INFO_HEADER *fih)
+{
+	u8 *fsp_cache;
+	size_t fsp_cache_length;
+	struct smm_fsp_cache_header *header;
+	size_t smm_fsp_cache_length;
+
+	if (IS_ENABLED(CONFIG_DISPLAY_SMM_MEMORY_MAP))
+		smm_memory_map();
+
+	/* Locate the FSP cache in SMM */
+	fsp_cache = smm_fsp_cache_base(&smm_fsp_cache_length);
+
+	/* Initialize the FSP cache header */
+	header = (struct smm_fsp_cache_header *)fsp_cache;
+	fsp_cache += sizeof(*header);
+	header->start = start;
+	header->size = size;
+	header->fih = fih;
+
+	/* Validate the CONFIG_FSP_CACHE_SIZE value */
+	fsp_cache_length = sizeof(*header) + size;
+	if (smm_fsp_cache_length < fsp_cache_length) {
+		printk(BIOS_ERR, "CONFIG_FSP_CACHE_SIZE < 0x%08x bytes\n",
+			(u32)fsp_cache_length);
+		die("ERROR: Insufficent space to cache FSP binary!\n");
+	}
+
+	/* Copy the FSP binary into the SMM region for safe keeping */
+	memcpy(fsp_cache, start, size);
+}
+
+/* SoC implementation for restoring support code after S3 resume. Returns
+ * previously passed fih pointer from soc_save_support_code(). */
+static FSP_INFO_HEADER *soc_restore_support_code(void)
+{
+	u8 *fsp_cache;
+	struct smm_fsp_cache_header *header;
+	size_t smm_fsp_cache_length;
+
+	/* Locate the FSP cache in SMM */
+	fsp_cache = smm_fsp_cache_base(&smm_fsp_cache_length);
+
+	/* Get the FSP cache header */
+	header = (struct smm_fsp_cache_header *)fsp_cache;
+	fsp_cache += sizeof(*header);
+
+	/* Copy the FSP binary from the SMM region back into RAM */
+	memcpy(header->start, fsp_cache, header->size);
+
+	/* Return the FSP_INFO_HEADER address */
+	return header->fih;
+}
+
+static void fsp_run_silicon_init(struct romstage_handoff *handoff)
+{
+	FSP_INFO_HEADER *fsp_info_header;
+	FSP_SILICON_INIT fsp_silicon_init;
+	SILICON_INIT_UPD *original_params;
+	SILICON_INIT_UPD silicon_init_params;
+	EFI_STATUS status;
+	UPD_DATA_REGION *upd_ptr;
+	VPD_DATA_REGION *vpd_ptr;
+
+	/* Find the FSP image */
+	fsp_info_header = fsp_get_fih();
+	if (fsp_info_header == NULL) {
+		printk(BIOS_ERR, "FSP_INFO_HEADER not set!\n");
+		return;
+	}
+	print_fsp_info(fsp_info_header);
+
+	/* Initialize the UPD values */
+	vpd_ptr = (VPD_DATA_REGION *)(fsp_info_header->CfgRegionOffset +
+					fsp_info_header->ImageBase);
+	printk(BIOS_DEBUG, "0x%p: VPD Data\n", vpd_ptr);
+	upd_ptr = (UPD_DATA_REGION *)(vpd_ptr->PcdUpdRegionOffset +
+					fsp_info_header->ImageBase);
+	printk(BIOS_DEBUG, "0x%p: UPD Data\n", upd_ptr);
+	original_params = (void *)((u8 *)upd_ptr +
+		upd_ptr->SiliconInitUpdOffset);
+	memcpy(&silicon_init_params, original_params,
+		sizeof(silicon_init_params));
+	soc_silicon_init_params(&silicon_init_params);
+
+	/* Locate VBT and pass to FSP GOP */
+	if (IS_ENABLED(CONFIG_GOP_SUPPORT))
+		load_vbt(handoff->s3_resume, &silicon_init_params);
+	mainboard_silicon_init_params(&silicon_init_params);
+
+	/* Display the UPD data */
+	if (IS_ENABLED(CONFIG_DISPLAY_UPD_DATA))
+		soc_display_silicon_init_params(original_params,
+			&silicon_init_params);
+
+	/* Perform silicon initialization after RAM is configured */
+	printk(BIOS_DEBUG, "Calling FspSiliconInit\n");
+	fsp_silicon_init = (FSP_SILICON_INIT)(fsp_info_header->ImageBase
+		+ fsp_info_header->FspSiliconInitEntryOffset);
+	timestamp_add_now(TS_FSP_SILICON_INIT_START);
+	printk(BIOS_DEBUG, "Calling FspSiliconInit(0x%p) at 0x%p\n",
+		&silicon_init_params, fsp_silicon_init);
+	status = fsp_silicon_init(&silicon_init_params);
+	timestamp_add_now(TS_FSP_SILICON_INIT_END);
+	printk(BIOS_DEBUG, "FspSiliconInit returned 0x%08x\n", status);
+
+#if IS_ENABLED(CONFIG_DISPLAY_HOBS)
+	/* Verify the HOBs */
+	const EFI_GUID graphics_info_guid = EFI_PEI_GRAPHICS_INFO_HOB_GUID;
+	void *hob_list_ptr = get_hob_list();
+	int missing_hob = 0;
+
+	if (hob_list_ptr == NULL)
+		die("ERROR - HOB pointer is NULL!\n");
+	print_hob_type_structure(0, hob_list_ptr);
+
+	/*
+	 * Verify that FSP is generating the required HOBs:
+	 *	7.1: FSP_BOOTLOADER_TEMP_MEMORY_HOB only produced for FSP 1.0
+	 *	7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB verified by raminit
+	 *	7.3: FSP_NON_VOLATILE_STORAGE_HOB verified by raminit
+	 *	7.4: FSP_BOOTLOADER_TOLUM_HOB verified by raminit
+	 *	7.5: EFI_PEI_GRAPHICS_INFO_HOB verified below,
+	 *	     if the ImageAttribute bit is set
+	 *	FSP_SMBIOS_MEMORY_INFO HOB verified by raminit
+	 */
+	if ((fsp_info_header->ImageAttribute & GRAPHICS_SUPPORT_BIT) &&
+		!get_next_guid_hob(&graphics_info_guid, hob_list_ptr)) {
+		printk(BIOS_ERR, "7.5: EFI_PEI_GRAPHICS_INFO_HOB missing!\n");
+		missing_hob = 1;
+	}
+	if (missing_hob)
+		die("ERROR - Missing one or more required FSP HOBs!\n");
+#endif
+
+	soc_after_silicon_init();
+}
+
+static void fsp_cache_save(void)
+{
+	const struct cbmem_entry *fsp_entry;
+	FSP_INFO_HEADER *fih;
+
+	fsp_entry = cbmem_entry_find(CBMEM_ID_REFCODE);
+
+	if (fsp_entry == NULL) {
+		printk(BIOS_ERR, "ERROR: FSP not found in CBMEM.\n");
+		return;
+	}
+
+	fih = fsp_get_fih();
+
+	if (fih == NULL) {
+		printk(BIOS_ERR, "ERROR: No FIH found.\n");
+		return;
+	}
+
+	soc_save_support_code(cbmem_entry_start(fsp_entry),
+				cbmem_entry_size(fsp_entry), fih);
+}
+
+static int fsp_find_and_relocate(void)
+{
+	void *fih;
+	void *data;
+	size_t length;
+
+	data = cbfs_boot_map_with_leak("fsp.bin", CBFS_TYPE_FSP, &length);
+
+	if (data == NULL) {
+		printk(BIOS_ERR, "Couldn't find fsp.bin in CBFS.\n");
+		return -1;
+	}
+
+	fih = fsp_relocate(data, length);
+
+	fsp_update_fih(fih);
+
+	return 0;
+}
+
+void intel_silicon_init(void)
+{
+	struct romstage_handoff *handoff;
+
+	handoff = cbmem_find(CBMEM_ID_ROMSTAGE_INFO);
+
+	if (handoff != NULL && handoff->s3_resume) {
+		printk(BIOS_DEBUG, "FSP: Loading binary from cache\n");
+		fsp_update_fih(soc_restore_support_code());
+	} else {
+		fsp_find_and_relocate();
+		printk(BIOS_DEBUG, "FSP: Saving binary in cache\n");
+		fsp_cache_save();
+	}
+
+	fsp_run_silicon_init(handoff);
+}
+
+/* Initialize the UPD parameters for SiliconInit */
+__attribute__((weak)) void mainboard_silicon_init_params(
+	SILICON_INIT_UPD *params)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+};
+
+/* Display the UPD parameters for SiliconInit */
+__attribute__((weak)) void soc_display_silicon_init_params(
+	const SILICON_INIT_UPD *old, SILICON_INIT_UPD *new)
+{
+	printk(BIOS_SPEW, "UPD values for SiliconInit:\n");
+	hexdump32(BIOS_SPEW, new, sizeof(*new));
+}
+
+/* Initialize the UPD parameters for SiliconInit */
+__attribute__((weak)) void soc_silicon_init_params(SILICON_INIT_UPD *params)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+}
diff --git a/src/soc/intel/common/gma.h b/src/soc/intel/common/gma.h
new file mode 100644
index 0000000..9666147
--- /dev/null
+++ b/src/soc/intel/common/gma.h
@@ -0,0 +1,176 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Chromium OS Authors
+ * Copyright (C) 2015 Intel Corp.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _GMA_H_
+#define _GMA_H_
+
+#include <types.h>
+
+/* mailbox 0: header */
+typedef struct {
+	u8	signature[16];
+	u32	size;
+	u32	version;
+	u8	sbios_version[32];
+	u8	vbios_version[16];
+	u8	driver_version[16];
+	u32	mailboxes;
+	u8	reserved[164];
+} __attribute__((packed)) opregion_header_t;
+
+#define IGD_OPREGION_SIGNATURE "IntelGraphicsMem"
+#define IGD_OPREGION_VERSION  2
+
+#define IGD_MBOX1	(1 << 0)
+#define IGD_MBOX2	(1 << 1)
+#define IGD_MBOX3	(1 << 2)
+#define IGD_MBOX4	(1 << 3)
+#define IGD_MBOX5	(1 << 4)
+
+#define MAILBOXES_MOBILE  (IGD_MBOX1 | IGD_MBOX2 | IGD_MBOX3 | \
+			   IGD_MBOX4 | IGD_MBOX5)
+#define MAILBOXES_DESKTOP (IGD_MBOX2 | IGD_MBOX4)
+
+#define SBIOS_VERSION_SIZE 32
+
+/* mailbox 1: public acpi methods */
+typedef struct {
+	u32	drdy;
+	u32	csts;
+	u32	cevt;
+	u8	reserved1[20];
+	u32	didl[8];
+	u32	cpdl[8];
+	u32	cadl[8];
+	u32	nadl[8];
+	u32	aslp;
+	u32	tidx;
+	u32	chpd;
+	u32	clid;
+	u32	cdck;
+	u32	sxsw;
+	u32	evts;
+	u32	cnot;
+	u32	nrdy;
+	u8	reserved2[60];
+} __attribute__((packed)) opregion_mailbox1_t;
+
+/* mailbox 2: software sci interface */
+typedef struct {
+	u32	scic;
+	u32	parm;
+	u32	dslp;
+	u8	reserved[244];
+} __attribute__((packed)) opregion_mailbox2_t;
+
+/* mailbox 3: power conservation */
+typedef struct {
+	u32	ardy;
+	u32	aslc;
+	u32	tche;
+	u32	alsi;
+	u32	bclp;
+	u32	pfit;
+	u32	cblv;
+	u16	bclm[20];
+	u32	cpfm;
+	u32	epfm;
+	u8	plut[74];
+	u32	pfmb;
+	u32	ccdv;
+	u32	pcft;
+	u8	reserved[94];
+} __attribute__((packed)) opregion_mailbox3_t;
+
+#define IGD_BACKLIGHT_BRIGHTNESS 0xff
+#define IGD_INITIAL_BRIGHTNESS 0x64
+
+#define IGD_FIELD_VALID	(1 << 31)
+#define IGD_WORD_FIELD_VALID (1 << 15)
+#define IGD_PFIT_STRETCH 6
+
+/* mailbox 4: vbt */
+typedef struct {
+	u8 gvd1[7168];
+} __attribute__((packed)) opregion_vbt_t;
+
+/* IGD OpRegion */
+typedef struct {
+	opregion_header_t header;
+	opregion_mailbox1_t mailbox1;
+	opregion_mailbox2_t mailbox2;
+	opregion_mailbox3_t mailbox3;
+	opregion_vbt_t vbt;
+} __attribute__((packed)) igd_opregion_t;
+
+/* Intel Video BIOS (Option ROM) */
+typedef struct {
+	u16	signature;
+	u8	size;
+	u8	reserved[21];
+	u16	pcir_offset;
+	u16	vbt_offset;
+} __attribute__((packed)) optionrom_header_t;
+
+#define OPROM_SIGNATURE 0xaa55
+
+typedef struct {
+	u32 signature;
+	u16 vendor;
+	u16 device;
+	u16 reserved1;
+	u16 length;
+	u8  revision;
+	u8  classcode[3];
+	u16 imagelength;
+	u16 coderevision;
+	u8  codetype;
+	u8  indicator;
+	u16 reserved2;
+} __attribute__((packed)) optionrom_pcir_t;
+
+typedef struct {
+	u8  hdr_signature[20];
+	u16 hdr_version;
+	u16 hdr_size;
+	u16 hdr_vbt_size;
+	u8  hdr_vbt_checksum;
+	u8  hdr_reserved;
+	u32 hdr_vbt_datablock;
+	u32 hdr_aim[4];
+	u8  datahdr_signature[16];
+	u16 datahdr_version;
+	u16 datahdr_size;
+	u16 datahdr_datablocksize;
+	u8  coreblock_id;
+	u16 coreblock_size;
+	u16 coreblock_biossize;
+	u8  coreblock_biostype;
+	u8  coreblock_releasestatus;
+	u8  coreblock_hwsupported;
+	u8  coreblock_integratedhw;
+	u8  coreblock_biosbuild[4];
+	u8  coreblock_biossignon[155];
+} __attribute__((packed)) optionrom_vbt_t;
+
+#define VBT_SIGNATURE 0x54425624
+
+#endif /* _GMA_H_ */
+
diff --git a/src/soc/intel/common/hda_verb.c b/src/soc/intel/common/hda_verb.c
index c4cdb3d..ecd6c81 100644
--- a/src/soc/intel/common/hda_verb.c
+++ b/src/soc/intel/common/hda_verb.c
@@ -72,7 +72,7 @@ int hda_codec_detect(u8 *base)
 
 	/* Clear the "State Change Status Register" STATESTS bits
 	 * for each of the "SDIN Stat Change Status Flag"
-	*/
+	 */
 	write8(base + HDA_STATESTS_REG, 0xf);
 
 	/* Turn off the link and poll RESET# bit until it reads back as 0 */
diff --git a/src/soc/intel/common/memmap.h b/src/soc/intel/common/memmap.h
new file mode 100644
index 0000000..840b51e
--- /dev/null
+++ b/src/soc/intel/common/memmap.h
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corporation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _COMMON_MEMMAP_H_
+#define _COMMON_MEMMAP_H_
+
+#include <types.h>
+
+/*
+ * mmap_region_granluarity must to return a size which is a positive non-zero
+ * integer multiple of the SMM size when SMM is in use.  When not using SMM,
+ * this value should be set to 8 MiB.
+ */
+size_t mmap_region_granluarity(void);
+void smm_region(void **start, size_t *size);
+
+#endif /* _COMMON_MEMMAP_H_ */
diff --git a/src/soc/intel/common/mrc_cache.c b/src/soc/intel/common/mrc_cache.c
index 6783f18..9a066d5 100644
--- a/src/soc/intel/common/mrc_cache.c
+++ b/src/soc/intel/common/mrc_cache.c
@@ -154,7 +154,7 @@ int mrc_cache_get_current(const struct mrc_saved_data **cache)
 	return __mrc_cache_get_current(&region, cache);
 }
 
-#if defined(__PRE_RAM__)
+#if ENV_ROMSTAGE
 
 /*
  * romstage code
@@ -331,4 +331,4 @@ static void update_mrc_cache(void *unused)
 
 BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY, update_mrc_cache, NULL);
 
-#endif /* defined(__PRE_RAM__) */
+#endif /* ENV_ROMSTAGE */
diff --git a/src/soc/intel/common/raminit.c b/src/soc/intel/common/raminit.c
new file mode 100644
index 0000000..a9663c5
--- /dev/null
+++ b/src/soc/intel/common/raminit.c
@@ -0,0 +1,320 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014-2015 Intel Corporation
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <cbmem.h>
+#include <console/console.h>
+#include <fsp_util.h>
+#include <lib.h> /* hexdump */
+#include <reset.h>
+#include <soc/intel/common/memmap.h>
+#include <soc/pei_data.h>
+#include <soc/romstage.h>
+#include <string.h>
+#include <timestamp.h>
+
+void raminit(struct romstage_params *params)
+{
+	const EFI_GUID bootldr_tolum_guid = FSP_BOOTLOADER_TOLUM_HOB_GUID;
+	EFI_HOB_RESOURCE_DESCRIPTOR *cbmem_root;
+	FSP_INFO_HEADER *fsp_header;
+	EFI_HOB_RESOURCE_DESCRIPTOR *fsp_memory;
+	FSP_MEMORY_INIT fsp_memory_init;
+	FSP_MEMORY_INIT_PARAMS fsp_memory_init_params;
+	const EFI_GUID fsp_reserved_guid =
+		FSP_RESERVED_MEMORY_RESOURCE_HOB_GUID;
+	void *fsp_reserved_memory_area;
+	FSP_INIT_RT_COMMON_BUFFER fsp_rt_common_buffer;
+	void *hob_list_ptr;
+	FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
+	const EFI_GUID memory_info_hob_guid = FSP_SMBIOS_MEMORY_INFO_GUID;
+	MEMORY_INIT_UPD memory_init_params;
+	const EFI_GUID mrc_guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
+	u32 *mrc_hob;
+	u32 fsp_reserved_bytes;
+	MEMORY_INIT_UPD *original_params;
+	struct pei_data *pei_ptr;
+	EFI_STATUS status;
+	VPD_DATA_REGION *vpd_ptr;
+	UPD_DATA_REGION *upd_ptr;
+	int fsp_verification_failure = 0;
+#if IS_ENABLED(CONFIG_DISPLAY_HOBS)
+	unsigned long int data;
+	EFI_PEI_HOB_POINTERS hob_ptr;
+#endif
+
+	/*
+	 * Find and copy the UPD region to the stack so the platform can modify
+	 * the settings if needed.  Modifications to the UPD buffer are done in
+	 * the platform callback code.  The platform callback code is also
+	 * responsible for assigning the UpdDataRngPtr to this buffer if any
+	 * updates are made.  The default state is to leave the UpdDataRngPtr
+	 * set to NULL.  This indicates that the FSP code will use the UPD
+	 * region in the FSP binary.
+	 */
+	post_code(0x34);
+	fsp_header = params->chipset_context;
+	vpd_ptr = (VPD_DATA_REGION *)(fsp_header->CfgRegionOffset +
+					fsp_header->ImageBase);
+	printk(BIOS_DEBUG, "VPD Data: 0x%p\n", vpd_ptr);
+	upd_ptr = (UPD_DATA_REGION *)(vpd_ptr->PcdUpdRegionOffset +
+					fsp_header->ImageBase);
+	printk(BIOS_DEBUG, "UPD Data: 0x%p\n", upd_ptr);
+	original_params = (void *)((u8 *)upd_ptr +
+		upd_ptr->MemoryInitUpdOffset);
+	memcpy(&memory_init_params, original_params,
+		sizeof(memory_init_params));
+
+	/* Zero fill RT Buffer data and start populating fields. */
+	memset(&fsp_rt_common_buffer, 0, sizeof(fsp_rt_common_buffer));
+	pei_ptr = params->pei_data;
+	if (pei_ptr->boot_mode == SLEEP_STATE_S3) {
+		fsp_rt_common_buffer.BootMode = BOOT_ON_S3_RESUME;
+	} else if (pei_ptr->saved_data != NULL) {
+		fsp_rt_common_buffer.BootMode =
+			BOOT_ASSUMING_NO_CONFIGURATION_CHANGES;
+	} else {
+		fsp_rt_common_buffer.BootMode = BOOT_WITH_FULL_CONFIGURATION;
+	}
+	fsp_rt_common_buffer.UpdDataRgnPtr = &memory_init_params;
+	fsp_rt_common_buffer.BootLoaderTolumSize = cbmem_overhead_size();
+
+	/* Get any board specific changes */
+	fsp_memory_init_params.NvsBufferPtr = (void *)pei_ptr->saved_data;
+	fsp_memory_init_params.RtBufferPtr = &fsp_rt_common_buffer;
+	fsp_memory_init_params.HobListPtr = &hob_list_ptr;
+
+	/* Update the UPD data */
+	soc_memory_init_params(&memory_init_params);
+	mainboard_memory_init_params(params, &memory_init_params);
+	post_code(0x36);
+
+	/* Display the UPD data */
+	if (IS_ENABLED(CONFIG_DISPLAY_UPD_DATA))
+		soc_display_memory_init_params(original_params,
+			&memory_init_params);
+
+	/* Call FspMemoryInit to initialize RAM */
+	fsp_memory_init = (FSP_MEMORY_INIT)(fsp_header->ImageBase
+		+ fsp_header->FspMemoryInitEntryOffset);
+	printk(BIOS_DEBUG, "Calling FspMemoryInit: 0x%p\n", fsp_memory_init);
+	printk(BIOS_SPEW, "    0x%p: NvsBufferPtr\n",
+		fsp_memory_init_params.NvsBufferPtr);
+	printk(BIOS_SPEW, "    0x%p: RtBufferPtr\n",
+		fsp_memory_init_params.RtBufferPtr);
+	printk(BIOS_SPEW, "    0x%p: HobListPtr\n",
+		fsp_memory_init_params.HobListPtr);
+
+	timestamp_add_now(TS_FSP_MEMORY_INIT_START);
+	status = fsp_memory_init(&fsp_memory_init_params);
+	post_code(0x37);
+	timestamp_add_now(TS_FSP_MEMORY_INIT_END);
+
+	printk(BIOS_DEBUG, "FspMemoryInit returned 0x%08x\n", status);
+	if (status != EFI_SUCCESS)
+		die("ERROR - FspMemoryInit failed to initialize memory!\n");
+
+	/* Locate the FSP reserved memory area */
+	fsp_reserved_bytes = 0;
+	fsp_memory = get_next_resource_hob(&fsp_reserved_guid, hob_list_ptr);
+	if (fsp_memory == NULL) {
+		fsp_verification_failure = 1;
+		printk(BIOS_DEBUG,
+			"7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB missing!\n");
+	} else {
+		fsp_reserved_bytes = fsp_memory->ResourceLength;
+		printk(BIOS_DEBUG, "Reserving 0x%016lx bytes for FSP\n",
+			(unsigned long int)fsp_reserved_bytes);
+	}
+
+	/* Display SMM area */
+#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)
+	char *smm_base;
+	size_t smm_size;
+
+	smm_region((void **)&smm_base, &smm_size);
+	printk(BIOS_DEBUG, "0x%08x: smm_size\n", (unsigned int)smm_size);
+	printk(BIOS_DEBUG, "0x%p: smm_base\n", smm_base);
+#endif
+
+	/* Migrate CAR data */
+	printk(BIOS_DEBUG, "0x%08x: CONFIG_CHIPSET_RESERVED_MEM_BYTES\n",
+		CONFIG_CHIPSET_RESERVED_MEM_BYTES);
+	printk(BIOS_DEBUG, "0x%p: cbmem_top\n", cbmem_top());
+	if (pei_ptr->boot_mode != SLEEP_STATE_S3) {
+		cbmem_initialize_empty_id_size(CBMEM_ID_FSP_RESERVED_MEMORY,
+			fsp_reserved_bytes);
+	} else if (cbmem_initialize_id_size(CBMEM_ID_FSP_RESERVED_MEMORY,
+		fsp_reserved_bytes)) {
+#if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)
+		printk(BIOS_DEBUG, "Failed to recover CBMEM in S3 resume.\n");
+		/* Failed S3 resume, reset to come up cleanly */
+		hard_reset();
+#endif
+	}
+
+	/* Save the FSP runtime parameters. */
+	fsp_set_runtime(params->chipset_context, hob_list_ptr);
+
+	/* Lookup the FSP_BOOTLOADER_TOLUM_HOB */
+	cbmem_root = get_next_resource_hob(&bootldr_tolum_guid, hob_list_ptr);
+	if (cbmem_root == NULL) {
+		fsp_verification_failure = 1;
+		printk(BIOS_ERR, "7.4: FSP_BOOTLOADER_TOLUM_HOB missing!\n");
+		printk(BIOS_ERR, "BootLoaderTolumSize: 0x%08x bytes\n",
+			fsp_rt_common_buffer.BootLoaderTolumSize);
+	}
+
+	/* Locate the FSP_SMBIOS_MEMORY_INFO HOB */
+	memory_info_hob = get_next_guid_hob(&memory_info_hob_guid,
+		hob_list_ptr);
+	if (NULL == memory_info_hob) {
+		printk(BIOS_ERR, "FSP_SMBIOS_MEMORY_INFO HOB missing!\n");
+		fsp_verification_failure = 1;
+	} else {
+		printk(BIOS_DEBUG,
+			"FSP_SMBIOS_MEMORY_INFO HOB: 0x%p\n",
+			memory_info_hob);
+	}
+
+#if IS_ENABLED(CONFIG_DISPLAY_HOBS)
+	if (hob_list_ptr == NULL)
+		die("ERROR - HOB pointer is NULL!\n");
+
+	/*
+	 * Verify that FSP is generating the required HOBs:
+	 *	7.1: FSP_BOOTLOADER_TEMP_MEMORY_HOB only produced for FSP 1.0
+	 *	7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB verified above
+	 *	7.3: FSP_NON_VOLATILE_STORAGE_HOB verified below
+	 *	7.4: FSP_BOOTLOADER_TOLUM_HOB verified above
+	 *	7.5: EFI_PEI_GRAPHICS_INFO_HOB produced by SiliconInit
+	 *	FSP_SMBIOS_MEMORY_INFO HOB verified above
+	 */
+	if (NULL != cbmem_root) {
+		printk(BIOS_DEBUG,
+			"7.4: FSP_BOOTLOADER_TOLUM_HOB: 0x%p\n",
+			cbmem_root);
+		data = cbmem_root->PhysicalStart;
+		printk(BIOS_DEBUG, "    0x%016lx: PhysicalStart\n", data);
+		data = cbmem_root->ResourceLength;
+		printk(BIOS_DEBUG, "    0x%016lx: ResourceLength\n", data);
+	}
+	hob_ptr.Raw = get_next_guid_hob(&mrc_guid, hob_list_ptr);
+	if (NULL == hob_ptr.Raw) {
+		printk(BIOS_ERR, "7.3: FSP_NON_VOLATILE_STORAGE_HOB missing!\n");
+		fsp_verification_failure =
+			(params->pei_data->saved_data == NULL) ? 1 : 0;
+	} else {
+		printk(BIOS_DEBUG,
+			"7.3: FSP_NON_VOLATILE_STORAGE_HOB: 0x%p\n",
+			hob_ptr.Raw);
+	}
+	if (fsp_memory != NULL) {
+		printk(BIOS_DEBUG,
+			"7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB: 0x%p\n",
+			fsp_memory);
+		data = fsp_memory->PhysicalStart;
+		printk(BIOS_DEBUG, "    0x%016lx: PhysicalStart\n", data);
+		data = fsp_memory->ResourceLength;
+		printk(BIOS_DEBUG, "    0x%016lx: ResourceLength\n", data);
+	}
+
+	/* Verify all the HOBs are present */
+	if (fsp_verification_failure)
+		printk(BIOS_DEBUG,
+			"ERROR - Missing one or more required FSP HOBs!\n");
+
+	/* Display the HOBs */
+	print_hob_type_structure(0, hob_list_ptr);
+#endif
+
+	/* Get the address of the CBMEM region for the FSP reserved memory */
+	fsp_reserved_memory_area = cbmem_find(CBMEM_ID_FSP_RESERVED_MEMORY);
+	printk(BIOS_DEBUG, "0x%p: fsp_reserved_memory_area\n",
+		fsp_reserved_memory_area);
+
+	/* Verify the order of CBMEM root and FSP memory */
+	if ((fsp_memory != NULL) && (cbmem_root != NULL) &&
+		(cbmem_root->PhysicalStart <= fsp_memory->PhysicalStart)) {
+		fsp_verification_failure = 1;
+		printk(BIOS_DEBUG,
+			"ERROR - FSP reserved memory above CBMEM root!\n");
+	}
+
+	/* Verify that the FSP memory was properly reserved */
+	if ((fsp_memory != NULL) && ((fsp_reserved_memory_area == NULL) ||
+		(fsp_memory->PhysicalStart !=
+			(unsigned int)fsp_reserved_memory_area))) {
+		fsp_verification_failure = 1;
+		printk(BIOS_DEBUG, "ERROR - Reserving FSP memory area!\n");
+#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)
+		if (cbmem_root != NULL) {
+			size_t delta_bytes = (unsigned int)smm_base
+				- cbmem_root->PhysicalStart
+				- cbmem_root->ResourceLength;
+			printk(BIOS_DEBUG,
+				"0x%08x: CONFIG_CHIPSET_RESERVED_MEM_BYTES\n",
+				CONFIG_CHIPSET_RESERVED_MEM_BYTES);
+			printk(BIOS_DEBUG,
+				"0x%08x: Chipset reserved bytes reported by FSP\n",
+				(unsigned int)delta_bytes);
+			die("Please verify the chipset reserved size\n");
+		}
+#endif
+	}
+
+	/* Verify the FSP 1.1 HOB interface */
+	if (fsp_verification_failure)
+		die("ERROR - Coreboot's requirements not met by FSP binary!\n");
+
+	/* Display the memory configuration */
+	report_memory_config();
+
+	/* Locate the memory configuration data to speed up the next reboot */
+	mrc_hob = get_next_guid_hob(&mrc_guid, hob_list_ptr);
+	if (mrc_hob == NULL)
+		printk(BIOS_DEBUG,
+			"Memory Configuration Data Hob not present\n");
+	else {
+		pei_ptr->data_to_save = GET_GUID_HOB_DATA(mrc_hob);
+		pei_ptr->data_to_save_size = ALIGN(
+			((u32)GET_HOB_LENGTH(mrc_hob)), 16);
+	}
+}
+
+/* Initialize the UPD parameters for MemoryInit */
+__attribute__((weak)) void mainboard_memory_init_params(
+	struct romstage_params *params,
+	MEMORY_INIT_UPD *upd_ptr)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+}
+
+/* Display the UPD parameters for MemoryInit */
+__attribute__((weak)) void soc_display_memory_init_params(
+	const MEMORY_INIT_UPD *old, MEMORY_INIT_UPD *new)
+{
+	printk(BIOS_SPEW, "UPD values for MemoryInit:\n");
+	hexdump32(BIOS_SPEW, new, sizeof(*new));
+}
+
+/* Initialize the UPD parameters for MemoryInit */
+__attribute__((weak)) void soc_memory_init_params(MEMORY_INIT_UPD *params)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+}
diff --git a/src/soc/intel/common/ramstage.h b/src/soc/intel/common/ramstage.h
new file mode 100644
index 0000000..414142a
--- /dev/null
+++ b/src/soc/intel/common/ramstage.h
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright (C) 2015 Intel Corporation.
+ *
+ * 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.
+ */
+
+#ifndef _INTEL_COMMON_RAMSTAGE_H_
+#define _INTEL_COMMON_RAMSTAGE_H_
+
+#include <fsp_util.h>
+#include <soc/intel/common/util.h>
+#include <stdint.h>
+
+/* Perform Intel silicon init. */
+void intel_silicon_init(void);
+/* Called after the silicon init code has run. */
+void soc_after_silicon_init(void);
+/* Initialize UPD data before SiliconInit call. */
+void soc_silicon_init_params(SILICON_INIT_UPD *params);
+void mainboard_silicon_init_params(SILICON_INIT_UPD *params);
+void soc_display_silicon_init_params(const SILICON_INIT_UPD *old,
+	SILICON_INIT_UPD *new);
+void load_vbt(uint8_t s3_resume, SILICON_INIT_UPD *params);
+
+#endif /* _INTEL_COMMON_RAMSTAGE_H_ */
diff --git a/src/soc/intel/common/romstage.c b/src/soc/intel/common/romstage.c
new file mode 100644
index 0000000..adebf51
--- /dev/null
+++ b/src/soc/intel/common/romstage.c
@@ -0,0 +1,447 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015 Intel Corporation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <arch/cpu.h>
+#include <arch/io.h>
+#include <arch/cbfs.h>
+#include <arch/stages.h>
+#include <arch/early_variables.h>
+#include <console/console.h>
+#include <cbmem.h>
+#include <cpu/x86/mtrr.h>
+#include <ec/google/chromeec/ec.h>
+#include <ec/google/chromeec/ec_commands.h>
+#include <elog.h>
+#include <memory_info.h>
+#include <reset.h>
+#include <romstage_handoff.h>
+#include <soc/intel/common/mrc_cache.h>
+#include <soc/intel/common/util.h>
+#include <soc/pei_wrapper.h>
+#include <soc/pm.h>
+#include <soc/romstage.h>
+#include <soc/spi.h>
+#include <stage_cache.h>
+#include <timestamp.h>
+#include <tpm.h>
+#include <vendorcode/google/chromeos/chromeos.h>
+
+/* Entry from cache-as-ram.inc. */
+asmlinkage void *romstage_main(unsigned int bist,
+				uint32_t tsc_low, uint32_t tsc_high,
+				void *chipset_context)
+{
+	void *top_of_stack;
+	struct pei_data pei_data;
+	struct romstage_params params = {
+		.bist = bist,
+		.pei_data = &pei_data,
+		.chipset_context = chipset_context,
+	};
+
+	post_code(0x30);
+
+	/* Save timestamp data */
+	timestamp_init((((uint64_t)tsc_high) << 32) | (uint64_t)tsc_low);
+	timestamp_add_now(TS_START_ROMSTAGE);
+
+	memset(&pei_data, 0, sizeof(pei_data));
+
+	/* Call into pre-console init code. */
+	soc_pre_console_init(&params);
+	mainboard_pre_console_init(&params);
+
+	/* Start console drivers */
+	console_init();
+
+	/* Display parameters */
+	printk(BIOS_SPEW, "bist: 0x%08x\n", bist);
+	printk(BIOS_SPEW, "tsc_low: 0x%08x\n", tsc_low);
+	printk(BIOS_SPEW, "tsc_hi: 0x%08x\n", tsc_high);
+	printk(BIOS_SPEW, "CONFIG_MMCONF_BASE_ADDRESS: 0x%08x\n",
+		CONFIG_MMCONF_BASE_ADDRESS);
+	printk(BIOS_INFO, "Using: %s\n",
+		IS_ENABLED(CONFIG_PLATFORM_USES_FSP1_1) ? "FSP 1.1" :
+		(IS_ENABLED(CONFIG_HAVE_MRC) ? "MRC" :
+		"No Memory Support"));
+
+	/* Display FSP banner */
+	if (IS_ENABLED(CONFIG_PLATFORM_USES_FSP1_1)) {
+		printk(BIOS_DEBUG, "FSP TempRamInit successful\n");
+		print_fsp_info(params.chipset_context);
+	}
+
+	/* Get power state */
+	params.power_state = fill_power_state();
+
+	/* Print useful platform information */
+	report_platform_info();
+
+	/* Set CPU frequency to maximum */
+	set_max_freq();
+
+	/* Perform SOC specific initialization. */
+	soc_romstage_init(&params);
+
+	/* Call into mainboard. */
+	mainboard_romstage_entry(&params);
+	soc_after_ram_init(&params);
+	post_code(0x38);
+
+	top_of_stack = setup_stack_and_mtrrs();
+
+	if (IS_ENABLED(CONFIG_PLATFORM_USES_FSP1_1)) {
+		printk(BIOS_DEBUG, "Calling FspTempRamExit API\n");
+		timestamp_add_now(TS_FSP_TEMP_RAM_EXIT_START);
+	}
+	return top_of_stack;
+}
+
+/* Entry from the mainboard. */
+void romstage_common(struct romstage_params *params)
+{
+	const struct mrc_saved_data *cache;
+	struct romstage_handoff *handoff;
+	struct pei_data *pei_data;
+
+	post_code(0x32);
+
+	timestamp_add_now(TS_BEFORE_INITRAM);
+
+	pei_data = params->pei_data;
+	pei_data->boot_mode = params->power_state->prev_sleep_state;
+
+#if IS_ENABLED(CONFIG_ELOG_BOOT_COUNT)
+	if (params->power_state->prev_sleep_state != SLEEP_STATE_S3)
+		boot_count_increment();
+#endif
+
+	/* Perform remaining SOC initialization */
+	soc_pre_ram_init(params);
+	post_code(0x33);
+
+	/* Check recovery and MRC cache */
+	params->pei_data->saved_data_size = 0;
+	params->pei_data->saved_data = NULL;
+	if (!params->pei_data->disable_saved_data) {
+		if (recovery_mode_enabled()) {
+			/* Recovery mode does not use MRC cache */
+			printk(BIOS_DEBUG,
+			       "Recovery mode: not using MRC cache.\n");
+		} else if (!mrc_cache_get_current(&cache)) {
+			/* MRC cache found */
+			params->pei_data->saved_data_size = cache->size;
+			params->pei_data->saved_data = &cache->data[0];
+		} else if (params->pei_data->boot_mode == SLEEP_STATE_S3) {
+			/* Waking from S3 and no cache. */
+			printk(BIOS_DEBUG,
+			       "No MRC cache found in S3 resume path.\n");
+			post_code(POST_RESUME_FAILURE);
+			hard_reset();
+		} else {
+			printk(BIOS_DEBUG, "No MRC cache found.\n");
+			mainboard_check_ec_image(params);
+		}
+	}
+
+	/* Initialize RAM */
+	raminit(params);
+	timestamp_add_now(TS_AFTER_INITRAM);
+
+	/* Save MRC output */
+	printk(BIOS_DEBUG, "MRC data at %p %d bytes\n", pei_data->data_to_save,
+	       pei_data->data_to_save_size);
+	if (params->pei_data->boot_mode != SLEEP_STATE_S3) {
+		if (params->pei_data->data_to_save_size != 0 &&
+		    params->pei_data->data_to_save != NULL) {
+			mrc_cache_stash_data(params->pei_data->data_to_save,
+				params->pei_data->data_to_save_size);
+		}
+	}
+
+	/* Save DIMM information */
+	mainboard_save_dimm_info(params);
+
+	/* Create romstage handof information */
+	handoff = romstage_handoff_find_or_add();
+	if (handoff != NULL)
+		handoff->s3_resume = (params->power_state->prev_sleep_state ==
+				      SLEEP_STATE_S3);
+	else {
+		printk(BIOS_DEBUG, "Romstage handoff structure not added!\n");
+		hard_reset();
+	}
+
+	if (IS_ENABLED(CONFIG_LPC_TPM))
+		init_tpm(params->power_state->prev_sleep_state == SLEEP_STATE_S3);
+}
+
+asmlinkage void romstage_after_car(void *chipset_context)
+{
+	if (IS_ENABLED(CONFIG_PLATFORM_USES_FSP1_1)) {
+		timestamp_add_now(TS_FSP_TEMP_RAM_EXIT_END);
+		printk(BIOS_DEBUG, "FspTempRamExit returned successfully\n");
+		soc_after_temp_ram_exit();
+		soc_display_mtrrs();
+	}
+
+	timestamp_add_now(TS_END_ROMSTAGE);
+
+	/* Load the ramstage. */
+	copy_and_run();
+	die("ERROR - Failed to load ramstage!");
+}
+
+/* Initialize the power state */
+__attribute__((weak)) struct chipset_power_state *fill_power_state(void)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+	return NULL;
+}
+
+__attribute__((weak)) void mainboard_check_ec_image(
+	struct romstage_params *params)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
+	struct pei_data *pei_data;
+
+	pei_data = params->pei_data;
+	if (params->pei_data->boot_mode == SLEEP_STATE_S0) {
+		/* Ensure EC is running RO firmware. */
+		google_chromeec_check_ec_image(EC_IMAGE_RO);
+	}
+#endif
+}
+
+/* Board initialization before the console is enabled */
+__attribute__((weak)) void mainboard_pre_console_init(
+	struct romstage_params *params)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+}
+
+/* Board initialization before and after RAM is enabled */
+__attribute__((weak)) void mainboard_romstage_entry(
+	struct romstage_params *params)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+
+	post_code(0x31);
+
+	/* Initliaze memory */
+	romstage_common(params);
+}
+
+/* Save the DIMM information for SMBIOS table 17 */
+#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP1_1)
+__attribute__((weak)) void mainboard_save_dimm_info(
+	struct romstage_params *params)
+{
+	int channel;
+	CHANNEL_INFO *channel_info;
+	int dimm;
+	DIMM_INFO *dimm_info;
+	int dimm_max;
+	void *hob_list_ptr;
+	EFI_HOB_GUID_TYPE *hob_ptr;
+	int index;
+	struct memory_info *mem_info;
+	FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
+	const EFI_GUID memory_info_hob_guid = FSP_SMBIOS_MEMORY_INFO_GUID;
+
+	/* Locate the memory info HOB, presence validated by raminit */
+	hob_list_ptr = fsp_get_hob_list();
+	hob_ptr = get_next_guid_hob(&memory_info_hob_guid, hob_list_ptr);
+	memory_info_hob = (FSP_SMBIOS_MEMORY_INFO *)(hob_ptr + 1);
+
+	/* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
+	if (IS_ENABLED(CONFIG_DISPLAY_HOBS)) {
+		printk(BIOS_DEBUG, "FSP_SMBIOS_MEMORY_INFO HOB\n");
+		printk(BIOS_DEBUG, "    0x%02x: Revision\n",
+			memory_info_hob->Revision);
+		printk(BIOS_DEBUG, "    0x%02x: MemoryType\n",
+			memory_info_hob->MemoryType);
+		printk(BIOS_DEBUG, "  0x%04x: MemoryFrequencyInMHz\n",
+			memory_info_hob->MemoryFrequencyInMHz);
+		printk(BIOS_DEBUG, "    0x%02x: ErrorCorrectionType\n",
+			memory_info_hob->ErrorCorrectionType);
+		printk(BIOS_DEBUG, "    0x%02x: ChannelCount\n",
+			memory_info_hob->ChannelCount);
+		for (channel = 0; channel < memory_info_hob->ChannelCount;
+			channel++) {
+			channel_info = &memory_info_hob->ChannelInfo[channel];
+			printk(BIOS_DEBUG, "  Channel %d\n", channel);
+			printk(BIOS_DEBUG, "      0x%02x: ChannelId\n",
+				channel_info->ChannelId);
+			printk(BIOS_DEBUG, "      0x%02x: DimmCount\n",
+				channel_info->DimmCount);
+			for (dimm = 0; dimm < channel_info->DimmCount;
+				dimm++) {
+				dimm_info = &channel_info->DimmInfo[dimm];
+				printk(BIOS_DEBUG, "   DIMM %d\n", dimm);
+				printk(BIOS_DEBUG, "      0x%02x: DimmId\n",
+					dimm_info->DimmId);
+				printk(BIOS_DEBUG, "      0x%02x: SizeInMb\n",
+					dimm_info->SizeInMb);
+			}
+		}
+	}
+
+	/*
+	 * Allocate CBMEM area for DIMM information used to populate SMBIOS
+	 * table 17
+	 */
+	mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
+	printk(BIOS_DEBUG, "CBMEM entry for DIMM info: 0x%p\n", mem_info);
+	if (mem_info == NULL)
+		return;
+	memset(mem_info, 0, sizeof(*mem_info));
+
+	/* Describe the first N DIMMs in the system */
+	index = 0;
+	dimm_max = ARRAY_SIZE(mem_info->dimm);
+	for (channel = 0; channel < memory_info_hob->ChannelCount; channel++) {
+		if (index >= dimm_max)
+			break;
+		channel_info = &memory_info_hob->ChannelInfo[channel];
+		for (dimm = 0; dimm < channel_info->DimmCount; dimm++) {
+			if (index >= dimm_max)
+				break;
+			dimm_info = &channel_info->DimmInfo[dimm];
+
+			/* Populate the DIMM information */
+			if (dimm_info->SizeInMb) {
+				mem_info->dimm[index].dimm_size =
+					dimm_info->SizeInMb;
+				mem_info->dimm[index].ddr_type =
+					memory_info_hob->MemoryType;
+				mem_info->dimm[index].ddr_frequency =
+					memory_info_hob->MemoryFrequencyInMHz;
+				mem_info->dimm[index].channel_num =
+					channel_info->ChannelId;
+				mem_info->dimm[index].dimm_num =
+					dimm_info->DimmId;
+				index++;
+			}
+		}
+	}
+	mem_info->dimm_cnt = index;
+	printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
+}
+#else /* CONFIG_PLATFORM_USES_FSP1_1 */
+__attribute__((weak)) void mainboard_save_dimm_info(
+	struct romstage_params *params)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+}
+#endif /* CONFIG_PLATFORM_USES_FSP1_1 */
+
+/* Get the memory configuration data */
+__attribute__((weak)) int mrc_cache_get_current(
+	const struct mrc_saved_data **cache)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+	return -1;
+}
+
+/* Save the memory configuration data */
+__attribute__((weak)) int mrc_cache_stash_data(void *data, size_t size)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+	return -1;
+}
+
+/* Transition RAM from off or self-refresh to active */
+__attribute__((weak)) void raminit(struct romstage_params *params)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+	post_code(0x34);
+	die("ERROR - No RAM initialization specified!\n");
+}
+
+void ramstage_cache_invalid(void)
+{
+	if (IS_ENABLED(CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE))
+		/* Perform cold reset on invalid ramstage cache. */
+		hard_reset();
+}
+
+/* Display the memory configuration */
+__attribute__((weak)) void report_memory_config(void)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+}
+
+/* Display the platform configuration */
+__attribute__((weak)) void report_platform_info(void)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+}
+
+/* Choose top of stack and setup MTRRs */
+__attribute__((weak)) void *setup_stack_and_mtrrs(void)
+{
+	printk(BIOS_ERR, "WEAK: %s/%s called\n", __FILE__, __func__);
+	die("ERROR - Must specify top of stack!\n");
+	return NULL;
+}
+
+/* Speed up the CPU to the maximum frequency */
+__attribute__((weak)) void set_max_freq(void)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+}
+
+/* SOC initialization after RAM is enabled */
+__attribute__((weak)) void soc_after_ram_init(struct romstage_params *params)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+}
+
+/* SOC initialization after temporary RAM is disabled */
+__attribute__((weak)) void soc_after_temp_ram_exit(void)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+}
+
+/* SOC initialization before the console is enabled */
+__attribute__((weak)) void soc_pre_console_init(struct romstage_params *params)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+}
+
+/* SOC initialization before RAM is enabled */
+__attribute__((weak)) void soc_pre_ram_init(struct romstage_params *params)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+}
+
+/* SOC initialization after console is enabled */
+__attribute__((weak)) void soc_romstage_init(struct romstage_params *params)
+{
+	printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
+#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
+	/* Ensure the EC is in the right mode for recovery */
+	google_chromeec_early_init();
+#endif
+}
diff --git a/src/soc/intel/common/romstage.h b/src/soc/intel/common/romstage.h
new file mode 100644
index 0000000..ac202ae
--- /dev/null
+++ b/src/soc/intel/common/romstage.h
@@ -0,0 +1,103 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ * Copyright (C) 2015 Intel Corporation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _COMMON_ROMSTAGE_H_
+#define _COMMON_ROMSTAGE_H_
+
+#include <stdint.h>
+#include <arch/cpu.h>
+#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP1_1)
+#include <fsp_util.h>
+#endif	/* CONFIG_PLATFORM_USES_FSP1_1 */
+#include <soc/intel/common/util.h>
+#include <soc/pei_data.h>
+#include <soc/pm.h>		/* chip_power_state */
+
+struct romstage_params {
+	unsigned long bist;
+	struct chipset_power_state *power_state;
+	struct pei_data *pei_data;
+	void *chipset_context;
+};
+
+/*
+ * FSP Boot Flow:
+ *   1.  src/cpu/x86/16bit/reset.inc
+ *   2.  src/cpu/x86/16bit/entry.inc
+ *   3.  other modules
+ *   4.  src/drivers/intel/fsp1_1/cache_as_ram.inc
+ *   5.  src/drivers/intel/fsp1_1/fsp_util.c/find_fsp
+ *   6.  FSP binary/TempRamInit
+ *   7.  src/drivers/intel/fsp1_1/cache_as_ram.inc - return
+ *   8.  src/soc/intel/common/romstage.c/romstage_main
+ *   9   src/soc/.../romstage/.../soc_pre_console_init
+ *  10   src/console/console.c/console_init
+ *  11   src/soc/.../romstage/.../soc_romstage_init
+ *  12.  src/mainboard/.../romstage.c/mainboard_romstage_entry
+ *  13.  src/soc/intel/common/romstage.c/romstage_common
+ *  14   src/soc/.../romstage/.../soc_pre_raminit
+ *  15.  FSP binary/MemoryInit
+ *  16.  src/soc/intel/common/romstage.c/romstage_common - return
+ *  17.  src/mainboard/.../romstage.c/mainboard_romstage_entry - return
+ *  18.  src/soc/intel/common/romstage.c/romstage_main - return
+ *  19.  src/soc/intel/common/stack.c/setup_stack_and_mttrs
+ *  20.  src/drivers/intel/fsp1_1/cache_as_ram.inc - return, cleanup
+ *       after call to romstage_main
+ *  21.  FSP binary/TempRamExit
+ *  22.  src/soc/intel/common/romstage.c/romstage_after_car
+ *  23.  FSP binary/SiliconInit
+ *  24.  src/soc/intel/common/romstage.c/romstage_after_car - return
+ *  25.  src/drivers/intel/fsp1_1/fsp_util.c/fsp_notify_boot_state_callback
+ *  26.  src/drivers/intel/fsp1_1/fsp_util.c/fsp_notify
+ *  27.  FSP binary/FspNotify
+ *  28.  src/drivers/intel/fsp1_1/fsp_util.c/fsp_notify_boot_state_callback
+ *  29.  src/drivers/intel/fsp1_1/fsp_util.c/fsp_notify
+ *  30.  FSP binary/FspNotify
+ */
+
+void mainboard_check_ec_image(struct romstage_params *params);
+#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP1_1)
+void mainboard_memory_init_params(struct romstage_params *params,
+	MEMORY_INIT_UPD *memory_params);
+#endif	/* CONFIG_PLATFORM_USES_FSP1_1 */
+void mainboard_pre_console_init(struct romstage_params *params);
+void mainboard_romstage_entry(struct romstage_params *params);
+void mainboard_save_dimm_info(struct romstage_params *params);
+void raminit(struct romstage_params *params);
+void report_memory_config(void);
+void report_platform_info(void);
+asmlinkage void romstage_after_car(void *chipset_context);
+void romstage_common(struct romstage_params *params);
+asmlinkage void *romstage_main(unsigned int bist, uint32_t tsc_lo,
+			       uint32_t tsc_high, void *chipset_context);
+void *setup_stack_and_mtrrs(void);
+void set_max_freq(void);
+void soc_after_ram_init(struct romstage_params *params);
+void soc_after_temp_ram_exit(void);
+#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP1_1)
+void soc_display_memory_init_params(const MEMORY_INIT_UPD *old,
+	MEMORY_INIT_UPD *new);
+void soc_memory_init_params(MEMORY_INIT_UPD *params);
+#endif	/* CONFIG_PLATFORM_USES_FSP1_1 */
+void soc_pre_console_init(struct romstage_params *params);
+void soc_pre_ram_init(struct romstage_params *params);
+void soc_romstage_init(struct romstage_params *params);
+
+#endif /* _COMMON_ROMSTAGE_H_ */
diff --git a/src/soc/intel/common/stack.c b/src/soc/intel/common/stack.c
new file mode 100644
index 0000000..0955b97
--- /dev/null
+++ b/src/soc/intel/common/stack.c
@@ -0,0 +1,183 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015 Intel Corp.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <cbmem.h>
+#include <console/console.h>
+#include <cpu/x86/mtrr.h>
+#include "memmap.h"
+#include "romstage.h"
+#include <soc/intel/common/util.h>
+#include "stack.h"
+#include <stdlib.h>
+
+const unsigned long romstage_ram_stack_size = CONFIG_ROMSTAGE_RAM_STACK_SIZE;
+
+/*
+ * Romstage needs quite a bit of stack for decompressing images since the lzma
+ * lib keeps its state on the stack during romstage.
+ */
+static unsigned long choose_top_of_stack(void)
+{
+	unsigned long stack_top;
+
+	/* cbmem_add() does a find() before add(). */
+	stack_top = (unsigned long)cbmem_add(CBMEM_ID_ROMSTAGE_RAM_STACK,
+					     romstage_ram_stack_size);
+	stack_top += romstage_ram_stack_size;
+	return stack_top;
+}
+
+/*
+ * 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)
+{
+	size_t alignment;
+	uint32_t aligned_ram;
+	uint32_t mtrr_mask_upper;
+	uint32_t max_mtrrs;
+	uint32_t num_mtrrs;
+	uint32_t *slot;
+	unsigned long top_of_stack;
+
+	/* Display the MTTRs */
+	soc_display_mtrrs();
+
+	/* Top of stack needs to be aligned to a 8-byte boundary. */
+	top_of_stack = choose_top_of_stack();
+	slot = (void *)top_of_stack;
+	num_mtrrs = 0;
+	max_mtrrs = soc_get_variable_mtrr_count(NULL);
+
+	/*
+	 * The upper bits of the MTRR mask need to set according to the number
+	 * of physical address bits.
+	 */
+	mtrr_mask_upper = (1 << ((cpuid_eax(0x80000008) & 0xff) - 32)) - 1;
+	alignment = mmap_region_granluarity();
+	aligned_ram = ALIGN_DOWN(top_of_stack - romstage_ram_stack_size,
+		alignment);
+
+	/*
+	 * The order for each MTRR is value then base with upper 32-bits of
+	 * each value coming before the lower 32-bits. The reasoning for
+	 * this ordering is to create a stack layout like the following:
+	 *
+	 *  +36: MTRR mask 1 63:32
+	 *  +32: MTRR mask 1 31:0
+	 *  +28: MTRR base 1 63:32
+	 *  +24: MTRR base 1 31:0
+	 *  +20: MTRR mask 0 63:32
+	 *  +16: MTRR mask 0 31:0
+	 *  +12: MTRR base 0 63:32
+	 *   +8: MTRR base 0 31:0
+	 *   +4: Number of MTRRs to setup (described above)
+	 *   +0: Number of variable MTRRs to clear
+	 */
+
+	/* Cache RAM as WB from 0 -> CONFIG_RAMTOP. */
+	slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */
+	slot = stack_push32(slot, ~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid);
+	slot = stack_push32(slot, 0); /* upper base */
+	slot = stack_push32(slot, 0 | MTRR_TYPE_WRBACK);
+	num_mtrrs++;
+
+	/*
+	 *     +-------------------------+  Top of RAM (aligned)
+	 *     | System Management Mode  |
+	 *     |      code and data      |  Length: CONFIG_TSEG_SIZE
+	 *     |         (TSEG)          |
+	 *     +-------------------------+  SMM base (aligned)
+	 *     |                         |
+	 *     | Chipset Reserved Memory |  Length: Multiple of CONFIG_TSEG_SIZE
+	 *     |                         |
+	 *     +-------------------------+  top_of_ram (aligned)
+	 *     |                         |
+	 *     |       CBMEM Root        |
+	 *     |                         |
+	 *     +-------------------------+
+	 *     |                         |
+	 *     |   FSP Reserved Memory   |
+	 *     |                         |
+	 *     +-------------------------+
+	 *     |                         |
+	 *     |  Various CBMEM Entries  |
+	 *     |                         |
+	 *     +-------------------------+  top_of_stack (8 byte aligned)
+	 *     |                         |
+	 *     |   stack (CBMEM Entry)   |
+	 *     |                         |
+	 *     +-------------------------+
+	 */
+
+	/*
+	 * Cache the stack and the other CBMEM entries as well as part or all
+	 * of the FSP reserved memory region.
+	 */
+	slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */
+	slot = stack_push32(slot, ~(alignment - 1) | MTRRphysMaskValid);
+	slot = stack_push32(slot, 0); /* upper base */
+	slot = stack_push32(slot, aligned_ram | MTRR_TYPE_WRBACK);
+	num_mtrrs++;
+
+#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)
+	void *smm_base;
+	size_t smm_size;
+	uint32_t tseg_base;
+
+	/*
+	 * Cache the TSEG region at the top of ram. This region is not
+	 * restricted to SMM mode until SMM has been relocated. By setting
+	 * the region to cacheable it provides faster access when relocating
+	 * the SMM handler as well as using the TSEG region for other purposes.
+	 */
+	smm_region(&smm_base, &smm_size);
+	tseg_base = (uint32_t)smm_base;
+	slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */
+	slot = stack_push32(slot, ~(alignment - 1) | MTRRphysMaskValid);
+	slot = stack_push32(slot, 0); /* upper base */
+	slot = stack_push32(slot, tseg_base | MTRR_TYPE_WRBACK);
+	num_mtrrs++;
+#endif
+
+	/* Cache the ROM as WP just below 4GiB. */
+	slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */
+	slot = stack_push32(slot, ~(CONFIG_ROM_SIZE - 1) | MTRRphysMaskValid);
+	slot = stack_push32(slot, 0); /* upper base */
+	slot = stack_push32(slot, ~(CONFIG_ROM_SIZE - 1) | MTRR_TYPE_WRPROT);
+	num_mtrrs++;
+
+	/* Validate the MTRR usage */
+	if (num_mtrrs > max_mtrrs) {
+		printk(BIOS_ERR, "MTRRs: max = %d, used = %d, available=%d",
+			max_mtrrs, num_mtrrs, max_mtrrs - num_mtrrs);
+		die("ERROR - MTRR use count incorrect!\n");
+	}
+
+	/*
+	 * Save the number of MTRRs to setup and clear.  Return the stack
+	 * location pointing to the number of MTRRs.
+	 */
+	slot = stack_push32(slot, num_mtrrs);
+	slot = stack_push32(slot, max_mtrrs);
+	return slot;
+}
+
diff --git a/src/soc/intel/common/stack.h b/src/soc/intel/common/stack.h
new file mode 100644
index 0000000..850a070
--- /dev/null
+++ b/src/soc/intel/common/stack.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc
+ * Copyright (C) 2015 Intel Corp.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _COMMON_STACK_H_
+#define _COMMON_STACK_H_
+
+#include <stdint.h>
+
+static inline void *stack_push32(void *stack, uint32_t value)
+{
+	uint32_t *stack32 = stack;
+
+	stack32 = &stack32[-1];
+	*stack32 = value;
+	return stack32;
+}
+
+#endif /* _COMMON_STACK_H_ */
diff --git a/src/soc/intel/common/stage_cache.c b/src/soc/intel/common/stage_cache.c
new file mode 100644
index 0000000..2dd4e47
--- /dev/null
+++ b/src/soc/intel/common/stage_cache.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015 Intel Corp.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <cbmem.h>
+#include <soc/intel/common/memmap.h>
+#include <soc/smm.h>
+#include <stage_cache.h>
+
+void stage_cache_external_region(void **base, size_t *size)
+{
+	char *smm_base;
+	size_t smm_size;
+	const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;
+
+	/*
+	 * The ramstage cache lives in the TSEG region.
+	 * The top of ram is defined to be the TSEG base address.
+	 */
+	smm_region((void **)&smm_base, &smm_size);
+	*size = cache_size;
+	*base = (void *)(&smm_base[smm_size - cache_size]);
+}
diff --git a/src/soc/intel/common/util.c b/src/soc/intel/common/util.c
new file mode 100644
index 0000000..39110a8
--- /dev/null
+++ b/src/soc/intel/common/util.c
@@ -0,0 +1,274 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corporation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/cpu.h>
+#include <console/console.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/mtrr.h>
+#include <soc/intel/common/util.h>
+#include <stddef.h>
+
+void soc_display_upd_value(const char *name, uint32_t size, uint64_t old,
+	uint64_t new)
+{
+	if (old == new) {
+		switch (size) {
+		case 1:
+			printk(BIOS_SPEW, "  0x%02llx: %s\n", new, name);
+			break;
+
+		case 2:
+			printk(BIOS_SPEW, "  0x%04llx: %s\n", new, name);
+			break;
+
+		case 4:
+			printk(BIOS_SPEW, "  0x%08llx: %s\n", new, name);
+			break;
+
+		case 8:
+			printk(BIOS_SPEW, "  0x%016llx: %s\n", new, name);
+			break;
+		}
+	} else {
+		switch (size) {
+		case 1:
+			printk(BIOS_SPEW, "  0x%02llx --> 0x%02llx: %s\n", old,
+				new, name);
+			break;
+
+		case 2:
+			printk(BIOS_SPEW, "  0x%04llx --> 0x%04llx: %s\n", old,
+				new, name);
+			break;
+
+		case 4:
+			printk(BIOS_SPEW, "  0x%08llx --> 0x%08llx: %s\n", old,
+				new, name);
+			break;
+
+		case 8:
+			printk(BIOS_SPEW, "  0x%016llx --> 0x%016llx: %s\n",
+				old, new, name);
+			break;
+		}
+	}
+}
+
+uint32_t soc_get_variable_mtrr_count(uint64_t *msr)
+{
+	union {
+		uint64_t u64;
+		msr_t s;
+	} mttrcap;
+
+	mttrcap.s = rdmsr(MTRRcap_MSR);
+	if (msr != NULL)
+		*msr = mttrcap.u64;
+	return mttrcap.u64 & MTRRcapVcnt;
+}
+
+static const char *soc_display_mtrr_type(uint32_t type)
+{
+	switch (type) {
+	default: return "reserved";
+	case 0: return "UC";
+	case 1: return "WC";
+	case 4: return "WT";
+	case 5: return "WP";
+	case 6: return "WB";
+	case 7: return "UC-";
+	}
+}
+
+static void soc_display_mtrr_fixed_types(uint64_t msr,
+	uint32_t starting_address, uint32_t memory_size)
+{
+	uint32_t base_address;
+	uint32_t index;
+	uint32_t next_address;
+	uint32_t next_type;
+	uint32_t type;
+
+	type = msr & MTRRdefTypeType;
+	base_address = starting_address;
+	next_address = base_address;
+	for (index = 0; index < 64; index += 8) {
+		next_address = starting_address + (memory_size *
+			((index >> 3) + 1));
+		next_type = (msr >> index) & MTRRdefTypeType;
+		if (next_type != type) {
+			printk(BIOS_DEBUG, "    0x%08x - 0x%08x: %s\n",
+				base_address, next_address - 1,
+				soc_display_mtrr_type(type));
+			base_address = next_address;
+			type = next_type;
+		}
+	}
+	if (base_address != next_address)
+		printk(BIOS_DEBUG, "    0x%08x - 0x%08x: %s\n",
+			base_address, next_address - 1,
+			soc_display_mtrr_type(type));
+}
+
+static void soc_display_4k_mtrr(uint32_t msr_reg, uint32_t starting_address,
+	const char *name)
+{
+	union {
+		uint64_t u64;
+		msr_t s;
+	} msr;
+
+	msr.s = rdmsr(msr_reg);
+	printk(BIOS_DEBUG, "0x%016llx: %s\n", msr.u64, name);
+	soc_display_mtrr_fixed_types(msr.u64, starting_address, 0x1000);
+}
+
+static void soc_display_16k_mtrr(uint32_t msr_reg, uint32_t starting_address,
+	const char *name)
+{
+	union {
+		uint64_t u64;
+		msr_t s;
+	} msr;
+
+	msr.s = rdmsr(msr_reg);
+	printk(BIOS_DEBUG, "0x%016llx: %s\n", msr.u64, name);
+	soc_display_mtrr_fixed_types(msr.u64, starting_address, 0x4000);
+}
+
+static void soc_display_64k_mtrr(void)
+{
+	union {
+		uint64_t u64;
+		msr_t s;
+	} msr;
+
+	msr.s = rdmsr(MTRRfix64K_00000_MSR);
+	printk(BIOS_DEBUG, "0x%016llx: IA32_MTRR_FIX64K_00000\n", msr.u64);
+	soc_display_mtrr_fixed_types(msr.u64, 0, 0x10000);
+}
+
+static uint32_t soc_display_mtrrcap(void)
+{
+	uint64_t msr;
+	uint32_t variable_mtrrs;
+
+	variable_mtrrs = soc_get_variable_mtrr_count(&msr);
+	printk(BIOS_DEBUG,
+		"0x%016llx: IA32_MTRRCAP: %s%s%s%d variable MTRRs\n",
+		msr,
+		(msr & MTRRcapSmrr) ? "SMRR, " : "",
+		(msr & MTRRcapWc) ? "WC, " : "",
+		(msr & MTRRcapFix) ? "FIX, " : "",
+		variable_mtrrs);
+	return variable_mtrrs;
+}
+
+static void soc_display_mtrr_def_type(void)
+{
+	union {
+		uint64_t u64;
+		msr_t s;
+	} msr;
+
+	msr.s = rdmsr(MTRRdefType_MSR);
+	printk(BIOS_DEBUG, "0x%016llx: IA32_MTRR_DEF_TYPE:%s%s %s\n",
+		msr.u64,
+		(msr.u64 & MTRRdefTypeEn) ? " E," : "",
+		(msr.u64 & MTRRdefTypeFixEn) ? " FE," : "",
+		soc_display_mtrr_type((uint32_t)(msr.u64 & MTRRdefTypeType)));
+}
+
+static void soc_display_variable_mtrr(uint32_t msr_reg, int index,
+	uint64_t address_mask)
+{
+	uint64_t base_address;
+	uint64_t length;
+	uint64_t mask;
+	union {
+		uint64_t u64;
+		msr_t s;
+	} msr_a;
+	union {
+		uint64_t u64;
+		msr_t s;
+	} msr_m;
+
+	msr_a.s = rdmsr(msr_reg);
+	msr_m.s = rdmsr(msr_reg + 1);
+	if (msr_m.u64 & MTRRphysMaskValid) {
+		base_address = (msr_a.u64 & 0xfffffffffffff000ULL)
+			& address_mask;
+		printk(BIOS_DEBUG,
+			"0x%016llx: PHYBASE%d: Address = 0x%016llx, %s\n",
+			msr_a.u64, index, base_address,
+			soc_display_mtrr_type(msr_a.u64 & MTRRdefTypeType));
+		mask = (msr_m.u64 & 0xfffffffffffff000ULL) & address_mask;
+		length = (~mask & address_mask) + 1;
+		printk(BIOS_DEBUG,
+			"0x%016llx: PHYMASK%d: Length  = 0x%016llx, Valid\n",
+			msr_m.u64, index, length);
+	} else {
+		printk(BIOS_DEBUG, "0x%016llx: PHYBASE%d\n", msr_a.u64, index);
+		printk(BIOS_DEBUG, "0x%016llx: PHYMASK%d: Disabled\n",
+			msr_m.u64, index);
+	}
+}
+
+asmlinkage void soc_display_mtrrs(void)
+{
+	if (IS_ENABLED(CONFIG_DISPLAY_MTRRS)) {
+		uint32_t address_bits;
+		uint64_t address_mask;
+		int i;
+		int variable_mtrrs;
+
+		/* Display the fixed MTRRs */
+		variable_mtrrs = soc_display_mtrrcap();
+		soc_display_mtrr_def_type();
+		soc_display_64k_mtrr();
+		soc_display_16k_mtrr(MTRRfix16K_80000_MSR, 0x80000,
+			"IA32_MTRR_FIX16K_80000");
+		soc_display_16k_mtrr(MTRRfix16K_A0000_MSR, 0xa0000,
+			"IA32_MTRR_FIX16K_A0000");
+		soc_display_4k_mtrr(MTRRfix4K_C0000_MSR, 0xc0000,
+			"IA32_MTRR_FIX4K_C0000");
+		soc_display_4k_mtrr(MTRRfix4K_C8000_MSR, 0xc8000,
+			"IA32_MTRR_FIX4K_C8000");
+		soc_display_4k_mtrr(MTRRfix4K_D0000_MSR, 0xd0000,
+			"IA32_MTRR_FIX4K_D0000");
+		soc_display_4k_mtrr(MTRRfix4K_D8000_MSR, 0xd8000,
+			"IA32_MTRR_FIX4K_D8000");
+		soc_display_4k_mtrr(MTRRfix4K_E0000_MSR, 0xe0000,
+			"IA32_MTRR_FIX4K_E0000");
+		soc_display_4k_mtrr(MTRRfix4K_E8000_MSR, 0xe8000,
+			"IA32_MTRR_FIX4K_E8000");
+		soc_display_4k_mtrr(MTRRfix4K_F0000_MSR, 0xf0000,
+			"IA32_MTRR_FIX4K_F0000");
+		soc_display_4k_mtrr(MTRRfix4K_F8000_MSR, 0xf8000,
+			"IA32_MTRR_FIX4K_F8000");
+		address_bits = cpu_phys_address_size();
+		address_mask = (1ULL << address_bits) - 1;
+
+		/* Display the variable MTRRs */
+		for (i = 0; i < variable_mtrrs; i++)
+			soc_display_variable_mtrr(MTRRphysBase_MSR(i), i,
+				address_mask);
+	}
+}
diff --git a/src/soc/intel/common/util.h b/src/soc/intel/common/util.h
new file mode 100644
index 0000000..db2b0ef
--- /dev/null
+++ b/src/soc/intel/common/util.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corporation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _INTEL_COMMON_UTIL_H_
+#define _INTEL_COMMON_UTIL_H_
+
+#include <arch/cpu.h>
+#include <stdint.h>
+
+asmlinkage void soc_display_mtrrs(void);
+void soc_display_upd_value(const char *name, uint32_t size, uint64_t old,
+	uint64_t new);
+uint32_t soc_get_variable_mtrr_count(uint64_t *msr);
+
+#endif /* _INTEL_COMMON_UTIL_H_ */
diff --git a/src/soc/intel/common/vbt.c b/src/soc/intel/common/vbt.c
new file mode 100644
index 0000000..302a4a6
--- /dev/null
+++ b/src/soc/intel/common/vbt.c
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Google Inc.
+ * Copyright (C) 2015 Intel Corp.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <cbfs.h>
+#include <console/console.h>
+#include <fsp_util.h>
+#include <lib.h>
+#include <soc/intel/common/ramstage.h>
+#include <string.h>
+
+/* Locate VBT and pass it to FSP GOP */
+void load_vbt(uint8_t s3_resume, SILICON_INIT_UPD *params)
+{
+	const optionrom_vbt_t *vbt_data;
+	uint32_t vbt_len;
+
+	/* Check boot mode - for S3 resume path VBT loading is not needed */
+	if (s3_resume) {
+		vbt_data = NULL;
+		printk(BIOS_DEBUG, "S3 resume do not pass VBT to GOP\n");
+	} else {
+		/* Get VBT data */
+		vbt_data = fsp_get_vbt(&vbt_len);
+		if (vbt_data != NULL)
+			printk(BIOS_DEBUG, "Passing VBT to GOP\n");
+		else
+			printk(BIOS_DEBUG, "VBT not found!\n");
+	}
+	params->PcdGraphicsConfigPtr = (u32)vbt_data;
+}



More information about the coreboot-gerrit mailing list