Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/44295 )
Change subject: [UNTESTED]cpu/amd/agesa: Use common MRC_CACHE code to save S3 data ......................................................................
[UNTESTED]cpu/amd/agesa: Use common MRC_CACHE code to save S3 data
Most of the code is copied from soc/amd/common/block/s3/s3_resume.c
The current default MRC_CACHE FMAP region is 64K instead of 8K. One could make this configurable in the future.
Change-Id: I0f4f36dcead52a6c550fb5e606772e0a99029872 Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/cpu/amd/agesa/Kconfig M src/cpu/amd/agesa/Makefile.inc M src/drivers/amd/agesa/oem_s3.c 3 files changed, 38 insertions(+), 81 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/95/44295/1
diff --git a/src/cpu/amd/agesa/Kconfig b/src/cpu/amd/agesa/Kconfig index 499cc5b..f407139 100644 --- a/src/cpu/amd/agesa/Kconfig +++ b/src/cpu/amd/agesa/Kconfig @@ -18,6 +18,7 @@ select SMM_ASEG select SSE2 select ACPI_NO_SMI_GNVS + select CACHE_MRC_SETTINGS
if CPU_AMD_AGESA
@@ -53,14 +54,6 @@ Try to restore memory training results from non-volatile memory.
-config S3_DATA_POS - hex - default 0xFFFF0000 - -config S3_DATA_SIZE - int - default 8192 - endif # CPU_AMD_AGESA
source "src/cpu/amd/agesa/family14/Kconfig" diff --git a/src/cpu/amd/agesa/Makefile.inc b/src/cpu/amd/agesa/Makefile.inc index 14067e1..1f9cca5 100644 --- a/src/cpu/amd/agesa/Makefile.inc +++ b/src/cpu/amd/agesa/Makefile.inc @@ -3,18 +3,3 @@ subdirs-$(CONFIG_CPU_AMD_AGESA_FAMILY14) += family14 subdirs-$(CONFIG_CPU_AMD_AGESA_FAMILY15_TN) += family15tn 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 diff --git a/src/drivers/amd/agesa/oem_s3.c b/src/drivers/amd/agesa/oem_s3.c index 0b37d3e..8d32bae 100644 --- a/src/drivers/amd/agesa/oem_s3.c +++ b/src/drivers/amd/agesa/oem_s3.c @@ -1,41 +1,53 @@ /* SPDX-License-Identifier: GPL-2.0-only */
-#include <spi-generic.h> -#include <spi_flash.h> #include <string.h> +#include <device/mmio.h> #include <cbmem.h> #include <console/console.h> +#include <mrc_cache.h> +#include <reset.h> #include <northbridge/amd/agesa/state_machine.h> #include <AGESA.h> #include <northbridge/amd/agesa/agesa_helper.h>
-/* The size needs to be 4k aligned, which is the sector size of most flashes. */ -#define S3_DATA_NONVOLATILE_SIZE 0x1000 +/* Training data versioning is not supported or tracked. */ +#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) +static void __noreturn reboot_from_resume(const char *message) { - /* FIXME: Find file from CBFS. */ - *pos = CONFIG_S3_DATA_POS; - *len= S3_DATA_NONVOLATILE_SIZE; + printk(BIOS_ERR, "%s", message); +// set_pm1cnt_s5(); TODO?? + board_reset(); }
AGESA_STATUS OemInitResume(AMD_S3_PARAMS *dataBlock) { - uintptr_t pos, size; - get_s3nv_data(&pos, &size); + void *base; + size_t size; + int i; + uint32_t erased = 0xffffffff; + struct region_device rdev;
- u32 len = *(u32*)pos; + if (mrc_cache_get_current(MRC_TRAINING_DATA, DEFAULT_MRC_VERSION, + &rdev)) + reboot_from_resume("mrc_cache_get_current error, rebooting.\n");
- /* Test for uninitialized s3nv data in SPI. */ - if (len == 0 || len == (u32)-1ULL) - return AGESA_FATAL; + base = rdev_mmap_full(&rdev); + size = region_device_sz(&rdev); + if (!base || !size) + reboot_from_resume("Error: S3 NV data not found, rebooting.\n");
- dataBlock->NvStorageSize = len; - dataBlock->NvStorage = (void *) (pos + sizeof(u32)); + /* Read 16 bytes to infer if the NV has been erased from flash. */ + for (i = 0; i < 4; i++) + erased &= read32((uint32_t *)base + i); + if (erased == 0xffffffff) + reboot_from_resume("Error: S3 NV data invalid, rebooting.\n"); + + dataBlock->NvStorage = base; + dataBlock->NvStorageSize = size; + printk(BIOS_SPEW, "S3 NV data @%p, 0x%0zx bytes\n", + dataBlock->NvStorage, (size_t)dataBlock->NvStorageSize); + return AGESA_SUCCESS; }
@@ -56,44 +68,13 @@ 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) { - uintptr_t pos, size; - - /* To be consumed in AmdInitResume. */ - get_s3nv_data(&pos, &size); - 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" - ); + if (mrc_cache_stash_data(MRC_TRAINING_DATA, DEFAULT_MRC_VERSION, + dataBlock->NvStorage, dataBlock->NvStorageSize) < 0) { + printk(BIOS_ERR, "Failed to stash MRC data\n"); + return AGESA_CRITICAL; + }
/* To be consumed in AmdS3LateRestore. */ char *heap = cbmem_add(CBMEM_ID_RESUME_SCRATCH, HIGH_MEMORY_SCRATCH); @@ -107,5 +88,3 @@
return AGESA_SUCCESS; } - -#endif /* ENV_RAMSTAGE */