summaryrefslogtreecommitdiffstats
path: root/resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0054-northbridge-amd-amdmct-Verify-MCT-NVRAM-options-befo.patch
blob: b7eead19ffc36cdcbd03a97d411613ef66748f7b (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
144
145
146
147
148
149
From fdb1ff9b466c0fb32c019ceeeeefb23e857cf00e Mon Sep 17 00:00:00 2001
From: Timothy Pearson <tpearson@raptorengineeringinc.com>
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 <tpearson@raptorengineeringinc.com>
---
 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