aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBorislav Petkov <borislav.petkov@amd.com>2009-07-28 07:50:43 -0400
committerBorislav Petkov <borislav.petkov@amd.com>2009-09-14 13:01:23 -0400
commit51966241360874e85d1e4d93c9fcdd2ef917b0fb (patch)
treeb060ab062f7ccdbaf14163ba71db095a80b3221f /drivers
parentd93cc222adf3532ddb442648f8db00c15d1dc4c1 (diff)
EDAC, AMD: decode data cache MCEs
Those get reported in MC0_STATUS, see Table 92, F10h BKDG (31116, rev. 3.28) for more details. Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/edac/edac_mce_amd.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index 81f812eb3aea..fe8ccebd9672 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -128,6 +128,49 @@ const char *ext_msgs[] = {
128}; 128};
129EXPORT_SYMBOL_GPL(ext_msgs); 129EXPORT_SYMBOL_GPL(ext_msgs);
130 130
131static void amd_decode_dc_mce(u64 mc0_status)
132{
133 u32 ec = mc0_status & 0xffff;
134 u32 xec = (mc0_status >> 16) & 0xf;
135
136 pr_emerg(" Data Cache Error");
137
138 if (xec == 1 && TLB_ERROR(ec))
139 pr_cont(": %s TLB multimatch.\n", LL_MSG(ec));
140 else if (xec == 0) {
141 if (mc0_status & (1ULL << 40))
142 pr_cont(" during Data Scrub.\n");
143 else if (TLB_ERROR(ec))
144 pr_cont(": %s TLB parity error.\n", LL_MSG(ec));
145 else if (MEM_ERROR(ec)) {
146 u8 ll = ec & 0x3;
147 u8 tt = (ec >> 2) & 0x3;
148 u8 rrrr = (ec >> 4) & 0xf;
149
150 /* see F10h BKDG (31116), Table 92. */
151 if (ll == 0x1) {
152 if (tt != 0x1)
153 goto wrong_dc_mce;
154
155 pr_cont(": Data/Tag %s error.\n", RRRR_MSG(ec));
156
157 } else if (ll == 0x2 && rrrr == 0x3)
158 pr_cont(" during L1 linefill from L2.\n");
159 else
160 goto wrong_dc_mce;
161 } else if (BUS_ERROR(ec) && boot_cpu_data.x86 == 0xf)
162 pr_cont(" during system linefill.\n");
163 else
164 goto wrong_dc_mce;
165 } else
166 goto wrong_dc_mce;
167
168 return;
169
170wrong_dc_mce:
171 pr_warning("Corrupted DC MCE info?\n");
172}
173
131void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors) 174void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
132{ 175{
133 u32 ec = ERROR_CODE(regs->nbsl); 176 u32 ec = ERROR_CODE(regs->nbsl);
@@ -211,9 +254,12 @@ void decode_mce(struct mce *m)
211 254
212 pr_cont("\n"); 255 pr_cont("\n");
213 256
214 amd_decode_err_code(m->status & 0xffff); 257 switch (m->bank) {
258 case 0:
259 amd_decode_dc_mce(m->status);
260 break;
215 261
216 if (m->bank == 4) { 262 case 4:
217 regs.nbsl = (u32) m->status; 263 regs.nbsl = (u32) m->status;
218 regs.nbsh = (u32)(m->status >> 32); 264 regs.nbsh = (u32)(m->status >> 32);
219 regs.nbeal = (u32) m->addr; 265 regs.nbeal = (u32) m->addr;
@@ -221,5 +267,11 @@ void decode_mce(struct mce *m)
221 node = per_cpu(cpu_llc_id, m->extcpu); 267 node = per_cpu(cpu_llc_id, m->extcpu);
222 268
223 amd_decode_nb_mce(node, &regs, 1); 269 amd_decode_nb_mce(node, &regs, 1);
270 break;
271
272 default:
273 break;
224 } 274 }
275
276 amd_decode_err_code(m->status & 0xffff);
225} 277}