Martin Roth (martin.roth(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5635
-gerrit
commit 8989431e3ffada3449c627a485768390a6281c03
Author: Martin Roth <gaumless(a)gmail.com>
Date: Fri Apr 25 14:12:13 2014 -0600
Intel FSP: add a shared set of functions for the FSP
- Move the non chipset-specific fsp pieces out of the chipset into a
shared area. This is used by northbridge / southbrige / SOC code. It
pulls in pieces from Kconfig, Makefile and FSP specific code.
- Enabled in the CPU code with a Kconfig "select PLATFORM_USES_FSP"
Change-Id: I7ffa934c1df09b71d48a876a56e3b888685870b8
Signed-off-by: Martin Roth <gaumless(a)gmail.com>
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
---
src/Kconfig | 1 +
src/cpu/x86/Kconfig | 7 +
src/drivers/intel/Makefile.inc | 1 +
src/drivers/intel/fsp/Kconfig | 143 +++++++++++
src/drivers/intel/fsp/Makefile.inc | 48 ++++
src/drivers/intel/fsp/cache_as_ram.inc | 169 +++++++++++++
src/drivers/intel/fsp/fastboot_cache.c | 253 +++++++++++++++++++
src/drivers/intel/fsp/fsp_util.c | 432 +++++++++++++++++++++++++++++++++
src/drivers/intel/fsp/fsp_util.h | 95 ++++++++
src/include/timestamp.h | 4 +
10 files changed, 1153 insertions(+)
diff --git a/src/Kconfig b/src/Kconfig
index 849e55d..48e688f 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -256,6 +256,7 @@ comment "Embedded Controllers"
source src/ec/Kconfig
comment "SoC"
source src/soc/Kconfig
+source src/drivers/intel/fsp/Kconfig
endmenu
diff --git a/src/cpu/x86/Kconfig b/src/cpu/x86/Kconfig
index b5bb7e6..5c37861 100644
--- a/src/cpu/x86/Kconfig
+++ b/src/cpu/x86/Kconfig
@@ -109,6 +109,13 @@ config X86_AMD_FIXED_MTRRS
This option informs the MTRR code to use the RdMem and WrMem fields
in the fixed MTRR MSRs.
+config PLATFORM_USES_FSP
+ bool
+ default n
+ help
+ Selected for Intel processors/platform combinations that use the
+ Intel Firmware Support Package (FSP) for initialization.
+
config PARALLEL_MP
def_bool n
help
diff --git a/src/drivers/intel/Makefile.inc b/src/drivers/intel/Makefile.inc
index eb8617c..12f7003 100644
--- a/src/drivers/intel/Makefile.inc
+++ b/src/drivers/intel/Makefile.inc
@@ -1 +1,2 @@
subdirs-y += gma
+subdirs-$(CONFIG_PLATFORM_USES_FSP) += fsp
diff --git a/src/drivers/intel/fsp/Kconfig b/src/drivers/intel/fsp/Kconfig
new file mode 100644
index 0000000..3e16266
--- /dev/null
+++ b/src/drivers/intel/fsp/Kconfig
@@ -0,0 +1,143 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 Sage Electronic Engineering, LLC.
+##
+## 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
+##
+
+if PLATFORM_USES_FSP
+
+comment "Intel FSP"
+
+config HAVE_FSP_BIN
+ bool "Use Intel Firmware Support Package"
+ help
+ Select this option to add an Intel FSP binary to
+ the resulting coreboot image.
+
+ Note: Without this binary, coreboot builds relying on the FSP
+ will not boot
+
+config DCACHE_RAM_BASE
+ hex
+ default 0xfef00000
+
+config DCACHE_RAM_SIZE
+ hex
+ default 0x4000
+
+if HAVE_FSP_BIN
+
+config FSP_FILE
+ string "Intel FSP binary path and filename"
+ help
+ The path and filename of the Intel FSP binary for this platform.
+
+config FSP_LOC
+ hex "Intel FSP Binary location in CBFS"
+ help
+ The location in CBFS that the FSP is located. This must match the
+ value that is set in the FSP binary. If the FSP needs to be moved,
+ rebase the FSP with Intel's BCT (tool).
+
+config ENABLE_FSP_FAST_BOOT
+ bool "Enable Fast Boot"
+ default n
+ help
+ Enabling this feature will force the MRC data to be cached in NV
+ storage to be used for speeding up boot time on future reboots
+ and/or power cycles.
+
+config ENABLE_MRC_CACHE
+ bool
+ default ENABLE_FSP_FAST_BOOT
+ help
+ Enabling this feature will cause MRC data to be cached in NV storage.
+ This can either be used for fast boot, or just because the FSP wants
+ it to be saved.
+
+config MRC_CACHE_SIZE
+ hex "Fast Boot Data Cache Size"
+ default 0x10000
+ depends on ENABLE_MRC_CACHE
+ help
+ This is the amount of space in NV storage that is reserved for the
+ fast boot data cache storage.
+
+ WARNING: Because this area will be erased and re-written, the size
+ should be a full sector of the flash ROM chip and nothing else should
+ be included in CBFS in any sector that the fast boot cache data is in.
+
+config OVERRIDE_CACHE_CACHE_LOC
+ bool
+ help
+ Selected by the platform to set a new default location for the
+ MRC/fast boot cache.
+
+config MRC_CACHE_LOC_OVERRIDE
+ hex
+ help
+ Sets the override CBFS location of the MRC/fast boot cache.
+
+config MRC_CACHE_LOC
+ hex "Fast Boot Data Cache location in CBFS"
+ default MRC_CACHE_LOC_OVERRIDE if OVERRIDE_CACHE_CACHE_LOC
+ default 0xfff50000
+ depends on ENABLE_MRC_CACHE
+ help
+ The location in CBFS for the MRC data to be cached.
+
+ WARNING: This should be on a sector boundary of the BIOS ROM chip
+ and nothing else should be included in that sector, or IT WILL BE
+ ERASED.
+
+config VIRTUAL_ROM_SIZE
+ hex "Virtual ROM Size"
+ default ROM_SIZE
+ depends on ENABLE_MRC_CACHE
+ help
+ This is used to calculate the offset of the MRC data cache in NV
+ Storage for fast boot. If in doubt, leave this set to the default
+ which sets the virtual size equal to the ROM size.
+
+ Example: Cougar Canyon 2 has two 8 MB SPI ROMs. When the SPI ROMs are
+ loaded with a 4 MB coreboot image, the virtual ROM size is 8 MB. When
+ the SPI ROMs are loaded with an 8 MB coreboot image, the virtual ROM
+ size is 16 MB.
+
+endif #HAVE_FSP_BIN
+
+config CACHE_ROM_SIZE_OVERRIDE
+ hex "Cache ROM Size"
+ default CBFS_SIZE
+ help
+ This is the size of the cachable area that is passed into the FSP in
+ the early initialization. Typically this should be the size of the CBFS
+ area, but the size must be a power of 2 whereas the CBFS size does not
+ have this limitation.
+
+config USE_GENERIC_FSP_CAR_INC
+ bool
+ default n
+ help
+ The chipset can select this to use a generic cache_as_ram.inc file
+ that should be good for all FSP based platforms.
+
+config FSP_USES_UPD
+ bool
+ default n
+ help
+ If this FSP uses UPD/VPD data regions, select this in the chipset Kconfig.
+endif #PLATFORM_USES_FSP
diff --git a/src/drivers/intel/fsp/Makefile.inc b/src/drivers/intel/fsp/Makefile.inc
new file mode 100644
index 0000000..9e083ec
--- /dev/null
+++ b/src/drivers/intel/fsp/Makefile.inc
@@ -0,0 +1,48 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2014 Sage Electronic Engineering, LLC.
+#
+# 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
+#
+
+ramstage-y += fsp_util.c
+romstage-y += fsp_util.c
+ramstage-$(CONFIG_ENABLE_MRC_CACHE) += fastboot_cache.c
+romstage-$(CONFIG_ENABLE_MRC_CACHE) += fastboot_cache.c
+
+INCLUDES += -Isrc/drivers/intel/fsp
+
+ifeq ($(CONFIG_USE_GENERIC_FSP_CAR_INC),y)
+cpu_incs += $(src)/drivers/intel/fsp/cache_as_ram.inc
+endif
+
+ifeq ($(CONFIG_HAVE_FSP_BIN),y)
+cbfs-files-y += fsp.bin
+fsp.bin-file := $(call strip_quotes,$(CONFIG_FSP_FILE))
+fsp.bin-position := $(CONFIG_FSP_LOC)
+fsp.bin-type := 0xab
+endif
+
+ifeq ($(CONFIG_ENABLE_MRC_CACHE),y)
+$(obj)/mrc.cache:
+ dd if=/dev/zero count=1 \
+ bs=$(shell printf "%d" $(CONFIG_MRC_CACHE_SIZE) ) | \
+ tr '\000' '\377' > $@
+
+cbfs-files-y += mrc.cache
+mrc.cache-file := $(obj)/mrc.cache
+mrc.cache-position := $(CONFIG_MRC_CACHE_LOC)
+mrc.cache-type := 0xac
+endif
diff --git a/src/drivers/intel/fsp/cache_as_ram.inc b/src/drivers/intel/fsp/cache_as_ram.inc
new file mode 100644
index 0000000..40787b5
--- /dev/null
+++ b/src/drivers/intel/fsp/cache_as_ram.inc
@@ -0,0 +1,169 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich(a)gmail.com>
+ * Copyright (C) 2007-2008 coresystems GmbH
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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 <cpu/x86/stack.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/post_code.h>
+#include <cbmem.h>
+
+#ifndef CONFIG_FSP_LOC
+# error "CONFIG_FSP_LOC must be set."
+#endif
+
+#ifndef CONFIG_POST_IO
+# error "CONFIG_POST_IO must be set."
+#endif
+
+#if CONFIG_POST_IO
+# ifndef CONFIG_POST_IO_PORT
+# error "CONFIG_POST_IO_PORT must be set."
+# endif
+#endif
+
+#ifndef CONFIG_CPU_MICROCODE_CBFS_LOC
+# error "CONFIG_CPU_MICROCODE_CBFS_LOC must be set."
+#endif
+
+#define LHLT_DELAY 0x50000 /* I/O delay between post codes on failure */
+
+ cmp $0, %eax
+ jne bisthalt
+
+cache_as_ram:
+ post_code(0x20)
+
+ /*
+ * Find the FSP binary in cbfs.
+ * Make a fake stack that has the return value back to this code.
+ */
+ lea fake_fsp_stack, %esp
+ jmp find_fsp
+find_fsp_ret:
+ /* Save the FSP location */
+ mov %eax, %ebp
+ cmp $CONFIG_FSP_LOC, %eax
+ jb halt1
+
+ post_code(0x22)
+
+ /* Calculate entry into FSP */
+ mov 0x30(%ebp), %eax /* Load TempRamInitEntry */
+ add 0x1c(%ebp), %eax /* add in the offset for the FSP base address */
+
+ /*
+ * Pass early init variables on a fake stack (no memory yet)
+ * as well as the return location
+ */
+ lea CAR_init_stack, %esp
+
+ /* call FSP binary to setup temporary stack */
+ jmp *%eax
+
+CAR_init_done:
+ addl $4, %esp
+ cmp $0, %eax
+ jne halt2
+
+ /* Save FSP_INFO_HEADER location in ebx */
+ mov %ebp, %ebx
+
+ /*
+ * set up bootloader stack
+ * ecx: stack base
+ * edx: stack top
+ */
+ lea -4(%edx), %esp
+ movl %esp, %ebp
+ pushl %ebx
+
+before_romstage:
+ post_code(0x23)
+
+ /* Call romstage.c main function. */
+ call main /* does not return */
+ movb $0xB8, %ah
+ jmp .Lhlt
+
+bisthalt:
+ movb $0xB9, %ah
+ jmp .Lhlt
+
+halt1:
+ /*
+ * Failures for postcode 0xBA - failed in find_fsp()
+ *
+ * Values are:
+ * 0x01 - FV signature, "_FVH" not present
+ * 0x02 - FFS GUID not present
+ * 0x03 - FSP INFO Header not found
+ * 0x04 - ImageBase does not equal CONFIG_FSP_LOC - Is the FSP rebased to
+ * a different location, or does it need to be?
+ * 0x05 - FSP INFO Header signature "FSPH" not found
+ * 0x06 - FSP Image ID is not the expected ID.
+ */
+ movb $0xBA, %ah
+ jmp .Lhlt
+
+halt2:
+ /*
+ * Failures for postcode 0xBB - failed in the FSP:
+ *
+ * 0x00 - FSP_SUCCESS: Temp RAM was initialized successfully.
+ * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid.
+ * 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode region.
+ * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
+ * 0x07 - FSP_DEVICE_ERROR: Temp RAM initialization failed
+ * 0x14 - FSP_ALREADY_STARTED: Temp RAM initialization has been invoked
+ */
+ movb $0xBB, %ah
+
+.Lhlt:
+ xchg %al, %ah
+#if CONFIG_POST_IO
+ outb %al, $CONFIG_POST_IO_PORT
+#else
+ post_code(POST_DEAD_CODE)
+#endif
+ movl $LHLT_DELAY, %ecx
+.Lhlt_Delay:
+ outb %al, $0xED
+ loop .Lhlt_Delay
+ jmp .Lhlt
+
+/*
+ * esp is set to this location so that the call into and return from the FSP
+ * in find_fsp will work.
+ */
+ .align 4
+fake_fsp_stack:
+ .long find_fsp_ret
+
+CAR_init_params:
+ .long CONFIG_CPU_MICROCODE_CBFS_LOC
+ .long CONFIG_CPU_MICROCODE_CBFS_LEN
+ .long 0xFFFFFFFF - CACHE_ROM_SIZE + 1 /* Firmware Location */
+ .long CACHE_ROM_SIZE /* Total Firmware Length */
+
+CAR_init_stack:
+ .long CAR_init_done
+ .long CAR_init_params
+
diff --git a/src/drivers/intel/fsp/fastboot_cache.c b/src/drivers/intel/fsp/fastboot_cache.c
new file mode 100644
index 0000000..b9a6e33
--- /dev/null
+++ b/src/drivers/intel/fsp/fastboot_cache.c
@@ -0,0 +1,253 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Google Inc.
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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 <stdint.h>
+#include <string.h>
+#include <bootstate.h>
+#include <console/console.h>
+#include <cbfs.h>
+#include <ip_checksum.h>
+#include <device/device.h>
+#include <cbmem.h>
+#include <spi-generic.h>
+#include <spi_flash.h>
+#include <lib.h> // hexdump
+#include "fsp_util.h"
+
+#ifndef CONFIG_VIRTUAL_ROM_SIZE
+#error "CONFIG_VIRTUAL_ROM_SIZE must be set."
+#endif
+
+/* convert a pointer to flash area into the offset inside the flash */
+static inline u32 to_flash_offset(void *p) {
+ return ((u32)p + CONFIG_VIRTUAL_ROM_SIZE);
+}
+
+static struct mrc_data_container *next_mrc_block(
+ struct mrc_data_container *mrc_cache)
+{
+ /* MRC data blocks are aligned within the region */
+ u32 mrc_size = sizeof(*mrc_cache) + mrc_cache->mrc_data_size;
+ if (mrc_size & (MRC_DATA_ALIGN - 1UL)) {
+ mrc_size &= ~(MRC_DATA_ALIGN - 1UL);
+ mrc_size += MRC_DATA_ALIGN;
+ }
+
+ u8 *region_ptr = (u8*)mrc_cache;
+ region_ptr += mrc_size;
+ return (struct mrc_data_container *)region_ptr;
+}
+
+static int is_mrc_cache(struct mrc_data_container *mrc_cache)
+{
+ return (!!mrc_cache) && (mrc_cache->mrc_signature == MRC_DATA_SIGNATURE);
+}
+
+static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr)
+{
+ size_t region_size;
+ *mrc_region_ptr = cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
+ "mrc.cache", 0xac,
+ ®ion_size);
+
+ return region_size;
+}
+
+/*
+ * Find the largest index block in the MRC cache. Return NULL if none is
+ * found.
+ */
+static struct mrc_data_container *find_current_mrc_cache_local
+ (struct mrc_data_container *mrc_cache, u32 region_size)
+{
+ u32 region_end;
+ u32 entry_id = 0;
+ struct mrc_data_container *mrc_next = mrc_cache;
+
+ region_end = (u32) mrc_cache + region_size;
+
+ /* Search for the last filled entry in the region */
+ while (is_mrc_cache(mrc_next)) {
+ entry_id++;
+ mrc_cache = mrc_next;
+ mrc_next = next_mrc_block(mrc_next);
+ if ((u32)mrc_next >= region_end) {
+ /* Stay in the MRC data region */
+ break;
+ }
+ }
+
+ if (entry_id == 0) {
+ printk(BIOS_ERR, "%s: No valid fast boot cache found.\n", __func__);
+ return NULL;
+ }
+
+ /* Verify checksum */
+ if (mrc_cache->mrc_checksum !=
+ compute_ip_checksum(mrc_cache->mrc_data,
+ mrc_cache->mrc_data_size)) {
+ printk(BIOS_ERR, "%s: fast boot cache checksum mismatch\n", __func__);
+ return NULL;
+ }
+
+ printk(BIOS_DEBUG, "%s: picked entry %u from cache block\n", __func__,
+ entry_id - 1);
+
+ return mrc_cache;
+}
+
+/* SPI code needs malloc/free.
+ * Also unknown if writing flash from XIP-flash code is a good idea
+ */
+#if !defined(__PRE_RAM__)
+/* find the first empty block in the MRC cache area.
+ * If there's none, return NULL.
+ *
+ * @mrc_cache_base - base address of the MRC cache area
+ * @mrc_cache - current entry (for which we need to find next)
+ * @region_size - total size of the MRC cache area
+ */
+static struct mrc_data_container *find_next_mrc_cache
+ (struct mrc_data_container *mrc_cache_base,
+ struct mrc_data_container *mrc_cache,
+ u32 region_size)
+{
+ u32 region_end = (u32) mrc_cache_base + region_size;
+ u32 mrc_data_size = mrc_cache->mrc_data_size;
+
+ mrc_cache = next_mrc_block(mrc_cache);
+ if (((u32)mrc_cache + mrc_data_size) >= region_end) {
+ /* Crossed the boundary */
+ mrc_cache = NULL;
+ printk(BIOS_DEBUG, "%s: no available entries found\n",
+ __func__);
+ } else {
+ printk(BIOS_DEBUG,
+ "%s: picked next entry from cache block at %p\n",
+ __func__, mrc_cache);
+ }
+
+ return mrc_cache;
+}
+
+void update_mrc_cache(void *unused)
+{
+ printk(BIOS_DEBUG, "Updating fast boot cache data.\n");
+ struct mrc_data_container *current = cbmem_find(CBMEM_ID_MRCDATA);
+ struct mrc_data_container *cache, *cache_base;
+ u32 cache_size;
+
+ if (!current) {
+ printk(BIOS_ERR, "No fast boot cache in cbmem. Can't update flash.\n");
+ return;
+ }
+ if (current->mrc_data_size == -1) {
+ printk(BIOS_ERR, "Fast boot cache data in cbmem invalid.\n");
+ return;
+ }
+
+ cache_size = get_mrc_cache_region(&cache_base);
+ if (cache_base == NULL) {
+ printk(BIOS_ERR, "%s: could not find fast boot cache area\n",
+ __func__);
+ return;
+ }
+
+ /*
+ * we need to:
+ * 0. compare MRC data to last mrc-cache block (exit if same)
+ */
+ cache = find_current_mrc_cache_local(cache_base, cache_size);
+
+ if (cache && (cache->mrc_data_size == current->mrc_data_size) &&
+ (memcmp(cache, current, cache->mrc_data_size) == 0)) {
+ printk(BIOS_DEBUG,
+ "MRC data in flash is up to date. No update.\n");
+ return;
+ }
+
+ /* 1. use spi_flash_probe() to find the flash, then... */
+ spi_init();
+ struct spi_flash *flash = spi_flash_probe(0, 0, 1000000, SPI_MODE_3);
+ if (!flash) {
+ printk(BIOS_DEBUG, "Could not find SPI device\n");
+ return;
+ }
+
+ /* 2. look up the first unused block */
+ if (cache)
+ cache = find_next_mrc_cache(cache_base, cache, cache_size);
+
+ /*
+ * 3. if no such place exists, erase entire mrc-cache range & use
+ * block 0. First time around the erase is not needed, but this is a
+ * small overhead for simpler code.
+ */
+ if (!cache) {
+ printk(BIOS_DEBUG,
+ "Need to erase the MRC cache region of %d bytes at %p\n",
+ cache_size, cache_base);
+
+ flash->erase(flash, to_flash_offset(cache_base), cache_size);
+
+ /* we will start at the beginning again */
+ cache = cache_base;
+ }
+ /* 4. write mrc data with flash->write() */
+ printk(BIOS_DEBUG, "Write MRC cache update to flash at %p\n",
+ cache);
+ flash->write(flash, to_flash_offset(cache),
+ current->mrc_data_size + sizeof(*current), current);
+}
+
+#endif /* !defined(__PRE_RAM__) */
+
+void * find_and_set_fastboot_cache(void)
+{
+ struct mrc_data_container *mrc_cache = NULL;
+ if (((mrc_cache = find_current_mrc_cache()) == NULL) ||
+ (mrc_cache->mrc_data_size == -1UL)) {
+ printk(BIOS_DEBUG, "FSP MRC cache not present.\n");
+ return NULL;
+ }
+ printk(BIOS_DEBUG, "FSP MRC cache present at %x.\n", (u32)mrc_cache);
+ printk(BIOS_SPEW, "Saved MRC data:\n");
+ hexdump32(BIOS_SPEW, (void *)mrc_cache->mrc_data, mrc_cache->mrc_data_size);
+ return (void *) mrc_cache->mrc_data;
+}
+
+struct mrc_data_container *find_current_mrc_cache(void)
+{
+ struct mrc_data_container *cache_base;
+ u32 cache_size;
+
+ cache_size = get_mrc_cache_region(&cache_base);
+ if (cache_base == NULL) {
+ printk(BIOS_ERR, "%s: could not find fast boot cache area\n",
+ __func__);
+ return NULL;
+ }
+
+ /*
+ * we need to:
+ * 0. compare MRC data to last mrc-cache block (exit if same)
+ */
+ return find_current_mrc_cache_local(cache_base, cache_size);
+}
diff --git a/src/drivers/intel/fsp/fsp_util.c b/src/drivers/intel/fsp/fsp_util.c
new file mode 100644
index 0000000..4e1db6b
--- /dev/null
+++ b/src/drivers/intel/fsp/fsp_util.c
@@ -0,0 +1,432 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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 <types.h>
+#include <string.h>
+#include <cpu/x86/stack.h>
+#include <console/console.h>
+#include <bootstate.h>
+#include <cbmem.h>
+#include "fsp_util.h"
+#include <lib.h> // hexdump
+#include <ip_checksum.h>
+#include <timestamp.h>
+
+#ifndef __PRE_RAM__
+/* Globals pointers for FSP structures */
+void *FspHobListPtr = NULL;
+FSP_INFO_HEADER *fsp_header_ptr = NULL;
+
+void FspNotify (u32 Phase)
+{
+ FSP_NOTFY_PHASE NotifyPhaseProc;
+ NOTIFY_PHASE_PARAMS NotifyPhaseParams;
+ EFI_STATUS Status;
+
+ if (fsp_header_ptr == NULL) {
+ fsp_header_ptr = (void *)find_fsp();
+ if ((u32)fsp_header_ptr < 0xff) {
+ post_code(0x4F); /* output something in case there is no serial */
+ die("Can't find the FSP!\n");
+ }
+ }
+
+ /* call FSP PEI to Notify PostPciEnumeration */
+ NotifyPhaseProc = (FSP_NOTFY_PHASE)(fsp_header_ptr->ImageBase +
+ fsp_header_ptr->NotifyPhaseEntry);
+ NotifyPhaseParams.Phase = Phase;
+
+ timestamp_add_now(Phase == EnumInitPhaseReadyToBoot ?
+ TS_FSP_BEFORE_FINALIZE : TS_FSP_BEFORE_ENUMERATE);
+
+ Status = NotifyPhaseProc (&NotifyPhaseParams);
+
+ timestamp_add_now(Phase == EnumInitPhaseReadyToBoot ?
+ TS_FSP_AFTER_FINALIZE : TS_FSP_AFTER_ENUMERATE);
+
+ if (Status != 0)
+ printk(BIOS_ERR,"FSP API NotifyPhase failed for phase 0x%x with status: 0x%x\n", Phase, Status);
+}
+#endif /* #ifndef __PRE_RAM__ */
+
+#ifdef __PRE_RAM__
+
+/*
+ * Call the FSP to do memory init. The FSP doesn't return to this function.
+ * The FSP returns to the romstage_main_continue().
+ */
+void __attribute__ ((noreturn)) fsp_early_init (FSP_INFO_HEADER *fsp_ptr)
+{
+ FSP_FSP_INIT FspInitApi;
+ FSP_INIT_PARAMS FspInitParams;
+ FSP_INIT_RT_BUFFER FspRtBuffer;
+#if IS_ENABLED(CONFIG_FSP_USES_UPD)
+ UPD_DATA_REGION fsp_upd_data;
+#endif
+
+ memset((void*)&FspRtBuffer, 0, sizeof(FSP_INIT_RT_BUFFER));
+ FspRtBuffer.Common.StackTop = (u32 *)ROMSTAGE_STACK;
+ FspInitParams.NvsBufferPtr = NULL;
+
+#if IS_ENABLED(CONFIG_FSP_USES_UPD)
+ FspRtBuffer.Common.UpdDataRgnPtr = &fsp_upd_data;
+#endif
+ FspInitParams.RtBufferPtr = (FSP_INIT_RT_BUFFER *)&FspRtBuffer;
+ FspInitParams.ContinuationFunc = (CONTINUATION_PROC)ChipsetFspReturnPoint;
+ FspInitApi = (FSP_FSP_INIT)(fsp_ptr->ImageBase + fsp_ptr->FspInitEntry);
+
+ /* Call the chipset code to fill in the chipset specific structures */
+ chipset_fsp_early_init(&FspInitParams, fsp_ptr);
+
+ /* Call back to romstage for board specific changes */
+ romstage_fsp_rt_buffer_callback(&FspRtBuffer);
+
+ FspInitApi(&FspInitParams);
+
+ /* Should never return. Control will continue from ContinuationFunc */
+ die("Uh Oh! FspInitApi returned");
+}
+#endif /* __PRE_RAM__ */
+
+volatile u8 * __attribute__((optimize("O0"))) find_fsp ()
+{
+
+#ifdef __PRE_RAM__
+ volatile register u8 *fsp_ptr asm ("eax");
+
+ /* Entry point for CAR assembly routine */
+ __asm__ __volatile__ (
+ ".global find_fsp\n\t"
+ "find_fsp:\n\t"
+ );
+#else
+ volatile u8 *fsp_ptr;
+#endif /* __PRE_RAM__ */
+
+#ifndef CONFIG_FSP_LOC
+#error "CONFIG_FSP_LOC must be set."
+#endif
+
+ /* The FSP is stored in CBFS */
+ fsp_ptr = (u8 *) CONFIG_FSP_LOC;
+
+ /* Check the FV signature, _FVH */
+ if (((EFI_FIRMWARE_VOLUME_HEADER *)fsp_ptr)->Signature == 0x4856465F) {
+ /* Go to the end of the FV header and align the address. */
+ fsp_ptr += ((EFI_FIRMWARE_VOLUME_HEADER *)fsp_ptr)->ExtHeaderOffset;
+ fsp_ptr += ((EFI_FIRMWARE_VOLUME_EXT_HEADER *)fsp_ptr)->ExtHeaderSize;
+ fsp_ptr = (u8 *)(((u32)fsp_ptr + 7) & 0xFFFFFFF8);
+ } else {
+ fsp_ptr = (u8*)ERROR_NO_FV_SIG;
+ }
+
+ /* Check the FFS GUID */
+ if (((u32)fsp_ptr > 0xff) &&
+ (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[0] == 0x912740BE) &&
+ (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[1] == 0x47342284) &&
+ (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[2] == 0xB08471B9) &&
+ (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[3] == 0x0C3F3527)) {
+ /* Add the FFS Header size to the base to find the Raw section Header */
+ fsp_ptr += sizeof(EFI_FFS_FILE_HEADER);
+ } else {
+ fsp_ptr = (u8 *)ERROR_NO_FFS_GUID;
+ }
+
+ if (((u32)fsp_ptr > 0xff) &&
+ ((EFI_RAW_SECTION *)fsp_ptr)->Type == EFI_SECTION_RAW) {
+ /* Add the Raw Header size to the base to find the FSP INFO Header */
+ fsp_ptr += sizeof(EFI_RAW_SECTION);
+ } else {
+ fsp_ptr = (u8 *)ERROR_NO_INFO_HEADER;
+ }
+
+ /* Verify that the FSP is set to the base address we're expecting.*/
+ if (((u32)fsp_ptr > 0xff) &&
+ (*(u32*)(fsp_ptr + FSP_IMAGE_BASE_LOC) != CONFIG_FSP_LOC)) {
+ fsp_ptr = (u8 *)ERROR_IMAGEBASE_MISMATCH;
+ }
+
+ /* Verify the FSP Signature */
+ if (((u32)fsp_ptr > 0xff) &&
+ (*(u32*)(fsp_ptr + FSP_IMAGE_SIG_LOC) != FSP_SIG)){
+ fsp_ptr = (u8 *)ERROR_INFO_HEAD_SIG_MISMATCH;
+ }
+
+ /* Verify the FSP ID */
+ if (((u32)fsp_ptr > 0xff) &&
+ ((*(u32 *)(fsp_ptr + FSP_IMAGE_ID_LOC) != FSP_IMAGE_ID_DWORD0) ||
+ (*(u32 *)(fsp_ptr + (FSP_IMAGE_ID_LOC + 4)) != FSP_IMAGE_ID_DWORD1))) {
+ fsp_ptr = (u8 *)ERROR_FSP_SIG_MISMATCH;
+ }
+
+ return (fsp_ptr);
+}
+
+#ifndef __PRE_RAM__ /* Only parse HOB data in ramstage */
+
+void print_fsp_info(void) {
+
+ if (fsp_header_ptr == NULL)
+ fsp_header_ptr = (void *)find_fsp();
+ if ((u32)fsp_header_ptr < 0xff) {
+ post_code(0x4F); /* output something in case there is no serial */
+ die("Can't find the FSP!\n");
+ }
+
+ if (FspHobListPtr == NULL) {
+ FspHobListPtr = (void*)*((u32*) cbmem_find(CBMEM_ID_HOB_POINTER));
+ }
+
+ printk(BIOS_SPEW,"fsp_header_ptr: %p\n", fsp_header_ptr);
+ printk(BIOS_INFO,"FSP Header Version: %d\n", fsp_header_ptr->HeaderRevision);
+ printk(BIOS_INFO,"FSP Revision: %d.%d\n",
+ (u8)((fsp_header_ptr->ImageRevision >> 8) & 0xff),
+ (u8)(fsp_header_ptr->ImageRevision & 0xff));
+}
+
+static void print_hob_mem_attributes(void *Hobptr) {
+ EFI_HOB_MEMORY_ALLOCATION *HobMemoryPtr = (EFI_HOB_MEMORY_ALLOCATION *)Hobptr;
+ EFI_MEMORY_TYPE Hobmemtype = HobMemoryPtr->AllocDescriptor.MemoryType;
+ u64 Hobmemaddr = HobMemoryPtr->AllocDescriptor.MemoryBaseAddress;
+ u64 Hobmemlength = HobMemoryPtr->AllocDescriptor.MemoryLength;
+ const char * Hobmemtypenames[15];
+
+ Hobmemtypenames[0] = "EfiReservedMemoryType";
+ Hobmemtypenames[1] = "EfiLoaderCode";
+ Hobmemtypenames[2] = "EfiLoaderData";
+ Hobmemtypenames[3] = "EfiBootServicesCode";
+ Hobmemtypenames[4] = "EfiBootServicesData";
+ Hobmemtypenames[5] = "EfiRuntimeServicesCode";
+ Hobmemtypenames[6] = "EfiRuntimeServicesData";
+ Hobmemtypenames[7] = "EfiConventionalMemory";
+ Hobmemtypenames[8] = "EfiUnusableMemory";
+ Hobmemtypenames[9] = "EfiACPIReclaimMemory";
+ Hobmemtypenames[10] = "EfiACPIMemoryNVS";
+ Hobmemtypenames[11] = "EfiMemoryMappedIO";
+ Hobmemtypenames[12] = "EfiMemoryMappedIOPortSpace";
+ Hobmemtypenames[13] = "EfiPalCode";
+ Hobmemtypenames[14] = "EfiMaxMemoryType";
+
+ printk(BIOS_SPEW, " Memory type %s (0x%x)\n",
+ Hobmemtypenames[(u32)Hobmemtype], (u32) Hobmemtype);
+ printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
+ (long unsigned int)Hobmemaddr, (long unsigned int)Hobmemlength);
+}
+
+static void print_hob_resource_attributes(void *Hobptr) {
+ EFI_HOB_RESOURCE_DESCRIPTOR *HobResourcePtr =
+ (EFI_HOB_RESOURCE_DESCRIPTOR *)Hobptr;
+ u32 Hobrestype = HobResourcePtr->ResourceType;
+ u32 Hobresattr = HobResourcePtr->ResourceAttribute;
+ u64 Hobresaddr = HobResourcePtr->PhysicalStart;
+ u64 Hobreslength = HobResourcePtr->ResourceLength;
+ const char *Hobrestypestr = NULL;
+
+ // HOB Resource Types
+ switch (Hobrestype) {
+ case EFI_RESOURCE_SYSTEM_MEMORY:
+ Hobrestypestr = "EFI_RESOURCE_SYSTEM_MEMORY"; break;
+ case EFI_RESOURCE_MEMORY_MAPPED_IO:
+ Hobrestypestr = "EFI_RESOURCE_MEMORY_MAPPED_IO"; break;
+ case EFI_RESOURCE_IO:
+ Hobrestypestr = "EFI_RESOURCE_IO"; break;
+ case EFI_RESOURCE_FIRMWARE_DEVICE:
+ Hobrestypestr = "EFI_RESOURCE_FIRMWARE_DEVICE"; break;
+ case EFI_RESOURCE_MEMORY_MAPPED_IO_PORT:
+ Hobrestypestr = "EFI_RESOURCE_MEMORY_MAPPED_IO_PORT"; break;
+ case EFI_RESOURCE_MEMORY_RESERVED:
+ Hobrestypestr = "EFI_RESOURCE_MEMORY_RESERVED"; break;
+ case EFI_RESOURCE_IO_RESERVED:
+ Hobrestypestr = "EFI_RESOURCE_IO_RESERVED"; break;
+ case EFI_RESOURCE_MAX_MEMORY_TYPE:
+ Hobrestypestr = "EFI_RESOURCE_MAX_MEMORY_TYPE"; break;
+ default:
+ Hobrestypestr = "EFI_RESOURCE_UNKNOWN"; break;
+ }
+
+ printk(BIOS_SPEW, " Resource %s (0x%0x) has attributes 0x%0x\n",
+ Hobrestypestr, Hobrestype, Hobresattr);
+ printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
+ (long unsigned int)Hobresaddr, (long unsigned int)Hobreslength);
+}
+
+static const char * get_hob_type_string(void *Hobptr) {
+ EFI_HOB_GENERIC_HEADER *HobHeaderPtr = (EFI_HOB_GENERIC_HEADER *)Hobptr;
+ u16 Hobtype = HobHeaderPtr->HobType;
+ const char *Hobtypestring = NULL;
+
+ switch (Hobtype) {
+ case EFI_HOB_TYPE_HANDOFF:
+ Hobtypestring = "EFI_HOB_TYPE_HANDOFF"; break;
+ case EFI_HOB_TYPE_MEMORY_ALLOCATION:
+ Hobtypestring = "EFI_HOB_TYPE_MEMORY_ALLOCATION"; break;
+ case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
+ Hobtypestring = "EFI_HOB_TYPE_RESOURCE_DESCRIPTOR"; break;
+ case EFI_HOB_TYPE_GUID_EXTENSION:
+ Hobtypestring = "EFI_HOB_TYPE_GUID_EXTENSION"; break;
+ case EFI_HOB_TYPE_MEMORY_POOL:
+ Hobtypestring = "EFI_HOB_TYPE_MEMORY_POOL"; break;
+ case EFI_HOB_TYPE_UNUSED:
+ Hobtypestring = "EFI_HOB_TYPE_UNUSED"; break;
+ case EFI_HOB_TYPE_END_OF_HOB_LIST:
+ Hobtypestring = "EFI_HOB_TYPE_END_OF_HOB_LIST"; break;
+ default:
+ Hobtypestring = "EFI_HOB_TYPE_UNRECOGNIZED"; break;
+ }
+
+ return Hobtypestring;
+}
+
+/* Print out a structure of all the HOBs
+ * that match a certain type:
+ * Print all types (0x0000)
+ * EFI_HOB_TYPE_HANDOFF (0x0001)
+ * EFI_HOB_TYPE_MEMORY_ALLOCATION (0x0002)
+ * EFI_HOB_TYPE_RESOURCE_DESCRIPTOR (0x0003)
+ * EFI_HOB_TYPE_GUID_EXTENSION (0x0004)
+ * EFI_HOB_TYPE_MEMORY_POOL (0x0007)
+ * EFI_HOB_TYPE_UNUSED (0xFFFE)
+ * EFI_HOB_TYPE_END_OF_HOB_LIST (0xFFFF)
+ */
+void print_hob_type_structure(u16 Hobtype, void *Hoblistptr) {
+ u32 *Currenthob;
+ u32 *Nexthob = 0;
+ u8 Lasthob = 0;
+ u32 Currenttype;
+ const char *Currenttypestr;
+
+ Currenthob = Hoblistptr;
+
+ /* Print out HOBs of our desired type until
+ * the end of the HOB list
+ */
+ printk(BIOS_DEBUG, "\n=== FSP HOB Data Structure ===\n");
+ printk(BIOS_DEBUG, "FSP Hoblistptr: 0x%0x\n",
+ (u32) Hoblistptr);
+ do {
+ EFI_HOB_GENERIC_HEADER *CurrentHeaderPtr =
+ (EFI_HOB_GENERIC_HEADER *)Currenthob;
+ Currenttype = CurrentHeaderPtr->HobType; /* Get the type of this HOB */
+ Currenttypestr = get_hob_type_string(Currenthob);
+
+ if (Currenttype == Hobtype || Hobtype == 0x0000) {
+ printk(BIOS_DEBUG, "HOB 0x%0x is an %s (type 0x%0x)\n",
+ (u32) Currenthob, Currenttypestr, Currenttype);
+ switch (Currenttype) {
+ case EFI_HOB_TYPE_MEMORY_ALLOCATION:
+ print_hob_mem_attributes(Currenthob); break;
+ case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
+ print_hob_resource_attributes(Currenthob); break;
+ }
+ }
+
+ Lasthob = END_OF_HOB_LIST(Currenthob); /* Check for end of HOB list */
+ if (!Lasthob) {
+ Nexthob = GET_NEXT_HOB(Currenthob); /* Get next HOB pointer */
+ Currenthob = Nexthob; // Start on next HOB
+ }
+ } while (!Lasthob);
+ printk(BIOS_DEBUG, "=== End of FSP HOB Data Structure ===\n\n");
+}
+
+#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
+/**
+ * Save the FSP memory HOB (mrc data) to the MRC area in CBMEM
+ */
+int save_mrc_data(void *hob_start)
+{
+ u32 *mrc_hob;
+ u32 *mrc_hob_data;
+ u32 mrc_hob_size;
+ struct mrc_data_container *mrc_data;
+ int output_len;
+ const EFI_GUID mrc_guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
+
+ mrc_hob = GetNextGuidHob(&mrc_guid, hob_start);
+ if (mrc_hob == NULL){
+ printk(BIOS_DEBUG, "Memory Configure Data Hob is not present\n");
+ return(0);
+ }
+
+ mrc_hob_data = GET_GUID_HOB_DATA (mrc_hob);
+ mrc_hob_size = (u32) GET_HOB_LENGTH(mrc_hob);
+
+ printk(BIOS_DEBUG, "Memory Configure Data Hob at %p (size = 0x%x).\n",
+ (void *)mrc_hob_data, mrc_hob_size);
+
+ output_len = ALIGN(mrc_hob_size, 16);
+
+ /* Save the MRC S3/fast boot/ADR restore data to cbmem */
+ mrc_data = cbmem_add (CBMEM_ID_MRCDATA,
+ output_len + sizeof(struct mrc_data_container));
+
+ /* Just return if there was a problem with getting CBMEM */
+ if (mrc_data == NULL) {
+ printk(BIOS_WARNING, "CBMEM was not available to save the fast boot cache data.\n");
+ return 0;
+ }
+
+ printk(BIOS_DEBUG, "Copy FSP MRC DATA to HOB (source addr %p, dest addr %p, %u bytes)\n",
+ (void *)mrc_hob_data, mrc_data, output_len);
+
+ mrc_data->mrc_signature = MRC_DATA_SIGNATURE;
+ mrc_data->mrc_data_size = output_len;
+ mrc_data->reserved = 0;
+ memcpy(mrc_data->mrc_data, (const void *)mrc_hob_data, mrc_hob_size);
+
+ /* Zero the unused space in aligned buffer. */
+ if (output_len > mrc_hob_size)
+ memset((mrc_data->mrc_data + mrc_hob_size), 0,
+ output_len - mrc_hob_size);
+
+ mrc_data->mrc_checksum = compute_ip_checksum(mrc_data->mrc_data,
+ mrc_data->mrc_data_size);
+
+ printk(BIOS_SPEW, "Fast boot data (includes align and checksum):\n");
+ hexdump32(BIOS_SPEW, (void *)mrc_data->mrc_data, output_len);
+ return (1);
+}
+#endif /* CONFIG_ENABLE_MRC_CACHE */
+
+static void find_fsp_hob_update_mrc(void *unused)
+{
+ /* Set the global HOB list pointer */
+ FspHobListPtr = (void*)*((u32*) cbmem_find(CBMEM_ID_HOB_POINTER));
+
+ if (!FspHobListPtr){
+ printk(BIOS_ERR, "ERROR: Could not find FSP HOB pointer in CBFS!\n");
+ } else {
+ /* 0x0000: Print all types */
+ print_hob_type_structure(0x000, FspHobListPtr);
+
+ #if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
+ if(save_mrc_data(FspHobListPtr))
+ update_mrc_cache(NULL);
+ else
+ printk(BIOS_DEBUG,"Not updating MRC data in flash.\n");
+ #endif
+ }
+}
+
+/* Update the MRC/fast boot cache as part of the late table writing stage */
+BOOT_STATE_INIT_ENTRIES(fsp_hob_find) = {
+ BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY,
+ find_fsp_hob_update_mrc, NULL),
+};
+#endif /* #ifndef __PRE_RAM__ */
diff --git a/src/drivers/intel/fsp/fsp_util.h b/src/drivers/intel/fsp/fsp_util.h
new file mode 100644
index 0000000..db8b6de
--- /dev/null
+++ b/src/drivers/intel/fsp/fsp_util.h
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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 FSP_UTIL_H
+#define FSP_UTIL_H
+
+#include <chipset_fsp_util.h>
+
+#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
+int save_mrc_data(void *hob_start);
+void * find_and_set_fastboot_cache(void);
+#endif
+
+volatile u8 * find_fsp (void);
+void fsp_early_init(FSP_INFO_HEADER *fsp_info);
+void FspNotify(u32 Phase);
+void FspNotifyReturnPoint(EFI_STATUS Status, VOID *HobListPtr);
+void print_hob_type_structure(u16 Hobtype, void *Hoblistptr);
+void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer);
+void print_fsp_info(void);
+
+void chipset_fsp_early_init(FSP_INIT_PARAMS *FspInitParams,
+ FSP_INFO_HEADER *fsp_ptr);
+void ChipsetFspReturnPoint(EFI_STATUS Status, VOID *HobListPtr);
+
+/* Additional HOB types not included in the FSP:
+ * #define EFI_HOB_TYPE_HANDOFF 0x0001
+ * #define EFI_HOB_TYPE_MEMORY_ALLOCATION 0x0002
+ * #define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR 0x0003
+ * #define EFI_HOB_TYPE_GUID_EXTENSION 0x0004
+ * #define EFI_HOB_TYPE_FV 0x0005
+ * #define EFI_HOB_TYPE_CPU 0x0006
+ * #define EFI_HOB_TYPE_MEMORY_POOL 0x0007
+ * #define EFI_HOB_TYPE_CV 0x0008
+ * #define EFI_HOB_TYPE_UNUSED 0xFFFE
+ * #define EFI_HOB_TYPE_END_OF_HOB_LIST 0xffff
+ */
+#define EFI_HOB_TYPE_HANDOFF 0x0001
+#define EFI_HOB_TYPE_MEMORY_POOL 0x0007
+
+#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
+#define MRC_DATA_ALIGN 0x1000
+#define MRC_DATA_SIGNATURE (('M'<<0)|('R'<<8)|('C'<<16)|('D'<<24))
+
+struct mrc_data_container {
+ u32 mrc_signature; // "MRCD"
+ u32 mrc_data_size; // Actual total size of this structure
+ u32 mrc_checksum; // IP style checksum
+ u32 reserved; // For header alignment
+ u8 mrc_data[0]; // Variable size, platform/run time dependent.
+} __attribute__ ((packed));
+
+struct mrc_data_container *find_current_mrc_cache(void);
+
+#if !defined(__PRE_RAM__)
+void update_mrc_cache(void *unused);
+#endif
+
+#endif
+
+/* The offset in bytes from the start of the info structure */
+#define FSP_IMAGE_SIG_LOC 0
+#define FSP_IMAGE_ID_LOC 16
+#define FSP_IMAGE_BASE_LOC 28
+
+#define FSP_SIG 0x48505346 /* 'FSPH' */
+
+#define ERROR_NO_FV_SIG 1
+#define ERROR_NO_FFS_GUID 2
+#define ERROR_NO_INFO_HEADER 3
+#define ERROR_IMAGEBASE_MISMATCH 4
+#define ERROR_INFO_HEAD_SIG_MISMATCH 5
+#define ERROR_FSP_SIG_MISMATCH 6
+
+#ifndef __PRE_RAM__
+extern void *FspHobListPtr;
+#endif
+
+#endif /* FSP_UTIL_H */
diff --git a/src/include/timestamp.h b/src/include/timestamp.h
index 9e780c3..66c1d9a 100644
--- a/src/include/timestamp.h
+++ b/src/include/timestamp.h
@@ -43,12 +43,16 @@ enum timestamp_id {
TS_END_COPYRAM = 9,
TS_START_RAMSTAGE = 10,
TS_DEVICE_ENUMERATE = 30,
+ TS_FSP_BEFORE_ENUMERATE,
+ TS_FSP_AFTER_ENUMERATE,
TS_DEVICE_CONFIGURE = 40,
TS_DEVICE_ENABLE = 50,
TS_DEVICE_INITIALIZE = 60,
TS_DEVICE_DONE = 70,
TS_CBMEM_POST = 75,
TS_WRITE_TABLES = 80,
+ TS_FSP_BEFORE_FINALIZE,
+ TS_FSP_AFTER_FINALIZE,
TS_LOAD_PAYLOAD = 90,
TS_ACPI_WAKE_JUMP = 98,
TS_SELFBOOT_JUMP = 99,
Martin Roth (martin.roth(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5636
-gerrit
commit a05280589eed34a9c964d70ff185b95accd6abdf
Author: Martin Roth <gaumless(a)gmail.com>
Date: Fri Apr 25 15:09:27 2014 -0600
cougar_canyon2: Switch CPU/NB/SB/to the shared FSP code
CPU - fsp_model_206ax:
- Remove Kconfig options and mark this as using the FSP.
- Use shared FSP cache_as_ram.inc file
Mainboard - intel/cougar_canyon2:
- Update to use the shared FSP header file.
- Modify to call copy_and_run() directly instead of returning to
cache_as_ram.inc.
Northbridge - fsp_sandybridge:
- remove mrccache, fsp_util.[ch]
- add fsp/chipset_fsp_util.[ch] with chipset specific FSP bits.
- Update to use the shared FSP header file.
Change-Id: Ibc52a78312c2fcbd1e632bc2484e4379a4f057d4
Signed-off-by: Martin Roth <gaumless(a)gmail.com>
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
---
src/cpu/intel/fsp_model_206ax/Kconfig | 23 +-
src/cpu/intel/fsp_model_206ax/Makefile.inc | 11 +-
src/cpu/intel/fsp_model_206ax/cache_as_ram.inc | 292 ---------------
src/mainboard/intel/cougar_canyon2/romstage.c | 13 +-
src/northbridge/intel/fsp_sandybridge/Kconfig | 67 +---
src/northbridge/intel/fsp_sandybridge/Makefile.inc | 27 +-
src/northbridge/intel/fsp_sandybridge/fsp/Kconfig | 42 +++
.../intel/fsp_sandybridge/fsp/Makefile.inc | 22 ++
.../intel/fsp_sandybridge/fsp/chipset_fsp_util.c | 117 ++++++
.../intel/fsp_sandybridge/fsp/chipset_fsp_util.h | 65 ++++
src/northbridge/intel/fsp_sandybridge/fsp_util.c | 414 ---------------------
src/northbridge/intel/fsp_sandybridge/fsp_util.h | 88 -----
src/northbridge/intel/fsp_sandybridge/mrccache.c | 257 -------------
.../intel/fsp_sandybridge/northbridge.c | 2 +-
.../intel/fsp_sandybridge/northbridge.h | 9 -
.../intel/fsp_sandybridge/northbridge_pci_devs.h | 47 +++
src/southbridge/intel/fsp_bd82x6x/Makefile.inc | 2 +
.../intel/fsp_bd82x6x/southbridge_pci_devs.h | 127 +++++++
18 files changed, 439 insertions(+), 1186 deletions(-)
diff --git a/src/cpu/intel/fsp_model_206ax/Kconfig b/src/cpu/intel/fsp_model_206ax/Kconfig
index 3aacaf7..1db5030 100644
--- a/src/cpu/intel/fsp_model_206ax/Kconfig
+++ b/src/cpu/intel/fsp_model_206ax/Kconfig
@@ -28,6 +28,7 @@ if CPU_INTEL_FSP_MODEL_206AX || CPU_INTEL_FSP_MODEL_306AX
config CPU_SPECIFIC_OPTIONS
def_bool y
+ select PLATFORM_USES_FSP
select ARCH_BOOTBLOCK_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
@@ -70,26 +71,4 @@ config MICROCODE_INCLUDE_PATH
default "../intel/cpu/ivybridge/microcode" if CPU_INTEL_FSP_MODEL_306AX
default "../intel/cpu/sandybridge/microcode" if CPU_INTEL_FSP_MODEL_206AX
-config FSP_IMAGE_ID_DWORD0
- hex
- default 0x2D325453 if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_I89XX
- default 0x2D324343 if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_BD82X6X
- help
- The FSP Image ID is different for each platform's FSP and can be used to
- verify that the right FSP binary is loaded.
- For the ivybridge/89xx FSP, the Image Id will be "ST2-FSP\0",
- for ivybridge/bd82x6x FSPs, the Image Id will be "CC2-FSP\0",
- This dword holds the first 4 bytes of the string, as
- a hex value.
-
-config FSP_IMAGE_ID_DWORD1
- hex
- default 0x00505346
- help
- For the ivybridge/I89xx FSP, the Image Id will be "ST2-FSP\0",
- for ivybridge/bd82x6x FSPs, the Image Id will be "CC2-FSP\0",
- This dword holds the second 4 bytes of the string, as
- a hex value. Since the strings use the same second dword,
- no additional logic is needed.
-
endif
diff --git a/src/cpu/intel/fsp_model_206ax/Makefile.inc b/src/cpu/intel/fsp_model_206ax/Makefile.inc
index 7986767..6004462 100644
--- a/src/cpu/intel/fsp_model_206ax/Makefile.inc
+++ b/src/cpu/intel/fsp_model_206ax/Makefile.inc
@@ -7,9 +7,8 @@ smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
-cpu_incs += $(src)/cpu/intel/fsp_model_206ax/cache_as_ram.inc
-
-CC_bootblock := $(CC_bootblock) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
-CC_romstage := $(CC_romstage) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
-CC_ramstage := $(CC_ramstage) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
-CC_x86_32 := $(CC_x86_32) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
+ifneq ($(CONFIG_MICROCODE_INCLUDE_PATH),)
+ifneq ($(wildcard $(shell realpath -L "$(top)/$(CONFIG_MICROCODE_INCLUDE_PATH)")),)
+INCLUDES += -I$(CONFIG_MICROCODE_INCLUDE_PATH)
+endif
+endif
diff --git a/src/cpu/intel/fsp_model_206ax/cache_as_ram.inc b/src/cpu/intel/fsp_model_206ax/cache_as_ram.inc
deleted file mode 100644
index cc35060..0000000
--- a/src/cpu/intel/fsp_model_206ax/cache_as_ram.inc
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich(a)gmail.com>
- * Copyright (C) 2007-2008 coresystems GmbH
- * Copyright (C) 2013 Sage Electronic Engineering, LLC.
- *
- * 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 <cpu/x86/stack.h>
-#include <cpu/x86/mtrr.h>
-#include <cpu/x86/cache.h>
-#include <cpu/x86/post_code.h>
-#include <cbmem.h>
-
-#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
-#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
-
-#define CPU_PHYSMASK_HI (1 << (CONFIG_CPU_ADDR_BITS - 32) - 1)
-#define LHLT_DELAY 0x50000 /* delay between post codes on FSP failure */
-#define NoEvictMod_MSR 0x2e0
-
-cache_as_ram:
- post_code(0x20)
-
- /* Send INIT IPI to all excluding ourself. */
- movl $0x000C4500, %eax
- movl $0xFEE00300, %esi
- movl %eax, (%esi)
-
- /* All CPUs need to be in Wait for SIPI state */
-wait_for_sipi:
- movl (%esi), %eax
- bt $12, %eax
- jc wait_for_sipi
-
- post_code(0x21)
- /* Zero out all fixed range and variable range MTRRs. */
- movl $mtrr_table, %esi
- movl $((mtrr_table_end - mtrr_table) / 2), %edi
- xorl %eax, %eax
- xorl %edx, %edx
-clear_mtrrs:
- movw (%esi), %bx
- movzx %bx, %ecx
- wrmsr
- add $2, %esi
- dec %edi
- jnz clear_mtrrs
-
- /* Init floating point */
- emms
- fninit
-
- /*
- * Find the FSP binary in cbfs.
- * Make a fake stack that has the return value back to this code.
- */
- lea fake_fsp_stack, %esp
- jmp find_fsp
-find_fsp_ret:
- /* Save the FSP location */
- mov %eax, %ebp
- cmp $CONFIG_FSP_LOC, %eax
- jb halt1
-
- post_code(0x22)
-
- /* Calculate entry into FSP */
- mov 0x30(%ebp), %eax /* Load TempRamInitEntry */
- add 0x1c(%ebp), %eax /* add in the offset for the FSP base address */
-
- /*
- * Pass early init variables on a fake stack (no memory yet)
- * as well as the return location
- */
- lea CAR_init_stack, %esp
-
- /* call FSP binary to setup temporary stack */
- jmp *%eax
-
-CAR_init_done:
- addl $4, %esp
- cmp $0, %eax
- jne halt2
-
- /* Save FSP_INFO_HEADER location in ebx */
- mov %ebp, %ebx
-
- /*
- * setup bootloader stack
- * ecx: stack base
- * edx: stack top
- */
- lea -4(%edx), %esp
- movl %esp, %ebp
-
-before_romstage:
- post_code(0x23)
-
- /* Call romstage.c main function. */
- pushl %ebx
- call main
-
-romstage_main_return:
- post_code(0x2f)
-
-/* Disable cache. */
- movl %cr0, %eax
- orl $CR0_CacheDisable, %eax
- movl %eax, %cr0
-
- post_code(0x31)
-
- /* Disable MTRR. */
- movl $MTRRdefType_MSR, %ecx
- rdmsr
- andl $(~MTRRdefTypeEn), %eax
- wrmsr
-
- post_code(0x32)
-
- /* Zero out all fixed range and variable range MTRRs. */
- movl $mtrr_table, %esi
- movl $((mtrr_table_end - mtrr_table) / 2), %edi
- xorl %eax, %eax
- xorl %edx, %edx
-_clear_mtrrs_:
- movw (%esi), %bx
- movzx %bx, %ecx
- wrmsr
- add $2, %esi
- dec %edi
- jnz _clear_mtrrs_
-
- post_code(0x33)
-
- /* Enable cache. */
- movl %cr0, %eax
- andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
- movl %eax, %cr0
-
- post_code(0x36)
-
- /* Disable cache. */
- movl %cr0, %eax
- orl $CR0_CacheDisable, %eax
- movl %eax, %cr0
-
- post_code(0x38)
-
- /* Enable Write Back and Speculative Reads for the first MB
- * and ramstage.
- */
- movl $MTRRphysBase_MSR(0), %ecx
- movl $(0x00000000 | MTRR_TYPE_WRBACK), %eax
- xorl %edx, %edx
- wrmsr
- movl $MTRRphysMask_MSR(0), %ecx
- movl $(~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid), %eax
- movl $CPU_PHYSMASK_HI, %edx // 36bit address space
- wrmsr
-
-#if CACHE_ROM_SIZE
- /* Enable Caching and speculative Reads for the
- * complete ROM now that we actually have RAM.
- */
- movl $MTRRphysBase_MSR(1), %ecx
- movl $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
- xorl %edx, %edx
- wrmsr
- movl $MTRRphysMask_MSR(1), %ecx
- movl $(~(CACHE_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
- movl $CPU_PHYSMASK_HI, %edx
- wrmsr
-#endif
-
- post_code(0x39)
-
- /* And enable cache again after setting MTRRs. */
- movl %cr0, %eax
- andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
- movl %eax, %cr0
-
- post_code(0x3a)
-
- /* Enable MTRR. */
- movl $MTRRdefType_MSR, %ecx
- rdmsr
- orl $MTRRdefTypeEn, %eax
- wrmsr
-
- post_code(0x3d)
-
- /* Clear boot_complete flag. */
- xorl %ebp, %ebp
-__main:
- post_code(POST_PREPARE_RAMSTAGE)
- cld /* Clear direction flag. */
-
- movl %ebp, %esi
-
- movl $ROMSTAGE_STACK, %esp
- movl %esp, %ebp
- pushl %esi
- call copy_and_run
-
-halt1:
- /*
- * Failures for postcode 0xBA - failed in find_fsp()
- *
- * Values are:
- * 0x01 - FV signature, "_FVH" not present
- * 0x02 - FFS GUID not present
- * 0x03 - FSP INFO Header not found
- * 0x04 - ImageBase does not equal CONFIG_FSP_LOC - Is the FSP rebased to
- * a different location, or does it need to be?
- * 0x05 - FSP INFO Header signature "FSPH" not found
- * 0x06 - FSP Image ID is not the expected ID.
- * For ivybridge_bd82x6x, the ID is expected to be 'CC2-FSP\0'
- * For ivybridge_i89xx, the ID is expected to be 'ST2-FSP\0'
- *
- */
- movb $0xBA, %ah
- jmp .Lhlt
-
-halt2:
- /*
- * Failures for postcode 0xBB - failed in the FSP:
- *
- * 0x00 - FSP_SUCCESS: Temp RAM was initialized successfully.
- * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid.
- * 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode region.
- * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
- * 0x07 - FSP_DEVICE_ERROR: Temp RAM initialization failed
- * 0x14 - FSP_ALREADY_STARTED: Temp RAM initialization has been invoked
- */
- movb $0xBB, %ah
-
-.Lhlt:
- xchg %al, %ah
-#if CONFIG_POST_IO
- outb %al, $CONFIG_POST_IO_PORT
-#else
- post_code(POST_DEAD_CODE)
-#endif
- movl $LHLT_DELAY, %ecx
-.Lhlt_Delay:
- outb %al, $0xED
- loop .Lhlt_Delay
- jmp .Lhlt
-
- .align 4
-fake_fsp_stack:
- .long find_fsp_ret
-
-CAR_init_params:
- .long CONFIG_CPU_MICROCODE_CBFS_LOC
- .long CONFIG_CPU_MICROCODE_CBFS_LEN /* Microcode Length */
- .long 0xFFFFFFFF - CONFIG_ROM_SIZE + 1 /* Firmware Location */
- .long CONFIG_ROM_SIZE /* Total Firmware Length */
-
-CAR_init_stack:
- .long CAR_init_done
- .long CAR_init_params
-
-mtrr_table:
- /* Fixed MTRRs */
- .word 0x250, 0x258, 0x259
- .word 0x268, 0x269, 0x26A
- .word 0x26B, 0x26C, 0x26D
- .word 0x26E, 0x26F
- /* Variable MTRRs */
- .word 0x200, 0x201, 0x202, 0x203
- .word 0x204, 0x205, 0x206, 0x207
- .word 0x208, 0x209, 0x20A, 0x20B
- .word 0x20C, 0x20D, 0x20E, 0x20F
-/* .word 0x210, 0x211, 0x212, 0x213 */
-mtrr_table_end:
-
diff --git a/src/mainboard/intel/cougar_canyon2/romstage.c b/src/mainboard/intel/cougar_canyon2/romstage.c
index afd7e25..6938925 100644
--- a/src/mainboard/intel/cougar_canyon2/romstage.c
+++ b/src/mainboard/intel/cougar_canyon2/romstage.c
@@ -33,7 +33,7 @@
#include <console/console.h>
#include <reset.h>
#include "superio/smsc/sio1007/chip.h"
-#include "northbridge/intel/fsp_sandybridge/fsp_util.h"
+#include <fsp_util.h>
#include "northbridge/intel/fsp_sandybridge/northbridge.h"
#include "northbridge/intel/fsp_sandybridge/raminit.h"
#include "southbridge/intel/fsp_bd82x6x/pch.h"
@@ -42,6 +42,7 @@
#include <arch/cpu.h>
#include <cpu/x86/msr.h>
#include "gpio.h"
+#include <arch/stages.h>
static inline void reset_system(void)
{
@@ -345,13 +346,9 @@ void romstage_main_continue(EFI_STATUS status, VOID *HobListPtr) {
cbmemc_reinit();
#endif
-/*
- * FSP returns to this function instead of main, so we can't return back
- * to the cache_as_ram.inc. Just jump there to finish the ramstage loading.
- */
- asm volatile (
- "jmp romstage_main_return\n"
- );
+ /* Load the ramstage. */
+ copy_and_run();
+ while (1);
}
void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer)
diff --git a/src/northbridge/intel/fsp_sandybridge/Kconfig b/src/northbridge/intel/fsp_sandybridge/Kconfig
index ce366ef..2e1c087 100644
--- a/src/northbridge/intel/fsp_sandybridge/Kconfig
+++ b/src/northbridge/intel/fsp_sandybridge/Kconfig
@@ -28,15 +28,6 @@ config NORTHBRIDGE_INTEL_FSP_IVYBRIDGE
if NORTHBRIDGE_INTEL_FSP_IVYBRIDGE || NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE
-config HAVE_FSP_BIN
- bool "Use Intel Firmware Support Package"
- help
- Select this option to add an Intel FSP binary to
- the resulting coreboot image.
-
- Note: Without this binary, coreboot builds relying on the FSP
- will not boot
-
config VGA_BIOS_ID
string
default "8086,0106"
@@ -47,32 +38,6 @@ config VGA_BIOS_ID
0x80860102, 0x8086010a, 0x80860112, 0x80860116
0x80860122, 0x80860126, 0x80860166
-config DCACHE_RAM_BASE
- hex
- default 0xff7f0000
-
-config DCACHE_RAM_SIZE
- hex
- default 0x10000
-
-
-if HAVE_FSP_BIN
-
-config FSP_FILE
- string "Intel FSP binary path and filename"
- default "../intel/fsp/ivybridge_bd82x6x/FvFsp.bin" if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_BD82X6X
- default "../intel/fsp/ivybridge_i89xx/FvFsp.bin" if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_I89XX
- help
- The path and filename of the Intel FSP binary for this platform.
-
-config FSP_LOC
- hex "Intel FSP Binary location in cbfs"
- default 0xfff80000
- help
- The location in cbfs that the FSP is located. This must match the
- value that is set in the FSP binary. If the FSP needs to be moved,
- rebase the FSP with the Intel's BCT (tool).
-
config CBFS_SIZE
hex "Size of CBFS filesystem in ROM"
default 0x100000
@@ -84,35 +49,7 @@ config CBFS_SIZE
This option specifies the maximum size of the CBFS portion in the
firmware image.
-config ENABLE_FAST_BOOT
- bool "Enable Fast Boot"
- default y if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_BD82X6X
- help
- Enabling this feature will cause MRC data to be cached in NV storage
- which will speed up boot time on future reboots and/or power cycles.
-
-config MRC_CACHE_SIZE
- hex "MRC Data Cache Size"
- default 0x10000
- depends on ENABLE_FAST_BOOT
- help
- This is the amount of space in NV storage that is reserved for MRC data
- cache storage when using fast boot.
-
-config VIRTUAL_ROM_SIZE
- hex "Virtual ROM Size"
- default ROM_SIZE
- depends on ENABLE_FAST_BOOT
- help
- This is used to calculate the offset of the MRC data cache in NV
- Storage for "Fast Boot". If in doubt, leave this set to the default
- which sets the virtual size equal to the ROM size.
-
- Example: Cougar Canyon 2 has 2 8 MB SPI ROMs. When the SPI ROMs are
- loaded with a 4 MB coreboot image, the virtual ROM size is 8 MB. When
- the SPI ROMs are loaded with an 8 MB coreboot image, the virtual ROM
- size is 16 MB.
-
-endif # HAVE_FSP_BIN
+# Ivybridge Specific FSP Kconfig
+source src/northbridge/intel/fsp_sandybridge/fsp/Kconfig
endif # NORTHBRIDGE_INTEL_FSP_IVYBRIDGE || NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE
diff --git a/src/northbridge/intel/fsp_sandybridge/Makefile.inc b/src/northbridge/intel/fsp_sandybridge/Makefile.inc
index 5bc3d58..f5dbbe4 100644
--- a/src/northbridge/intel/fsp_sandybridge/Makefile.inc
+++ b/src/northbridge/intel/fsp_sandybridge/Makefile.inc
@@ -2,7 +2,7 @@
# This file is part of the coreboot project.
#
# Copyright (C) 2010 Google Inc.
-# Copyright (C) 2013 Sage Electronic Engineering, LLC.
+# Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
#
# 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
@@ -18,41 +18,20 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
+subdirs-y += fsp
ramstage-y += northbridge.c
ramstage-y += gma.c
ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpi.c
-ramstage-y += fsp_util.c
-ramstage-$(CONFIG_ENABLE_FAST_BOOT) += mrccache.c
romstage-y += raminit.c
-romstage-y += fsp_util.c
romstage-y += early_init.c
romstage-y += report_platform.c
romstage-y += ../../../arch/x86/lib/walkcbfs.S
-romstage-$(CONFIG_ENABLE_FAST_BOOT) += mrccache.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += udelay.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
-ifeq ($(CONFIG_HAVE_FSP_BIN),y)
-# We don't ship an FSP, but booting without it is bound to fail
-cbfs-files-y += fsp.bin
-fsp.bin-file := $(call strip_quotes,$(CONFIG_FSP_FILE))
-fsp.bin-position := $(CONFIG_FSP_LOC)
-fsp.bin-type := 0xab
-endif
-
-ifeq ($(CONFIG_ENABLE_FAST_BOOT),y)
-$(obj)/mrc.cache:
- dd if=/dev/zero count=1 \
- bs=$(shell printf "%d" $(CONFIG_MRC_CACHE_SIZE) ) | \
- tr '\000' '\377' > $@
-
-cbfs-files-y += mrc.cache
-mrc.cache-file := $(obj)/mrc.cache
-mrc.cache-position := 0xfff50000
-mrc.cache-type := 0xac
-endif
+INCLUDES += -I$(src)/northbridge/intel/fsp_sandybridge/fsp
$(obj)/northbridge/intel/fsp_sandybridge/acpi.ramstage.o : $(obj)/build.h
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig b/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig
new file mode 100644
index 0000000..03999618
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig
@@ -0,0 +1,42 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 Sage Electronic Engineering, LLC.
+##
+## 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
+##
+
+config SANDYBRIDGE_FSP_SPECIFIC_OPTIONS
+ def_bool y
+ select PLATFORM_USES_FSP
+ select USE_GENERIC_FSP_CAR_INC
+ select FSP_USES_UPD if SOUTHBRIDGE_INTEL_FSP_I89XX
+
+config FSP_FILE
+ string
+ default "../intel/fsp/ivybridge_bd82x6x/FvFsp.bin" if SOUTHBRIDGE_INTEL_FSP_BD82X6X
+ default "../intel/fsp/ivybridge_i89xx/FvFsp.bin" if SOUTHBRIDGE_INTEL_FSP_I89XX
+ help
+ The path and filename of the Intel FSP binary for this platform.
+
+config FSP_LOC
+ hex "Intel FSP Binary location in CBFS"
+ default 0xfff80000
+ help
+ The location in CBFS that the FSP is located. This must match the
+ value that is set in the FSP binary. If the FSP needs to be moved,
+ rebase the FSP with the Intel's BCT (tool).
+
+ The Ivy Bridge Processor/Panther Point FSP is built with a preferred
+ base address of 0xFFF80000
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/Makefile.inc b/src/northbridge/intel/fsp_sandybridge/fsp/Makefile.inc
new file mode 100644
index 0000000..ebdc80a
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/Makefile.inc
@@ -0,0 +1,22 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2014 Sage Electronic Engineering, LLC.
+#
+# 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
+#
+
+ramstage-y += chipset_fsp_util.c
+romstage-y += chipset_fsp_util.c
+
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.c b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.c
new file mode 100644
index 0000000..f7bb023
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.c
@@ -0,0 +1,117 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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 <types.h>
+#include <string.h>
+#include <cpu/x86/stack.h>
+#include <console/console.h>
+#include <bootstate.h>
+#include <cbmem.h>
+#include <device/device.h>
+#include <southbridge_pci_devs.h>
+#include <fsp_util.h>
+#include "../chip.h"
+#include <reset.h>
+
+#ifndef CONFIG_ENABLE_FSP_FAST_BOOT
+# error "CONFIG_ENABLE_FSP_FAST_BOOT must be set."
+#endif
+
+#ifdef __PRE_RAM__
+
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+static void GetUpdDefaultFromFsp (FSP_INFO_HEADER *FspInfo, UPD_DATA_REGION *UpdData)
+{
+ VPD_DATA_REGION *VpdDataRgnPtr;
+ UPD_DATA_REGION *UpdDataRgnPtr;
+ VpdDataRgnPtr = (VPD_DATA_REGION *)(UINT32)(FspInfo->CfgRegionOffset + FspInfo->ImageBase);
+ UpdDataRgnPtr = (UPD_DATA_REGION *)(UINT32)(VpdDataRgnPtr->PcdUpdRegionOffset + FspInfo->ImageBase);
+ memcpy((void*)UpdData, (void*)UpdDataRgnPtr, sizeof(UPD_DATA_REGION));
+}
+
+static void ConfigureDefaultUpdData(UPD_DATA_REGION *UpdData)
+{
+ UpdData->HTEnable = TRUE;
+ UpdData->TurboEnable = FALSE;
+ UpdData->MemoryDownEnable = FALSE;
+ UpdData->FastBootEnable = CONFIG_ENABLE_FSP_FAST_BOOT;
+}
+#else /* IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) */
+const PLATFORM_CONFIG DefaultPlatformConfig = {
+#if IS_ENABLED(CONFIG_DISABLE_SANDYBRIDGE_HYPERTHREADING)
+ FALSE, /* Hyperthreading */
+#else
+ TRUE, /* Hyperthreading */
+#endif
+ FALSE, /* Turbo Mode */
+ FALSE, /* Memory Down */
+#if IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT)
+ TRUE, /* Fast Boot */
+#else
+ FALSE, /* Fast Boot */
+#endif /* CONFIG_ENABLE_FSP_FAST_BOOT */
+};
+#endif /* IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) */
+
+/*
+ *
+ * Call the FSP to do memory init. The FSP doesn't return to this function.
+ * The FSP returns to the romstage_main_continue().
+ *
+ */
+void chipset_fsp_early_init(FSP_INIT_PARAMS *FspInitParams,
+ FSP_INFO_HEADER *fsp_ptr)
+{
+ FSP_INIT_RT_BUFFER *pFspRtBuffer = FspInitParams->RtBufferPtr;
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+ UPD_DATA_REGION *fsp_upd_data = pFspRtBuffer->Common.UpdDataRgnPtr;
+#else
+ MEM_CONFIG MemoryConfig;
+ memset((void*)&MemoryConfig, 0, sizeof(MEM_CONFIG));
+#endif
+ FspInitParams->NvsBufferPtr = NULL;
+
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+ /* Initialize the UPD Data */
+ GetUpdDefaultFromFsp (fsp_ptr, fsp_upd_data);/home/martin/extra/git/coreboot
+ ConfigureDefaultUpdData(fsp_upd_data);
+#else
+ pFspRtBuffer->Platform.MemoryConfig = &MemoryConfig;
+ pFspRtBuffer->PlatformConfiguration.PlatformConfig = &DefaultPlatformConfig;
+#endif
+
+#if IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT)
+ /* Find the fastboot cache that was saved in the ROM */
+ FspInitParams->NvsBufferPtr = find_and_set_fastboot_cache();
+#endif
+
+ pFspRtBuffer->Common.BootMode = 0;
+}
+
+/* The FSP returns here after the fsp_early_init call */
+void ChipsetFspReturnPoint(EFI_STATUS Status,
+ VOID *HobListPtr)
+{
+ if (Status == 0xFFFFFFFF) {
+ hard_reset();
+ }
+ romstage_main_continue(Status, HobListPtr);
+}
+
+#endif /* __PRE_RAM__ */
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.h b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.h
new file mode 100644
index 0000000..2374943
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.h
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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 CHIPSET_FSP_UTIL_H
+#define CHIPSET_FSP_UTIL_H
+
+#include <fsptypes.h>
+#include <fspfv.h>
+#include <fspffs.h>
+#include <fspapi.h>
+#include <fspplatform.h>
+#include <fspinfoheader.h>
+#include <fsphob.h>
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+#include <peifsp.h>
+#include <fsp_vpd.h>
+#endif
+
+#define FSP_RESERVE_MEMORY_SIZE 0x200000
+
+#define FSP_INFO_HEADER_GUID \
+ { \
+ 0x912740BE, 0x2284, 0x4734, {0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C} \
+ }
+
+#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \
+ { \
+ 0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0 } \
+ }
+
+
+/*
+ *The FSP Image ID is different for each platform's FSP and
+ * can be used to verify that the right FSP binary is loaded.
+ */
+
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+/* ST2-FSP0 */
+#define FSP_IMAGE_ID_DWORD0 0x2D325453
+#define FSP_IMAGE_ID_DWORD1 0x30505346
+#elif IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_BD82X6X)
+/* CC2-FSP\0 */
+#define FSP_IMAGE_ID_DWORD0 0x2D324343
+#define FSP_IMAGE_ID_DWORD1 0x00505346
+#endif
+
+void romstage_main_continue(EFI_STATUS status, VOID *HobListPtr);
+
+#endif /* CHIPSET_FSP_UTIL_H */
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp_util.c b/src/northbridge/intel/fsp_sandybridge/fsp_util.c
deleted file mode 100644
index a653747..0000000
--- a/src/northbridge/intel/fsp_sandybridge/fsp_util.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013 Sage Electronic Engineering, LLC.
- *
- * 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 <types.h>
-#include <string.h>
-#include <cpu/x86/stack.h>
-#include <console/console.h>
-#include <lib.h>
-#include "fsp_util.h"
-
-#if CONFIG_ENABLE_FAST_BOOT
-#include <device/device.h>
-#include "northbridge.h"
-#include <cbmem.h>
-#include <ip_checksum.h>
-#endif
-
-void find_fsp (void);
-
-#ifndef __PRE_RAM__
-/* Globals pointers for FSP structures */
-void *FspHobListPtr;
-FSP_INFO_HEADER *fsp_header_ptr;
-
-void FspNotify (u32 Phase)
-{
- FSP_NOTFY_PHASE NotifyPhaseProc;
- NOTIFY_PHASE_PARAMS NotifyPhaseParams;
- EFI_STATUS Status;
-
- if (fsp_header_ptr == NULL) {
- find_fsp();
- if (fsp_header_ptr == NULL) {
- post_code(0x4F); /* output something in case there is no serial */
- die("Can't find the FSP!\n");
- }
- }
-
- /* call FSP PEI to Notify PostPciEnumeration */
- NotifyPhaseProc = (FSP_NOTFY_PHASE)(fsp_header_ptr->ImageBase + fsp_header_ptr->NotifyPhaseEntry);
- NotifyPhaseParams.Phase = Phase;
- Status = NotifyPhaseProc (&NotifyPhaseParams);
- if (Status != 0)
- printk(BIOS_ERR,"FSP API NotifyPhase failed for phase 0x%x with status: 0x%x\n", Phase, Status);
-}
-#endif
-
-#ifdef __PRE_RAM__
-/*
- *
- * Call the FSP to do memory init. The FSP doesn't return to this function.
- * The FSP returns to the romstage_main_continue().
- *
- */
-const PLATFORM_CONFIG DefaultPlatformConfig = {
- TRUE, // Hyperthreading
- FALSE, // Turbo Mode
- FALSE, // Memory Down
-#if CONFIG_ENABLE_FAST_BOOT
- TRUE, // Fast Boot
-#else
- FALSE, // Fast Boot
-#endif
-};
-
-void __attribute__ ((noreturn)) fsp_early_init (FSP_INFO_HEADER *fsp_ptr)
-{
- FSP_FSP_INIT FspInitApi;
- FSP_INIT_PARAMS FspInitParams;
- FSP_INIT_RT_BUFFER FspRtBuffer;
- MEM_CONFIG MemoryConfig;
- memset((void*)&MemoryConfig, 0, sizeof(MEM_CONFIG));
-
- memset((void*)&FspRtBuffer, 0, sizeof(FSP_INIT_RT_BUFFER));
- FspRtBuffer.Common.StackTop = (u32 *)ROMSTAGE_STACK;
- FspRtBuffer.Platform.MemoryConfig = &MemoryConfig;
- FspRtBuffer.PlatformConfiguration.PlatformConfig = &DefaultPlatformConfig;
- FspInitParams.NvsBufferPtr = NULL;
-
-#if CONFIG_ENABLE_FAST_BOOT
- /* find_current_mrc_cache */
- struct mrc_data_container *mrc_cache = NULL;
- if (((mrc_cache = find_current_mrc_cache()) == NULL) || (mrc_cache->mrc_data_size == -1UL)) {
- printk(BIOS_DEBUG, "FSP MRC cache not present.\n");
- FspInitParams.NvsBufferPtr = (void *) NULL;
- } else {
- printk(BIOS_DEBUG, "FSP MRC cache present at %x.\n", (u32)mrc_cache);
- printk(BIOS_SPEW, "Saved MRC data:\n");
- hexdump32(BIOS_SPEW, (void *)mrc_cache->mrc_data, (mrc_cache->mrc_data_size / 4));
- FspInitParams.NvsBufferPtr = (void *) (EFI_HOB_GUID_TYPE *) mrc_cache->mrc_data;
- }
-#endif
-
- /* Not sure why passing BootMode is required - the only valid value is 0 */
- FspRtBuffer.Common.BootMode = 0;
- FspInitParams.RtBufferPtr = (FSP_INIT_RT_BUFFER *)&FspRtBuffer;
- FspInitParams.ContinuationFunc = (CONTINUATION_PROC)romstage_main_continue;
- FspInitApi = (FSP_FSP_INIT)(fsp_ptr->ImageBase + fsp_ptr->FspInitEntry);
-
- /* call back to romstage.c here to allow structures to be changed */
- romstage_fsp_rt_buffer_callback(&FspRtBuffer);
-
- FspInitApi(&FspInitParams);
-
- /* Should never return. Control will continue from ContinuationFunc */
- die("Uh Oh! FspInitApi returned");
-}
-#endif
-
-void __attribute__((optimize("O0"))) find_fsp ()
-{
-
-#ifdef __PRE_RAM__
- volatile register u8 *fsp_ptr asm ("eax");
-
- /* Entry point for CAR assembly routine */
- __asm__ __volatile__ (
- ".global find_fsp\n\t"
- "find_fsp:\n\t"
- );
-#else
- u8 *fsp_ptr;
-#endif
-
- /* The FSP is stored in CBFS */
- fsp_ptr = (u8 *) CONFIG_FSP_LOC;
-
- /* Check the FV signature, _FVH */
- if (((EFI_FIRMWARE_VOLUME_HEADER *)fsp_ptr)->Signature == 0x4856465F) {
- /* Go to the end of the FV header and align the address. */
- fsp_ptr += ((EFI_FIRMWARE_VOLUME_HEADER *)fsp_ptr)->ExtHeaderOffset;
- fsp_ptr += ((EFI_FIRMWARE_VOLUME_EXT_HEADER *)fsp_ptr)->ExtHeaderSize;
- fsp_ptr = (u8 *)(((u32)fsp_ptr + 7) & 0xFFFFFFF8);
- } else {
- fsp_ptr = (u8*)ERROR_NO_FV_SIG;
- }
-
- /* Check the FFS GUID */
- if (((u32)fsp_ptr > 0xff) &&
- (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[0] == 0x912740BE) &&
- (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[1] == 0x47342284) &&
- (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[2] == 0xB08471B9) &&
- (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[3] == 0x0C3F3527)) {
- /* Add the FFS Header size to the base to find the Raw section Header */
- fsp_ptr += sizeof(EFI_FFS_FILE_HEADER);
- } else {
- fsp_ptr = (u8 *)ERROR_NO_FFS_GUID;
- }
-
- if (((u32)fsp_ptr > 0xff) &&
- ((EFI_RAW_SECTION *)fsp_ptr)->Type == EFI_SECTION_RAW) {
- /* Add the Raw Header size to the base to find the FSP INFO Header */
- fsp_ptr += sizeof(EFI_RAW_SECTION);
- } else {
- fsp_ptr = (u8 *)ERROR_NO_INFO_HEADER;
- }
-
-#if 0 /* removed for debugging */
- /* Verify that the FSP is set to the base address we're expecting.*/
- if (((u32)fsp_ptr > 0xff) &&
- (*(u32*)(fsp_ptr + FSP_IMAGE_BASE_LOC) != CONFIG_FSP_LOC)) {
- fsp_ptr = (u8 *)ERROR_IMAGEBASE_MISMATCH;
- }
- /* Verify the FSP Signature */
- if (((u32)fsp_ptr > 0xff) &&
- (*(u32*)(fsp_ptr + FSP_IMAGE_SIG_LOC) != FSP_SIG)){
- fsp_ptr = (u8 *)ERROR_INFO_HEAD_SIG_MISMATCH;
- }
-
- /* Verify the FSP ID */
- if (((u32)fsp_ptr > 0xff) &&
- (*(u32 *)(fsp_ptr + FSP_IMAGE_ID_LOC) != CONFIG_FSP_IMAGE_ID_DWORD0)){
- fsp_ptr = (u8 *)ERROR_FSP_SIG_MISMATCH;
- }
- if (((u32)fsp_ptr > 0xff) &&
- (*(u32 *)(fsp_ptr + FSP_IMAGE_ID_LOC + 4) != CONFIG_FSP_IMAGE_ID_DWORD1)) {
- fsp_ptr = (u8 *)ERROR_FSP_SIG_MISMATCH;
- }
-#endif /* removed for debugging */
-
-#ifdef __PRE_RAM__
- __asm__ __volatile__ ("ret");
-#else
- fsp_header_ptr = (FSP_INFO_HEADER *) fsp_ptr;
- printk(BIOS_SPEW,"fsp_header_ptr: 0x%x\n", (u32)fsp_header_ptr);
- return;
-#endif
-}
-
-void print_fsp_info(void) {
-
-#ifndef __PRE_RAM__
- if (fsp_header_ptr == NULL)
- find_fsp();
-
- printk(BIOS_INFO,"FSP Header Version: %d\n", fsp_header_ptr->HeaderRevision);
- printk(BIOS_INFO,"FSP Revision: %d.%d\n",
- (u8)((fsp_header_ptr->ImageRevision >> 8) & 0xff),
- (u8)(fsp_header_ptr->ImageRevision & 0xff));
-#endif
-}
-
-#ifndef __PRE_RAM__ /* Only parse HOB data in ramstage */
-static void print_hob_mem_attributes(void *Hobptr) {
- EFI_HOB_MEMORY_ALLOCATION *HobMemoryPtr = (EFI_HOB_MEMORY_ALLOCATION *)Hobptr;
- EFI_MEMORY_TYPE Hobmemtype = HobMemoryPtr->AllocDescriptor.MemoryType;
- u64 Hobmemaddr = HobMemoryPtr->AllocDescriptor.MemoryBaseAddress;
- u64 Hobmemlength = HobMemoryPtr->AllocDescriptor.MemoryLength;
- const char * Hobmemtypenames[15];
-
- Hobmemtypenames[0] = "EfiReservedMemoryType";
- Hobmemtypenames[1] = "EfiLoaderCode";
- Hobmemtypenames[2] = "EfiLoaderData";
- Hobmemtypenames[3] = "EfiBootServicesCode";
- Hobmemtypenames[4] = "EfiBootServicesData";
- Hobmemtypenames[5] = "EfiRuntimeServicesCode";
- Hobmemtypenames[6] = "EfiRuntimeServicesData";
- Hobmemtypenames[7] = "EfiConventionalMemory";
- Hobmemtypenames[8] = "EfiUnusableMemory";
- Hobmemtypenames[9] = "EfiACPIReclaimMemory";
- Hobmemtypenames[10] = "EfiACPIMemoryNVS";
- Hobmemtypenames[11] = "EfiMemoryMappedIO";
- Hobmemtypenames[12] = "EfiMemoryMappedIOPortSpace";
- Hobmemtypenames[13] = "EfiPalCode";
- Hobmemtypenames[14] = "EfiMaxMemoryType";
-
- printk(BIOS_SPEW, " Memory type %s (0x%x)\n",
- Hobmemtypenames[(u32)Hobmemtype], (u32) Hobmemtype);
- printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
- (long unsigned int)Hobmemaddr, (long unsigned int)Hobmemlength);
-}
-
-static void print_hob_resource_attributes(void *Hobptr) {
- EFI_HOB_RESOURCE_DESCRIPTOR *HobResourcePtr = (EFI_HOB_RESOURCE_DESCRIPTOR *)Hobptr;
- u32 Hobrestype = HobResourcePtr->ResourceType;
- u32 Hobresattr = HobResourcePtr->ResourceAttribute;
- u64 Hobresaddr = HobResourcePtr->PhysicalStart;
- u64 Hobreslength = HobResourcePtr->ResourceLength;
- const char *Hobrestypestr = NULL;
-
- // HOB Resource Types
- switch (Hobrestype) {
- case EFI_RESOURCE_SYSTEM_MEMORY:
- Hobrestypestr = "EFI_RESOURCE_SYSTEM_MEMORY"; break;
- case EFI_RESOURCE_MEMORY_MAPPED_IO:
- Hobrestypestr = "EFI_RESOURCE_MEMORY_MAPPED_IO"; break;
- case EFI_RESOURCE_IO:
- Hobrestypestr = "EFI_RESOURCE_IO"; break;
- case EFI_RESOURCE_FIRMWARE_DEVICE:
- Hobrestypestr = "EFI_RESOURCE_FIRMWARE_DEVICE"; break;
- case EFI_RESOURCE_MEMORY_MAPPED_IO_PORT:
- Hobrestypestr = "EFI_RESOURCE_MEMORY_MAPPED_IO_PORT"; break;
- case EFI_RESOURCE_MEMORY_RESERVED:
- Hobrestypestr = "EFI_RESOURCE_MEMORY_RESERVED"; break;
- case EFI_RESOURCE_IO_RESERVED:
- Hobrestypestr = "EFI_RESOURCE_IO_RESERVED"; break;
- case EFI_RESOURCE_MAX_MEMORY_TYPE:
- Hobrestypestr = "EFI_RESOURCE_MAX_MEMORY_TYPE"; break;
- default:
- Hobrestypestr = "EFI_RESOURCE_UNKNOWN"; break;
- }
-
- printk(BIOS_SPEW, " Resource %s (0x%0x) has attributes 0x%0x\n",
- Hobrestypestr, Hobrestype, Hobresattr);
- printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
- (long unsigned int)Hobresaddr, (long unsigned int)Hobreslength);
-}
-
-static const char * get_hob_type_string(void *Hobptr) {
- EFI_HOB_GENERIC_HEADER *HobHeaderPtr = (EFI_HOB_GENERIC_HEADER *)Hobptr;
- u16 Hobtype = HobHeaderPtr->HobType;
- const char *Hobtypestring = NULL;
-
- switch (Hobtype) {
- case EFI_HOB_TYPE_HANDOFF:
- Hobtypestring = "EFI_HOB_TYPE_HANDOFF"; break;
- case EFI_HOB_TYPE_MEMORY_ALLOCATION:
- Hobtypestring = "EFI_HOB_TYPE_MEMORY_ALLOCATION"; break;
- case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
- Hobtypestring = "EFI_HOB_TYPE_RESOURCE_DESCRIPTOR"; break;
- case EFI_HOB_TYPE_GUID_EXTENSION:
- Hobtypestring = "EFI_HOB_TYPE_GUID_EXTENSION"; break;
- case EFI_HOB_TYPE_MEMORY_POOL:
- Hobtypestring = "EFI_HOB_TYPE_MEMORY_POOL"; break;
- case EFI_HOB_TYPE_UNUSED:
- Hobtypestring = "EFI_HOB_TYPE_UNUSED"; break;
- case EFI_HOB_TYPE_END_OF_HOB_LIST:
- Hobtypestring = "EFI_HOB_TYPE_END_OF_HOB_LIST"; break;
- default:
- Hobtypestring = "EFI_HOB_TYPE_UNRECOGNIZED"; break;
- }
-
- return Hobtypestring;
-}
-
-/* Print out a structure of all the HOBs
- * that match a certain type:
- * Print all types (0x0000)
- * EFI_HOB_TYPE_HANDOFF (0x0001)
- * EFI_HOB_TYPE_MEMORY_ALLOCATION (0x0002)
- * EFI_HOB_TYPE_RESOURCE_DESCRIPTOR (0x0003)
- * EFI_HOB_TYPE_GUID_EXTENSION (0x0004)
- * EFI_HOB_TYPE_MEMORY_POOL (0x0007)
- * EFI_HOB_TYPE_UNUSED (0xFFFE)
- * EFI_HOB_TYPE_END_OF_HOB_LIST (0xFFFF)
- */
-void print_hob_type_structure(u16 Hobtype, void *Hoblistptr) {
- u32 *Currenthob;
- u32 *Nexthob = 0;
- u8 Lasthob = 0;
- u32 Currenttype;
- const char *Currenttypestr;
-
- Currenthob = Hoblistptr;
-
- /* Print out HOBs of our desired type until
- * the end of the HOB list
- */
- printk(BIOS_DEBUG, "\n=== FSP HOB Data Structure ===\n");
- printk(BIOS_DEBUG, "FSP Hoblistptr: 0x%0x\n",
- (u32) Hoblistptr);
- do {
- EFI_HOB_GENERIC_HEADER *CurrentHeaderPtr = (EFI_HOB_GENERIC_HEADER *)Currenthob;
- Currenttype = CurrentHeaderPtr->HobType; // Get the type of this HOB
- Currenttypestr = get_hob_type_string(Currenthob);
-
- if (Currenttype == Hobtype || Hobtype == 0x0000) {
- printk(BIOS_DEBUG, "HOB 0x%0x is an %s (type 0x%0x)\n",
- (u32) Currenthob, Currenttypestr, Currenttype);
- switch (Currenttype) {
- case EFI_HOB_TYPE_MEMORY_ALLOCATION:
- print_hob_mem_attributes(Currenthob); break;
- case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
- print_hob_resource_attributes(Currenthob); break;
- }
- }
-
- Lasthob = END_OF_HOB_LIST(Currenthob); // Check for end of HOB list
- if (!Lasthob) {
- Nexthob = GET_NEXT_HOB(Currenthob); // Get next HOB pointer
- Currenthob = Nexthob; // Start on next HOB
- }
- } while (!Lasthob);
- printk(BIOS_DEBUG, "=== End of FSP HOB Data Structure ===\n\n");
-}
-
-#if CONFIG_ENABLE_FAST_BOOT
-/**
- * Save the FSP memory HOB (mrc data) to the MRC area in CBMEM
- */
-void save_mrc_data(void *hob_start)
-{
- u32 *mrc_hob;
- u32 *mrc_hob_data;
- u32 mrc_hob_size;
- struct mrc_data_container *mrc_data;
- int output_len;
- const EFI_GUID mrc_guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
-
- mrc_hob = GetNextGuidHob(&mrc_guid, hob_start);
- if (mrc_hob == NULL) die ("mrc_hob is NULL");
-
- mrc_hob_data = GET_GUID_HOB_DATA (mrc_hob);
- mrc_hob_size = (u32) GET_HOB_LENGTH(mrc_hob);
-
- printk(BIOS_DEBUG, "Memory Configure Data Hob at %p (size = 0x%x).\n",
- (void *)mrc_hob_data, mrc_hob_size);
-
- output_len = ALIGN(mrc_hob_size, 16);
-
- /* Save the MRC S3/Fastboot/ADR restore data to cbmem */
- mrc_data = cbmem_add (CBMEM_ID_MRCDATA,
- output_len + sizeof(struct mrc_data_container));
-
- /* Just return if there was a problem with getting CBMEM */
- if (mrc_data == NULL) return;
-
- printk(BIOS_DEBUG, "Copy FSP MRC DATA to HOB (source addr %p, dest addr %p, %u bytes)\n",
- (void *)mrc_hob_data, mrc_data, output_len);
-
- mrc_data->mrc_signature = MRC_DATA_SIGNATURE;
- mrc_data->mrc_data_size = output_len;
- mrc_data->reserved = 0;
- memcpy(mrc_data->mrc_data, (const void *)mrc_hob_data, mrc_hob_size);
-
- /* Zero the unused space in aligned buffer. */
- if (output_len > mrc_hob_size)
- memset((mrc_data->mrc_data + mrc_hob_size), 0,
- output_len - mrc_hob_size);
-
- mrc_data->mrc_checksum = compute_ip_checksum(mrc_data->mrc_data,
- mrc_data->mrc_data_size);
-
- printk(BIOS_SPEW, "MRC data in CBMEM(includes align and checksum):\n");
- hexdump32(BIOS_SPEW, (void *)mrc_data->mrc_data, (output_len / 4));
-}
-#endif
-#endif /*__PRE_RAM__*/
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp_util.h b/src/northbridge/intel/fsp_sandybridge/fsp_util.h
deleted file mode 100644
index d87cf58..0000000
--- a/src/northbridge/intel/fsp_sandybridge/fsp_util.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013 Sage Electronic Engineering, LLC.
- *
- * 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 FSP_UTIL_H
-#define FSP_UTIL_H
-
-#include <fsptypes.h>
-#include <fspfv.h>
-#include <fspffs.h>
-#include <fspapi.h>
-#include <fspplatform.h>
-#include <fspinfoheader.h>
-#include <fsphob.h>
-
-void fsp_early_init(FSP_INFO_HEADER *fsp_info);
-void FspNotify(u32 Phase);
-void romstage_main_continue(EFI_STATUS Status, VOID *HobListPtr);
-void print_hob_type_structure(u16 Hobtype, void *Hoblistptr);
-void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer);
-void print_fsp_info(void);
-
-#if CONFIG_ENABLE_FAST_BOOT
-void save_mrc_data(void *hob_start);
-#endif
-
-
-/* Additional HOB types not included in the FSP:
- * #define EFI_HOB_TYPE_HANDOFF 0x0001
- * #define EFI_HOB_TYPE_MEMORY_ALLOCATION 0x0002
- * #define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR 0x0003
- * #define EFI_HOB_TYPE_GUID_EXTENSION 0x0004
- * #define EFI_HOB_TYPE_FV 0x0005
- * #define EFI_HOB_TYPE_CPU 0x0006
- * #define EFI_HOB_TYPE_MEMORY_POOL 0x0007
- * #define EFI_HOB_TYPE_CV 0x0008
- * #define EFI_HOB_TYPE_UNUSED 0xFFFE
- * #define EFI_HOB_TYPE_END_OF_HOB_LIST 0xffff
- */
-#define EFI_HOB_TYPE_HANDOFF 0x0001
-#define EFI_HOB_TYPE_MEMORY_POOL 0x0007
-
-#if CONFIG_ENABLE_FAST_BOOT
-#define FSP_INFO_HEADER_GUID \
- { \
- 0x912740BE, 0x2284, 0x4734, {0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C} \
- }
-
-#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \
- { \
- 0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0 } \
- }
-#endif
-
-/* The offset in bytes from the start of the info structure */
-#define FSP_IMAGE_SIG_LOC 0
-#define FSP_IMAGE_ID_LOC 16
-#define FSP_IMAGE_BASE_LOC 28
-
-#define FSP_SIG 0x48505346 /* 'FSPH' */
-
-#define ERROR_NO_FV_SIG 1
-#define ERROR_NO_FFS_GUID 2
-#define ERROR_NO_INFO_HEADER 3
-#define ERROR_IMAGEBASE_MISMATCH 4
-#define ERROR_INFO_HEAD_SIG_MISMATCH 5
-#define ERROR_FSP_SIG_MISMATCH 6
-
-#ifndef __PRE_RAM__
-extern void *FspHobListPtr;
-#endif
-
-#endif /* FSP_UTIL_H */
diff --git a/src/northbridge/intel/fsp_sandybridge/mrccache.c b/src/northbridge/intel/fsp_sandybridge/mrccache.c
deleted file mode 100644
index b8893ae..0000000
--- a/src/northbridge/intel/fsp_sandybridge/mrccache.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Google Inc.
- * Copyright (C) 2013 Sage Electronic Engineering, LLC.
- *
- * 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 <stdint.h>
-#include <string.h>
-#include <bootstate.h>
-#include <console/console.h>
-#include <cbfs.h>
-#include <ip_checksum.h>
-#include <device/device.h>
-#include <cbmem.h>
-#include "northbridge.h"
-#include <spi-generic.h>
-#include <spi_flash.h>
-#include "fsp_util.h"
-
-/* convert a pointer to flash area into the offset inside the flash */
-static inline u32 to_flash_offset(void *p) {
- return ((u32)p + CONFIG_VIRTUAL_ROM_SIZE);
-}
-
-static struct mrc_data_container *next_mrc_block(
- struct mrc_data_container *mrc_cache)
-{
- /* MRC data blocks are aligned within the region */
- u32 mrc_size = sizeof(*mrc_cache) + mrc_cache->mrc_data_size;
- if (mrc_size & (MRC_DATA_ALIGN - 1UL)) {
- mrc_size &= ~(MRC_DATA_ALIGN - 1UL);
- mrc_size += MRC_DATA_ALIGN;
- }
-
- u8 *region_ptr = (u8*)mrc_cache;
- region_ptr += mrc_size;
- return (struct mrc_data_container *)region_ptr;
-}
-
-static int is_mrc_cache(struct mrc_data_container *mrc_cache)
-{
- return (!!mrc_cache) && (mrc_cache->mrc_signature == MRC_DATA_SIGNATURE);
-}
-
-static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr)
-{
- size_t region_size;
- *mrc_region_ptr = cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
- "mrc.cache", 0xac,
- ®ion_size);
-
- return region_size;
-}
-
-/*
- * Find the largest index block in the MRC cache. Return NULL if none is
- * found.
- */
-static struct mrc_data_container *find_current_mrc_cache_local
- (struct mrc_data_container *mrc_cache, u32 region_size)
-{
- u32 region_end;
- u32 entry_id = 0;
- struct mrc_data_container *mrc_next = mrc_cache;
-
- region_end = (u32) mrc_cache + region_size;
-
- /* Search for the last filled entry in the region */
- while (is_mrc_cache(mrc_next)) {
- entry_id++;
- mrc_cache = mrc_next;
- mrc_next = next_mrc_block(mrc_next);
- if ((u32)mrc_next >= region_end) {
- /* Stay in the MRC data region */
- break;
- }
- }
-
- if (entry_id == 0) {
- printk(BIOS_ERR, "%s: No valid MRC cache found.\n", __func__);
- return NULL;
- }
-
- /* Verify checksum */
- if (mrc_cache->mrc_checksum !=
- compute_ip_checksum(mrc_cache->mrc_data,
- mrc_cache->mrc_data_size)) {
- printk(BIOS_ERR, "%s: MRC cache checksum mismatch\n", __func__);
- return NULL;
- }
-
- printk(BIOS_DEBUG, "%s: picked entry %u from cache block\n", __func__,
- entry_id - 1);
-
- return mrc_cache;
-}
-
-/* SPI code needs malloc/free.
- * Also unknown if writing flash from XIP-flash code is a good idea
- */
-#if !defined(__PRE_RAM__)
-/* find the first empty block in the MRC cache area.
- * If there's none, return NULL.
- *
- * @mrc_cache_base - base address of the MRC cache area
- * @mrc_cache - current entry (for which we need to find next)
- * @region_size - total size of the MRC cache area
- */
-static struct mrc_data_container *find_next_mrc_cache
- (struct mrc_data_container *mrc_cache_base,
- struct mrc_data_container *mrc_cache,
- u32 region_size)
-{
- u32 region_end = (u32) mrc_cache_base + region_size;
- u32 mrc_data_size = mrc_cache->mrc_data_size;
-
- mrc_cache = next_mrc_block(mrc_cache);
- if (((u32)mrc_cache + mrc_data_size) >= region_end) {
- /* Crossed the boundary */
- mrc_cache = NULL;
- printk(BIOS_DEBUG, "%s: no available entries found\n",
- __func__);
- } else {
- printk(BIOS_DEBUG,
- "%s: picked next entry from cache block at %p\n",
- __func__, mrc_cache);
- }
-
- return mrc_cache;
-}
-
-static void update_mrc_cache(void *unused)
-{
- printk(BIOS_DEBUG, "Updating MRC cache data.\n");
- struct mrc_data_container *current = cbmem_find(CBMEM_ID_MRCDATA);
- struct mrc_data_container *cache, *cache_base;
- u32 cache_size;
-
- if (!current) {
- printk(BIOS_ERR, "No MRC cache in cbmem. Can't update flash.\n");
- return;
- }
- if (current->mrc_data_size == -1) {
- printk(BIOS_ERR, "MRC cache data in cbmem invalid.\n");
- return;
- }
-
- cache_size = get_mrc_cache_region(&cache_base);
- if (cache_base == NULL) {
- printk(BIOS_ERR, "%s: could not find MRC cache area\n",
- __func__);
- return;
- }
-
- /*
- * we need to:
- */
- // 0. compare MRC data to last mrc-cache block (exit if same)
- cache = find_current_mrc_cache_local(cache_base, cache_size);
-
- if (cache && (cache->mrc_data_size == current->mrc_data_size) &&
- (memcmp(cache, current, cache->mrc_data_size) == 0)) {
- printk(BIOS_DEBUG,
- "MRC data in flash is up to date. No update.\n");
- return;
- }
-
- // 1. use spi_flash_probe() to find the flash, then
- spi_init();
- struct spi_flash *flash = spi_flash_probe(0, 0, 1000000, SPI_MODE_3);
- if (!flash) {
- printk(BIOS_DEBUG, "Could not find SPI device\n");
- return;
- }
-
- // 2. look up the first unused block
- if (cache)
- cache = find_next_mrc_cache(cache_base, cache, cache_size);
-
- /*
- * 3. if no such place exists, erase entire mrc-cache range & use
- * block 0. First time around the erase is not needed, but this is a
- * small overhead for simpler code.
- */
- if (!cache) {
- printk(BIOS_DEBUG,
- "Need to erase the MRC cache region of %d bytes at %p\n",
- cache_size, cache_base);
-
- flash->erase(flash, to_flash_offset(cache_base), cache_size);
-
- /* we will start at the beginning again */
- cache = cache_base;
- }
- // 4. write mrc data with flash->write()
- printk(BIOS_DEBUG, "Write MRC cache update to flash at %p\n",
- cache);
- flash->write(flash, to_flash_offset(cache),
- current->mrc_data_size + sizeof(*current), current);
-}
-
-static void find_fsp_hob(void *unused)
-{
- /* Set the global HOB list pointer */
- FspHobListPtr = (void*)*((u32*) cbmem_find(CBMEM_ID_HOB_POINTER));
-
- if (!FspHobListPtr){
- printk(BIOS_ERR, "ERROR: Could not find FSP HOB pointer in CBFS!\n");
- } else {
- /* 0x0000: Print all types */
- print_hob_type_structure(0x000, FspHobListPtr);
-
- #if CONFIG_ENABLE_FAST_BOOT
- save_mrc_data(FspHobListPtr);
- update_mrc_cache(NULL);
- #endif
- }
-}
-
-BOOT_STATE_INIT_ENTRIES(fsp_hob_find) = {
- BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY,
- find_fsp_hob, NULL),
-};
-#endif /* !defined(__PRE_RAM__) */
-
-struct mrc_data_container *find_current_mrc_cache(void)
-{
- struct mrc_data_container *cache_base;
- u32 cache_size;
-
- cache_size = get_mrc_cache_region(&cache_base);
- if (cache_base == NULL) {
- printk(BIOS_ERR, "%s: could not find MRC cache area\n",
- __func__);
- return NULL;
- }
-
- /*
- * we need to:
- */
- // 0. compare MRC data to last mrc-cache block (exit if same)
- return find_current_mrc_cache_local(cache_base, cache_size);
-}
diff --git a/src/northbridge/intel/fsp_sandybridge/northbridge.c b/src/northbridge/intel/fsp_sandybridge/northbridge.c
index 20595ee..d5b1575 100644
--- a/src/northbridge/intel/fsp_sandybridge/northbridge.c
+++ b/src/northbridge/intel/fsp_sandybridge/northbridge.c
@@ -36,7 +36,7 @@
#include <cbmem.h>
#include "chip.h"
#include "northbridge.h"
-#include "fsp_util.h"
+#include <fsp_util.h>
static int bridge_revision_id = -1;
static u8 finished_FSP_after_pci = 0;
diff --git a/src/northbridge/intel/fsp_sandybridge/northbridge.h b/src/northbridge/intel/fsp_sandybridge/northbridge.h
index 3179832..9a0cf42 100644
--- a/src/northbridge/intel/fsp_sandybridge/northbridge.h
+++ b/src/northbridge/intel/fsp_sandybridge/northbridge.h
@@ -226,15 +226,6 @@ void report_platform_info(void);
#define MRC_DATA_ALIGN 0x1000
#define MRC_DATA_SIGNATURE (('M'<<0)|('R'<<8)|('C'<<16)|('D'<<24))
-struct mrc_data_container {
- u32 mrc_signature; // "MRCD"
- u32 mrc_data_size; // Actual total size of this structure
- u32 mrc_checksum; // IP style checksum
- u32 reserved; // For header alignment
- u8 mrc_data[0]; // Variable size, platform/run time dependent.
-} __attribute__ ((packed));
-
-struct mrc_data_container *find_current_mrc_cache(void);
#if !defined(__PRE_RAM__)
#include "gma.h"
int init_igd_opregion(igd_opregion_t *igd_opregion);
diff --git a/src/northbridge/intel/fsp_sandybridge/northbridge_pci_devs.h b/src/northbridge/intel/fsp_sandybridge/northbridge_pci_devs.h
new file mode 100644
index 0000000..5713712
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/northbridge_pci_devs.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC.
+ *
+ * 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_FSP_SANDYBRIDGE_PCI_DEVS_H_
+#define _INTEL_FSP_SANDYBRIDGE_PCI_DEVS_H_
+
+#include <device/pci_def.h>
+
+#define BUS0 0
+
+/* NB PCIe PEG slot */
+#define NB_PEG_DEV 0x01
+#define NB_PEG_FUNC 0
+# define NB_PEG_DEVFN PCI_DEVFN(NB_PEG_DEV, NB_PEG_FUNC)
+#define PCIE_CTRL1_FUNC 1
+# define PCIE_CTRL1_DEVFN PCI_DEVFN(NB_PEG_DEV, PCIE_CTRL1_FUNC)
+#define PCIE_CTRL2_FUNC 2
+# define PCIE_CTRL2_DEVFN PCI_DEVFN(NB_PEG_DEV, PCIE_CTRL2_FUNC)
+
+/* Onboard Graphics */
+#define GFX_DEV 0x02
+#define GFX_FUNC 0
+# define GFX_DEVFN PCI_DEVFN(GFX_DEV, GFX_FUNC)
+
+/* NB PCIe slot */
+#define NB_PCIE_DEV 0x06
+#define NB_PCIE_FUNC 0
+# define NB_PCIE_DEVFN PCI_DEVFN(NB_PCIE_DEV, NB_PCIE_FUNC)
+
+#endif /* _INTEL_FSP_SANDYBRIDGE_PCI_DEVS_H_ */
diff --git a/src/southbridge/intel/fsp_bd82x6x/Makefile.inc b/src/southbridge/intel/fsp_bd82x6x/Makefile.inc
index 7088caa..a1d3e62 100644
--- a/src/southbridge/intel/fsp_bd82x6x/Makefile.inc
+++ b/src/southbridge/intel/fsp_bd82x6x/Makefile.inc
@@ -69,3 +69,5 @@ else
endif
PHONY += bd82x6x_add_me
+
+INCLUDES += -I$(src)/southbridge/intel/fsp_bd82x6x
diff --git a/src/southbridge/intel/fsp_bd82x6x/southbridge_pci_devs.h b/src/southbridge/intel/fsp_bd82x6x/southbridge_pci_devs.h
new file mode 100644
index 0000000..1f991d7
--- /dev/null
+++ b/src/southbridge/intel/fsp_bd82x6x/southbridge_pci_devs.h
@@ -0,0 +1,127 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC.
+ *
+ * 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_FSP_BD82X6X_PCI_DEVS_H_
+#define _INTEL_FSP_BD82X6X_PCI_DEVS_H_
+
+#include <device/pci_def.h>
+
+#define BUS0 0
+
+/* XHCI */
+#define XHCI_DEV 0x14
+#define XHCI_FUNC 0
+# define XHCI_DEVFN PCI_DEVFN(XHCI_DEV, XHCI_FUNC)
+
+/* Management Engine Interface */
+#define MEI_DEV 0x16
+#define MEI1_FUNC 0x0
+# define MEI1_DEVFN PCI_DEVFN(MEI_DEV, MEI1_FUNC)
+
+#define MEI2_FUNC 0x1
+# define MEI2_DEVFN PCI_DEVFN(MEI_DEV, MEI2_FUNC)
+
+/* MEI - IDE Redirection */
+#define IDE_DEV 0x16
+#define IDE_FUNC 2
+# define IDE_DEVFN PCI_DEVFN(IDE_DEV, IDE_FUNC)
+
+/* MEI - Keyboard / Text Redirection */
+#define KT_DEV 0x16
+#define KT_FUNC 0x3
+#define KT_DEVFN PCI_DEVFN(KT_DEV, KT_FUNC)
+
+/* Gigabit Ethernet */
+#define GBE_DEV 0x19
+#define GBE_FUNC 0x0
+#define GBE_DEVFN PCI_DEVFN(GBE_DEV, GBE_FUNC)
+
+/* EHCI */
+#define EHCI1_DEV 0x1D
+#define EHCI1_FUNC 0
+# define EHCI1_DEVFN PCI_DEVFN(EHCI1_DEV, EHCI1_FUNC)
+
+#define EHCI2_DEV 0x1A
+#define EHCI2_FUNC 0
+# define EHCI2_DEVFN PCI_DEVFN(EHCI2_DEV, EHCI2_FUNC)
+
+/* HD Audio */
+#define HDA_DEV 0x1B
+#define HDA_FUNC 0
+# define HDA_DEVFN PCI_DEVFN(HDA_DEV, HDA_FUNC)
+
+/* PCIe Ports */
+#define SB_PCIE_DEV 0x1C
+#define SB_PCIE_PORT1_FUNC 0
+# define SB_PCIE_PORT1_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT1_FUNC)
+
+#define SB_PCIE_PORT2_FUNC 1
+# define SB_PCIE_PORT2_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT2_FUNC)
+
+#define SB_PCIE_PORT3_FUNC 2
+# define SB_PCIE_PORT3_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT3_FUNC)
+
+#define SB_PCIE_PORT4_FUNC 3
+# define SB_PCIE_PORT4_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT4_FUNC)
+
+#define SB_PCIE_PORT5_FUNC 4
+# define SB_PCIE_PORT5_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT5_FUNC)
+
+#define SB_PCIE_PORT6_FUNC 5
+# define SB_PCIE_PORT6_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT6_FUNC)
+
+#define SB_PCIE_PORT7_FUNC 6
+# define SB_PCIE_PORT7_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT7_FUNC)
+
+#define SB_PCIE_PORT8_FUNC 7
+# define SB_PCIE_PORT8_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT8_FUNC)
+
+/* PCI Bridge */
+#define SB_PCI_DEV 0x1E
+#define SB_PCI_PORT_FUNC 0
+# define SB_PCI_PORT_DEVFN PCI_DEVFN(SB_PCI_PORT_DEV, SB_PCI_PORT_FUNC)
+
+/* Platform Controller Hub */
+#define PCH_DEV 0x1F
+
+/* LPC */
+#define LPC_DEV PCH_DEV
+#define LPC_FUNC 0
+# define LPC_DEVFN PCI_DEVFN(LPC_DEV, LPC_FUNC)
+
+/* SMBUS */
+#define SMBUS_DEV PCH_DEV
+#define SMBUS_FUNC 3
+# define SMBUS_DEVFN PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC)
+
+/* SATA */
+#define SATA_DEV PCH_DEV
+#define SATA1_FUNC 2
+# define SATA1_DEVFN PCI_DEVFN(SATA_DEV, SATA1_FUNC)
+
+#define SATA2_FUNC 5
+# define SATA2_DEVFN PCI_DEVFN(SATA_DEV, SATA2_FUNC)
+
+/* Thermal Sensor */
+#define TS_DEV PCH_DEV
+#define TS_FUNC 6
+# define TS_DEVFN PCI_DEVFN(TS_DEV, TS_FUNC)
+
+#endif /* _INTEL_FSP_BD82X6X_PCI_DEVS_H_ */
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5673
-gerrit
commit 241e099f931c14237193128b0286e4baf8fa7f7d
Author: Furquan Shaikh <furquan(a)google.com>
Date: Tue May 6 18:00:19 2014 -0700
Arch-level Kconfig menu cleanup
Remove arch-level Kconfig menu option as it shows all available architectures in
make menuconfig. Instead pull the bootblock options for choice and update image
to top-level Kconfig since it is already present for both x86 and arm.
Change-Id: Iab9c4539f05cd54a7f751565fefcaf7b6f0edc86
Signed-off-by: Furquan Shaikh <furquan(a)google.com>
---
src/Kconfig | 26 ++++++++++++++++++++++++++
src/arch/armv7/Kconfig | 30 ------------------------------
src/arch/x86/Kconfig | 33 ---------------------------------
3 files changed, 26 insertions(+), 63 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig
index 849e55d..dcfce06 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -242,6 +242,32 @@ source src/arch/armv7/Kconfig
source src/vendorcode/Kconfig
+choice
+ prompt "Bootblock behaviour"
+ default BOOTBLOCK_SIMPLE
+
+config BOOTBLOCK_SIMPLE
+ bool "Always load fallback"
+
+config BOOTBLOCK_NORMAL
+ bool "Switch to normal if CMOS says so"
+
+endchoice
+
+config BOOTBLOCK_SOURCE
+ string
+ default "bootblock_simple.c" if BOOTBLOCK_SIMPLE
+ default "bootblock_normal.c" if BOOTBLOCK_NORMAL
+
+config UPDATE_IMAGE
+ bool "Update existing coreboot.rom image"
+ default n
+ help
+ If this option is enabled, no new coreboot.rom file
+ is created. Instead it is expected that there already
+ is a suitable file for further processing.
+ The bootblock will not be modified.
+
menu "Chipset"
comment "CPU"
diff --git a/src/arch/armv7/Kconfig b/src/arch/armv7/Kconfig
index e541074..ec24e17 100644
--- a/src/arch/armv7/Kconfig
+++ b/src/arch/armv7/Kconfig
@@ -1,5 +1,3 @@
-menu "Architecture (armv7)"
-
config ARCH_BOOTBLOCK_ARMV7
bool
default n
@@ -12,31 +10,3 @@ config ARCH_ROMSTAGE_ARMV7
config ARCH_RAMSTAGE_ARMV7
bool
default n
-
-choice
- prompt "Bootblock behaviour"
- default ARM_BOOTBLOCK_SIMPLE
-
-config ARM_BOOTBLOCK_SIMPLE
- bool "Always load fallback"
-
-config ARM_BOOTBLOCK_NORMAL
- bool "Switch to normal if non-volatile memory says so"
-
-endchoice
-
-config BOOTBLOCK_SOURCE
- string
- default "bootblock_simple.c" if ARM_BOOTBLOCK_SIMPLE
- default "bootblock_normal.c" if ARM_BOOTBLOCK_NORMAL
-
-config UPDATE_IMAGE
- bool "Update existing coreboot.rom image"
- default n
- help
- If this option is enabled, no new coreboot.rom file
- is created. Instead it is expected that there already
- is a suitable file for further processing.
- The bootblock will not be modified.
-
-endmenu
diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig
index 1ce11df..c2e0624 100644
--- a/src/arch/x86/Kconfig
+++ b/src/arch/x86/Kconfig
@@ -1,5 +1,3 @@
-menu "Architecture (x86)"
-
config ARCH_BOOTBLOCK_X86_32
bool
default n
@@ -49,35 +47,6 @@ config NUM_IPI_STARTS
int
default 2
-# We had to rename the choice options under arch/ because otherwise
-# the options would conflict between different architectures despite
-# the if ARCH_xxx guarding the arch/xxx/Kconfig sourcing.
-choice
- prompt "Bootblock behaviour"
- default X86_BOOTBLOCK_SIMPLE
-
-config X86_BOOTBLOCK_SIMPLE
- bool "Always load fallback"
-
-config X86_BOOTBLOCK_NORMAL
- bool "Switch to normal if CMOS says so"
-
-endchoice
-
-config BOOTBLOCK_SOURCE
- string
- default "bootblock_simple.c" if X86_BOOTBLOCK_SIMPLE
- default "bootblock_normal.c" if X86_BOOTBLOCK_NORMAL
-
-config UPDATE_IMAGE
- bool "Update existing coreboot.rom image"
- default n
- help
- If this option is enabled, no new coreboot.rom file
- is created. Instead it is expected that there already
- is a suitable file for further processing.
- The bootblock will not be modified.
-
config ROMCC
bool
default n
@@ -118,5 +87,3 @@ config HPET_ADDRESS
config ID_SECTION_OFFSET
hex
default 0x80
-
-endmenu
Martin Roth (martin.roth(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5635
-gerrit
commit 619dbbb4eb54eeb717d553ef6d2ec611168f5660
Author: Martin Roth <gaumless(a)gmail.com>
Date: Fri Apr 25 14:12:13 2014 -0600
Intel FSP: add a shared set of functions for the FSP
- Move the non chipset-specific fsp pieces out of the chipset into a
shared area. This is used by northbridge / southbrige / SOC code. It
pulls in pieces from Kconfig, Makefile and FSP specific code.
- Enabled in the CPU code with a Kconfig "select PLATFORM_USES_FSP"
Change-Id: I7ffa934c1df09b71d48a876a56e3b888685870b8
Signed-off-by: Martin Roth <gaumless(a)gmail.com>
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
---
src/Kconfig | 1 +
src/cpu/x86/Kconfig | 7 +
src/drivers/intel/Makefile.inc | 1 +
src/drivers/intel/fsp/Kconfig | 143 +++++++++++
src/drivers/intel/fsp/Makefile.inc | 48 ++++
src/drivers/intel/fsp/cache_as_ram.inc | 169 +++++++++++++
src/drivers/intel/fsp/fastboot_cache.c | 253 +++++++++++++++++++
src/drivers/intel/fsp/fsp_util.c | 432 +++++++++++++++++++++++++++++++++
src/drivers/intel/fsp/fsp_util.h | 95 ++++++++
src/include/timestamp.h | 4 +
10 files changed, 1153 insertions(+)
diff --git a/src/Kconfig b/src/Kconfig
index 849e55d..48e688f 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -256,6 +256,7 @@ comment "Embedded Controllers"
source src/ec/Kconfig
comment "SoC"
source src/soc/Kconfig
+source src/drivers/intel/fsp/Kconfig
endmenu
diff --git a/src/cpu/x86/Kconfig b/src/cpu/x86/Kconfig
index b5bb7e6..5c37861 100644
--- a/src/cpu/x86/Kconfig
+++ b/src/cpu/x86/Kconfig
@@ -109,6 +109,13 @@ config X86_AMD_FIXED_MTRRS
This option informs the MTRR code to use the RdMem and WrMem fields
in the fixed MTRR MSRs.
+config PLATFORM_USES_FSP
+ bool
+ default n
+ help
+ Selected for Intel processors/platform combinations that use the
+ Intel Firmware Support Package (FSP) for initialization.
+
config PARALLEL_MP
def_bool n
help
diff --git a/src/drivers/intel/Makefile.inc b/src/drivers/intel/Makefile.inc
index eb8617c..12f7003 100644
--- a/src/drivers/intel/Makefile.inc
+++ b/src/drivers/intel/Makefile.inc
@@ -1 +1,2 @@
subdirs-y += gma
+subdirs-$(CONFIG_PLATFORM_USES_FSP) += fsp
diff --git a/src/drivers/intel/fsp/Kconfig b/src/drivers/intel/fsp/Kconfig
new file mode 100644
index 0000000..af30417
--- /dev/null
+++ b/src/drivers/intel/fsp/Kconfig
@@ -0,0 +1,143 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 Sage Electronic Engineering, LLC.
+##
+## 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
+##
+
+if PLATFORM_USES_FSP
+
+comment "Intel FSP"
+
+config HAVE_FSP_BIN
+ bool "Use Intel Firmware Support Package"
+ help
+ Select this option to add an Intel FSP binary to
+ the resulting coreboot image.
+
+ Note: Without this binary, coreboot builds relying on the FSP
+ will not boot
+
+config DCACHE_RAM_BASE
+ hex
+ default 0xfef00000
+
+config DCACHE_RAM_SIZE
+ hex
+ default 0x4000
+
+if HAVE_FSP_BIN
+
+config FSP_FILE
+ string "Intel FSP binary path and filename"
+ help
+ The path and filename of the Intel FSP binary for this platform.
+
+config FSP_LOC
+ hex "Intel FSP Binary location in CBFS"
+ help
+ The location in CBFS that the FSP is located. This must match the
+ value that is set in the FSP binary. If the FSP needs to be moved,
+ rebase the FSP with Intel's BCT (tool).
+
+config ENABLE_FSP_FAST_BOOT
+ bool "Enable Fast Boot"
+ default n
+ help
+ Enabling this feature will force the MRC data to be cached in NV
+ storage to be used for speeding up boot time on future reboots
+ and/or power cycles.
+
+config ENABLE_MRC_CACHE
+ bool
+ default ENABLE_FSP_FAST_BOOT
+ help
+ Enabling this feature will cause MRC data to be cached in NV storage.
+ This can either be used for fastboot, or just because the FSP wants
+ it to be saved.
+
+config MRC_CACHE_SIZE
+ hex "Fastboot Data Cache Size"
+ default 0x10000
+ depends on ENABLE_MRC_CACHE
+ help
+ This is the amount of space in NV storage that is reserved for the
+ fastboot data cache storage.
+
+ WARNING: Because this area will be erased and re-written, the size
+ should be a full sector of the flash ROM chip and nothing else should
+ be included in CBFS in any sector that the fast boot cache data is in.
+
+config OVERRIDE_CACHE_CACHE_LOC
+ bool
+ help
+ Selected by the platform to set a new default location for the
+ MRC/fast boot cache.
+
+config MRC_CACHE_LOC_OVERRIDE
+ hex
+ help
+ Sets the override CBFS location of the MRC/fast boot cache.
+
+config MRC_CACHE_LOC
+ hex "Fast Boot Data Cache location in CBFS"
+ default MRC_CACHE_LOC_OVERRIDE if OVERRIDE_CACHE_CACHE_LOC
+ default 0xfff50000
+ depends on ENABLE_MRC_CACHE
+ help
+ The location in CBFS for the MRC data to be cached.
+
+ WARNING: This should be on a sector boundary of the BIOS ROM chip
+ and nothing else should be included in that sector, or IT WILL BE
+ ERASED.
+
+config VIRTUAL_ROM_SIZE
+ hex "Virtual ROM Size"
+ default ROM_SIZE
+ depends on ENABLE_MRC_CACHE
+ help
+ This is used to calculate the offset of the MRC data cache in NV
+ Storage for fast boot. If in doubt, leave this set to the default
+ which sets the virtual size equal to the ROM size.
+
+ Example: Cougar Canyon 2 has two 8 MB SPI ROMs. When the SPI ROMs are
+ loaded with a 4 MB coreboot image, the virtual ROM size is 8 MB. When
+ the SPI ROMs are loaded with an 8 MB coreboot image, the virtual ROM
+ size is 16 MB.
+
+endif #HAVE_FSP_BIN
+
+config CACHE_ROM_SIZE_OVERRIDE
+ hex "Cache ROM Size"
+ default CBFS_SIZE
+ help
+ This is the size of the cachable area that is passed into the FSP in
+ the early initialization. Typically this should be the size of the CBFS
+ area, but the size must be a power of 2 whereas the CBFS size does not
+ have this limitation.
+
+config USE_GENERIC_FSP_CAR_INC
+ bool
+ default n
+ help
+ The chipset can select this to use a generic cache_as_ram.inc file
+ that should be good for all FSP based platforms.
+
+config FSP_USES_UPD
+ bool
+ default n
+ help
+ If this FSP uses UPD/VPD data regions, select this in the chipset Kconfig.
+endif #PLATFORM_USES_FSP
diff --git a/src/drivers/intel/fsp/Makefile.inc b/src/drivers/intel/fsp/Makefile.inc
new file mode 100644
index 0000000..9e083ec
--- /dev/null
+++ b/src/drivers/intel/fsp/Makefile.inc
@@ -0,0 +1,48 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2014 Sage Electronic Engineering, LLC.
+#
+# 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
+#
+
+ramstage-y += fsp_util.c
+romstage-y += fsp_util.c
+ramstage-$(CONFIG_ENABLE_MRC_CACHE) += fastboot_cache.c
+romstage-$(CONFIG_ENABLE_MRC_CACHE) += fastboot_cache.c
+
+INCLUDES += -Isrc/drivers/intel/fsp
+
+ifeq ($(CONFIG_USE_GENERIC_FSP_CAR_INC),y)
+cpu_incs += $(src)/drivers/intel/fsp/cache_as_ram.inc
+endif
+
+ifeq ($(CONFIG_HAVE_FSP_BIN),y)
+cbfs-files-y += fsp.bin
+fsp.bin-file := $(call strip_quotes,$(CONFIG_FSP_FILE))
+fsp.bin-position := $(CONFIG_FSP_LOC)
+fsp.bin-type := 0xab
+endif
+
+ifeq ($(CONFIG_ENABLE_MRC_CACHE),y)
+$(obj)/mrc.cache:
+ dd if=/dev/zero count=1 \
+ bs=$(shell printf "%d" $(CONFIG_MRC_CACHE_SIZE) ) | \
+ tr '\000' '\377' > $@
+
+cbfs-files-y += mrc.cache
+mrc.cache-file := $(obj)/mrc.cache
+mrc.cache-position := $(CONFIG_MRC_CACHE_LOC)
+mrc.cache-type := 0xac
+endif
diff --git a/src/drivers/intel/fsp/cache_as_ram.inc b/src/drivers/intel/fsp/cache_as_ram.inc
new file mode 100644
index 0000000..0e2f678
--- /dev/null
+++ b/src/drivers/intel/fsp/cache_as_ram.inc
@@ -0,0 +1,169 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich(a)gmail.com>
+ * Copyright (C) 2007-2008 coresystems GmbH
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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 <cpu/x86/stack.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/post_code.h>
+#include <cbmem.h>
+
+#ifndef CONFIG_FSP_LOC
+# error "CONFIG_FSP_LOC must be set."
+#endif
+
+#ifndef CONFIG_POST_IO
+# error "CONFIG_POST_IO must be set."
+#endif
+
+#if CONFIG_POST_IO
+# ifndef CONFIG_POST_IO_PORT
+# error "CONFIG_POST_IO_PORT must be set."
+# endif
+#endif
+
+#ifndef CONFIG_CPU_MICROCODE_CBFS_LOC
+# error "CONFIG_CPU_MICROCODE_CBFS_LOC must be set."
+#endif
+
+#define LHLT_DELAY 0x50000 /* I/O delay between post codes on failure */
+
+ cmp $0, %eax
+ jne bisthalt
+
+cache_as_ram:
+ post_code(0x20)
+
+ /*
+ * Find the FSP binary in cbfs.
+ * Make a fake stack that has the return value back to this code.
+ */
+ lea fake_fsp_stack, %esp
+ jmp find_fsp
+find_fsp_ret:
+ /* Save the FSP location */
+ mov %eax, %ebp
+ cmp $CONFIG_FSP_LOC, %eax
+ jb halt1
+
+ post_code(0x22)
+
+ /* Calculate entry into FSP */
+ mov 0x30(%ebp), %eax /* Load TempRamInitEntry */
+ add 0x1c(%ebp), %eax /* add in the offset for the FSP base address */
+
+ /*
+ * Pass early init variables on a fake stack (no memory yet)
+ * as well as the return location
+ */
+ lea CAR_init_stack, %esp
+
+ /* call FSP binary to setup temporary stack */
+ jmp *%eax
+
+CAR_init_done:
+ addl $4, %esp
+ cmp $0, %eax
+ jne halt2
+
+ /* Save FSP_INFO_HEADER location in ebx */
+ mov %ebp, %ebx
+
+ /*
+ * set up bootloader stack
+ * ecx: stack base
+ * edx: stack top
+ */
+ lea -4(%edx), %esp
+ movl %esp, %ebp
+ pushl %ebx
+
+before_romstage:
+ post_code(0x23)
+
+ /* Call romstage.c main function. */
+ call main /* does not return */
+ movb $0xB8, %ah
+ jmp .Lhlt
+
+bisthalt:
+ movb $0xB9, %ah
+ jmp .Lhlt
+
+halt1:
+ /*
+ * Failures for postcode 0xBA - failed in find_fsp()
+ *
+ * Values are:
+ * 0x01 - FV signature, "_FVH" not present
+ * 0x02 - FFS GUID not present
+ * 0x03 - FSP INFO Header not found
+ * 0x04 - ImageBase does not equal CONFIG_FSP_LOC - Is the FSP rebased to
+ * a different location, or does it need to be?
+ * 0x05 - FSP INFO Header signature "FSPH" not found
+ * 0x06 - FSP Image ID is not the expected ID.
+ */
+ movb $0xBA, %ah
+ jmp .Lhlt
+
+halt2:
+ /*
+ * Failures for postcode 0xBB - failed in the FSP:
+ *
+ * 0x00 - FSP_SUCCESS: Temp RAM was initialized successfully.
+ * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid.
+ * 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode region.
+ * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
+ * 0x07 - FSP_DEVICE_ERROR: Temp RAM initialization failed
+ * 0x14 - FSP_ALREADY_STARTED: Temp RAM initialization has been invoked
+ */
+ movb $0xBB, %ah
+
+.Lhlt:
+ xchg %al, %ah
+#if CONFIG_POST_IO
+ outb %al, $CONFIG_POST_IO_PORT
+#else
+ post_code(POST_DEAD_CODE)
+#endif
+ movl $LHLT_DELAY, %ecx
+.Lhlt_Delay:
+ outb %al, $0xED
+ loop .Lhlt_Delay
+ jmp .Lhlt
+
+/*
+ * esp is set to this location so that the call into and return from the FSP
+ * in find_fsp will work.
+ */
+ .align 4
+fake_fsp_stack:
+ .long find_fsp_ret
+
+CAR_init_params:
+ .long CONFIG_CPU_MICROCODE_CBFS_LOC
+ .long CONFIG_CPU_MICROCODE_CBFS_LEN
+ .long 0xFFFFFFFF - CACHE_ROM_SIZE + 1 /* Firmware Location */
+ .long CACHE_ROM_SIZE /* Total Firmware Length */
+
+CAR_init_stack:
+ .long CAR_init_done
+ .long CAR_init_params
+
diff --git a/src/drivers/intel/fsp/fastboot_cache.c b/src/drivers/intel/fsp/fastboot_cache.c
new file mode 100644
index 0000000..f88d6f6
--- /dev/null
+++ b/src/drivers/intel/fsp/fastboot_cache.c
@@ -0,0 +1,253 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Google Inc.
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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 <stdint.h>
+#include <string.h>
+#include <bootstate.h>
+#include <console/console.h>
+#include <cbfs.h>
+#include <ip_checksum.h>
+#include <device/device.h>
+#include <cbmem.h>
+#include <spi-generic.h>
+#include <spi_flash.h>
+#include <lib.h> // hexdump
+#include "fsp_util.h"
+
+#ifndef CONFIG_VIRTUAL_ROM_SIZE
+#error "CONFIG_VIRTUAL_ROM_SIZE must be set."
+#endif
+
+/* convert a pointer to flash area into the offset inside the flash */
+static inline u32 to_flash_offset(void *p) {
+ return ((u32)p + CONFIG_VIRTUAL_ROM_SIZE);
+}
+
+static struct mrc_data_container *next_mrc_block(
+ struct mrc_data_container *mrc_cache)
+{
+ /* MRC data blocks are aligned within the region */
+ u32 mrc_size = sizeof(*mrc_cache) + mrc_cache->mrc_data_size;
+ if (mrc_size & (MRC_DATA_ALIGN - 1UL)) {
+ mrc_size &= ~(MRC_DATA_ALIGN - 1UL);
+ mrc_size += MRC_DATA_ALIGN;
+ }
+
+ u8 *region_ptr = (u8*)mrc_cache;
+ region_ptr += mrc_size;
+ return (struct mrc_data_container *)region_ptr;
+}
+
+static int is_mrc_cache(struct mrc_data_container *mrc_cache)
+{
+ return (!!mrc_cache) && (mrc_cache->mrc_signature == MRC_DATA_SIGNATURE);
+}
+
+static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr)
+{
+ size_t region_size;
+ *mrc_region_ptr = cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
+ "mrc.cache", 0xac,
+ ®ion_size);
+
+ return region_size;
+}
+
+/*
+ * Find the largest index block in the MRC cache. Return NULL if none is
+ * found.
+ */
+static struct mrc_data_container *find_current_mrc_cache_local
+ (struct mrc_data_container *mrc_cache, u32 region_size)
+{
+ u32 region_end;
+ u32 entry_id = 0;
+ struct mrc_data_container *mrc_next = mrc_cache;
+
+ region_end = (u32) mrc_cache + region_size;
+
+ /* Search for the last filled entry in the region */
+ while (is_mrc_cache(mrc_next)) {
+ entry_id++;
+ mrc_cache = mrc_next;
+ mrc_next = next_mrc_block(mrc_next);
+ if ((u32)mrc_next >= region_end) {
+ /* Stay in the MRC data region */
+ break;
+ }
+ }
+
+ if (entry_id == 0) {
+ printk(BIOS_ERR, "%s: No valid fastboot cache found.\n", __func__);
+ return NULL;
+ }
+
+ /* Verify checksum */
+ if (mrc_cache->mrc_checksum !=
+ compute_ip_checksum(mrc_cache->mrc_data,
+ mrc_cache->mrc_data_size)) {
+ printk(BIOS_ERR, "%s: fastboot cache checksum mismatch\n", __func__);
+ return NULL;
+ }
+
+ printk(BIOS_DEBUG, "%s: picked entry %u from cache block\n", __func__,
+ entry_id - 1);
+
+ return mrc_cache;
+}
+
+/* SPI code needs malloc/free.
+ * Also unknown if writing flash from XIP-flash code is a good idea
+ */
+#if !defined(__PRE_RAM__)
+/* find the first empty block in the MRC cache area.
+ * If there's none, return NULL.
+ *
+ * @mrc_cache_base - base address of the MRC cache area
+ * @mrc_cache - current entry (for which we need to find next)
+ * @region_size - total size of the MRC cache area
+ */
+static struct mrc_data_container *find_next_mrc_cache
+ (struct mrc_data_container *mrc_cache_base,
+ struct mrc_data_container *mrc_cache,
+ u32 region_size)
+{
+ u32 region_end = (u32) mrc_cache_base + region_size;
+ u32 mrc_data_size = mrc_cache->mrc_data_size;
+
+ mrc_cache = next_mrc_block(mrc_cache);
+ if (((u32)mrc_cache + mrc_data_size) >= region_end) {
+ /* Crossed the boundary */
+ mrc_cache = NULL;
+ printk(BIOS_DEBUG, "%s: no available entries found\n",
+ __func__);
+ } else {
+ printk(BIOS_DEBUG,
+ "%s: picked next entry from cache block at %p\n",
+ __func__, mrc_cache);
+ }
+
+ return mrc_cache;
+}
+
+void update_mrc_cache(void *unused)
+{
+ printk(BIOS_DEBUG, "Updating fastboot cache data.\n");
+ struct mrc_data_container *current = cbmem_find(CBMEM_ID_MRCDATA);
+ struct mrc_data_container *cache, *cache_base;
+ u32 cache_size;
+
+ if (!current) {
+ printk(BIOS_ERR, "No fastboot cache in cbmem. Can't update flash.\n");
+ return;
+ }
+ if (current->mrc_data_size == -1) {
+ printk(BIOS_ERR, "Fastboot cache data in cbmem invalid.\n");
+ return;
+ }
+
+ cache_size = get_mrc_cache_region(&cache_base);
+ if (cache_base == NULL) {
+ printk(BIOS_ERR, "%s: could not find fast boot cache area\n",
+ __func__);
+ return;
+ }
+
+ /*
+ * we need to:
+ * 0. compare MRC data to last mrc-cache block (exit if same)
+ */
+ cache = find_current_mrc_cache_local(cache_base, cache_size);
+
+ if (cache && (cache->mrc_data_size == current->mrc_data_size) &&
+ (memcmp(cache, current, cache->mrc_data_size) == 0)) {
+ printk(BIOS_DEBUG,
+ "MRC data in flash is up to date. No update.\n");
+ return;
+ }
+
+ /* 1. use spi_flash_probe() to find the flash, then... */
+ spi_init();
+ struct spi_flash *flash = spi_flash_probe(0, 0, 1000000, SPI_MODE_3);
+ if (!flash) {
+ printk(BIOS_DEBUG, "Could not find SPI device\n");
+ return;
+ }
+
+ /* 2. look up the first unused block */
+ if (cache)
+ cache = find_next_mrc_cache(cache_base, cache, cache_size);
+
+ /*
+ * 3. if no such place exists, erase entire mrc-cache range & use
+ * block 0. First time around the erase is not needed, but this is a
+ * small overhead for simpler code.
+ */
+ if (!cache) {
+ printk(BIOS_DEBUG,
+ "Need to erase the MRC cache region of %d bytes at %p\n",
+ cache_size, cache_base);
+
+ flash->erase(flash, to_flash_offset(cache_base), cache_size);
+
+ /* we will start at the beginning again */
+ cache = cache_base;
+ }
+ /* 4. write mrc data with flash->write() */
+ printk(BIOS_DEBUG, "Write MRC cache update to flash at %p\n",
+ cache);
+ flash->write(flash, to_flash_offset(cache),
+ current->mrc_data_size + sizeof(*current), current);
+}
+
+#endif /* !defined(__PRE_RAM__) */
+
+void * find_and_set_fastboot_cache(void)
+{
+ struct mrc_data_container *mrc_cache = NULL;
+ if (((mrc_cache = find_current_mrc_cache()) == NULL) ||
+ (mrc_cache->mrc_data_size == -1UL)) {
+ printk(BIOS_DEBUG, "FSP MRC cache not present.\n");
+ return NULL;
+ }
+ printk(BIOS_DEBUG, "FSP MRC cache present at %x.\n", (u32)mrc_cache);
+ printk(BIOS_SPEW, "Saved MRC data:\n");
+ hexdump32(BIOS_SPEW, (void *)mrc_cache->mrc_data, mrc_cache->mrc_data_size);
+ return (void *) mrc_cache->mrc_data;
+}
+
+struct mrc_data_container *find_current_mrc_cache(void)
+{
+ struct mrc_data_container *cache_base;
+ u32 cache_size;
+
+ cache_size = get_mrc_cache_region(&cache_base);
+ if (cache_base == NULL) {
+ printk(BIOS_ERR, "%s: could not find fastboot cache area\n",
+ __func__);
+ return NULL;
+ }
+
+ /*
+ * we need to:
+ * 0. compare MRC data to last mrc-cache block (exit if same)
+ */
+ return find_current_mrc_cache_local(cache_base, cache_size);
+}
diff --git a/src/drivers/intel/fsp/fsp_util.c b/src/drivers/intel/fsp/fsp_util.c
new file mode 100644
index 0000000..e9ae36d
--- /dev/null
+++ b/src/drivers/intel/fsp/fsp_util.c
@@ -0,0 +1,432 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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 <types.h>
+#include <string.h>
+#include <cpu/x86/stack.h>
+#include <console/console.h>
+#include <bootstate.h>
+#include <cbmem.h>
+#include "fsp_util.h"
+#include <lib.h> // hexdump
+#include <ip_checksum.h>
+#include <timestamp.h>
+
+#ifndef __PRE_RAM__
+/* Globals pointers for FSP structures */
+void *FspHobListPtr = NULL;
+FSP_INFO_HEADER *fsp_header_ptr = NULL;
+
+void FspNotify (u32 Phase)
+{
+ FSP_NOTFY_PHASE NotifyPhaseProc;
+ NOTIFY_PHASE_PARAMS NotifyPhaseParams;
+ EFI_STATUS Status;
+
+ if (fsp_header_ptr == NULL) {
+ fsp_header_ptr = (void *)find_fsp();
+ if ((u32)fsp_header_ptr < 0xff) {
+ post_code(0x4F); /* output something in case there is no serial */
+ die("Can't find the FSP!\n");
+ }
+ }
+
+ /* call FSP PEI to Notify PostPciEnumeration */
+ NotifyPhaseProc = (FSP_NOTFY_PHASE)(fsp_header_ptr->ImageBase +
+ fsp_header_ptr->NotifyPhaseEntry);
+ NotifyPhaseParams.Phase = Phase;
+
+ timestamp_add_now(Phase == EnumInitPhaseReadyToBoot ?
+ TS_FSP_BEFORE_FINALIZE : TS_FSP_BEFORE_ENUMERATE);
+
+ Status = NotifyPhaseProc (&NotifyPhaseParams);
+
+ timestamp_add_now(Phase == EnumInitPhaseReadyToBoot ?
+ TS_FSP_AFTER_FINALIZE : TS_FSP_AFTER_ENUMERATE);
+
+ if (Status != 0)
+ printk(BIOS_ERR,"FSP API NotifyPhase failed for phase 0x%x with status: 0x%x\n", Phase, Status);
+}
+#endif /* #ifndef __PRE_RAM__ */
+
+#ifdef __PRE_RAM__
+
+/*
+ * Call the FSP to do memory init. The FSP doesn't return to this function.
+ * The FSP returns to the romstage_main_continue().
+ */
+void __attribute__ ((noreturn)) fsp_early_init (FSP_INFO_HEADER *fsp_ptr)
+{
+ FSP_FSP_INIT FspInitApi;
+ FSP_INIT_PARAMS FspInitParams;
+ FSP_INIT_RT_BUFFER FspRtBuffer;
+#if IS_ENABLED(CONFIG_FSP_USES_UPD)
+ UPD_DATA_REGION fsp_upd_data;
+#endif
+
+ memset((void*)&FspRtBuffer, 0, sizeof(FSP_INIT_RT_BUFFER));
+ FspRtBuffer.Common.StackTop = (u32 *)ROMSTAGE_STACK;
+ FspInitParams.NvsBufferPtr = NULL;
+
+#if IS_ENABLED(CONFIG_FSP_USES_UPD)
+ FspRtBuffer.Common.UpdDataRgnPtr = &fsp_upd_data;
+#endif
+ FspInitParams.RtBufferPtr = (FSP_INIT_RT_BUFFER *)&FspRtBuffer;
+ FspInitParams.ContinuationFunc = (CONTINUATION_PROC)ChipsetFspReturnPoint;
+ FspInitApi = (FSP_FSP_INIT)(fsp_ptr->ImageBase + fsp_ptr->FspInitEntry);
+
+ /* Call the chipset code to fill in the chipset specific structures */
+ chipset_fsp_early_init(&FspInitParams, fsp_ptr);
+
+ /* Call back to romstage for board specific changes */
+ romstage_fsp_rt_buffer_callback(&FspRtBuffer);
+
+ FspInitApi(&FspInitParams);
+
+ /* Should never return. Control will continue from ContinuationFunc */
+ die("Uh Oh! FspInitApi returned");
+}
+#endif /* __PRE_RAM__ */
+
+volatile u8 * __attribute__((optimize("O0"))) find_fsp ()
+{
+
+#ifdef __PRE_RAM__
+ volatile register u8 *fsp_ptr asm ("eax");
+
+ /* Entry point for CAR assembly routine */
+ __asm__ __volatile__ (
+ ".global find_fsp\n\t"
+ "find_fsp:\n\t"
+ );
+#else
+ volatile u8 *fsp_ptr;
+#endif /* __PRE_RAM__ */
+
+#ifndef CONFIG_FSP_LOC
+#error "CONFIG_FSP_LOC must be set."
+#endif
+
+ /* The FSP is stored in CBFS */
+ fsp_ptr = (u8 *) CONFIG_FSP_LOC;
+
+ /* Check the FV signature, _FVH */
+ if (((EFI_FIRMWARE_VOLUME_HEADER *)fsp_ptr)->Signature == 0x4856465F) {
+ /* Go to the end of the FV header and align the address. */
+ fsp_ptr += ((EFI_FIRMWARE_VOLUME_HEADER *)fsp_ptr)->ExtHeaderOffset;
+ fsp_ptr += ((EFI_FIRMWARE_VOLUME_EXT_HEADER *)fsp_ptr)->ExtHeaderSize;
+ fsp_ptr = (u8 *)(((u32)fsp_ptr + 7) & 0xFFFFFFF8);
+ } else {
+ fsp_ptr = (u8*)ERROR_NO_FV_SIG;
+ }
+
+ /* Check the FFS GUID */
+ if (((u32)fsp_ptr > 0xff) &&
+ (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[0] == 0x912740BE) &&
+ (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[1] == 0x47342284) &&
+ (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[2] == 0xB08471B9) &&
+ (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[3] == 0x0C3F3527)) {
+ /* Add the FFS Header size to the base to find the Raw section Header */
+ fsp_ptr += sizeof(EFI_FFS_FILE_HEADER);
+ } else {
+ fsp_ptr = (u8 *)ERROR_NO_FFS_GUID;
+ }
+
+ if (((u32)fsp_ptr > 0xff) &&
+ ((EFI_RAW_SECTION *)fsp_ptr)->Type == EFI_SECTION_RAW) {
+ /* Add the Raw Header size to the base to find the FSP INFO Header */
+ fsp_ptr += sizeof(EFI_RAW_SECTION);
+ } else {
+ fsp_ptr = (u8 *)ERROR_NO_INFO_HEADER;
+ }
+
+ /* Verify that the FSP is set to the base address we're expecting.*/
+ if (((u32)fsp_ptr > 0xff) &&
+ (*(u32*)(fsp_ptr + FSP_IMAGE_BASE_LOC) != CONFIG_FSP_LOC)) {
+ fsp_ptr = (u8 *)ERROR_IMAGEBASE_MISMATCH;
+ }
+
+ /* Verify the FSP Signature */
+ if (((u32)fsp_ptr > 0xff) &&
+ (*(u32*)(fsp_ptr + FSP_IMAGE_SIG_LOC) != FSP_SIG)){
+ fsp_ptr = (u8 *)ERROR_INFO_HEAD_SIG_MISMATCH;
+ }
+
+ /* Verify the FSP ID */
+ if (((u32)fsp_ptr > 0xff) &&
+ ((*(u32 *)(fsp_ptr + FSP_IMAGE_ID_LOC) != FSP_IMAGE_ID_DWORD0) ||
+ (*(u32 *)(fsp_ptr + (FSP_IMAGE_ID_LOC + 4)) != FSP_IMAGE_ID_DWORD1))) {
+ fsp_ptr = (u8 *)ERROR_FSP_SIG_MISMATCH;
+ }
+
+ return (fsp_ptr);
+}
+
+#ifndef __PRE_RAM__ /* Only parse HOB data in ramstage */
+
+void print_fsp_info(void) {
+
+ if (fsp_header_ptr == NULL)
+ fsp_header_ptr = (void *)find_fsp();
+ if ((u32)fsp_header_ptr < 0xff) {
+ post_code(0x4F); /* output something in case there is no serial */
+ die("Can't find the FSP!\n");
+ }
+
+ if (FspHobListPtr == NULL) {
+ FspHobListPtr = (void*)*((u32*) cbmem_find(CBMEM_ID_HOB_POINTER));
+ }
+
+ printk(BIOS_SPEW,"fsp_header_ptr: %p\n", fsp_header_ptr);
+ printk(BIOS_INFO,"FSP Header Version: %d\n", fsp_header_ptr->HeaderRevision);
+ printk(BIOS_INFO,"FSP Revision: %d.%d\n",
+ (u8)((fsp_header_ptr->ImageRevision >> 8) & 0xff),
+ (u8)(fsp_header_ptr->ImageRevision & 0xff));
+}
+
+static void print_hob_mem_attributes(void *Hobptr) {
+ EFI_HOB_MEMORY_ALLOCATION *HobMemoryPtr = (EFI_HOB_MEMORY_ALLOCATION *)Hobptr;
+ EFI_MEMORY_TYPE Hobmemtype = HobMemoryPtr->AllocDescriptor.MemoryType;
+ u64 Hobmemaddr = HobMemoryPtr->AllocDescriptor.MemoryBaseAddress;
+ u64 Hobmemlength = HobMemoryPtr->AllocDescriptor.MemoryLength;
+ const char * Hobmemtypenames[15];
+
+ Hobmemtypenames[0] = "EfiReservedMemoryType";
+ Hobmemtypenames[1] = "EfiLoaderCode";
+ Hobmemtypenames[2] = "EfiLoaderData";
+ Hobmemtypenames[3] = "EfiBootServicesCode";
+ Hobmemtypenames[4] = "EfiBootServicesData";
+ Hobmemtypenames[5] = "EfiRuntimeServicesCode";
+ Hobmemtypenames[6] = "EfiRuntimeServicesData";
+ Hobmemtypenames[7] = "EfiConventionalMemory";
+ Hobmemtypenames[8] = "EfiUnusableMemory";
+ Hobmemtypenames[9] = "EfiACPIReclaimMemory";
+ Hobmemtypenames[10] = "EfiACPIMemoryNVS";
+ Hobmemtypenames[11] = "EfiMemoryMappedIO";
+ Hobmemtypenames[12] = "EfiMemoryMappedIOPortSpace";
+ Hobmemtypenames[13] = "EfiPalCode";
+ Hobmemtypenames[14] = "EfiMaxMemoryType";
+
+ printk(BIOS_SPEW, " Memory type %s (0x%x)\n",
+ Hobmemtypenames[(u32)Hobmemtype], (u32) Hobmemtype);
+ printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
+ (long unsigned int)Hobmemaddr, (long unsigned int)Hobmemlength);
+}
+
+static void print_hob_resource_attributes(void *Hobptr) {
+ EFI_HOB_RESOURCE_DESCRIPTOR *HobResourcePtr =
+ (EFI_HOB_RESOURCE_DESCRIPTOR *)Hobptr;
+ u32 Hobrestype = HobResourcePtr->ResourceType;
+ u32 Hobresattr = HobResourcePtr->ResourceAttribute;
+ u64 Hobresaddr = HobResourcePtr->PhysicalStart;
+ u64 Hobreslength = HobResourcePtr->ResourceLength;
+ const char *Hobrestypestr = NULL;
+
+ // HOB Resource Types
+ switch (Hobrestype) {
+ case EFI_RESOURCE_SYSTEM_MEMORY:
+ Hobrestypestr = "EFI_RESOURCE_SYSTEM_MEMORY"; break;
+ case EFI_RESOURCE_MEMORY_MAPPED_IO:
+ Hobrestypestr = "EFI_RESOURCE_MEMORY_MAPPED_IO"; break;
+ case EFI_RESOURCE_IO:
+ Hobrestypestr = "EFI_RESOURCE_IO"; break;
+ case EFI_RESOURCE_FIRMWARE_DEVICE:
+ Hobrestypestr = "EFI_RESOURCE_FIRMWARE_DEVICE"; break;
+ case EFI_RESOURCE_MEMORY_MAPPED_IO_PORT:
+ Hobrestypestr = "EFI_RESOURCE_MEMORY_MAPPED_IO_PORT"; break;
+ case EFI_RESOURCE_MEMORY_RESERVED:
+ Hobrestypestr = "EFI_RESOURCE_MEMORY_RESERVED"; break;
+ case EFI_RESOURCE_IO_RESERVED:
+ Hobrestypestr = "EFI_RESOURCE_IO_RESERVED"; break;
+ case EFI_RESOURCE_MAX_MEMORY_TYPE:
+ Hobrestypestr = "EFI_RESOURCE_MAX_MEMORY_TYPE"; break;
+ default:
+ Hobrestypestr = "EFI_RESOURCE_UNKNOWN"; break;
+ }
+
+ printk(BIOS_SPEW, " Resource %s (0x%0x) has attributes 0x%0x\n",
+ Hobrestypestr, Hobrestype, Hobresattr);
+ printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
+ (long unsigned int)Hobresaddr, (long unsigned int)Hobreslength);
+}
+
+static const char * get_hob_type_string(void *Hobptr) {
+ EFI_HOB_GENERIC_HEADER *HobHeaderPtr = (EFI_HOB_GENERIC_HEADER *)Hobptr;
+ u16 Hobtype = HobHeaderPtr->HobType;
+ const char *Hobtypestring = NULL;
+
+ switch (Hobtype) {
+ case EFI_HOB_TYPE_HANDOFF:
+ Hobtypestring = "EFI_HOB_TYPE_HANDOFF"; break;
+ case EFI_HOB_TYPE_MEMORY_ALLOCATION:
+ Hobtypestring = "EFI_HOB_TYPE_MEMORY_ALLOCATION"; break;
+ case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
+ Hobtypestring = "EFI_HOB_TYPE_RESOURCE_DESCRIPTOR"; break;
+ case EFI_HOB_TYPE_GUID_EXTENSION:
+ Hobtypestring = "EFI_HOB_TYPE_GUID_EXTENSION"; break;
+ case EFI_HOB_TYPE_MEMORY_POOL:
+ Hobtypestring = "EFI_HOB_TYPE_MEMORY_POOL"; break;
+ case EFI_HOB_TYPE_UNUSED:
+ Hobtypestring = "EFI_HOB_TYPE_UNUSED"; break;
+ case EFI_HOB_TYPE_END_OF_HOB_LIST:
+ Hobtypestring = "EFI_HOB_TYPE_END_OF_HOB_LIST"; break;
+ default:
+ Hobtypestring = "EFI_HOB_TYPE_UNRECOGNIZED"; break;
+ }
+
+ return Hobtypestring;
+}
+
+/* Print out a structure of all the HOBs
+ * that match a certain type:
+ * Print all types (0x0000)
+ * EFI_HOB_TYPE_HANDOFF (0x0001)
+ * EFI_HOB_TYPE_MEMORY_ALLOCATION (0x0002)
+ * EFI_HOB_TYPE_RESOURCE_DESCRIPTOR (0x0003)
+ * EFI_HOB_TYPE_GUID_EXTENSION (0x0004)
+ * EFI_HOB_TYPE_MEMORY_POOL (0x0007)
+ * EFI_HOB_TYPE_UNUSED (0xFFFE)
+ * EFI_HOB_TYPE_END_OF_HOB_LIST (0xFFFF)
+ */
+void print_hob_type_structure(u16 Hobtype, void *Hoblistptr) {
+ u32 *Currenthob;
+ u32 *Nexthob = 0;
+ u8 Lasthob = 0;
+ u32 Currenttype;
+ const char *Currenttypestr;
+
+ Currenthob = Hoblistptr;
+
+ /* Print out HOBs of our desired type until
+ * the end of the HOB list
+ */
+ printk(BIOS_DEBUG, "\n=== FSP HOB Data Structure ===\n");
+ printk(BIOS_DEBUG, "FSP Hoblistptr: 0x%0x\n",
+ (u32) Hoblistptr);
+ do {
+ EFI_HOB_GENERIC_HEADER *CurrentHeaderPtr =
+ (EFI_HOB_GENERIC_HEADER *)Currenthob;
+ Currenttype = CurrentHeaderPtr->HobType; /* Get the type of this HOB */
+ Currenttypestr = get_hob_type_string(Currenthob);
+
+ if (Currenttype == Hobtype || Hobtype == 0x0000) {
+ printk(BIOS_DEBUG, "HOB 0x%0x is an %s (type 0x%0x)\n",
+ (u32) Currenthob, Currenttypestr, Currenttype);
+ switch (Currenttype) {
+ case EFI_HOB_TYPE_MEMORY_ALLOCATION:
+ print_hob_mem_attributes(Currenthob); break;
+ case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
+ print_hob_resource_attributes(Currenthob); break;
+ }
+ }
+
+ Lasthob = END_OF_HOB_LIST(Currenthob); /* Check for end of HOB list */
+ if (!Lasthob) {
+ Nexthob = GET_NEXT_HOB(Currenthob); /* Get next HOB pointer */
+ Currenthob = Nexthob; // Start on next HOB
+ }
+ } while (!Lasthob);
+ printk(BIOS_DEBUG, "=== End of FSP HOB Data Structure ===\n\n");
+}
+
+#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
+/**
+ * Save the FSP memory HOB (mrc data) to the MRC area in CBMEM
+ */
+int save_mrc_data(void *hob_start)
+{
+ u32 *mrc_hob;
+ u32 *mrc_hob_data;
+ u32 mrc_hob_size;
+ struct mrc_data_container *mrc_data;
+ int output_len;
+ const EFI_GUID mrc_guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
+
+ mrc_hob = GetNextGuidHob(&mrc_guid, hob_start);
+ if (mrc_hob == NULL){
+ printk(BIOS_DEBUG, "Memory Configure Data Hob is not present\n");
+ return(0);
+ }
+
+ mrc_hob_data = GET_GUID_HOB_DATA (mrc_hob);
+ mrc_hob_size = (u32) GET_HOB_LENGTH(mrc_hob);
+
+ printk(BIOS_DEBUG, "Memory Configure Data Hob at %p (size = 0x%x).\n",
+ (void *)mrc_hob_data, mrc_hob_size);
+
+ output_len = ALIGN(mrc_hob_size, 16);
+
+ /* Save the MRC S3/fast boot/ADR restore data to cbmem */
+ mrc_data = cbmem_add (CBMEM_ID_MRCDATA,
+ output_len + sizeof(struct mrc_data_container));
+
+ /* Just return if there was a problem with getting CBMEM */
+ if (mrc_data == NULL) {
+ printk(BIOS_WARNING, "CBMEM was not available to save the fast boot cache data.\n");
+ return 0;
+ }
+
+ printk(BIOS_DEBUG, "Copy FSP MRC DATA to HOB (source addr %p, dest addr %p, %u bytes)\n",
+ (void *)mrc_hob_data, mrc_data, output_len);
+
+ mrc_data->mrc_signature = MRC_DATA_SIGNATURE;
+ mrc_data->mrc_data_size = output_len;
+ mrc_data->reserved = 0;
+ memcpy(mrc_data->mrc_data, (const void *)mrc_hob_data, mrc_hob_size);
+
+ /* Zero the unused space in aligned buffer. */
+ if (output_len > mrc_hob_size)
+ memset((mrc_data->mrc_data + mrc_hob_size), 0,
+ output_len - mrc_hob_size);
+
+ mrc_data->mrc_checksum = compute_ip_checksum(mrc_data->mrc_data,
+ mrc_data->mrc_data_size);
+
+ printk(BIOS_SPEW, "Fastboot data (includes align and checksum):\n");
+ hexdump32(BIOS_SPEW, (void *)mrc_data->mrc_data, output_len);
+ return (1);
+}
+#endif /* CONFIG_ENABLE_MRC_CACHE */
+
+static void find_fsp_hob_update_mrc(void *unused)
+{
+ /* Set the global HOB list pointer */
+ FspHobListPtr = (void*)*((u32*) cbmem_find(CBMEM_ID_HOB_POINTER));
+
+ if (!FspHobListPtr){
+ printk(BIOS_ERR, "ERROR: Could not find FSP HOB pointer in CBFS!\n");
+ } else {
+ /* 0x0000: Print all types */
+ print_hob_type_structure(0x000, FspHobListPtr);
+
+ #if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
+ if(save_mrc_data(FspHobListPtr))
+ update_mrc_cache(NULL);
+ else
+ printk(BIOS_DEBUG,"Not updating MRC data in flash.\n");
+ #endif
+ }
+}
+
+/* Update the MRC/fast boot cache as part of the late table writing stage */
+BOOT_STATE_INIT_ENTRIES(fsp_hob_find) = {
+ BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY,
+ find_fsp_hob_update_mrc, NULL),
+};
+#endif /* #ifndef __PRE_RAM__ */
diff --git a/src/drivers/intel/fsp/fsp_util.h b/src/drivers/intel/fsp/fsp_util.h
new file mode 100644
index 0000000..eaf2d37
--- /dev/null
+++ b/src/drivers/intel/fsp/fsp_util.h
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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 FSP_UTIL_H
+#define FSP_UTIL_H
+
+#include <chipset_fsp_util.h>
+
+#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
+int save_mrc_data(void *hob_start);
+void * find_and_set_fastboot_cache(void);
+#endif
+
+volatile u8 * find_fsp (void);
+void fsp_early_init(FSP_INFO_HEADER *fsp_info);
+void FspNotify(u32 Phase);
+void FspNotifyReturnPoint(EFI_STATUS Status, VOID *HobListPtr);
+void print_hob_type_structure(u16 Hobtype, void *Hoblistptr);
+void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer);
+void print_fsp_info(void);
+
+void chipset_fsp_early_init(FSP_INIT_PARAMS *FspInitParams,
+ FSP_INFO_HEADER *fsp_ptr);
+void ChipsetFspReturnPoint(EFI_STATUS Status, VOID *HobListPtr);
+
+/* Additional HOB types not included in the FSP:
+ * #define EFI_HOB_TYPE_HANDOFF 0x0001
+ * #define EFI_HOB_TYPE_MEMORY_ALLOCATION 0x0002
+ * #define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR 0x0003
+ * #define EFI_HOB_TYPE_GUID_EXTENSION 0x0004
+ * #define EFI_HOB_TYPE_FV 0x0005
+ * #define EFI_HOB_TYPE_CPU 0x0006
+ * #define EFI_HOB_TYPE_MEMORY_POOL 0x0007
+ * #define EFI_HOB_TYPE_CV 0x0008
+ * #define EFI_HOB_TYPE_UNUSED 0xFFFE
+ * #define EFI_HOB_TYPE_END_OF_HOB_LIST 0xffff
+ */
+#define EFI_HOB_TYPE_HANDOFF 0x0001
+#define EFI_HOB_TYPE_MEMORY_POOL 0x0007
+
+#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
+#define MRC_DATA_ALIGN 0x1000
+#define MRC_DATA_SIGNATURE (('M'<<0)|('R'<<8)|('C'<<16)|('D'<<24))
+
+struct mrc_data_container {
+ u32 mrc_signature; // "MRCD"
+ u32 mrc_data_size; // Actual total size of this structure
+ u32 mrc_checksum; // IP style checksum
+ u32 reserved; // For header alignment
+ u8 mrc_data[0]; // Variable size, platform/run time dependent.
+} __attribute__ ((packed));
+
+struct mrc_data_container *find_current_mrc_cache(void);
+
+#if !defined(__PRE_RAM__)
+void update_mrc_cache(void *unused);
+#endif
+
+#endif
+
+/* The offset in bytes from the start of the info structure */
+#define FSP_IMAGE_SIG_LOC 0
+#define FSP_IMAGE_ID_LOC 16
+#define FSP_IMAGE_BASE_LOC 28
+
+#define FSP_SIG 0x48505346 /* 'FSPH' */
+
+#define ERROR_NO_FV_SIG 1
+#define ERROR_NO_FFS_GUID 2
+#define ERROR_NO_INFO_HEADER 3
+#define ERROR_IMAGEBASE_MISMATCH 4
+#define ERROR_INFO_HEAD_SIG_MISMATCH 5
+#define ERROR_FSP_SIG_MISMATCH 6
+
+#ifndef __PRE_RAM__
+extern void *FspHobListPtr;
+#endif
+
+#endif /* FSP_UTIL_H */
diff --git a/src/include/timestamp.h b/src/include/timestamp.h
index 9e780c3..66c1d9a 100644
--- a/src/include/timestamp.h
+++ b/src/include/timestamp.h
@@ -43,12 +43,16 @@ enum timestamp_id {
TS_END_COPYRAM = 9,
TS_START_RAMSTAGE = 10,
TS_DEVICE_ENUMERATE = 30,
+ TS_FSP_BEFORE_ENUMERATE,
+ TS_FSP_AFTER_ENUMERATE,
TS_DEVICE_CONFIGURE = 40,
TS_DEVICE_ENABLE = 50,
TS_DEVICE_INITIALIZE = 60,
TS_DEVICE_DONE = 70,
TS_CBMEM_POST = 75,
TS_WRITE_TABLES = 80,
+ TS_FSP_BEFORE_FINALIZE,
+ TS_FSP_AFTER_FINALIZE,
TS_LOAD_PAYLOAD = 90,
TS_ACPI_WAKE_JUMP = 98,
TS_SELFBOOT_JUMP = 99,
Martin Roth (martin.roth(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5636
-gerrit
commit 75ad223759dcbb6e69b83bc6c2297af4f633787d
Author: Martin Roth <gaumless(a)gmail.com>
Date: Fri Apr 25 15:09:27 2014 -0600
cougar_canyon2: Switch CPU/NB/SB/to the shared FSP code
CPU - fsp_model_206ax:
- Remove Kconfig options and mark this as using the FSP.
- Use shared FSP cache_as_ram.inc file
Mainboard - intel/cougar_canyon2:
- Update to use the shared FSP header file.
- Modify to call copy_and_run() directly instead of returning to
cache_as_ram.inc.
Northbridge - fsp_sandybridge:
- remove mrccache, fsp_util.[ch]
- add fsp/chipset_fsp_util.[ch] with chipset specific FSP bits.
- Update to use the shared FSP header file.
Change-Id: Ibc52a78312c2fcbd1e632bc2484e4379a4f057d4
Signed-off-by: Martin Roth <gaumless(a)gmail.com>
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
---
src/cpu/intel/fsp_model_206ax/Kconfig | 23 +-
src/cpu/intel/fsp_model_206ax/Makefile.inc | 11 +-
src/cpu/intel/fsp_model_206ax/cache_as_ram.inc | 292 ---------------
src/mainboard/intel/cougar_canyon2/romstage.c | 13 +-
src/northbridge/intel/fsp_sandybridge/Kconfig | 67 +---
src/northbridge/intel/fsp_sandybridge/Makefile.inc | 27 +-
src/northbridge/intel/fsp_sandybridge/fsp/Kconfig | 42 +++
.../intel/fsp_sandybridge/fsp/Makefile.inc | 22 ++
.../intel/fsp_sandybridge/fsp/chipset_fsp_util.c | 117 ++++++
.../intel/fsp_sandybridge/fsp/chipset_fsp_util.h | 65 ++++
src/northbridge/intel/fsp_sandybridge/fsp_util.c | 414 ---------------------
src/northbridge/intel/fsp_sandybridge/fsp_util.h | 88 -----
src/northbridge/intel/fsp_sandybridge/mrccache.c | 257 -------------
.../intel/fsp_sandybridge/northbridge.c | 2 +-
.../intel/fsp_sandybridge/northbridge.h | 9 -
.../intel/fsp_sandybridge/northbridge_pci_devs.h | 47 +++
src/southbridge/intel/fsp_bd82x6x/Makefile.inc | 2 +
.../intel/fsp_bd82x6x/southbridge_pci_devs.h | 127 +++++++
18 files changed, 439 insertions(+), 1186 deletions(-)
diff --git a/src/cpu/intel/fsp_model_206ax/Kconfig b/src/cpu/intel/fsp_model_206ax/Kconfig
index 3aacaf7..1db5030 100644
--- a/src/cpu/intel/fsp_model_206ax/Kconfig
+++ b/src/cpu/intel/fsp_model_206ax/Kconfig
@@ -28,6 +28,7 @@ if CPU_INTEL_FSP_MODEL_206AX || CPU_INTEL_FSP_MODEL_306AX
config CPU_SPECIFIC_OPTIONS
def_bool y
+ select PLATFORM_USES_FSP
select ARCH_BOOTBLOCK_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
@@ -70,26 +71,4 @@ config MICROCODE_INCLUDE_PATH
default "../intel/cpu/ivybridge/microcode" if CPU_INTEL_FSP_MODEL_306AX
default "../intel/cpu/sandybridge/microcode" if CPU_INTEL_FSP_MODEL_206AX
-config FSP_IMAGE_ID_DWORD0
- hex
- default 0x2D325453 if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_I89XX
- default 0x2D324343 if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_BD82X6X
- help
- The FSP Image ID is different for each platform's FSP and can be used to
- verify that the right FSP binary is loaded.
- For the ivybridge/89xx FSP, the Image Id will be "ST2-FSP\0",
- for ivybridge/bd82x6x FSPs, the Image Id will be "CC2-FSP\0",
- This dword holds the first 4 bytes of the string, as
- a hex value.
-
-config FSP_IMAGE_ID_DWORD1
- hex
- default 0x00505346
- help
- For the ivybridge/I89xx FSP, the Image Id will be "ST2-FSP\0",
- for ivybridge/bd82x6x FSPs, the Image Id will be "CC2-FSP\0",
- This dword holds the second 4 bytes of the string, as
- a hex value. Since the strings use the same second dword,
- no additional logic is needed.
-
endif
diff --git a/src/cpu/intel/fsp_model_206ax/Makefile.inc b/src/cpu/intel/fsp_model_206ax/Makefile.inc
index 7986767..6004462 100644
--- a/src/cpu/intel/fsp_model_206ax/Makefile.inc
+++ b/src/cpu/intel/fsp_model_206ax/Makefile.inc
@@ -7,9 +7,8 @@ smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
-cpu_incs += $(src)/cpu/intel/fsp_model_206ax/cache_as_ram.inc
-
-CC_bootblock := $(CC_bootblock) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
-CC_romstage := $(CC_romstage) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
-CC_ramstage := $(CC_ramstage) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
-CC_x86_32 := $(CC_x86_32) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
+ifneq ($(CONFIG_MICROCODE_INCLUDE_PATH),)
+ifneq ($(wildcard $(shell realpath -L "$(top)/$(CONFIG_MICROCODE_INCLUDE_PATH)")),)
+INCLUDES += -I$(CONFIG_MICROCODE_INCLUDE_PATH)
+endif
+endif
diff --git a/src/cpu/intel/fsp_model_206ax/cache_as_ram.inc b/src/cpu/intel/fsp_model_206ax/cache_as_ram.inc
deleted file mode 100644
index cc35060..0000000
--- a/src/cpu/intel/fsp_model_206ax/cache_as_ram.inc
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich(a)gmail.com>
- * Copyright (C) 2007-2008 coresystems GmbH
- * Copyright (C) 2013 Sage Electronic Engineering, LLC.
- *
- * 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 <cpu/x86/stack.h>
-#include <cpu/x86/mtrr.h>
-#include <cpu/x86/cache.h>
-#include <cpu/x86/post_code.h>
-#include <cbmem.h>
-
-#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
-#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
-
-#define CPU_PHYSMASK_HI (1 << (CONFIG_CPU_ADDR_BITS - 32) - 1)
-#define LHLT_DELAY 0x50000 /* delay between post codes on FSP failure */
-#define NoEvictMod_MSR 0x2e0
-
-cache_as_ram:
- post_code(0x20)
-
- /* Send INIT IPI to all excluding ourself. */
- movl $0x000C4500, %eax
- movl $0xFEE00300, %esi
- movl %eax, (%esi)
-
- /* All CPUs need to be in Wait for SIPI state */
-wait_for_sipi:
- movl (%esi), %eax
- bt $12, %eax
- jc wait_for_sipi
-
- post_code(0x21)
- /* Zero out all fixed range and variable range MTRRs. */
- movl $mtrr_table, %esi
- movl $((mtrr_table_end - mtrr_table) / 2), %edi
- xorl %eax, %eax
- xorl %edx, %edx
-clear_mtrrs:
- movw (%esi), %bx
- movzx %bx, %ecx
- wrmsr
- add $2, %esi
- dec %edi
- jnz clear_mtrrs
-
- /* Init floating point */
- emms
- fninit
-
- /*
- * Find the FSP binary in cbfs.
- * Make a fake stack that has the return value back to this code.
- */
- lea fake_fsp_stack, %esp
- jmp find_fsp
-find_fsp_ret:
- /* Save the FSP location */
- mov %eax, %ebp
- cmp $CONFIG_FSP_LOC, %eax
- jb halt1
-
- post_code(0x22)
-
- /* Calculate entry into FSP */
- mov 0x30(%ebp), %eax /* Load TempRamInitEntry */
- add 0x1c(%ebp), %eax /* add in the offset for the FSP base address */
-
- /*
- * Pass early init variables on a fake stack (no memory yet)
- * as well as the return location
- */
- lea CAR_init_stack, %esp
-
- /* call FSP binary to setup temporary stack */
- jmp *%eax
-
-CAR_init_done:
- addl $4, %esp
- cmp $0, %eax
- jne halt2
-
- /* Save FSP_INFO_HEADER location in ebx */
- mov %ebp, %ebx
-
- /*
- * setup bootloader stack
- * ecx: stack base
- * edx: stack top
- */
- lea -4(%edx), %esp
- movl %esp, %ebp
-
-before_romstage:
- post_code(0x23)
-
- /* Call romstage.c main function. */
- pushl %ebx
- call main
-
-romstage_main_return:
- post_code(0x2f)
-
-/* Disable cache. */
- movl %cr0, %eax
- orl $CR0_CacheDisable, %eax
- movl %eax, %cr0
-
- post_code(0x31)
-
- /* Disable MTRR. */
- movl $MTRRdefType_MSR, %ecx
- rdmsr
- andl $(~MTRRdefTypeEn), %eax
- wrmsr
-
- post_code(0x32)
-
- /* Zero out all fixed range and variable range MTRRs. */
- movl $mtrr_table, %esi
- movl $((mtrr_table_end - mtrr_table) / 2), %edi
- xorl %eax, %eax
- xorl %edx, %edx
-_clear_mtrrs_:
- movw (%esi), %bx
- movzx %bx, %ecx
- wrmsr
- add $2, %esi
- dec %edi
- jnz _clear_mtrrs_
-
- post_code(0x33)
-
- /* Enable cache. */
- movl %cr0, %eax
- andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
- movl %eax, %cr0
-
- post_code(0x36)
-
- /* Disable cache. */
- movl %cr0, %eax
- orl $CR0_CacheDisable, %eax
- movl %eax, %cr0
-
- post_code(0x38)
-
- /* Enable Write Back and Speculative Reads for the first MB
- * and ramstage.
- */
- movl $MTRRphysBase_MSR(0), %ecx
- movl $(0x00000000 | MTRR_TYPE_WRBACK), %eax
- xorl %edx, %edx
- wrmsr
- movl $MTRRphysMask_MSR(0), %ecx
- movl $(~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid), %eax
- movl $CPU_PHYSMASK_HI, %edx // 36bit address space
- wrmsr
-
-#if CACHE_ROM_SIZE
- /* Enable Caching and speculative Reads for the
- * complete ROM now that we actually have RAM.
- */
- movl $MTRRphysBase_MSR(1), %ecx
- movl $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
- xorl %edx, %edx
- wrmsr
- movl $MTRRphysMask_MSR(1), %ecx
- movl $(~(CACHE_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
- movl $CPU_PHYSMASK_HI, %edx
- wrmsr
-#endif
-
- post_code(0x39)
-
- /* And enable cache again after setting MTRRs. */
- movl %cr0, %eax
- andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
- movl %eax, %cr0
-
- post_code(0x3a)
-
- /* Enable MTRR. */
- movl $MTRRdefType_MSR, %ecx
- rdmsr
- orl $MTRRdefTypeEn, %eax
- wrmsr
-
- post_code(0x3d)
-
- /* Clear boot_complete flag. */
- xorl %ebp, %ebp
-__main:
- post_code(POST_PREPARE_RAMSTAGE)
- cld /* Clear direction flag. */
-
- movl %ebp, %esi
-
- movl $ROMSTAGE_STACK, %esp
- movl %esp, %ebp
- pushl %esi
- call copy_and_run
-
-halt1:
- /*
- * Failures for postcode 0xBA - failed in find_fsp()
- *
- * Values are:
- * 0x01 - FV signature, "_FVH" not present
- * 0x02 - FFS GUID not present
- * 0x03 - FSP INFO Header not found
- * 0x04 - ImageBase does not equal CONFIG_FSP_LOC - Is the FSP rebased to
- * a different location, or does it need to be?
- * 0x05 - FSP INFO Header signature "FSPH" not found
- * 0x06 - FSP Image ID is not the expected ID.
- * For ivybridge_bd82x6x, the ID is expected to be 'CC2-FSP\0'
- * For ivybridge_i89xx, the ID is expected to be 'ST2-FSP\0'
- *
- */
- movb $0xBA, %ah
- jmp .Lhlt
-
-halt2:
- /*
- * Failures for postcode 0xBB - failed in the FSP:
- *
- * 0x00 - FSP_SUCCESS: Temp RAM was initialized successfully.
- * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid.
- * 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode region.
- * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
- * 0x07 - FSP_DEVICE_ERROR: Temp RAM initialization failed
- * 0x14 - FSP_ALREADY_STARTED: Temp RAM initialization has been invoked
- */
- movb $0xBB, %ah
-
-.Lhlt:
- xchg %al, %ah
-#if CONFIG_POST_IO
- outb %al, $CONFIG_POST_IO_PORT
-#else
- post_code(POST_DEAD_CODE)
-#endif
- movl $LHLT_DELAY, %ecx
-.Lhlt_Delay:
- outb %al, $0xED
- loop .Lhlt_Delay
- jmp .Lhlt
-
- .align 4
-fake_fsp_stack:
- .long find_fsp_ret
-
-CAR_init_params:
- .long CONFIG_CPU_MICROCODE_CBFS_LOC
- .long CONFIG_CPU_MICROCODE_CBFS_LEN /* Microcode Length */
- .long 0xFFFFFFFF - CONFIG_ROM_SIZE + 1 /* Firmware Location */
- .long CONFIG_ROM_SIZE /* Total Firmware Length */
-
-CAR_init_stack:
- .long CAR_init_done
- .long CAR_init_params
-
-mtrr_table:
- /* Fixed MTRRs */
- .word 0x250, 0x258, 0x259
- .word 0x268, 0x269, 0x26A
- .word 0x26B, 0x26C, 0x26D
- .word 0x26E, 0x26F
- /* Variable MTRRs */
- .word 0x200, 0x201, 0x202, 0x203
- .word 0x204, 0x205, 0x206, 0x207
- .word 0x208, 0x209, 0x20A, 0x20B
- .word 0x20C, 0x20D, 0x20E, 0x20F
-/* .word 0x210, 0x211, 0x212, 0x213 */
-mtrr_table_end:
-
diff --git a/src/mainboard/intel/cougar_canyon2/romstage.c b/src/mainboard/intel/cougar_canyon2/romstage.c
index afd7e25..6938925 100644
--- a/src/mainboard/intel/cougar_canyon2/romstage.c
+++ b/src/mainboard/intel/cougar_canyon2/romstage.c
@@ -33,7 +33,7 @@
#include <console/console.h>
#include <reset.h>
#include "superio/smsc/sio1007/chip.h"
-#include "northbridge/intel/fsp_sandybridge/fsp_util.h"
+#include <fsp_util.h>
#include "northbridge/intel/fsp_sandybridge/northbridge.h"
#include "northbridge/intel/fsp_sandybridge/raminit.h"
#include "southbridge/intel/fsp_bd82x6x/pch.h"
@@ -42,6 +42,7 @@
#include <arch/cpu.h>
#include <cpu/x86/msr.h>
#include "gpio.h"
+#include <arch/stages.h>
static inline void reset_system(void)
{
@@ -345,13 +346,9 @@ void romstage_main_continue(EFI_STATUS status, VOID *HobListPtr) {
cbmemc_reinit();
#endif
-/*
- * FSP returns to this function instead of main, so we can't return back
- * to the cache_as_ram.inc. Just jump there to finish the ramstage loading.
- */
- asm volatile (
- "jmp romstage_main_return\n"
- );
+ /* Load the ramstage. */
+ copy_and_run();
+ while (1);
}
void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer)
diff --git a/src/northbridge/intel/fsp_sandybridge/Kconfig b/src/northbridge/intel/fsp_sandybridge/Kconfig
index ce366ef..2e1c087 100644
--- a/src/northbridge/intel/fsp_sandybridge/Kconfig
+++ b/src/northbridge/intel/fsp_sandybridge/Kconfig
@@ -28,15 +28,6 @@ config NORTHBRIDGE_INTEL_FSP_IVYBRIDGE
if NORTHBRIDGE_INTEL_FSP_IVYBRIDGE || NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE
-config HAVE_FSP_BIN
- bool "Use Intel Firmware Support Package"
- help
- Select this option to add an Intel FSP binary to
- the resulting coreboot image.
-
- Note: Without this binary, coreboot builds relying on the FSP
- will not boot
-
config VGA_BIOS_ID
string
default "8086,0106"
@@ -47,32 +38,6 @@ config VGA_BIOS_ID
0x80860102, 0x8086010a, 0x80860112, 0x80860116
0x80860122, 0x80860126, 0x80860166
-config DCACHE_RAM_BASE
- hex
- default 0xff7f0000
-
-config DCACHE_RAM_SIZE
- hex
- default 0x10000
-
-
-if HAVE_FSP_BIN
-
-config FSP_FILE
- string "Intel FSP binary path and filename"
- default "../intel/fsp/ivybridge_bd82x6x/FvFsp.bin" if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_BD82X6X
- default "../intel/fsp/ivybridge_i89xx/FvFsp.bin" if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_I89XX
- help
- The path and filename of the Intel FSP binary for this platform.
-
-config FSP_LOC
- hex "Intel FSP Binary location in cbfs"
- default 0xfff80000
- help
- The location in cbfs that the FSP is located. This must match the
- value that is set in the FSP binary. If the FSP needs to be moved,
- rebase the FSP with the Intel's BCT (tool).
-
config CBFS_SIZE
hex "Size of CBFS filesystem in ROM"
default 0x100000
@@ -84,35 +49,7 @@ config CBFS_SIZE
This option specifies the maximum size of the CBFS portion in the
firmware image.
-config ENABLE_FAST_BOOT
- bool "Enable Fast Boot"
- default y if CPU_INTEL_FSP_MODEL_306AX && SOUTHBRIDGE_INTEL_FSP_BD82X6X
- help
- Enabling this feature will cause MRC data to be cached in NV storage
- which will speed up boot time on future reboots and/or power cycles.
-
-config MRC_CACHE_SIZE
- hex "MRC Data Cache Size"
- default 0x10000
- depends on ENABLE_FAST_BOOT
- help
- This is the amount of space in NV storage that is reserved for MRC data
- cache storage when using fast boot.
-
-config VIRTUAL_ROM_SIZE
- hex "Virtual ROM Size"
- default ROM_SIZE
- depends on ENABLE_FAST_BOOT
- help
- This is used to calculate the offset of the MRC data cache in NV
- Storage for "Fast Boot". If in doubt, leave this set to the default
- which sets the virtual size equal to the ROM size.
-
- Example: Cougar Canyon 2 has 2 8 MB SPI ROMs. When the SPI ROMs are
- loaded with a 4 MB coreboot image, the virtual ROM size is 8 MB. When
- the SPI ROMs are loaded with an 8 MB coreboot image, the virtual ROM
- size is 16 MB.
-
-endif # HAVE_FSP_BIN
+# Ivybridge Specific FSP Kconfig
+source src/northbridge/intel/fsp_sandybridge/fsp/Kconfig
endif # NORTHBRIDGE_INTEL_FSP_IVYBRIDGE || NORTHBRIDGE_INTEL_FSP_SANDYBRIDGE
diff --git a/src/northbridge/intel/fsp_sandybridge/Makefile.inc b/src/northbridge/intel/fsp_sandybridge/Makefile.inc
index 5bc3d58..f5dbbe4 100644
--- a/src/northbridge/intel/fsp_sandybridge/Makefile.inc
+++ b/src/northbridge/intel/fsp_sandybridge/Makefile.inc
@@ -2,7 +2,7 @@
# This file is part of the coreboot project.
#
# Copyright (C) 2010 Google Inc.
-# Copyright (C) 2013 Sage Electronic Engineering, LLC.
+# Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
#
# 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
@@ -18,41 +18,20 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
+subdirs-y += fsp
ramstage-y += northbridge.c
ramstage-y += gma.c
ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpi.c
-ramstage-y += fsp_util.c
-ramstage-$(CONFIG_ENABLE_FAST_BOOT) += mrccache.c
romstage-y += raminit.c
-romstage-y += fsp_util.c
romstage-y += early_init.c
romstage-y += report_platform.c
romstage-y += ../../../arch/x86/lib/walkcbfs.S
-romstage-$(CONFIG_ENABLE_FAST_BOOT) += mrccache.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += udelay.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
-ifeq ($(CONFIG_HAVE_FSP_BIN),y)
-# We don't ship an FSP, but booting without it is bound to fail
-cbfs-files-y += fsp.bin
-fsp.bin-file := $(call strip_quotes,$(CONFIG_FSP_FILE))
-fsp.bin-position := $(CONFIG_FSP_LOC)
-fsp.bin-type := 0xab
-endif
-
-ifeq ($(CONFIG_ENABLE_FAST_BOOT),y)
-$(obj)/mrc.cache:
- dd if=/dev/zero count=1 \
- bs=$(shell printf "%d" $(CONFIG_MRC_CACHE_SIZE) ) | \
- tr '\000' '\377' > $@
-
-cbfs-files-y += mrc.cache
-mrc.cache-file := $(obj)/mrc.cache
-mrc.cache-position := 0xfff50000
-mrc.cache-type := 0xac
-endif
+INCLUDES += -I$(src)/northbridge/intel/fsp_sandybridge/fsp
$(obj)/northbridge/intel/fsp_sandybridge/acpi.ramstage.o : $(obj)/build.h
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig b/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig
new file mode 100644
index 0000000..03999618
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig
@@ -0,0 +1,42 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 Sage Electronic Engineering, LLC.
+##
+## 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
+##
+
+config SANDYBRIDGE_FSP_SPECIFIC_OPTIONS
+ def_bool y
+ select PLATFORM_USES_FSP
+ select USE_GENERIC_FSP_CAR_INC
+ select FSP_USES_UPD if SOUTHBRIDGE_INTEL_FSP_I89XX
+
+config FSP_FILE
+ string
+ default "../intel/fsp/ivybridge_bd82x6x/FvFsp.bin" if SOUTHBRIDGE_INTEL_FSP_BD82X6X
+ default "../intel/fsp/ivybridge_i89xx/FvFsp.bin" if SOUTHBRIDGE_INTEL_FSP_I89XX
+ help
+ The path and filename of the Intel FSP binary for this platform.
+
+config FSP_LOC
+ hex "Intel FSP Binary location in CBFS"
+ default 0xfff80000
+ help
+ The location in CBFS that the FSP is located. This must match the
+ value that is set in the FSP binary. If the FSP needs to be moved,
+ rebase the FSP with the Intel's BCT (tool).
+
+ The Ivy Bridge Processor/Panther Point FSP is built with a preferred
+ base address of 0xFFF80000
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/Makefile.inc b/src/northbridge/intel/fsp_sandybridge/fsp/Makefile.inc
new file mode 100644
index 0000000..ebdc80a
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/Makefile.inc
@@ -0,0 +1,22 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2014 Sage Electronic Engineering, LLC.
+#
+# 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
+#
+
+ramstage-y += chipset_fsp_util.c
+romstage-y += chipset_fsp_util.c
+
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.c b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.c
new file mode 100644
index 0000000..f7bb023
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.c
@@ -0,0 +1,117 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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 <types.h>
+#include <string.h>
+#include <cpu/x86/stack.h>
+#include <console/console.h>
+#include <bootstate.h>
+#include <cbmem.h>
+#include <device/device.h>
+#include <southbridge_pci_devs.h>
+#include <fsp_util.h>
+#include "../chip.h"
+#include <reset.h>
+
+#ifndef CONFIG_ENABLE_FSP_FAST_BOOT
+# error "CONFIG_ENABLE_FSP_FAST_BOOT must be set."
+#endif
+
+#ifdef __PRE_RAM__
+
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+static void GetUpdDefaultFromFsp (FSP_INFO_HEADER *FspInfo, UPD_DATA_REGION *UpdData)
+{
+ VPD_DATA_REGION *VpdDataRgnPtr;
+ UPD_DATA_REGION *UpdDataRgnPtr;
+ VpdDataRgnPtr = (VPD_DATA_REGION *)(UINT32)(FspInfo->CfgRegionOffset + FspInfo->ImageBase);
+ UpdDataRgnPtr = (UPD_DATA_REGION *)(UINT32)(VpdDataRgnPtr->PcdUpdRegionOffset + FspInfo->ImageBase);
+ memcpy((void*)UpdData, (void*)UpdDataRgnPtr, sizeof(UPD_DATA_REGION));
+}
+
+static void ConfigureDefaultUpdData(UPD_DATA_REGION *UpdData)
+{
+ UpdData->HTEnable = TRUE;
+ UpdData->TurboEnable = FALSE;
+ UpdData->MemoryDownEnable = FALSE;
+ UpdData->FastBootEnable = CONFIG_ENABLE_FSP_FAST_BOOT;
+}
+#else /* IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) */
+const PLATFORM_CONFIG DefaultPlatformConfig = {
+#if IS_ENABLED(CONFIG_DISABLE_SANDYBRIDGE_HYPERTHREADING)
+ FALSE, /* Hyperthreading */
+#else
+ TRUE, /* Hyperthreading */
+#endif
+ FALSE, /* Turbo Mode */
+ FALSE, /* Memory Down */
+#if IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT)
+ TRUE, /* Fast Boot */
+#else
+ FALSE, /* Fast Boot */
+#endif /* CONFIG_ENABLE_FSP_FAST_BOOT */
+};
+#endif /* IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX) */
+
+/*
+ *
+ * Call the FSP to do memory init. The FSP doesn't return to this function.
+ * The FSP returns to the romstage_main_continue().
+ *
+ */
+void chipset_fsp_early_init(FSP_INIT_PARAMS *FspInitParams,
+ FSP_INFO_HEADER *fsp_ptr)
+{
+ FSP_INIT_RT_BUFFER *pFspRtBuffer = FspInitParams->RtBufferPtr;
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+ UPD_DATA_REGION *fsp_upd_data = pFspRtBuffer->Common.UpdDataRgnPtr;
+#else
+ MEM_CONFIG MemoryConfig;
+ memset((void*)&MemoryConfig, 0, sizeof(MEM_CONFIG));
+#endif
+ FspInitParams->NvsBufferPtr = NULL;
+
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+ /* Initialize the UPD Data */
+ GetUpdDefaultFromFsp (fsp_ptr, fsp_upd_data);/home/martin/extra/git/coreboot
+ ConfigureDefaultUpdData(fsp_upd_data);
+#else
+ pFspRtBuffer->Platform.MemoryConfig = &MemoryConfig;
+ pFspRtBuffer->PlatformConfiguration.PlatformConfig = &DefaultPlatformConfig;
+#endif
+
+#if IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT)
+ /* Find the fastboot cache that was saved in the ROM */
+ FspInitParams->NvsBufferPtr = find_and_set_fastboot_cache();
+#endif
+
+ pFspRtBuffer->Common.BootMode = 0;
+}
+
+/* The FSP returns here after the fsp_early_init call */
+void ChipsetFspReturnPoint(EFI_STATUS Status,
+ VOID *HobListPtr)
+{
+ if (Status == 0xFFFFFFFF) {
+ hard_reset();
+ }
+ romstage_main_continue(Status, HobListPtr);
+}
+
+#endif /* __PRE_RAM__ */
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.h b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.h
new file mode 100644
index 0000000..2374943
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/chipset_fsp_util.h
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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 CHIPSET_FSP_UTIL_H
+#define CHIPSET_FSP_UTIL_H
+
+#include <fsptypes.h>
+#include <fspfv.h>
+#include <fspffs.h>
+#include <fspapi.h>
+#include <fspplatform.h>
+#include <fspinfoheader.h>
+#include <fsphob.h>
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+#include <peifsp.h>
+#include <fsp_vpd.h>
+#endif
+
+#define FSP_RESERVE_MEMORY_SIZE 0x200000
+
+#define FSP_INFO_HEADER_GUID \
+ { \
+ 0x912740BE, 0x2284, 0x4734, {0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C} \
+ }
+
+#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \
+ { \
+ 0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0 } \
+ }
+
+
+/*
+ *The FSP Image ID is different for each platform's FSP and
+ * can be used to verify that the right FSP binary is loaded.
+ */
+
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_I89XX)
+/* ST2-FSP0 */
+#define FSP_IMAGE_ID_DWORD0 0x2D325453
+#define FSP_IMAGE_ID_DWORD1 0x30505346
+#elif IS_ENABLED(CONFIG_SOUTHBRIDGE_INTEL_FSP_BD82X6X)
+/* CC2-FSP\0 */
+#define FSP_IMAGE_ID_DWORD0 0x2D324343
+#define FSP_IMAGE_ID_DWORD1 0x00505346
+#endif
+
+void romstage_main_continue(EFI_STATUS status, VOID *HobListPtr);
+
+#endif /* CHIPSET_FSP_UTIL_H */
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp_util.c b/src/northbridge/intel/fsp_sandybridge/fsp_util.c
deleted file mode 100644
index a653747..0000000
--- a/src/northbridge/intel/fsp_sandybridge/fsp_util.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013 Sage Electronic Engineering, LLC.
- *
- * 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 <types.h>
-#include <string.h>
-#include <cpu/x86/stack.h>
-#include <console/console.h>
-#include <lib.h>
-#include "fsp_util.h"
-
-#if CONFIG_ENABLE_FAST_BOOT
-#include <device/device.h>
-#include "northbridge.h"
-#include <cbmem.h>
-#include <ip_checksum.h>
-#endif
-
-void find_fsp (void);
-
-#ifndef __PRE_RAM__
-/* Globals pointers for FSP structures */
-void *FspHobListPtr;
-FSP_INFO_HEADER *fsp_header_ptr;
-
-void FspNotify (u32 Phase)
-{
- FSP_NOTFY_PHASE NotifyPhaseProc;
- NOTIFY_PHASE_PARAMS NotifyPhaseParams;
- EFI_STATUS Status;
-
- if (fsp_header_ptr == NULL) {
- find_fsp();
- if (fsp_header_ptr == NULL) {
- post_code(0x4F); /* output something in case there is no serial */
- die("Can't find the FSP!\n");
- }
- }
-
- /* call FSP PEI to Notify PostPciEnumeration */
- NotifyPhaseProc = (FSP_NOTFY_PHASE)(fsp_header_ptr->ImageBase + fsp_header_ptr->NotifyPhaseEntry);
- NotifyPhaseParams.Phase = Phase;
- Status = NotifyPhaseProc (&NotifyPhaseParams);
- if (Status != 0)
- printk(BIOS_ERR,"FSP API NotifyPhase failed for phase 0x%x with status: 0x%x\n", Phase, Status);
-}
-#endif
-
-#ifdef __PRE_RAM__
-/*
- *
- * Call the FSP to do memory init. The FSP doesn't return to this function.
- * The FSP returns to the romstage_main_continue().
- *
- */
-const PLATFORM_CONFIG DefaultPlatformConfig = {
- TRUE, // Hyperthreading
- FALSE, // Turbo Mode
- FALSE, // Memory Down
-#if CONFIG_ENABLE_FAST_BOOT
- TRUE, // Fast Boot
-#else
- FALSE, // Fast Boot
-#endif
-};
-
-void __attribute__ ((noreturn)) fsp_early_init (FSP_INFO_HEADER *fsp_ptr)
-{
- FSP_FSP_INIT FspInitApi;
- FSP_INIT_PARAMS FspInitParams;
- FSP_INIT_RT_BUFFER FspRtBuffer;
- MEM_CONFIG MemoryConfig;
- memset((void*)&MemoryConfig, 0, sizeof(MEM_CONFIG));
-
- memset((void*)&FspRtBuffer, 0, sizeof(FSP_INIT_RT_BUFFER));
- FspRtBuffer.Common.StackTop = (u32 *)ROMSTAGE_STACK;
- FspRtBuffer.Platform.MemoryConfig = &MemoryConfig;
- FspRtBuffer.PlatformConfiguration.PlatformConfig = &DefaultPlatformConfig;
- FspInitParams.NvsBufferPtr = NULL;
-
-#if CONFIG_ENABLE_FAST_BOOT
- /* find_current_mrc_cache */
- struct mrc_data_container *mrc_cache = NULL;
- if (((mrc_cache = find_current_mrc_cache()) == NULL) || (mrc_cache->mrc_data_size == -1UL)) {
- printk(BIOS_DEBUG, "FSP MRC cache not present.\n");
- FspInitParams.NvsBufferPtr = (void *) NULL;
- } else {
- printk(BIOS_DEBUG, "FSP MRC cache present at %x.\n", (u32)mrc_cache);
- printk(BIOS_SPEW, "Saved MRC data:\n");
- hexdump32(BIOS_SPEW, (void *)mrc_cache->mrc_data, (mrc_cache->mrc_data_size / 4));
- FspInitParams.NvsBufferPtr = (void *) (EFI_HOB_GUID_TYPE *) mrc_cache->mrc_data;
- }
-#endif
-
- /* Not sure why passing BootMode is required - the only valid value is 0 */
- FspRtBuffer.Common.BootMode = 0;
- FspInitParams.RtBufferPtr = (FSP_INIT_RT_BUFFER *)&FspRtBuffer;
- FspInitParams.ContinuationFunc = (CONTINUATION_PROC)romstage_main_continue;
- FspInitApi = (FSP_FSP_INIT)(fsp_ptr->ImageBase + fsp_ptr->FspInitEntry);
-
- /* call back to romstage.c here to allow structures to be changed */
- romstage_fsp_rt_buffer_callback(&FspRtBuffer);
-
- FspInitApi(&FspInitParams);
-
- /* Should never return. Control will continue from ContinuationFunc */
- die("Uh Oh! FspInitApi returned");
-}
-#endif
-
-void __attribute__((optimize("O0"))) find_fsp ()
-{
-
-#ifdef __PRE_RAM__
- volatile register u8 *fsp_ptr asm ("eax");
-
- /* Entry point for CAR assembly routine */
- __asm__ __volatile__ (
- ".global find_fsp\n\t"
- "find_fsp:\n\t"
- );
-#else
- u8 *fsp_ptr;
-#endif
-
- /* The FSP is stored in CBFS */
- fsp_ptr = (u8 *) CONFIG_FSP_LOC;
-
- /* Check the FV signature, _FVH */
- if (((EFI_FIRMWARE_VOLUME_HEADER *)fsp_ptr)->Signature == 0x4856465F) {
- /* Go to the end of the FV header and align the address. */
- fsp_ptr += ((EFI_FIRMWARE_VOLUME_HEADER *)fsp_ptr)->ExtHeaderOffset;
- fsp_ptr += ((EFI_FIRMWARE_VOLUME_EXT_HEADER *)fsp_ptr)->ExtHeaderSize;
- fsp_ptr = (u8 *)(((u32)fsp_ptr + 7) & 0xFFFFFFF8);
- } else {
- fsp_ptr = (u8*)ERROR_NO_FV_SIG;
- }
-
- /* Check the FFS GUID */
- if (((u32)fsp_ptr > 0xff) &&
- (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[0] == 0x912740BE) &&
- (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[1] == 0x47342284) &&
- (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[2] == 0xB08471B9) &&
- (((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[3] == 0x0C3F3527)) {
- /* Add the FFS Header size to the base to find the Raw section Header */
- fsp_ptr += sizeof(EFI_FFS_FILE_HEADER);
- } else {
- fsp_ptr = (u8 *)ERROR_NO_FFS_GUID;
- }
-
- if (((u32)fsp_ptr > 0xff) &&
- ((EFI_RAW_SECTION *)fsp_ptr)->Type == EFI_SECTION_RAW) {
- /* Add the Raw Header size to the base to find the FSP INFO Header */
- fsp_ptr += sizeof(EFI_RAW_SECTION);
- } else {
- fsp_ptr = (u8 *)ERROR_NO_INFO_HEADER;
- }
-
-#if 0 /* removed for debugging */
- /* Verify that the FSP is set to the base address we're expecting.*/
- if (((u32)fsp_ptr > 0xff) &&
- (*(u32*)(fsp_ptr + FSP_IMAGE_BASE_LOC) != CONFIG_FSP_LOC)) {
- fsp_ptr = (u8 *)ERROR_IMAGEBASE_MISMATCH;
- }
- /* Verify the FSP Signature */
- if (((u32)fsp_ptr > 0xff) &&
- (*(u32*)(fsp_ptr + FSP_IMAGE_SIG_LOC) != FSP_SIG)){
- fsp_ptr = (u8 *)ERROR_INFO_HEAD_SIG_MISMATCH;
- }
-
- /* Verify the FSP ID */
- if (((u32)fsp_ptr > 0xff) &&
- (*(u32 *)(fsp_ptr + FSP_IMAGE_ID_LOC) != CONFIG_FSP_IMAGE_ID_DWORD0)){
- fsp_ptr = (u8 *)ERROR_FSP_SIG_MISMATCH;
- }
- if (((u32)fsp_ptr > 0xff) &&
- (*(u32 *)(fsp_ptr + FSP_IMAGE_ID_LOC + 4) != CONFIG_FSP_IMAGE_ID_DWORD1)) {
- fsp_ptr = (u8 *)ERROR_FSP_SIG_MISMATCH;
- }
-#endif /* removed for debugging */
-
-#ifdef __PRE_RAM__
- __asm__ __volatile__ ("ret");
-#else
- fsp_header_ptr = (FSP_INFO_HEADER *) fsp_ptr;
- printk(BIOS_SPEW,"fsp_header_ptr: 0x%x\n", (u32)fsp_header_ptr);
- return;
-#endif
-}
-
-void print_fsp_info(void) {
-
-#ifndef __PRE_RAM__
- if (fsp_header_ptr == NULL)
- find_fsp();
-
- printk(BIOS_INFO,"FSP Header Version: %d\n", fsp_header_ptr->HeaderRevision);
- printk(BIOS_INFO,"FSP Revision: %d.%d\n",
- (u8)((fsp_header_ptr->ImageRevision >> 8) & 0xff),
- (u8)(fsp_header_ptr->ImageRevision & 0xff));
-#endif
-}
-
-#ifndef __PRE_RAM__ /* Only parse HOB data in ramstage */
-static void print_hob_mem_attributes(void *Hobptr) {
- EFI_HOB_MEMORY_ALLOCATION *HobMemoryPtr = (EFI_HOB_MEMORY_ALLOCATION *)Hobptr;
- EFI_MEMORY_TYPE Hobmemtype = HobMemoryPtr->AllocDescriptor.MemoryType;
- u64 Hobmemaddr = HobMemoryPtr->AllocDescriptor.MemoryBaseAddress;
- u64 Hobmemlength = HobMemoryPtr->AllocDescriptor.MemoryLength;
- const char * Hobmemtypenames[15];
-
- Hobmemtypenames[0] = "EfiReservedMemoryType";
- Hobmemtypenames[1] = "EfiLoaderCode";
- Hobmemtypenames[2] = "EfiLoaderData";
- Hobmemtypenames[3] = "EfiBootServicesCode";
- Hobmemtypenames[4] = "EfiBootServicesData";
- Hobmemtypenames[5] = "EfiRuntimeServicesCode";
- Hobmemtypenames[6] = "EfiRuntimeServicesData";
- Hobmemtypenames[7] = "EfiConventionalMemory";
- Hobmemtypenames[8] = "EfiUnusableMemory";
- Hobmemtypenames[9] = "EfiACPIReclaimMemory";
- Hobmemtypenames[10] = "EfiACPIMemoryNVS";
- Hobmemtypenames[11] = "EfiMemoryMappedIO";
- Hobmemtypenames[12] = "EfiMemoryMappedIOPortSpace";
- Hobmemtypenames[13] = "EfiPalCode";
- Hobmemtypenames[14] = "EfiMaxMemoryType";
-
- printk(BIOS_SPEW, " Memory type %s (0x%x)\n",
- Hobmemtypenames[(u32)Hobmemtype], (u32) Hobmemtype);
- printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
- (long unsigned int)Hobmemaddr, (long unsigned int)Hobmemlength);
-}
-
-static void print_hob_resource_attributes(void *Hobptr) {
- EFI_HOB_RESOURCE_DESCRIPTOR *HobResourcePtr = (EFI_HOB_RESOURCE_DESCRIPTOR *)Hobptr;
- u32 Hobrestype = HobResourcePtr->ResourceType;
- u32 Hobresattr = HobResourcePtr->ResourceAttribute;
- u64 Hobresaddr = HobResourcePtr->PhysicalStart;
- u64 Hobreslength = HobResourcePtr->ResourceLength;
- const char *Hobrestypestr = NULL;
-
- // HOB Resource Types
- switch (Hobrestype) {
- case EFI_RESOURCE_SYSTEM_MEMORY:
- Hobrestypestr = "EFI_RESOURCE_SYSTEM_MEMORY"; break;
- case EFI_RESOURCE_MEMORY_MAPPED_IO:
- Hobrestypestr = "EFI_RESOURCE_MEMORY_MAPPED_IO"; break;
- case EFI_RESOURCE_IO:
- Hobrestypestr = "EFI_RESOURCE_IO"; break;
- case EFI_RESOURCE_FIRMWARE_DEVICE:
- Hobrestypestr = "EFI_RESOURCE_FIRMWARE_DEVICE"; break;
- case EFI_RESOURCE_MEMORY_MAPPED_IO_PORT:
- Hobrestypestr = "EFI_RESOURCE_MEMORY_MAPPED_IO_PORT"; break;
- case EFI_RESOURCE_MEMORY_RESERVED:
- Hobrestypestr = "EFI_RESOURCE_MEMORY_RESERVED"; break;
- case EFI_RESOURCE_IO_RESERVED:
- Hobrestypestr = "EFI_RESOURCE_IO_RESERVED"; break;
- case EFI_RESOURCE_MAX_MEMORY_TYPE:
- Hobrestypestr = "EFI_RESOURCE_MAX_MEMORY_TYPE"; break;
- default:
- Hobrestypestr = "EFI_RESOURCE_UNKNOWN"; break;
- }
-
- printk(BIOS_SPEW, " Resource %s (0x%0x) has attributes 0x%0x\n",
- Hobrestypestr, Hobrestype, Hobresattr);
- printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
- (long unsigned int)Hobresaddr, (long unsigned int)Hobreslength);
-}
-
-static const char * get_hob_type_string(void *Hobptr) {
- EFI_HOB_GENERIC_HEADER *HobHeaderPtr = (EFI_HOB_GENERIC_HEADER *)Hobptr;
- u16 Hobtype = HobHeaderPtr->HobType;
- const char *Hobtypestring = NULL;
-
- switch (Hobtype) {
- case EFI_HOB_TYPE_HANDOFF:
- Hobtypestring = "EFI_HOB_TYPE_HANDOFF"; break;
- case EFI_HOB_TYPE_MEMORY_ALLOCATION:
- Hobtypestring = "EFI_HOB_TYPE_MEMORY_ALLOCATION"; break;
- case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
- Hobtypestring = "EFI_HOB_TYPE_RESOURCE_DESCRIPTOR"; break;
- case EFI_HOB_TYPE_GUID_EXTENSION:
- Hobtypestring = "EFI_HOB_TYPE_GUID_EXTENSION"; break;
- case EFI_HOB_TYPE_MEMORY_POOL:
- Hobtypestring = "EFI_HOB_TYPE_MEMORY_POOL"; break;
- case EFI_HOB_TYPE_UNUSED:
- Hobtypestring = "EFI_HOB_TYPE_UNUSED"; break;
- case EFI_HOB_TYPE_END_OF_HOB_LIST:
- Hobtypestring = "EFI_HOB_TYPE_END_OF_HOB_LIST"; break;
- default:
- Hobtypestring = "EFI_HOB_TYPE_UNRECOGNIZED"; break;
- }
-
- return Hobtypestring;
-}
-
-/* Print out a structure of all the HOBs
- * that match a certain type:
- * Print all types (0x0000)
- * EFI_HOB_TYPE_HANDOFF (0x0001)
- * EFI_HOB_TYPE_MEMORY_ALLOCATION (0x0002)
- * EFI_HOB_TYPE_RESOURCE_DESCRIPTOR (0x0003)
- * EFI_HOB_TYPE_GUID_EXTENSION (0x0004)
- * EFI_HOB_TYPE_MEMORY_POOL (0x0007)
- * EFI_HOB_TYPE_UNUSED (0xFFFE)
- * EFI_HOB_TYPE_END_OF_HOB_LIST (0xFFFF)
- */
-void print_hob_type_structure(u16 Hobtype, void *Hoblistptr) {
- u32 *Currenthob;
- u32 *Nexthob = 0;
- u8 Lasthob = 0;
- u32 Currenttype;
- const char *Currenttypestr;
-
- Currenthob = Hoblistptr;
-
- /* Print out HOBs of our desired type until
- * the end of the HOB list
- */
- printk(BIOS_DEBUG, "\n=== FSP HOB Data Structure ===\n");
- printk(BIOS_DEBUG, "FSP Hoblistptr: 0x%0x\n",
- (u32) Hoblistptr);
- do {
- EFI_HOB_GENERIC_HEADER *CurrentHeaderPtr = (EFI_HOB_GENERIC_HEADER *)Currenthob;
- Currenttype = CurrentHeaderPtr->HobType; // Get the type of this HOB
- Currenttypestr = get_hob_type_string(Currenthob);
-
- if (Currenttype == Hobtype || Hobtype == 0x0000) {
- printk(BIOS_DEBUG, "HOB 0x%0x is an %s (type 0x%0x)\n",
- (u32) Currenthob, Currenttypestr, Currenttype);
- switch (Currenttype) {
- case EFI_HOB_TYPE_MEMORY_ALLOCATION:
- print_hob_mem_attributes(Currenthob); break;
- case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
- print_hob_resource_attributes(Currenthob); break;
- }
- }
-
- Lasthob = END_OF_HOB_LIST(Currenthob); // Check for end of HOB list
- if (!Lasthob) {
- Nexthob = GET_NEXT_HOB(Currenthob); // Get next HOB pointer
- Currenthob = Nexthob; // Start on next HOB
- }
- } while (!Lasthob);
- printk(BIOS_DEBUG, "=== End of FSP HOB Data Structure ===\n\n");
-}
-
-#if CONFIG_ENABLE_FAST_BOOT
-/**
- * Save the FSP memory HOB (mrc data) to the MRC area in CBMEM
- */
-void save_mrc_data(void *hob_start)
-{
- u32 *mrc_hob;
- u32 *mrc_hob_data;
- u32 mrc_hob_size;
- struct mrc_data_container *mrc_data;
- int output_len;
- const EFI_GUID mrc_guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
-
- mrc_hob = GetNextGuidHob(&mrc_guid, hob_start);
- if (mrc_hob == NULL) die ("mrc_hob is NULL");
-
- mrc_hob_data = GET_GUID_HOB_DATA (mrc_hob);
- mrc_hob_size = (u32) GET_HOB_LENGTH(mrc_hob);
-
- printk(BIOS_DEBUG, "Memory Configure Data Hob at %p (size = 0x%x).\n",
- (void *)mrc_hob_data, mrc_hob_size);
-
- output_len = ALIGN(mrc_hob_size, 16);
-
- /* Save the MRC S3/Fastboot/ADR restore data to cbmem */
- mrc_data = cbmem_add (CBMEM_ID_MRCDATA,
- output_len + sizeof(struct mrc_data_container));
-
- /* Just return if there was a problem with getting CBMEM */
- if (mrc_data == NULL) return;
-
- printk(BIOS_DEBUG, "Copy FSP MRC DATA to HOB (source addr %p, dest addr %p, %u bytes)\n",
- (void *)mrc_hob_data, mrc_data, output_len);
-
- mrc_data->mrc_signature = MRC_DATA_SIGNATURE;
- mrc_data->mrc_data_size = output_len;
- mrc_data->reserved = 0;
- memcpy(mrc_data->mrc_data, (const void *)mrc_hob_data, mrc_hob_size);
-
- /* Zero the unused space in aligned buffer. */
- if (output_len > mrc_hob_size)
- memset((mrc_data->mrc_data + mrc_hob_size), 0,
- output_len - mrc_hob_size);
-
- mrc_data->mrc_checksum = compute_ip_checksum(mrc_data->mrc_data,
- mrc_data->mrc_data_size);
-
- printk(BIOS_SPEW, "MRC data in CBMEM(includes align and checksum):\n");
- hexdump32(BIOS_SPEW, (void *)mrc_data->mrc_data, (output_len / 4));
-}
-#endif
-#endif /*__PRE_RAM__*/
diff --git a/src/northbridge/intel/fsp_sandybridge/fsp_util.h b/src/northbridge/intel/fsp_sandybridge/fsp_util.h
deleted file mode 100644
index d87cf58..0000000
--- a/src/northbridge/intel/fsp_sandybridge/fsp_util.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013 Sage Electronic Engineering, LLC.
- *
- * 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 FSP_UTIL_H
-#define FSP_UTIL_H
-
-#include <fsptypes.h>
-#include <fspfv.h>
-#include <fspffs.h>
-#include <fspapi.h>
-#include <fspplatform.h>
-#include <fspinfoheader.h>
-#include <fsphob.h>
-
-void fsp_early_init(FSP_INFO_HEADER *fsp_info);
-void FspNotify(u32 Phase);
-void romstage_main_continue(EFI_STATUS Status, VOID *HobListPtr);
-void print_hob_type_structure(u16 Hobtype, void *Hoblistptr);
-void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer);
-void print_fsp_info(void);
-
-#if CONFIG_ENABLE_FAST_BOOT
-void save_mrc_data(void *hob_start);
-#endif
-
-
-/* Additional HOB types not included in the FSP:
- * #define EFI_HOB_TYPE_HANDOFF 0x0001
- * #define EFI_HOB_TYPE_MEMORY_ALLOCATION 0x0002
- * #define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR 0x0003
- * #define EFI_HOB_TYPE_GUID_EXTENSION 0x0004
- * #define EFI_HOB_TYPE_FV 0x0005
- * #define EFI_HOB_TYPE_CPU 0x0006
- * #define EFI_HOB_TYPE_MEMORY_POOL 0x0007
- * #define EFI_HOB_TYPE_CV 0x0008
- * #define EFI_HOB_TYPE_UNUSED 0xFFFE
- * #define EFI_HOB_TYPE_END_OF_HOB_LIST 0xffff
- */
-#define EFI_HOB_TYPE_HANDOFF 0x0001
-#define EFI_HOB_TYPE_MEMORY_POOL 0x0007
-
-#if CONFIG_ENABLE_FAST_BOOT
-#define FSP_INFO_HEADER_GUID \
- { \
- 0x912740BE, 0x2284, 0x4734, {0xB9, 0x71, 0x84, 0xB0, 0x27, 0x35, 0x3F, 0x0C} \
- }
-
-#define FSP_NON_VOLATILE_STORAGE_HOB_GUID \
- { \
- 0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0xb, 0x7b, 0xa9, 0xe4, 0xb0 } \
- }
-#endif
-
-/* The offset in bytes from the start of the info structure */
-#define FSP_IMAGE_SIG_LOC 0
-#define FSP_IMAGE_ID_LOC 16
-#define FSP_IMAGE_BASE_LOC 28
-
-#define FSP_SIG 0x48505346 /* 'FSPH' */
-
-#define ERROR_NO_FV_SIG 1
-#define ERROR_NO_FFS_GUID 2
-#define ERROR_NO_INFO_HEADER 3
-#define ERROR_IMAGEBASE_MISMATCH 4
-#define ERROR_INFO_HEAD_SIG_MISMATCH 5
-#define ERROR_FSP_SIG_MISMATCH 6
-
-#ifndef __PRE_RAM__
-extern void *FspHobListPtr;
-#endif
-
-#endif /* FSP_UTIL_H */
diff --git a/src/northbridge/intel/fsp_sandybridge/mrccache.c b/src/northbridge/intel/fsp_sandybridge/mrccache.c
deleted file mode 100644
index b8893ae..0000000
--- a/src/northbridge/intel/fsp_sandybridge/mrccache.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Google Inc.
- * Copyright (C) 2013 Sage Electronic Engineering, LLC.
- *
- * 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 <stdint.h>
-#include <string.h>
-#include <bootstate.h>
-#include <console/console.h>
-#include <cbfs.h>
-#include <ip_checksum.h>
-#include <device/device.h>
-#include <cbmem.h>
-#include "northbridge.h"
-#include <spi-generic.h>
-#include <spi_flash.h>
-#include "fsp_util.h"
-
-/* convert a pointer to flash area into the offset inside the flash */
-static inline u32 to_flash_offset(void *p) {
- return ((u32)p + CONFIG_VIRTUAL_ROM_SIZE);
-}
-
-static struct mrc_data_container *next_mrc_block(
- struct mrc_data_container *mrc_cache)
-{
- /* MRC data blocks are aligned within the region */
- u32 mrc_size = sizeof(*mrc_cache) + mrc_cache->mrc_data_size;
- if (mrc_size & (MRC_DATA_ALIGN - 1UL)) {
- mrc_size &= ~(MRC_DATA_ALIGN - 1UL);
- mrc_size += MRC_DATA_ALIGN;
- }
-
- u8 *region_ptr = (u8*)mrc_cache;
- region_ptr += mrc_size;
- return (struct mrc_data_container *)region_ptr;
-}
-
-static int is_mrc_cache(struct mrc_data_container *mrc_cache)
-{
- return (!!mrc_cache) && (mrc_cache->mrc_signature == MRC_DATA_SIGNATURE);
-}
-
-static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr)
-{
- size_t region_size;
- *mrc_region_ptr = cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
- "mrc.cache", 0xac,
- ®ion_size);
-
- return region_size;
-}
-
-/*
- * Find the largest index block in the MRC cache. Return NULL if none is
- * found.
- */
-static struct mrc_data_container *find_current_mrc_cache_local
- (struct mrc_data_container *mrc_cache, u32 region_size)
-{
- u32 region_end;
- u32 entry_id = 0;
- struct mrc_data_container *mrc_next = mrc_cache;
-
- region_end = (u32) mrc_cache + region_size;
-
- /* Search for the last filled entry in the region */
- while (is_mrc_cache(mrc_next)) {
- entry_id++;
- mrc_cache = mrc_next;
- mrc_next = next_mrc_block(mrc_next);
- if ((u32)mrc_next >= region_end) {
- /* Stay in the MRC data region */
- break;
- }
- }
-
- if (entry_id == 0) {
- printk(BIOS_ERR, "%s: No valid MRC cache found.\n", __func__);
- return NULL;
- }
-
- /* Verify checksum */
- if (mrc_cache->mrc_checksum !=
- compute_ip_checksum(mrc_cache->mrc_data,
- mrc_cache->mrc_data_size)) {
- printk(BIOS_ERR, "%s: MRC cache checksum mismatch\n", __func__);
- return NULL;
- }
-
- printk(BIOS_DEBUG, "%s: picked entry %u from cache block\n", __func__,
- entry_id - 1);
-
- return mrc_cache;
-}
-
-/* SPI code needs malloc/free.
- * Also unknown if writing flash from XIP-flash code is a good idea
- */
-#if !defined(__PRE_RAM__)
-/* find the first empty block in the MRC cache area.
- * If there's none, return NULL.
- *
- * @mrc_cache_base - base address of the MRC cache area
- * @mrc_cache - current entry (for which we need to find next)
- * @region_size - total size of the MRC cache area
- */
-static struct mrc_data_container *find_next_mrc_cache
- (struct mrc_data_container *mrc_cache_base,
- struct mrc_data_container *mrc_cache,
- u32 region_size)
-{
- u32 region_end = (u32) mrc_cache_base + region_size;
- u32 mrc_data_size = mrc_cache->mrc_data_size;
-
- mrc_cache = next_mrc_block(mrc_cache);
- if (((u32)mrc_cache + mrc_data_size) >= region_end) {
- /* Crossed the boundary */
- mrc_cache = NULL;
- printk(BIOS_DEBUG, "%s: no available entries found\n",
- __func__);
- } else {
- printk(BIOS_DEBUG,
- "%s: picked next entry from cache block at %p\n",
- __func__, mrc_cache);
- }
-
- return mrc_cache;
-}
-
-static void update_mrc_cache(void *unused)
-{
- printk(BIOS_DEBUG, "Updating MRC cache data.\n");
- struct mrc_data_container *current = cbmem_find(CBMEM_ID_MRCDATA);
- struct mrc_data_container *cache, *cache_base;
- u32 cache_size;
-
- if (!current) {
- printk(BIOS_ERR, "No MRC cache in cbmem. Can't update flash.\n");
- return;
- }
- if (current->mrc_data_size == -1) {
- printk(BIOS_ERR, "MRC cache data in cbmem invalid.\n");
- return;
- }
-
- cache_size = get_mrc_cache_region(&cache_base);
- if (cache_base == NULL) {
- printk(BIOS_ERR, "%s: could not find MRC cache area\n",
- __func__);
- return;
- }
-
- /*
- * we need to:
- */
- // 0. compare MRC data to last mrc-cache block (exit if same)
- cache = find_current_mrc_cache_local(cache_base, cache_size);
-
- if (cache && (cache->mrc_data_size == current->mrc_data_size) &&
- (memcmp(cache, current, cache->mrc_data_size) == 0)) {
- printk(BIOS_DEBUG,
- "MRC data in flash is up to date. No update.\n");
- return;
- }
-
- // 1. use spi_flash_probe() to find the flash, then
- spi_init();
- struct spi_flash *flash = spi_flash_probe(0, 0, 1000000, SPI_MODE_3);
- if (!flash) {
- printk(BIOS_DEBUG, "Could not find SPI device\n");
- return;
- }
-
- // 2. look up the first unused block
- if (cache)
- cache = find_next_mrc_cache(cache_base, cache, cache_size);
-
- /*
- * 3. if no such place exists, erase entire mrc-cache range & use
- * block 0. First time around the erase is not needed, but this is a
- * small overhead for simpler code.
- */
- if (!cache) {
- printk(BIOS_DEBUG,
- "Need to erase the MRC cache region of %d bytes at %p\n",
- cache_size, cache_base);
-
- flash->erase(flash, to_flash_offset(cache_base), cache_size);
-
- /* we will start at the beginning again */
- cache = cache_base;
- }
- // 4. write mrc data with flash->write()
- printk(BIOS_DEBUG, "Write MRC cache update to flash at %p\n",
- cache);
- flash->write(flash, to_flash_offset(cache),
- current->mrc_data_size + sizeof(*current), current);
-}
-
-static void find_fsp_hob(void *unused)
-{
- /* Set the global HOB list pointer */
- FspHobListPtr = (void*)*((u32*) cbmem_find(CBMEM_ID_HOB_POINTER));
-
- if (!FspHobListPtr){
- printk(BIOS_ERR, "ERROR: Could not find FSP HOB pointer in CBFS!\n");
- } else {
- /* 0x0000: Print all types */
- print_hob_type_structure(0x000, FspHobListPtr);
-
- #if CONFIG_ENABLE_FAST_BOOT
- save_mrc_data(FspHobListPtr);
- update_mrc_cache(NULL);
- #endif
- }
-}
-
-BOOT_STATE_INIT_ENTRIES(fsp_hob_find) = {
- BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY,
- find_fsp_hob, NULL),
-};
-#endif /* !defined(__PRE_RAM__) */
-
-struct mrc_data_container *find_current_mrc_cache(void)
-{
- struct mrc_data_container *cache_base;
- u32 cache_size;
-
- cache_size = get_mrc_cache_region(&cache_base);
- if (cache_base == NULL) {
- printk(BIOS_ERR, "%s: could not find MRC cache area\n",
- __func__);
- return NULL;
- }
-
- /*
- * we need to:
- */
- // 0. compare MRC data to last mrc-cache block (exit if same)
- return find_current_mrc_cache_local(cache_base, cache_size);
-}
diff --git a/src/northbridge/intel/fsp_sandybridge/northbridge.c b/src/northbridge/intel/fsp_sandybridge/northbridge.c
index 20595ee..d5b1575 100644
--- a/src/northbridge/intel/fsp_sandybridge/northbridge.c
+++ b/src/northbridge/intel/fsp_sandybridge/northbridge.c
@@ -36,7 +36,7 @@
#include <cbmem.h>
#include "chip.h"
#include "northbridge.h"
-#include "fsp_util.h"
+#include <fsp_util.h>
static int bridge_revision_id = -1;
static u8 finished_FSP_after_pci = 0;
diff --git a/src/northbridge/intel/fsp_sandybridge/northbridge.h b/src/northbridge/intel/fsp_sandybridge/northbridge.h
index 3179832..9a0cf42 100644
--- a/src/northbridge/intel/fsp_sandybridge/northbridge.h
+++ b/src/northbridge/intel/fsp_sandybridge/northbridge.h
@@ -226,15 +226,6 @@ void report_platform_info(void);
#define MRC_DATA_ALIGN 0x1000
#define MRC_DATA_SIGNATURE (('M'<<0)|('R'<<8)|('C'<<16)|('D'<<24))
-struct mrc_data_container {
- u32 mrc_signature; // "MRCD"
- u32 mrc_data_size; // Actual total size of this structure
- u32 mrc_checksum; // IP style checksum
- u32 reserved; // For header alignment
- u8 mrc_data[0]; // Variable size, platform/run time dependent.
-} __attribute__ ((packed));
-
-struct mrc_data_container *find_current_mrc_cache(void);
#if !defined(__PRE_RAM__)
#include "gma.h"
int init_igd_opregion(igd_opregion_t *igd_opregion);
diff --git a/src/northbridge/intel/fsp_sandybridge/northbridge_pci_devs.h b/src/northbridge/intel/fsp_sandybridge/northbridge_pci_devs.h
new file mode 100644
index 0000000..5713712
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/northbridge_pci_devs.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC.
+ *
+ * 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_FSP_SANDYBRIDGE_PCI_DEVS_H_
+#define _INTEL_FSP_SANDYBRIDGE_PCI_DEVS_H_
+
+#include <device/pci_def.h>
+
+#define BUS0 0
+
+/* NB PCIe PEG slot */
+#define NB_PEG_DEV 0x01
+#define NB_PEG_FUNC 0
+# define NB_PEG_DEVFN PCI_DEVFN(NB_PEG_DEV, NB_PEG_FUNC)
+#define PCIE_CTRL1_FUNC 1
+# define PCIE_CTRL1_DEVFN PCI_DEVFN(NB_PEG_DEV, PCIE_CTRL1_FUNC)
+#define PCIE_CTRL2_FUNC 2
+# define PCIE_CTRL2_DEVFN PCI_DEVFN(NB_PEG_DEV, PCIE_CTRL2_FUNC)
+
+/* Onboard Graphics */
+#define GFX_DEV 0x02
+#define GFX_FUNC 0
+# define GFX_DEVFN PCI_DEVFN(GFX_DEV, GFX_FUNC)
+
+/* NB PCIe slot */
+#define NB_PCIE_DEV 0x06
+#define NB_PCIE_FUNC 0
+# define NB_PCIE_DEVFN PCI_DEVFN(NB_PCIE_DEV, NB_PCIE_FUNC)
+
+#endif /* _INTEL_FSP_SANDYBRIDGE_PCI_DEVS_H_ */
diff --git a/src/southbridge/intel/fsp_bd82x6x/Makefile.inc b/src/southbridge/intel/fsp_bd82x6x/Makefile.inc
index 7088caa..a1d3e62 100644
--- a/src/southbridge/intel/fsp_bd82x6x/Makefile.inc
+++ b/src/southbridge/intel/fsp_bd82x6x/Makefile.inc
@@ -69,3 +69,5 @@ else
endif
PHONY += bd82x6x_add_me
+
+INCLUDES += -I$(src)/southbridge/intel/fsp_bd82x6x
diff --git a/src/southbridge/intel/fsp_bd82x6x/southbridge_pci_devs.h b/src/southbridge/intel/fsp_bd82x6x/southbridge_pci_devs.h
new file mode 100644
index 0000000..1f991d7
--- /dev/null
+++ b/src/southbridge/intel/fsp_bd82x6x/southbridge_pci_devs.h
@@ -0,0 +1,127 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC.
+ *
+ * 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_FSP_BD82X6X_PCI_DEVS_H_
+#define _INTEL_FSP_BD82X6X_PCI_DEVS_H_
+
+#include <device/pci_def.h>
+
+#define BUS0 0
+
+/* XHCI */
+#define XHCI_DEV 0x14
+#define XHCI_FUNC 0
+# define XHCI_DEVFN PCI_DEVFN(XHCI_DEV, XHCI_FUNC)
+
+/* Management Engine Interface */
+#define MEI_DEV 0x16
+#define MEI1_FUNC 0x0
+# define MEI1_DEVFN PCI_DEVFN(MEI_DEV, MEI1_FUNC)
+
+#define MEI2_FUNC 0x1
+# define MEI2_DEVFN PCI_DEVFN(MEI_DEV, MEI2_FUNC)
+
+/* MEI - IDE Redirection */
+#define IDE_DEV 0x16
+#define IDE_FUNC 2
+# define IDE_DEVFN PCI_DEVFN(IDE_DEV, IDE_FUNC)
+
+/* MEI - Keyboard / Text Redirection */
+#define KT_DEV 0x16
+#define KT_FUNC 0x3
+#define KT_DEVFN PCI_DEVFN(KT_DEV, KT_FUNC)
+
+/* Gigabit Ethernet */
+#define GBE_DEV 0x19
+#define GBE_FUNC 0x0
+#define GBE_DEVFN PCI_DEVFN(GBE_DEV, GBE_FUNC)
+
+/* EHCI */
+#define EHCI1_DEV 0x1D
+#define EHCI1_FUNC 0
+# define EHCI1_DEVFN PCI_DEVFN(EHCI1_DEV, EHCI1_FUNC)
+
+#define EHCI2_DEV 0x1A
+#define EHCI2_FUNC 0
+# define EHCI2_DEVFN PCI_DEVFN(EHCI2_DEV, EHCI2_FUNC)
+
+/* HD Audio */
+#define HDA_DEV 0x1B
+#define HDA_FUNC 0
+# define HDA_DEVFN PCI_DEVFN(HDA_DEV, HDA_FUNC)
+
+/* PCIe Ports */
+#define SB_PCIE_DEV 0x1C
+#define SB_PCIE_PORT1_FUNC 0
+# define SB_PCIE_PORT1_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT1_FUNC)
+
+#define SB_PCIE_PORT2_FUNC 1
+# define SB_PCIE_PORT2_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT2_FUNC)
+
+#define SB_PCIE_PORT3_FUNC 2
+# define SB_PCIE_PORT3_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT3_FUNC)
+
+#define SB_PCIE_PORT4_FUNC 3
+# define SB_PCIE_PORT4_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT4_FUNC)
+
+#define SB_PCIE_PORT5_FUNC 4
+# define SB_PCIE_PORT5_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT5_FUNC)
+
+#define SB_PCIE_PORT6_FUNC 5
+# define SB_PCIE_PORT6_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT6_FUNC)
+
+#define SB_PCIE_PORT7_FUNC 6
+# define SB_PCIE_PORT7_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT7_FUNC)
+
+#define SB_PCIE_PORT8_FUNC 7
+# define SB_PCIE_PORT8_DEVFN PCI_DEVFN(SB_PCIE_DEV, SB_PCIE_PORT8_FUNC)
+
+/* PCI Bridge */
+#define SB_PCI_DEV 0x1E
+#define SB_PCI_PORT_FUNC 0
+# define SB_PCI_PORT_DEVFN PCI_DEVFN(SB_PCI_PORT_DEV, SB_PCI_PORT_FUNC)
+
+/* Platform Controller Hub */
+#define PCH_DEV 0x1F
+
+/* LPC */
+#define LPC_DEV PCH_DEV
+#define LPC_FUNC 0
+# define LPC_DEVFN PCI_DEVFN(LPC_DEV, LPC_FUNC)
+
+/* SMBUS */
+#define SMBUS_DEV PCH_DEV
+#define SMBUS_FUNC 3
+# define SMBUS_DEVFN PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC)
+
+/* SATA */
+#define SATA_DEV PCH_DEV
+#define SATA1_FUNC 2
+# define SATA1_DEVFN PCI_DEVFN(SATA_DEV, SATA1_FUNC)
+
+#define SATA2_FUNC 5
+# define SATA2_DEVFN PCI_DEVFN(SATA_DEV, SATA2_FUNC)
+
+/* Thermal Sensor */
+#define TS_DEV PCH_DEV
+#define TS_FUNC 6
+# define TS_DEVFN PCI_DEVFN(TS_DEV, TS_FUNC)
+
+#endif /* _INTEL_FSP_BD82X6X_PCI_DEVS_H_ */