diff options
author | Aaron Durbin <adurbin@chromium.org> | 2013-10-10 20:37:04 -0500 |
---|---|---|
committer | Aaron Durbin <adurbin@google.com> | 2014-01-30 06:04:02 +0100 |
commit | 75e297428f6a88406fa3e1c0b54ab3d4f411db5c (patch) | |
tree | 79f92c66708898c4e2625ce0b8e6398383823361 /src/cpu | |
parent | 6ac3405fdff9277d73db9b03cf88ca8dcc9d4455 (diff) | |
download | coreboot-75e297428f6a88406fa3e1c0b54ab3d4f411db5c.tar.xz |
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.
Change-Id: I70d0940f7a8f73640c92a75fd22588c2c234241b
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/172602
Reviewed-by: Stefan Reinauer <reinauer@google.com>
Reviewed-on: http://review.coreboot.org/4876
Tested-by: build bot (Jenkins)
Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/intel/haswell/haswell.h | 16 | ||||
-rw-r--r-- | src/cpu/intel/haswell/romstage.c | 66 |
2 files changed, 10 insertions, 72 deletions
diff --git a/src/cpu/intel/haswell/haswell.h b/src/cpu/intel/haswell/haswell.h index dcd5dc70ea..190abc65ee 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 6b5780bdbc..60a1c3a155 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 @@ -316,67 +317,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 |