soc/intel/apollolake: Add save/restore variable MRC cache
Apollolake MRC cache is divided into two regions: constant and variable. Currently they are clubbed together. Since variable data changes across cold reboot it triggers invalidation of the whole cache region. This change declubs the data, adds routines to load/store variable data on flash. BUG=chrome-os-partner:57515 TEST=with patch series applied: cold reboot, make sure MRC is not updated. Do S3 suspend/resume cycle. Change-Id: I374519777abe9b9a1e6cceae5318decd405bb527 Signed-off-by: Andrey Petrov <andrey.petrov@intel.com> Reviewed-on: https://review.coreboot.org/17237 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
ef9a9ea3b7
commit
96e9ff168c
|
@ -161,6 +161,10 @@ config CACHE_MRC_SETTINGS
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config MRC_SETTINGS_VARIABLE_DATA
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config FSP_M_ADDR
|
config FSP_M_ADDR
|
||||||
hex
|
hex
|
||||||
default 0xfef40000
|
default 0xfef40000
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <fsp/memmap.h>
|
#include <fsp/memmap.h>
|
||||||
#include <fsp/util.h>
|
#include <fsp/util.h>
|
||||||
#include <soc/cpu.h>
|
#include <soc/cpu.h>
|
||||||
|
#include <soc/intel/common/mrc_cache.h>
|
||||||
#include <soc/iomap.h>
|
#include <soc/iomap.h>
|
||||||
#include <soc/northbridge.h>
|
#include <soc/northbridge.h>
|
||||||
#include <soc/pci_devs.h>
|
#include <soc/pci_devs.h>
|
||||||
|
@ -47,6 +48,13 @@
|
||||||
|
|
||||||
static struct chipset_power_state power_state CAR_GLOBAL;
|
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 */
|
/* High Performance Event Timer Configuration */
|
||||||
#define P2SB_HPTC 0x60
|
#define P2SB_HPTC 0x60
|
||||||
#define P2SB_HPTC_ADDRESS_ENABLE (1 << 7)
|
#define P2SB_HPTC_ADDRESS_ENABLE (1 << 7)
|
||||||
|
@ -170,7 +178,8 @@ asmlinkage void car_stage_entry(void)
|
||||||
bool s3wake;
|
bool s3wake;
|
||||||
struct chipset_power_state *ps = car_get_var_ptr(&power_state);
|
struct chipset_power_state *ps = car_get_var_ptr(&power_state);
|
||||||
void *smm_base;
|
void *smm_base;
|
||||||
size_t smm_size;
|
size_t smm_size, var_size;
|
||||||
|
const void *new_var_data;
|
||||||
uintptr_t tseg_base;
|
uintptr_t tseg_base;
|
||||||
|
|
||||||
timestamp_add_now(TS_START_ROMSTAGE);
|
timestamp_add_now(TS_START_ROMSTAGE);
|
||||||
|
@ -188,6 +197,15 @@ asmlinkage void car_stage_entry(void)
|
||||||
else
|
else
|
||||||
printk(BIOS_DEBUG, "Punit failed to initialize properly\n");
|
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))
|
if (postcar_frame_init(&pcf, 1*KiB))
|
||||||
die("Unable to initialize postcar frame.\n");
|
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)
|
void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
|
||||||
{
|
{
|
||||||
|
const struct mrc_saved_data *msd;
|
||||||
|
|
||||||
fill_console_params(mupd);
|
fill_console_params(mupd);
|
||||||
mainboard_memory_init_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.
|
* skip HECI2 reset.
|
||||||
*/
|
*/
|
||||||
mupd->FspmConfig.EnableS3Heci2 = 0;
|
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))
|
__attribute__ ((weak))
|
||||||
|
|
Loading…
Reference in New Issue