summaryrefslogtreecommitdiffstats
path: root/resources/libreboot/patch/kgpe-d16/0055-northbridge-amd-amdmct-Verify-MCT-NVRAM-options-befo.patch
blob: 5de148257079d0ae3cba8bf8dacb6a37148439d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
From 1786c1ae0d378df7f2a0f99e13d32df619e0f010 Mon Sep 17 00:00:00 2001
From: Timothy Pearson <kb9vqf@pearsoncomputing.net>
Date: Wed, 10 Jun 2015 10:46:17 -0500
Subject: [PATCH 055/146] northbridge/amd/amdmct: Verify MCT NVRAM options
 before skipping training

---
 src/northbridge/amd/amdmct/mct_ddr3/mct_d.c   |    5 +++-
 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, 43 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 6d8c23e..e493158 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
@@ -4119,7 +4119,7 @@ static void mct_preInitDCT(struct MCTStatStruc *pMCTstat,
 	calculate_and_store_spd_hashes(pMCTstat, pDCTstat);
 
 #if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)
-	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 {
@@ -4134,6 +4134,9 @@ static void mct_preInitDCT(struct MCTStatStruc *pMCTstat,
 	if (get_option(&nvram, "allow_spd_nvram_cache_restore") == CB_SUCCESS)
 		allow_config_restore = !!nvram;
 
+	if (pMCTstat->nvram_checksum != calculate_nvram_mct_hash())
+		allow_config_restore = 0;
+
 	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 4c0e58d..2132648 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