diff --git a/src/cpu/amd/agesa/s3_resume.c b/src/cpu/amd/agesa/s3_resume.c index 2ba684650a..9789cc402e 100644 --- a/src/cpu/amd/agesa/s3_resume.c +++ b/src/cpu/amd/agesa/s3_resume.c @@ -34,18 +34,16 @@ #include #include "s3_resume.h" +#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(); @@ -103,6 +101,8 @@ void restore_mtrr(void) wrmsr(SYS_CFG, msr_data); } +#endif + #ifdef __PRE_RAM__ static void *backup_resume(void) { @@ -138,10 +138,6 @@ static void move_stack_high_mem(void) #endif #ifndef __PRE_RAM__ -/* FIXME: Why store MTRR in SPI, just use CBMEM ? */ -#define S3_DATA_MTRR_SIZE 0x1000 -static u8 mtrr_store[S3_DATA_MTRR_SIZE]; - static void write_mtrr(u8 **p_nvram_pos, unsigned idx) { msr_t msr_data; @@ -151,13 +147,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; @@ -187,44 +182,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 79f6f1bac4..ce16f7dccf 100644 --- a/src/cpu/amd/agesa/s3_resume.h +++ b/src/cpu/amd/agesa/s3_resume.h @@ -20,20 +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); -u32 OemAgesaSaveS3Info (S3_DATA_TYPE S3DataType, u32 DataSize, void *Data); -void OemAgesaGetS3Info (S3_DATA_TYPE S3DataType, u32 *DataSize, void **Data); -void OemAgesaSaveMtrr (void); - -void get_s3nv_data(S3_DATA_TYPE S3DataType, u32 *pos, u32 *len); -int spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len); +void backup_mtrr(void *mtrr_store, u32 *mtrr_store_size); +const void *OemS3Saved_MTRR_Storage(void); #endif diff --git a/src/northbridge/amd/agesa/agesawrapper.c b/src/northbridge/amd/agesa/agesawrapper.c index 82088ac363..8ad36c7df2 100644 --- a/src/northbridge/amd/agesa/agesawrapper.c +++ b/src/northbridge/amd/agesa/agesawrapper.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #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; + OemS3Save(AmdS3SaveParamsPtr); - 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); - } - - OemAgesaSaveMtrr(); AmdReleaseStruct(&AmdInterfaceParams); return status; diff --git a/src/northbridge/amd/agesa/agesawrapper.h b/src/northbridge/amd/agesa/agesawrapper.h index 9ec6b75fe5..eb1a59cda5 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 index c196be2abd..08f68e58b4 100644 --- a/src/northbridge/amd/agesa/oem_s3.c +++ b/src/northbridge/amd/agesa/oem_s3.c @@ -21,6 +21,15 @@ #include #include #include +#include +#include +#include + +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 @@ -32,7 +41,7 @@ #error "Please increase the value of S3_DATA_SIZE" #endif -void get_s3nv_data(S3_DATA_TYPE S3DataType, u32 *pos, u32 *len) +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; @@ -57,7 +66,42 @@ void get_s3nv_data(S3_DATA_TYPE S3DataType, u32 *pos, u32 *len) } } -int spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len) +#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; @@ -81,3 +125,45 @@ int spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len) 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