Trevor Mosey (uberushaximus(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5637
-gerrit
commit e09f16f2f1fb7c7fc5d38a8c51c468c6dbbe0857
Author: Trevor Mosey <uberushaximus(a)gmail.com>
Date: Fri May 2 16:11:50 2014 -0500
lenovo/t60: Move mainboard_enable() code into a mainboard_init()
mainboard_enable() is now modelled after google/parrot where the
enable function only sets dev->ops->init for the root device to
point to a mainboard_init() function, which in turn is called in a
later pass over the device tree to do the actual initialization.
Change-Id: I89a5192bd45ca8321b2b1ac49b073122e0f6ee2b
Signed-off-by: Trevor Mosey <uberushaximus(a)gmail.com>
---
src/mainboard/lenovo/t60/mainboard.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/mainboard/lenovo/t60/mainboard.c b/src/mainboard/lenovo/t60/mainboard.c
index bfdbef6..623031a 100644
--- a/src/mainboard/lenovo/t60/mainboard.c
+++ b/src/mainboard/lenovo/t60/mainboard.c
@@ -46,7 +46,7 @@ int get_cst_entries(acpi_cstate_t **entries)
return ARRAY_SIZE(cst_entries);
}
-static void mainboard_enable(device_t dev)
+static void mainboard_init(device_t dev)
{
struct southbridge_intel_i82801gx_config *config;
device_t dev0, idedev;
@@ -78,6 +78,11 @@ static void mainboard_enable(device_t dev)
ec_write(0x0c, inb(0x164c) & 8 ? 0x89 : 0x09);
}
+static void mainboard_enable(device_t dev)
+{
+ dev->ops->init = mainboard_init;
+}
+
struct chip_operations mainboard_ops = {
.enable_dev = mainboard_enable,
};
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 4caf56fb1ba56a3ba3b55591d04258e44ab8badd
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/include/timestamp.h | 4 +
src/lib/Makefile.inc | 1 +
src/lib/fsp/Kconfig | 144 ++++++++++++++
src/lib/fsp/Makefile.inc | 49 +++++
src/lib/fsp/cache_as_ram.inc | 169 +++++++++++++++++
src/lib/fsp/fastboot_cache.c | 253 +++++++++++++++++++++++++
src/lib/fsp/fsp_util.c | 433 +++++++++++++++++++++++++++++++++++++++++++
src/lib/fsp/fsp_util.h | 95 ++++++++++
10 files changed, 1156 insertions(+)
diff --git a/src/Kconfig b/src/Kconfig
index cc80b43..a42cc26 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -275,6 +275,7 @@ comment "Embedded Controllers"
source src/ec/Kconfig
comment "SoC"
source src/soc/Kconfig
+source src/lib/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/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,
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 8a82058..c181909 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -17,6 +17,7 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
subdirs-y += loaders
+subdirs-$(CONFIG_PLATFORM_USES_FSP) += fsp
bootblock-y += cbfs.c
ifneq ($(CONFIG_HAVE_ARCH_MEMSET),y)
diff --git a/src/lib/fsp/Kconfig b/src/lib/fsp/Kconfig
new file mode 100644
index 0000000..82021a9
--- /dev/null
+++ b/src/lib/fsp/Kconfig
@@ -0,0 +1,144 @@
+##
+## 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"
+ default 0xfffc0000 if SOC_INTEL_FSP_BAYTRAIL
+ 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 ENABLE_FAST_BOOT
+ bool "Enable Fast Boot"
+ default n
+ 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 ENABLE_MRC_CACHE
+ bool
+ default ENABLE_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 BIOS ROM and nothing else should be
+ included in CBFS in any sector that the Fastboot cache data is in.
+
+config OVERRIDE_CACHE_CACHE_LOC
+ bool
+ help
+ Selected by the platform to set a new default location for the
+ MRC/Fastboot cache.
+
+config MRC_CACHE_LOC_OVERRIDE
+ hex
+ help
+ Sets the override CBFS location of the MRC/Fastboot cache.
+
+config MRC_CACHE_LOC
+ hex "Fastboot 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 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
+
+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/lib/fsp/Makefile.inc b/src/lib/fsp/Makefile.inc
new file mode 100644
index 0000000..ff0dcf5
--- /dev/null
+++ b/src/lib/fsp/Makefile.inc
@@ -0,0 +1,49 @@
+#
+# 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/lib/fsp
+
+ifeq ($(CONFIG_USE_GENERIC_FSP_CAR_INC),y)
+cpu_incs += $(src)/lib/fsp/cache_as_ram.inc
+endif
+
+ifneq ($(CONFIG_HAVE_FSP_BIN),)
+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/lib/fsp/cache_as_ram.inc b/src/lib/fsp/cache_as_ram.inc
new file mode 100644
index 0000000..32c1a61
--- /dev/null
+++ b/src/lib/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_IO_POST
+# 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 /* delay between post codes on FSP 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/lib/fsp/fastboot_cache.c b/src/lib/fsp/fastboot_cache.c
new file mode 100644
index 0000000..c1666a4
--- /dev/null
+++ b/src/lib/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 Fastboot 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/lib/fsp/fsp_util.c b/src/lib/fsp/fsp_util.c
new file mode 100644
index 0000000..b2a21aa
--- /dev/null
+++ b/src/lib/fsp/fsp_util.c
@@ -0,0 +1,433 @@
+/*
+ * 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;
+
+ #if IS_ENABLED(CONFIG_COLLECT_TIMESTAMPS)
+ timestamp_add_now(Phase == EnumInitPhaseReadyToBoot ?
+ TS_FSP_BEFORE_FINALIZE : TS_FSP_BEFORE_ENUMERATE);
+ #endif
+
+ Status = NotifyPhaseProc (&NotifyPhaseParams);
+
+ #if IS_ENABLED(CONFIG_COLLECT_TIMESTAMPS)
+ timestamp_add_now(Phase == EnumInitPhaseReadyToBoot ?
+ TS_FSP_AFTER_FINALIZE : TS_FSP_AFTER_ENUMERATE);
+ #endif
+
+ 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/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) {
+ printk(BIOS_WARNING, "CBMEM was not available to save the fastboot 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_FAST_BOOT */
+
+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/Fastboot 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/lib/fsp/fsp_util.h b/src/lib/fsp/fsp_util.h
new file mode 100644
index 0000000..eaf2d37
--- /dev/null
+++ b/src/lib/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 */
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 0634168471564b3dd3c8b531a82ea4ee03800e02
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 | 22 +-
src/cpu/intel/fsp_model_206ax/Makefile.inc | 2 -
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 | 28 +-
src/northbridge/intel/fsp_sandybridge/fsp/Kconfig | 31 ++
.../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, 424 insertions(+), 1181 deletions(-)
diff --git a/src/cpu/intel/fsp_model_206ax/Kconfig b/src/cpu/intel/fsp_model_206ax/Kconfig
index 6a008bf..7fbb870 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 SMP
select SSE2
select UDELAY_LAPIC
@@ -67,26 +68,5 @@ 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 1ea9c2a..a491308 100644
--- a/src/cpu/intel/fsp_model_206ax/Makefile.inc
+++ b/src/cpu/intel/fsp_model_206ax/Makefile.inc
@@ -7,6 +7,4 @@ 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 := $(CC) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
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..2bb5c10 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 "lib/fsp/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..1fcb5a3 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,21 @@
# 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
+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..ce1139c
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig
@@ -0,0 +1,31 @@
+##
+## 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.
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..6305158
--- /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 <lib/fsp/fsp_util.h>
+#include "../chip.h"
+#include <reset.h>
+
+#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;
+#if IS_ENABLED(CONFIG_ENABLE_FAST_BOOT)
+ UpdData->FastBootEnable = TRUE;
+#else
+ UpdData->FastBootEnable = FALSE;
+#endif
+}
+#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_FAST_BOOT)
+ TRUE, /* Fast Boot */
+#else
+ FALSE, /* Fast Boot */
+#endif /* CONFIG_ENABLE_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_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..065cd32 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 "lib/fsp/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_ */
the following patch was just integrated into master:
commit c38f3ae0dee4c413fc931bd1c294faeada807665
Author: Patrick Georgi <patrick(a)georgi-clan.de>
Date: Sat Apr 26 15:29:10 2014 +0200
build: allow building crossgcc when .config exists
Under some circumstances the coreboot toolchain test prevented
building crossgcc, which is counter-productive: If a .config file
exists but no suitable .xcompile.
Don't assume anything about the tree when building crossgcc or
crosstools targets.
Change-Id: I4d6e7a88908dc967342daf30df0fcbcc269ae63d
Signed-off-by: Patrick Georgi <patrick(a)georgi-clan.de>
Reviewed-on: http://review.coreboot.org/5584
Tested-by: build bot (Jenkins)
Reviewed-by: Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
Reviewed-by: Martin Roth <martin.roth(a)se-eng.com>
See http://review.coreboot.org/5584 for details.
-gerrit
the following patch was just integrated into master:
commit 88ca81a6d41f8f0b3491ce9f4b1ac553ed093ddf
Author: Furquan Shaikh <furquan(a)google.com>
Date: Tue Apr 22 16:33:22 2014 -0700
Move redundant Makefile rules from arch to top level.
Remove all the common Makefile rules like coreboot.pre, coreboot.pre1 and others
from arch level Makefile.inc to top level Makefile.inc.
Also, organize Makefile.inc at arch level into per-stage rules and variables.
Change-Id: I7dc5b2d31c959b55bb92d9c7811427c4dada1db5
Signed-off-by: Furquan Shaikh <furquan(a)google.com>
Reviewed-on: http://review.coreboot.org/5571
Tested-by: build bot (Jenkins)
Reviewed-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
See http://review.coreboot.org/5571 for details.
-gerrit
the following patch was just integrated into master:
commit fd33781fbf709c714b9287d69dbb63a09fad097e
Author: Furquan Shaikh <furquan(a)google.com>
Date: Tue Apr 22 15:16:54 2014 -0700
Move ARCH_* from board/Kconfig to cpu or soc Kconfig.
CONFIG_ARCH is a property of the cpu or soc rather than a property of the
board. Hence, move ARCH_* from every single board to respective cpu or soc
Kconfigs. Also update abuild to ignore ARCH_ from mainboards.
Change-Id: I6ec1206de5a20601c32d001a384a47f46e6ce479
Signed-off-by: Furquan Shaikh <furquan(a)google.com>
Reviewed-on: http://review.coreboot.org/5570
Tested-by: build bot (Jenkins)
Reviewed-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
See http://review.coreboot.org/5570 for details.
-gerrit
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 958f846c04b02138fd1e60160b7f20da0931aa19
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/include/timestamp.h | 4 +
src/lib/Makefile.inc | 1 +
src/lib/fsp/Kconfig | 144 ++++++++++++++
src/lib/fsp/Makefile.inc | 47 +++++
src/lib/fsp/cache_as_ram.inc | 169 +++++++++++++++++
src/lib/fsp/fastboot_cache.c | 253 +++++++++++++++++++++++++
src/lib/fsp/fsp_util.c | 433 +++++++++++++++++++++++++++++++++++++++++++
src/lib/fsp/fsp_util.h | 95 ++++++++++
10 files changed, 1154 insertions(+)
diff --git a/src/Kconfig b/src/Kconfig
index cc80b43..a42cc26 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -275,6 +275,7 @@ comment "Embedded Controllers"
source src/ec/Kconfig
comment "SoC"
source src/soc/Kconfig
+source src/lib/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/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,
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 8a82058..c181909 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -17,6 +17,7 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
subdirs-y += loaders
+subdirs-$(CONFIG_PLATFORM_USES_FSP) += fsp
bootblock-y += cbfs.c
ifneq ($(CONFIG_HAVE_ARCH_MEMSET),y)
diff --git a/src/lib/fsp/Kconfig b/src/lib/fsp/Kconfig
new file mode 100644
index 0000000..82021a9
--- /dev/null
+++ b/src/lib/fsp/Kconfig
@@ -0,0 +1,144 @@
+##
+## 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"
+ default 0xfffc0000 if SOC_INTEL_FSP_BAYTRAIL
+ 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 ENABLE_FAST_BOOT
+ bool "Enable Fast Boot"
+ default n
+ 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 ENABLE_MRC_CACHE
+ bool
+ default ENABLE_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 BIOS ROM and nothing else should be
+ included in CBFS in any sector that the Fastboot cache data is in.
+
+config OVERRIDE_CACHE_CACHE_LOC
+ bool
+ help
+ Selected by the platform to set a new default location for the
+ MRC/Fastboot cache.
+
+config MRC_CACHE_LOC_OVERRIDE
+ hex
+ help
+ Sets the override CBFS location of the MRC/Fastboot cache.
+
+config MRC_CACHE_LOC
+ hex "Fastboot 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 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
+
+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/lib/fsp/Makefile.inc b/src/lib/fsp/Makefile.inc
new file mode 100644
index 0000000..25387f3
--- /dev/null
+++ b/src/lib/fsp/Makefile.inc
@@ -0,0 +1,47 @@
+#
+# 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/lib/fsp
+
+ifeq ($(CONFIG_USE_GENERIC_FSP_CAR_INC),y)
+cpu_incs += $(src)/lib/fsp/cache_as_ram.inc
+endif
+
+cbfs-files-y += fsp.bin
+fsp.bin-file := $(call strip_quotes,$(CONFIG_FSP_FILE))
+fsp.bin-position := $(CONFIG_FSP_LOC)
+fsp.bin-type := 0xab
+
+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/lib/fsp/cache_as_ram.inc b/src/lib/fsp/cache_as_ram.inc
new file mode 100644
index 0000000..32c1a61
--- /dev/null
+++ b/src/lib/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_IO_POST
+# 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 /* delay between post codes on FSP 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/lib/fsp/fastboot_cache.c b/src/lib/fsp/fastboot_cache.c
new file mode 100644
index 0000000..c1666a4
--- /dev/null
+++ b/src/lib/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 Fastboot 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/lib/fsp/fsp_util.c b/src/lib/fsp/fsp_util.c
new file mode 100644
index 0000000..b2a21aa
--- /dev/null
+++ b/src/lib/fsp/fsp_util.c
@@ -0,0 +1,433 @@
+/*
+ * 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;
+
+ #if IS_ENABLED(CONFIG_COLLECT_TIMESTAMPS)
+ timestamp_add_now(Phase == EnumInitPhaseReadyToBoot ?
+ TS_FSP_BEFORE_FINALIZE : TS_FSP_BEFORE_ENUMERATE);
+ #endif
+
+ Status = NotifyPhaseProc (&NotifyPhaseParams);
+
+ #if IS_ENABLED(CONFIG_COLLECT_TIMESTAMPS)
+ timestamp_add_now(Phase == EnumInitPhaseReadyToBoot ?
+ TS_FSP_AFTER_FINALIZE : TS_FSP_AFTER_ENUMERATE);
+ #endif
+
+ 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/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) {
+ printk(BIOS_WARNING, "CBMEM was not available to save the fastboot 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_FAST_BOOT */
+
+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/Fastboot 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/lib/fsp/fsp_util.h b/src/lib/fsp/fsp_util.h
new file mode 100644
index 0000000..eaf2d37
--- /dev/null
+++ b/src/lib/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 */
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 7bda82f24dad9dee24753c285eabacace900983a
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 | 22 +-
src/cpu/intel/fsp_model_206ax/Makefile.inc | 2 -
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 | 28 +-
src/northbridge/intel/fsp_sandybridge/fsp/Kconfig | 31 ++
.../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, 424 insertions(+), 1181 deletions(-)
diff --git a/src/cpu/intel/fsp_model_206ax/Kconfig b/src/cpu/intel/fsp_model_206ax/Kconfig
index 6a008bf..7fbb870 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 SMP
select SSE2
select UDELAY_LAPIC
@@ -67,26 +68,5 @@ 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 1ea9c2a..a491308 100644
--- a/src/cpu/intel/fsp_model_206ax/Makefile.inc
+++ b/src/cpu/intel/fsp_model_206ax/Makefile.inc
@@ -7,6 +7,4 @@ 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 := $(CC) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
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..2bb5c10 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 "lib/fsp/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..1fcb5a3 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,21 @@
# 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
+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..ce1139c
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig
@@ -0,0 +1,31 @@
+##
+## 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.
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..6305158
--- /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 <lib/fsp/fsp_util.h>
+#include "../chip.h"
+#include <reset.h>
+
+#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;
+#if IS_ENABLED(CONFIG_ENABLE_FAST_BOOT)
+ UpdData->FastBootEnable = TRUE;
+#else
+ UpdData->FastBootEnable = FALSE;
+#endif
+}
+#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_FAST_BOOT)
+ TRUE, /* Fast Boot */
+#else
+ FALSE, /* Fast Boot */
+#endif /* CONFIG_ENABLE_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_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..065cd32 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 "lib/fsp/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_ */
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 06c0d542591ce36fd2f85336741f0da70c500500
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 | 22 +-
src/cpu/intel/fsp_model_206ax/Makefile.inc | 2 -
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 | 28 +-
src/northbridge/intel/fsp_sandybridge/fsp/Kconfig | 31 ++
.../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, 424 insertions(+), 1181 deletions(-)
diff --git a/src/cpu/intel/fsp_model_206ax/Kconfig b/src/cpu/intel/fsp_model_206ax/Kconfig
index 6a008bf..7fbb870 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 SMP
select SSE2
select UDELAY_LAPIC
@@ -67,26 +68,5 @@ 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 1ea9c2a..a491308 100644
--- a/src/cpu/intel/fsp_model_206ax/Makefile.inc
+++ b/src/cpu/intel/fsp_model_206ax/Makefile.inc
@@ -7,6 +7,4 @@ 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 := $(CC) -I$(CONFIG_MICROCODE_INCLUDE_PATH)
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..2bb5c10 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 "lib/fsp/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..1fcb5a3 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,21 @@
# 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
+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..ce1139c
--- /dev/null
+++ b/src/northbridge/intel/fsp_sandybridge/fsp/Kconfig
@@ -0,0 +1,31 @@
+##
+## 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.
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..6305158
--- /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 <lib/fsp/fsp_util.h>
+#include "../chip.h"
+#include <reset.h>
+
+#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;
+#if IS_ENABLED(CONFIG_ENABLE_FAST_BOOT)
+ UpdData->FastBootEnable = TRUE;
+#else
+ UpdData->FastBootEnable = FALSE;
+#endif
+}
+#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_FAST_BOOT)
+ TRUE, /* Fast Boot */
+#else
+ FALSE, /* Fast Boot */
+#endif /* CONFIG_ENABLE_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_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..065cd32 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 "lib/fsp/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_ */
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 9896e534aca8217eaace581e47a6b2401e50926c
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/lib/Makefile.inc | 1 +
src/lib/fsp/Kconfig | 144 ++++++++++++++
src/lib/fsp/cache_as_ram.inc | 169 +++++++++++++++++
src/lib/fsp/fastboot_cache.c | 253 +++++++++++++++++++++++++
src/lib/fsp/fsp_util.c | 433 +++++++++++++++++++++++++++++++++++++++++++
src/lib/fsp/fsp_util.h | 95 ++++++++++
8 files changed, 1103 insertions(+)
diff --git a/src/Kconfig b/src/Kconfig
index cc80b43..a42cc26 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -275,6 +275,7 @@ comment "Embedded Controllers"
source src/ec/Kconfig
comment "SoC"
source src/soc/Kconfig
+source src/lib/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/lib/Makefile.inc b/src/lib/Makefile.inc
index 8a82058..c181909 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -17,6 +17,7 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
subdirs-y += loaders
+subdirs-$(CONFIG_PLATFORM_USES_FSP) += fsp
bootblock-y += cbfs.c
ifneq ($(CONFIG_HAVE_ARCH_MEMSET),y)
diff --git a/src/lib/fsp/Kconfig b/src/lib/fsp/Kconfig
new file mode 100644
index 0000000..82021a9
--- /dev/null
+++ b/src/lib/fsp/Kconfig
@@ -0,0 +1,144 @@
+##
+## 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"
+ default 0xfffc0000 if SOC_INTEL_FSP_BAYTRAIL
+ 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 ENABLE_FAST_BOOT
+ bool "Enable Fast Boot"
+ default n
+ 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 ENABLE_MRC_CACHE
+ bool
+ default ENABLE_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 BIOS ROM and nothing else should be
+ included in CBFS in any sector that the Fastboot cache data is in.
+
+config OVERRIDE_CACHE_CACHE_LOC
+ bool
+ help
+ Selected by the platform to set a new default location for the
+ MRC/Fastboot cache.
+
+config MRC_CACHE_LOC_OVERRIDE
+ hex
+ help
+ Sets the override CBFS location of the MRC/Fastboot cache.
+
+config MRC_CACHE_LOC
+ hex "Fastboot 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 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
+
+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/lib/fsp/cache_as_ram.inc b/src/lib/fsp/cache_as_ram.inc
new file mode 100644
index 0000000..32c1a61
--- /dev/null
+++ b/src/lib/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_IO_POST
+# 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 /* delay between post codes on FSP 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/lib/fsp/fastboot_cache.c b/src/lib/fsp/fastboot_cache.c
new file mode 100644
index 0000000..c1666a4
--- /dev/null
+++ b/src/lib/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 Fastboot 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/lib/fsp/fsp_util.c b/src/lib/fsp/fsp_util.c
new file mode 100644
index 0000000..b2a21aa
--- /dev/null
+++ b/src/lib/fsp/fsp_util.c
@@ -0,0 +1,433 @@
+/*
+ * 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;
+
+ #if IS_ENABLED(CONFIG_COLLECT_TIMESTAMPS)
+ timestamp_add_now(Phase == EnumInitPhaseReadyToBoot ?
+ TS_FSP_BEFORE_FINALIZE : TS_FSP_BEFORE_ENUMERATE);
+ #endif
+
+ Status = NotifyPhaseProc (&NotifyPhaseParams);
+
+ #if IS_ENABLED(CONFIG_COLLECT_TIMESTAMPS)
+ timestamp_add_now(Phase == EnumInitPhaseReadyToBoot ?
+ TS_FSP_AFTER_FINALIZE : TS_FSP_AFTER_ENUMERATE);
+ #endif
+
+ 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/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) {
+ printk(BIOS_WARNING, "CBMEM was not available to save the fastboot 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_FAST_BOOT */
+
+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/Fastboot 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/lib/fsp/fsp_util.h b/src/lib/fsp/fsp_util.h
new file mode 100644
index 0000000..eaf2d37
--- /dev/null
+++ b/src/lib/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 */