EDAC/amd64: Split ecc_enabled() into dct/umc functions
authorMuralidhara M K <muralidhara.mk@amd.com>
Fri, 27 Jan 2023 17:04:13 +0000 (17:04 +0000)
committerBorislav Petkov (AMD) <bp@alien8.de>
Fri, 24 Mar 2023 12:03:20 +0000 (13:03 +0100)
Call them using a function pointer in pvt->ops. The "ECC enabled"
check is done outside of the hardware information gathering done in
hw_info_get(). So a high-level function pointer is needed to separate
the legacy and modern paths.

No functional change is intended.

  [Yazen: rebased/reworked patch and reworded commit message. ]

Signed-off-by: Muralidhara M K <muralidhara.mk@amd.com>
Co-developed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
Signed-off-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
Co-developed-by: Yazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20230127170419.1824692-17-yazen.ghannam@amd.com
drivers/edac/amd64_edac.c
drivers/edac/amd64_edac.h

index df95f3b..ef8f097 100644 (file)
@@ -3527,52 +3527,59 @@ static void restore_ecc_error_reporting(struct ecc_settings *s, u16 nid,
                amd64_warn("Error restoring NB MCGCTL settings!\n");
 }
 
-static bool ecc_enabled(struct amd64_pvt *pvt)
+static bool dct_ecc_enabled(struct amd64_pvt *pvt)
 {
        u16 nid = pvt->mc_node_id;
        bool nb_mce_en = false;
-       u8 ecc_en = 0, i;
+       u8 ecc_en = 0;
        u32 value;
 
-       if (boot_cpu_data.x86 >= 0x17) {
-               u8 umc_en_mask = 0, ecc_en_mask = 0;
-               struct amd64_umc *umc;
+       amd64_read_pci_cfg(pvt->F3, NBCFG, &value);
 
-               for_each_umc(i) {
-                       umc = &pvt->umc[i];
+       ecc_en = !!(value & NBCFG_ECC_ENABLE);
 
-                       /* Only check enabled UMCs. */
-                       if (!(umc->sdp_ctrl & UMC_SDP_INIT))
-                               continue;
+       nb_mce_en = nb_mce_bank_enabled_on_node(nid);
+       if (!nb_mce_en)
+               edac_dbg(0, "NB MCE bank disabled, set MSR 0x%08x[4] on node %d to enable.\n",
+                        MSR_IA32_MCG_CTL, nid);
 
-                       umc_en_mask |= BIT(i);
+       edac_dbg(3, "Node %d: DRAM ECC %s.\n", nid, (ecc_en ? "enabled" : "disabled"));
 
-                       if (umc->umc_cap_hi & UMC_ECC_ENABLED)
-                               ecc_en_mask |= BIT(i);
-               }
+       if (!ecc_en || !nb_mce_en)
+               return false;
+       else
+               return true;
+}
 
-               /* Check whether at least one UMC is enabled: */
-               if (umc_en_mask)
-                       ecc_en = umc_en_mask == ecc_en_mask;
-               else
-                       edac_dbg(0, "Node %d: No enabled UMCs.\n", nid);
+static bool umc_ecc_enabled(struct amd64_pvt *pvt)
+{
+       u8 umc_en_mask = 0, ecc_en_mask = 0;
+       u16 nid = pvt->mc_node_id;
+       struct amd64_umc *umc;
+       u8 ecc_en = 0, i;
 
-               /* Assume UMC MCA banks are enabled. */
-               nb_mce_en = true;
-       } else {
-               amd64_read_pci_cfg(pvt->F3, NBCFG, &value);
+       for_each_umc(i) {
+               umc = &pvt->umc[i];
+
+               /* Only check enabled UMCs. */
+               if (!(umc->sdp_ctrl & UMC_SDP_INIT))
+                       continue;
 
-               ecc_en = !!(value & NBCFG_ECC_ENABLE);
+               umc_en_mask |= BIT(i);
 
-               nb_mce_en = nb_mce_bank_enabled_on_node(nid);
-               if (!nb_mce_en)
-                       edac_dbg(0, "NB MCE bank disabled, set MSR 0x%08x[4] on node %d to enable.\n",
-                                    MSR_IA32_MCG_CTL, nid);
+               if (umc->umc_cap_hi & 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;
+       else
+               edac_dbg(0, "Node %d: No enabled UMCs.\n", nid);
+
        edac_dbg(3, "Node %d: DRAM ECC %s.\n", nid, (ecc_en ? "enabled" : "disabled"));
 
-       if (!ecc_en || !nb_mce_en)
+       if (!ecc_en)
                return false;
        else
                return true;
@@ -3678,6 +3685,7 @@ static void hw_info_put(struct amd64_pvt *pvt)
 
 static struct low_ops umc_ops = {
        .hw_info_get                    = umc_hw_info_get,
+       .ecc_enabled                    = umc_ecc_enabled,
 };
 
 /* Use Family 16h versions for defaults and adjust as needed below. */
@@ -3685,6 +3693,7 @@ static struct low_ops dct_ops = {
        .map_sysaddr_to_csrow           = f1x_map_sysaddr_to_csrow,
        .dbam_to_cs                     = f16_dbam_to_chip_select,
        .hw_info_get                    = dct_hw_info_get,
+       .ecc_enabled                    = dct_ecc_enabled,
 };
 
 static int per_family_init(struct amd64_pvt *pvt)
@@ -3910,7 +3919,7 @@ static int probe_one_instance(unsigned int nid)
                goto err_enable;
        }
 
-       if (!ecc_enabled(pvt)) {
+       if (!pvt->ops->ecc_enabled(pvt)) {
                ret = -ENODEV;
 
                if (!ecc_enable_override)
index 00b3f32..103cd38 100644 (file)
@@ -467,6 +467,7 @@ struct low_ops {
        int  (*dbam_to_cs)(struct amd64_pvt *pvt, u8 dct,
                           unsigned int cs_mode, int cs_mask_nr);
        int (*hw_info_get)(struct amd64_pvt *pvt);
+       bool (*ecc_enabled)(struct amd64_pvt *pvt);
 };
 
 int __amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,