EDAC, MCE: Add F15h DC 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
25a4f8b0 78static bool f12h_dc_mce(u16 ec, u8 xec)
51966241 79{
888ab8e6 80 bool ret = false;
51966241 81
888ab8e6
BP
82 if (MEM_ERROR(ec)) {
83 u8 ll = ec & 0x3;
84 ret = true;
51966241 85
888ab8e6
BP
86 if (ll == LL_L2)
87 pr_cont("during L1 linefill from L2.\n");
88 else if (ll == LL_L1)
89 pr_cont("Data/Tag %s error.\n", RRRR_MSG(ec));
90 else
91 ret = false;
92 }
93 return ret;
94}
51966241 95
25a4f8b0 96static bool f10h_dc_mce(u16 ec, u8 xec)
9be0bb10
BP
97{
98 u8 r4 = (ec >> 4) & 0xf;
99 u8 ll = ec & 0x3;
100
101 if (r4 == R4_GEN && ll == LL_L1) {
102 pr_cont("during data scrub.\n");
103 return true;
104 }
25a4f8b0 105 return f12h_dc_mce(ec, xec);
9be0bb10
BP
106}
107
25a4f8b0 108static bool k8_dc_mce(u16 ec, u8 xec)
888ab8e6
BP
109{
110 if (BUS_ERROR(ec)) {
111 pr_cont("during system linefill.\n");
112 return true;
113 }
51966241 114
25a4f8b0 115 return f10h_dc_mce(ec, xec);
888ab8e6
BP
116}
117
25a4f8b0 118static bool f14h_dc_mce(u16 ec, u8 xec)
888ab8e6
BP
119{
120 u8 r4 = (ec >> 4) & 0xf;
121 u8 ll = ec & 0x3;
122 u8 tt = (ec >> 2) & 0x3;
123 u8 ii = tt;
124 bool ret = true;
125
126 if (MEM_ERROR(ec)) {
127
128 if (tt != TT_DATA || ll != LL_L1)
129 return false;
130
131 switch (r4) {
132 case R4_DRD:
133 case R4_DWR:
134 pr_cont("Data/Tag parity error due to %s.\n",
135 (r4 == R4_DRD ? "load/hw prf" : "store"));
136 break;
137 case R4_EVICT:
138 pr_cont("Copyback parity error on a tag miss.\n");
139 break;
140 case R4_SNOOP:
141 pr_cont("Tag parity error during snoop.\n");
142 break;
143 default:
144 ret = false;
145 }
146 } else if (BUS_ERROR(ec)) {
147
148 if ((ii != II_MEM && ii != II_IO) || ll != LL_LG)
149 return false;
150
151 pr_cont("System read data error on a ");
152
153 switch (r4) {
154 case R4_RD:
155 pr_cont("TLB reload.\n");
156 break;
157 case R4_DWR:
158 pr_cont("store.\n");
159 break;
160 case R4_DRD:
161 pr_cont("load.\n");
162 break;
163 default:
164 ret = false;
165 }
166 } else {
167 ret = false;
168 }
169
170 return ret;
171}
172
25a4f8b0
BP
173static bool f15h_dc_mce(u16 ec, u8 xec)
174{
175 bool ret = true;
176
177 if (MEM_ERROR(ec)) {
178
179 switch (xec) {
180 case 0x0:
181 pr_cont("Data Array access error.\n");
182 break;
183
184 case 0x1:
185 pr_cont("UC error during a linefill from L2/NB.\n");
186 break;
187
188 case 0x2:
189 case 0x11:
190 pr_cont("STQ access error.\n");
191 break;
192
193 case 0x3:
194 pr_cont("SCB access error.\n");
195 break;
196
197 case 0x10:
198 pr_cont("Tag error.\n");
199 break;
200
201 case 0x12:
202 pr_cont("LDQ access error.\n");
203 break;
204
205 default:
206 ret = false;
207 }
208 } else if (BUS_ERROR(ec)) {
209
210 if (!xec)
211 pr_cont("during system linefill.\n");
212 else
213 pr_cont(" Internal %s condition.\n",
214 ((xec == 1) ? "livelock" : "deadlock"));
215 } else
216 ret = false;
217
218 return ret;
219}
220
888ab8e6
BP
221static void amd_decode_dc_mce(struct mce *m)
222{
223 u16 ec = m->status & 0xffff;
2be64bfa 224 u8 xec = (m->status >> 16) & xec_mask;
888ab8e6
BP
225
226 pr_emerg(HW_ERR "Data Cache Error: ");
227
228 /* TLB error signatures are the same across families */
229 if (TLB_ERROR(ec)) {
230 u8 tt = (ec >> 2) & 0x3;
231
232 if (tt == TT_DATA) {
233 pr_cont("%s TLB %s.\n", LL_MSG(ec),
25a4f8b0
BP
234 ((xec == 2) ? "locked miss"
235 : (xec ? "multimatch" : "parity")));
888ab8e6
BP
236 return;
237 }
25a4f8b0
BP
238 } else if (fam_ops->dc_mce(ec, xec))
239 ;
240 else
241 pr_emerg(HW_ERR "Corrupted DC MCE info?\n");
51966241
BP
242}
243
dd53bce4 244static bool k8_ic_mce(u16 ec)
ab5535e7 245{
dd53bce4
BP
246 u8 ll = ec & 0x3;
247 u8 r4 = (ec >> 4) & 0xf;
248 bool ret = true;
ab5535e7 249
dd53bce4
BP
250 if (!MEM_ERROR(ec))
251 return false;
ab5535e7 252
dd53bce4
BP
253 if (ll == 0x2)
254 pr_cont("during a linefill from L2.\n");
255 else if (ll == 0x1) {
256 switch (r4) {
257 case R4_IRD:
258 pr_cont("Parity error during data load.\n");
259 break;
ab5535e7 260
dd53bce4
BP
261 case R4_EVICT:
262 pr_cont("Copyback Parity/Victim error.\n");
263 break;
264
265 case R4_SNOOP:
266 pr_cont("Tag Snoop error.\n");
267 break;
268
269 default:
270 ret = false;
271 break;
272 }
ab5535e7 273 } else
dd53bce4 274 ret = false;
ab5535e7 275
dd53bce4
BP
276 return ret;
277}
278
279static bool f14h_ic_mce(u16 ec)
280{
281 u8 ll = ec & 0x3;
282 u8 tt = (ec >> 2) & 0x3;
283 u8 r4 = (ec >> 4) & 0xf;
284 bool ret = true;
ab5535e7 285
dd53bce4
BP
286 if (MEM_ERROR(ec)) {
287 if (tt != 0 || ll != 1)
288 ret = false;
289
290 if (r4 == R4_IRD)
291 pr_cont("Data/tag array parity error for a tag hit.\n");
292 else if (r4 == R4_SNOOP)
293 pr_cont("Tag error during snoop/victimization.\n");
294 else
295 ret = false;
296 }
297 return ret;
298}
299
300static void amd_decode_ic_mce(struct mce *m)
301{
302 u16 ec = m->status & 0xffff;
2be64bfa 303 u8 xec = (m->status >> 16) & xec_mask;
dd53bce4
BP
304
305 pr_emerg(HW_ERR "Instruction Cache Error: ");
306
307 if (TLB_ERROR(ec))
308 pr_cont("%s TLB %s.\n", LL_MSG(ec),
309 (xec ? "multimatch" : "parity error"));
310 else if (BUS_ERROR(ec)) {
525906bc 311 bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
dd53bce4
BP
312
313 pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
314 } else if (fam_ops->ic_mce(ec))
315 ;
316 else
317 pr_emerg(HW_ERR "Corrupted IC MCE info?\n");
ab5535e7
BP
318}
319
7cfd4a87 320static void amd_decode_bu_mce(struct mce *m)
56cad2d6 321{
7cfd4a87 322 u32 ec = m->status & 0xffff;
2be64bfa 323 u32 xec = (m->status >> 16) & xec_mask;
56cad2d6 324
c9f281fd 325 pr_emerg(HW_ERR "Bus Unit Error");
56cad2d6
BP
326
327 if (xec == 0x1)
328 pr_cont(" in the write data buffers.\n");
329 else if (xec == 0x3)
330 pr_cont(" in the victim data buffers.\n");
331 else if (xec == 0x2 && MEM_ERROR(ec))
332 pr_cont(": %s error in the L2 cache tags.\n", RRRR_MSG(ec));
333 else if (xec == 0x0) {
334 if (TLB_ERROR(ec))
335 pr_cont(": %s error in a Page Descriptor Cache or "
336 "Guest TLB.\n", TT_MSG(ec));
337 else if (BUS_ERROR(ec))
338 pr_cont(": %s/ECC error in data read from NB: %s.\n",
339 RRRR_MSG(ec), PP_MSG(ec));
340 else if (MEM_ERROR(ec)) {
341 u8 rrrr = (ec >> 4) & 0xf;
342
343 if (rrrr >= 0x7)
344 pr_cont(": %s error during data copyback.\n",
345 RRRR_MSG(ec));
346 else if (rrrr <= 0x1)
347 pr_cont(": %s parity/ECC error during data "
348 "access from L2.\n", RRRR_MSG(ec));
349 else
350 goto wrong_bu_mce;
351 } else
352 goto wrong_bu_mce;
353 } else
354 goto wrong_bu_mce;
355
356 return;
357
358wrong_bu_mce:
c9f281fd 359 pr_emerg(HW_ERR "Corrupted BU MCE info?\n");
56cad2d6
BP
360}
361
7cfd4a87 362static void amd_decode_ls_mce(struct mce *m)
f9350efd 363{
ded50623 364 u16 ec = m->status & 0xffff;
2be64bfa 365 u8 xec = (m->status >> 16) & xec_mask;
ded50623
BP
366
367 if (boot_cpu_data.x86 == 0x14) {
368 pr_emerg("You shouldn't be seeing an LS MCE on this cpu family,"
369 " please report on LKML.\n");
370 return;
371 }
f9350efd 372
c9f281fd 373 pr_emerg(HW_ERR "Load Store Error");
f9350efd
BP
374
375 if (xec == 0x0) {
ded50623 376 u8 r4 = (ec >> 4) & 0xf;
f9350efd 377
ded50623 378 if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR))
f9350efd
BP
379 goto wrong_ls_mce;
380
381 pr_cont(" during %s.\n", RRRR_MSG(ec));
ded50623
BP
382 } else
383 goto wrong_ls_mce;
384
f9350efd
BP
385 return;
386
387wrong_ls_mce:
c9f281fd 388 pr_emerg(HW_ERR "Corrupted LS MCE info?\n");
f9350efd
BP
389}
390
5ce88f6e
BP
391static bool k8_nb_mce(u16 ec, u8 xec)
392{
393 bool ret = true;
394
395 switch (xec) {
396 case 0x1:
397 pr_cont("CRC error detected on HT link.\n");
398 break;
399
400 case 0x5:
401 pr_cont("Invalid GART PTE entry during GART table walk.\n");
402 break;
403
404 case 0x6:
405 pr_cont("Unsupported atomic RMW received from an IO link.\n");
406 break;
407
408 case 0x0:
409 case 0x8:
f0157b3a
BP
410 if (boot_cpu_data.x86 == 0x11)
411 return false;
412
5ce88f6e
BP
413 pr_cont("DRAM ECC error detected on the NB.\n");
414 break;
415
416 case 0xd:
417 pr_cont("Parity error on the DRAM addr/ctl signals.\n");
418 break;
419
420 default:
421 ret = false;
422 break;
423 }
424
425 return ret;
426}
427
428static bool f10h_nb_mce(u16 ec, u8 xec)
429{
430 bool ret = true;
431 u8 offset = 0;
432
433 if (k8_nb_mce(ec, xec))
434 return true;
435
436 switch(xec) {
437 case 0xa ... 0xc:
438 offset = 10;
439 break;
440
441 case 0xe:
442 offset = 11;
443 break;
444
445 case 0xf:
446 if (TLB_ERROR(ec))
447 pr_cont("GART Table Walk data error.\n");
448 else if (BUS_ERROR(ec))
449 pr_cont("DMA Exclusion Vector Table Walk error.\n");
450 else
451 ret = false;
452
453 goto out;
454 break;
455
456 case 0x1c ... 0x1f:
457 offset = 24;
458 break;
459
460 default:
461 ret = false;
462
463 goto out;
464 break;
465 }
466
467 pr_cont("%s.\n", f10h_nb_mce_desc[xec - offset]);
468
469out:
470 return ret;
471}
472
cb9d5ecd 473static bool nb_noop_mce(u16 ec, u8 xec)
5ce88f6e
BP
474{
475 return false;
476}
477
7cfd4a87 478void amd_decode_nb_mce(int node_id, struct mce *m, u32 nbcfg)
549d042d 479{
5ce88f6e
BP
480 u8 xec = (m->status >> 16) & 0x1f;
481 u16 ec = m->status & 0xffff;
7cfd4a87 482 u32 nbsh = (u32)(m->status >> 32);
256f7276 483
5ce88f6e 484 pr_emerg(HW_ERR "Northbridge Error, node %d: ", node_id);
549d042d
BP
485
486 /*
487 * F10h, revD can disable ErrCpu[3:0] so check that first and also the
488 * value encoding has changed so interpret those differently
489 */
490 if ((boot_cpu_data.x86 == 0x10) &&
cec7924f 491 (boot_cpu_data.x86_model > 7)) {
7cfd4a87 492 if (nbsh & K8_NBSH_ERR_CPU_VAL)
5ce88f6e 493 pr_cont(", core: %u", (u8)(nbsh & nb_err_cpumask));
549d042d 494 } else {
5ce88f6e 495 u8 assoc_cpus = nbsh & nb_err_cpumask;
5b89d2f9
BP
496
497 if (assoc_cpus > 0)
498 pr_cont(", core: %d", fls(assoc_cpus) - 1);
5ce88f6e 499 }
5b89d2f9 500
5ce88f6e
BP
501 switch (xec) {
502 case 0x2:
503 pr_cont("Sync error (sync packets on HT link detected).\n");
504 return;
505
506 case 0x3:
507 pr_cont("HT Master abort.\n");
508 return;
509
510 case 0x4:
511 pr_cont("HT Target abort.\n");
512 return;
513
514 case 0x7:
515 pr_cont("NB Watchdog timeout.\n");
516 return;
517
518 case 0x9:
519 pr_cont("SVM DMA Exclusion Vector error.\n");
520 return;
521
522 default:
523 break;
549d042d
BP
524 }
525
5ce88f6e
BP
526 if (!fam_ops->nb_mce(ec, xec))
527 goto wrong_nb_mce;
528
529 if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10)
530 if ((xec == 0x8 || xec == 0x0) && nb_bus_decoder)
531 nb_bus_decoder(node_id, m, nbcfg);
d93cc222 532
5ce88f6e
BP
533 return;
534
535wrong_nb_mce:
536 pr_emerg(HW_ERR "Corrupted NB MCE info?\n");
d93cc222
BP
537}
538EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
539
7cfd4a87 540static void amd_decode_fr_mce(struct mce *m)
53bd5fed 541{
f0157b3a
BP
542 if (boot_cpu_data.x86 == 0xf ||
543 boot_cpu_data.x86 == 0x11)
fe4ea262
BP
544 goto wrong_fr_mce;
545
53bd5fed 546 /* we have only one error signature so match all fields at once. */
fe4ea262
BP
547 if ((m->status & 0xffff) == 0x0f0f) {
548 pr_emerg(HW_ERR "FR Error: CPU Watchdog timer expire.\n");
549 return;
550 }
551
552wrong_fr_mce:
553 pr_emerg(HW_ERR "Corrupted FR MCE info?\n");
53bd5fed
BP
554}
555
6337583d 556static inline void amd_decode_err_code(u16 ec)
d93cc222 557{
549d042d 558 if (TLB_ERROR(ec)) {
c9f281fd 559 pr_emerg(HW_ERR "Transaction: %s, Cache Level: %s\n",
549d042d
BP
560 TT_MSG(ec), LL_MSG(ec));
561 } else if (MEM_ERROR(ec)) {
6337583d 562 pr_emerg(HW_ERR "Transaction: %s, Type: %s, Cache Level: %s\n",
549d042d
BP
563 RRRR_MSG(ec), TT_MSG(ec), LL_MSG(ec));
564 } else if (BUS_ERROR(ec)) {
6337583d 565 pr_emerg(HW_ERR "Transaction: %s (%s), %s, Cache Level: %s, "
d93cc222
BP
566 "Participating Processor: %s\n",
567 RRRR_MSG(ec), II_MSG(ec), TO_MSG(ec), LL_MSG(ec),
568 PP_MSG(ec));
569 } else
c9f281fd 570 pr_emerg(HW_ERR "Huh? Unknown MCE error 0x%x\n", ec);
549d042d 571}
549d042d 572
5ce88f6e
BP
573/*
574 * Filter out unwanted MCE signatures here.
575 */
576static bool amd_filter_mce(struct mce *m)
577{
578 u8 xec = (m->status >> 16) & 0x1f;
579
580 /*
581 * NB GART TLB error reporting is disabled by default.
582 */
583 if (m->bank == 4 && xec == 0x5 && !report_gart_errors)
584 return true;
585
586 return false;
587}
588
9cdeb404 589int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
549d042d 590{
fb253195 591 struct mce *m = (struct mce *)data;
b69b29de 592 int node, ecc;
549d042d 593
5ce88f6e
BP
594 if (amd_filter_mce(m))
595 return NOTIFY_STOP;
596
c9f281fd 597 pr_emerg(HW_ERR "MC%d_STATUS: ", m->bank);
549d042d 598
37b7370a 599 pr_cont("%sorrected error, other errors lost: %s, "
b69b29de
BP
600 "CPU context corrupt: %s",
601 ((m->status & MCI_STATUS_UC) ? "Unc" : "C"),
37b7370a 602 ((m->status & MCI_STATUS_OVER) ? "yes" : "no"),
b69b29de 603 ((m->status & MCI_STATUS_PCC) ? "yes" : "no"));
549d042d 604
b69b29de 605 /* do the two bits[14:13] together */
35d824b2 606 ecc = (m->status >> 45) & 0x3;
b69b29de
BP
607 if (ecc)
608 pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
609
610 pr_cont("\n");
611
51966241
BP
612 switch (m->bank) {
613 case 0:
7cfd4a87 614 amd_decode_dc_mce(m);
51966241 615 break;
d93cc222 616
ab5535e7 617 case 1:
7cfd4a87 618 amd_decode_ic_mce(m);
ab5535e7
BP
619 break;
620
56cad2d6 621 case 2:
7cfd4a87 622 amd_decode_bu_mce(m);
56cad2d6
BP
623 break;
624
f9350efd 625 case 3:
7cfd4a87 626 amd_decode_ls_mce(m);
f9350efd
BP
627 break;
628
51966241 629 case 4:
7cfd4a87
BP
630 node = amd_get_nb_id(m->extcpu);
631 amd_decode_nb_mce(node, m, 0);
51966241
BP
632 break;
633
53bd5fed 634 case 5:
7cfd4a87 635 amd_decode_fr_mce(m);
53bd5fed
BP
636 break;
637
51966241
BP
638 default:
639 break;
b69b29de 640 }
51966241
BP
641
642 amd_decode_err_code(m->status & 0xffff);
fb253195
BP
643
644 return NOTIFY_STOP;
549d042d 645}
9cdeb404 646EXPORT_SYMBOL_GPL(amd_decode_mce);
f436f8bb 647
fb253195
BP
648static struct notifier_block amd_mce_dec_nb = {
649 .notifier_call = amd_decode_mce,
650};
651
f436f8bb
IM
652static int __init mce_amd_init(void)
653{
e045c291
BP
654 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
655 return 0;
656
fda7561f 657 if ((boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x12) &&
9530d608 658 (boot_cpu_data.x86 != 0x14 || boot_cpu_data.x86_model > 0xf))
e045c291
BP
659 return 0;
660
888ab8e6
BP
661 fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL);
662 if (!fam_ops)
663 return -ENOMEM;
664
665 switch (boot_cpu_data.x86) {
666 case 0xf:
667 fam_ops->dc_mce = k8_dc_mce;
dd53bce4 668 fam_ops->ic_mce = k8_ic_mce;
5ce88f6e 669 fam_ops->nb_mce = k8_nb_mce;
888ab8e6
BP
670 break;
671
672 case 0x10:
673 fam_ops->dc_mce = f10h_dc_mce;
dd53bce4 674 fam_ops->ic_mce = k8_ic_mce;
5ce88f6e 675 fam_ops->nb_mce = f10h_nb_mce;
888ab8e6
BP
676 break;
677
f0157b3a
BP
678 case 0x11:
679 fam_ops->dc_mce = k8_dc_mce;
680 fam_ops->ic_mce = k8_ic_mce;
681 fam_ops->nb_mce = f10h_nb_mce;
682 break;
683
9be0bb10
BP
684 case 0x12:
685 fam_ops->dc_mce = f12h_dc_mce;
e7281eb3 686 fam_ops->ic_mce = k8_ic_mce;
cb9d5ecd 687 fam_ops->nb_mce = nb_noop_mce;
9be0bb10
BP
688 break;
689
888ab8e6 690 case 0x14:
5ce88f6e 691 nb_err_cpumask = 0x3;
888ab8e6 692 fam_ops->dc_mce = f14h_dc_mce;
dd53bce4 693 fam_ops->ic_mce = f14h_ic_mce;
cb9d5ecd 694 fam_ops->nb_mce = nb_noop_mce;
888ab8e6
BP
695 break;
696
2be64bfa
BP
697 case 0x15:
698 xec_mask = 0x1f;
25a4f8b0 699 fam_ops->dc_mce = f15h_dc_mce;
2be64bfa
BP
700 break;
701
888ab8e6
BP
702 default:
703 printk(KERN_WARNING "Huh? What family is that: %d?!\n",
704 boot_cpu_data.x86);
705 kfree(fam_ops);
706 return -EINVAL;
707 }
708
9530d608
BP
709 pr_info("MCE: In-kernel MCE decoding enabled.\n");
710
e045c291 711 atomic_notifier_chain_register(&x86_mce_decoder_chain, &amd_mce_dec_nb);
f436f8bb
IM
712
713 return 0;
714}
715early_initcall(mce_amd_init);
0d18b2e3
BP
716
717#ifdef MODULE
718static void __exit mce_amd_exit(void)
719{
fb253195 720 atomic_notifier_chain_unregister(&x86_mce_decoder_chain, &amd_mce_dec_nb);
888ab8e6 721 kfree(fam_ops);
0d18b2e3
BP
722}
723
724MODULE_DESCRIPTION("AMD MCE decoder");
725MODULE_ALIAS("edac-mce-amd");
726MODULE_LICENSE("GPL");
727module_exit(mce_amd_exit);
728#endif
This page took 0.154022 seconds and 5 git commands to generate.