aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBorislav Petkov <borislav.petkov@amd.com>2010-08-26 13:05:49 -0400
committerBorislav Petkov <bp@amd64.org>2010-10-21 08:48:01 -0400
commitdd53bce4e8987f6848840d42bbeead5221eff308 (patch)
tree0aa19cb96710be5c5f978b513a231e85590f6f60 /drivers
parent888ab8e6eb2e41179cdc8edf5d0abd1cce0f0370 (diff)
EDAC, MCE: Adjust IC decoders to F14h
Add support for IC MCEs for F14h CPUs. K8 and F10h are almost identical so use one function for both. Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/edac/mce_amd.c118
-rw-r--r--drivers/edac/mce_amd.h1
2 files changed, 71 insertions, 48 deletions
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index 33985aa61356..60d5d9f4dfee 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -219,61 +219,80 @@ wrong_dc_mce:
219 pr_emerg(HW_ERR "Corrupted DC MCE info?\n"); 219 pr_emerg(HW_ERR "Corrupted DC MCE info?\n");
220} 220}
221 221
222static void amd_decode_ic_mce(struct mce *m) 222static bool k8_ic_mce(u16 ec)
223{ 223{
224 u32 ec = m->status & 0xffff; 224 u8 ll = ec & 0x3;
225 u32 xec = (m->status >> 16) & 0xf; 225 u8 r4 = (ec >> 4) & 0xf;
226 bool ret = true;
226 227
227 pr_emerg(HW_ERR "Instruction Cache Error"); 228 if (!MEM_ERROR(ec))
229 return false;
228 230
229 if (xec == 1 && TLB_ERROR(ec)) 231 if (ll == 0x2)
230 pr_cont(": %s TLB multimatch.\n", LL_MSG(ec)); 232 pr_cont("during a linefill from L2.\n");
231 else if (xec == 0) { 233 else if (ll == 0x1) {
232 if (TLB_ERROR(ec)) 234 switch (r4) {
233 pr_cont(": %s TLB Parity error.\n", LL_MSG(ec)); 235 case R4_IRD:
234 else if (BUS_ERROR(ec)) { 236 pr_cont("Parity error during data load.\n");
235 if (boot_cpu_data.x86 == 0xf && 237 break;
236 (m->status & BIT(58)))
237 pr_cont(" during system linefill.\n");
238 else
239 pr_cont(" during attempted NB data read.\n");
240 } else if (MEM_ERROR(ec)) {
241 u8 ll = ec & 0x3;
242 u8 rrrr = (ec >> 4) & 0xf;
243 238
244 if (ll == 0x2) 239 case R4_EVICT:
245 pr_cont(" during a linefill from L2.\n"); 240 pr_cont("Copyback Parity/Victim error.\n");
246 else if (ll == 0x1) { 241 break;
247 242
248 switch (rrrr) { 243 case R4_SNOOP:
249 case 0x5: 244 pr_cont("Tag Snoop error.\n");
250 pr_cont(": Parity error during " 245 break;
251 "data load.\n"); 246
252 break; 247 default:
253 248 ret = false;
254 case 0x7: 249 break;
255 pr_cont(": Copyback Parity/Victim" 250 }
256 " error.\n");
257 break;
258
259 case 0x8:
260 pr_cont(": Tag Snoop error.\n");
261 break;
262
263 default:
264 goto wrong_ic_mce;
265 break;
266 }
267 }
268 } else
269 goto wrong_ic_mce;
270 } else 251 } else
271 goto wrong_ic_mce; 252 ret = false;
272 253
273 return; 254 return ret;
255}
256
257static bool f14h_ic_mce(u16 ec)
258{
259 u8 ll = ec & 0x3;
260 u8 tt = (ec >> 2) & 0x3;
261 u8 r4 = (ec >> 4) & 0xf;
262 bool ret = true;
274 263
275wrong_ic_mce: 264 if (MEM_ERROR(ec)) {
276 pr_emerg(HW_ERR "Corrupted IC MCE info?\n"); 265 if (tt != 0 || ll != 1)
266 ret = false;
267
268 if (r4 == R4_IRD)
269 pr_cont("Data/tag array parity error for a tag hit.\n");
270 else if (r4 == R4_SNOOP)
271 pr_cont("Tag error during snoop/victimization.\n");
272 else
273 ret = false;
274 }
275 return ret;
276}
277
278static void amd_decode_ic_mce(struct mce *m)
279{
280 u16 ec = m->status & 0xffff;
281 u8 xec = (m->status >> 16) & 0xf;
282
283 pr_emerg(HW_ERR "Instruction Cache Error: ");
284
285 if (TLB_ERROR(ec))
286 pr_cont("%s TLB %s.\n", LL_MSG(ec),
287 (xec ? "multimatch" : "parity error"));
288 else if (BUS_ERROR(ec)) {
289 bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT(58)));
290
291 pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
292 } else if (fam_ops->ic_mce(ec))
293 ;
294 else
295 pr_emerg(HW_ERR "Corrupted IC MCE info?\n");
277} 296}
278 297
279static void amd_decode_bu_mce(struct mce *m) 298static void amd_decode_bu_mce(struct mce *m)
@@ -481,14 +500,17 @@ static int __init mce_amd_init(void)
481 switch (boot_cpu_data.x86) { 500 switch (boot_cpu_data.x86) {
482 case 0xf: 501 case 0xf:
483 fam_ops->dc_mce = k8_dc_mce; 502 fam_ops->dc_mce = k8_dc_mce;
503 fam_ops->ic_mce = k8_ic_mce;
484 break; 504 break;
485 505
486 case 0x10: 506 case 0x10:
487 fam_ops->dc_mce = f10h_dc_mce; 507 fam_ops->dc_mce = f10h_dc_mce;
508 fam_ops->ic_mce = k8_ic_mce;
488 break; 509 break;
489 510
490 case 0x14: 511 case 0x14:
491 fam_ops->dc_mce = f14h_dc_mce; 512 fam_ops->dc_mce = f14h_dc_mce;
513 fam_ops->ic_mce = f14h_ic_mce;
492 break; 514 break;
493 515
494 default: 516 default:
diff --git a/drivers/edac/mce_amd.h b/drivers/edac/mce_amd.h
index 85985c225442..dc81dba9364b 100644
--- a/drivers/edac/mce_amd.h
+++ b/drivers/edac/mce_amd.h
@@ -101,6 +101,7 @@ struct err_regs {
101 */ 101 */
102struct amd_decoder_ops { 102struct amd_decoder_ops {
103 bool (*dc_mce)(u16); 103 bool (*dc_mce)(u16);
104 bool (*ic_mce)(u16);
104}; 105};
105 106
106void amd_report_gart_errors(bool); 107void amd_report_gart_errors(bool);