EDAC/i10nm: Print an extra register set of retry_rd_err_log
authorQiuxu Zhuo <qiuxu.zhuo@intel.com>
Fri, 22 Jul 2022 23:33:37 +0000 (16:33 -0700)
committerTony Luck <tony.luck@intel.com>
Fri, 23 Sep 2022 19:33:27 +0000 (12:33 -0700)
Sapphire Rapids server adds an extra register set for logging more
retry_rd_err_log data. So add code to print the extra register set.

Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Link: https://lore.kernel.org/all/20220722233338.341567-1-tony.luck@intel.com
drivers/edac/i10nm_base.c
drivers/edac/skx_common.h

index b5e9db16291541e76c0b8f39baba683fb4f1fb44..a22ea053f8e1cdbd92d507128258edc450fcb409 100644 (file)
@@ -83,26 +83,38 @@ static u32 offsets_scrub_spr_hbm0[]  = {0x2860, 0x2854, 0x2b08, 0x2858, 0x2828,
 static u32 offsets_scrub_spr_hbm1[]  = {0x2c60, 0x2c54, 0x2f08, 0x2c58, 0x2c28, 0x0fa8};
 static u32 offsets_demand_icx[] = {0x22e54, 0x22e60, 0x22e64, 0x22e58, 0x22e5c, 0x20ee0};
 static u32 offsets_demand_spr[] = {0x22e54, 0x22e60, 0x22f10, 0x22e58, 0x22e5c, 0x20ee0};
+static u32 offsets_demand2_spr[] = {0x22c70, 0x22d80, 0x22f18, 0x22d58, 0x22c64, 0x20f10};
 static u32 offsets_demand_spr_hbm0[] = {0x2a54, 0x2a60, 0x2b10, 0x2a58, 0x2a5c, 0x0ee0};
 static u32 offsets_demand_spr_hbm1[] = {0x2e54, 0x2e60, 0x2f10, 0x2e58, 0x2e5c, 0x0fb0};
 
 static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable,
-                                     u32 *offsets_scrub, u32 *offsets_demand)
+                                     u32 *offsets_scrub, u32 *offsets_demand,
+                                     u32 *offsets_demand2)
 {
-       u32 s, d;
+       u32 s, d, d2;
 
        s = I10NM_GET_REG32(imc, chan, offsets_scrub[0]);
        d = I10NM_GET_REG32(imc, chan, offsets_demand[0]);
+       if (offsets_demand2)
+               d2 = I10NM_GET_REG32(imc, chan, offsets_demand2[0]);
 
        if (enable) {
                /* Save default configurations */
                imc->chan[chan].retry_rd_err_log_s = s;
                imc->chan[chan].retry_rd_err_log_d = d;
+               if (offsets_demand2)
+                       imc->chan[chan].retry_rd_err_log_d2 = d2;
 
                s &= ~RETRY_RD_ERR_LOG_NOOVER_UC;
                s |=  RETRY_RD_ERR_LOG_EN;
                d &= ~RETRY_RD_ERR_LOG_NOOVER_UC;
                d |=  RETRY_RD_ERR_LOG_EN;
+
+               if (offsets_demand2) {
+                       d2 &= ~RETRY_RD_ERR_LOG_UC;
+                       d2 |=  RETRY_RD_ERR_LOG_NOOVER;
+                       d2 |=  RETRY_RD_ERR_LOG_EN;
+               }
        } else {
                /* Restore default configurations */
                if (imc->chan[chan].retry_rd_err_log_s & RETRY_RD_ERR_LOG_UC)
@@ -117,10 +129,21 @@ static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable
                        d |=  RETRY_RD_ERR_LOG_NOOVER;
                if (!(imc->chan[chan].retry_rd_err_log_d & RETRY_RD_ERR_LOG_EN))
                        d &= ~RETRY_RD_ERR_LOG_EN;
+
+               if (offsets_demand2) {
+                       if (imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_UC)
+                               d2 |=  RETRY_RD_ERR_LOG_UC;
+                       if (!(imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_NOOVER))
+                               d2 &=  ~RETRY_RD_ERR_LOG_NOOVER;
+                       if (!(imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_EN))
+                               d2 &= ~RETRY_RD_ERR_LOG_EN;
+               }
        }
 
        I10NM_SET_REG32(imc, chan, offsets_scrub[0], s);
        I10NM_SET_REG32(imc, chan, offsets_demand[0], d);
+       if (offsets_demand2)
+               I10NM_SET_REG32(imc, chan, offsets_demand2[0], d2);
 }
 
 static void enable_retry_rd_err_log(bool enable)
@@ -141,14 +164,17 @@ static void enable_retry_rd_err_log(bool enable)
                                if (imc->hbm_mc) {
                                        __enable_retry_rd_err_log(imc, j, enable,
                                                                  res_cfg->offsets_scrub_hbm0,
-                                                                 res_cfg->offsets_demand_hbm0);
+                                                                 res_cfg->offsets_demand_hbm0,
+                                                                 NULL);
                                        __enable_retry_rd_err_log(imc, j, enable,
                                                                  res_cfg->offsets_scrub_hbm1,
-                                                                 res_cfg->offsets_demand_hbm1);
+                                                                 res_cfg->offsets_demand_hbm1,
+                                                                 NULL);
                                } else {
                                        __enable_retry_rd_err_log(imc, j, enable,
                                                                  res_cfg->offsets_scrub,
-                                                                 res_cfg->offsets_demand);
+                                                                 res_cfg->offsets_demand,
+                                                                 res_cfg->offsets_demand2);
                                }
                        }
        }
