From fdb1ff9b466c0fb32c019ceeeeefb23e857cf00e Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Wed, 10 Jun 2015 10:46:17 -0500 Subject: [PATCH 054/143] northbridge/amd/amdmct: Verify MCT NVRAM options before skipping training Change-Id: If26e5d148a906d63bd1407b8ffa58f08ae6b4275 Signed-off-by: Timothy Pearson --- src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 9 ++++++- src/northbridge/amd/amdmct/mct_ddr3/mct_d.h | 2 ++ src/northbridge/amd/amdmct/mct_ddr3/s3utils.c | 36 ++++++++++++++++++++++++- src/northbridge/amd/amdmct/mct_ddr3/s3utils.h | 3 ++- 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c index 3edce9e..4d7e5aa 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c @@ -4126,7 +4126,7 @@ static void mct_preInitDCT(struct MCTStatStruc *pMCTstat, #if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) calculate_and_store_spd_hashes(pMCTstat, pDCTstat); - if (load_spd_hashes_from_nvram(pDCTstat) < 0) { + if (load_spd_hashes_from_nvram(pMCTstat, pDCTstat) < 0) { pDCTstat->spd_data.nvram_spd_match = 0; } else { @@ -4141,6 +4141,13 @@ static void mct_preInitDCT(struct MCTStatStruc *pMCTstat, if (get_option(&nvram, "allow_spd_nvram_cache_restore") == CB_SUCCESS) allow_config_restore = !!nvram; +#if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) + if (pMCTstat->nvram_checksum != calculate_nvram_mct_hash()) + allow_config_restore = 0; +#else + allow_config_restore = 0; +#endif + if (!allow_config_restore) pDCTstat->spd_data.nvram_spd_match = 0; } diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h index adf89b2..11555ae 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h @@ -301,6 +301,7 @@ struct MCTStatStruc { u32 Sub4GCacheTop; /* If not zero, the 32-bit top of cacheable memory.*/ u32 SysLimit; /* LIMIT[39:8] (system address)*/ uint32_t TSCFreq; + uint16_t nvram_checksum; } __attribute__((packed)); /*============================================================================= @@ -796,6 +797,7 @@ struct amd_s3_persistent_node_data { struct amd_s3_persistent_data { struct amd_s3_persistent_node_data node[MAX_NODES_SUPPORTED]; + uint16_t nvram_checksum; } __attribute__((packed)); /*=============================================================================== diff --git a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c index 1e5c1a0..fe89af1 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c @@ -143,6 +143,36 @@ void calculate_spd_hash(uint8_t *spd_data, uint64_t *spd_hash) *spd_hash = *spd_hash ^ (*spd_hash << 37); } +uint16_t calculate_nvram_mct_hash(void) +{ + uint32_t nvram; + uint16_t ret; + + ret = 0; + if (get_option(&nvram, "max_mem_clock") == CB_SUCCESS) + ret |= nvram & 0xf; + if (get_option(&nvram, "minimum_memory_voltage") == CB_SUCCESS) + ret |= (nvram & 0x3) << 4; + if (get_option(&nvram, "ECC_memory") == CB_SUCCESS) + ret |= (nvram & 0x1) << 6; + if (get_option(&nvram, "ECC_redirection") == CB_SUCCESS) + ret |= (nvram & 0x1) << 7; + if (get_option(&nvram, "ecc_scrub_rate") == CB_SUCCESS) + ret |= (nvram & 0x1) << 8; + if (get_option(&nvram, "interleave_chip_selects") == CB_SUCCESS) + ret |= (nvram & 0x1) << 9; + if (get_option(&nvram, "interleave_nodes") == CB_SUCCESS) + ret |= (nvram & 0x1) << 10; + if (get_option(&nvram, "interleave_memory_channels") == CB_SUCCESS) + ret |= (nvram & 0x1) << 11; + if (get_option(&nvram, "cpu_c_states") == CB_SUCCESS) + ret |= (nvram & 0x1) << 12; + if (get_option(&nvram, "cpu_cc6_state") == CB_SUCCESS) + ret |= (nvram & 0x1) << 13; + + return ret; +} + static struct amd_s3_persistent_data * map_s3nv_in_nvram(void) { ssize_t s3nv_offset; @@ -173,7 +203,7 @@ static struct amd_s3_persistent_data * map_s3nv_in_nvram(void) } #ifdef __PRE_RAM__ -int8_t load_spd_hashes_from_nvram(struct DCTStatStruc *pDCTstat) +int8_t load_spd_hashes_from_nvram(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat) { struct amd_s3_persistent_data *persistent_data; @@ -184,6 +214,8 @@ int8_t load_spd_hashes_from_nvram(struct DCTStatStruc *pDCTstat) memcpy(pDCTstat->spd_data.nvram_spd_hash, persistent_data->node[pDCTstat->Node_ID].spd_hash, sizeof(pDCTstat->spd_data.nvram_spd_hash)); memcpy(pDCTstat->spd_data.nvram_memclk, persistent_data->node[pDCTstat->Node_ID].memclk, sizeof(pDCTstat->spd_data.nvram_memclk)); + pMCTstat->nvram_checksum = persistent_data->nvram_checksum; + return 0; } #endif @@ -237,6 +269,8 @@ static void copy_cbmem_spd_data_to_save_variable(struct amd_s3_persistent_data* for (channel = 0; channel < 2; channel++) persistent_data->node[node].memclk[channel] = mem_info->dct_stat[node].Speed; + persistent_data->nvram_checksum = calculate_nvram_mct_hash(); + if (restored) { if (mem_info->mct_stat.GStatus & (1 << GSB_ConfigRestored)) *restored = 1; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.h b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.h index 82f73a7..74922c4 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.h +++ b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.h @@ -21,9 +21,10 @@ #include "mct_d.h" void calculate_spd_hash(uint8_t *spd_data, uint64_t *spd_hash); +uint16_t calculate_nvram_mct_hash(void); #ifdef __PRE_RAM__ -int8_t load_spd_hashes_from_nvram(struct DCTStatStruc *pDCTstat); +int8_t load_spd_hashes_from_nvram(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); #endif #ifdef __RAMSTAGE__ -- 1.7.9.5