Kyösti Mälkki (kyosti.malkki@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8606
-gerrit
commit d26fa4c610971402c72c1792ac2adc4d0a994017 Author: Kyösti Mälkki kyosti.malkki@gmail.com Date: Tue Dec 16 19:50:47 2014 +0200
AGESA: Refactor OEM S3 storage
Use function prototypes that match more closely with the structure of other OEM hooks in agesawrappers.
Change-Id: Id241fdce78a21a5138ef60ac2f841b694da92241 Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com --- src/cpu/amd/agesa/Makefile.inc | 1 - src/cpu/amd/agesa/s3_resume.c | 89 ++-------------- src/cpu/amd/agesa/s3_resume.h | 15 +-- src/cpu/amd/agesa/spi.c | 49 --------- src/northbridge/amd/agesa/Makefile.inc | 3 + src/northbridge/amd/agesa/agesawrapper.c | 37 ++----- src/northbridge/amd/agesa/agesawrapper.h | 5 + src/northbridge/amd/agesa/oem_s3.c | 170 +++++++++++++++++++++++++++++++ 8 files changed, 198 insertions(+), 171 deletions(-)
diff --git a/src/cpu/amd/agesa/Makefile.inc b/src/cpu/amd/agesa/Makefile.inc index 668efbe..a434381 100644 --- a/src/cpu/amd/agesa/Makefile.inc +++ b/src/cpu/amd/agesa/Makefile.inc @@ -26,7 +26,6 @@ subdirs-$(CONFIG_CPU_AMD_AGESA_FAMILY16_KB) += family16kb
romstage-y += s3_resume.c ramstage-y += s3_resume.c -ramstage-$(CONFIG_SPI_FLASH) += spi.c
cpu_incs += $(src)/cpu/amd/agesa/cache_as_ram.inc
diff --git a/src/cpu/amd/agesa/s3_resume.c b/src/cpu/amd/agesa/s3_resume.c index fc619f7..501e29f 100644 --- a/src/cpu/amd/agesa/s3_resume.c +++ b/src/cpu/amd/agesa/s3_resume.c @@ -34,52 +34,17 @@ #include <northbridge/amd/agesa/BiosCallOuts.h> #include "s3_resume.h"
-/* The size needs to be 4k aligned, which is the sector size of most flashes. */ -#define S3_DATA_VOLATILE_SIZE 0x6000 -#define S3_DATA_MTRR_SIZE 0x1000 -#define S3_DATA_NONVOLATILE_SIZE 0x1000 - -#if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) && \ - (S3_DATA_VOLATILE_SIZE + S3_DATA_MTRR_SIZE + S3_DATA_NONVOLATILE_SIZE) > CONFIG_S3_DATA_SIZE -#error "Please increase the value of S3_DATA_SIZE" -#endif
-static void get_s3nv_data(S3_DATA_TYPE S3DataType, u32 *pos, u32 *len) -{ - /* FIXME: Find file from CBFS. */ - u32 s3_data = CONFIG_S3_DATA_POS; - - switch (S3DataType) { - case S3DataTypeVolatile: - *pos = s3_data; - *len = S3_DATA_VOLATILE_SIZE; - break; - case S3DataTypeMTRR: - *pos = s3_data + S3_DATA_VOLATILE_SIZE; - *len = S3_DATA_MTRR_SIZE; - break; - case S3DataTypeNonVolatile: - *pos = s3_data + S3_DATA_VOLATILE_SIZE + S3_DATA_MTRR_SIZE; - *len = S3_DATA_NONVOLATILE_SIZE; - break; - default: - *pos = 0; - *len = 0; - break; - } -} +#ifndef __PRE_RAM__
void restore_mtrr(void) { + volatile u32 *msrPtr = (u32 *) OemS3Saved_MTRR_Storage(); u32 msr; - volatile UINT32 *msrPtr; msr_t msr_data;
- printk(BIOS_SPEW, "%s\n", __func__); - - u32 pos, size; - get_s3nv_data(S3DataTypeMTRR, &pos, &size); - msrPtr = (UINT32 *)(pos + sizeof(UINT32)); + if (!msrPtr) + return;
disable_cache();
@@ -137,6 +102,8 @@ void restore_mtrr(void) wrmsr(SYS_CFG, msr_data); }
+#endif + #ifdef __PRE_RAM__ static void *backup_resume(void) { @@ -172,9 +139,6 @@ static void move_stack_high_mem(void) #endif
#ifndef __PRE_RAM__ -/* FIXME: Why store MTRR in SPI, just use CBMEM ? */ -static u8 mtrr_store[S3_DATA_MTRR_SIZE]; - static void write_mtrr(u8 **p_nvram_pos, unsigned idx) { msr_t msr_data; @@ -184,13 +148,12 @@ static void write_mtrr(u8 **p_nvram_pos, unsigned idx) *p_nvram_pos += sizeof(msr_data); }
-void OemAgesaSaveMtrr(void) +void backup_mtrr(void *mtrr_store, u32 *mtrr_store_size) { + u8 *nvram_pos = mtrr_store; msr_t msr_data; u32 i;
- u8 *nvram_pos = (u8 *) mtrr_store; - /* Enable access to AMD RdDram and WrDram extension bits */ msr_data = rdmsr(SYS_CFG); msr_data.lo |= SYSCFG_MSR_MtrrFixDramModEn; @@ -220,44 +183,10 @@ void OemAgesaSaveMtrr(void) /* TOM2 */ write_mtrr(&nvram_pos, 0xC001001D);
-#if IS_ENABLED(CONFIG_SPI_FLASH) - u32 pos, size; - get_s3nv_data(S3DataTypeMTRR, &pos, &size); - spi_SaveS3info(pos, size, mtrr_store, nvram_pos - (u8 *) mtrr_store); -#endif -} - -u32 OemAgesaSaveS3Info(S3_DATA_TYPE S3DataType, u32 DataSize, void *Data) -{ -#if IS_ENABLED(CONFIG_SPI_FLASH) - u32 pos, size; - get_s3nv_data(S3DataType, &pos, &size); - spi_SaveS3info(pos, size, Data, DataSize); -#endif - return AGESA_SUCCESS; + *mtrr_store_size = nvram_pos - (u8*) mtrr_store; } #endif
-void OemAgesaGetS3Info(S3_DATA_TYPE S3DataType, u32 *DataSize, void **Data) -{ - AMD_CONFIG_PARAMS StdHeader; - - u32 pos, size; - get_s3nv_data(S3DataType, &pos, &size); - - if (S3DataType == S3DataTypeNonVolatile) { - *DataSize = *(UINT32 *) pos; - *Data = (void *) (pos + sizeof(UINT32)); - } else if (S3DataType == S3DataTypeVolatile) { - u32 len = *(UINT32 *) pos; - void *src = (void *) (pos + sizeof(UINT32)); - void *dst = (void *) GetHeapBase(&StdHeader); - memcpy(dst, src, len); - *DataSize = len; - *Data = dst; - } -} - #ifdef __PRE_RAM__ static void set_resume_cache(void) { diff --git a/src/cpu/amd/agesa/s3_resume.h b/src/cpu/amd/agesa/s3_resume.h index 14984df..df13257 100644 --- a/src/cpu/amd/agesa/s3_resume.h +++ b/src/cpu/amd/agesa/s3_resume.h @@ -20,19 +20,10 @@ #ifndef S3_RESUME_H #define S3_RESUME_H
-typedef enum { - S3DataTypeNonVolatile=0, ///< NonVolatile Data Type - S3DataTypeVolatile, ///< Volatile Data Type - S3DataTypeMTRR ///< MTRR storage -} S3_DATA_TYPE; - void restore_mtrr(void); -void prepare_for_resume(void); +void backup_mtrr(void *mtrr_store, u32 *mtrr_store_size); +const void *OemS3Saved_MTRR_Storage(void);
-u32 OemAgesaSaveS3Info (S3_DATA_TYPE S3DataType, u32 DataSize, void *Data); -void OemAgesaGetS3Info (S3_DATA_TYPE S3DataType, u32 *DataSize, void **Data); -void OemAgesaSaveMtrr (void); - -void spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len); +void prepare_for_resume(void);
#endif diff --git a/src/cpu/amd/agesa/spi.c b/src/cpu/amd/agesa/spi.c deleted file mode 100644 index 1c652fd..0000000 --- a/src/cpu/amd/agesa/spi.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <console/console.h> -#include <spi-generic.h> -#include <spi_flash.h> - -#include "s3_resume.h" - -void spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len) -{ - struct spi_flash *flash; - - spi_init(); - flash = spi_flash_probe(0, 0); - if (!flash) { - printk(BIOS_DEBUG, "Could not find SPI device\n"); - /* Dont make flow stop. */ - return; - } - - flash->spi->rw = SPI_WRITE_FLAG; - spi_claim_bus(flash->spi); - - flash->erase(flash, pos, size); - flash->write(flash, pos, sizeof(len), &len); - flash->write(flash, pos + sizeof(len), len, buf); - - flash->spi->rw = SPI_WRITE_FLAG; - spi_release_bus(flash->spi); - - return; -} diff --git a/src/northbridge/amd/agesa/Makefile.inc b/src/northbridge/amd/agesa/Makefile.inc index 8cf9ae3..04fe26d 100644 --- a/src/northbridge/amd/agesa/Makefile.inc +++ b/src/northbridge/amd/agesa/Makefile.inc @@ -26,3 +26,6 @@ subdirs-$(CONFIG_NORTHBRIDGE_AMD_AGESA_FAMILY16_KB) += family16kb
romstage-y += def_callouts.c agesawrapper.c eventlog.c ramstage-y += def_callouts.c agesawrapper.c eventlog.c + +romstage-y += oem_s3.c +ramstage-y += oem_s3.c diff --git a/src/northbridge/amd/agesa/agesawrapper.c b/src/northbridge/amd/agesa/agesawrapper.c index cd1347d..4f2fcf0 100644 --- a/src/northbridge/amd/agesa/agesawrapper.c +++ b/src/northbridge/amd/agesa/agesawrapper.c @@ -20,7 +20,6 @@ #include <stdint.h> #include <string.h>
-#include <cpu/amd/agesa/s3_resume.h> #include <northbridge/amd/agesa/agesawrapper.h> #include <northbridge/amd/agesa/BiosCallOuts.h> #include "amdlib.h" @@ -125,7 +124,6 @@ AGESA_STATUS agesawrapper_amdinitresume(void) AGESA_STATUS status; AMD_INTERFACE_PARAMS AmdParamStruct; AMD_RESUME_PARAMS *AmdResumeParamsPtr; - S3_DATA_TYPE S3DataType;
memset(&AmdParamStruct, 0, sizeof(AMD_INTERFACE_PARAMS));
@@ -141,13 +139,9 @@ AGESA_STATUS agesawrapper_amdinitresume(void)
AmdResumeParamsPtr->S3DataBlock.NvStorageSize = 0; AmdResumeParamsPtr->S3DataBlock.VolatileStorageSize = 0; - S3DataType = S3DataTypeNonVolatile; + OemInitResume(AmdResumeParamsPtr);
- OemAgesaGetS3Info(S3DataType, - (u32 *) & AmdResumeParamsPtr->S3DataBlock.NvStorageSize, - (void **)&AmdResumeParamsPtr->S3DataBlock.NvStorage); - - status = AmdInitResume((AMD_RESUME_PARAMS *) AmdParamStruct.NewStructPtr); + status = AmdInitResume(AmdResumeParamsPtr);
AGESA_EVENTLOG(status, &AmdParamStruct.StdHeader); AmdReleaseStruct(&AmdParamStruct); @@ -185,7 +179,6 @@ AGESA_STATUS agesawrapper_amds3laterestore(void) AMD_INTERFACE_PARAMS AmdInterfaceParams; AMD_S3LATE_PARAMS AmdS3LateParams; AMD_S3LATE_PARAMS *AmdS3LateParamsPtr; - S3_DATA_TYPE S3DataType;
memset(&AmdS3LateParams, 0, sizeof(AMD_S3LATE_PARAMS));
@@ -199,12 +192,12 @@ AGESA_STATUS agesawrapper_amds3laterestore(void)
AmdCreateStruct(&AmdInterfaceParams);
+#if 0 + /* TODO: What to do with NvStorage here? */ + AmdS3LateParamsPtr->S3DataBlock.NvStorageSize = 0; +#endif AmdS3LateParamsPtr->S3DataBlock.VolatileStorageSize = 0; - S3DataType = S3DataTypeVolatile; - - OemAgesaGetS3Info(S3DataType, - (u32 *) & AmdS3LateParamsPtr->S3DataBlock.VolatileStorageSize, - (void **)&AmdS3LateParamsPtr->S3DataBlock.VolatileStorage); + OemS3LateRestore(AmdS3LateParamsPtr);
status = AmdS3LateRestore(AmdS3LateParamsPtr); AGESA_EVENTLOG(status, &AmdInterfaceParams.StdHeader); @@ -249,7 +242,6 @@ AGESA_STATUS agesawrapper_amdS3Save(void) AGESA_STATUS status; AMD_S3SAVE_PARAMS *AmdS3SaveParamsPtr; AMD_INTERFACE_PARAMS AmdInterfaceParams; - S3_DATA_TYPE S3DataType;
memset(&AmdInterfaceParams, 0, sizeof(AMD_INTERFACE_PARAMS));
@@ -269,21 +261,8 @@ AGESA_STATUS agesawrapper_amdS3Save(void) AGESA_EVENTLOG(status, &AmdInterfaceParams.StdHeader); ASSERT(status == AGESA_SUCCESS);
- S3DataType = S3DataTypeNonVolatile; - - status = OemAgesaSaveS3Info(S3DataType, - AmdS3SaveParamsPtr->S3DataBlock.NvStorageSize, - AmdS3SaveParamsPtr->S3DataBlock.NvStorage); - - if (AmdS3SaveParamsPtr->S3DataBlock.VolatileStorageSize != 0) { - S3DataType = S3DataTypeVolatile; - - status = OemAgesaSaveS3Info(S3DataType, - AmdS3SaveParamsPtr->S3DataBlock.VolatileStorageSize, - AmdS3SaveParamsPtr->S3DataBlock.VolatileStorage); - } + OemS3Save(AmdS3SaveParamsPtr);
- OemAgesaSaveMtrr(); AmdReleaseStruct(&AmdInterfaceParams);
return status; diff --git a/src/northbridge/amd/agesa/agesawrapper.h b/src/northbridge/amd/agesa/agesawrapper.h index 09cb07d..2050f7f 100644 --- a/src/northbridge/amd/agesa/agesawrapper.h +++ b/src/northbridge/amd/agesa/agesawrapper.h @@ -71,4 +71,9 @@ struct OEM_HOOK
extern const struct OEM_HOOK OemCustomize;
+/* For suspend-to-ram support. */ +AGESA_STATUS OemInitResume(AMD_RESUME_PARAMS *ResumeParams); +AGESA_STATUS OemS3LateRestore(AMD_S3LATE_PARAMS *S3LateParams); +AGESA_STATUS OemS3Save(AMD_S3SAVE_PARAMS *S3SaveParams); + #endif /* _AGESAWRAPPER_H_ */ diff --git a/src/northbridge/amd/agesa/oem_s3.c b/src/northbridge/amd/agesa/oem_s3.c new file mode 100644 index 0000000..6c3168c --- /dev/null +++ b/src/northbridge/amd/agesa/oem_s3.c @@ -0,0 +1,170 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <AGESA.h> +#include <spi-generic.h> +#include <spi_flash.h> +#include <string.h> +#include <cpu/amd/agesa/s3_resume.h> +#include <northbridge/amd/agesa/BiosCallOuts.h> +#include <northbridge/amd/agesa/agesawrapper.h> + +typedef enum { + S3DataTypeNonVolatile=0, ///< NonVolatile Data Type + S3DataTypeVolatile, ///< Volatile Data Type + S3DataTypeMTRR ///< MTRR storage +} S3_DATA_TYPE; + +/* The size needs to be 4k aligned, which is the sector size of most flashes. */ +#define S3_DATA_VOLATILE_SIZE 0x6000 +#define S3_DATA_MTRR_SIZE 0x1000 +#define S3_DATA_NONVOLATILE_SIZE 0x1000 + +#if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) && \ + (S3_DATA_VOLATILE_SIZE + S3_DATA_MTRR_SIZE + S3_DATA_NONVOLATILE_SIZE) > CONFIG_S3_DATA_SIZE +#error "Please increase the value of S3_DATA_SIZE" +#endif + +static void get_s3nv_data(S3_DATA_TYPE S3DataType, u32 *pos, u32 *len) +{ + /* FIXME: Find file from CBFS. */ + u32 s3_data = CONFIG_S3_DATA_POS; + + switch (S3DataType) { + case S3DataTypeVolatile: + *pos = s3_data; + *len = S3_DATA_VOLATILE_SIZE; + break; + case S3DataTypeMTRR: + *pos = s3_data + S3_DATA_VOLATILE_SIZE; + *len = S3_DATA_MTRR_SIZE; + break; + case S3DataTypeNonVolatile: + *pos = s3_data + S3_DATA_VOLATILE_SIZE + S3_DATA_MTRR_SIZE; + *len = S3_DATA_NONVOLATILE_SIZE; + break; + default: + *pos = 0; + *len = 0; + break; + } +} + +#if defined(__PRE_RAM__) + +AGESA_STATUS OemInitResume(AMD_RESUME_PARAMS *ResumeParams) +{ + AMD_S3_PARAMS *dataBlock = &ResumeParams->S3DataBlock; + u32 pos, size; + + get_s3nv_data(S3DataTypeNonVolatile, &pos, &size); + + /* TODO: Our NvStorage is really const. */ + dataBlock->NvStorageSize = *(UINT32 *) pos; + dataBlock->NvStorage = (void *) (pos + sizeof(UINT32)); + return AGESA_SUCCESS; +} + +AGESA_STATUS OemS3LateRestore(AMD_S3LATE_PARAMS *S3LateParams) +{ + AMD_S3_PARAMS *dataBlock = &S3LateParams->S3DataBlock; + AMD_CONFIG_PARAMS StdHeader; + u32 pos, size; + + get_s3nv_data(S3DataTypeVolatile, &pos, &size); + + u32 len = *(UINT32 *) pos; + void *src = (void *) (pos + sizeof(UINT32)); + void *dst = (void *) GetHeapBase(&StdHeader); + + memcpy(dst, src, len); + dataBlock->VolatileStorageSize = len; + dataBlock->VolatileStorage = dst; + return AGESA_SUCCESS; +} + +#else + +static int spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len) +{ +#if IS_ENABLED(CONFIG_SPI_FLASH) + struct spi_flash *flash; + + spi_init(); + flash = spi_flash_probe(0, 0); + if (!flash) + return -1; + + flash->spi->rw = SPI_WRITE_FLAG; + spi_claim_bus(flash->spi); + + flash->erase(flash, pos, size); + flash->write(flash, pos, sizeof(len), &len); + flash->write(flash, pos + sizeof(len), len, buf); + + flash->spi->rw = SPI_WRITE_FLAG; + spi_release_bus(flash->spi); + return 0; +#else + return -1; +#endif +} + +AGESA_STATUS OemS3Save(AMD_S3SAVE_PARAMS *S3SaveParams) +{ + AMD_S3_PARAMS *dataBlock = &S3SaveParams->S3DataBlock; + u8 MTRRStorage[S3_DATA_MTRR_SIZE]; + u32 MTRRStorageSize = 0; + u32 pos, size; + + /* To be consumed in AmdInitResume. */ + get_s3nv_data(S3DataTypeNonVolatile, &pos, &size); + if (size && dataBlock->NvStorageSize) + spi_SaveS3info(pos, size, dataBlock->NvStorage, + dataBlock->NvStorageSize); + + /* To be consumed in AmdS3LateRestore. */ + get_s3nv_data(S3DataTypeVolatile, &pos, &size); + if (size && dataBlock->VolatileStorageSize) + spi_SaveS3info(pos, size, dataBlock->VolatileStorage, + dataBlock->VolatileStorageSize); + + /* Collect MTRR setup. */ + backup_mtrr(MTRRStorage, &MTRRStorageSize); + + /* To be consumed in restore_mtrr, CPU enumeration in ramstage. */ + get_s3nv_data(S3DataTypeMTRR, &pos, &size); + if (size && MTRRStorageSize) + spi_SaveS3info(pos, size, MTRRStorage, MTRRStorageSize); + + return AGESA_SUCCESS; +} + +const void *OemS3Saved_MTRR_Storage(void) +{ + u32 pos, size; + get_s3nv_data(S3DataTypeMTRR, &pos, &size); + if (!size) + return NULL; + + return (void*)(pos + sizeof(UINT32)); +} + +#endif +