@@ -160,7 +186,10 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
        struct skx_imc *imc = &res->dev->imc[res->imc];
        u32 log0, log1, log2, log3, log4;
        u32 corr0, corr1, corr2, corr3;
+       u32 lxg0, lxg1, lxg3, lxg4;
+       u32 *xffsets = NULL;
        u64 log2a, log5;
+       u64 lxg2a, lxg5;
        u32 *offsets;
        int n, pch;
 
@@ -177,8 +206,12 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
                        offsets = scrub_err ? res_cfg->offsets_scrub_hbm0 :
                                              res_cfg->offsets_demand_hbm0;
        } else {
-               offsets = scrub_err ? res_cfg->offsets_scrub :
-                                     res_cfg->offsets_demand;
+               if (scrub_err) {
+                       offsets = res_cfg->offsets_scrub;
+               } else {
+                       offsets = res_cfg->offsets_demand;
+                       xffsets = res_cfg->offsets_demand2;
+               }
        }
 
        log0 = I10NM_GET_REG32(imc, res->channel, offsets[0]);
@@ -187,10 +220,28 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
        log4 = I10NM_GET_REG32(imc, res->channel, offsets[4]);
        log5 = I10NM_GET_REG64(imc, res->channel, offsets[5]);
 
+       if (xffsets) {
+               lxg0 = I10NM_GET_REG32(imc, res->channel, xffsets[0]);
+               lxg1 = I10NM_GET_REG32(imc, res->channel, xffsets[1]);
+               lxg3 = I10NM_GET_REG32(imc, res->channel, xffsets[3]);
+               lxg4 = I10NM_GET_REG32(imc, res->channel, xffsets[4]);
+               lxg5 = I10NM_GET_REG64(imc, res->channel, xffsets[5]);
+       }
+
        if (res_cfg->type == SPR) {
                log2a = I10NM_GET_REG64(imc, res->channel, offsets[2]);
-               n = snprintf(msg, len, " retry_rd_err_log[%.8x %.8x %.16llx %.8x %.8x %.16llx]",
+               n = snprintf(msg, len, " retry_rd_err_log[%.8x %.8x %.16llx %.8x %.8x %.16llx",
                             log0, log1, log2a, log3, log4, log5);
+
+               if (len - n > 0) {
+                       if (xffsets) {
+                               lxg2a = I10NM_GET_REG64(imc, res->channel, xffsets[2]);
+                               n += snprintf(msg + n, len - n, " %.8x %.8x %.16llx %.8x %.8x %.16llx]",
+                                            lxg0, lxg1, lxg2a, lxg3, lxg4, lxg5);
+                       } else {
+                               n += snprintf(msg + n, len - n, "]");
+                       }
+               }
        } else {
                log2 = I10NM_GET_REG32(imc, res->channel, offsets[2]);
                n = snprintf(msg, len, " retry_rd_err_log[%.8x %.8x %.8x %.8x %.8x %.16llx]",
@@ -225,9 +276,16 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
                         corr3 & 0xffff, corr3 >> 16);
 
        /* Clear status bits */
-       if (retry_rd_err_log == 2 && (log0 & RETRY_RD_ERR_LOG_OVER_UC_V)) {
-               log0 &= ~RETRY_RD_ERR_LOG_OVER_UC_V;
-               I10NM_SET_REG32(imc, res->channel, offsets[0], log0);
+       if (retry_rd_err_log == 2) {
+               if (log0 & RETRY_RD_ERR_LOG_OVER_UC_V) {
+                       log0 &= ~RETRY_RD_ERR_LOG_OVER_UC_V;
+                       I10NM_SET_REG32(imc, res->channel, offsets[0], log0);
+               }
+
+               if (xffsets && (lxg0 & RETRY_RD_ERR_LOG_OVER_UC_V)) {
+                       lxg0 &= ~RETRY_RD_ERR_LOG_OVER_UC_V;
+                       I10NM_SET_REG32(imc, res->channel, xffsets[0], lxg0);
+               }
        }
 }
 
@@ -568,6 +626,7 @@ static struct res_config spr_cfg = {
        .offsets_scrub_hbm0     = offsets_scrub_spr_hbm0,
        .offsets_scrub_hbm1     = offsets_scrub_spr_hbm1,
        .offsets_demand         = offsets_demand_spr,
+       .offsets_demand2        = offsets_demand2_spr,
        .offsets_demand_hbm0    = offsets_demand_spr_hbm0,
        .offsets_demand_hbm1    = offsets_demand_spr_hbm1,
 };
index 455e652c0e465ba5eedd453e729bcdadaabf63f6..0cbadd3d2cd39044f438dfa6bc6431ac72826229 100644 (file)
@@ -86,6 +86,7 @@ struct skx_dev {
                        struct pci_dev  *edev;
                        u32 retry_rd_err_log_s;
                        u32 retry_rd_err_log_d;
+                       u32 retry_rd_err_log_d2;
                        struct skx_dimm {
                                u8 close_pg;
                                u8 bank_xor_enable;
@@ -167,6 +168,7 @@ struct res_config {
        u32 *offsets_scrub_hbm0;
        u32 *offsets_scrub_hbm1;
        u32 *offsets_demand;
+       u32 *offsets_demand2;
        u32 *offsets_demand_hbm0;
        u32 *offsets_demand_hbm1;
 };