cpu/amd/agesa: Use common MRC_CACHE code to save S3 data

Use the common code to save data for fast boot or S3 resume.
An notable improvement that comes with this, is that the same 4K page
is not rewritten all the time. This prolongs the hardware's life.

TESTED on pcengines/apu1 and lenovo/g505s: S3 resume works fine.

Change-Id: I0f4f36dcead52a6c550fb5e606772e0a99029872
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/44295
Reviewed-by: Mike Banon <mikebdp2@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-by: Michał Żygowski <michal.zygowski@3mdeb.com>
This commit is contained in:
Arthur Heymans 2020-08-07 22:30:04 +02:00 committed by Michał Żygowski
parent 750d57ff5d
commit b97a303fa6
5 changed files with 22 additions and 84 deletions

View File

@ -13,6 +13,7 @@ config CPU_AMD_AGESA
select LAPIC_MONOTONIC_TIMER select LAPIC_MONOTONIC_TIMER
select SPI_FLASH if HAVE_ACPI_RESUME select SPI_FLASH if HAVE_ACPI_RESUME
select SSE2 select SSE2
select CACHE_MRC_SETTINGS
if CPU_AMD_AGESA if CPU_AMD_AGESA
@ -44,14 +45,6 @@ config ENABLE_MRC_CACHE
Try to restore memory training results Try to restore memory training results
from non-volatile memory. from non-volatile memory.
config S3_DATA_POS
hex
default 0xFFFF0000
config S3_DATA_SIZE
int
default 4096
endif # CPU_AMD_AGESA endif # CPU_AMD_AGESA
source "src/cpu/amd/agesa/family14/Kconfig" source "src/cpu/amd/agesa/family14/Kconfig"

View File

@ -3,18 +3,3 @@
subdirs-$(CONFIG_CPU_AMD_AGESA_FAMILY14) += family14 subdirs-$(CONFIG_CPU_AMD_AGESA_FAMILY14) += family14
subdirs-$(CONFIG_CPU_AMD_AGESA_FAMILY15_TN) += family15tn subdirs-$(CONFIG_CPU_AMD_AGESA_FAMILY15_TN) += family15tn
subdirs-$(CONFIG_CPU_AMD_AGESA_FAMILY16_KB) += family16kb subdirs-$(CONFIG_CPU_AMD_AGESA_FAMILY16_KB) += family16kb
ifeq ($(CONFIG_HAVE_ACPI_RESUME), y)
$(obj)/coreboot_s3nv.rom: $(obj)/config.h
echo " S3 NVRAM $(CONFIG_S3_DATA_POS) (S3 storage area)"
# force C locale, so cygwin awk doesn't try to interpret the 0xff below as UTF-8 (or worse)
printf %d $(CONFIG_S3_DATA_SIZE) | LC_ALL=C awk '{for (i=0; i<$$1; i++) {printf "%c", 255}}' > $@.tmp
mv $@.tmp $@
cbfs-files-y += s3nv
s3nv-file := $(obj)/coreboot_s3nv.rom
s3nv-position := $(CONFIG_S3_DATA_POS)
s3nv-type := raw
endif # CONFIG_HAVE_ACPI_RESUME == y

View File

