drivers/intel/fsp2_0: Update MRC cache in ramstage
Currently the MRC cache is updated in romstage, immediately after returning from FSP-M. Since cbmem is not cached in romstage, the update is slow (~6 ms on nissa). Specifically, the new MRC data returned by the FSP is stored in the FSP reserved memory in cbmem, so hashing the new data is slow. Move the MRC cache update to ramstage, where cbmem is cached. On nissa, this saves ~5 ms of boot time. Before: 552:finished loading ChromeOS VPD (RW) 631,667 (16) 3:after RAM initialization 637,703 (6,036) 4:end of romstage 650,307 (12,603) After: 552:finished loading ChromeOS VPD (RW) 631,832 (15) 3:after RAM initialization 633,002 (1,169) 4:end of romstage 645,582 (12,580) In ramstage, save_mrc_data() takes ~138 us. BUG=b:242667207 TEST=MRC caching still works as expected on nivviks - after clearing the MRC cache, memory is retrained on the next boot, but cached data is used on subsequent boots. Change-Id: Ie6aa2dee83a3ab8913830746593935d36a034b8d Signed-off-by: Reka Norman <rekanorman@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/67669 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
parent
c4fbeacd01
commit
7b5a93153a
|
@ -26,6 +26,7 @@
|
||||||
#define CBMEM_ID_FREESPACE 0x46524545
|
#define CBMEM_ID_FREESPACE 0x46524545
|
||||||
#define CBMEM_ID_FSP_RESERVED_MEMORY 0x46535052
|
#define CBMEM_ID_FSP_RESERVED_MEMORY 0x46535052
|
||||||
#define CBMEM_ID_FSP_RUNTIME 0x52505346
|
#define CBMEM_ID_FSP_RUNTIME 0x52505346
|
||||||
|
#define CBMEM_ID_FSPM_VERSION 0x56505346
|
||||||
#define CBMEM_ID_GDT 0x4c474454
|
#define CBMEM_ID_GDT 0x4c474454
|
||||||
#define CBMEM_ID_HOB_POINTER 0x484f4221
|
#define CBMEM_ID_HOB_POINTER 0x484f4221
|
||||||
#define CBMEM_ID_IGD_OPREGION 0x4f444749
|
#define CBMEM_ID_IGD_OPREGION 0x4f444749
|
||||||
|
@ -108,6 +109,7 @@
|
||||||
{ CBMEM_ID_FREESPACE, "FREE SPACE " }, \
|
{ CBMEM_ID_FREESPACE, "FREE SPACE " }, \
|
||||||
{ CBMEM_ID_FSP_RESERVED_MEMORY, "FSP MEMORY " }, \
|
{ CBMEM_ID_FSP_RESERVED_MEMORY, "FSP MEMORY " }, \
|
||||||
{ CBMEM_ID_FSP_RUNTIME, "FSP RUNTIME" }, \
|
{ CBMEM_ID_FSP_RUNTIME, "FSP RUNTIME" }, \
|
||||||
|
{ CBMEM_ID_FSPM_VERSION, "FSPM VERSION" }, \
|
||||||
{ CBMEM_ID_GDT, "GDT " }, \
|
{ CBMEM_ID_GDT, "GDT " }, \
|
||||||
{ CBMEM_ID_HOB_POINTER, "HOB " }, \
|
{ CBMEM_ID_HOB_POINTER, "HOB " }, \
|
||||||
{ CBMEM_ID_IGD_OPREGION, "IGD OPREGION" }, \
|
{ CBMEM_ID_IGD_OPREGION, "IGD OPREGION" }, \
|
||||||
|
|
|
@ -29,6 +29,7 @@ ramstage-y += notify.c
|
||||||
ramstage-y += silicon_init.c
|
ramstage-y += silicon_init.c
|
||||||
ramstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c
|
ramstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c
|
||||||
ramstage-y += util.c
|
ramstage-y += util.c
|
||||||
|
ramstage-$(CONFIG_CACHE_MRC_SETTINGS) += save_mrc_data.c
|
||||||
ramstage-$(CONFIG_MMA) += mma_core.c
|
ramstage-$(CONFIG_MMA) += mma_core.c
|
||||||
|
|
||||||
ifneq ($(CONFIG_NO_FSP_TEMP_RAM_EXIT),y)
|
ifneq ($(CONFIG_NO_FSP_TEMP_RAM_EXIT),y)
|
||||||
|
|
|
@ -26,31 +26,10 @@
|
||||||
|
|
||||||
static uint8_t temp_ram[CONFIG_FSP_TEMP_RAM_SIZE] __aligned(sizeof(uint64_t));
|
static uint8_t temp_ram[CONFIG_FSP_TEMP_RAM_SIZE] __aligned(sizeof(uint64_t));
|
||||||
|
|
||||||
static void save_memory_training_data(uint32_t fsp_version)
|
|
||||||
{
|
|
||||||
size_t mrc_data_size;
|
|
||||||
const void *mrc_data;
|
|
||||||
|
|
||||||
mrc_data = fsp_find_nv_storage_data(&mrc_data_size);
|
|
||||||
if (!mrc_data) {
|
|
||||||
printk(BIOS_ERR, "FSP_NON_VOLATILE_STORAGE_HOB missing!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Save MRC Data to CBMEM. By always saving the data this forces
|
|
||||||
* a retrain after a trip through ChromeOS recovery path. The
|
|
||||||
* code which saves the data to flash doesn't write if the latest
|
|
||||||
* training data matches this one.
|
|
||||||
*/
|
|
||||||
if (mrc_cache_stash_data(MRC_TRAINING_DATA, fsp_version, mrc_data,
|
|
||||||
mrc_data_size) < 0)
|
|
||||||
printk(BIOS_ERR, "Failed to stash MRC data\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void do_fsp_post_memory_init(bool s3wake, uint32_t fsp_version)
|
static void do_fsp_post_memory_init(bool s3wake, uint32_t fsp_version)
|
||||||
{
|
{
|
||||||
struct range_entry fsp_mem;
|
struct range_entry fsp_mem;
|
||||||
|
uint32_t *fsp_version_cbmem;
|
||||||
|
|
||||||
fsp_find_reserved_memory(&fsp_mem);
|
fsp_find_reserved_memory(&fsp_mem);
|
||||||
|
|
||||||
|
@ -73,8 +52,14 @@ static void do_fsp_post_memory_init(bool s3wake, uint32_t fsp_version)
|
||||||
(uintptr_t)cbmem_find(CBMEM_ID_FSP_RESERVED_MEMORY))
|
(uintptr_t)cbmem_find(CBMEM_ID_FSP_RESERVED_MEMORY))
|
||||||
die("Failed to accommodate FSP reserved memory request!\n");
|
die("Failed to accommodate FSP reserved memory request!\n");
|
||||||
|
|
||||||
if (CONFIG(CACHE_MRC_SETTINGS) && !s3wake)
|
/* ramstage uses the FSP-M version when updating the MRC cache */
|
||||||
save_memory_training_data(fsp_version);
|
if (CONFIG(CACHE_MRC_SETTINGS) && !s3wake) {
|
||||||
|
fsp_version_cbmem = cbmem_add(CBMEM_ID_FSPM_VERSION,
|
||||||
|
sizeof(fsp_version));
|
||||||
|
if (!fsp_version_cbmem)
|
||||||
|
printk(BIOS_ERR, "Failed to add FSP-M version to cbmem.\n");
|
||||||
|
*fsp_version_cbmem = fsp_version;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create romstage handof information */
|
/* Create romstage handof information */
|
||||||
romstage_handoff_init(s3wake);
|
romstage_handoff_init(s3wake);
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include <acpi/acpi.h>
|
||||||
|
#include <bootstate.h>
|
||||||
|
#include <cbmem.h>
|
||||||
|
#include <console/console.h>
|
||||||
|
#include <fsp/util.h>
|
||||||
|
#include <mrc_cache.h>
|
||||||
|
|
||||||
|
static void save_mrc_data(void *unused)
|
||||||
|
{
|
||||||
|
size_t mrc_data_size;
|
||||||
|
const void *mrc_data;
|
||||||
|
uint32_t *fspm_version;
|
||||||
|
|
||||||
|
if (acpi_is_wakeup_s3())
|
||||||
|
return;
|
||||||
|
|
||||||
|
fspm_version = cbmem_find(CBMEM_ID_FSPM_VERSION);
|
||||||
|
if (!fspm_version) {
|
||||||
|
printk(BIOS_ERR, "Failed to read FSP-M version from cbmem.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mrc_data = fsp_find_nv_storage_data(&mrc_data_size);
|
||||||
|
if (!mrc_data) {
|
||||||
|
printk(BIOS_ERR, "FSP_NON_VOLATILE_STORAGE_HOB missing!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save MRC data to SPI flash. By always saving the data this forces
|
||||||
|
* a retrain after a trip through ChromeOS recovery path. The
|
||||||
|
* code which saves the data to flash doesn't write if the latest
|
||||||
|
* training data matches this one.
|
||||||
|
*/
|
||||||
|
if (mrc_cache_stash_data(MRC_TRAINING_DATA, *fspm_version, mrc_data,
|
||||||
|
mrc_data_size) < 0)
|
||||||
|
printk(BIOS_ERR, "Failed to stash MRC data\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should be done before ramstage_cse_fw_sync() to avoid traning memory twice on
|
||||||
|
* a cold boot after a full firmware update.
|
||||||
|
*/
|
||||||
|
BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, save_mrc_data, NULL);
|
Loading…
Reference in New Issue