diff options
author | Borislav Petkov <borislav.petkov@amd.com> | 2011-11-24 15:29:57 -0500 |
---|---|---|
committer | Borislav Petkov <bp@alien8.de> | 2012-03-19 07:06:25 -0400 |
commit | 68782673e6dd69054a9b75b0983a5e45e16f6625 (patch) | |
tree | b25cf845be2205fa20d81edc456d03d03f440993 /drivers/edac | |
parent | b64a99c1752d2b6525a5011a8e473f8f8a4bdd79 (diff) |
MCE, AMD: Rework NB MCE signatures
Correct their formulation, replace per-family functions with a single,
unified lookup table.
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Reviewed-by: Andreas Herrmann <andreas.herrmann3@amd.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/mce_amd.c | 176 | ||||
-rw-r--r-- | drivers/edac/mce_amd.h | 1 |
2 files changed, 48 insertions, 129 deletions
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c index bf6dd9978aa7..f6ebe5e9a57f 100644 --- a/drivers/edac/mce_amd.c +++ b/drivers/edac/mce_amd.c | |||
@@ -64,17 +64,6 @@ EXPORT_SYMBOL_GPL(to_msgs); | |||
64 | const char *ii_msgs[] = { "MEM", "RESV", "IO", "GEN" }; | 64 | const char *ii_msgs[] = { "MEM", "RESV", "IO", "GEN" }; |
65 | EXPORT_SYMBOL_GPL(ii_msgs); | 65 | EXPORT_SYMBOL_GPL(ii_msgs); |
66 | 66 | ||
67 | static 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" | ||
76 | }; | ||
77 | |||
78 | static const char * const f15h_ic_mce_desc[] = { | 67 | static const char * const f15h_ic_mce_desc[] = { |
79 | "UC during a demand linefill from L2", | 68 | "UC during a demand linefill from L2", |
80 | "Parity error during data load from IC", | 69 | "Parity error during data load from IC", |
@@ -112,6 +101,28 @@ static const char * const f15h_cu_mce_desc[] = { | |||
112 | "PRB address parity error" | 101 | "PRB address parity error" |
113 | }; | 102 | }; |
114 | 103 | ||
104 | static const char *nb_mce_desc[] = { | ||
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 | |||
115 | static const char * const fr_ex_mce_desc[] = { | 126 | static const char * const fr_ex_mce_desc[] = { |
116 | "CPU Watchdog timer expire", | 127 | "CPU Watchdog timer expire", |
117 | "Wakeup array dest tag", | 128 | "Wakeup array dest tag", |
@@ -499,58 +510,31 @@ wrong_ls_mce: | |||
499 | pr_emerg(HW_ERR "Corrupted LS MCE info?\n"); | 510 | pr_emerg(HW_ERR "Corrupted LS MCE info?\n"); |
500 | } | 511 | } |
501 | 512 | ||
502 | static bool k8_nb_mce(u16 ec, u8 xec) | 513 | void amd_decode_nb_mce(struct mce *m) |
503 | { | 514 | { |
504 | bool ret = true; | 515 | struct cpuinfo_x86 *c = &boot_cpu_data; |
505 | 516 | int node_id = amd_get_nb_id(m->extcpu); | |
506 | switch (xec) { | 517 | u16 ec = EC(m->status); |
507 | case 0x1: | 518 | u8 xec = XEC(m->status, 0x1f); |
508 | pr_cont("CRC error detected on HT link.\n"); | 519 | u8 offset = 0; |
509 | break; | ||
510 | |||
511 | case 0x5: | ||
512 | pr_cont("Invalid GART PTE entry during GART table walk.\n"); | ||
513 | break; | ||
514 | |||
515 | case 0x6: | ||
516 | pr_cont("Unsupported atomic RMW received from an IO link.\n"); | ||
517 | break; | ||
518 | |||
519 | case 0x0: | ||
520 | case 0x8: | ||
521 | if (boot_cpu_data.x86 == 0x11) | ||
522 | return false; | ||
523 | |||
524 | pr_cont("DRAM ECC error detected on the NB.\n"); | ||
525 | break; | ||
526 | |||
527 | case 0xd: | ||
528 | pr_cont("Parity error on the DRAM addr/ctl signals.\n"); | ||
529 | break; | ||
530 | |||
531 | default: | ||
532 | ret = false; | ||
533 | break; | ||
534 | } | ||
535 | 520 | ||
536 | return ret; | 521 | pr_emerg(HW_ERR "Northbridge Error (node %d): ", node_id); |
537 | } | ||
538 | 522 | ||
539 | static bool f10h_nb_mce(u16 ec, u8 xec) | 523 | switch (xec) { |
540 | { | 524 | case 0x0 ... 0xe: |
541 | bool ret = true; | ||
542 | u8 offset = 0; | ||
543 | 525 | ||
544 | if (k8_nb_mce(ec, xec)) | 526 | /* special handling for DRAM ECCs */ |
545 | return true; | 527 | if (xec == 0x0 || xec == 0x8) { |
528 | /* no ECCs on F11h */ | ||
529 | if (c->x86 == 0x11) | ||
530 | goto wrong_nb_mce; | ||
546 | 531 | ||
547 | switch(xec) { | 532 | pr_cont("%s.\n", nb_mce_desc[xec]); |
548 | case 0xa ... 0xc: | ||
549 | offset = 10; | ||
550 | break; | ||
551 | 533 | ||
552 | case 0xe: | 534 | if (nb_bus_decoder) |
553 | offset = 11; | 535 | nb_bus_decoder(node_id, m); |
536 | return; | ||
537 | } | ||
554 | break; | 538 | break; |
555 | 539 | ||
556 | case 0xf: | 540 | case 0xf: |
@@ -559,83 +543,25 @@ static bool f10h_nb_mce(u16 ec, u8 xec) | |||
559 | else if (BUS_ERROR(ec)) | 543 | else if (BUS_ERROR(ec)) |
560 | pr_cont("DMA Exclusion Vector Table Walk error.\n"); | 544 | pr_cont("DMA Exclusion Vector Table Walk error.\n"); |
561 | else | 545 | else |
562 | ret = false; | 546 | goto wrong_nb_mce; |
563 | 547 | return; | |
564 | goto out; | ||
565 | break; | ||
566 | 548 | ||
567 | case 0x19: | 549 | case 0x19: |
568 | if (boot_cpu_data.x86 == 0x15) | 550 | if (boot_cpu_data.x86 == 0x15) |
569 | pr_cont("Compute Unit Data Error.\n"); | 551 | pr_cont("Compute Unit Data Error.\n"); |
570 | else | 552 | else |
571 | ret = false; | 553 | goto wrong_nb_mce; |
572 | 554 | return; | |
573 | goto out; | ||
574 | break; | ||
575 | 555 | ||
576 | case 0x1c ... 0x1f: | 556 | case 0x1c ... 0x1f: |
577 | offset = 24; | 557 | offset = 13; |
578 | break; | 558 | break; |
579 | 559 | ||
580 | default: | 560 | default: |
581 | ret = false; | ||
582 | |||
583 | goto out; | ||
584 | break; | ||
585 | } | ||
586 | |||
587 | pr_cont("%s.\n", f10h_nb_mce_desc[xec - offset]); | ||
588 | |||
589 | out: | ||
590 | return ret; | ||
591 | } | ||
592 | |||
593 | static bool nb_noop_mce(u16 ec, u8 xec) | ||
594 | { | ||
595 | return false; | ||
596 | } | ||
597 | |||
598 | void amd_decode_nb_mce(struct mce *m) | ||
599 | { | ||
600 | struct cpuinfo_x86 *c = &boot_cpu_data; | ||
601 | int node_id = amd_get_nb_id(m->extcpu); | ||
602 | u16 ec = EC(m->status); | ||
603 | u8 xec = XEC(m->status, 0x1f); | ||
604 | |||
605 | pr_emerg(HW_ERR "Northbridge Error (node %d): ", node_id); | ||
606 | |||
607 | switch (xec) { | ||
608 | case 0x2: | ||
609 | pr_cont("Sync error (sync packets on HT link detected).\n"); | ||
610 | return; | ||
611 | |||
612 | case 0x3: | ||
613 | pr_cont("HT Master abort.\n"); | ||
614 | return; | ||
615 | |||
616 | case 0x4: | ||
617 | pr_cont("HT Target abort.\n"); | ||
618 | return; | ||
619 | |||
620 | case 0x7: | ||
621 | pr_cont("NB Watchdog timeout.\n"); | ||
622 | return; | ||
623 | |||
624 | case 0x9: | ||
625 | pr_cont("SVM DMA Exclusion Vector error.\n"); | ||
626 | return; | ||
627 | |||
628 | default: | ||
629 | break; | ||
630 | } | ||
631 | |||
632 | if (!fam_ops->nb_mce(ec, xec)) | ||
633 | goto wrong_nb_mce; | 561 | goto wrong_nb_mce; |
562 | } | ||
634 | 563 | ||
635 | if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x15) | 564 | pr_cont("%s.\n", nb_mce_desc[xec - offset]); |
636 | if ((xec == 0x8 || xec == 0x0) && nb_bus_decoder) | ||
637 | nb_bus_decoder(node_id, m); | ||
638 | |||
639 | return; | 565 | return; |
640 | 566 | ||
641 | wrong_nb_mce: | 567 | wrong_nb_mce: |
@@ -844,39 +770,33 @@ static int __init mce_amd_init(void) | |||
844 | case 0xf: | 770 | case 0xf: |
845 | fam_ops->dc_mce = k8_dc_mce; | 771 | fam_ops->dc_mce = k8_dc_mce; |
846 | fam_ops->ic_mce = k8_ic_mce; | 772 | fam_ops->ic_mce = k8_ic_mce; |
847 | fam_ops->nb_mce = k8_nb_mce; | ||
848 | break; | 773 | break; |
849 | 774 | ||
850 | case 0x10: | 775 | case 0x10: |
851 | fam_ops->dc_mce = f10h_dc_mce; | 776 | fam_ops->dc_mce = f10h_dc_mce; |
852 | fam_ops->ic_mce = k8_ic_mce; | 777 | fam_ops->ic_mce = k8_ic_mce; |
853 | fam_ops->nb_mce = f10h_nb_mce; | ||
854 | break; | 778 | break; |
855 | 779 | ||
856 | case 0x11: | 780 | case 0x11: |
857 | fam_ops->dc_mce = k8_dc_mce; | 781 | fam_ops->dc_mce = k8_dc_mce; |
858 | fam_ops->ic_mce = k8_ic_mce; | 782 | fam_ops->ic_mce = k8_ic_mce; |
859 | fam_ops->nb_mce = f10h_nb_mce; | ||
860 | break; | 783 | break; |
861 | 784 | ||
862 | case 0x12: | 785 | case 0x12: |
863 | fam_ops->dc_mce = f12h_dc_mce; | 786 | fam_ops->dc_mce = f12h_dc_mce; |
864 | fam_ops->ic_mce = k8_ic_mce; | 787 | fam_ops->ic_mce = k8_ic_mce; |
865 | fam_ops->nb_mce = nb_noop_mce; | ||
866 | break; | 788 | break; |
867 | 789 | ||
868 | case 0x14: | 790 | case 0x14: |
869 | nb_err_cpumask = 0x3; | 791 | nb_err_cpumask = 0x3; |
870 | fam_ops->dc_mce = f14h_dc_mce; | 792 | fam_ops->dc_mce = f14h_dc_mce; |
871 | fam_ops->ic_mce = f14h_ic_mce; | 793 | fam_ops->ic_mce = f14h_ic_mce; |
872 | fam_ops->nb_mce = nb_noop_mce; | ||
873 | break; | 794 | break; |
874 | 795 | ||
875 | case 0x15: | 796 | case 0x15: |
876 | xec_mask = 0x1f; | 797 | xec_mask = 0x1f; |
877 | fam_ops->dc_mce = f15h_dc_mce; | 798 | fam_ops->dc_mce = f15h_dc_mce; |
878 | fam_ops->ic_mce = f15h_ic_mce; | 799 | fam_ops->ic_mce = f15h_ic_mce; |
879 | fam_ops->nb_mce = f10h_nb_mce; | ||
880 | break; | 800 | break; |
881 | 801 | ||
882 | default: | 802 | default: |
diff --git a/drivers/edac/mce_amd.h b/drivers/edac/mce_amd.h index 0106747e240c..6fcf599e691f 100644 --- a/drivers/edac/mce_amd.h +++ b/drivers/edac/mce_amd.h | |||
@@ -82,7 +82,6 @@ extern const char *ii_msgs[]; | |||
82 | struct amd_decoder_ops { | 82 | struct amd_decoder_ops { |
83 | bool (*dc_mce)(u16, u8); | 83 | bool (*dc_mce)(u16, u8); |
84 | bool (*ic_mce)(u16, u8); | 84 | bool (*ic_mce)(u16, u8); |
85 | bool (*nb_mce)(u16, u8); | ||
86 | }; | 85 | }; |
87 | 86 | ||
88 | void amd_report_gart_errors(bool); | 87 | void amd_report_gart_errors(bool); |