mb/google/puff: add a region to cache SPD data

This patch adds a SPI rom region RW_SPD_CACHE on Puff and it can be used
on spd_cache to reduce reading SPD data from SODIMM by smbus. It's for
saving the boot time and it can be used to trigger MRC retraining when
memory DIMM is changed.

BUG=b:146457985
BRANCH=None
TEST=Build puff successfully and verified below two items.
     1. To change memory DIMM can trigger retraining.
     2. one DIMM save the boot time : 158ms
        two DIMM save the boot time : 265ms

Change-Id: I8d07fddf113a767d62394cb31e33b56f22f74351
Signed-off-by: Jamie Chen <jamie.chen@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/40415
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
This commit is contained in:
Jamie Chen 2020-04-16 01:42:51 +08:00 committed by Patrick Georgi
parent 92ba06fb3e
commit 7410992391
4 changed files with 131 additions and 2 deletions

View File

@ -79,10 +79,19 @@ config DRIVER_TPM_SPI_BUS
config UART_FOR_CONSOLE
default 0
if ROMSTAGE_SPD_CBFS
config FMDFILE
string
default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/chromeos-16MiB.fmd" if BOARD_ROMSIZE_KB_16384
default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/chromeos.fmd" if BOARD_ROMSIZE_KB_32768
endif
if ROMSTAGE_SPD_SMBUS
config FMDFILE
string
default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/chromeos-16MiB-spd.fmd" if BOARD_ROMSIZE_KB_16384
default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/chromeos-spd.fmd" if BOARD_ROMSIZE_KB_32768
endif
config MAINBOARD_DIR
string

View File

@ -0,0 +1,44 @@
FLASH@0xff000000 0x1000000 {
SI_ALL@0x0 0x400000 {
SI_DESC@0x0 0x1000
SI_ME@0x1000 0x3ff000
}
SI_BIOS@0x400000 0xc00000 {
RW_SECTION_A@0x0 0x368000 {
VBLOCK_A@0x0 0x10000
FW_MAIN_A(CBFS)@0x10000 0x357fc0
RW_FWID_A@0x367fc0 0x40
}
RW_SECTION_B@0x368000 0x368000 {
VBLOCK_B@0x0 0x10000
FW_MAIN_B(CBFS)@0x10000 0x357fc0
RW_FWID_B@0x367fc0 0x40
}
RW_MISC@0x6D0000 0x30000 {
UNIFIED_MRC_CACHE@0x0 0x20000 {
RECOVERY_MRC_CACHE@0x0 0x10000
RW_MRC_CACHE@0x10000 0x10000
}
RW_ELOG(PRESERVE)@0x20000 0x4000
RW_SHARED@0x24000 0x4000 {
SHARED_DATA@0x0 0x2000
VBLOCK_DEV@0x2000 0x2000
}
RW_VPD(PRESERVE)@0x28000 0x2000
RW_NVRAM(PRESERVE)@0x2a000 0x5000
RW_SPD_CACHE(PRESERVE)@0x2f000 0x1000
}
# RW_LEGACY needs to be minimum of 1MB
RW_LEGACY(CBFS)@0x700000 0x100000
WP_RO@0x800000 0x400000 {
RO_VPD(PRESERVE)@0x0 0x4000
RO_SECTION@0x4000 0x3fc000 {
FMAP@0x0 0x800
RO_FRID@0x800 0x40
RO_FRID_PAD@0x840 0x7c0
GBB@0x1000 0x3000
COREBOOT(CBFS)@0x4000 0x3f8000
}
}
}
}

View File

@ -0,0 +1,48 @@
FLASH@0xfe000000 0x2000000 {
SI_ALL@0x0 0x400000 {
SI_DESC@0x0 0x1000
SI_ME@0x1000 0x3ff000
}
SI_BIOS@0x400000 0x1c00000 {
# Place RW_LEGACY at the start of BIOS region such that the rest
# of BIOS regions start at 16MiB boundary. Since this is a 32MiB
# SPI flash only the top 16MiB actually gets memory mapped.
RW_LEGACY(CBFS)@0x0 0x1000000
RW_SECTION_A@0x1000000 0x3e0000 {
VBLOCK_A@0x0 0x10000
FW_MAIN_A(CBFS)@0x10000 0x3cffc0
RW_FWID_A@0x3dffc0 0x40
}
RW_SECTION_B@0x13e0000 0x3e0000 {
VBLOCK_B@0x0 0x10000
FW_MAIN_B(CBFS)@0x10000 0x3cffc0
RW_FWID_B@0x3dffc0 0x40
}
RW_MISC@0x17c0000 0x40000 {
UNIFIED_MRC_CACHE(PRESERVE)@0x0 0x30000 {
RECOVERY_MRC_CACHE@0x0 0x10000
RW_MRC_CACHE@0x10000 0x20000
}
RW_ELOG(PRESERVE)@0x30000 0x4000
RW_SHARED@0x34000 0x4000 {
SHARED_DATA@0x0 0x2000
VBLOCK_DEV@0x2000 0x2000
}
RW_VPD(PRESERVE)@0x38000 0x2000
RW_NVRAM(PRESERVE)@0x3a000 0x5000
RW_SPD_CACHE(PRESERVE)@0x3f000 0x1000
}
# Make WP_RO region align with SPI vendor
# memory protected range specification.
WP_RO@0x1800000 0x400000 {
RO_VPD(PRESERVE)@0x0 0x4000
RO_SECTION@0x4000 0x3fc000 {
FMAP@0x0 0x800
RO_FRID@0x800 0x40
RO_FRID_PAD@0x840 0x7c0
GBB@0x1000 0x3000
COREBOOT(CBFS)@0x4000 0x3f8000
}
}
}
}

View File

@ -4,6 +4,7 @@
#include <soc/cnl_memcfg_init.h>
#include <soc/romstage.h>
#include <spd_bin.h>
#include <spd_cache.h>
void mainboard_memory_init_params(FSPM_UPD *memupd)
{
@ -15,8 +16,35 @@ void mainboard_memory_init_params(FSPM_UPD *memupd)
.addr_map = { 0x50, 0x52, },
};
/* Access memory info through SMBUS. */
get_spd_smbus(&blk);
uint8_t *spd_cache;
size_t spd_cache_sz;
bool need_update_cache = false;
bool dimm_changed = true;
/* load spd cache from RW_SPD_CACHE */
if (load_spd_cache(&spd_cache, &spd_cache_sz) == CB_SUCCESS) {
if (!spd_cache_is_valid(spd_cache, spd_cache_sz)) {
printk(BIOS_WARNING, "Invalid SPD cache\n");
} else {
dimm_changed = check_if_dimm_changed(spd_cache, &blk);
if (dimm_changed && memupd->FspmArchUpd.NvsBufferPtr != NULL) {
/* Set mrc_cache as invalid */
printk(BIOS_INFO, "Set mrc_cache as invalid\n");
memupd->FspmArchUpd.NvsBufferPtr = NULL;
}
}
need_update_cache = true;
}
if (!dimm_changed) {
spd_fill_from_cache(spd_cache, &blk);
} else {
/* Access memory info through SMBUS. */
get_spd_smbus(&blk);
if (need_update_cache && update_spd_cache(&blk) == CB_ERR)
printk(BIOS_WARNING, "update SPD cache failed\n");
}
if (blk.spd_array[0] == NULL) {
memcfg.spd[0].read_type = NOT_EXISTING;