[coreboot-gerrit] Patch set updated for coreboot: b59a132 coreboot: config to cache ramstage outside CBMEM

Aaron Durbin (adurbin@google.com) gerrit at coreboot.org
Tue Jan 28 05:23:35 CET 2014


Aaron Durbin (adurbin at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4876

-gerrit

commit b59a132e097939df1700d747492f2a21aee8cbaf
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Thu Oct 10 20:37:04 2013 -0500

    coreboot: config to cache ramstage outside CBMEM
    
    Haswell was the original chipset to store the cache
    in another area besides CBMEM. However, it was specific
    to the implementation. Instead, provide a generic way
    to obtain the location of the ramstage cache. This option
    is selected using the CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM
    Kconfig option.
    
    BUG=chrome-os-partner:23249
    BRANCH=None
    TEST=Built and booted with baytrail support. Also built for
         falco successfully.
    CQ-DEPEND=CL:172643
    CQ-DEPEND=CL:*146397
    CQ-DEPEND=CL:*146398
    CQ-DEPEND=CL:*146435
    CQ-DEPEND=CL:*146445
    
    Change-Id: I70d0940f7a8f73640c92a75fd22588c2c234241b
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
    Reviewed-on: https://chromium-review.googlesource.com/172602
    Reviewed-by: Stefan Reinauer <reinauer at google.com>
---
 src/Kconfig                      |   8 +++
 src/cpu/intel/haswell/haswell.h  |  16 -----
 src/cpu/intel/haswell/romstage.c |  66 +++---------------
 src/include/ramstage_cache.h     |  49 +++++++++++++
 src/lib/Makefile.inc             |   2 +
 src/lib/cbfs.c                   |  47 -------------
 src/lib/ramstage_cache.c         | 144 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 213 insertions(+), 119 deletions(-)

diff --git a/src/Kconfig b/src/Kconfig
index c6696af..7492e22 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -431,6 +431,14 @@ config RELOCATABLE_RAMSTAGE
 	 wake. When selecting this option the romstage is responsible for
 	 determing a stack location to use for loading the ramstage.
 
+config CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM
+	depends on RELOCATABLE_RAMSTAGE
+	bool "Cache the relocated ramstage outside of cbmem."
+	default n
+	help
+	 The relocated ramstage is saved in an area specified by the
+	 by the board and/or chipset.
+
 config HAVE_ACPI_TABLES
 	bool
 	help
diff --git a/src/cpu/intel/haswell/haswell.h b/src/cpu/intel/haswell/haswell.h
index dcd5dc7..190abc6 100644
--- a/src/cpu/intel/haswell/haswell.h
+++ b/src/cpu/intel/haswell/haswell.h
@@ -215,22 +215,6 @@ void release_aps_for_smm_relocation(int do_parallel_relocation);
 extern int ht_disabled;
 #endif
 
-/* This structure is saved along with the relocated ramstage program in SMM
- * space. It is used to protect the integrity of the ramstage program on S3
- * resume by saving a copy of the relocated ramstage in SMM space with the
- * assumption that the SMM region cannot be altered from the OS. The magic
- * value just serves as a quick sanity check. */
-
-#define RAMSTAGE_CACHE_MAGIC 0xf3c3a02a
-
-struct ramstage_cache {
-	uint32_t magic;
-	uint32_t entry_point;
-	uint32_t load_address;
-	uint32_t size;
-	char program[0];
-} __attribute__((packed));
-
 /* CPU identification */
 int haswell_family_model(void);
 int haswell_stepping(void);
diff --git a/src/cpu/intel/haswell/romstage.c b/src/cpu/intel/haswell/romstage.c
index 40a396d..53c5987 100644
--- a/src/cpu/intel/haswell/romstage.c
+++ b/src/cpu/intel/haswell/romstage.c
@@ -33,6 +33,7 @@
 #include <device/pci_def.h>
 #include <cpu/x86/lapic.h>
 #include <cbfs.h>
+#include <ramstage_cache.h>
 #include <romstage_handoff.h>
 #include <reset.h>
 #if CONFIG_CHROMEOS
@@ -318,67 +319,20 @@ void romstage_after_car(void)
 
 
 #if CONFIG_RELOCATABLE_RAMSTAGE
-void cache_loaded_ramstage(struct romstage_handoff *handoff,
-                           const struct cbmem_entry *ramstage,
-                           void *entry_point)
-{
-	struct ramstage_cache *cache;
-	uint32_t total_size;
-	uint32_t ramstage_size;
-	void *ramstage_base;
-
-	ramstage_size = cbmem_entry_size(ramstage);
-	ramstage_base = cbmem_entry_start(ramstage);
+#include <ramstage_cache.h>
 
+struct ramstage_cache *ramstage_cache_location(long *size)
+{
 	/* The ramstage cache lives in the TSEG region at RESERVED_SMM_OFFSET.
 	 * The top of ram is defined to be the TSEG base address. */
-	cache = (void *)(get_top_of_ram() + RESERVED_SMM_OFFSET);
-	total_size = sizeof(*cache) + ramstage_size;
-	if (total_size > RESERVED_SMM_SIZE) {
-		printk(BIOS_DEBUG, "0x%08x > RESERVED_SMM_SIZE (0x%08x)\n",
-		       total_size, RESERVED_SMM_SIZE);
-		/* Nuke whatever may be there now just in case. */
-		cache->magic = ~RAMSTAGE_CACHE_MAGIC;
-		return;
-	}
-
-	cache->magic = RAMSTAGE_CACHE_MAGIC;
-	cache->entry_point = (uint32_t)entry_point;
-	cache->load_address = (uint32_t)ramstage_base;
-	cache->size = ramstage_size;
-
-	printk(BIOS_DEBUG, "Saving ramstage to SMM space cache.\n");
-
-	/* Copy over the program. */
-	memcpy(&cache->program[0], ramstage_base, ramstage_size);
-
-	if (handoff == NULL)
-		return;
-
-	handoff->ramstage_entry_point = (uint32_t)entry_point;
+	*size = RESERVED_SMM_SIZE;
+	return (void *)(get_top_of_ram() + RESERVED_SMM_OFFSET);
 }
 
-void *load_cached_ramstage(struct romstage_handoff *handoff,
-                           const struct cbmem_entry *ramstage)
+void ramstage_cache_invalid(struct ramstage_cache *cache)
 {
-	struct ramstage_cache *cache;
-
-	/* The ramstage cache lives in the TSEG region at RESERVED_SMM_OFFSET.
-	 * The top of ram is defined to be the TSEG base address. */
-	cache = (void *)(get_top_of_ram() + RESERVED_SMM_OFFSET);
-
-	if (cache->magic != RAMSTAGE_CACHE_MAGIC) {
-		printk(BIOS_DEBUG, "Invalid ramstage cache found.\n");
-		#if CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE
-		reset_system();
-		#endif
-		return NULL;
-	}
-
-	printk(BIOS_DEBUG, "Loading ramstage from SMM space cache.\n");
-
-	memcpy((void *)cache->load_address, &cache->program[0], cache->size);
-
-	return (void *)cache->entry_point;
+#if CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE
+	reset_system();
+#endif
 }
 #endif
diff --git a/src/include/ramstage_cache.h b/src/include/ramstage_cache.h
new file mode 100644
index 0000000..5b0597a
--- /dev/null
+++ b/src/include/ramstage_cache.h
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _RAMSTAGE_CACHE_
+#define _RAMSTAGE_CACHE_
+
+#if !defined(__PRE_RAM__)
+#error "ramstage_cache only used in romstage for loading ramstage."
+#endif
+
+/* This structure is saved along with the relocated ramstage program when
+ * CONFIG_RELOCATED_RAMSTAGE is employed.  For x86, it can used to protect
+ * the integrity of the ramstage program on S3 resume by saving a copy of
+ * the relocated ramstage in SMM space with the assumption that the SMM region
+ * cannot be altered from the OS. The magic value just serves as a quick sanity
+ * check. */
+
+#define RAMSTAGE_CACHE_MAGIC 0xf3c3a02a
+
+struct ramstage_cache {
+	uint32_t magic;
+	uint32_t entry_point;
+	uint32_t load_address;
+	uint32_t size;
+	char program[0];
+} __attribute__((packed));
+
+/* Chipset/Board function for obtaining cache location and size. */
+struct ramstage_cache *ramstage_cache_location(long *size);
+/* Chipset/Board function called when cache is invalid on resume. */
+void ramstage_cache_invalid(struct ramstage_cache *cache);
+
+#endif  /* _RAMSTAGE_CACHE_ */
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 37c7dea..18b30ef 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -119,6 +119,8 @@ romstage-y += hexdump.c
 
 ramstage-$(CONFIG_CONSOLE_NE2K) += ne2k.c
 
+romstage-$(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) += ramstage_cache.c
+
 ifneq ($(CONFIG_HAVE_ARCH_MEMSET),y)
 smm-y += memset.c
 endif
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index e38f856..396fe33 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -127,53 +127,6 @@ void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor,
 
 #include <rmodule.h>
 #include <romstage_handoff.h>
-/* When CONFIG_RELOCATABLE_RAMSTAGE is enabled and this file is being compiled
- * for the romstage, the rmodule loader is used.  */
-void __attribute__((weak))
-cache_loaded_ramstage(struct romstage_handoff *handoff,
-                      const struct cbmem_entry *ramstage, void *entry_point)
-{
-	uint32_t ramstage_size;
-	const struct cbmem_entry *entry;
-
-	if (handoff == NULL)
-		return;
-
-	ramstage_size = cbmem_entry_size(ramstage);
-	/* cbmem_entry_add() does a find() before add(). */
-	entry = cbmem_entry_add(CBMEM_ID_RAMSTAGE_CACHE, ramstage_size);
-
-	if (entry == NULL)
-		return;
-
-	/* Keep track of the entry point in the handoff structure. */
-	handoff->ramstage_entry_point = (uint32_t)entry_point;
-
-	memcpy(cbmem_entry_start(entry), cbmem_entry_start(ramstage),
-	       ramstage_size);
-}
-
-void * __attribute__((weak))
-load_cached_ramstage(struct romstage_handoff *handoff,
-                     const struct cbmem_entry *ramstage)
-{
-	const struct cbmem_entry *entry_cache;
-
-	if (handoff == NULL)
-		return NULL;
-
-	entry_cache = cbmem_entry_find(CBMEM_ID_RAMSTAGE_CACHE);
-
-	if (entry_cache == NULL)
-		return NULL;
-
-	/* Load the cached ramstage copy into the to-be-run region. */
-	memcpy(cbmem_entry_start(ramstage), cbmem_entry_start(entry_cache),
-	       cbmem_entry_size(ramstage));
-
-	return (void *)handoff->ramstage_entry_point;
-}
-
 static void *load_stage_from_cbfs(struct cbfs_media *media, const char *name,
                                   struct romstage_handoff *handoff)
 {
diff --git a/src/lib/ramstage_cache.c b/src/lib/ramstage_cache.c
new file mode 100644
index 0000000..a1a4804
--- /dev/null
+++ b/src/lib/ramstage_cache.c
@@ -0,0 +1,144 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <cbfs.h>
+#include <console/console.h>
+#include <ramstage_cache.h>
+#include <romstage_handoff.h>
+
+#if CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM
+
+void cache_loaded_ramstage(struct romstage_handoff *handoff,
+                           const struct cbmem_entry *ramstage,
+                           void *entry_point)
+{
+	struct ramstage_cache *cache;
+	uint32_t total_size;
+	uint32_t ramstage_size;
+	void *ramstage_base;
+	long cache_size = 0;
+
+	ramstage_size = cbmem_entry_size(ramstage);
+	ramstage_base = cbmem_entry_start(ramstage);
+
+	cache = ramstage_cache_location(&cache_size);
+
+	if (cache == NULL) {
+		printk(BIOS_DEBUG, "No ramstage cache location provided.\n");
+		return;
+	}
+
+	total_size = sizeof(*cache) + ramstage_size;
+	if (total_size > cache_size) {
+		printk(BIOS_DEBUG, "cache size too small: 0x%08x > 0x%08lx\n",
+		       total_size, cache_size);
+		/* Nuke whatever may be there now just in case. */
+		cache->magic = ~RAMSTAGE_CACHE_MAGIC;
+		return;
+	}
+
+	cache->magic = RAMSTAGE_CACHE_MAGIC;
+	cache->entry_point = (uint32_t)entry_point;
+	cache->load_address = (uint32_t)ramstage_base;
+	cache->size = ramstage_size;
+
+	printk(BIOS_DEBUG, "Saving ramstage to %p.\n", cache);
+
+	/* Copy over the program. */
+	memcpy(&cache->program[0], ramstage_base, ramstage_size);
+
+	if (handoff == NULL)
+		return;
+
+	handoff->ramstage_entry_point = (uint32_t)entry_point;
+}
+
+void *load_cached_ramstage(struct romstage_handoff *handoff,
+                           const struct cbmem_entry *ramstage)
+{
+	struct ramstage_cache *cache;
+	long size = 0;
+
+	cache = ramstage_cache_location(&size);
+
+	if (cache == NULL || cache->magic != RAMSTAGE_CACHE_MAGIC) {
+		printk(BIOS_DEBUG, "Invalid ramstage cache found.\n");
+		ramstage_cache_invalid(cache);
+		return NULL;
+	}
+
+	printk(BIOS_DEBUG, "Loading ramstage from %p.\n", cache);
+
+	memcpy((void *)cache->load_address, &cache->program[0], cache->size);
+
+	return (void *)cache->entry_point;
+}
+
+#else
+
+/* Cache relocated ramstage in CBMEM. */
+
+void __attribute__((weak))
+cache_loaded_ramstage(struct romstage_handoff *handoff,
+                      const struct cbmem_entry *ramstage, void *entry_point)
+{
+	uint32_t ramstage_size;
+	const struct cbmem_entry *entry;
+
+	if (handoff == NULL)
+		return;
+
+	ramstage_size = cbmem_entry_size(ramstage);
+	/* cbmem_entry_add() does a find() before add(). */
+	entry = cbmem_entry_add(CBMEM_ID_RAMSTAGE_CACHE, ramstage_size);
+
+	if (entry == NULL)
+		return;
+
+	/* Keep track of the entry point in the handoff structure. */
+	handoff->ramstage_entry_point = (uint32_t)entry_point;
+
+	memcpy(cbmem_entry_start(entry), cbmem_entry_start(ramstage),
+	       ramstage_size);
+}
+
+void * __attribute__((weak))
+load_cached_ramstage(struct romstage_handoff *handoff,
+                     const struct cbmem_entry *ramstage)
+{
+	const struct cbmem_entry *entry_cache;
+
+	if (handoff == NULL)
+		return NULL;
+
+	entry_cache = cbmem_entry_find(CBMEM_ID_RAMSTAGE_CACHE);
+
+	if (entry_cache == NULL)
+		return NULL;
+
+	/* Load the cached ramstage copy into the to-be-run region. */
+	memcpy(cbmem_entry_start(ramstage), cbmem_entry_start(entry_cache),
+	       cbmem_entry_size(ramstage));
+
+	return (void *)handoff->ramstage_entry_point;
+}
+
+#endif



More information about the coreboot-gerrit mailing list