Aaron Durbin (adurbin@google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8625
-gerrit
commit 344945b2cfd2ced91ae1b70ddc8638d91fa7b715 Author: Aaron Durbin adurbin@chromium.org Date: Fri Mar 6 23:17:33 2015 -0600
coreboot: common stage cache
Many chipsets were using a stage cache for reference code or when using a relocatable ramstage. Provide a common API for the chipsets to use while reducing code duplication.
Change-Id: Ia36efa169fe6bd8a3dbe07bf57a9729c7edbdd46 Signed-off-by: Aaron Durbin adurbin@chromium.org --- src/cpu/intel/haswell/romstage.c | 12 +-- src/include/cbfs.h | 35 +++----- src/include/cbmem.h | 2 + src/include/ramstage_cache.h | 53 ------------ src/include/romstage_handoff.h | 4 - src/include/stage_cache.h | 48 +++++++++++ src/lib/Makefile.inc | 3 + src/lib/dynamic_cbmem.c | 50 +++++++++++ src/lib/ext_stage_cache.c | 110 ++++++++++++++++++++++++ src/lib/loaders/load_and_run_ramstage.c | 23 ++---- src/lib/ramstage_cache.c | 124 +++------------------------- src/soc/intel/baytrail/refcode.c | 59 ++----------- src/soc/intel/baytrail/romstage/raminit.c | 17 ++-- src/soc/intel/baytrail/romstage/romstage.c | 6 +- src/soc/intel/baytrail/stage_cache.c | 6 +- src/soc/intel/broadwell/refcode.c | 59 ++----------- src/soc/intel/broadwell/romstage/romstage.c | 5 +- src/soc/intel/broadwell/stage_cache.c | 6 +- 18 files changed, 287 insertions(+), 335 deletions(-)
diff --git a/src/cpu/intel/haswell/romstage.c b/src/cpu/intel/haswell/romstage.c index 50150cf..d000272 100644 --- a/src/cpu/intel/haswell/romstage.c +++ b/src/cpu/intel/haswell/romstage.c @@ -19,6 +19,7 @@
#include <stdint.h> #include <string.h> +#include <cbfs.h> #include <cbmem.h> #include <console/console.h> #include <arch/cpu.h> @@ -33,9 +34,9 @@ #include <device/pci_def.h> #include <cpu/x86/lapic.h> #include <cbfs.h> -#include <ramstage_cache.h> #include <romstage_handoff.h> #include <reset.h> +#include <stage_cache.h> #include <vendorcode/google/chromeos/chromeos.h> #if CONFIG_EC_GOOGLE_CHROMEEC #include <ec/google/chromeec/ec.h> @@ -307,18 +308,17 @@ void romstage_after_car(void) }
-#if CONFIG_RELOCATABLE_RAMSTAGE -#include <ramstage_cache.h> +#if IS_ENABLED(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM)
-struct ramstage_cache *ramstage_cache_location(long *size) +void stage_cache_external_region(void **base, size_t *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. */ *size = RESERVED_SMM_SIZE; - return (void *)((uint32_t)cbmem_top() + RESERVED_SMM_OFFSET); + *base = (void *)((uint32_t)cbmem_top() + RESERVED_SMM_OFFSET); }
-void ramstage_cache_invalid(struct ramstage_cache *cache) +void ramstage_cache_invalid(void) { #if CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE reset_system(); diff --git a/src/include/cbfs.h b/src/include/cbfs.h index 5297230..8e74d58 100644 --- a/src/include/cbfs.h +++ b/src/include/cbfs.h @@ -2,7 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2008 Jordan Crouse jordan@cosmicpenguin.net - * Copyright (C) 2013 The Chromium OS Authors. All rights reserved. + * Copyright (C) 2013-2015 Google, Inc. * * This file is dual-licensed. You can choose between: * - The GNU GPL, version 2, as published by the Free Software Foundation @@ -88,30 +88,17 @@ struct cbmem_entry; * relocated ramstage is saved using the cbmem infrastructure. These * functions are only valid during romstage. */
-/* The implementer of cache_loaded_ramstage() may use the romstage_handoff - * structure to store information, but note that the handoff variable can be - * NULL. The ramstage cbmem_entry represents the region occupied by the loaded - * ramstage. */ -void cache_loaded_ramstage(struct romstage_handoff *handoff, - const struct cbmem_entry *ramstage, void *entry_point); -/* Return NULL on error or entry point on success. The ramstage cbmem_entry is - * the region where to load the cached contents to. */ -void * load_cached_ramstage(struct romstage_handoff *handoff, - const struct cbmem_entry *ramstage); +/* Cache the loaded ramstage provided the cbmem_entry for ramstage location + * and the provided entry point. */ +void cache_loaded_ramstage(const struct cbmem_entry *ramstage, void *entry); +/* Return NULL on error or entry point on success. */ +void *load_cached_ramstage(void); +/* Chipset/Board function called when cache is invalid on resume. */ +void ramstage_cache_invalid(void); #else /* CONFIG_RELOCATABLE_RAMSTAGE */ - -static inline void cache_loaded_ramstage(struct romstage_handoff *handoff, - const struct cbmem_entry *ramstage, void *entry_point) -{ -} - -static inline void * -load_cached_ramstage(struct romstage_handoff *handoff, - const struct cbmem_entry *ramstage) -{ - return NULL; -} - +static inline void cache_loaded_ramstage(const struct cbmem_entry *ramstage, + void *entry_point) { } +static inline void *load_cached_ramstage(void) { return NULL; } #endif /* CONFIG_RELOCATABLE_RAMSTAGE */ #endif /* defined(__PRE_RAM__) */
diff --git a/src/include/cbmem.h b/src/include/cbmem.h index a8c96ee..f904683 100644 --- a/src/include/cbmem.h +++ b/src/include/cbmem.h @@ -75,6 +75,8 @@ #define CBMEM_ID_NONE 0x00000000 #define CBMEM_ID_AGESA_RUNTIME 0x41474553 #define CBMEM_ID_HOB_POINTER 0x484f4221 +#define CBMEM_ID_STAGEx_META 0x57a9e000 +#define CBMEM_ID_STAGEx_CACHE 0x57a9e100
#ifndef __ASSEMBLER__ #include <stddef.h> diff --git a/src/include/ramstage_cache.h b/src/include/ramstage_cache.h deleted file mode 100644 index 8d9b095..0000000 --- a/src/include/ramstage_cache.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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_ - -#include <stddef.h> -#include <stdint.h> - -/* 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); - -static inline int ramstage_cache_is_valid(const struct ramstage_cache *c) -{ - return (c != NULL && c->magic == RAMSTAGE_CACHE_MAGIC); -} - -#endif /* _RAMSTAGE_CACHE_ */ diff --git a/src/include/romstage_handoff.h b/src/include/romstage_handoff.h index 307babd..679633d 100644 --- a/src/include/romstage_handoff.h +++ b/src/include/romstage_handoff.h @@ -34,10 +34,6 @@ struct romstage_handoff { * will be re-loaded from cbfs (which can be slower since it lives * in flash). */ uint32_t s3_resume; - /* The ramstage_entry_point is cached in the stag loading path. This - * cached value can only be utilized when the chipset code properly - * fills in the s3_resume field above. */ - uint32_t ramstage_entry_point; };
#if defined(__PRE_RAM__) diff --git a/src/include/stage_cache.h b/src/include/stage_cache.h new file mode 100644 index 0000000..ac40f91 --- /dev/null +++ b/src/include/stage_cache.h @@ -0,0 +1,48 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 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 _STAGE_CACHE_H_ +#define _STAGE_CACHE_H_ + +#include <stddef.h> +#include <stdint.h> + +enum { + STAGE_RAMSTAGE, + STAGE_REFCODE, +}; + +/* Create an empty stage cache. */ +void stage_cache_create_empty(void); +/* Recover existing stage cache. */ +void stage_cache_recover(void); +/* Cache the loaded stage provided according to the parameters. */ +void stage_cache_add(int stage_id, void *base, size_t size, void *entry); +/* Load the cached stage at given location returning the stage entry point. */ +void *stage_cache_load_stage(int stage_id); +/* Fill in parameters for the external stage cache, if utilized. */ +void stage_cache_external_region(void **base, size_t *size); + +/* Metadata associated with each stage. */ +struct stage_cache { + uint64_t load_addr; + uint64_t entry_addr; +}; + +#endif /* _STAGE_CACHE_H_ */ diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index f9bdc0a..d5ba8e4 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -96,6 +96,9 @@ ramstage-$(CONFIG_REG_SCRIPT) += reg_script.c
romstage-$(CONFIG_RELOCATABLE_RAMSTAGE) += ramstage_cache.c
+ramstage-$(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) += ext_stage_cache.c +romstage-$(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) += ext_stage_cache.c + smm-y += cbfs.c cbfs_core.c memcmp.c smm-$(CONFIG_COMPILER_GCC) += gcc.c
diff --git a/src/lib/dynamic_cbmem.c b/src/lib/dynamic_cbmem.c index fa73527..8f7a9cd 100644 --- a/src/lib/dynamic_cbmem.c +++ b/src/lib/dynamic_cbmem.c @@ -22,6 +22,7 @@ #include <console/console.h> #include <cbmem.h> #include <imd.h> +#include <stage_cache.h> #include <string.h> #include <stdlib.h> #include <arch/early_variables.h> @@ -255,3 +256,52 @@ void cbmem_list(void) imd_print_entries(cbmem_get_imd(), lookup, ARRAY_SIZE(lookup)); } #endif /* __PRE_RAM__ */ + +/* Provide empty implementations by default. */ +void __attribute__((weak)) stage_cache_create_empty(void) {} +void __attribute__((weak)) stage_cache_recover(void) {} + +#if !IS_ENABLED(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) +/* Stage cache uses cbmem. */ +void stage_cache_add(int stage_id, void *base, size_t size, void *entry) +{ + struct stage_cache *meta; + void *c; + + meta = cbmem_add(CBMEM_ID_STAGEx_META + stage_id, sizeof(*meta)); + if (meta == NULL) + return; + meta->load_addr = (uintptr_t)base; + meta->entry_addr = (uintptr_t)entry; + + c = cbmem_add(CBMEM_ID_STAGEx_CACHE + stage_id, size); + if (c == NULL) + return; + + memcpy(c, base, size); +} + +void *stage_cache_load_stage(int stage_id) +{ + struct stage_cache *meta; + const struct cbmem_entry *e; + void *c; + size_t size; + + meta = cbmem_find(CBMEM_ID_STAGEx_META + stage_id); + if (meta == NULL) + return NULL; + + e = cbmem_entry_find(CBMEM_ID_STAGEx_CACHE + stage_id); + + if (e == NULL) + return NULL; + + c = cbmem_entry_start(e); + size = cbmem_entry_size(e); + + memcpy((void *)(uintptr_t)meta->load_addr, c, size); + + return (void *)(uintptr_t)meta->entry_addr; +} +#endif /* !IS_ENABLED(CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) */ diff --git a/src/lib/ext_stage_cache.c b/src/lib/ext_stage_cache.c new file mode 100644 index 0000000..65b4327 --- /dev/null +++ b/src/lib/ext_stage_cache.c @@ -0,0 +1,110 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 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 <arch/early_variables.h> +#include <cbmem.h> +#include <imd.h> +#include <stage_cache.h> +#include <string.h> + +static struct imd imd_stage_cache CAR_GLOBAL = { }; + +static inline struct imd *imd_get(void) +{ + return car_get_var_ptr(&imd_stage_cache); +} + +static struct imd *sc_imd_init(void) +{ + struct imd *imd; + void *base; + size_t size; + + imd = imd_get(); + stage_cache_external_region(&base, &size); + imd_handle_init(imd, (void *)(size + (uintptr_t)base)); + + return imd; +} + +void stage_cache_create_empty(void) +{ + imd_create_tiered_empty(sc_imd_init(), 4096, 4096, 1024, 32); +} + +void stage_cache_recover(void) +{ + imd_recover(sc_imd_init()); +} + +void stage_cache_add(int stage_id, void *base, size_t size, void *entry) +{ + struct imd *imd; + const struct imd_entry *e; + struct stage_cache *meta; + void *c; + + imd = imd_get(); + e = imd_entry_add(imd, CBMEM_ID_STAGEx_META + stage_id, sizeof(*meta)); + + if (e == NULL) + return; + + meta = imd_entry_at(imd, e); + + meta->load_addr = (uintptr_t)base; + meta->entry_addr = (uintptr_t)entry; + + e = imd_entry_add(imd, CBMEM_ID_STAGEx_CACHE + stage_id, size); + + if (e == NULL) + return; + + c = imd_entry_at(imd, e); + + memcpy(c, base, size); +} + +void *stage_cache_load_stage(int stage_id) +{ + struct imd *imd; + struct stage_cache *meta; + const struct imd_entry *e; + void *c; + size_t size; + + imd = imd_get(); + e = imd_entry_find(imd, CBMEM_ID_STAGEx_META + stage_id); + if (e == NULL) + return NULL; + + meta = imd_entry_at(imd, e); + + e = imd_entry_find(imd, CBMEM_ID_STAGEx_CACHE + stage_id); + + if (e == NULL) + return NULL; + + c = imd_entry_at(imd, e); + size = imd_entry_size(imd, e); + + memcpy((void *)(uintptr_t)meta->load_addr, c, size); + + return (void *)(uintptr_t)meta->entry_addr; +} diff --git a/src/lib/loaders/load_and_run_ramstage.c b/src/lib/loaders/load_and_run_ramstage.c index 5237e20..0b0b4bf 100644 --- a/src/lib/loaders/load_and_run_ramstage.c +++ b/src/lib/loaders/load_and_run_ramstage.c @@ -39,8 +39,7 @@ static const struct ramstage_loader_ops *loaders[] = { static const char *ramstage_name = CONFIG_CBFS_PREFIX "/ramstage"; static const uint32_t ramstage_id = CBMEM_ID_RAMSTAGE;
-static void -load_ramstage(const struct ramstage_loader_ops *ops, struct romstage_handoff *handoff) +static void load_ramstage(const struct ramstage_loader_ops *ops) { const struct cbmem_entry *cbmem_entry; void *entry_point; @@ -51,7 +50,7 @@ load_ramstage(const struct ramstage_loader_ops *ops, struct romstage_handoff *ha if (entry_point == NULL) return;
- cache_loaded_ramstage(handoff, cbmem_entry, entry_point); + cache_loaded_ramstage(cbmem_entry, entry_point);
timestamp_add_now(TS_END_COPYRAM);
@@ -60,18 +59,9 @@ load_ramstage(const struct ramstage_loader_ops *ops, struct romstage_handoff *ha
static void run_ramstage_from_resume(struct romstage_handoff *handoff) { - void *entry; - const struct cbmem_entry *cbmem_entry; - if (handoff != NULL && handoff->s3_resume) { - cbmem_entry = cbmem_entry_find(ramstage_id); - - /* No place to load ramstage. */ - if (cbmem_entry == NULL) - return; - /* Load the cached ramstage to runtime location. */ - entry = load_cached_ramstage(handoff, cbmem_entry); + void *entry = load_cached_ramstage();
if (entry != NULL) { printk(BIOS_DEBUG, "Jumping to image.\n"); @@ -82,18 +72,15 @@ static void run_ramstage_from_resume(struct romstage_handoff *handoff)
void run_ramstage(void) { - struct romstage_handoff *handoff; const struct ramstage_loader_ops *ops; int i;
- handoff = romstage_handoff_find_or_add(); - - run_ramstage_from_resume(handoff); + run_ramstage_from_resume(romstage_handoff_find_or_add());
for (i = 0; i < ARRAY_SIZE(loaders); i++) { ops = loaders[i]; printk(BIOS_DEBUG, "Trying %s ramstage loader.\n", ops->name); - load_ramstage(ops, handoff); + load_ramstage(ops); }
die("Ramstage was not loaded!\n"); diff --git a/src/lib/ramstage_cache.c b/src/lib/ramstage_cache.c index 814d807..8cedc70 100644 --- a/src/lib/ramstage_cache.c +++ b/src/lib/ramstage_cache.c @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2013 Google Inc. + * Copyright 2013-2015 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 @@ -20,123 +20,21 @@ #include <stddef.h> #include <string.h> #include <cbfs.h> -#include <console/console.h> -#include <ramstage_cache.h> -#include <romstage_handoff.h> +#include <cbmem.h> +#include <stage_cache.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 (!ramstage_cache_is_valid(cache)) { - 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 cache_loaded_ramstage(struct romstage_handoff *handoff, - const struct cbmem_entry *ramstage, void *entry_point) +void cache_loaded_ramstage(const struct cbmem_entry *ramstage, void *entry) { - uint32_t ramstage_size; - const struct cbmem_entry *entry; - - if (handoff == NULL) - return; + void *base; + size_t size;
- ramstage_size = cbmem_entry_size(ramstage); - /* cbmem_entry_add() does a find() before add(). */ - entry = cbmem_entry_add(CBMEM_ID_RAMSTAGE_CACHE, ramstage_size); + base = cbmem_entry_start(ramstage); + size = cbmem_entry_size(ramstage);
- 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); + stage_cache_add(STAGE_RAMSTAGE, base, size, entry); }
-void *load_cached_ramstage(struct romstage_handoff *handoff, - const struct cbmem_entry *ramstage) +void *load_cached_ramstage(void) { - 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; + return stage_cache_load_stage(STAGE_RAMSTAGE); } - -#endif diff --git a/src/soc/intel/baytrail/refcode.c b/src/soc/intel/baytrail/refcode.c index e855218..1e066d5 100644 --- a/src/soc/intel/baytrail/refcode.c +++ b/src/soc/intel/baytrail/refcode.c @@ -23,17 +23,12 @@ #include <console/console.h> #include <cpu/x86/tsc.h> #include <rmodule.h> -#include <ramstage_cache.h> +#include <stage_cache.h> #include <vendorcode/google/chromeos/vboot_handoff.h>
#include <baytrail/ramstage.h> #include <baytrail/efi_wrapper.h>
-static inline struct ramstage_cache *next_cache(struct ramstage_cache *c) -{ - return (struct ramstage_cache *)&c->program[c->size]; -} - static void ABI_X86 send_to_console(unsigned char b) { console_tx_byte(b); @@ -41,60 +36,24 @@ static void ABI_X86 send_to_console(unsigned char b)
static efi_wrapper_entry_t load_refcode_from_cache(void) { - struct ramstage_cache *c; - long cache_size; + void *entry;
printk(BIOS_DEBUG, "refcode loading from cache.\n");
- c = ramstage_cache_location(&cache_size); - - if (!ramstage_cache_is_valid(c)) { - printk(BIOS_DEBUG, "Invalid ramstage cache descriptor.\n"); - return NULL; - } - - c = next_cache(c); - if (!ramstage_cache_is_valid(c)) { - printk(BIOS_DEBUG, "Invalid refcode cache descriptor.\n"); - return NULL; - } - - printk(BIOS_DEBUG, "Loading cached reference code from 0x%08x(%x)\n", - c->load_address, c->size); - memcpy((void *)c->load_address, &c->program[0], c->size); + entry = stage_cache_load_stage(STAGE_REFCODE);
- return (efi_wrapper_entry_t)c->entry_point; + return (efi_wrapper_entry_t)entry; }
static void cache_refcode(const struct rmod_stage_load *rsl) { - struct ramstage_cache *c; - long cache_size; - - c = ramstage_cache_location(&cache_size); - - if (!ramstage_cache_is_valid(c)) { - printk(BIOS_DEBUG, "No place to cache reference code.\n"); - return; - } - - /* Determine how much remaining cache available. */ - cache_size -= c->size + sizeof(*c); - - if (cache_size < (sizeof(*c) + cbmem_entry_size(rsl->cbmem_entry))) { - printk(BIOS_DEBUG, "Not enough cache space for ref code.\n"); - return; - } + void *load_addr; + size_t size;
- c = next_cache(c); - c->magic = RAMSTAGE_CACHE_MAGIC; - c->entry_point = (uint32_t)rsl->entry; - c->load_address = (uint32_t)cbmem_entry_start(rsl->cbmem_entry); - c->size = cbmem_entry_size(rsl->cbmem_entry); + load_adr = cbmem_entry_start(rsl->cbmem_entry); + size = cbmem_entry_size(rsl->cbmem_entry);
- printk(BIOS_DEBUG, "Caching refcode at 0x%p(%x)\n", - &c->program[0], c->size); - memcpy(&c->program[0], (void *)c->load_address, c->size); + stage_cache_add(STAGE_REFCODE, load_addr, size, rsl->entry); }
static int load_refcode_from_vboot(struct rmod_stage_load *refcode, diff --git a/src/soc/intel/baytrail/romstage/raminit.c b/src/soc/intel/baytrail/romstage/raminit.c index a51853a..7488215 100644 --- a/src/soc/intel/baytrail/romstage/raminit.c +++ b/src/soc/intel/baytrail/romstage/raminit.c @@ -25,6 +25,7 @@ #include <console/console.h> #include <device/pci_def.h> #include <halt.h> +#include <stage_cache.h> #include <baytrail/gpio.h> #include <soc/intel/common/mrc_cache.h> #include <baytrail/iomap.h> @@ -169,12 +170,16 @@ void raminit(struct mrc_params *mp, int prev_sleep_state)
if (prev_sleep_state != 3) { cbmem_initialize_empty(); - } else if (cbmem_initialize()) { - #if CONFIG_HAVE_ACPI_RESUME - printk(BIOS_DEBUG, "Failed to recover CBMEM in S3 resume.\n"); - /* Failed S3 resume, reset to come up cleanly */ - reset_system(); - #endif + stage_cache_create_empty(); + } else { + stage_cache_recover(); + if (cbmem_initialize()) { + #if CONFIG_HAVE_ACPI_RESUME + printk(BIOS_DEBUG, "Failed to recover CBMEM in S3 resume.\n"); + /* Failed S3 resume, reset to come up cleanly */ + reset_system(); + #endif + } }
printk(BIOS_DEBUG, "MRC Wrapper returned %d\n", ret); diff --git a/src/soc/intel/baytrail/romstage/romstage.c b/src/soc/intel/baytrail/romstage/romstage.c index 91548e3..e961ccd 100644 --- a/src/soc/intel/baytrail/romstage/romstage.c +++ b/src/soc/intel/baytrail/romstage/romstage.c @@ -20,18 +20,18 @@ #include <stddef.h> #include <arch/cpu.h> #include <arch/io.h> -#include <arch/cbfs.h> #include <arch/stages.h> #include <arch/early_variables.h> #include <console/console.h> +#include <cbfs.h> #include <cbmem.h> #include <cpu/x86/mtrr.h> #if CONFIG_EC_GOOGLE_CHROMEEC #include <ec/google/chromeec/ec.h> #endif #include <elog.h> -#include <ramstage_cache.h> #include <romstage_handoff.h> +#include <stage_cache.h> #include <timestamp.h> #include <vendorcode/google/chromeos/chromeos.h> #include <baytrail/gpio.h> @@ -359,7 +359,7 @@ static void *setup_stack_and_mttrs(void) return slot; }
-void ramstage_cache_invalid(struct ramstage_cache *cache) +void ramstage_cache_invalid(void) { #if CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE /* Perform cold reset on invalid ramstage cache. */ diff --git a/src/soc/intel/baytrail/stage_cache.c b/src/soc/intel/baytrail/stage_cache.c index 3bda56d..c133bc8 100644 --- a/src/soc/intel/baytrail/stage_cache.c +++ b/src/soc/intel/baytrail/stage_cache.c @@ -18,10 +18,10 @@ */
#include <cbmem.h> -#include <ramstage_cache.h> +#include <stage_cache.h> #include <baytrail/smm.h>
-struct ramstage_cache *ramstage_cache_location(long *size) +void stage_cache_external_region(void **base, size_t *size) { char *smm_base; /* 1MiB cache size */ @@ -31,5 +31,5 @@ struct ramstage_cache *ramstage_cache_location(long *size) * cbmem_top(). */ smm_base = cbmem_top(); *size = cache_size; - return (void *)&smm_base[smm_region_size() - cache_size]; + *base = &smm_base[smm_region_size() - cache_size]; } diff --git a/src/soc/intel/broadwell/refcode.c b/src/soc/intel/broadwell/refcode.c index a745101..d1bdb18 100644 --- a/src/soc/intel/broadwell/refcode.c +++ b/src/soc/intel/broadwell/refcode.c @@ -23,7 +23,7 @@ #include <console/console.h> #include <cpu/x86/tsc.h> #include <rmodule.h> -#include <ramstage_cache.h> +#include <stage_cache.h> #include <string.h> #include <vendorcode/google/chromeos/vboot_handoff.h> #include <broadwell/pei_data.h> @@ -39,67 +39,26 @@ static inline int is_s3_resume(void) #endif }
-static inline struct ramstage_cache *next_cache(struct ramstage_cache *c) -{ - return (struct ramstage_cache *)&c->program[c->size]; -} - static pei_wrapper_entry_t load_refcode_from_cache(void) { - struct ramstage_cache *c; - long cache_size; + void *entry;
printk(BIOS_DEBUG, "refcode loading from cache.\n");
- c = ramstage_cache_location(&cache_size); - - if (!ramstage_cache_is_valid(c)) { - printk(BIOS_DEBUG, "Invalid ramstage cache descriptor.\n"); - return NULL; - } - - c = next_cache(c); - if (!ramstage_cache_is_valid(c)) { - printk(BIOS_DEBUG, "Invalid refcode cache descriptor.\n"); - return NULL; - } - - printk(BIOS_DEBUG, "Loading cached reference code from 0x%08x(%x)\n", - c->load_address, c->size); - memcpy((void *)c->load_address, &c->program[0], c->size); + entry = stage_cache_load_stage(STAGE_REFCODE);
- return (pei_wrapper_entry_t)c->entry_point; + return (pei_wrapper_entry_t)entry; }
static void cache_refcode(const struct rmod_stage_load *rsl) { - struct ramstage_cache *c; - long cache_size; - - c = ramstage_cache_location(&cache_size); - - if (!ramstage_cache_is_valid(c)) { - printk(BIOS_DEBUG, "No place to cache reference code.\n"); - return; - } - - /* Determine how much remaining cache available. */ - cache_size -= c->size + sizeof(*c); - - if (cache_size < (sizeof(*c) + cbmem_entry_size(rsl->cbmem_entry))) { - printk(BIOS_DEBUG, "Not enough cache space for ref code.\n"); - return; - } + void *load_addr; + size_t size;
- c = next_cache(c); - c->magic = RAMSTAGE_CACHE_MAGIC; - c->entry_point = (uint32_t)rsl->entry; - c->load_address = (uint32_t)cbmem_entry_start(rsl->cbmem_entry); - c->size = cbmem_entry_size(rsl->cbmem_entry); + load_adr = cbmem_entry_start(rsl->cbmem_entry); + size = cbmem_entry_size(rsl->cbmem_entry);
- printk(BIOS_DEBUG, "Caching refcode at 0x%p(%x)\n", - &c->program[0], c->size); - memcpy(&c->program[0], (void *)c->load_address, c->size); + stage_cache_add(STAGE_REFCODE, load_addr, size, rsl->entry); }
static int load_refcode_from_vboot(struct rmod_stage_load *refcode, diff --git a/src/soc/intel/broadwell/romstage/romstage.c b/src/soc/intel/broadwell/romstage/romstage.c index 5ca57d0..202cd42 100644 --- a/src/soc/intel/broadwell/romstage/romstage.c +++ b/src/soc/intel/broadwell/romstage/romstage.c @@ -25,11 +25,12 @@ #include <arch/stages.h> #include <arch/early_variables.h> #include <console/console.h> +#include <cbfs.h> #include <cbmem.h> #include <cpu/x86/mtrr.h> #include <elog.h> -#include <ramstage_cache.h> #include <romstage_handoff.h> +#include <stage_cache.h> #include <timestamp.h> #include <broadwell/me.h> #include <broadwell/pei_data.h> @@ -130,7 +131,7 @@ void asmlinkage romstage_after_car(void) while (1); }
-void ramstage_cache_invalid(struct ramstage_cache *cache) +void ramstage_cache_invalid(void) { #if CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE /* Perform cold reset on invalid ramstage cache. */ diff --git a/src/soc/intel/broadwell/stage_cache.c b/src/soc/intel/broadwell/stage_cache.c index 6c6b6fb..80c7cc5 100644 --- a/src/soc/intel/broadwell/stage_cache.c +++ b/src/soc/intel/broadwell/stage_cache.c @@ -18,11 +18,11 @@ */
#include <cbmem.h> -#include <ramstage_cache.h> +#include <stage_cache.h> #include <broadwell/smm.h> #include <stdint.h>
-struct ramstage_cache *ramstage_cache_location(long *size) +void stage_cache_external_region(void **base, size_t *size) { /* The ramstage cache lives in the TSEG region. * The top of ram is defined to be the TSEG base address. */ @@ -30,6 +30,6 @@ struct ramstage_cache *ramstage_cache_location(long *size) offset -= CONFIG_IED_REGION_SIZE; offset -= CONFIG_SMM_RESERVED_SIZE;
+ *base = (void *)(cbmem_top() + offset); *size = CONFIG_SMM_RESERVED_SIZE; - return (void *)(cbmem_top() + offset); }