EDAC, MCE: Add an F15h NB MCE decoder
[deliverable/linux.git] / drivers / edac / mce_amd.c
CommitLineData
b70ef010 1#include <linux/module.h>
888ab8e6
BP
2#include <linux/slab.h>
3
47ca08a4 4#include "mce_amd.h"
b52401ce 5
888ab8e6
BP
6static struct amd_decoder_ops *fam_ops;
7
2be64bfa 8static u8 xec_mask = 0xf;
5ce88f6e
BP
9static u8 nb_err_cpumask = 0xf;
10
549d042d 11static bool report_gart_errors;
7cfd4a87 12static void (*nb_bus_decoder)(int node_id, struct mce *m, u32 nbcfg);
549d042d
BP
13
14void amd_report_gart_errors(bool v)
15{
16 report_gart_errors = v;
17}
18EXPORT_SYMBOL_GPL(amd_report_gart_errors);
19
7cfd4a87 20void amd_register_ecc_decoder(void (*f)(int, struct mce *, u32))
549d042d
BP
21{
22 nb_bus_decoder = f;
23}
24EXPORT_SYMBOL_GPL(amd_register_ecc_decoder);
25
7cfd4a87 26void amd_unregister_ecc_decoder(void (*f)(int, struct mce *, u32))
549d042d
BP
27{
28 if (nb_bus_decoder) {
29 WARN_ON(nb_bus_decoder != f);
30
31 nb_bus_decoder = NULL;
32 }
33}
34EXPORT_SYMBOL_GPL(amd_unregister_ecc_decoder);
35
b52401ce
DT
36/*
37 * string representation for the different MCA reported error types, see F3x48
38 * or MSR0000_0411.
39 */
6337583d
BP
40
41/* transaction type */
42const char *tt_msgs[] = { "INSN", "DATA", "GEN", "RESV" };
b70ef010 43EXPORT_SYMBOL_GPL(tt_msgs);
b52401ce 44
6337583d
BP
45/* cache level */
46const char *ll_msgs[] = { "RESV", "L1", "L2", "L3/GEN" };
b70ef010 47EXPORT_SYMBOL_GPL(ll_msgs);
b52401ce 48
6337583d 49/* memory transaction type */
b52401ce 50const char *rrrr_msgs[] = {
6337583d 51 "GEN", "RD", "WR", "DRD", "DWR", "IRD", "PRF", "EV", "SNP"
b52401ce 52};
b70ef010 53EXPORT_SYMBOL_GPL(rrrr_msgs);
b52401ce 54
6337583d
BP
55/* participating processor */
56const char *pp_msgs[] = { "SRC", "RES", "OBS", "GEN" };
b70ef010 57EXPORT_SYMBOL_GPL(pp_msgs);
b52401ce 58
6337583d
BP
59/* request timeout */
60const char *to_msgs[] = { "no timeout", "timed out" };
b70ef010 61EXPORT_SYMBOL_GPL(to_msgs);
b52401ce 62
6337583d
BP
63/* memory or i/o */
64const char *ii_msgs[] = { "MEM", "RESV", "IO", "GEN" };
b70ef010 65EXPORT_SYMBOL_GPL(ii_msgs);
b52401ce 66
5ce88f6e
BP
67static const char *f10h_nb_mce_desc[] = {
68 "HT link data error",
69 "Protocol error (link, L3, probe filter, etc.)",
70 "Parity error in NB-internal arrays",
71 "Link Retry due to IO link transmission error",
72 "L3 ECC data cache error",
73 "ECC error in L3 cache tag",
74 "L3 LRU parity bits error",
75 "ECC Error in the Probe Filter directory"
b52401ce 76};
549d042d 77
86039cd4
BP
78static const char * const f15h_ic_mce_desc[] = {
79 "UC during a demand linefill from L2",
80 "Parity error during data load from IC",
81 "Parity error for IC valid bit",
82 "Main tag parity error",
83 "Parity error in prediction queue",
84 "PFB data/address parity error",
85 "Parity error in the branch status reg",
86 "PFB promotion address error",
87 "Tag error during probe/victimization",
88 "Parity error for IC probe tag valid bit",
89 "PFB non-cacheable bit parity error",
90 "PFB valid bit parity error", /* xec = 0xd */
91 "patch RAM", /* xec = 010 */
92 "uop queue",
93 "insn buffer",
94 "predecode buffer",
95 "fetch address FIFO"
96};
97
70fdb494
BP
98static const char * const f15h_cu_mce_desc[] = {
99 "Fill ECC error on data fills", /* xec = 0x4 */
100 "Fill parity error on insn fills",
101 "Prefetcher request FIFO parity error",
102 "PRQ address parity error",
103 "PRQ data parity error",
104 "WCC Tag ECC error",
105 "WCC Data ECC error",
106 "WCB Data parity error",
107 "VB Data/ECC error",
108 "L2 Tag ECC error", /* xec = 0x10 */
109 "Hard L2 Tag ECC error",
110 "Multiple hits on L2 tag",
111 "XAB parity error",
112 "PRB address parity error"
113};
114
25a4f8b0 115static bool f12h_dc_mce(u16 ec, u8 xec)
51966241 116{
888ab8e6 117 bool ret = false;
51966241 118
888ab8e6
BP
119 if (MEM_ERROR(ec)) {
120 u8 ll = ec & 0x3;
121 ret = true;
51966241 122
888ab8e6
BP
123 if (ll == LL_L2)
124 pr_cont("during L1 linefill from L2.\n");
125 else if (ll == LL_L1)
126 pr_cont("Data/Tag %s error.\n", RRRR_MSG(ec));
127 else
128 ret = false;
129 }
130 return ret;
131}
51966241 132
25a4f8b0 133static bool f10h_dc_mce(u16 ec, u8 xec)
9be0bb10
BP
134{
135 u8 r4 = (ec >> 4) & 0xf;
136 u8 ll = ec & 0x3;
137
138 if (r4 == R4_GEN && ll == LL_L1) {
139 pr_cont("during data scrub.\n");
140 return true;
141 }
25a4f8b0 142 return f12h_dc_mce(ec, xec);
9be0bb10
BP
143}
144
25a4f8b0 145static bool k8_dc_mce(u16 ec, u8 xec)
888ab8e6
BP
146{
147 if (BUS_ERROR(ec)) {
148 pr_cont("during system linefill.\n");
149 return true;
150 }
51966241 151
25a4f8b0 152 return f10h_dc_mce(ec, xec);
888ab8e6
BP
153}
154
25a4f8b0 155static bool f14h_dc_mce(u16 ec, u8 xec)
888ab8e6
BP
156{
157 u8 r4 = (ec >> 4) & 0xf;
158 u8 ll = ec & 0x3;
159 u8 tt = (ec >> 2) & 0x3;
160 u8 ii = tt;
161 bool ret = true;
162
163 if (MEM_ERROR(ec)) {
164
165 if (tt != TT_DATA || ll != LL_L1)
166 return false;
167
168 switch (r4) {
169 case R4_DRD:
170 case R4_DWR:
171 pr_cont("Data/Tag parity error due to %s.\n",
172 (r4 == R4_DRD ? "load/hw prf" : "store"));
173 break;
174 case R4_EVICT:
175 pr_cont("Copyback parity error on a tag miss.\n");
176 break;
177 case R4_SNOOP:
178 pr_cont("Tag parity error during snoop.\n");
179 break;
180 default:
181 ret = false;
182 }
183 } else if (BUS_ERROR(ec)) {
184
185 if ((ii != II_MEM && ii != II_IO) || ll != LL_LG)
186 return false;
187
188 pr_cont("System read data error on a ");
189
190 switch (r4) {
191 case R4_RD:
192 pr_cont("TLB reload.\n");
193 break;
194 case R4_DWR:
195 pr_cont("store.\n");
196 break;
197 case R4_DRD:
198 pr_cont("load.\n");
199 break;
200 default:
201 ret = false;
202 }
203 } else {
204 ret = false;
205 }
206
207 return ret;
208}
209
25a4f8b0
BP
210static bool f15h_dc_mce(u16 ec, u8 xec)
211{
212 bool ret = true;
213
214 if (MEM_ERROR(ec)) {
215
216 switch (xec) {
217 case 0x0:
218 pr_cont("Data Array access error.\n");
219 break;
220
221 case 0x1:
222 pr_cont("UC error during a linefill from L2/NB.\n");
223 break;
224
225 case 0x2:
226 case 0x11:
227 pr_cont("STQ access error.\n");
228 break;
229
230 case 0x3:
231 pr_cont("SCB access error.\n");
232 break;
233
234 case 0x10:
235 pr_cont("Tag error.\n");
236 break;
237
238 case 0x12:
239 pr_cont("LDQ access error.\n");
240 break;
241
242 default:
243 ret = false;
244 }
245 } else if (BUS_ERROR(ec)) {
246
247 if (!xec)
248 pr_cont("during system linefill.\n");
249 else
250 pr_cont(" Internal %s condition.\n",
251 ((xec == 1) ? "livelock" : "deadlock"));
252 } else
253 ret = false;
254
255 return ret;
256}
257
888ab8e6
BP
258static void amd_decode_dc_mce(struct mce *m)
259{
260 u16 ec = m->status & 0xffff;
2be64bfa 261 u8 xec = (m->status >> 16) & xec_mask;
888ab8e6
BP
262
263 pr_emerg(HW_ERR "Data Cache Error: ");
264
265 /* TLB error signatures are the same across families */
266 if (TLB_ERROR(ec)) {
267 u8 tt = (ec >> 2) & 0x3;
268
269 if (tt == TT_DATA) {
270 pr_cont("%s TLB %s.\n", LL_MSG(ec),
25a4f8b0
BP
271 ((xec == 2) ? "locked miss"
272 : (xec ? "multimatch" : "parity")));
888ab8e6
BP
273 return;
274 }
25a4f8b0
BP
275 } else if (fam_ops->dc_mce(ec, xec))
276 ;
277 else
278 pr_emerg(HW_ERR "Corrupted DC MCE info?\n");
51966241
BP
279}
280
86039cd4 281static bool k8_ic_mce(u16 ec, u8 xec)
ab5535e7 282{
dd53bce4
BP
283 u8 ll = ec & 0x3;
284 u8 r4 = (ec >> 4) & 0xf;
285 bool ret = true;
ab5535e7 286
dd53bce4
BP
287 if (!MEM_ERROR(ec))
288 return false;
ab5535e7 289
dd53bce4
BP
290 if (ll == 0x2)
291 pr_cont("during a linefill from L2.\n");
292 else if (ll == 0x1) {
293 switch (r4) {
294 case R4_IRD:
295 pr_cont("Parity error during data load.\n");
296 break;
ab5535e7 297
dd53bce4
BP
298 case R4_EVICT:
299 pr_cont("Copyback Parity/Victim error.\n");
300 break;
301
302 case R4_SNOOP:
303 pr_cont("Tag Snoop error.\n");
304 break;
305
306 default:
307 ret = false;
308 break;
309 }
ab5535e7 310 } else
dd53bce4 311 ret = false;
ab5535e7 312
dd53bce4
BP
313 return ret;
314}
315
86039cd4 316static bool f14h_ic_mce(u16 ec, u8 xec)
dd53bce4
BP
317{
318 u8 ll = ec & 0x3;
319 u8 tt = (ec >> 2) & 0x3;
320 u8 r4 = (ec >> 4) & 0xf;
321 bool ret = true;
ab5535e7 322
dd53bce4
BP
323 if (MEM_ERROR(ec)) {
324 if (tt != 0 || ll != 1)
325 ret = false;
326
327 if (r4 == R4_IRD)
328 pr_cont("Data/tag array parity error for a tag hit.\n");
329 else if (r4 == R4_SNOOP)
330 pr_cont("Tag error during snoop/victimization.\n");
331 else
332 ret = false;
333 }
334 return ret;
335}
336
86039cd4
BP
337static bool f15h_ic_mce(u16 ec, u8 xec)
338{
339 bool ret = true;
340
341 if (!MEM_ERROR(ec))
342 return false;
343
344 switch (xec) {
345 case 0x0 ... 0xa:
346 pr_cont("%s.\n", f15h_ic_mce_desc[xec]);
347 break;
348
349 case 0xd:
350 pr_cont("%s.\n", f15h_ic_mce_desc[xec-2]);
351 break;
352
353 case 0x10 ... 0x14:
354 pr_cont("Decoder %s parity error.\n", f15h_ic_mce_desc[xec-4]);
355 break;
356
357 default:
358 ret = false;
359 }
360 return ret;
361}
362
dd53bce4
BP
363static void amd_decode_ic_mce(struct mce *m)
364{
365 u16 ec = m->status & 0xffff;
2be64bfa 366 u8 xec = (m->status >> 16) & xec_mask;
dd53bce4
BP
367
368 pr_emerg(HW_ERR "Instruction Cache Error: ");
369
370 if (TLB_ERROR(ec))
371 pr_cont("%s TLB %s.\n", LL_MSG(ec),
372 (xec ? "multimatch" : "parity error"));
373 else if (BUS_ERROR(ec)) {
525906bc 374 bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
dd53bce4
BP
375
376 pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
86039cd4 377 } else if (fam_ops->ic_mce(ec, xec))
dd53bce4
BP
378 ;
379 else
380 pr_emerg(HW_ERR "Corrupted IC MCE info?\n");
ab5535e7
BP
381}
382
7cfd4a87 383static void amd_decode_bu_mce(struct mce *m)
56cad2d6 384{
7cfd4a87 385 u32 ec = m->status & 0xffff;
2be64bfa 386 u32 xec = (m->status >> 16) & xec_mask;
56cad2d6 387
c9f281fd 388 pr_emerg(HW_ERR "Bus Unit Error");
56cad2d6
BP
389
390 if (xec == 0x1)
391 pr_cont(" in the write data buffers.\n");
392 else if (xec == 0x3)
393 pr_cont(" in the victim data buffers.\n");
394 else if (xec == 0x2 && MEM_ERROR(ec))
395 pr_cont(": %s error in the L2 cache tags.\n", RRRR_MSG(ec));
396 else if (xec == 0x0) {
397 if (TLB_ERROR(ec))
398 pr_cont(": %s error in a Page Descriptor Cache or "
399 "Guest TLB.\n", TT_MSG(ec));
400 else if (BUS_ERROR(ec))
401 pr_cont(": %s/ECC error in data read from NB: %s.\n",
402 RRRR_MSG(ec), PP_MSG(ec));
403 else if (MEM_ERROR(ec)) {
404 u8 rrrr = (ec >> 4) & 0xf;
405
406 if (rrrr >= 0x7)
407 pr_cont(": %s error during data copyback.\n",
408 RRRR_MSG(ec));
409 else if (rrrr <= 0x1)
410 pr_cont(": %s parity/ECC error during data "
411 "access from L2.\n", RRRR_MSG(ec));
412 else
413 goto wrong_bu_mce;
414 } else
415 goto wrong_bu_mce;
416 } else
417 goto wrong_bu_mce;
418
419 return;
420
421wrong_bu_mce:
c9f281fd 422 pr_emerg(HW_ERR "Corrupted BU MCE info?\n");
56cad2d6
BP
423}
424
70fdb494
BP
425static void amd_decode_cu_mce(struct mce *m)
426{
427 u16 ec = m->status & 0xffff;
428 u8 xec = (m->status >> 16) & xec_mask;
429
430 pr_emerg(HW_ERR "Combined Unit Error: ");
431
432 if (TLB_ERROR(ec)) {
433 if (xec == 0x0)
434 pr_cont("Data parity TLB read error.\n");
435 else if (xec == 0x1)
436 pr_cont("Poison data provided for TLB fill.\n");
437 else
438 goto wrong_cu_mce;
439 } else if (BUS_ERROR(ec)) {
440 if (xec > 2)
441 goto wrong_cu_mce;
442
443 pr_cont("Error during attempted NB data read.\n");
444 } else if (MEM_ERROR(ec)) {
445 switch (xec) {
446 case 0x4 ... 0xc:
447 pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x4]);
448 break;
449
450 case 0x10 ... 0x14:
451 pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x7]);
452 break;
453
454 default:
455 goto wrong_cu_mce;
456 }
457 }
458
459 return;
460
461wrong_cu_mce:
462 pr_emerg(HW_ERR "Corrupted CU MCE info?\n");
463}
464
7cfd4a87 465static void amd_decode_ls_mce(struct mce *m)
f9350efd 466{
ded50623 467 u16 ec = m->status & 0xffff;
2be64bfa 468 u8 xec = (m->status >> 16) & xec_mask;
ded50623 469
b18434ca 470 if (boot_cpu_data.x86 >= 0x14) {
ded50623
BP
471 pr_emerg("You shouldn't be seeing an LS MCE on this cpu family,"
472 " please report on LKML.\n");
473 return;
474 }
f9350efd 475
c9f281fd 476 pr_emerg(HW_ERR "Load Store Error");
f9350efd
BP
477
478 if (xec == 0x0) {
ded50623 479 u8 r4 = (ec >> 4) & 0xf;
f9350efd 480
ded50623 481 if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR))
f9350efd
BP
482 goto wrong_ls_mce;
483
484 pr_cont(" during %s.\n", RRRR_MSG(ec));
ded50623
BP
485 } else
486 goto wrong_ls_mce;
487
f9350efd
BP
488 return;
489
490wrong_ls_mce:
c9f281fd 491 pr_emerg(HW_ERR "Corrupted LS MCE info?\n");
f9350efd
BP
492}
493
5ce88f6e
BP
494static bool k8_nb_mce(u16 ec, u8 xec)
495{
496 bool ret = true;
497
498 switch (xec) {
499 case 0x1:
500 pr_cont("CRC error detected on HT link.\n");
501 break;
502
503 case 0x5:
504 pr_cont("Invalid GART PTE entry during GART table walk.\n");
505 break;
506
507 case 0x6:
508 pr_cont("Unsupported atomic RMW received from an IO link.\n");
509 break;
510
511 case 0x0:
512 case 0x8:
f0157b3a
BP
513 if (boot_cpu_data.x86 == 0x11)
514 return false;
515
5ce88f6e
BP
516 pr_cont("DRAM ECC error detected on the NB.\n");
517 break;
518
519 case 0xd:
520 pr_cont("Parity error on the DRAM addr/ctl signals.\n");
521 break;
522
523 default:
524 ret = false;
525 break;
526 }
527
528 return ret;
529}
530
531static bool f10h_nb_mce(u16 ec, u8 xec)
532{
533 bool ret = true;
534 u8 offset = 0;
535
536 if (k8_nb_mce(ec, xec))
537 return true;
538
539 switch(xec) {
540 case 0xa ... 0xc:
541 offset = 10;
542 break;
543
544 case 0xe:
545 offset = 11;
546 break;
547
548 case 0xf:
549 if (TLB_ERROR(ec))
550 pr_cont("GART Table Walk data error.\n");
551 else if (BUS_ERROR(ec))
552 pr_cont("DMA Exclusion Vector Table Walk error.\n");
553 else
554 ret = false;
555
556 goto out;
557 break;
558
05cd667d
BP
559 case 0x19:
560 if (boot_cpu_data.x86 == 0x15)
561 pr_cont("Compute Unit Data Error.\n");
562 else
563 ret = false;
564
565 goto out;
566 break;
567
5ce88f6e
BP
568 case 0x1c ... 0x1f:
569 offset = 24;
570 break;
571
572 default:
573 ret = false;
574
575 goto out;
576 break;
577 }
578
579 pr_cont("%s.\n", f10h_nb_mce_desc[xec - offset]);
580
581out:
582 return ret;
583}
584
cb9d5ecd 585static bool nb_noop_mce(u16 ec, u8 xec)
5ce88f6e
BP
586{
587 return false;
588}
589
7cfd4a87 590void amd_decode_nb_mce(int node_id, struct mce *m, u32 nbcfg)
549d042d 591{
5ce88f6e
BP
592 u8 xec = (m->status >> 16) & 0x1f;
593 u16 ec = m->status & 0xffff;
7cfd4a87 594 u32 nbsh = (u32)(m->status >> 32);
256f7276 595
5ce88f6e 596 pr_emerg(HW_ERR "Northbridge Error, node %d: ", node_id);
549d042d
BP
597
598 /*
599 * F10h, revD can disable ErrCpu[3:0] so check that first and also the
600 * value encoding has changed so interpret those differently
601 */
602 if ((boot_cpu_data.x86 == 0x10) &&
cec7924f 603 (boot_cpu_data.x86_model > 7)) {
7cfd4a87 604 if (nbsh & K8_NBSH_ERR_CPU_VAL)
5ce88f6e 605 pr_cont(", core: %u", (u8)(nbsh & nb_err_cpumask));
549d042d 606 } else {
5ce88f6e 607 u8 assoc_cpus = nbsh & nb_err_cpumask;
5b89d2f9
BP
608
609 if (assoc_cpus > 0)
610 pr_cont(", core: %d", fls(assoc_cpus) - 1);
5ce88f6e 611 }
5b89d2f9 612
5ce88f6e
BP
613 switch (xec) {
614 case 0x2:
615 pr_cont("Sync error (sync packets on HT link detected).\n");
616 return;
617
618 case 0x3:
619 pr_cont("HT Master abort.\n");
620 return;
621
622 case 0x4:
623 pr_cont("HT Target abort.\n");
624 return;
625
626 case 0x7:
627 pr_cont("NB Watchdog timeout.\n");
628 return;
629
630 case 0x9:
631 pr_cont("SVM DMA Exclusion Vector error.\n");
632 return;
633
634 default:
635 break;
549d042d
BP
636 }
637
5ce88f6e
BP
638 if (!fam_ops->nb_mce(ec, xec))
639 goto wrong_nb_mce;
640
641 if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10)
642 if ((xec == 0x8 || xec == 0x0) && nb_bus_decoder)
643 nb_bus_decoder(node_id, m, nbcfg);
d93cc222 644
5ce88f6e
BP
645 return;
646
647wrong_nb_mce:
648 pr_emerg(HW_ERR "Corrupted NB MCE info?\n");
d93cc222
BP
649}
650EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
651
7cfd4a87 652static void amd_decode_fr_mce(struct mce *m)
53bd5fed 653{
f0157b3a
BP
654 if (boot_cpu_data.x86 == 0xf ||
655 boot_cpu_data.x86 == 0x11)
fe4ea262
BP
656 goto wrong_fr_mce;
657
53bd5fed 658 /* we have only one error signature so match all fields at once. */
fe4ea262
BP
659 if ((m->status & 0xffff) == 0x0f0f) {
660 pr_emerg(HW_ERR "FR Error: CPU Watchdog timer expire.\n");
661 return;
662 }
663
664wrong_fr_mce:
665 pr_emerg(HW_ERR "Corrupted FR MCE info?\n");
53bd5fed
BP
666}
667
6337583d 668static inline void amd_decode_err_code(u16 ec)
d93cc222 669{
549d042d 670 if (TLB_ERROR(ec)) {
c9f281fd 671 pr_emerg(HW_ERR "Transaction: %s, Cache Level: %s\n",
549d042d
BP
672 TT_MSG(ec), LL_MSG(ec));
673 } else if (MEM_ERROR(ec)) {
6337583d 674 pr_emerg(HW_ERR "Transaction: %s, Type: %s, Cache Level: %s\n",
549d042d
BP
675 RRRR_MSG(ec), TT_MSG(ec), LL_MSG(ec));
676 } else if (BUS_ERROR(ec)) {
6337583d 677 pr_emerg(HW_ERR "Transaction: %s (%s), %s, Cache Level: %s, "
d93cc222
BP
678 "Participating Processor: %s\n",
679 RRRR_MSG(ec), II_MSG(ec), TO_MSG(ec), LL_MSG(ec),
680 PP_MSG(ec));
681 } else
c9f281fd 682 pr_emerg(HW_ERR "Huh? Unknown MCE error 0x%x\n", ec);
549d042d 683}
549d042d 684
5ce88f6e
BP
685/*
686 * Filter out unwanted MCE signatures here.
687 */
688static bool amd_filter_mce(struct mce *m)
689{
690 u8 xec = (m->status >> 16) & 0x1f;
691
692 /*
693 * NB GART TLB error reporting is disabled by default.
694 */
695 if (m->bank == 4 && xec == 0x5 && !report_gart_errors)
696 return true;
697
698 return false;
699}
700
9cdeb404 701int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
549d042d 702{
fb253195 703 struct mce *m = (struct mce *)data;
b69b29de 704 int node, ecc;
549d042d 705
5ce88f6e
BP
706 if (amd_filter_mce(m))
707 return NOTIFY_STOP;
708
c9f281fd 709 pr_emerg(HW_ERR "MC%d_STATUS: ", m->bank);
549d042d 710
37b7370a 711 pr_cont("%sorrected error, other errors lost: %s, "
b69b29de
BP
712 "CPU context corrupt: %s",
713 ((m->status & MCI_STATUS_UC) ? "Unc" : "C"),
37b7370a 714 ((m->status & MCI_STATUS_OVER) ? "yes" : "no"),
b69b29de 715 ((m->status & MCI_STATUS_PCC) ? "yes" : "no"));
549d042d 716
b69b29de 717 /* do the two bits[14:13] together */
35d824b2 718 ecc = (m->status >> 45) & 0x3;
b69b29de
BP
719 if (ecc)
720 pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
721
722 pr_cont("\n");
723
51966241
BP
724 switch (m->bank) {
725 case 0:
7cfd4a87 726 amd_decode_dc_mce(m);
51966241 727 break;
d93cc222 728
ab5535e7 729 case 1:
7cfd4a87 730 amd_decode_ic_mce(m);
ab5535e7
BP
731 break;
732
56cad2d6 733 case 2:
70fdb494
BP
734 if (boot_cpu_data.x86 == 0x15)
735 amd_decode_cu_mce(m);
736 else
737 amd_decode_bu_mce(m);
56cad2d6
BP
738 break;
739
f9350efd 740 case 3:
7cfd4a87 741 amd_decode_ls_mce(m);
f9350efd
BP
742 break;
743
51966241 744 case 4:
7cfd4a87
BP
745 node = amd_get_nb_id(m->extcpu);
746 amd_decode_nb_mce(node, m, 0);
51966241
BP
747 break;
748
53bd5fed 749 case 5:
7cfd4a87 750 amd_decode_fr_mce(m);
53bd5fed
BP
751 break;
752
51966241
BP
753 default:
754 break;
b69b29de 755 }
51966241
BP
756
757 amd_decode_err_code(m->status & 0xffff);
fb253195
BP
758
759 return NOTIFY_STOP;
549d042d 760}
9cdeb404 761EXPORT_SYMBOL_GPL(amd_decode_mce);
f436f8bb 762
fb253195
BP
763static struct notifier_block amd_mce_dec_nb = {
764 .notifier_call = amd_decode_mce,
765};
766
f436f8bb
IM
767static int __init mce_amd_init(void)
768{
e045c291
BP
769 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
770 return 0;
771
fda7561f 772 if ((boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x12) &&
9530d608 773 (boot_cpu_data.x86 != 0x14 || boot_cpu_data.x86_model > 0xf))
e045c291
BP
774 return 0;
775
888ab8e6
BP
776 fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL);
777 if (!fam_ops)
778 return -ENOMEM;
779
780 switch (boot_cpu_data.x86) {
781 case 0xf:
782 fam_ops->dc_mce = k8_dc_mce;
dd53bce4 783 fam_ops->ic_mce = k8_ic_mce;
5ce88f6e 784 fam_ops->nb_mce = k8_nb_mce;
888ab8e6
BP
785 break;
786
787 case 0x10:
788 fam_ops->dc_mce = f10h_dc_mce;
dd53bce4 789 fam_ops->ic_mce = k8_ic_mce;
5ce88f6e 790 fam_ops->nb_mce = f10h_nb_mce;
888ab8e6
BP
791 break;
792
f0157b3a
BP
793 case 0x11:
794 fam_ops->dc_mce = k8_dc_mce;
795 fam_ops->ic_mce = k8_ic_mce;
796 fam_ops->nb_mce = f10h_nb_mce;
797 break;
798
9be0bb10
BP
799 case 0x12:
800 fam_ops->dc_mce = f12h_dc_mce;
e7281eb3 801 fam_ops->ic_mce = k8_ic_mce;
cb9d5ecd 802 fam_ops->nb_mce = nb_noop_mce;
9be0bb10
BP
803 break;
804
888ab8e6 805 case 0x14:
5ce88f6e 806 nb_err_cpumask = 0x3;
888ab8e6 807 fam_ops->dc_mce = f14h_dc_mce;
dd53bce4 808 fam_ops->ic_mce = f14h_ic_mce;
cb9d5ecd 809 fam_ops->nb_mce = nb_noop_mce;
888ab8e6
BP
810 break;
811
2be64bfa
BP
812 case 0x15:
813 xec_mask = 0x1f;
25a4f8b0 814 fam_ops->dc_mce = f15h_dc_mce;
86039cd4 815 fam_ops->ic_mce = f15h_ic_mce;
05cd667d 816 fam_ops->nb_mce = f10h_nb_mce;
2be64bfa
BP
817 break;
818
888ab8e6
BP
819 default:
820 printk(KERN_WARNING "Huh? What family is that: %d?!\n",
821 boot_cpu_data.x86);
822 kfree(fam_ops);
823 return -EINVAL;
824 }
825
9530d608
BP
826 pr_info("MCE: In-kernel MCE decoding enabled.\n");
827
e045c291 828 atomic_notifier_chain_register(&x86_mce_decoder_chain, &amd_mce_dec_nb);
f436f8bb
IM
829
830 return 0;
831}
832early_initcall(mce_amd_init);
0d18b2e3
BP
833
834#ifdef MODULE
835static void __exit mce_amd_exit(void)
836{
fb253195 837 atomic_notifier_chain_unregister(&x86_mce_decoder_chain, &amd_mce_dec_nb);
888ab8e6 838 kfree(fam_ops);
0d18b2e3
BP
839}
840
841MODULE_DESCRIPTION("AMD MCE decoder");
842MODULE_ALIAS("edac-mce-amd");
843MODULE_LICENSE("GPL");
844module_exit(mce_amd_exit);
845#endif
This page took 0.15375 seconds and 5 git commands to generate.