x86/MCE/AMD, EDAC/mce_amd: Add new McaTypes for CS, PSP, and SMU units
[linux-block.git] / drivers / edac / mce_amd.c
CommitLineData
b70ef010 1#include <linux/module.h>
888ab8e6
BP
2#include <linux/slab.h>
3
f3c0891c
BP
4#include <asm/cpu.h>
5
47ca08a4 6#include "mce_amd.h"
b52401ce 7
888ab8e6
BP
8static struct amd_decoder_ops *fam_ops;
9
2be64bfa 10static u8 xec_mask = 0xf;
5ce88f6e 11
549d042d 12static bool report_gart_errors;
5c332202 13static void (*decode_dram_ecc)(int node_id, struct mce *m);
549d042d
BP
14
15void amd_report_gart_errors(bool v)
16{
17 report_gart_errors = v;
18}
19EXPORT_SYMBOL_GPL(amd_report_gart_errors);
20
b0b07a2b 21void amd_register_ecc_decoder(void (*f)(int, struct mce *))
549d042d 22{
5c332202 23 decode_dram_ecc = f;
549d042d
BP
24}
25EXPORT_SYMBOL_GPL(amd_register_ecc_decoder);
26
b0b07a2b 27void amd_unregister_ecc_decoder(void (*f)(int, struct mce *))
549d042d 28{
5c332202
YG
29 if (decode_dram_ecc) {
30 WARN_ON(decode_dram_ecc != f);
549d042d 31
5c332202 32 decode_dram_ecc = NULL;
549d042d
BP
33 }
34}
35EXPORT_SYMBOL_GPL(amd_unregister_ecc_decoder);
36
b52401ce
DT
37/*
38 * string representation for the different MCA reported error types, see F3x48
39 * or MSR0000_0411.
40 */
6337583d
BP
41
42/* transaction type */
0f08669e 43static const char * const tt_msgs[] = { "INSN", "DATA", "GEN", "RESV" };
b52401ce 44
6337583d 45/* cache level */
0f08669e 46static const char * const ll_msgs[] = { "RESV", "L1", "L2", "L3/GEN" };
b52401ce 47
6337583d 48/* memory transaction type */
0f08669e 49static const char * const rrrr_msgs[] = {
6337583d 50 "GEN", "RD", "WR", "DRD", "DWR", "IRD", "PRF", "EV", "SNP"
b52401ce
DT
51};
52
6337583d 53/* participating processor */
ebe2aea8 54const char * const pp_msgs[] = { "SRC", "RES", "OBS", "GEN" };
b70ef010 55EXPORT_SYMBOL_GPL(pp_msgs);
b52401ce 56
6337583d 57/* request timeout */
0f08669e 58static const char * const to_msgs[] = { "no timeout", "timed out" };
b52401ce 59
6337583d 60/* memory or i/o */
0f08669e 61static const char * const ii_msgs[] = { "MEM", "RESV", "IO", "GEN" };
b52401ce 62
980eec8b 63/* internal error type */
0f08669e 64static const char * const uu_msgs[] = { "RESV", "RESV", "HWA", "RESV" };
980eec8b 65
f05c41a9 66static const char * const f15h_mc1_mce_desc[] = {
86039cd4
BP
67 "UC during a demand linefill from L2",
68 "Parity error during data load from IC",
69 "Parity error for IC valid bit",
70 "Main tag parity error",
71 "Parity error in prediction queue",
72 "PFB data/address parity error",
73 "Parity error in the branch status reg",
74 "PFB promotion address error",
75 "Tag error during probe/victimization",
76 "Parity error for IC probe tag valid bit",
77 "PFB non-cacheable bit parity error",
78 "PFB valid bit parity error", /* xec = 0xd */
6c1173a6 79 "Microcode Patch Buffer", /* xec = 010 */
86039cd4
BP
80 "uop queue",
81 "insn buffer",
82 "predecode buffer",
eba4bfb3
AG
83 "fetch address FIFO",
84 "dispatch uop queue"
86039cd4
BP
85};
86
f05c41a9 87static const char * const f15h_mc2_mce_desc[] = {
70fdb494
BP
88 "Fill ECC error on data fills", /* xec = 0x4 */
89 "Fill parity error on insn fills",
90 "Prefetcher request FIFO parity error",
91 "PRQ address parity error",
92 "PRQ data parity error",
93 "WCC Tag ECC error",
94 "WCC Data ECC error",
95 "WCB Data parity error",
b64a99c1 96 "VB Data ECC or parity error",
70fdb494
BP
97 "L2 Tag ECC error", /* xec = 0x10 */
98 "Hard L2 Tag ECC error",
99 "Multiple hits on L2 tag",
100 "XAB parity error",
101 "PRB address parity error"
102};
103
f05c41a9 104static const char * const mc4_mce_desc[] = {
68782673
BP
105 "DRAM ECC error detected on the NB",
106 "CRC error detected on HT link",
107 "Link-defined sync error packets detected on HT link",
108 "HT Master abort",
109 "HT Target abort",
110 "Invalid GART PTE entry during GART table walk",
111 "Unsupported atomic RMW received from an IO link",
112 "Watchdog timeout due to lack of progress",
113 "DRAM ECC error detected on the NB",
114 "SVM DMA Exclusion Vector error",
115 "HT data error detected on link",
116 "Protocol error (link, L3, probe filter)",
117 "NB internal arrays parity error",
118 "DRAM addr/ctl signals parity error",
119 "IO link transmission error",
120 "L3 data cache ECC error", /* xec = 0x1c */
121 "L3 cache tag error",
122 "L3 LRU parity bits error",
123 "ECC Error in the Probe Filter directory"
124};
125
f05c41a9 126static const char * const mc5_mce_desc[] = {
8259a7e5
BP
127 "CPU Watchdog timer expire",
128 "Wakeup array dest tag",
129 "AG payload array",
130 "EX payload array",
131 "IDRF array",
132 "Retire dispatch queue",
133 "Mapper checkpoint array",
134 "Physical register file EX0 port",
135 "Physical register file EX1 port",
136 "Physical register file AG0 port",
137 "Physical register file AG1 port",
138 "Flag register file",
aad19e51
AG
139 "DE error occurred",
140 "Retire status queue"
8259a7e5
BP
141};
142
bc4febe9
AG
143static const char * const mc6_mce_desc[] = {
144 "Hardware Assertion",
145 "Free List",
146 "Physical Register File",
147 "Retire Queue",
148 "Scheduler table",
149 "Status Register File",
150};
151
be0aec23 152/* Scalable MCA error strings */
856095b1 153static const char * const smca_ls_mce_desc[] = {
be0aec23
AG
154 "Load queue parity",
155 "Store queue parity",
156 "Miss address buffer payload parity",
157 "L1 TLB parity",
856095b1 158 "Reserved",
be0aec23
AG
159 "DC tag error type 6",
160 "DC tag error type 1",
161 "Internal error type 1",
162 "Internal error type 2",
163 "Sys Read data error thread 0",
164 "Sys read data error thread 1",
165 "DC tag error type 2",
bdf1bf17 166 "DC data error type 1 (poison consumption)",
be0aec23
AG
167 "DC data error type 2",
168 "DC data error type 3",
169 "DC tag error type 4",
170 "L2 TLB parity",
171 "PDC parity error",
172 "DC tag error type 3",
173 "DC tag error type 5",
174 "L2 fill data error",
175};
176
856095b1 177static const char * const smca_if_mce_desc[] = {
be0aec23
AG
178 "microtag probe port parity error",
179 "IC microtag or full tag multi-hit error",
180 "IC full tag parity",
181 "IC data array parity",
182 "Decoupling queue phys addr parity error",
183 "L0 ITLB parity error",
184 "L1 ITLB parity error",
185 "L2 ITLB parity error",
186 "BPQ snoop parity on Thread 0",
187 "BPQ snoop parity on Thread 1",
188 "L1 BTB multi-match error",
189 "L2 BTB multi-match error",
c019b951
YG
190 "L2 Cache Response Poison error",
191 "System Read Data error",
be0aec23
AG
192};
193
856095b1 194static const char * const smca_l2_mce_desc[] = {
be0aec23
AG
195 "L2M tag multi-way-hit error",
196 "L2M tag ECC error",
197 "L2M data ECC error",
198 "HW assert",
199};
200
856095b1 201static const char * const smca_de_mce_desc[] = {
be0aec23
AG
202 "uop cache tag parity error",
203 "uop cache data parity error",
204 "Insn buffer parity error",
c019b951 205 "uop queue parity error",
be0aec23
AG
206 "Insn dispatch queue parity error",
207 "Fetch address FIFO parity",
208 "Patch RAM data parity",
209 "Patch RAM sequencer parity",
210 "uop buffer parity"
211};
212
856095b1 213static const char * const smca_ex_mce_desc[] = {
be0aec23
AG
214 "Watchdog timeout error",
215 "Phy register file parity",
216 "Flag register file parity",
217 "Immediate displacement register file parity",
218 "Address generator payload parity",
219 "EX payload parity",
220 "Checkpoint queue parity",
221 "Retire dispatch queue parity",
c019b951
YG
222 "Retire status queue parity error",
223 "Scheduling queue parity error",
224 "Branch buffer queue parity error",
be0aec23
AG
225};
226
856095b1 227static const char * const smca_fp_mce_desc[] = {
be0aec23
AG
228 "Physical register file parity",
229 "Freelist parity error",
230 "Schedule queue parity",
231 "NSQ parity error",
232 "Retire queue parity",
233 "Status register file parity",
c019b951 234 "Hardware assertion",
be0aec23
AG
235};
236
856095b1 237static const char * const smca_l3_mce_desc[] = {
be0aec23
AG
238 "Shadow tag macro ECC error",
239 "Shadow tag macro multi-way-hit error",
240 "L3M tag ECC error",
241 "L3M tag multi-way-hit error",
242 "L3M data ECC error",
243 "XI parity, L3 fill done channel error",
244 "L3 victim queue parity",
245 "L3 HW assert",
246};
247
856095b1 248static const char * const smca_cs_mce_desc[] = {
be0aec23
AG
249 "Illegal request from transport layer",
250 "Address violation",
251 "Security violation",
252 "Illegal response from transport layer",
253 "Unexpected response",
254 "Parity error on incoming request or probe response data",
255 "Parity error on incoming read response data",
256 "Atomic request parity",
257 "ECC error on probe filter access",
258};
259
3ad7e748
YG
260static const char * const smca_cs2_mce_desc[] = {
261 "Illegal Request",
262 "Address Violation",
263 "Security Violation",
264 "Illegal Response",
265 "Unexpected Response",
266 "Request or Probe Parity Error",
267 "Read Response Parity Error",
268 "Atomic Request Parity Error",
269 "SDP read response had no match in the CS queue",
270 "Probe Filter Protocol Error",
271 "Probe Filter ECC Error",
272 "SDP read response had an unexpected RETRY error",
273 "Counter overflow error",
274 "Counter underflow error",
275};
276
856095b1 277static const char * const smca_pie_mce_desc[] = {
be0aec23
AG
278 "HW assert",
279 "Internal PIE register security violation",
280 "Error on GMI link",
281 "Poison data written to internal PIE register",
282};
283
856095b1 284static const char * const smca_umc_mce_desc[] = {
be0aec23
AG
285 "DRAM ECC error",
286 "Data poison error on DRAM",
287 "SDP parity error",
288 "Advanced peripheral bus error",
289 "Command/address parity error",
290 "Write data CRC error",
291};
292
856095b1 293static const char * const smca_pb_mce_desc[] = {
be0aec23
AG
294 "Parameter Block RAM ECC error",
295};
296
856095b1 297static const char * const smca_psp_mce_desc[] = {
be0aec23
AG
298 "PSP RAM ECC or parity error",
299};
300
3ad7e748
YG
301static const char * const smca_psp2_mce_desc[] = {
302 "High SRAM ECC or parity error",
303 "Low SRAM ECC or parity error",
304 "Instruction Cache Bank 0 ECC or parity error",
305 "Instruction Cache Bank 1 ECC or parity error",
306 "Instruction Tag Ram 0 parity error",
307 "Instruction Tag Ram 1 parity error",
308 "Data Cache Bank 0 ECC or parity error",
309 "Data Cache Bank 1 ECC or parity error",
310 "Data Cache Bank 2 ECC or parity error",
311 "Data Cache Bank 3 ECC or parity error",
312 "Data Tag Bank 0 parity error",
313 "Data Tag Bank 1 parity error",
314 "Data Tag Bank 2 parity error",
315 "Data Tag Bank 3 parity error",
316 "Dirty Data Ram parity error",
317 "TLB Bank 0 parity error",
318 "TLB Bank 1 parity error",
319 "System Hub Read Buffer ECC or parity error",
320};
321
856095b1 322static const char * const smca_smu_mce_desc[] = {
be0aec23
AG
323 "SMU RAM ECC or parity error",
324};
325
3ad7e748
YG
326static const char * const smca_smu2_mce_desc[] = {
327 "High SRAM ECC or parity error",
328 "Low SRAM ECC or parity error",
329 "Data Cache Bank A ECC or parity error",
330 "Data Cache Bank B ECC or parity error",
331 "Data Tag Cache Bank A ECC or parity error",
332 "Data Tag Cache Bank B ECC or parity error",
333 "Instruction Cache Bank A ECC or parity error",
334 "Instruction Cache Bank B ECC or parity error",
335 "Instruction Tag Cache Bank A ECC or parity error",
336 "Instruction Tag Cache Bank B ECC or parity error",
337 "System Hub Read Buffer ECC or parity error",
338};
339
cbfa447e
YG
340static const char * const smca_mp5_mce_desc[] = {
341 "High SRAM ECC or parity error",
342 "Low SRAM ECC or parity error",
343 "Data Cache Bank A ECC or parity error",
344 "Data Cache Bank B ECC or parity error",
345 "Data Tag Cache Bank A ECC or parity error",
346 "Data Tag Cache Bank B ECC or parity error",
347 "Instruction Cache Bank A ECC or parity error",
348 "Instruction Cache Bank B ECC or parity error",
349 "Instruction Tag Cache Bank A ECC or parity error",
350 "Instruction Tag Cache Bank B ECC or parity error",
351};
352
353static const char * const smca_nbio_mce_desc[] = {
354 "ECC or Parity error",
355 "PCIE error",
356 "SDP ErrEvent error",
357 "SDP Egress Poison Error",
358 "IOHC Internal Poison Error",
359};
360
361static const char * const smca_pcie_mce_desc[] = {
362 "CCIX PER Message logging",
363 "CCIX Read Response with Status: Non-Data Error",
364 "CCIX Write Response with Status: Non-Data Error",
365 "CCIX Read Response with Status: Data Error",
366 "CCIX Non-okay write response with data error",
367};
368
5896820e
YG
369struct smca_mce_desc {
370 const char * const *descs;
371 unsigned int num_descs;
372};
373
374static struct smca_mce_desc smca_mce_descs[] = {
375 [SMCA_LS] = { smca_ls_mce_desc, ARRAY_SIZE(smca_ls_mce_desc) },
376 [SMCA_IF] = { smca_if_mce_desc, ARRAY_SIZE(smca_if_mce_desc) },
377 [SMCA_L2_CACHE] = { smca_l2_mce_desc, ARRAY_SIZE(smca_l2_mce_desc) },
378 [SMCA_DE] = { smca_de_mce_desc, ARRAY_SIZE(smca_de_mce_desc) },
379 [SMCA_EX] = { smca_ex_mce_desc, ARRAY_SIZE(smca_ex_mce_desc) },
380 [SMCA_FP] = { smca_fp_mce_desc, ARRAY_SIZE(smca_fp_mce_desc) },
381 [SMCA_L3_CACHE] = { smca_l3_mce_desc, ARRAY_SIZE(smca_l3_mce_desc) },
382 [SMCA_CS] = { smca_cs_mce_desc, ARRAY_SIZE(smca_cs_mce_desc) },
3ad7e748 383 [SMCA_CS_V2] = { smca_cs2_mce_desc, ARRAY_SIZE(smca_cs2_mce_desc) },
5896820e
YG
384 [SMCA_PIE] = { smca_pie_mce_desc, ARRAY_SIZE(smca_pie_mce_desc) },
385 [SMCA_UMC] = { smca_umc_mce_desc, ARRAY_SIZE(smca_umc_mce_desc) },
386 [SMCA_PB] = { smca_pb_mce_desc, ARRAY_SIZE(smca_pb_mce_desc) },
387 [SMCA_PSP] = { smca_psp_mce_desc, ARRAY_SIZE(smca_psp_mce_desc) },
3ad7e748 388 [SMCA_PSP_V2] = { smca_psp2_mce_desc, ARRAY_SIZE(smca_psp2_mce_desc) },
5896820e 389 [SMCA_SMU] = { smca_smu_mce_desc, ARRAY_SIZE(smca_smu_mce_desc) },
3ad7e748 390 [SMCA_SMU_V2] = { smca_smu2_mce_desc, ARRAY_SIZE(smca_smu2_mce_desc) },
cbfa447e
YG
391 [SMCA_MP5] = { smca_mp5_mce_desc, ARRAY_SIZE(smca_mp5_mce_desc) },
392 [SMCA_NBIO] = { smca_nbio_mce_desc, ARRAY_SIZE(smca_nbio_mce_desc) },
393 [SMCA_PCIE] = { smca_pcie_mce_desc, ARRAY_SIZE(smca_pcie_mce_desc) },
5896820e
YG
394};
395
f05c41a9 396static bool f12h_mc0_mce(u16 ec, u8 xec)
51966241 397{
888ab8e6 398 bool ret = false;
51966241 399
888ab8e6 400 if (MEM_ERROR(ec)) {
62452882 401 u8 ll = LL(ec);
888ab8e6 402 ret = true;
51966241 403
888ab8e6
BP
404 if (ll == LL_L2)
405 pr_cont("during L1 linefill from L2.\n");
406 else if (ll == LL_L1)
62452882 407 pr_cont("Data/Tag %s error.\n", R4_MSG(ec));
888ab8e6
BP
408 else
409 ret = false;
410 }
411 return ret;
412}
51966241 413
f05c41a9 414static bool f10h_mc0_mce(u16 ec, u8 xec)
9be0bb10 415{
62452882 416 if (R4(ec) == R4_GEN && LL(ec) == LL_L1) {
9be0bb10
BP
417 pr_cont("during data scrub.\n");
418 return true;
419 }
f05c41a9 420 return f12h_mc0_mce(ec, xec);
9be0bb10
BP
421}
422
f05c41a9 423static bool k8_mc0_mce(u16 ec, u8 xec)
888ab8e6
BP
424{
425 if (BUS_ERROR(ec)) {
426 pr_cont("during system linefill.\n");
427 return true;
428 }
51966241 429
f05c41a9 430 return f10h_mc0_mce(ec, xec);
888ab8e6
BP
431}
432
980eec8b 433static bool cat_mc0_mce(u16 ec, u8 xec)
888ab8e6 434{
62452882 435 u8 r4 = R4(ec);
888ab8e6
BP
436 bool ret = true;
437
438 if (MEM_ERROR(ec)) {
439
62452882 440 if (TT(ec) != TT_DATA || LL(ec) != LL_L1)
888ab8e6
BP
441 return false;
442
443 switch (r4) {
444 case R4_DRD:
445 case R4_DWR:
446 pr_cont("Data/Tag parity error due to %s.\n",
447 (r4 == R4_DRD ? "load/hw prf" : "store"));
448 break;
449 case R4_EVICT:
450 pr_cont("Copyback parity error on a tag miss.\n");
451 break;
452 case R4_SNOOP:
453 pr_cont("Tag parity error during snoop.\n");
454 break;
455 default:
456 ret = false;
457 }
458 } else if (BUS_ERROR(ec)) {
459
62452882 460 if ((II(ec) != II_MEM && II(ec) != II_IO) || LL(ec) != LL_LG)
888ab8e6
BP
461 return false;
462
463 pr_cont("System read data error on a ");
464
465 switch (r4) {
466 case R4_RD:
467 pr_cont("TLB reload.\n");
468 break;
469 case R4_DWR:
470 pr_cont("store.\n");
471 break;
472 case R4_DRD:
473 pr_cont("load.\n");
474 break;
475 default:
476 ret = false;
477 }
478 } else {
479 ret = false;
480 }
481
482 return ret;
483}
484
f05c41a9 485static bool f15h_mc0_mce(u16 ec, u8 xec)
25a4f8b0
BP
486{
487 bool ret = true;
488
489 if (MEM_ERROR(ec)) {
490
491 switch (xec) {
492 case 0x0:
493 pr_cont("Data Array access error.\n");
494 break;
495
496 case 0x1:
497 pr_cont("UC error during a linefill from L2/NB.\n");
498 break;
499
500 case 0x2:
501 case 0x11:
502 pr_cont("STQ access error.\n");
503 break;
504
505 case 0x3:
506 pr_cont("SCB access error.\n");
507 break;
508
509 case 0x10:
510 pr_cont("Tag error.\n");
511 break;
512
513 case 0x12:
514 pr_cont("LDQ access error.\n");
515 break;
516
517 default:
518 ret = false;
519 }
520 } else if (BUS_ERROR(ec)) {
521
522 if (!xec)
344f0a06 523 pr_cont("System Read Data Error.\n");
25a4f8b0 524 else
344f0a06 525 pr_cont(" Internal error condition type %d.\n", xec);
eba4bfb3
AG
526 } else if (INT_ERROR(ec)) {
527 if (xec <= 0x1f)
528 pr_cont("Hardware Assert.\n");
529 else
530 ret = false;
531
25a4f8b0
BP
532 } else
533 ret = false;
534
535 return ret;
536}
537
f05c41a9 538static void decode_mc0_mce(struct mce *m)
888ab8e6 539{
62452882
BP
540 u16 ec = EC(m->status);
541 u8 xec = XEC(m->status, xec_mask);
888ab8e6 542
f05c41a9 543 pr_emerg(HW_ERR "MC0 Error: ");
888ab8e6
BP
544
545 /* TLB error signatures are the same across families */
546 if (TLB_ERROR(ec)) {
62452882 547 if (TT(ec) == TT_DATA) {
888ab8e6 548 pr_cont("%s TLB %s.\n", LL_MSG(ec),
25a4f8b0
BP
549 ((xec == 2) ? "locked miss"
550 : (xec ? "multimatch" : "parity")));
888ab8e6
BP
551 return;
552 }
f05c41a9 553 } else if (fam_ops->mc0_mce(ec, xec))
25a4f8b0
BP
554 ;
555 else
f05c41a9 556 pr_emerg(HW_ERR "Corrupted MC0 MCE info?\n");
51966241
BP
557}
558
f05c41a9 559static bool k8_mc1_mce(u16 ec, u8 xec)
ab5535e7 560{
62452882 561 u8 ll = LL(ec);
dd53bce4 562 bool ret = true;
ab5535e7 563
dd53bce4
BP
564 if (!MEM_ERROR(ec))
565 return false;
ab5535e7 566
dd53bce4
BP
567 if (ll == 0x2)
568 pr_cont("during a linefill from L2.\n");
569 else if (ll == 0x1) {
62452882 570 switch (R4(ec)) {
dd53bce4
BP
571 case R4_IRD:
572 pr_cont("Parity error during data load.\n");
573 break;
ab5535e7 574
dd53bce4
BP
575 case R4_EVICT:
576 pr_cont("Copyback Parity/Victim error.\n");
577 break;
578
579 case R4_SNOOP:
580 pr_cont("Tag Snoop error.\n");
581 break;
582
583 default:
584 ret = false;
585 break;
586 }
ab5535e7 587 } else
dd53bce4 588 ret = false;
ab5535e7 589
dd53bce4
BP
590 return ret;
591}
592
980eec8b 593static bool cat_mc1_mce(u16 ec, u8 xec)
dd53bce4 594{
62452882 595 u8 r4 = R4(ec);
dd53bce4 596 bool ret = true;
ab5535e7 597
980eec8b
JS
598 if (!MEM_ERROR(ec))
599 return false;
600
601 if (TT(ec) != TT_INSTR)
602 return false;
603
604 if (r4 == R4_IRD)
605 pr_cont("Data/tag array parity error for a tag hit.\n");
606 else if (r4 == R4_SNOOP)
607 pr_cont("Tag error during snoop/victimization.\n");
608 else if (xec == 0x0)
609 pr_cont("Tag parity error from victim castout.\n");
610 else if (xec == 0x2)
611 pr_cont("Microcode patch RAM parity error.\n");
612 else
613 ret = false;
dd53bce4 614
dd53bce4
BP
615 return ret;
616}
617
f05c41a9 618static bool f15h_mc1_mce(u16 ec, u8 xec)
86039cd4
BP
619{
620 bool ret = true;
621
622 if (!MEM_ERROR(ec))
623 return false;
624
625 switch (xec) {
626 case 0x0 ... 0xa:
f05c41a9 627 pr_cont("%s.\n", f15h_mc1_mce_desc[xec]);
86039cd4
BP
628 break;
629
630 case 0xd:
f05c41a9 631 pr_cont("%s.\n", f15h_mc1_mce_desc[xec-2]);
86039cd4
BP
632 break;
633
6c1173a6 634 case 0x10:
f05c41a9 635 pr_cont("%s.\n", f15h_mc1_mce_desc[xec-4]);
6c1173a6
BP
636 break;
637
eba4bfb3 638 case 0x11 ... 0x15:
f05c41a9 639 pr_cont("Decoder %s parity error.\n", f15h_mc1_mce_desc[xec-4]);
86039cd4
BP
640 break;
641
642 default:
643 ret = false;
644 }
645 return ret;
646}
647
f05c41a9 648static void decode_mc1_mce(struct mce *m)
dd53bce4 649{
62452882
BP
650 u16 ec = EC(m->status);
651 u8 xec = XEC(m->status, xec_mask);
dd53bce4 652
f05c41a9 653 pr_emerg(HW_ERR "MC1 Error: ");
dd53bce4
BP
654
655 if (TLB_ERROR(ec))
656 pr_cont("%s TLB %s.\n", LL_MSG(ec),
657 (xec ? "multimatch" : "parity error"));
658 else if (BUS_ERROR(ec)) {
525906bc 659 bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
dd53bce4
BP
660
661 pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
eba4bfb3
AG
662 } else if (INT_ERROR(ec)) {
663 if (xec <= 0x3f)
664 pr_cont("Hardware Assert.\n");
665 else
666 goto wrong_mc1_mce;
f05c41a9 667 } else if (fam_ops->mc1_mce(ec, xec))
dd53bce4
BP
668 ;
669 else
eba4bfb3
AG
670 goto wrong_mc1_mce;
671
672 return;
673
674wrong_mc1_mce:
675 pr_emerg(HW_ERR "Corrupted MC1 MCE info?\n");
ab5535e7
BP
676}
677
4a73d3de 678static bool k8_mc2_mce(u16 ec, u8 xec)
56cad2d6 679{
4a73d3de 680 bool ret = true;
56cad2d6
BP
681
682 if (xec == 0x1)
683 pr_cont(" in the write data buffers.\n");
684 else if (xec == 0x3)
685 pr_cont(" in the victim data buffers.\n");
686 else if (xec == 0x2 && MEM_ERROR(ec))
62452882 687 pr_cont(": %s error in the L2 cache tags.\n", R4_MSG(ec));
56cad2d6
BP
688 else if (xec == 0x0) {
689 if (TLB_ERROR(ec))
50872ccd
BP
690 pr_cont("%s error in a Page Descriptor Cache or Guest TLB.\n",
691 TT_MSG(ec));
56cad2d6
BP
692 else if (BUS_ERROR(ec))
693 pr_cont(": %s/ECC error in data read from NB: %s.\n",
62452882 694 R4_MSG(ec), PP_MSG(ec));
56cad2d6 695 else if (MEM_ERROR(ec)) {
62452882 696 u8 r4 = R4(ec);
56cad2d6 697
62452882 698 if (r4 >= 0x7)
56cad2d6 699 pr_cont(": %s error during data copyback.\n",
62452882
BP
700 R4_MSG(ec));
701 else if (r4 <= 0x1)
56cad2d6 702 pr_cont(": %s parity/ECC error during data "
62452882 703 "access from L2.\n", R4_MSG(ec));
56cad2d6 704 else
4a73d3de 705 ret = false;
56cad2d6 706 } else
4a73d3de 707 ret = false;
56cad2d6 708 } else
4a73d3de 709 ret = false;
56cad2d6 710
4a73d3de 711 return ret;
56cad2d6
BP
712}
713
4a73d3de 714static bool f15h_mc2_mce(u16 ec, u8 xec)
70fdb494 715{
4a73d3de 716 bool ret = true;
70fdb494
BP
717
718 if (TLB_ERROR(ec)) {
719 if (xec == 0x0)
720 pr_cont("Data parity TLB read error.\n");
721 else if (xec == 0x1)
722 pr_cont("Poison data provided for TLB fill.\n");
723 else
4a73d3de 724 ret = false;
70fdb494
BP
725 } else if (BUS_ERROR(ec)) {
726 if (xec > 2)
4a73d3de 727 ret = false;
70fdb494
BP
728
729 pr_cont("Error during attempted NB data read.\n");
730 } else if (MEM_ERROR(ec)) {
731 switch (xec) {
732 case 0x4 ... 0xc:
f05c41a9 733 pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x4]);
70fdb494
BP
734 break;
735
736 case 0x10 ... 0x14:
f05c41a9 737 pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x7]);
70fdb494
BP
738 break;
739
740 default:
4a73d3de 741 ret = false;
70fdb494 742 }
eba4bfb3
AG
743 } else if (INT_ERROR(ec)) {
744 if (xec <= 0x3f)
745 pr_cont("Hardware Assert.\n");
746 else
747 ret = false;
70fdb494
BP
748 }
749
4a73d3de
JS
750 return ret;
751}
752
980eec8b
JS
753static bool f16h_mc2_mce(u16 ec, u8 xec)
754{
755 u8 r4 = R4(ec);
756
757 if (!MEM_ERROR(ec))
758 return false;
759
760 switch (xec) {
761 case 0x04 ... 0x05:
762 pr_cont("%cBUFF parity error.\n", (r4 == R4_RD) ? 'I' : 'O');
763 break;
764
765 case 0x09 ... 0x0b:
766 case 0x0d ... 0x0f:
767 pr_cont("ECC error in L2 tag (%s).\n",
768 ((r4 == R4_GEN) ? "BankReq" :
769 ((r4 == R4_SNOOP) ? "Prb" : "Fill")));
770 break;
771
772 case 0x10 ... 0x19:
773 case 0x1b:
774 pr_cont("ECC error in L2 data array (%s).\n",
775 (((r4 == R4_RD) && !(xec & 0x3)) ? "Hit" :
776 ((r4 == R4_GEN) ? "Attr" :
777 ((r4 == R4_EVICT) ? "Vict" : "Fill"))));
778 break;
779
780 case 0x1c ... 0x1d:
781 case 0x1f:
782 pr_cont("Parity error in L2 attribute bits (%s).\n",
783 ((r4 == R4_RD) ? "Hit" :
784 ((r4 == R4_GEN) ? "Attr" : "Fill")));
785 break;
786
787 default:
788 return false;
789 }
790
791 return true;
792}
793
4a73d3de
JS
794static void decode_mc2_mce(struct mce *m)
795{
796 u16 ec = EC(m->status);
797 u8 xec = XEC(m->status, xec_mask);
70fdb494 798
4a73d3de
JS
799 pr_emerg(HW_ERR "MC2 Error: ");
800
801 if (!fam_ops->mc2_mce(ec, xec))
802 pr_cont(HW_ERR "Corrupted MC2 MCE info?\n");
70fdb494
BP
803}
804
f05c41a9 805static void decode_mc3_mce(struct mce *m)
f9350efd 806{
62452882
BP
807 u16 ec = EC(m->status);
808 u8 xec = XEC(m->status, xec_mask);
ded50623 809
b18434ca 810 if (boot_cpu_data.x86 >= 0x14) {
f05c41a9 811 pr_emerg("You shouldn't be seeing MC3 MCE on this cpu family,"
ded50623
BP
812 " please report on LKML.\n");
813 return;
814 }
f9350efd 815
f05c41a9 816 pr_emerg(HW_ERR "MC3 Error");
f9350efd
BP
817
818 if (xec == 0x0) {
62452882 819 u8 r4 = R4(ec);
f9350efd 820
ded50623 821 if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR))
f05c41a9 822 goto wrong_mc3_mce;
f9350efd 823
62452882 824 pr_cont(" during %s.\n", R4_MSG(ec));
ded50623 825 } else
f05c41a9 826 goto wrong_mc3_mce;
ded50623 827
f9350efd
BP
828 return;
829
f05c41a9
BP
830 wrong_mc3_mce:
831 pr_emerg(HW_ERR "Corrupted MC3 MCE info?\n");
f9350efd
BP
832}
833
f05c41a9 834static void decode_mc4_mce(struct mce *m)
5ce88f6e 835{
f3c0891c 836 unsigned int fam = x86_family(m->cpuid);
68782673
BP
837 int node_id = amd_get_nb_id(m->extcpu);
838 u16 ec = EC(m->status);
839 u8 xec = XEC(m->status, 0x1f);
840 u8 offset = 0;
5ce88f6e 841
f05c41a9 842 pr_emerg(HW_ERR "MC4 Error (node %d): ", node_id);
5ce88f6e 843
68782673
BP
844 switch (xec) {
845 case 0x0 ... 0xe:
5ce88f6e 846
68782673
BP
847 /* special handling for DRAM ECCs */
848 if (xec == 0x0 || xec == 0x8) {
849 /* no ECCs on F11h */
f3c0891c 850 if (fam == 0x11)
f05c41a9 851 goto wrong_mc4_mce;
5ce88f6e 852
f05c41a9 853 pr_cont("%s.\n", mc4_mce_desc[xec]);
5ce88f6e 854
5c332202
YG
855 if (decode_dram_ecc)
856 decode_dram_ecc(node_id, m);
68782673
BP
857 return;
858 }
5ce88f6e
BP
859 break;
860
861 case 0xf:
862 if (TLB_ERROR(ec))
863 pr_cont("GART Table Walk data error.\n");
864 else if (BUS_ERROR(ec))
865 pr_cont("DMA Exclusion Vector Table Walk error.\n");
866 else
f05c41a9 867 goto wrong_mc4_mce;
68782673 868 return;
5ce88f6e 869
05cd667d 870 case 0x19:
f3c0891c 871 if (fam == 0x15 || fam == 0x16)
05cd667d
BP
872 pr_cont("Compute Unit Data Error.\n");
873 else
f05c41a9 874 goto wrong_mc4_mce;
68782673 875 return;
05cd667d 876
5ce88f6e 877 case 0x1c ... 0x1f:
68782673 878 offset = 13;
5ce88f6e
BP
879 break;
880
881 default:
f05c41a9 882 goto wrong_mc4_mce;
68782673 883 }
5ce88f6e 884
f05c41a9 885 pr_cont("%s.\n", mc4_mce_desc[xec - offset]);
5ce88f6e
BP
886 return;
887
f05c41a9
BP
888 wrong_mc4_mce:
889 pr_emerg(HW_ERR "Corrupted MC4 MCE info?\n");
d93cc222 890}
d93cc222 891
f05c41a9 892static void decode_mc5_mce(struct mce *m)
53bd5fed 893{
f3c0891c 894 unsigned int fam = x86_family(m->cpuid);
eba4bfb3 895 u16 ec = EC(m->status);
62452882 896 u8 xec = XEC(m->status, xec_mask);
8259a7e5 897
f3c0891c 898 if (fam == 0xf || fam == 0x11)
f05c41a9 899 goto wrong_mc5_mce;
fe4ea262 900
f05c41a9 901 pr_emerg(HW_ERR "MC5 Error: ");
8259a7e5 902
eba4bfb3
AG
903 if (INT_ERROR(ec)) {
904 if (xec <= 0x1f) {
905 pr_cont("Hardware Assert.\n");
906 return;
907 } else
908 goto wrong_mc5_mce;
909 }
910
8259a7e5 911 if (xec == 0x0 || xec == 0xc)
f05c41a9 912 pr_cont("%s.\n", mc5_mce_desc[xec]);
aad19e51 913 else if (xec <= 0xd)
f05c41a9 914 pr_cont("%s parity error.\n", mc5_mce_desc[xec]);
8259a7e5 915 else
f05c41a9 916 goto wrong_mc5_mce;
8259a7e5
BP
917
918 return;
fe4ea262 919
f05c41a9
BP
920 wrong_mc5_mce:
921 pr_emerg(HW_ERR "Corrupted MC5 MCE info?\n");
53bd5fed
BP
922}
923
f05c41a9 924static void decode_mc6_mce(struct mce *m)
b8f85c47 925{
62452882 926 u8 xec = XEC(m->status, xec_mask);
b8f85c47 927
f05c41a9 928 pr_emerg(HW_ERR "MC6 Error: ");
b8f85c47 929
bc4febe9 930 if (xec > 0x5)
f05c41a9 931 goto wrong_mc6_mce;
b8f85c47 932
bc4febe9 933 pr_cont("%s parity error.\n", mc6_mce_desc[xec]);
b8f85c47
BP
934 return;
935
f05c41a9
BP
936 wrong_mc6_mce:
937 pr_emerg(HW_ERR "Corrupted MC6 MCE info?\n");
b8f85c47
BP
938}
939
be0aec23 940/* Decode errors according to Scalable MCA specification */
4ab1784b 941static void decode_smca_error(struct mce *m)
be0aec23 942{
1ce9cd7f 943 struct smca_hwid *hwid;
68627a69 944 enum smca_bank_types bank_type;
be0aec23 945 const char *ip_name;
5896820e 946 u8 xec = XEC(m->status, xec_mask);
be0aec23 947
5896820e 948 if (m->bank >= ARRAY_SIZE(smca_banks))
be0aec23 949 return;
be0aec23 950
1ce9cd7f
BP
951 hwid = smca_banks[m->bank].hwid;
952 if (!hwid)
be0aec23 953 return;
be0aec23 954
1ce9cd7f 955 bank_type = hwid->bank_type;
68627a69
YG
956
957 if (bank_type == SMCA_RESERVED) {
958 pr_emerg(HW_ERR "Bank %d is reserved.\n", m->bank);
959 return;
960 }
961
c09a8c40 962 ip_name = smca_get_long_name(bank_type);
be0aec23 963
5896820e 964 pr_emerg(HW_ERR "%s Extended Error Code: %d\n", ip_name, xec);
be0aec23 965
5896820e
YG
966 /* Only print the decode of valid error codes */
967 if (xec < smca_mce_descs[bank_type].num_descs &&
1ce9cd7f 968 (hwid->xec_bitmap & BIT_ULL(xec))) {
5896820e
YG
969 pr_emerg(HW_ERR "%s Error: ", ip_name);
970 pr_cont("%s.\n", smca_mce_descs[bank_type].descs[xec]);
971 }
5c332202 972
5c332202 973 if (bank_type == SMCA_UMC && xec == 0 && decode_dram_ecc)
fbe63acf 974 decode_dram_ecc(cpu_to_node(m->extcpu), m);
be0aec23
AG
975}
976
6337583d 977static inline void amd_decode_err_code(u16 ec)
d93cc222 978{
980eec8b
JS
979 if (INT_ERROR(ec)) {
980 pr_emerg(HW_ERR "internal: %s\n", UU_MSG(ec));
981 return;
982 }
fa7ae8cc
BP
983
984 pr_emerg(HW_ERR "cache level: %s", LL_MSG(ec));
985
986 if (BUS_ERROR(ec))
987 pr_cont(", mem/io: %s", II_MSG(ec));
988 else
989 pr_cont(", tx: %s", TT_MSG(ec));
990
991 if (MEM_ERROR(ec) || BUS_ERROR(ec)) {
992 pr_cont(", mem-tx: %s", R4_MSG(ec));
993
994 if (BUS_ERROR(ec))
995 pr_cont(", part-proc: %s (%s)", PP_MSG(ec), TO_MSG(ec));
996 }
997
998 pr_cont("\n");
549d042d 999}
549d042d 1000
5ce88f6e
BP
1001/*
1002 * Filter out unwanted MCE signatures here.
1003 */
1004static bool amd_filter_mce(struct mce *m)
1005{
5ce88f6e
BP
1006 /*
1007 * NB GART TLB error reporting is disabled by default.
1008 */
39844347 1009 if (m->bank == 4 && XEC(m->status, 0x1f) == 0x5 && !report_gart_errors)
5ce88f6e
BP
1010 return true;
1011
1012 return false;
1013}
1014
d5c6770d
BP
1015static const char *decode_error_status(struct mce *m)
1016{
1017 if (m->status & MCI_STATUS_UC) {
1018 if (m->status & MCI_STATUS_PCC)
1019 return "System Fatal error.";
1020 if (m->mcgstatus & MCG_STATUS_RIPV)
1021 return "Uncorrected, software restartable error.";
1022 return "Uncorrected, software containable error.";
1023 }
1024
1025 if (m->status & MCI_STATUS_DEFERRED)
67d7fd30 1026 return "Deferred error, no action required.";
d5c6770d
BP
1027
1028 return "Corrected error, no action required.";
1029}
1030
1fbcd909
BP
1031static int
1032amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
549d042d 1033{
fb253195 1034 struct mce *m = (struct mce *)data;
f3c0891c 1035 unsigned int fam = x86_family(m->cpuid);
b0b07a2b 1036 int ecc;
549d042d 1037
5ce88f6e
BP
1038 if (amd_filter_mce(m))
1039 return NOTIFY_STOP;
1040
fd0f5fff
BP
1041 pr_emerg(HW_ERR "%s\n", decode_error_status(m));
1042
1043 pr_emerg(HW_ERR "CPU:%d (%x:%x:%x) MC%d_STATUS[%s|%s|%s|%s|%s",
1044 m->extcpu,
f3c0891c 1045 fam, x86_model(m->cpuid), x86_stepping(m->cpuid),
fd0f5fff
BP
1046 m->bank,
1047 ((m->status & MCI_STATUS_OVER) ? "Over" : "-"),
99e1dfb7
AG
1048 ((m->status & MCI_STATUS_UC) ? "UE" :
1049 (m->status & MCI_STATUS_DEFERRED) ? "-" : "CE"),
fd0f5fff
BP
1050 ((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"),
1051 ((m->status & MCI_STATUS_PCC) ? "PCC" : "-"),
1052 ((m->status & MCI_STATUS_ADDRV) ? "AddrV" : "-"));
1053
f3c0891c 1054 if (fam >= 0x15) {
a6c14dce
YG
1055 pr_cont("|%s", (m->status & MCI_STATUS_DEFERRED ? "Deferred" : "-"));
1056
1057 /* F15h, bank4, bit 43 is part of McaStatSubCache. */
f3c0891c 1058 if (fam != 0x15 || m->bank != 4)
a6c14dce
YG
1059 pr_cont("|%s", (m->status & MCI_STATUS_POISON ? "Poison" : "-"));
1060 }
fd0f5fff 1061
a348ed83 1062 if (boot_cpu_has(X86_FEATURE_SMCA)) {
be0aec23
AG
1063 u32 low, high;
1064 u32 addr = MSR_AMD64_SMCA_MCx_CONFIG(m->bank);
1065
b300e873
YG
1066 pr_cont("|%s", ((m->status & MCI_STATUS_SYNDV) ? "SyndV" : "-"));
1067
be0aec23
AG
1068 if (!rdmsr_safe(addr, &low, &high) &&
1069 (low & MCI_CONFIG_MCAX))
1070 pr_cont("|%s", ((m->status & MCI_STATUS_TCC) ? "TCC" : "-"));
1071 }
1072
fd0f5fff
BP
1073 /* do the two bits[14:13] together */
1074 ecc = (m->status >> 45) & 0x3;
1075 if (ecc)
1076 pr_cont("|%sECC", ((ecc == 2) ? "C" : "U"));
1077
1078 pr_cont("]: 0x%016llx\n", m->status);
1079
1080 if (m->status & MCI_STATUS_ADDRV)
75bf2f64 1081 pr_emerg(HW_ERR "Error Addr: 0x%016llx\n", m->addr);
fd0f5fff 1082
a348ed83 1083 if (boot_cpu_has(X86_FEATURE_SMCA)) {
75bf2f64
YG
1084 pr_emerg(HW_ERR "IPID: 0x%016llx", m->ipid);
1085
b300e873
YG
1086 if (m->status & MCI_STATUS_SYNDV)
1087 pr_cont(", Syndrome: 0x%016llx", m->synd);
1088
1089 pr_cont("\n");
1090
4ab1784b 1091 decode_smca_error(m);
be0aec23 1092 goto err_code;
75bf2f64 1093 }
be0aec23 1094
0bceab67
BP
1095 if (m->tsc)
1096 pr_emerg(HW_ERR "TSC: %llu\n", m->tsc);
1097
fd0f5fff
BP
1098 if (!fam_ops)
1099 goto err_code;
1100
51966241
BP
1101 switch (m->bank) {
1102 case 0:
f05c41a9 1103 decode_mc0_mce(m);
51966241 1104 break;
d93cc222 1105
ab5535e7 1106 case 1:
f05c41a9 1107 decode_mc1_mce(m);
ab5535e7
BP
1108 break;
1109
56cad2d6 1110 case 2:
4a73d3de 1111 decode_mc2_mce(m);
56cad2d6
BP
1112 break;
1113
f9350efd 1114 case 3:
f05c41a9 1115 decode_mc3_mce(m);
f9350efd
BP
1116 break;
1117
51966241 1118 case 4:
f05c41a9 1119 decode_mc4_mce(m);
51966241
BP
1120 break;
1121
53bd5fed 1122 case 5:
f05c41a9 1123 decode_mc5_mce(m);
53bd5fed
BP
1124 break;
1125
b8f85c47 1126 case 6:
f05c41a9 1127 decode_mc6_mce(m);
b8f85c47
BP
1128 break;
1129
51966241
BP
1130 default:
1131 break;
b69b29de 1132 }
51966241 1133
fd0f5fff 1134 err_code:
51966241 1135 amd_decode_err_code(m->status & 0xffff);
fb253195
BP
1136
1137 return NOTIFY_STOP;
549d042d 1138}
f436f8bb 1139
fb253195
BP
1140static struct notifier_block amd_mce_dec_nb = {
1141 .notifier_call = amd_decode_mce,
9026cc82 1142 .priority = MCE_PRIO_EDAC,
fb253195
BP
1143};
1144
f436f8bb
IM
1145static int __init mce_amd_init(void)
1146{
bad11e03
BP
1147 struct cpuinfo_x86 *c = &boot_cpu_data;
1148
c4a3e946
PW
1149 if (c->x86_vendor != X86_VENDOR_AMD &&
1150 c->x86_vendor != X86_VENDOR_HYGON)
fd0f5fff 1151 return -ENODEV;
e045c291 1152
888ab8e6
BP
1153 fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL);
1154 if (!fam_ops)
1155 return -ENOMEM;
1156
bad11e03 1157 switch (c->x86) {
888ab8e6 1158 case 0xf:
f05c41a9
BP
1159 fam_ops->mc0_mce = k8_mc0_mce;
1160 fam_ops->mc1_mce = k8_mc1_mce;
4a73d3de 1161 fam_ops->mc2_mce = k8_mc2_mce;
888ab8e6
BP
1162 break;
1163
1164 case 0x10:
f05c41a9
BP
1165 fam_ops->mc0_mce = f10h_mc0_mce;
1166 fam_ops->mc1_mce = k8_mc1_mce;
4a73d3de 1167 fam_ops->mc2_mce = k8_mc2_mce;
888ab8e6
BP
1168 break;
1169
f0157b3a 1170 case 0x11:
f05c41a9
BP
1171 fam_ops->mc0_mce = k8_mc0_mce;
1172 fam_ops->mc1_mce = k8_mc1_mce;
4a73d3de 1173 fam_ops->mc2_mce = k8_mc2_mce;
f0157b3a
BP
1174 break;
1175
9be0bb10 1176 case 0x12:
f05c41a9
BP
1177 fam_ops->mc0_mce = f12h_mc0_mce;
1178 fam_ops->mc1_mce = k8_mc1_mce;
4a73d3de 1179 fam_ops->mc2_mce = k8_mc2_mce;
9be0bb10
BP
1180 break;
1181
888ab8e6 1182 case 0x14:
980eec8b
JS
1183 fam_ops->mc0_mce = cat_mc0_mce;
1184 fam_ops->mc1_mce = cat_mc1_mce;
4a73d3de 1185 fam_ops->mc2_mce = k8_mc2_mce;
888ab8e6
BP
1186 break;
1187
2be64bfa 1188 case 0x15:
eba4bfb3
AG
1189 xec_mask = c->x86_model == 0x60 ? 0x3f : 0x1f;
1190
f05c41a9
BP
1191 fam_ops->mc0_mce = f15h_mc0_mce;
1192 fam_ops->mc1_mce = f15h_mc1_mce;
4a73d3de 1193 fam_ops->mc2_mce = f15h_mc2_mce;
2be64bfa
BP
1194 break;
1195
980eec8b
JS
1196 case 0x16:
1197 xec_mask = 0x1f;
1198 fam_ops->mc0_mce = cat_mc0_mce;
1199 fam_ops->mc1_mce = cat_mc1_mce;
1200 fam_ops->mc2_mce = f16h_mc2_mce;
1201 break;
1202
be0aec23 1203 case 0x17:
c4a3e946 1204 case 0x18:
be0aec23 1205 xec_mask = 0x3f;
a348ed83 1206 if (!boot_cpu_has(X86_FEATURE_SMCA)) {
be0aec23
AG
1207 printk(KERN_WARNING "Decoding supported only on Scalable MCA processors.\n");
1208 goto err_out;
1209 }
1210 break;
1211
888ab8e6 1212 default:
ec3e82d6 1213 printk(KERN_WARNING "Huh? What family is it: 0x%x?!\n", c->x86);
be0aec23 1214 goto err_out;
888ab8e6
BP
1215 }
1216
9530d608
BP
1217 pr_info("MCE: In-kernel MCE decoding enabled.\n");
1218
3653ada5 1219 mce_register_decode_chain(&amd_mce_dec_nb);
f436f8bb
IM
1220
1221 return 0;
be0aec23
AG
1222
1223err_out:
1224 kfree(fam_ops);
1225 fam_ops = NULL;
1226 return -EINVAL;
f436f8bb
IM
1227}
1228early_initcall(mce_amd_init);
0d18b2e3
BP
1229
1230#ifdef MODULE
1231static void __exit mce_amd_exit(void)
1232{
3653ada5 1233 mce_unregister_decode_chain(&amd_mce_dec_nb);
888ab8e6 1234 kfree(fam_ops);
0d18b2e3
BP
1235}
1236
1237MODULE_DESCRIPTION("AMD MCE decoder");
1238MODULE_ALIAS("edac-mce-amd");
1239MODULE_LICENSE("GPL");
1240module_exit(mce_amd_exit);
1241#endif