Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 196b79fc authored by Yazen Ghannam's avatar Yazen Ghannam Committed by Borislav Petkov
Browse files

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: default avatarYazen 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: default avatarBorislav Petkov <bp@suse.de>
parent 627bc29e
Loading
Loading
Loading
Loading
+40 −10
Original line number Diff line number Diff line
@@ -2664,20 +2664,50 @@ 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;

	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);
	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",
			amd64_notice("NB MCE bank disabled, set MSR 0x%08x[4] on node %d to enable.\n",
				     MSR_IA32_MCG_CTL, nid);
	}

	amd64_info("DRAM ECC %s.\n", (ecc_en ? "enabled" : "disabled"));

	if (!ecc_en || !nb_mce_en) {
		amd64_notice("%s", ecc_msg);
+16 −0
Original line number Diff line number Diff line
@@ -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;