forked from luck/tmp_suning_uos_patched
EDAC, amd64: Extend ecc_enabled() to Fam17h
Update the ecc_enabled() function to work on Fam17h. This entails reading a different set of registers and using the SMN (System Management Network) rather than PCI devices. Signed-off-by: Yazen Ghannam <Yazen.Ghannam@amd.com> Cc: Aravind Gopalakrishnan <aravindksg.lkml@gmail.com> Cc: linux-edac <linux-edac@vger.kernel.org> Cc: x86-ml <x86@kernel.org> Link: http://lkml.kernel.org/r/1479423463-8536-9-git-send-email-Yazen.Ghannam@amd.com [ Fixup ecc_en assignment and get_umc_base(). ] Signed-off-by: Borislav Petkov <bp@suse.de>
This commit is contained in:
parent
627bc29ed9
commit
196b79fcc8
@ -2664,21 +2664,51 @@ static const char *ecc_msg =
|
||||
|
||||
static bool ecc_enabled(struct pci_dev *F3, u16 nid)
|
||||
{
|
||||
u32 value;
|
||||
u8 ecc_en = 0;
|
||||
bool nb_mce_en = false;
|
||||
u8 ecc_en = 0, i;
|
||||
u32 value;
|
||||
|
||||
amd64_read_pci_cfg(F3, NBCFG, &value);
|
||||
if (boot_cpu_data.x86 >= 0x17) {
|
||||
u8 umc_en_mask = 0, ecc_en_mask = 0;
|
||||
|
||||
for (i = 0; i < NUM_UMCS; i++) {
|
||||
u32 base = get_umc_base(i);
|
||||
|
||||
/* Only check enabled UMCs. */
|
||||
if (amd_smn_read(nid, base + UMCCH_SDP_CTRL, &value))
|
||||
continue;
|
||||
|
||||
if (!(value & UMC_SDP_INIT))
|
||||
continue;
|
||||
|
||||
umc_en_mask |= BIT(i);
|
||||
|
||||
if (amd_smn_read(nid, base + UMCCH_UMC_CAP_HI, &value))
|
||||
continue;
|
||||
|
||||
if (value & UMC_ECC_ENABLED)
|
||||
ecc_en_mask |= BIT(i);
|
||||
}
|
||||
|
||||
/* Check whether at least one UMC is enabled: */
|
||||
if (umc_en_mask)
|
||||
ecc_en = umc_en_mask == ecc_en_mask;
|
||||
|
||||
/* Assume UMC MCA banks are enabled. */
|
||||
nb_mce_en = true;
|
||||
} else {
|
||||
amd64_read_pci_cfg(F3, NBCFG, &value);
|
||||
|
||||
ecc_en = !!(value & NBCFG_ECC_ENABLE);
|
||||
|
||||
nb_mce_en = nb_mce_bank_enabled_on_node(nid);
|
||||
if (!nb_mce_en)
|
||||
amd64_notice("NB MCE bank disabled, set MSR 0x%08x[4] on node %d to enable.\n",
|
||||
MSR_IA32_MCG_CTL, nid);
|
||||
}
|
||||
|
||||
ecc_en = !!(value & NBCFG_ECC_ENABLE);
|
||||
amd64_info("DRAM ECC %s.\n", (ecc_en ? "enabled" : "disabled"));
|
||||
|
||||
nb_mce_en = nb_mce_bank_enabled_on_node(nid);
|
||||
if (!nb_mce_en)
|
||||
amd64_notice("NB MCE bank disabled, set MSR "
|
||||
"0x%08x[4] on node %d to enable.\n",
|
||||
MSR_IA32_MCG_CTL, nid);
|
||||
|
||||
if (!ecc_en || !nb_mce_en) {
|
||||
amd64_notice("%s", ecc_msg);
|
||||
return false;
|
||||
|
@ -248,6 +248,16 @@
|
||||
/* MSRs */
|
||||
#define MSR_MCGCTL_NBE BIT(4)
|
||||
|
||||
/* UMC CH register offsets */
|
||||
#define UMCCH_SDP_CTRL 0x104
|
||||
#define UMCCH_UMC_CAP_HI 0xDF4
|
||||
|
||||
/* UMC CH bitfields */
|
||||
#define UMC_ECC_ENABLED BIT(30)
|
||||
#define UMC_SDP_INIT BIT(31)
|
||||
|
||||
#define NUM_UMCS 2
|
||||
|
||||
enum amd_families {
|
||||
K8_CPUS = 0,
|
||||
F10_CPUS,
|
||||
@ -354,6 +364,12 @@ struct err_info {
|
||||
u32 offset;
|
||||
};
|
||||
|
||||
static inline u32 get_umc_base(u8 channel)
|
||||
{
|
||||
/* ch0: 0x50000, ch1: 0x150000 */
|
||||
return 0x50000 + (!!channel << 20);
|
||||
}
|
||||
|
||||
static inline u64 get_dram_base(struct amd64_pvt *pvt, u8 i)
|
||||
{
|
||||
u64 addr = ((u64)pvt->ranges[i].base.lo & 0xffff0000) << 8;
|
||||
|
Loading…
Reference in New Issue
Block a user