diff options
author | Borislav Petkov <borislav.petkov@amd.com> | 2010-11-08 09:03:35 -0500 |
---|---|---|
committer | Borislav Petkov <borislav.petkov@amd.com> | 2011-01-07 05:54:15 -0500 |
commit | 86039cd401e1780573733870f9c0bd458fc96ea2 (patch) | |
tree | 64f2acb7d10b8d50983a8b625de849160274f676 /drivers/edac | |
parent | 25a4f8b05917f8137bfff8a3f8c6c8c1ac561208 (diff) |
EDAC, MCE: Add F15h IC MCE decoder
Add support for decoding F15h IC MCEs.
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/mce_amd.c | 53 | ||||
-rw-r--r-- | drivers/edac/mce_amd.h | 2 |
2 files changed, 51 insertions, 4 deletions
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c index 12bae3b18e3d..158cd5fa2146 100644 --- a/drivers/edac/mce_amd.c +++ b/drivers/edac/mce_amd.c | |||
@@ -75,6 +75,26 @@ static const char *f10h_nb_mce_desc[] = { | |||
75 | "ECC Error in the Probe Filter directory" | 75 | "ECC Error in the Probe Filter directory" |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static 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 | |||
78 | static bool f12h_dc_mce(u16 ec, u8 xec) | 98 | static bool f12h_dc_mce(u16 ec, u8 xec) |
79 | { | 99 | { |
80 | bool ret = false; | 100 | bool ret = false; |
@@ -241,7 +261,7 @@ static void amd_decode_dc_mce(struct mce *m) | |||
241 | pr_emerg(HW_ERR "Corrupted DC MCE info?\n"); | 261 | pr_emerg(HW_ERR "Corrupted DC MCE info?\n"); |
242 | } | 262 | } |
243 | 263 | ||
244 | static bool k8_ic_mce(u16 ec) | 264 | static bool k8_ic_mce(u16 ec, u8 xec) |
245 | { | 265 | { |
246 | u8 ll = ec & 0x3; | 266 | u8 ll = ec & 0x3; |
247 | u8 r4 = (ec >> 4) & 0xf; | 267 | u8 r4 = (ec >> 4) & 0xf; |
@@ -276,7 +296,7 @@ static bool k8_ic_mce(u16 ec) | |||
276 | return ret; | 296 | return ret; |
277 | } | 297 | } |
278 | 298 | ||
279 | static bool f14h_ic_mce(u16 ec) | 299 | static bool f14h_ic_mce(u16 ec, u8 xec) |
280 | { | 300 | { |
281 | u8 ll = ec & 0x3; | 301 | u8 ll = ec & 0x3; |
282 | u8 tt = (ec >> 2) & 0x3; | 302 | u8 tt = (ec >> 2) & 0x3; |
@@ -297,6 +317,32 @@ static bool f14h_ic_mce(u16 ec) | |||
297 | return ret; | 317 | return ret; |
298 | } | 318 | } |
299 | 319 | ||
320 | static bool f15h_ic_mce(u16 ec, u8 xec) | ||
321 | { | ||
322 | bool ret = true; | ||
323 | |||
324 | if (!MEM_ERROR(ec)) | ||
325 | return false; | ||
326 | |||
327 | switch (xec) { | ||
328 | case 0x0 ... 0xa: | ||
329 | pr_cont("%s.\n", f15h_ic_mce_desc[xec]); | ||
330 | break; | ||
331 | |||
332 | case 0xd: | ||
333 | pr_cont("%s.\n", f15h_ic_mce_desc[xec-2]); | ||
334 | break; | ||
335 | |||
336 | case 0x10 ... 0x14: | ||
337 | pr_cont("Decoder %s parity error.\n", f15h_ic_mce_desc[xec-4]); | ||
338 | break; | ||
339 | |||
340 | default: | ||
341 | ret = false; | ||
342 | } | ||
343 | return ret; | ||
344 | } | ||
345 | |||
300 | static void amd_decode_ic_mce(struct mce *m) | 346 | static void amd_decode_ic_mce(struct mce *m) |
301 | { | 347 | { |
302 | u16 ec = m->status & 0xffff; | 348 | u16 ec = m->status & 0xffff; |
@@ -311,7 +357,7 @@ static void amd_decode_ic_mce(struct mce *m) | |||
311 | bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58))); | 357 | bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58))); |
312 | 358 | ||
313 | pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read")); | 359 | pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read")); |
314 | } else if (fam_ops->ic_mce(ec)) | 360 | } else if (fam_ops->ic_mce(ec, xec)) |
315 | ; | 361 | ; |
316 | else | 362 | else |
317 | pr_emerg(HW_ERR "Corrupted IC MCE info?\n"); | 363 | pr_emerg(HW_ERR "Corrupted IC MCE info?\n"); |
@@ -697,6 +743,7 @@ static int __init mce_amd_init(void) | |||
697 | case 0x15: | 743 | case 0x15: |
698 | xec_mask = 0x1f; | 744 | xec_mask = 0x1f; |
699 | fam_ops->dc_mce = f15h_dc_mce; | 745 | fam_ops->dc_mce = f15h_dc_mce; |
746 | fam_ops->ic_mce = f15h_ic_mce; | ||
700 | break; | 747 | break; |
701 | 748 | ||
702 | default: | 749 | default: |
diff --git a/drivers/edac/mce_amd.h b/drivers/edac/mce_amd.h index c12394db9bdf..83988471123f 100644 --- a/drivers/edac/mce_amd.h +++ b/drivers/edac/mce_amd.h | |||
@@ -101,7 +101,7 @@ struct err_regs { | |||
101 | */ | 101 | */ |
102 | struct amd_decoder_ops { | 102 | struct amd_decoder_ops { |
103 | bool (*dc_mce)(u16, u8); | 103 | bool (*dc_mce)(u16, u8); |
104 | bool (*ic_mce)(u16); | 104 | bool (*ic_mce)(u16, u8); |
105 | bool (*nb_mce)(u16, u8); | 105 | bool (*nb_mce)(u16, u8); |
106 | }; | 106 | }; |
107 | 107 | ||