Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[linux-2.6/libata-dev.git] / drivers / edac / mce_amd.c
blobf3f0c930d550ebb34509eb05dec7faf17c579151
1 #include <linux/module.h>
2 #include <linux/slab.h>
4 #include "mce_amd.h"
6 static struct amd_decoder_ops *fam_ops;
8 static u8 xec_mask = 0xf;
9 static u8 nb_err_cpumask = 0xf;
11 static bool report_gart_errors;
12 static void (*nb_bus_decoder)(int node_id, struct mce *m);
14 void amd_report_gart_errors(bool v)
16 report_gart_errors = v;
18 EXPORT_SYMBOL_GPL(amd_report_gart_errors);
20 void amd_register_ecc_decoder(void (*f)(int, struct mce *))
22 nb_bus_decoder = f;
24 EXPORT_SYMBOL_GPL(amd_register_ecc_decoder);
26 void amd_unregister_ecc_decoder(void (*f)(int, struct mce *))
28 if (nb_bus_decoder) {
29 WARN_ON(nb_bus_decoder != f);
31 nb_bus_decoder = NULL;
34 EXPORT_SYMBOL_GPL(amd_unregister_ecc_decoder);
37 * string representation for the different MCA reported error types, see F3x48
38 * or MSR0000_0411.
41 /* transaction type */
42 static const char * const tt_msgs[] = { "INSN", "DATA", "GEN", "RESV" };
44 /* cache level */
45 static const char * const ll_msgs[] = { "RESV", "L1", "L2", "L3/GEN" };
47 /* memory transaction type */
48 static const char * const rrrr_msgs[] = {
49 "GEN", "RD", "WR", "DRD", "DWR", "IRD", "PRF", "EV", "SNP"
52 /* participating processor */
53 const char * const pp_msgs[] = { "SRC", "RES", "OBS", "GEN" };
54 EXPORT_SYMBOL_GPL(pp_msgs);
56 /* request timeout */
57 static const char * const to_msgs[] = { "no timeout", "timed out" };
59 /* memory or i/o */
60 static const char * const ii_msgs[] = { "MEM", "RESV", "IO", "GEN" };
62 /* internal error type */
63 static const char * const uu_msgs[] = { "RESV", "RESV", "HWA", "RESV" };
65 static const char * const f15h_mc1_mce_desc[] = {
66 "UC during a demand linefill from L2",
67 "Parity error during data load from IC",
68 "Parity error for IC valid bit",
69 "Main tag parity error",
70 "Parity error in prediction queue",
71 "PFB data/address parity error",
72 "Parity error in the branch status reg",
73 "PFB promotion address error",
74 "Tag error during probe/victimization",
75 "Parity error for IC probe tag valid bit",
76 "PFB non-cacheable bit parity error",
77 "PFB valid bit parity error", /* xec = 0xd */
78 "Microcode Patch Buffer", /* xec = 010 */
79 "uop queue",
80 "insn buffer",
81 "predecode buffer",
82 "fetch address FIFO"
85 static const char * const f15h_mc2_mce_desc[] = {
86 "Fill ECC error on data fills", /* xec = 0x4 */
87 "Fill parity error on insn fills",
88 "Prefetcher request FIFO parity error",
89 "PRQ address parity error",
90 "PRQ data parity error",
91 "WCC Tag ECC error",
92 "WCC Data ECC error",
93 "WCB Data parity error",
94 "VB Data ECC or parity error",
95 "L2 Tag ECC error", /* xec = 0x10 */
96 "Hard L2 Tag ECC error",
97 "Multiple hits on L2 tag",
98 "XAB parity error",
99 "PRB address parity error"
102 static const char * const mc4_mce_desc[] = {
103 "DRAM ECC error detected on the NB",
104 "CRC error detected on HT link",
105 "Link-defined sync error packets detected on HT link",
106 "HT Master abort",
107 "HT Target abort",
108 "Invalid GART PTE entry during GART table walk",
109 "Unsupported atomic RMW received from an IO link",
110 "Watchdog timeout due to lack of progress",
111 "DRAM ECC error detected on the NB",
112 "SVM DMA Exclusion Vector error",
113 "HT data error detected on link",
114 "Protocol error (link, L3, probe filter)",
115 "NB internal arrays parity error",
116 "DRAM addr/ctl signals parity error",
117 "IO link transmission error",
118 "L3 data cache ECC error", /* xec = 0x1c */
119 "L3 cache tag error",
120 "L3 LRU parity bits error",
121 "ECC Error in the Probe Filter directory"
124 static const char * const mc5_mce_desc[] = {
125 "CPU Watchdog timer expire",
126 "Wakeup array dest tag",
127 "AG payload array",
128 "EX payload array",
129 "IDRF array",
130 "Retire dispatch queue",
131 "Mapper checkpoint array",
132 "Physical register file EX0 port",
133 "Physical register file EX1 port",
134 "Physical register file AG0 port",
135 "Physical register file AG1 port",
136 "Flag register file",
137 "DE error occurred"
140 static bool f12h_mc0_mce(u16 ec, u8 xec)
142 bool ret = false;
144 if (MEM_ERROR(ec)) {
145 u8 ll = LL(ec);
146 ret = true;
148 if (ll == LL_L2)
149 pr_cont("during L1 linefill from L2.\n");
150 else if (ll == LL_L1)
151 pr_cont("Data/Tag %s error.\n", R4_MSG(ec));
152 else
153 ret = false;
155 return ret;
158 static bool f10h_mc0_mce(u16 ec, u8 xec)
160 if (R4(ec) == R4_GEN && LL(ec) == LL_L1) {
161 pr_cont("during data scrub.\n");
162 return true;
164 return f12h_mc0_mce(ec, xec);
167 static bool k8_mc0_mce(u16 ec, u8 xec)
169 if (BUS_ERROR(ec)) {
170 pr_cont("during system linefill.\n");
171 return true;
174 return f10h_mc0_mce(ec, xec);
177 static bool cat_mc0_mce(u16 ec, u8 xec)
179 u8 r4 = R4(ec);
180 bool ret = true;
182 if (MEM_ERROR(ec)) {
184 if (TT(ec) != TT_DATA || LL(ec) != LL_L1)
185 return false;
187 switch (r4) {
188 case R4_DRD:
189 case R4_DWR:
190 pr_cont("Data/Tag parity error due to %s.\n",
191 (r4 == R4_DRD ? "load/hw prf" : "store"));
192 break;
193 case R4_EVICT:
194 pr_cont("Copyback parity error on a tag miss.\n");
195 break;
196 case R4_SNOOP:
197 pr_cont("Tag parity error during snoop.\n");
198 break;
199 default:
200 ret = false;
202 } else if (BUS_ERROR(ec)) {
204 if ((II(ec) != II_MEM && II(ec) != II_IO) || LL(ec) != LL_LG)
205 return false;
207 pr_cont("System read data error on a ");
209 switch (r4) {
210 case R4_RD:
211 pr_cont("TLB reload.\n");
212 break;
213 case R4_DWR:
214 pr_cont("store.\n");
215 break;
216 case R4_DRD:
217 pr_cont("load.\n");
218 break;
219 default:
220 ret = false;
222 } else {
223 ret = false;
226 return ret;
229 static bool f15h_mc0_mce(u16 ec, u8 xec)
231 bool ret = true;
233 if (MEM_ERROR(ec)) {
235 switch (xec) {
236 case 0x0:
237 pr_cont("Data Array access error.\n");
238 break;
240 case 0x1:
241 pr_cont("UC error during a linefill from L2/NB.\n");
242 break;
244 case 0x2:
245 case 0x11:
246 pr_cont("STQ access error.\n");
247 break;
249 case 0x3:
250 pr_cont("SCB access error.\n");
251 break;
253 case 0x10:
254 pr_cont("Tag error.\n");
255 break;
257 case 0x12:
258 pr_cont("LDQ access error.\n");
259 break;
261 default:
262 ret = false;
264 } else if (BUS_ERROR(ec)) {
266 if (!xec)
267 pr_cont("System Read Data Error.\n");
268 else
269 pr_cont(" Internal error condition type %d.\n", xec);
270 } else
271 ret = false;
273 return ret;
276 static void decode_mc0_mce(struct mce *m)
278 u16 ec = EC(m->status);
279 u8 xec = XEC(m->status, xec_mask);
281 pr_emerg(HW_ERR "MC0 Error: ");
283 /* TLB error signatures are the same across families */
284 if (TLB_ERROR(ec)) {
285 if (TT(ec) == TT_DATA) {
286 pr_cont("%s TLB %s.\n", LL_MSG(ec),
287 ((xec == 2) ? "locked miss"
288 : (xec ? "multimatch" : "parity")));
289 return;
291 } else if (fam_ops->mc0_mce(ec, xec))
293 else
294 pr_emerg(HW_ERR "Corrupted MC0 MCE info?\n");
297 static bool k8_mc1_mce(u16 ec, u8 xec)
299 u8 ll = LL(ec);
300 bool ret = true;
302 if (!MEM_ERROR(ec))
303 return false;
305 if (ll == 0x2)
306 pr_cont("during a linefill from L2.\n");
307 else if (ll == 0x1) {
308 switch (R4(ec)) {
309 case R4_IRD:
310 pr_cont("Parity error during data load.\n");
311 break;
313 case R4_EVICT:
314 pr_cont("Copyback Parity/Victim error.\n");
315 break;
317 case R4_SNOOP:
318 pr_cont("Tag Snoop error.\n");
319 break;
321 default:
322 ret = false;
323 break;
325 } else
326 ret = false;
328 return ret;
331 static bool cat_mc1_mce(u16 ec, u8 xec)
333 u8 r4 = R4(ec);
334 bool ret = true;
336 if (!MEM_ERROR(ec))
337 return false;
339 if (TT(ec) != TT_INSTR)
340 return false;
342 if (r4 == R4_IRD)
343 pr_cont("Data/tag array parity error for a tag hit.\n");
344 else if (r4 == R4_SNOOP)
345 pr_cont("Tag error during snoop/victimization.\n");
346 else if (xec == 0x0)
347 pr_cont("Tag parity error from victim castout.\n");
348 else if (xec == 0x2)
349 pr_cont("Microcode patch RAM parity error.\n");
350 else
351 ret = false;
353 return ret;
356 static bool f15h_mc1_mce(u16 ec, u8 xec)
358 bool ret = true;
360 if (!MEM_ERROR(ec))
361 return false;
363 switch (xec) {
364 case 0x0 ... 0xa:
365 pr_cont("%s.\n", f15h_mc1_mce_desc[xec]);
366 break;
368 case 0xd:
369 pr_cont("%s.\n", f15h_mc1_mce_desc[xec-2]);
370 break;
372 case 0x10:
373 pr_cont("%s.\n", f15h_mc1_mce_desc[xec-4]);
374 break;
376 case 0x11 ... 0x14:
377 pr_cont("Decoder %s parity error.\n", f15h_mc1_mce_desc[xec-4]);
378 break;
380 default:
381 ret = false;
383 return ret;
386 static void decode_mc1_mce(struct mce *m)
388 u16 ec = EC(m->status);
389 u8 xec = XEC(m->status, xec_mask);
391 pr_emerg(HW_ERR "MC1 Error: ");
393 if (TLB_ERROR(ec))
394 pr_cont("%s TLB %s.\n", LL_MSG(ec),
395 (xec ? "multimatch" : "parity error"));
396 else if (BUS_ERROR(ec)) {
397 bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
399 pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
400 } else if (fam_ops->mc1_mce(ec, xec))
402 else
403 pr_emerg(HW_ERR "Corrupted MC1 MCE info?\n");
406 static bool k8_mc2_mce(u16 ec, u8 xec)
408 bool ret = true;
410 if (xec == 0x1)
411 pr_cont(" in the write data buffers.\n");
412 else if (xec == 0x3)
413 pr_cont(" in the victim data buffers.\n");
414 else if (xec == 0x2 && MEM_ERROR(ec))
415 pr_cont(": %s error in the L2 cache tags.\n", R4_MSG(ec));
416 else if (xec == 0x0) {
417 if (TLB_ERROR(ec))
418 pr_cont(": %s error in a Page Descriptor Cache or "
419 "Guest TLB.\n", TT_MSG(ec));
420 else if (BUS_ERROR(ec))
421 pr_cont(": %s/ECC error in data read from NB: %s.\n",
422 R4_MSG(ec), PP_MSG(ec));
423 else if (MEM_ERROR(ec)) {
424 u8 r4 = R4(ec);
426 if (r4 >= 0x7)
427 pr_cont(": %s error during data copyback.\n",
428 R4_MSG(ec));
429 else if (r4 <= 0x1)
430 pr_cont(": %s parity/ECC error during data "
431 "access from L2.\n", R4_MSG(ec));
432 else
433 ret = false;
434 } else
435 ret = false;
436 } else
437 ret = false;
439 return ret;
442 static bool f15h_mc2_mce(u16 ec, u8 xec)
444 bool ret = true;
446 if (TLB_ERROR(ec)) {
447 if (xec == 0x0)
448 pr_cont("Data parity TLB read error.\n");
449 else if (xec == 0x1)
450 pr_cont("Poison data provided for TLB fill.\n");
451 else
452 ret = false;
453 } else if (BUS_ERROR(ec)) {
454 if (xec > 2)
455 ret = false;
457 pr_cont("Error during attempted NB data read.\n");
458 } else if (MEM_ERROR(ec)) {
459 switch (xec) {
460 case 0x4 ... 0xc:
461 pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x4]);
462 break;
464 case 0x10 ... 0x14:
465 pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x7]);
466 break;
468 default:
469 ret = false;
473 return ret;
476 static bool f16h_mc2_mce(u16 ec, u8 xec)
478 u8 r4 = R4(ec);
480 if (!MEM_ERROR(ec))
481 return false;
483 switch (xec) {
484 case 0x04 ... 0x05:
485 pr_cont("%cBUFF parity error.\n", (r4 == R4_RD) ? 'I' : 'O');
486 break;
488 case 0x09 ... 0x0b:
489 case 0x0d ... 0x0f:
490 pr_cont("ECC error in L2 tag (%s).\n",
491 ((r4 == R4_GEN) ? "BankReq" :
492 ((r4 == R4_SNOOP) ? "Prb" : "Fill")));
493 break;
495 case 0x10 ... 0x19:
496 case 0x1b:
497 pr_cont("ECC error in L2 data array (%s).\n",
498 (((r4 == R4_RD) && !(xec & 0x3)) ? "Hit" :
499 ((r4 == R4_GEN) ? "Attr" :
500 ((r4 == R4_EVICT) ? "Vict" : "Fill"))));
501 break;
503 case 0x1c ... 0x1d:
504 case 0x1f:
505 pr_cont("Parity error in L2 attribute bits (%s).\n",
506 ((r4 == R4_RD) ? "Hit" :
507 ((r4 == R4_GEN) ? "Attr" : "Fill")));
508 break;
510 default:
511 return false;
514 return true;
517 static void decode_mc2_mce(struct mce *m)
519 u16 ec = EC(m->status);
520 u8 xec = XEC(m->status, xec_mask);
522 pr_emerg(HW_ERR "MC2 Error: ");
524 if (!fam_ops->mc2_mce(ec, xec))
525 pr_cont(HW_ERR "Corrupted MC2 MCE info?\n");
528 static void decode_mc3_mce(struct mce *m)
530 u16 ec = EC(m->status);
531 u8 xec = XEC(m->status, xec_mask);
533 if (boot_cpu_data.x86 >= 0x14) {
534 pr_emerg("You shouldn't be seeing MC3 MCE on this cpu family,"
535 " please report on LKML.\n");
536 return;
539 pr_emerg(HW_ERR "MC3 Error");
541 if (xec == 0x0) {
542 u8 r4 = R4(ec);
544 if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR))
545 goto wrong_mc3_mce;
547 pr_cont(" during %s.\n", R4_MSG(ec));
548 } else
549 goto wrong_mc3_mce;
551 return;
553 wrong_mc3_mce:
554 pr_emerg(HW_ERR "Corrupted MC3 MCE info?\n");
557 static void decode_mc4_mce(struct mce *m)
559 struct cpuinfo_x86 *c = &boot_cpu_data;
560 int node_id = amd_get_nb_id(m->extcpu);
561 u16 ec = EC(m->status);
562 u8 xec = XEC(m->status, 0x1f);
563 u8 offset = 0;
565 pr_emerg(HW_ERR "MC4 Error (node %d): ", node_id);
567 switch (xec) {
568 case 0x0 ... 0xe:
570 /* special handling for DRAM ECCs */
571 if (xec == 0x0 || xec == 0x8) {
572 /* no ECCs on F11h */
573 if (c->x86 == 0x11)
574 goto wrong_mc4_mce;
576 pr_cont("%s.\n", mc4_mce_desc[xec]);
578 if (nb_bus_decoder)
579 nb_bus_decoder(node_id, m);
580 return;
582 break;
584 case 0xf:
585 if (TLB_ERROR(ec))
586 pr_cont("GART Table Walk data error.\n");
587 else if (BUS_ERROR(ec))
588 pr_cont("DMA Exclusion Vector Table Walk error.\n");
589 else
590 goto wrong_mc4_mce;
591 return;
593 case 0x19:
594 if (boot_cpu_data.x86 == 0x15 || boot_cpu_data.x86 == 0x16)
595 pr_cont("Compute Unit Data Error.\n");
596 else
597 goto wrong_mc4_mce;
598 return;
600 case 0x1c ... 0x1f:
601 offset = 13;
602 break;
604 default:
605 goto wrong_mc4_mce;
608 pr_cont("%s.\n", mc4_mce_desc[xec - offset]);
609 return;
611 wrong_mc4_mce:
612 pr_emerg(HW_ERR "Corrupted MC4 MCE info?\n");
615 static void decode_mc5_mce(struct mce *m)
617 struct cpuinfo_x86 *c = &boot_cpu_data;
618 u8 xec = XEC(m->status, xec_mask);
620 if (c->x86 == 0xf || c->x86 == 0x11)
621 goto wrong_mc5_mce;
623 pr_emerg(HW_ERR "MC5 Error: ");
625 if (xec == 0x0 || xec == 0xc)
626 pr_cont("%s.\n", mc5_mce_desc[xec]);
627 else if (xec < 0xd)
628 pr_cont("%s parity error.\n", mc5_mce_desc[xec]);
629 else
630 goto wrong_mc5_mce;
632 return;
634 wrong_mc5_mce:
635 pr_emerg(HW_ERR "Corrupted MC5 MCE info?\n");
638 static void decode_mc6_mce(struct mce *m)
640 u8 xec = XEC(m->status, xec_mask);
642 pr_emerg(HW_ERR "MC6 Error: ");
644 switch (xec) {
645 case 0x1:
646 pr_cont("Free List");
647 break;
649 case 0x2:
650 pr_cont("Physical Register File");
651 break;
653 case 0x3:
654 pr_cont("Retire Queue");
655 break;
657 case 0x4:
658 pr_cont("Scheduler table");
659 break;
661 case 0x5:
662 pr_cont("Status Register File");
663 break;
665 default:
666 goto wrong_mc6_mce;
667 break;
670 pr_cont(" parity error.\n");
672 return;
674 wrong_mc6_mce:
675 pr_emerg(HW_ERR "Corrupted MC6 MCE info?\n");
678 static inline void amd_decode_err_code(u16 ec)
680 if (INT_ERROR(ec)) {
681 pr_emerg(HW_ERR "internal: %s\n", UU_MSG(ec));
682 return;
685 pr_emerg(HW_ERR "cache level: %s", LL_MSG(ec));
687 if (BUS_ERROR(ec))
688 pr_cont(", mem/io: %s", II_MSG(ec));
689 else
690 pr_cont(", tx: %s", TT_MSG(ec));
692 if (MEM_ERROR(ec) || BUS_ERROR(ec)) {
693 pr_cont(", mem-tx: %s", R4_MSG(ec));
695 if (BUS_ERROR(ec))
696 pr_cont(", part-proc: %s (%s)", PP_MSG(ec), TO_MSG(ec));
699 pr_cont("\n");
703 * Filter out unwanted MCE signatures here.
705 static bool amd_filter_mce(struct mce *m)
707 u8 xec = (m->status >> 16) & 0x1f;
710 * NB GART TLB error reporting is disabled by default.
712 if (m->bank == 4 && xec == 0x5 && !report_gart_errors)
713 return true;
715 return false;
718 static const char *decode_error_status(struct mce *m)
720 if (m->status & MCI_STATUS_UC) {
721 if (m->status & MCI_STATUS_PCC)
722 return "System Fatal error.";
723 if (m->mcgstatus & MCG_STATUS_RIPV)
724 return "Uncorrected, software restartable error.";
725 return "Uncorrected, software containable error.";
728 if (m->status & MCI_STATUS_DEFERRED)
729 return "Deferred error.";
731 return "Corrected error, no action required.";
734 int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
736 struct mce *m = (struct mce *)data;
737 struct cpuinfo_x86 *c = &cpu_data(m->extcpu);
738 int ecc;
740 if (amd_filter_mce(m))
741 return NOTIFY_STOP;
743 switch (m->bank) {
744 case 0:
745 decode_mc0_mce(m);
746 break;
748 case 1:
749 decode_mc1_mce(m);
750 break;
752 case 2:
753 decode_mc2_mce(m);
754 break;
756 case 3:
757 decode_mc3_mce(m);
758 break;
760 case 4:
761 decode_mc4_mce(m);
762 break;
764 case 5:
765 decode_mc5_mce(m);
766 break;
768 case 6:
769 decode_mc6_mce(m);
770 break;
772 default:
773 break;
776 pr_emerg(HW_ERR "Error Status: %s\n", decode_error_status(m));
778 pr_emerg(HW_ERR "CPU:%d (%x:%x:%x) MC%d_STATUS[%s|%s|%s|%s|%s",
779 m->extcpu,
780 c->x86, c->x86_model, c->x86_mask,
781 m->bank,
782 ((m->status & MCI_STATUS_OVER) ? "Over" : "-"),
783 ((m->status & MCI_STATUS_UC) ? "UE" : "CE"),
784 ((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"),
785 ((m->status & MCI_STATUS_PCC) ? "PCC" : "-"),
786 ((m->status & MCI_STATUS_ADDRV) ? "AddrV" : "-"));
788 if (c->x86 == 0x15 || c->x86 == 0x16)
789 pr_cont("|%s|%s",
790 ((m->status & MCI_STATUS_DEFERRED) ? "Deferred" : "-"),
791 ((m->status & MCI_STATUS_POISON) ? "Poison" : "-"));
793 /* do the two bits[14:13] together */
794 ecc = (m->status >> 45) & 0x3;
795 if (ecc)
796 pr_cont("|%sECC", ((ecc == 2) ? "C" : "U"));
798 pr_cont("]: 0x%016llx\n", m->status);
800 if (m->status & MCI_STATUS_ADDRV)
801 pr_emerg(HW_ERR "MC%d_ADDR: 0x%016llx\n", m->bank, m->addr);
803 amd_decode_err_code(m->status & 0xffff);
805 return NOTIFY_STOP;
807 EXPORT_SYMBOL_GPL(amd_decode_mce);
809 static struct notifier_block amd_mce_dec_nb = {
810 .notifier_call = amd_decode_mce,
813 static int __init mce_amd_init(void)
815 struct cpuinfo_x86 *c = &boot_cpu_data;
817 if (c->x86_vendor != X86_VENDOR_AMD)
818 return 0;
820 if (c->x86 < 0xf || c->x86 > 0x16)
821 return 0;
823 fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL);
824 if (!fam_ops)
825 return -ENOMEM;
827 switch (c->x86) {
828 case 0xf:
829 fam_ops->mc0_mce = k8_mc0_mce;
830 fam_ops->mc1_mce = k8_mc1_mce;
831 fam_ops->mc2_mce = k8_mc2_mce;
832 break;
834 case 0x10:
835 fam_ops->mc0_mce = f10h_mc0_mce;
836 fam_ops->mc1_mce = k8_mc1_mce;
837 fam_ops->mc2_mce = k8_mc2_mce;
838 break;
840 case 0x11:
841 fam_ops->mc0_mce = k8_mc0_mce;
842 fam_ops->mc1_mce = k8_mc1_mce;
843 fam_ops->mc2_mce = k8_mc2_mce;
844 break;
846 case 0x12:
847 fam_ops->mc0_mce = f12h_mc0_mce;
848 fam_ops->mc1_mce = k8_mc1_mce;
849 fam_ops->mc2_mce = k8_mc2_mce;
850 break;
852 case 0x14:
853 nb_err_cpumask = 0x3;
854 fam_ops->mc0_mce = cat_mc0_mce;
855 fam_ops->mc1_mce = cat_mc1_mce;
856 fam_ops->mc2_mce = k8_mc2_mce;
857 break;
859 case 0x15:
860 xec_mask = 0x1f;
861 fam_ops->mc0_mce = f15h_mc0_mce;
862 fam_ops->mc1_mce = f15h_mc1_mce;
863 fam_ops->mc2_mce = f15h_mc2_mce;
864 break;
866 case 0x16:
867 xec_mask = 0x1f;
868 fam_ops->mc0_mce = cat_mc0_mce;
869 fam_ops->mc1_mce = cat_mc1_mce;
870 fam_ops->mc2_mce = f16h_mc2_mce;
871 break;
873 default:
874 printk(KERN_WARNING "Huh? What family is it: 0x%x?!\n", c->x86);
875 kfree(fam_ops);
876 return -EINVAL;
879 pr_info("MCE: In-kernel MCE decoding enabled.\n");
881 mce_register_decode_chain(&amd_mce_dec_nb);
883 return 0;
885 early_initcall(mce_amd_init);
887 #ifdef MODULE
888 static void __exit mce_amd_exit(void)
890 mce_unregister_decode_chain(&amd_mce_dec_nb);
891 kfree(fam_ops);
894 MODULE_DESCRIPTION("AMD MCE decoder");
895 MODULE_ALIAS("edac-mce-amd");
896 MODULE_LICENSE("GPL");
897 module_exit(mce_amd_exit);
898 #endif