@ -1,41 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
#include <spi-generic.h>
#include <spi_flash.h>
#include <string.h> #include <string.h>
#include <cbmem.h> #include <cbmem.h>
#include <console/console.h> #include <console/console.h>
#include <mrc_cache.h>
#include <northbridge/amd/agesa/state_machine.h> #include <northbridge/amd/agesa/state_machine.h>
#include <AGESA.h> #include <AGESA.h>
#include <northbridge/amd/agesa/agesa_helper.h> #include <northbridge/amd/agesa/agesa_helper.h>
/* The size needs to be 4k aligned, which is the sector size of most flashes. */ /* Training data versioning is not supported or tracked. */
#define S3_DATA_NONVOLATILE_SIZE 0x1000 #define DEFAULT_MRC_VERSION 0
#if CONFIG(HAVE_ACPI_RESUME) && S3_DATA_NONVOLATILE_SIZE > CONFIG_S3_DATA_SIZE
#error "Please increase the value of S3_DATA_SIZE"
#endif
static void get_s3nv_data(uintptr_t *pos, uintptr_t *len)
{
/* FIXME: Find file from CBFS. */
*pos = CONFIG_S3_DATA_POS;
*len = S3_DATA_NONVOLATILE_SIZE;
}
AGESA_STATUS OemInitResume(AMD_S3_PARAMS *dataBlock) AGESA_STATUS OemInitResume(AMD_S3_PARAMS *dataBlock)
{ {
uintptr_t pos, size; void *nv_storage = NULL;
get_s3nv_data(&pos, &size); size_t nv_storage_size = 0;
u32 len = *(u32*)pos; nv_storage = mrc_cache_current_mmap_leak(MRC_TRAINING_DATA, DEFAULT_MRC_VERSION,
&nv_storage_size);
/* Test for uninitialized s3nv data in SPI. */ if (nv_storage == NULL || nv_storage_size == 0) {
if (len == 0 || len == (u32)-1ULL) printk(BIOS_ERR, "%s: No valid MRC cache!\n", __func__);
return AGESA_FATAL; return AGESA_CRITICAL;
}
dataBlock->NvStorage = nv_storage;
dataBlock->NvStorageSize = nv_storage_size;
dataBlock->NvStorageSize = len;
dataBlock->NvStorage = (void *) (pos + sizeof(u32));
return AGESA_SUCCESS; return AGESA_SUCCESS;
} }
@ -56,44 +47,13 @@ AGESA_STATUS OemS3LateRestore(AMD_S3_PARAMS *dataBlock)
return AGESA_SUCCESS; return AGESA_SUCCESS;
} }
#if ENV_RAMSTAGE
static int spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len)
{
#if CONFIG(SPI_FLASH)
struct spi_flash flash;
spi_init();
if (spi_flash_probe(0, 0, &flash))
return -1;
spi_flash_volatile_group_begin(&flash);
spi_flash_erase(&flash, pos, size);
spi_flash_write(&flash, pos, sizeof(len), &len);
spi_flash_write(&flash, pos + sizeof(len), len, buf);
spi_flash_volatile_group_end(&flash);
return 0;
#else
return -1;
#endif
}
AGESA_STATUS OemS3Save(AMD_S3_PARAMS *dataBlock) AGESA_STATUS OemS3Save(AMD_S3_PARAMS *dataBlock)
{ {
uintptr_t pos, size; if (mrc_cache_stash_data(MRC_TRAINING_DATA, DEFAULT_MRC_VERSION,
dataBlock->NvStorage, dataBlock->NvStorageSize) < 0) {
/* To be consumed in AmdInitResume. */ printk(BIOS_ERR, "%s: Failed to stash MRC data\n", __func__);
get_s3nv_data(&pos, &size); return AGESA_CRITICAL;
if (size && dataBlock->NvStorageSize) }
spi_SaveS3info(pos, size, dataBlock->NvStorage,
dataBlock->NvStorageSize);
else
printk(BIOS_EMERG,
"Error: Cannot store memory training results in SPI.\n"
"Error: S3 resume will not be possible.\n"
);
/* To be consumed in AmdS3LateRestore. */ /* To be consumed in AmdS3LateRestore. */
char *heap = cbmem_add(CBMEM_ID_RESUME_SCRATCH, HIGH_MEMORY_SCRATCH); char *heap = cbmem_add(CBMEM_ID_RESUME_SCRATCH, HIGH_MEMORY_SCRATCH);
@ -107,5 +67,3 @@ AGESA_STATUS OemS3Save(AMD_S3_PARAMS *dataBlock)
return AGESA_SUCCESS; return AGESA_SUCCESS;
} }
#endif /* ENV_RAMSTAGE */

View File

@ -17,6 +17,7 @@ config SOUTHBRIDGE_SPECIFIC_OPTIONS
select SOC_AMD_COMMON_BLOCK_ACPIMMIO select SOC_AMD_COMMON_BLOCK_ACPIMMIO
select SOC_AMD_COMMON_BLOCK_ACPIMMIO_BIOSRAM select SOC_AMD_COMMON_BLOCK_ACPIMMIO_BIOSRAM
select SOC_AMD_COMMON_BLOCK_PCI_MMCONF select SOC_AMD_COMMON_BLOCK_PCI_MMCONF
select BOOT_DEVICE_SUPPORTS_WRITES
config EHCI_BAR config EHCI_BAR
hex hex

View File

@ -11,6 +11,7 @@ config SOUTHBRIDGE_AMD_CIMX_SB800
select SOC_AMD_COMMON_BLOCK_ACPIMMIO select SOC_AMD_COMMON_BLOCK_ACPIMMIO
select SOC_AMD_COMMON_BLOCK_ACPIMMIO_BIOSRAM select SOC_AMD_COMMON_BLOCK_ACPIMMIO_BIOSRAM
select SOC_AMD_COMMON_BLOCK_PCI_MMCONF select SOC_AMD_COMMON_BLOCK_PCI_MMCONF
select BOOT_DEVICE_SUPPORTS_WRITES
if SOUTHBRIDGE_AMD_CIMX_SB800 if SOUTHBRIDGE_AMD_CIMX_SB800
config ENABLE_IDE_COMBINED_MODE config ENABLE_IDE_COMBINED_MODE