summaryrefslogtreecommitdiff
path: root/src/soc/intel/apollolake
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/apollolake')
-rw-r--r--src/soc/intel/apollolake/Kconfig4
-rw-r--r--src/soc/intel/apollolake/romstage.c39
2 files changed, 42 insertions, 1 deletions
diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig
index d1d660bc78..092102cfbc 100644
--- a/src/soc/intel/apollolake/Kconfig
+++ b/src/soc/intel/apollolake/Kconfig
@@ -161,6 +161,10 @@ config CACHE_MRC_SETTINGS
bool
default y
+config MRC_SETTINGS_VARIABLE_DATA
+ bool
+ default y
+
config FSP_M_ADDR
hex
default 0xfef40000
diff --git a/src/soc/intel/apollolake/romstage.c b/src/soc/intel/apollolake/romstage.c
index d623913086..039b586263 100644
--- a/src/soc/intel/apollolake/romstage.c
+++ b/src/soc/intel/apollolake/romstage.c
@@ -32,6 +32,7 @@
#include <fsp/memmap.h>
#include <fsp/util.h>
#include <soc/cpu.h>
+#include <soc/intel/common/mrc_cache.h>
#include <soc/iomap.h>
#include <soc/northbridge.h>
#include <soc/pci_devs.h>
@@ -47,6 +48,13 @@
static struct chipset_power_state power_state CAR_GLOBAL;
+static const uint8_t hob_variable_guid[16] = {
+ 0x7d, 0x14, 0x34, 0xa0, 0x0c, 0x69, 0x54, 0x41,
+ 0x8d, 0xe6, 0xc0, 0x44, 0x64, 0x1d, 0xe9, 0x42,
+};
+
+static uint32_t fsp_version CAR_GLOBAL;
+
/* High Performance Event Timer Configuration */
#define P2SB_HPTC 0x60
#define P2SB_HPTC_ADDRESS_ENABLE (1 << 7)
@@ -170,7 +178,8 @@ asmlinkage void car_stage_entry(void)
bool s3wake;
struct chipset_power_state *ps = car_get_var_ptr(&power_state);
void *smm_base;
- size_t smm_size;
+ size_t smm_size, var_size;
+ const void *new_var_data;
uintptr_t tseg_base;
timestamp_add_now(TS_START_ROMSTAGE);
@@ -188,6 +197,15 @@ asmlinkage void car_stage_entry(void)
else
printk(BIOS_DEBUG, "Punit failed to initialize properly\n");
+ /* Stash variable MRC data and let cache system update it later */
+ new_var_data = fsp_find_extension_hob_by_guid(hob_variable_guid,
+ &var_size);
+ if (new_var_data)
+ mrc_cache_stash_vardata(new_var_data, var_size,
+ car_get_var(fsp_version));
+ else
+ printk(BIOS_ERR, "Failed to determine variable data\n");
+
if (postcar_frame_init(&pcf, 1*KiB))
die("Unable to initialize postcar frame.\n");
@@ -239,6 +257,8 @@ static void fill_console_params(FSPM_UPD *mupd)
void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
{
+ const struct mrc_saved_data *msd;
+
fill_console_params(mupd);
mainboard_memory_init_params(mupd);
@@ -262,6 +282,23 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
* skip HECI2 reset.
*/
mupd->FspmConfig.EnableS3Heci2 = 0;
+
+ /*
+ * Apollolake splits MRC cache into two parts: constant and variable.
+ * The constant part is not expected to change often and variable is.
+ * Currently variable part consists of parameters that change on cold
+ * boots such as scrambler seed and some memory controller registers.
+ * Scrambler seed is vital for S3 resume case because attempt to use
+ * wrong/missing key renders DRAM contents useless.
+ */
+
+ if (mrc_cache_get_vardata(&msd, version) < 0) {
+ printk(BIOS_DEBUG, "MRC variable data missing/invalid\n");
+ } else {
+ mupd->FspmConfig.VariableNvsBufferPtr = (void*) msd->data;
+ }
+
+ car_set_var(fsp_version, version);
}
__attribute__ ((weak))