blob: afda6de5d7e3727ac831ed761bc51ce856002443 [file] [log] [blame]
Borislav Petkovb70ef012009-06-25 19:32:38 +02001#include <linux/module.h>
Borislav Petkov888ab8e2010-08-18 15:11:35 +02002#include <linux/slab.h>
3
Borislav Petkov47ca08a2010-09-27 15:30:39 +02004#include "mce_amd.h"
Doug Thompsonb52401c2009-05-06 17:57:20 +02005
Borislav Petkov888ab8e2010-08-18 15:11:35 +02006static struct amd_decoder_ops *fam_ops;
7
Borislav Petkov2be64bf2010-09-17 19:11:47 +02008static u8 xec_mask = 0xf;
Borislav Petkov5ce88f62010-08-31 18:28:08 +02009static u8 nb_err_cpumask = 0xf;
10
Borislav Petkov549d0422009-07-24 13:51:42 +020011static bool report_gart_errors;
Borislav Petkov7cfd4a82010-09-01 14:45:20 +020012static void (*nb_bus_decoder)(int node_id, struct mce *m, u32 nbcfg);
Borislav Petkov549d0422009-07-24 13:51:42 +020013
14void amd_report_gart_errors(bool v)
15{
16 report_gart_errors = v;
17}
18EXPORT_SYMBOL_GPL(amd_report_gart_errors);
19
Borislav Petkov7cfd4a82010-09-01 14:45:20 +020020void amd_register_ecc_decoder(void (*f)(int, struct mce *, u32))
Borislav Petkov549d0422009-07-24 13:51:42 +020021{
22 nb_bus_decoder = f;
23}
24EXPORT_SYMBOL_GPL(amd_register_ecc_decoder);
25
Borislav Petkov7cfd4a82010-09-01 14:45:20 +020026void amd_unregister_ecc_decoder(void (*f)(int, struct mce *, u32))
Borislav Petkov549d0422009-07-24 13:51:42 +020027{
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
Doug Thompsonb52401c2009-05-06 17:57:20 +020036/*
37 * string representation for the different MCA reported error types, see F3x48
38 * or MSR0000_0411.
39 */
Borislav Petkov63375832010-09-06 18:13:39 +020040
41/* transaction type */
42const char *tt_msgs[] = { "INSN", "DATA", "GEN", "RESV" };
Borislav Petkovb70ef012009-06-25 19:32:38 +020043EXPORT_SYMBOL_GPL(tt_msgs);
Doug Thompsonb52401c2009-05-06 17:57:20 +020044
Borislav Petkov63375832010-09-06 18:13:39 +020045/* cache level */
46const char *ll_msgs[] = { "RESV", "L1", "L2", "L3/GEN" };
Borislav Petkovb70ef012009-06-25 19:32:38 +020047EXPORT_SYMBOL_GPL(ll_msgs);
Doug Thompsonb52401c2009-05-06 17:57:20 +020048
Borislav Petkov63375832010-09-06 18:13:39 +020049/* memory transaction type */
Doug Thompsonb52401c2009-05-06 17:57:20 +020050const char *rrrr_msgs[] = {
Borislav Petkov63375832010-09-06 18:13:39 +020051 "GEN", "RD", "WR", "DRD", "DWR", "IRD", "PRF", "EV", "SNP"
Doug Thompsonb52401c2009-05-06 17:57:20 +020052};
Borislav Petkovb70ef012009-06-25 19:32:38 +020053EXPORT_SYMBOL_GPL(rrrr_msgs);
Doug Thompsonb52401c2009-05-06 17:57:20 +020054
Borislav Petkov63375832010-09-06 18:13:39 +020055/* participating processor */
56const char *pp_msgs[] = { "SRC", "RES", "OBS", "GEN" };
Borislav Petkovb70ef012009-06-25 19:32:38 +020057EXPORT_SYMBOL_GPL(pp_msgs);
Doug Thompsonb52401c2009-05-06 17:57:20 +020058
Borislav Petkov63375832010-09-06 18:13:39 +020059/* request timeout */
60const char *to_msgs[] = { "no timeout", "timed out" };
Borislav Petkovb70ef012009-06-25 19:32:38 +020061EXPORT_SYMBOL_GPL(to_msgs);
Doug Thompsonb52401c2009-05-06 17:57:20 +020062
Borislav Petkov63375832010-09-06 18:13:39 +020063/* memory or i/o */
64const char *ii_msgs[] = { "MEM", "RESV", "IO", "GEN" };
Borislav Petkovb70ef012009-06-25 19:32:38 +020065EXPORT_SYMBOL_GPL(ii_msgs);
Doug Thompsonb52401c2009-05-06 17:57:20 +020066
Borislav Petkov5ce88f62010-08-31 18:28:08 +020067static 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"
Doug Thompsonb52401c2009-05-06 17:57:20 +020076};
Borislav Petkov549d0422009-07-24 13:51:42 +020077
Borislav Petkov86039cd2010-11-08 15:03:35 +010078static 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
Borislav Petkov70fdb492010-09-21 20:45:10 +020098static 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
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200115static const char * const fr_ex_mce_desc[] = {
116 "CPU Watchdog timer expire",
117 "Wakeup array dest tag",
118 "AG payload array",
119 "EX payload array",
120 "IDRF array",
121 "Retire dispatch queue",
122 "Mapper checkpoint array",
123 "Physical register file EX0 port",
124 "Physical register file EX1 port",
125 "Physical register file AG0 port",
126 "Physical register file AG1 port",
127 "Flag register file",
128 "DE correctable error could not be corrected"
129};
130
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200131static bool f12h_dc_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200132{
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200133 bool ret = false;
134
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200135 if (MEM_ERROR(ec)) {
136 u8 ll = ec & 0x3;
137 ret = true;
138
139 if (ll == LL_L2)
140 pr_cont("during L1 linefill from L2.\n");
141 else if (ll == LL_L1)
142 pr_cont("Data/Tag %s error.\n", RRRR_MSG(ec));
143 else
144 ret = false;
145 }
146 return ret;
147}
148
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200149static bool f10h_dc_mce(u16 ec, u8 xec)
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200150{
151 u8 r4 = (ec >> 4) & 0xf;
152 u8 ll = ec & 0x3;
153
154 if (r4 == R4_GEN && ll == LL_L1) {
155 pr_cont("during data scrub.\n");
156 return true;
157 }
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200158 return f12h_dc_mce(ec, xec);
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200159}
160
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200161static bool k8_dc_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200162{
163 if (BUS_ERROR(ec)) {
164 pr_cont("during system linefill.\n");
165 return true;
166 }
167
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200168 return f10h_dc_mce(ec, xec);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200169}
170
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200171static bool f14h_dc_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200172{
173 u8 r4 = (ec >> 4) & 0xf;
174 u8 ll = ec & 0x3;
175 u8 tt = (ec >> 2) & 0x3;
176 u8 ii = tt;
177 bool ret = true;
178
179 if (MEM_ERROR(ec)) {
180
181 if (tt != TT_DATA || ll != LL_L1)
182 return false;
183
184 switch (r4) {
185 case R4_DRD:
186 case R4_DWR:
187 pr_cont("Data/Tag parity error due to %s.\n",
188 (r4 == R4_DRD ? "load/hw prf" : "store"));
189 break;
190 case R4_EVICT:
191 pr_cont("Copyback parity error on a tag miss.\n");
192 break;
193 case R4_SNOOP:
194 pr_cont("Tag parity error during snoop.\n");
195 break;
196 default:
197 ret = false;
198 }
199 } else if (BUS_ERROR(ec)) {
200
201 if ((ii != II_MEM && ii != II_IO) || ll != LL_LG)
202 return false;
203
204 pr_cont("System read data error on a ");
205
206 switch (r4) {
207 case R4_RD:
208 pr_cont("TLB reload.\n");
209 break;
210 case R4_DWR:
211 pr_cont("store.\n");
212 break;
213 case R4_DRD:
214 pr_cont("load.\n");
215 break;
216 default:
217 ret = false;
218 }
219 } else {
220 ret = false;
221 }
222
223 return ret;
224}
225
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200226static bool f15h_dc_mce(u16 ec, u8 xec)
227{
228 bool ret = true;
229
230 if (MEM_ERROR(ec)) {
231
232 switch (xec) {
233 case 0x0:
234 pr_cont("Data Array access error.\n");
235 break;
236
237 case 0x1:
238 pr_cont("UC error during a linefill from L2/NB.\n");
239 break;
240
241 case 0x2:
242 case 0x11:
243 pr_cont("STQ access error.\n");
244 break;
245
246 case 0x3:
247 pr_cont("SCB access error.\n");
248 break;
249
250 case 0x10:
251 pr_cont("Tag error.\n");
252 break;
253
254 case 0x12:
255 pr_cont("LDQ access error.\n");
256 break;
257
258 default:
259 ret = false;
260 }
261 } else if (BUS_ERROR(ec)) {
262
263 if (!xec)
264 pr_cont("during system linefill.\n");
265 else
266 pr_cont(" Internal %s condition.\n",
267 ((xec == 1) ? "livelock" : "deadlock"));
268 } else
269 ret = false;
270
271 return ret;
272}
273
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200274static void amd_decode_dc_mce(struct mce *m)
Borislav Petkov51966242009-07-28 13:50:43 +0200275{
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200276 u16 ec = m->status & 0xffff;
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200277 u8 xec = (m->status >> 16) & xec_mask;
Borislav Petkov51966242009-07-28 13:50:43 +0200278
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200279 pr_emerg(HW_ERR "Data Cache Error: ");
Borislav Petkov51966242009-07-28 13:50:43 +0200280
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200281 /* TLB error signatures are the same across families */
282 if (TLB_ERROR(ec)) {
283 u8 tt = (ec >> 2) & 0x3;
Borislav Petkov51966242009-07-28 13:50:43 +0200284
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200285 if (tt == TT_DATA) {
286 pr_cont("%s TLB %s.\n", LL_MSG(ec),
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200287 ((xec == 2) ? "locked miss"
288 : (xec ? "multimatch" : "parity")));
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200289 return;
290 }
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200291 } else if (fam_ops->dc_mce(ec, xec))
292 ;
293 else
294 pr_emerg(HW_ERR "Corrupted DC MCE info?\n");
Borislav Petkov51966242009-07-28 13:50:43 +0200295}
296
Borislav Petkov86039cd2010-11-08 15:03:35 +0100297static bool k8_ic_mce(u16 ec, u8 xec)
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200298{
299 u8 ll = ec & 0x3;
300 u8 r4 = (ec >> 4) & 0xf;
301 bool ret = true;
302
303 if (!MEM_ERROR(ec))
304 return false;
305
306 if (ll == 0x2)
307 pr_cont("during a linefill from L2.\n");
308 else if (ll == 0x1) {
309 switch (r4) {
310 case R4_IRD:
311 pr_cont("Parity error during data load.\n");
312 break;
313
314 case R4_EVICT:
315 pr_cont("Copyback Parity/Victim error.\n");
316 break;
317
318 case R4_SNOOP:
319 pr_cont("Tag Snoop error.\n");
320 break;
321
322 default:
323 ret = false;
324 break;
325 }
326 } else
327 ret = false;
328
329 return ret;
330}
331
Borislav Petkov86039cd2010-11-08 15:03:35 +0100332static bool f14h_ic_mce(u16 ec, u8 xec)
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200333{
334 u8 ll = ec & 0x3;
335 u8 tt = (ec >> 2) & 0x3;
336 u8 r4 = (ec >> 4) & 0xf;
337 bool ret = true;
338
339 if (MEM_ERROR(ec)) {
340 if (tt != 0 || ll != 1)
341 ret = false;
342
343 if (r4 == R4_IRD)
344 pr_cont("Data/tag array parity error for a tag hit.\n");
345 else if (r4 == R4_SNOOP)
346 pr_cont("Tag error during snoop/victimization.\n");
347 else
348 ret = false;
349 }
350 return ret;
351}
352
Borislav Petkov86039cd2010-11-08 15:03:35 +0100353static bool f15h_ic_mce(u16 ec, u8 xec)
354{
355 bool ret = true;
356
357 if (!MEM_ERROR(ec))
358 return false;
359
360 switch (xec) {
361 case 0x0 ... 0xa:
362 pr_cont("%s.\n", f15h_ic_mce_desc[xec]);
363 break;
364
365 case 0xd:
366 pr_cont("%s.\n", f15h_ic_mce_desc[xec-2]);
367 break;
368
369 case 0x10 ... 0x14:
370 pr_cont("Decoder %s parity error.\n", f15h_ic_mce_desc[xec-4]);
371 break;
372
373 default:
374 ret = false;
375 }
376 return ret;
377}
378
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200379static void amd_decode_ic_mce(struct mce *m)
Borislav Petkovab5535e2009-07-28 14:06:26 +0200380{
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200381 u16 ec = m->status & 0xffff;
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200382 u8 xec = (m->status >> 16) & xec_mask;
Borislav Petkovab5535e2009-07-28 14:06:26 +0200383
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200384 pr_emerg(HW_ERR "Instruction Cache Error: ");
Borislav Petkovab5535e2009-07-28 14:06:26 +0200385
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200386 if (TLB_ERROR(ec))
387 pr_cont("%s TLB %s.\n", LL_MSG(ec),
388 (xec ? "multimatch" : "parity error"));
389 else if (BUS_ERROR(ec)) {
Borislav Petkov525906b2010-10-15 15:27:02 +0200390 bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
Borislav Petkovab5535e2009-07-28 14:06:26 +0200391
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200392 pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
Borislav Petkov86039cd2010-11-08 15:03:35 +0100393 } else if (fam_ops->ic_mce(ec, xec))
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200394 ;
395 else
396 pr_emerg(HW_ERR "Corrupted IC MCE info?\n");
Borislav Petkovab5535e2009-07-28 14:06:26 +0200397}
398
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200399static void amd_decode_bu_mce(struct mce *m)
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200400{
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200401 u32 ec = m->status & 0xffff;
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200402 u32 xec = (m->status >> 16) & xec_mask;
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200403
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200404 pr_emerg(HW_ERR "Bus Unit Error");
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200405
406 if (xec == 0x1)
407 pr_cont(" in the write data buffers.\n");
408 else if (xec == 0x3)
409 pr_cont(" in the victim data buffers.\n");
410 else if (xec == 0x2 && MEM_ERROR(ec))
411 pr_cont(": %s error in the L2 cache tags.\n", RRRR_MSG(ec));
412 else if (xec == 0x0) {
413 if (TLB_ERROR(ec))
414 pr_cont(": %s error in a Page Descriptor Cache or "
415 "Guest TLB.\n", TT_MSG(ec));
416 else if (BUS_ERROR(ec))
417 pr_cont(": %s/ECC error in data read from NB: %s.\n",
418 RRRR_MSG(ec), PP_MSG(ec));
419 else if (MEM_ERROR(ec)) {
420 u8 rrrr = (ec >> 4) & 0xf;
421
422 if (rrrr >= 0x7)
423 pr_cont(": %s error during data copyback.\n",
424 RRRR_MSG(ec));
425 else if (rrrr <= 0x1)
426 pr_cont(": %s parity/ECC error during data "
427 "access from L2.\n", RRRR_MSG(ec));
428 else
429 goto wrong_bu_mce;
430 } else
431 goto wrong_bu_mce;
432 } else
433 goto wrong_bu_mce;
434
435 return;
436
437wrong_bu_mce:
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200438 pr_emerg(HW_ERR "Corrupted BU MCE info?\n");
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200439}
440
Borislav Petkov70fdb492010-09-21 20:45:10 +0200441static void amd_decode_cu_mce(struct mce *m)
442{
443 u16 ec = m->status & 0xffff;
444 u8 xec = (m->status >> 16) & xec_mask;
445
446 pr_emerg(HW_ERR "Combined Unit Error: ");
447
448 if (TLB_ERROR(ec)) {
449 if (xec == 0x0)
450 pr_cont("Data parity TLB read error.\n");
451 else if (xec == 0x1)
452 pr_cont("Poison data provided for TLB fill.\n");
453 else
454 goto wrong_cu_mce;
455 } else if (BUS_ERROR(ec)) {
456 if (xec > 2)
457 goto wrong_cu_mce;
458
459 pr_cont("Error during attempted NB data read.\n");
460 } else if (MEM_ERROR(ec)) {
461 switch (xec) {
462 case 0x4 ... 0xc:
463 pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x4]);
464 break;
465
466 case 0x10 ... 0x14:
467 pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x7]);
468 break;
469
470 default:
471 goto wrong_cu_mce;
472 }
473 }
474
475 return;
476
477wrong_cu_mce:
478 pr_emerg(HW_ERR "Corrupted CU MCE info?\n");
479}
480
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200481static void amd_decode_ls_mce(struct mce *m)
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200482{
Borislav Petkovded50622010-08-27 17:03:34 +0200483 u16 ec = m->status & 0xffff;
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200484 u8 xec = (m->status >> 16) & xec_mask;
Borislav Petkovded50622010-08-27 17:03:34 +0200485
Borislav Petkovb18434c2010-09-22 11:53:32 +0200486 if (boot_cpu_data.x86 >= 0x14) {
Borislav Petkovded50622010-08-27 17:03:34 +0200487 pr_emerg("You shouldn't be seeing an LS MCE on this cpu family,"
488 " please report on LKML.\n");
489 return;
490 }
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200491
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200492 pr_emerg(HW_ERR "Load Store Error");
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200493
494 if (xec == 0x0) {
Borislav Petkovded50622010-08-27 17:03:34 +0200495 u8 r4 = (ec >> 4) & 0xf;
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200496
Borislav Petkovded50622010-08-27 17:03:34 +0200497 if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR))
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200498 goto wrong_ls_mce;
499
500 pr_cont(" during %s.\n", RRRR_MSG(ec));
Borislav Petkovded50622010-08-27 17:03:34 +0200501 } else
502 goto wrong_ls_mce;
503
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200504 return;
505
506wrong_ls_mce:
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200507 pr_emerg(HW_ERR "Corrupted LS MCE info?\n");
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200508}
509
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200510static bool k8_nb_mce(u16 ec, u8 xec)
511{
512 bool ret = true;
513
514 switch (xec) {
515 case 0x1:
516 pr_cont("CRC error detected on HT link.\n");
517 break;
518
519 case 0x5:
520 pr_cont("Invalid GART PTE entry during GART table walk.\n");
521 break;
522
523 case 0x6:
524 pr_cont("Unsupported atomic RMW received from an IO link.\n");
525 break;
526
527 case 0x0:
528 case 0x8:
Borislav Petkovf0157b32010-10-05 19:07:16 +0200529 if (boot_cpu_data.x86 == 0x11)
530 return false;
531
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200532 pr_cont("DRAM ECC error detected on the NB.\n");
533 break;
534
535 case 0xd:
536 pr_cont("Parity error on the DRAM addr/ctl signals.\n");
537 break;
538
539 default:
540 ret = false;
541 break;
542 }
543
544 return ret;
545}
546
547static bool f10h_nb_mce(u16 ec, u8 xec)
548{
549 bool ret = true;
550 u8 offset = 0;
551
552 if (k8_nb_mce(ec, xec))
553 return true;
554
555 switch(xec) {
556 case 0xa ... 0xc:
557 offset = 10;
558 break;
559
560 case 0xe:
561 offset = 11;
562 break;
563
564 case 0xf:
565 if (TLB_ERROR(ec))
566 pr_cont("GART Table Walk data error.\n");
567 else if (BUS_ERROR(ec))
568 pr_cont("DMA Exclusion Vector Table Walk error.\n");
569 else
570 ret = false;
571
572 goto out;
573 break;
574
Borislav Petkov05cd6672010-09-22 15:06:24 +0200575 case 0x19:
576 if (boot_cpu_data.x86 == 0x15)
577 pr_cont("Compute Unit Data Error.\n");
578 else
579 ret = false;
580
581 goto out;
582 break;
583
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200584 case 0x1c ... 0x1f:
585 offset = 24;
586 break;
587
588 default:
589 ret = false;
590
591 goto out;
592 break;
593 }
594
595 pr_cont("%s.\n", f10h_nb_mce_desc[xec - offset]);
596
597out:
598 return ret;
599}
600
Borislav Petkovcb9d5ec2010-09-16 17:36:12 +0200601static bool nb_noop_mce(u16 ec, u8 xec)
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200602{
603 return false;
604}
605
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200606void amd_decode_nb_mce(int node_id, struct mce *m, u32 nbcfg)
Borislav Petkov549d0422009-07-24 13:51:42 +0200607{
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200608 u8 xec = (m->status >> 16) & 0x1f;
609 u16 ec = m->status & 0xffff;
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200610 u32 nbsh = (u32)(m->status >> 32);
Borislav Petkov549d0422009-07-24 13:51:42 +0200611
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200612 pr_emerg(HW_ERR "Northbridge Error, node %d: ", node_id);
Borislav Petkov549d0422009-07-24 13:51:42 +0200613
614 /*
615 * F10h, revD can disable ErrCpu[3:0] so check that first and also the
616 * value encoding has changed so interpret those differently
617 */
618 if ((boot_cpu_data.x86 == 0x10) &&
Borislav Petkovcec79242009-10-27 19:12:02 +0100619 (boot_cpu_data.x86_model > 7)) {
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200620 if (nbsh & K8_NBSH_ERR_CPU_VAL)
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200621 pr_cont(", core: %u", (u8)(nbsh & nb_err_cpumask));
Borislav Petkov549d0422009-07-24 13:51:42 +0200622 } else {
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200623 u8 assoc_cpus = nbsh & nb_err_cpumask;
Borislav Petkov5b89d2f2010-03-09 20:38:48 +0100624
625 if (assoc_cpus > 0)
626 pr_cont(", core: %d", fls(assoc_cpus) - 1);
Borislav Petkov549d0422009-07-24 13:51:42 +0200627 }
628
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200629 switch (xec) {
630 case 0x2:
631 pr_cont("Sync error (sync packets on HT link detected).\n");
632 return;
Borislav Petkovd93cc222009-07-28 10:56:15 +0200633
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200634 case 0x3:
635 pr_cont("HT Master abort.\n");
636 return;
637
638 case 0x4:
639 pr_cont("HT Target abort.\n");
640 return;
641
642 case 0x7:
643 pr_cont("NB Watchdog timeout.\n");
644 return;
645
646 case 0x9:
647 pr_cont("SVM DMA Exclusion Vector error.\n");
648 return;
649
650 default:
651 break;
652 }
653
654 if (!fam_ops->nb_mce(ec, xec))
655 goto wrong_nb_mce;
656
657 if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10)
658 if ((xec == 0x8 || xec == 0x0) && nb_bus_decoder)
659 nb_bus_decoder(node_id, m, nbcfg);
660
661 return;
662
663wrong_nb_mce:
664 pr_emerg(HW_ERR "Corrupted NB MCE info?\n");
Borislav Petkovd93cc222009-07-28 10:56:15 +0200665}
666EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
667
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200668static void amd_decode_fr_mce(struct mce *m)
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200669{
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200670 struct cpuinfo_x86 *c = &boot_cpu_data;
671 u8 xec = (m->status >> 16) & xec_mask;
672
673 if (c->x86 == 0xf || c->x86 == 0x11)
Borislav Petkovfe4ea262010-08-31 18:38:24 +0200674 goto wrong_fr_mce;
675
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200676 if (c->x86 != 0x15 && xec != 0x0)
677 goto wrong_fr_mce;
678
679 pr_emerg(HW_ERR "%s Error: ",
680 (c->x86 == 0x15 ? "Execution Unit" : "FIROB"));
681
682 if (xec == 0x0 || xec == 0xc)
683 pr_cont("%s.\n", fr_ex_mce_desc[xec]);
684 else if (xec < 0xd)
685 pr_cont("%s parity error.\n", fr_ex_mce_desc[xec]);
686 else
687 goto wrong_fr_mce;
688
689 return;
Borislav Petkovfe4ea262010-08-31 18:38:24 +0200690
691wrong_fr_mce:
692 pr_emerg(HW_ERR "Corrupted FR MCE info?\n");
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200693}
694
Borislav Petkov63375832010-09-06 18:13:39 +0200695static inline void amd_decode_err_code(u16 ec)
Borislav Petkovd93cc222009-07-28 10:56:15 +0200696{
Borislav Petkov549d0422009-07-24 13:51:42 +0200697 if (TLB_ERROR(ec)) {
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200698 pr_emerg(HW_ERR "Transaction: %s, Cache Level: %s\n",
Borislav Petkov549d0422009-07-24 13:51:42 +0200699 TT_MSG(ec), LL_MSG(ec));
700 } else if (MEM_ERROR(ec)) {
Borislav Petkov63375832010-09-06 18:13:39 +0200701 pr_emerg(HW_ERR "Transaction: %s, Type: %s, Cache Level: %s\n",
Borislav Petkov549d0422009-07-24 13:51:42 +0200702 RRRR_MSG(ec), TT_MSG(ec), LL_MSG(ec));
703 } else if (BUS_ERROR(ec)) {
Borislav Petkov63375832010-09-06 18:13:39 +0200704 pr_emerg(HW_ERR "Transaction: %s (%s), %s, Cache Level: %s, "
Borislav Petkovd93cc222009-07-28 10:56:15 +0200705 "Participating Processor: %s\n",
706 RRRR_MSG(ec), II_MSG(ec), TO_MSG(ec), LL_MSG(ec),
707 PP_MSG(ec));
708 } else
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200709 pr_emerg(HW_ERR "Huh? Unknown MCE error 0x%x\n", ec);
Borislav Petkov549d0422009-07-24 13:51:42 +0200710}
Borislav Petkov549d0422009-07-24 13:51:42 +0200711
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200712/*
713 * Filter out unwanted MCE signatures here.
714 */
715static bool amd_filter_mce(struct mce *m)
716{
717 u8 xec = (m->status >> 16) & 0x1f;
718
719 /*
720 * NB GART TLB error reporting is disabled by default.
721 */
722 if (m->bank == 4 && xec == 0x5 && !report_gart_errors)
723 return true;
724
725 return false;
726}
727
Borislav Petkov9cdeb402010-09-02 18:33:24 +0200728int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
Borislav Petkov549d0422009-07-24 13:51:42 +0200729{
Borislav Petkovfb253192009-10-07 13:20:38 +0200730 struct mce *m = (struct mce *)data;
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200731 int node, ecc;
Borislav Petkov549d0422009-07-24 13:51:42 +0200732
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200733 if (amd_filter_mce(m))
734 return NOTIFY_STOP;
735
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200736 pr_emerg(HW_ERR "MC%d_STATUS: ", m->bank);
Borislav Petkov549d0422009-07-24 13:51:42 +0200737
Borislav Petkov37b73702010-08-24 18:21:42 +0200738 pr_cont("%sorrected error, other errors lost: %s, "
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200739 "CPU context corrupt: %s",
740 ((m->status & MCI_STATUS_UC) ? "Unc" : "C"),
Borislav Petkov37b73702010-08-24 18:21:42 +0200741 ((m->status & MCI_STATUS_OVER) ? "yes" : "no"),
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200742 ((m->status & MCI_STATUS_PCC) ? "yes" : "no"));
Borislav Petkov549d0422009-07-24 13:51:42 +0200743
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200744 /* do the two bits[14:13] together */
Borislav Petkov35d824b2010-04-30 15:19:02 +0200745 ecc = (m->status >> 45) & 0x3;
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200746 if (ecc)
747 pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
748
749 pr_cont("\n");
750
Borislav Petkov51966242009-07-28 13:50:43 +0200751 switch (m->bank) {
752 case 0:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200753 amd_decode_dc_mce(m);
Borislav Petkov51966242009-07-28 13:50:43 +0200754 break;
Borislav Petkovd93cc222009-07-28 10:56:15 +0200755
Borislav Petkovab5535e2009-07-28 14:06:26 +0200756 case 1:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200757 amd_decode_ic_mce(m);
Borislav Petkovab5535e2009-07-28 14:06:26 +0200758 break;
759
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200760 case 2:
Borislav Petkov70fdb492010-09-21 20:45:10 +0200761 if (boot_cpu_data.x86 == 0x15)
762 amd_decode_cu_mce(m);
763 else
764 amd_decode_bu_mce(m);
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200765 break;
766
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200767 case 3:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200768 amd_decode_ls_mce(m);
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200769 break;
770
Borislav Petkov51966242009-07-28 13:50:43 +0200771 case 4:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200772 node = amd_get_nb_id(m->extcpu);
773 amd_decode_nb_mce(node, m, 0);
Borislav Petkov51966242009-07-28 13:50:43 +0200774 break;
775
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200776 case 5:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200777 amd_decode_fr_mce(m);
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200778 break;
779
Borislav Petkov51966242009-07-28 13:50:43 +0200780 default:
781 break;
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200782 }
Borislav Petkov51966242009-07-28 13:50:43 +0200783
784 amd_decode_err_code(m->status & 0xffff);
Borislav Petkovfb253192009-10-07 13:20:38 +0200785
786 return NOTIFY_STOP;
Borislav Petkov549d0422009-07-24 13:51:42 +0200787}
Borislav Petkov9cdeb402010-09-02 18:33:24 +0200788EXPORT_SYMBOL_GPL(amd_decode_mce);
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200789
Borislav Petkovfb253192009-10-07 13:20:38 +0200790static struct notifier_block amd_mce_dec_nb = {
791 .notifier_call = amd_decode_mce,
792};
793
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200794static int __init mce_amd_init(void)
795{
Borislav Petkove045c292010-08-06 18:55:45 +0200796 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
797 return 0;
798
Borislav Petkovfda75612010-09-22 16:12:03 +0200799 if ((boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x12) &&
Borislav Petkov9530d602010-09-06 15:05:45 +0200800 (boot_cpu_data.x86 != 0x14 || boot_cpu_data.x86_model > 0xf))
Borislav Petkove045c292010-08-06 18:55:45 +0200801 return 0;
802
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200803 fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL);
804 if (!fam_ops)
805 return -ENOMEM;
806
807 switch (boot_cpu_data.x86) {
808 case 0xf:
809 fam_ops->dc_mce = k8_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200810 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200811 fam_ops->nb_mce = k8_nb_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200812 break;
813
814 case 0x10:
815 fam_ops->dc_mce = f10h_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200816 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200817 fam_ops->nb_mce = f10h_nb_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200818 break;
819
Borislav Petkovf0157b32010-10-05 19:07:16 +0200820 case 0x11:
821 fam_ops->dc_mce = k8_dc_mce;
822 fam_ops->ic_mce = k8_ic_mce;
823 fam_ops->nb_mce = f10h_nb_mce;
824 break;
825
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200826 case 0x12:
827 fam_ops->dc_mce = f12h_dc_mce;
Borislav Petkove7281eb2010-09-16 16:45:22 +0200828 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkovcb9d5ec2010-09-16 17:36:12 +0200829 fam_ops->nb_mce = nb_noop_mce;
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200830 break;
831
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200832 case 0x14:
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200833 nb_err_cpumask = 0x3;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200834 fam_ops->dc_mce = f14h_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200835 fam_ops->ic_mce = f14h_ic_mce;
Borislav Petkovcb9d5ec2010-09-16 17:36:12 +0200836 fam_ops->nb_mce = nb_noop_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200837 break;
838
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200839 case 0x15:
840 xec_mask = 0x1f;
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200841 fam_ops->dc_mce = f15h_dc_mce;
Borislav Petkov86039cd2010-11-08 15:03:35 +0100842 fam_ops->ic_mce = f15h_ic_mce;
Borislav Petkov05cd6672010-09-22 15:06:24 +0200843 fam_ops->nb_mce = f10h_nb_mce;
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200844 break;
845
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200846 default:
847 printk(KERN_WARNING "Huh? What family is that: %d?!\n",
848 boot_cpu_data.x86);
849 kfree(fam_ops);
850 return -EINVAL;
851 }
852
Borislav Petkov9530d602010-09-06 15:05:45 +0200853 pr_info("MCE: In-kernel MCE decoding enabled.\n");
854
Borislav Petkove045c292010-08-06 18:55:45 +0200855 atomic_notifier_chain_register(&x86_mce_decoder_chain, &amd_mce_dec_nb);
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200856
857 return 0;
858}
859early_initcall(mce_amd_init);
Borislav Petkov0d18b2e2009-10-02 15:31:48 +0200860
861#ifdef MODULE
862static void __exit mce_amd_exit(void)
863{
Borislav Petkovfb253192009-10-07 13:20:38 +0200864 atomic_notifier_chain_unregister(&x86_mce_decoder_chain, &amd_mce_dec_nb);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200865 kfree(fam_ops);
Borislav Petkov0d18b2e2009-10-02 15:31:48 +0200866}
867
868MODULE_DESCRIPTION("AMD MCE decoder");
869MODULE_ALIAS("edac-mce-amd");
870MODULE_LICENSE("GPL");
871module_exit(mce_amd_exit);
872#endif