aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/amd64_edac.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 28f85c9e3afc..3d6d0007ed5d 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -729,3 +729,145 @@ static int sys_addr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr)
729 return csrow; 729 return csrow;
730} 730}
731 731
732static int get_channel_from_ecc_syndrome(unsigned short syndrome);
733
734static void amd64_cpu_display_info(struct amd64_pvt *pvt)
735{
736 if (boot_cpu_data.x86 == 0x11)
737 edac_printk(KERN_DEBUG, EDAC_MC, "F11h CPU detected\n");
738 else if (boot_cpu_data.x86 == 0x10)
739 edac_printk(KERN_DEBUG, EDAC_MC, "F10h CPU detected\n");
740 else if (boot_cpu_data.x86 == 0xf)
741 edac_printk(KERN_DEBUG, EDAC_MC, "%s detected\n",
742 (pvt->ext_model >= OPTERON_CPU_REV_F) ?
743 "Rev F or later" : "Rev E or earlier");
744 else
745 /* we'll hardly ever ever get here */
746 edac_printk(KERN_ERR, EDAC_MC, "Unknown cpu!\n");
747}
748
749/*
750 * Determine if the DIMMs have ECC enabled. ECC is enabled ONLY if all the DIMMs
751 * are ECC capable.
752 */
753static enum edac_type amd64_determine_edac_cap(struct amd64_pvt *pvt)
754{
755 int bit;
756 enum dev_type edac_cap = EDAC_NONE;
757
758 bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= OPTERON_CPU_REV_F)
759 ? 19
760 : 17;
761
762 if (pvt->dclr0 >> BIT(bit))
763 edac_cap = EDAC_FLAG_SECDED;
764
765 return edac_cap;
766}
767
768
769static void f10_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt,
770 int ganged);
771
772/* Display and decode various NB registers for debug purposes. */
773static void amd64_dump_misc_regs(struct amd64_pvt *pvt)
774{
775 int ganged;
776
777 debugf1(" nbcap:0x%8.08x DctDualCap=%s DualNode=%s 8-Node=%s\n",
778 pvt->nbcap,
779 (pvt->nbcap & K8_NBCAP_DCT_DUAL) ? "True" : "False",
780 (pvt->nbcap & K8_NBCAP_DUAL_NODE) ? "True" : "False",
781 (pvt->nbcap & K8_NBCAP_8_NODE) ? "True" : "False");
782 debugf1(" ECC Capable=%s ChipKill Capable=%s\n",
783 (pvt->nbcap & K8_NBCAP_SECDED) ? "True" : "False",
784 (pvt->nbcap & K8_NBCAP_CHIPKILL) ? "True" : "False");
785 debugf1(" DramCfg0-low=0x%08x DIMM-ECC=%s Parity=%s Width=%s\n",
786 pvt->dclr0,
787 (pvt->dclr0 & BIT(19)) ? "Enabled" : "Disabled",
788 (pvt->dclr0 & BIT(8)) ? "Enabled" : "Disabled",
789 (pvt->dclr0 & BIT(11)) ? "128b" : "64b");
790 debugf1(" DIMM x4 Present: L0=%s L1=%s L2=%s L3=%s DIMM Type=%s\n",
791 (pvt->dclr0 & BIT(12)) ? "Y" : "N",
792 (pvt->dclr0 & BIT(13)) ? "Y" : "N",
793 (pvt->dclr0 & BIT(14)) ? "Y" : "N",
794 (pvt->dclr0 & BIT(15)) ? "Y" : "N",
795 (pvt->dclr0 & BIT(16)) ? "UN-Buffered" : "Buffered");
796
797
798 debugf1(" online-spare: 0x%8.08x\n", pvt->online_spare);
799
800 if (boot_cpu_data.x86 == 0xf) {
801 debugf1(" dhar: 0x%8.08x Base=0x%08x Offset=0x%08x\n",
802 pvt->dhar, dhar_base(pvt->dhar),
803 k8_dhar_offset(pvt->dhar));
804 debugf1(" DramHoleValid=%s\n",
805 (pvt->dhar & DHAR_VALID) ? "True" : "False");
806
807 debugf1(" dbam-dkt: 0x%8.08x\n", pvt->dbam0);
808
809 /* everything below this point is Fam10h and above */
810 return;
811
812 } else {
813 debugf1(" dhar: 0x%8.08x Base=0x%08x Offset=0x%08x\n",
814 pvt->dhar, dhar_base(pvt->dhar),
815 f10_dhar_offset(pvt->dhar));
816 debugf1(" DramMemHoistValid=%s DramHoleValid=%s\n",
817 (pvt->dhar & F10_DRAM_MEM_HOIST_VALID) ?
818 "True" : "False",
819 (pvt->dhar & DHAR_VALID) ?
820 "True" : "False");
821 }
822
823 /* Only if NOT ganged does dcl1 have valid info */
824 if (!dct_ganging_enabled(pvt)) {
825 debugf1(" DramCfg1-low=0x%08x DIMM-ECC=%s Parity=%s "
826 "Width=%s\n", pvt->dclr1,
827 (pvt->dclr1 & BIT(19)) ? "Enabled" : "Disabled",
828 (pvt->dclr1 & BIT(8)) ? "Enabled" : "Disabled",
829 (pvt->dclr1 & BIT(11)) ? "128b" : "64b");
830 debugf1(" DIMM x4 Present: L0=%s L1=%s L2=%s L3=%s "
831 "DIMM Type=%s\n",
832 (pvt->dclr1 & BIT(12)) ? "Y" : "N",
833 (pvt->dclr1 & BIT(13)) ? "Y" : "N",
834 (pvt->dclr1 & BIT(14)) ? "Y" : "N",
835 (pvt->dclr1 & BIT(15)) ? "Y" : "N",
836 (pvt->dclr1 & BIT(16)) ? "UN-Buffered" : "Buffered");
837 }
838
839 /*
840 * Determine if ganged and then dump memory sizes for first controller,
841 * and if NOT ganged dump info for 2nd controller.
842 */
843 ganged = dct_ganging_enabled(pvt);
844
845 f10_debug_display_dimm_sizes(0, pvt, ganged);
846
847 if (!ganged)
848 f10_debug_display_dimm_sizes(1, pvt, ganged);
849}
850
851/* Read in both of DBAM registers */
852static void amd64_read_dbam_reg(struct amd64_pvt *pvt)
853{
854 int err = 0;
855 unsigned int reg;
856
857 reg = DBAM0;
858 err = pci_read_config_dword(pvt->dram_f2_ctl, reg, &pvt->dbam0);
859 if (err)
860 goto err_reg;
861
862 if (boot_cpu_data.x86 >= 0x10) {
863 reg = DBAM1;
864 err = pci_read_config_dword(pvt->dram_f2_ctl, reg, &pvt->dbam1);
865
866 if (err)
867 goto err_reg;
868 }
869
870err_reg:
871 debugf0("Error reading F2x%03x.\n", reg);
872}
873