diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-20 14:28:50 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-20 14:28:50 -0500 |
commit | 55529fa5762462beb39f913c5277cb96c7be0858 (patch) | |
tree | 668c1fc750bba414fac65e955cf8e23fee75a0bf /drivers/edac | |
parent | 8793422fd9ac5037f5047f80473007301df3689f (diff) | |
parent | e7d2c215e56dc9fa0a01e26f2acfc3d73c889ba3 (diff) |
Merge tag 'edac_3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp
Pull EDAC updates from Borislav Petkov:
"Mostly AMD's side of EDAC. It is basically a new family enablement
stuff: AMD F16h MCE decoding enablement from Jacob Shin. The rest is
trivial cleanups."
* tag 'edac_3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp:
mpc85xx_edac: Fix typo
EDAC, MCE, AMD: Remove unneeded exports
EDAC, MCE, AMD: Add MCE decoding support for Family 16h
EDAC, MCE, AMD: Make MC2 decoding per-family
amd64_edac: Remove dead code
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/amd64_edac.c | 105 | ||||
-rw-r--r-- | drivers/edac/mce_amd.c | 166 | ||||
-rw-r--r-- | drivers/edac/mce_amd.h | 13 | ||||
-rw-r--r-- | drivers/edac/mpc85xx_edac.c | 4 |
4 files changed, 120 insertions, 168 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 2d3f8825e8b8..910b0116c128 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -602,111 +602,6 @@ static u64 sys_addr_to_input_addr(struct mem_ctl_info *mci, u64 sys_addr) | |||
602 | return input_addr; | 602 | return input_addr; |
603 | } | 603 | } |
604 | 604 | ||
605 | |||
606 | /* | ||
607 | * @input_addr is an InputAddr associated with the node represented by mci. | ||
608 | * Translate @input_addr to a DramAddr and return the result. | ||
609 | */ | ||
610 | static u64 input_addr_to_dram_addr(struct mem_ctl_info *mci, u64 input_addr) | ||
611 | { | ||
612 | struct amd64_pvt *pvt; | ||
613 | unsigned node_id, intlv_shift; | ||
614 | u64 bits, dram_addr; | ||
615 | u32 intlv_sel; | ||
616 | |||
617 | /* | ||
618 | * Near the start of section 3.4.4 (p. 70, BKDG #26094, K8, revA-E) | ||
619 | * shows how to translate a DramAddr to an InputAddr. Here we reverse | ||
620 | * this procedure. When translating from a DramAddr to an InputAddr, the | ||
621 | * bits used for node interleaving are discarded. Here we recover these | ||
622 | * bits from the IntlvSel field of the DRAM Limit register (section | ||
623 | * 3.4.4.2) for the node that input_addr is associated with. | ||
624 | */ | ||
625 | pvt = mci->pvt_info; | ||
626 | node_id = pvt->mc_node_id; | ||
627 | |||
628 | BUG_ON(node_id > 7); | ||
629 | |||
630 | intlv_shift = num_node_interleave_bits(dram_intlv_en(pvt, 0)); | ||
631 | if (intlv_shift == 0) { | ||
632 | edac_dbg(1, " InputAddr 0x%lx translates to DramAddr of same value\n", | ||
633 | (unsigned long)input_addr); | ||
634 | |||
635 | return input_addr; | ||
636 | } | ||
637 | |||
638 | bits = ((input_addr & GENMASK(12, 35)) << intlv_shift) + | ||
639 | (input_addr & 0xfff); | ||
640 | |||
641 | intlv_sel = dram_intlv_sel(pvt, node_id) & ((1 << intlv_shift) - 1); | ||
642 | dram_addr = bits + (intlv_sel << 12); | ||
643 | |||
644 | edac_dbg(1, "InputAddr 0x%lx translates to DramAddr 0x%lx (%d node interleave bits)\n", | ||
645 | (unsigned long)input_addr, | ||
646 | (unsigned long)dram_addr, intlv_shift); | ||
647 | |||
648 | return dram_addr; | ||
649 | } | ||
650 | |||
651 | /* | ||
652 | * @dram_addr is a DramAddr that maps to the node represented by mci. Convert | ||
653 | * @dram_addr to a SysAddr. | ||
654 | */ | ||
655 | static u64 dram_addr_to_sys_addr(struct mem_ctl_info *mci, u64 dram_addr) | ||
656 | { | ||
657 | struct amd64_pvt *pvt = mci->pvt_info; | ||
658 | u64 hole_base, hole_offset, hole_size, base, sys_addr; | ||
659 | int ret = 0; | ||
660 | |||
661 | ret = amd64_get_dram_hole_info(mci, &hole_base, &hole_offset, | ||
662 | &hole_size); | ||
663 | if (!ret) { | ||
664 | if ((dram_addr >= hole_base) && | ||
665 | (dram_addr < (hole_base + hole_size))) { | ||
666 | sys_addr = dram_addr + hole_offset; | ||
667 | |||
668 | edac_dbg(1, "using DHAR to translate DramAddr 0x%lx to SysAddr 0x%lx\n", | ||
669 | (unsigned long)dram_addr, | ||
670 | (unsigned long)sys_addr); | ||
671 | |||
672 | return sys_addr; | ||
673 | } | ||
674 | } | ||
675 | |||
676 | base = get_dram_base(pvt, pvt->mc_node_id); | ||
677 | sys_addr = dram_addr + base; | ||
678 | |||
679 | /* | ||
680 | * The sys_addr we have computed up to this point is a 40-bit value | ||
681 | * because the k8 deals with 40-bit values. However, the value we are | ||
682 | * supposed to return is a full 64-bit physical address. The AMD | ||
683 | * x86-64 architecture specifies that the most significant implemented | ||
684 | * address bit through bit 63 of a physical address must be either all | ||
685 | * 0s or all 1s. Therefore we sign-extend the 40-bit sys_addr to a | ||
686 | * 64-bit value below. See section 3.4.2 of AMD publication 24592: | ||
687 | * AMD x86-64 Architecture Programmer's Manual Volume 1 Application | ||
688 | * Programming. | ||
689 | */ | ||
690 | sys_addr |= ~((sys_addr & (1ull << 39)) - 1); | ||
691 | |||
692 | edac_dbg(1, " Node %d, DramAddr 0x%lx to SysAddr 0x%lx\n", | ||
693 | pvt->mc_node_id, (unsigned long)dram_addr, | ||
694 | (unsigned long)sys_addr); | ||
695 | |||
696 | return sys_addr; | ||
697 | } | ||
698 | |||
699 | /* | ||
700 | * @input_addr is an InputAddr associated with the node given by mci. Translate | ||
701 | * @input_addr to a SysAddr. | ||
702 | */ | ||
703 | static inline u64 input_addr_to_sys_addr(struct mem_ctl_info *mci, | ||
704 | u64 input_addr) | ||
705 | { | ||
706 | return dram_addr_to_sys_addr(mci, | ||
707 | input_addr_to_dram_addr(mci, input_addr)); | ||
708 | } | ||
709 | |||
710 | /* Map the Error address to a PAGE and PAGE OFFSET. */ | 605 | /* Map the Error address to a PAGE and PAGE OFFSET. */ |
711 | static inline void error_address_to_page_and_offset(u64 error_address, | 606 | static inline void error_address_to_page_and_offset(u64 error_address, |
712 | struct err_info *err) | 607 | struct err_info *err) |
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c index ad637572d8c7..f3f0c930d550 100644 --- a/drivers/edac/mce_amd.c +++ b/drivers/edac/mce_amd.c | |||
@@ -39,30 +39,28 @@ EXPORT_SYMBOL_GPL(amd_unregister_ecc_decoder); | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | /* transaction type */ | 41 | /* transaction type */ |
42 | const char * const tt_msgs[] = { "INSN", "DATA", "GEN", "RESV" }; | 42 | static const char * const tt_msgs[] = { "INSN", "DATA", "GEN", "RESV" }; |
43 | EXPORT_SYMBOL_GPL(tt_msgs); | ||
44 | 43 | ||
45 | /* cache level */ | 44 | /* cache level */ |
46 | const char * const ll_msgs[] = { "RESV", "L1", "L2", "L3/GEN" }; | 45 | static const char * const ll_msgs[] = { "RESV", "L1", "L2", "L3/GEN" }; |
47 | EXPORT_SYMBOL_GPL(ll_msgs); | ||
48 | 46 | ||
49 | /* memory transaction type */ | 47 | /* memory transaction type */ |
50 | const char * const rrrr_msgs[] = { | 48 | static const char * const rrrr_msgs[] = { |
51 | "GEN", "RD", "WR", "DRD", "DWR", "IRD", "PRF", "EV", "SNP" | 49 | "GEN", "RD", "WR", "DRD", "DWR", "IRD", "PRF", "EV", "SNP" |
52 | }; | 50 | }; |
53 | EXPORT_SYMBOL_GPL(rrrr_msgs); | ||
54 | 51 | ||
55 | /* participating processor */ | 52 | /* participating processor */ |
56 | const char * const pp_msgs[] = { "SRC", "RES", "OBS", "GEN" }; | 53 | const char * const pp_msgs[] = { "SRC", "RES", "OBS", "GEN" }; |
57 | EXPORT_SYMBOL_GPL(pp_msgs); | 54 | EXPORT_SYMBOL_GPL(pp_msgs); |
58 | 55 | ||
59 | /* request timeout */ | 56 | /* request timeout */ |
60 | const char * const to_msgs[] = { "no timeout", "timed out" }; | 57 | static const char * const to_msgs[] = { "no timeout", "timed out" }; |
61 | EXPORT_SYMBOL_GPL(to_msgs); | ||
62 | 58 | ||
63 | /* memory or i/o */ | 59 | /* memory or i/o */ |
64 | const char * const ii_msgs[] = { "MEM", "RESV", "IO", "GEN" }; | 60 | static const char * const ii_msgs[] = { "MEM", "RESV", "IO", "GEN" }; |
65 | EXPORT_SYMBOL_GPL(ii_msgs); | 61 | |
62 | /* internal error type */ | ||
63 | static const char * const uu_msgs[] = { "RESV", "RESV", "HWA", "RESV" }; | ||
66 | 64 | ||
67 | static const char * const f15h_mc1_mce_desc[] = { | 65 | static const char * const f15h_mc1_mce_desc[] = { |
68 | "UC during a demand linefill from L2", | 66 | "UC during a demand linefill from L2", |
@@ -176,7 +174,7 @@ static bool k8_mc0_mce(u16 ec, u8 xec) | |||
176 | return f10h_mc0_mce(ec, xec); | 174 | return f10h_mc0_mce(ec, xec); |
177 | } | 175 | } |
178 | 176 | ||
179 | static bool f14h_mc0_mce(u16 ec, u8 xec) | 177 | static bool cat_mc0_mce(u16 ec, u8 xec) |
180 | { | 178 | { |
181 | u8 r4 = R4(ec); | 179 | u8 r4 = R4(ec); |
182 | bool ret = true; | 180 | bool ret = true; |
@@ -330,22 +328,28 @@ static bool k8_mc1_mce(u16 ec, u8 xec) | |||
330 | return ret; | 328 | return ret; |
331 | } | 329 | } |
332 | 330 | ||
333 | static bool f14h_mc1_mce(u16 ec, u8 xec) | 331 | static bool cat_mc1_mce(u16 ec, u8 xec) |
334 | { | 332 | { |
335 | u8 r4 = R4(ec); | 333 | u8 r4 = R4(ec); |
336 | bool ret = true; | 334 | bool ret = true; |
337 | 335 | ||
338 | if (MEM_ERROR(ec)) { | 336 | if (!MEM_ERROR(ec)) |
339 | if (TT(ec) != 0 || LL(ec) != 1) | 337 | return false; |
340 | ret = false; | 338 | |
339 | if (TT(ec) != TT_INSTR) | ||
340 | return false; | ||
341 | |||
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; | ||
341 | 352 | ||
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 | ||
347 | ret = false; | ||
348 | } | ||
349 | return ret; | 353 | return ret; |
350 | } | 354 | } |
351 | 355 | ||
@@ -399,12 +403,9 @@ static void decode_mc1_mce(struct mce *m) | |||
399 | pr_emerg(HW_ERR "Corrupted MC1 MCE info?\n"); | 403 | pr_emerg(HW_ERR "Corrupted MC1 MCE info?\n"); |
400 | } | 404 | } |
401 | 405 | ||
402 | static void decode_mc2_mce(struct mce *m) | 406 | static bool k8_mc2_mce(u16 ec, u8 xec) |
403 | { | 407 | { |
404 | u16 ec = EC(m->status); | 408 | bool ret = true; |
405 | u8 xec = XEC(m->status, xec_mask); | ||
406 | |||
407 | pr_emerg(HW_ERR "MC2 Error"); | ||
408 | 409 | ||
409 | if (xec == 0x1) | 410 | if (xec == 0x1) |
410 | pr_cont(" in the write data buffers.\n"); | 411 | pr_cont(" in the write data buffers.\n"); |
@@ -429,24 +430,18 @@ static void decode_mc2_mce(struct mce *m) | |||
429 | pr_cont(": %s parity/ECC error during data " | 430 | pr_cont(": %s parity/ECC error during data " |
430 | "access from L2.\n", R4_MSG(ec)); | 431 | "access from L2.\n", R4_MSG(ec)); |
431 | else | 432 | else |
432 | goto wrong_mc2_mce; | 433 | ret = false; |
433 | } else | 434 | } else |
434 | goto wrong_mc2_mce; | 435 | ret = false; |
435 | } else | 436 | } else |
436 | goto wrong_mc2_mce; | 437 | ret = false; |
437 | |||
438 | return; | ||
439 | 438 | ||
440 | wrong_mc2_mce: | 439 | return ret; |
441 | pr_emerg(HW_ERR "Corrupted MC2 MCE info?\n"); | ||
442 | } | 440 | } |
443 | 441 | ||
444 | static void decode_f15_mc2_mce(struct mce *m) | 442 | static bool f15h_mc2_mce(u16 ec, u8 xec) |
445 | { | 443 | { |
446 | u16 ec = EC(m->status); | 444 | bool ret = true; |
447 | u8 xec = XEC(m->status, xec_mask); | ||
448 | |||
449 | pr_emerg(HW_ERR "MC2 Error: "); | ||
450 | 445 | ||
451 | if (TLB_ERROR(ec)) { | 446 | if (TLB_ERROR(ec)) { |
452 | if (xec == 0x0) | 447 | if (xec == 0x0) |
@@ -454,10 +449,10 @@ static void decode_f15_mc2_mce(struct mce *m) | |||
454 | else if (xec == 0x1) | 449 | else if (xec == 0x1) |
455 | pr_cont("Poison data provided for TLB fill.\n"); | 450 | pr_cont("Poison data provided for TLB fill.\n"); |
456 | else | 451 | else |
457 | goto wrong_f15_mc2_mce; | 452 | ret = false; |
458 | } else if (BUS_ERROR(ec)) { | 453 | } else if (BUS_ERROR(ec)) { |
459 | if (xec > 2) | 454 | if (xec > 2) |
460 | goto wrong_f15_mc2_mce; | 455 | ret = false; |
461 | 456 | ||
462 | pr_cont("Error during attempted NB data read.\n"); | 457 | pr_cont("Error during attempted NB data read.\n"); |
463 | } else if (MEM_ERROR(ec)) { | 458 | } else if (MEM_ERROR(ec)) { |
@@ -471,14 +466,63 @@ static void decode_f15_mc2_mce(struct mce *m) | |||
471 | break; | 466 | break; |
472 | 467 | ||
473 | default: | 468 | default: |
474 | goto wrong_f15_mc2_mce; | 469 | ret = false; |
475 | } | 470 | } |
476 | } | 471 | } |
477 | 472 | ||
478 | return; | 473 | return ret; |
474 | } | ||
479 | 475 | ||
480 | wrong_f15_mc2_mce: | 476 | static bool f16h_mc2_mce(u16 ec, u8 xec) |
481 | pr_emerg(HW_ERR "Corrupted MC2 MCE info?\n"); | 477 | { |
478 | u8 r4 = R4(ec); | ||
479 | |||
480 | if (!MEM_ERROR(ec)) | ||
481 | return false; | ||
482 | |||
483 | switch (xec) { | ||
484 | case 0x04 ... 0x05: | ||
485 | pr_cont("%cBUFF parity error.\n", (r4 == R4_RD) ? 'I' : 'O'); | ||
486 | break; | ||
487 | |||
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; | ||
494 | |||
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; | ||
502 | |||
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; | ||
509 | |||
510 | default: | ||
511 | return false; | ||
512 | } | ||
513 | |||
514 | return true; | ||
515 | } | ||
516 | |||
517 | static void decode_mc2_mce(struct mce *m) | ||
518 | { | ||
519 | u16 ec = EC(m->status); | ||
520 | u8 xec = XEC(m->status, xec_mask); | ||
521 | |||
522 | pr_emerg(HW_ERR "MC2 Error: "); | ||
523 | |||
524 | if (!fam_ops->mc2_mce(ec, xec)) | ||
525 | pr_cont(HW_ERR "Corrupted MC2 MCE info?\n"); | ||
482 | } | 526 | } |
483 | 527 | ||
484 | static void decode_mc3_mce(struct mce *m) | 528 | static void decode_mc3_mce(struct mce *m) |
@@ -547,7 +591,7 @@ static void decode_mc4_mce(struct mce *m) | |||
547 | return; | 591 | return; |
548 | 592 | ||
549 | case 0x19: | 593 | case 0x19: |
550 | if (boot_cpu_data.x86 == 0x15) | 594 | if (boot_cpu_data.x86 == 0x15 || boot_cpu_data.x86 == 0x16) |
551 | pr_cont("Compute Unit Data Error.\n"); | 595 | pr_cont("Compute Unit Data Error.\n"); |
552 | else | 596 | else |
553 | goto wrong_mc4_mce; | 597 | goto wrong_mc4_mce; |
@@ -633,6 +677,10 @@ static void decode_mc6_mce(struct mce *m) | |||
633 | 677 | ||
634 | static inline void amd_decode_err_code(u16 ec) | 678 | static inline void amd_decode_err_code(u16 ec) |
635 | { | 679 | { |
680 | if (INT_ERROR(ec)) { | ||
681 | pr_emerg(HW_ERR "internal: %s\n", UU_MSG(ec)); | ||
682 | return; | ||
683 | } | ||
636 | 684 | ||
637 | pr_emerg(HW_ERR "cache level: %s", LL_MSG(ec)); | 685 | pr_emerg(HW_ERR "cache level: %s", LL_MSG(ec)); |
638 | 686 | ||
@@ -702,10 +750,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data) | |||
702 | break; | 750 | break; |
703 | 751 | ||
704 | case 2: | 752 | case 2: |
705 | if (c->x86 == 0x15) | 753 | decode_mc2_mce(m); |
706 | decode_f15_mc2_mce(m); | ||
707 | else | ||
708 | decode_mc2_mce(m); | ||
709 | break; | 754 | break; |
710 | 755 | ||
711 | case 3: | 756 | case 3: |
@@ -740,7 +785,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data) | |||
740 | ((m->status & MCI_STATUS_PCC) ? "PCC" : "-"), | 785 | ((m->status & MCI_STATUS_PCC) ? "PCC" : "-"), |
741 | ((m->status & MCI_STATUS_ADDRV) ? "AddrV" : "-")); | 786 | ((m->status & MCI_STATUS_ADDRV) ? "AddrV" : "-")); |
742 | 787 | ||
743 | if (c->x86 == 0x15) | 788 | if (c->x86 == 0x15 || c->x86 == 0x16) |
744 | pr_cont("|%s|%s", | 789 | pr_cont("|%s|%s", |
745 | ((m->status & MCI_STATUS_DEFERRED) ? "Deferred" : "-"), | 790 | ((m->status & MCI_STATUS_DEFERRED) ? "Deferred" : "-"), |
746 | ((m->status & MCI_STATUS_POISON) ? "Poison" : "-")); | 791 | ((m->status & MCI_STATUS_POISON) ? "Poison" : "-")); |
@@ -772,7 +817,7 @@ static int __init mce_amd_init(void) | |||
772 | if (c->x86_vendor != X86_VENDOR_AMD) | 817 | if (c->x86_vendor != X86_VENDOR_AMD) |
773 | return 0; | 818 | return 0; |
774 | 819 | ||
775 | if (c->x86 < 0xf || c->x86 > 0x15) | 820 | if (c->x86 < 0xf || c->x86 > 0x16) |
776 | return 0; | 821 | return 0; |
777 | 822 | ||
778 | fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL); | 823 | fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL); |
@@ -783,33 +828,46 @@ static int __init mce_amd_init(void) | |||
783 | case 0xf: | 828 | case 0xf: |
784 | fam_ops->mc0_mce = k8_mc0_mce; | 829 | fam_ops->mc0_mce = k8_mc0_mce; |
785 | fam_ops->mc1_mce = k8_mc1_mce; | 830 | fam_ops->mc1_mce = k8_mc1_mce; |
831 | fam_ops->mc2_mce = k8_mc2_mce; | ||
786 | break; | 832 | break; |
787 | 833 | ||
788 | case 0x10: | 834 | case 0x10: |
789 | fam_ops->mc0_mce = f10h_mc0_mce; | 835 | fam_ops->mc0_mce = f10h_mc0_mce; |
790 | fam_ops->mc1_mce = k8_mc1_mce; | 836 | fam_ops->mc1_mce = k8_mc1_mce; |
837 | fam_ops->mc2_mce = k8_mc2_mce; | ||
791 | break; | 838 | break; |
792 | 839 | ||
793 | case 0x11: | 840 | case 0x11: |
794 | fam_ops->mc0_mce = k8_mc0_mce; | 841 | fam_ops->mc0_mce = k8_mc0_mce; |
795 | fam_ops->mc1_mce = k8_mc1_mce; | 842 | fam_ops->mc1_mce = k8_mc1_mce; |
843 | fam_ops->mc2_mce = k8_mc2_mce; | ||
796 | break; | 844 | break; |
797 | 845 | ||
798 | case 0x12: | 846 | case 0x12: |
799 | fam_ops->mc0_mce = f12h_mc0_mce; | 847 | fam_ops->mc0_mce = f12h_mc0_mce; |
800 | fam_ops->mc1_mce = k8_mc1_mce; | 848 | fam_ops->mc1_mce = k8_mc1_mce; |
849 | fam_ops->mc2_mce = k8_mc2_mce; | ||
801 | break; | 850 | break; |
802 | 851 | ||
803 | case 0x14: | 852 | case 0x14: |
804 | nb_err_cpumask = 0x3; | 853 | nb_err_cpumask = 0x3; |
805 | fam_ops->mc0_mce = f14h_mc0_mce; | 854 | fam_ops->mc0_mce = cat_mc0_mce; |
806 | fam_ops->mc1_mce = f14h_mc1_mce; | 855 | fam_ops->mc1_mce = cat_mc1_mce; |
856 | fam_ops->mc2_mce = k8_mc2_mce; | ||
807 | break; | 857 | break; |
808 | 858 | ||
809 | case 0x15: | 859 | case 0x15: |
810 | xec_mask = 0x1f; | 860 | xec_mask = 0x1f; |
811 | fam_ops->mc0_mce = f15h_mc0_mce; | 861 | fam_ops->mc0_mce = f15h_mc0_mce; |
812 | fam_ops->mc1_mce = f15h_mc1_mce; | 862 | fam_ops->mc1_mce = f15h_mc1_mce; |
863 | fam_ops->mc2_mce = f15h_mc2_mce; | ||
864 | break; | ||
865 | |||
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; | ||
813 | break; | 871 | break; |
814 | 872 | ||
815 | default: | 873 | default: |
diff --git a/drivers/edac/mce_amd.h b/drivers/edac/mce_amd.h index 679679951e23..51b7e3a36e37 100644 --- a/drivers/edac/mce_amd.h +++ b/drivers/edac/mce_amd.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #define TLB_ERROR(x) (((x) & 0xFFF0) == 0x0010) | 14 | #define TLB_ERROR(x) (((x) & 0xFFF0) == 0x0010) |
15 | #define MEM_ERROR(x) (((x) & 0xFF00) == 0x0100) | 15 | #define MEM_ERROR(x) (((x) & 0xFF00) == 0x0100) |
16 | #define BUS_ERROR(x) (((x) & 0xF800) == 0x0800) | 16 | #define BUS_ERROR(x) (((x) & 0xF800) == 0x0800) |
17 | #define INT_ERROR(x) (((x) & 0xF4FF) == 0x0400) | ||
17 | 18 | ||
18 | #define TT(x) (((x) >> 2) & 0x3) | 19 | #define TT(x) (((x) >> 2) & 0x3) |
19 | #define TT_MSG(x) tt_msgs[TT(x)] | 20 | #define TT_MSG(x) tt_msgs[TT(x)] |
@@ -25,6 +26,8 @@ | |||
25 | #define TO_MSG(x) to_msgs[TO(x)] | 26 | #define TO_MSG(x) to_msgs[TO(x)] |
26 | #define PP(x) (((x) >> 9) & 0x3) | 27 | #define PP(x) (((x) >> 9) & 0x3) |
27 | #define PP_MSG(x) pp_msgs[PP(x)] | 28 | #define PP_MSG(x) pp_msgs[PP(x)] |
29 | #define UU(x) (((x) >> 8) & 0x3) | ||
30 | #define UU_MSG(x) uu_msgs[UU(x)] | ||
28 | 31 | ||
29 | #define R4(x) (((x) >> 4) & 0xf) | 32 | #define R4(x) (((x) >> 4) & 0xf) |
30 | #define R4_MSG(x) ((R4(x) < 9) ? rrrr_msgs[R4(x)] : "Wrong R4!") | 33 | #define R4_MSG(x) ((R4(x) < 9) ? rrrr_msgs[R4(x)] : "Wrong R4!") |
@@ -32,6 +35,8 @@ | |||
32 | #define MCI_STATUS_DEFERRED BIT_64(44) | 35 | #define MCI_STATUS_DEFERRED BIT_64(44) |
33 | #define MCI_STATUS_POISON BIT_64(43) | 36 | #define MCI_STATUS_POISON BIT_64(43) |
34 | 37 | ||
38 | extern const char * const pp_msgs[]; | ||
39 | |||
35 | enum tt_ids { | 40 | enum tt_ids { |
36 | TT_INSTR = 0, | 41 | TT_INSTR = 0, |
37 | TT_DATA, | 42 | TT_DATA, |
@@ -65,19 +70,13 @@ enum rrrr_ids { | |||
65 | R4_SNOOP, | 70 | R4_SNOOP, |
66 | }; | 71 | }; |
67 | 72 | ||
68 | extern const char * const tt_msgs[]; | ||
69 | extern const char * const ll_msgs[]; | ||
70 | extern const char * const rrrr_msgs[]; | ||
71 | extern const char * const pp_msgs[]; | ||
72 | extern const char * const to_msgs[]; | ||
73 | extern const char * const ii_msgs[]; | ||
74 | |||
75 | /* | 73 | /* |
76 | * per-family decoder ops | 74 | * per-family decoder ops |
77 | */ | 75 | */ |
78 | struct amd_decoder_ops { | 76 | struct amd_decoder_ops { |
79 | bool (*mc0_mce)(u16, u8); | 77 | bool (*mc0_mce)(u16, u8); |
80 | bool (*mc1_mce)(u16, u8); | 78 | bool (*mc1_mce)(u16, u8); |
79 | bool (*mc2_mce)(u16, u8); | ||
81 | }; | 80 | }; |
82 | 81 | ||
83 | void amd_report_gart_errors(bool); | 82 | void amd_report_gart_errors(bool); |
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 42a840d530a5..3eb32f62d72a 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c | |||
@@ -301,7 +301,7 @@ int mpc85xx_pci_err_probe(struct platform_device *op) | |||
301 | "[EDAC] PCI err", pci); | 301 | "[EDAC] PCI err", pci); |
302 | if (res < 0) { | 302 | if (res < 0) { |
303 | printk(KERN_ERR | 303 | printk(KERN_ERR |
304 | "%s: Unable to requiest irq %d for " | 304 | "%s: Unable to request irq %d for " |
305 | "MPC85xx PCI err\n", __func__, pdata->irq); | 305 | "MPC85xx PCI err\n", __func__, pdata->irq); |
306 | irq_dispose_mapping(pdata->irq); | 306 | irq_dispose_mapping(pdata->irq); |
307 | res = -ENODEV; | 307 | res = -ENODEV; |
@@ -583,7 +583,7 @@ static int mpc85xx_l2_err_probe(struct platform_device *op) | |||
583 | "[EDAC] L2 err", edac_dev); | 583 | "[EDAC] L2 err", edac_dev); |
584 | if (res < 0) { | 584 | if (res < 0) { |
585 | printk(KERN_ERR | 585 | printk(KERN_ERR |
586 | "%s: Unable to requiest irq %d for " | 586 | "%s: Unable to request irq %d for " |
587 | "MPC85xx L2 err\n", __func__, pdata->irq); | 587 | "MPC85xx L2 err\n", __func__, pdata->irq); |
588 | irq_dispose_mapping(pdata->irq); | 588 | irq_dispose_mapping(pdata->irq); |
589 | res = -ENODEV; | 589 | res = -ENODEV; |