Skip to content

Commit 126168f

Browse files
qzhuo2aegl
authored andcommitted
EDAC/{skx_common,i10nm}: Refactor show_retry_rd_err_log()
Make the {valid bit, overwritten status, number} of RRL registers and the {number, offsets, widths} of per-channel CORRERRCNT registers configurable. Refactor show_retry_rd_err_log() to use the configurable fields of struct reg_rrl, making the code more scalable and simpler. No functional changes intended. Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com> Signed-off-by: Tony Luck <tony.luck@intel.com> Tested-by: Feng Xu <feng.f.xu@intel.com> Link: https://lore.kernel.org/r/20250417150724.1170168-7-qiuxu.zhuo@intel.com
1 parent ba3985c commit 126168f

File tree

2 files changed

+81
-92
lines changed

2 files changed

+81
-92
lines changed

drivers/edac/i10nm_base.c

Lines changed: 71 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@
7272
#define I10NM_SAD_ENABLE(reg) GET_BITFIELD(reg, 0, 0)
7373
#define I10NM_SAD_NM_CACHEABLE(reg) GET_BITFIELD(reg, 5, 5)
7474

75-
#define RETRY_RD_ERR_LOG_OVER_UC_V (BIT(2) | BIT(1) | BIT(0))
76-
7775
static struct list_head *i10nm_edac_list;
7876

7977
static struct res_config *res_cfg;
@@ -83,59 +81,87 @@ static bool mem_cfg_2lm;
8381

8482
static struct reg_rrl icx_reg_rrl_ddr = {
8583
.set_num = 2,
84+
.reg_num = 6,
8685
.modes = {LRE_SCRUB, LRE_DEMAND},
8786
.offsets = {
8887
{0x22c60, 0x22c54, 0x22c5c, 0x22c58, 0x22c28, 0x20ed8},
8988
{0x22e54, 0x22e60, 0x22e64, 0x22e58, 0x22e5c, 0x20ee0},
9089
},
9190
.widths = {4, 4, 4, 4, 4, 8},
91+
.v_mask = BIT(0),
9292
.uc_mask = BIT(1),
93+
.over_mask = BIT(2),
9394
.en_patspr_mask = BIT(13),
9495
.noover_mask = BIT(14),
9596
.en_mask = BIT(15),
97+
98+
.cecnt_num = 4,
99+
.cecnt_offsets = {0x22c18, 0x22c1c, 0x22c20, 0x22c24},
100+
.cecnt_widths = {4, 4, 4, 4},
96101
};
97102

98103
static struct reg_rrl spr_reg_rrl_ddr = {
99104
.set_num = 3,
105+
.reg_num = 6,
100106
.modes = {LRE_SCRUB, LRE_DEMAND, FRE_DEMAND},
101107
.offsets = {
102108
{0x22c60, 0x22c54, 0x22f08, 0x22c58, 0x22c28, 0x20ed8},
103109
{0x22e54, 0x22e60, 0x22f10, 0x22e58, 0x22e5c, 0x20ee0},
104110
{0x22c70, 0x22d80, 0x22f18, 0x22d58, 0x22c64, 0x20f10},
105111
},
106112
.widths = {4, 4, 8, 4, 4, 8},
113+
.v_mask = BIT(0),
107114
.uc_mask = BIT(1),
115+
.over_mask = BIT(2),
108116
.en_patspr_mask = BIT(13),
109117
.noover_mask = BIT(14),
110118
.en_mask = BIT(15),
119+
120+
.cecnt_num = 4,
121+
.cecnt_offsets = {0x22c18, 0x22c1c, 0x22c20, 0x22c24},
122+
.cecnt_widths = {4, 4, 4, 4},
111123
};
112124

113125
static struct reg_rrl spr_reg_rrl_hbm_pch0 = {
114126
.set_num = 2,
127+
.reg_num = 6,
115128
.modes = {LRE_SCRUB, LRE_DEMAND},
116129
.offsets = {
117130
{0x2860, 0x2854, 0x2b08, 0x2858, 0x2828, 0x0ed8},
118131
{0x2a54, 0x2a60, 0x2b10, 0x2a58, 0x2a5c, 0x0ee0},
119132
},
120133
.widths = {4, 4, 8, 4, 4, 8},
134+
.v_mask = BIT(0),
121135
.uc_mask = BIT(1),
136+
.over_mask = BIT(2),
122137
.en_patspr_mask = BIT(13),
123138
.noover_mask = BIT(14),
124139
.en_mask = BIT(15),
140+
141+
.cecnt_num = 4,
142+
.cecnt_offsets = {0x2818, 0x281c, 0x2820, 0x2824},
143+
.cecnt_widths = {4, 4, 4, 4},
125144
};
126145

127146
static struct reg_rrl spr_reg_rrl_hbm_pch1 = {
128147
.set_num = 2,
148+
.reg_num = 6,
129149
.modes = {LRE_SCRUB, LRE_DEMAND},
130150
.offsets = {
131151
{0x2c60, 0x2c54, 0x2f08, 0x2c58, 0x2c28, 0x0fa8},
132152
{0x2e54, 0x2e60, 0x2f10, 0x2e58, 0x2e5c, 0x0fb0},
133153
},
134154
.widths = {4, 4, 8, 4, 4, 8},
155+
.v_mask = BIT(0),
135156
.uc_mask = BIT(1),
157+
.over_mask = BIT(2),
136158
.en_patspr_mask = BIT(13),
137159
.noover_mask = BIT(14),
138160
.en_mask = BIT(15),
161+
162+
.cecnt_num = 4,
163+
.cecnt_offsets = {0x2c18, 0x2c1c, 0x2c20, 0x2c24},
164+
.cecnt_widths = {4, 4, 4, 4},
139165
};
140166

141167
static u64 read_imc_reg(struct skx_imc *imc, int chan, u32 offset, u8 width)
@@ -276,110 +302,64 @@ static void enable_retry_rd_err_log(bool enable)
276302
static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
277303
int len, bool scrub_err)
278304
{
305+
int i, j, n, ch = res->channel, pch = res->cs & 1;
279306
struct skx_imc *imc = &res->dev->imc[res->imc];
280-
u32 log0, log1, log2, log3, log4;
281-
u32 corr0, corr1, corr2, corr3;
282-
u32 lxg0, lxg1, lxg3, lxg4;
283-
u32 *xffsets = NULL;
284-
u64 log2a, log5;
285-
u64 lxg2a, lxg5;
286-
u32 *offsets;
287-
int n, pch;
307+
u32 offset, status_mask;
308+
struct reg_rrl *rrl;
309+
u64 log, corr;
310+
bool scrub;
311+
u8 width;
288312

289313
if (!imc->mbase)
290314
return;
291315

292-
if (imc->hbm_mc) {
293-
pch = res->cs & 1;
316+
rrl = imc->hbm_mc ? res_cfg->reg_rrl_hbm[pch] : res_cfg->reg_rrl_ddr;
294317

295-
if (pch)
296-
offsets = scrub_err ? res_cfg->reg_rrl_hbm[1]->offsets[0] :
297-
res_cfg->reg_rrl_hbm[1]->offsets[1];
298-
else
299-
offsets = scrub_err ? res_cfg->reg_rrl_hbm[0]->offsets[0] :
300-
res_cfg->reg_rrl_hbm[0]->offsets[1];
301-
} else {
302-
if (scrub_err) {
303-
offsets = res_cfg->reg_rrl_ddr->offsets[0];
304-
} else {
305-
offsets = res_cfg->reg_rrl_ddr->offsets[1];
306-
if (res_cfg->reg_rrl_ddr->set_num > 2)
307-
xffsets = res_cfg->reg_rrl_ddr->offsets[2];
308-
}
309-
}
318+
if (!rrl)
319+
return;
310320

311-
log0 = I10NM_GET_REG32(imc, res->channel, offsets[0]);
312-
log1 = I10NM_GET_REG32(imc, res->channel, offsets[1]);
313-
log3 = I10NM_GET_REG32(imc, res->channel, offsets[3]);
314-
log4 = I10NM_GET_REG32(imc, res->channel, offsets[4]);
315-
log5 = I10NM_GET_REG64(imc, res->channel, offsets[5]);
316-
317-
if (xffsets) {
318-
lxg0 = I10NM_GET_REG32(imc, res->channel, xffsets[0]);
319-
lxg1 = I10NM_GET_REG32(imc, res->channel, xffsets[1]);
320-
lxg3 = I10NM_GET_REG32(imc, res->channel, xffsets[3]);
321-
lxg4 = I10NM_GET_REG32(imc, res->channel, xffsets[4]);
322-
lxg5 = I10NM_GET_REG64(imc, res->channel, xffsets[5]);
323-
}
321+
status_mask = rrl->over_mask | rrl->uc_mask | rrl->v_mask;
324322

325-
if (res_cfg->type == SPR) {
326-
log2a = I10NM_GET_REG64(imc, res->channel, offsets[2]);
327-
n = snprintf(msg, len, " retry_rd_err_log[%.8x %.8x %.16llx %.8x %.8x %.16llx",
328-
log0, log1, log2a, log3, log4, log5);
323+
n = snprintf(msg, len, " retry_rd_err_log[");
324+
for (i = 0; i < rrl->set_num; i++) {
325+
scrub = (rrl->modes[i] == FRE_SCRUB || rrl->modes[i] == LRE_SCRUB);
326+
if (scrub_err != scrub)
327+
continue;
329328

330-
if (len - n > 0) {
331-
if (xffsets) {
332-
lxg2a = I10NM_GET_REG64(imc, res->channel, xffsets[2]);
333-
n += snprintf(msg + n, len - n, " %.8x %.8x %.16llx %.8x %.8x %.16llx]",
334-
lxg0, lxg1, lxg2a, lxg3, lxg4, lxg5);
335-
} else {
336-
n += snprintf(msg + n, len - n, "]");
337-
}
338-
}
339-
} else {
340-
log2 = I10NM_GET_REG32(imc, res->channel, offsets[2]);
341-
n = snprintf(msg, len, " retry_rd_err_log[%.8x %.8x %.8x %.8x %.8x %.16llx]",
342-
log0, log1, log2, log3, log4, log5);
343-
}
329+
for (j = 0; j < rrl->reg_num && len - n > 0; j++) {
330+
offset = rrl->offsets[i][j];
331+
width = rrl->widths[j];
332+
log = read_imc_reg(imc, ch, offset, width);
344333

345-
if (imc->hbm_mc) {
346-
if (pch) {
347-
corr0 = I10NM_GET_REG32(imc, res->channel, 0x2c18);
348-
corr1 = I10NM_GET_REG32(imc, res->channel, 0x2c1c);
349-
corr2 = I10NM_GET_REG32(imc, res->channel, 0x2c20);
350-
corr3 = I10NM_GET_REG32(imc, res->channel, 0x2c24);
351-
} else {
352-
corr0 = I10NM_GET_REG32(imc, res->channel, 0x2818);
353-
corr1 = I10NM_GET_REG32(imc, res->channel, 0x281c);
354-
corr2 = I10NM_GET_REG32(imc, res->channel, 0x2820);
355-
corr3 = I10NM_GET_REG32(imc, res->channel, 0x2824);
334+
if (width == 4)
335+
n += snprintf(msg + n, len - n, "%.8llx ", log);
336+
else
337+
n += snprintf(msg + n, len - n, "%.16llx ", log);
338+
339+
/* Clear RRL status if RRL in Linux control mode. */
340+
if (retry_rd_err_log == 2 && !j && (log & status_mask))
341+
write_imc_reg(imc, ch, offset, width, log & ~status_mask);
356342
}
357-
} else {
358-
corr0 = I10NM_GET_REG32(imc, res->channel, 0x22c18);
359-
corr1 = I10NM_GET_REG32(imc, res->channel, 0x22c1c);
360-
corr2 = I10NM_GET_REG32(imc, res->channel, 0x22c20);
361-
corr3 = I10NM_GET_REG32(imc, res->channel, 0x22c24);
362343
}
363344

364-
if (len - n > 0)
365-
snprintf(msg + n, len - n,
366-
" correrrcnt[%.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x]",
367-
corr0 & 0xffff, corr0 >> 16,
368-
corr1 & 0xffff, corr1 >> 16,
369-
corr2 & 0xffff, corr2 >> 16,
370-
corr3 & 0xffff, corr3 >> 16);
371-
372-
/* Clear status bits */
373-
if (retry_rd_err_log == 2) {
374-
if (log0 & RETRY_RD_ERR_LOG_OVER_UC_V) {
375-
log0 &= ~RETRY_RD_ERR_LOG_OVER_UC_V;
376-
I10NM_SET_REG32(imc, res->channel, offsets[0], log0);
377-
}
345+
/* Move back one space. */
346+
n--;
347+
n += snprintf(msg + n, len - n, "]");
348+
349+
if (len - n > 0) {
350+
n += snprintf(msg + n, len - n, " correrrcnt[");
351+
for (i = 0; i < rrl->cecnt_num && len - n > 0; i++) {
352+
offset = rrl->cecnt_offsets[i];
353+
width = rrl->cecnt_widths[i];
354+
corr = read_imc_reg(imc, ch, offset, width);
378355

379-
if (xffsets && (lxg0 & RETRY_RD_ERR_LOG_OVER_UC_V)) {
380-
lxg0 &= ~RETRY_RD_ERR_LOG_OVER_UC_V;
381-
I10NM_SET_REG32(imc, res->channel, xffsets[0], lxg0);
356+
n += snprintf(msg + n, len - n, "%.4llx %.4llx ",
357+
corr & 0xffff, corr >> 16);
382358
}
359+
360+
/* Move back one space. */
361+
n--;
362+
n += snprintf(msg + n, len - n, "]");
383363
}
384364
}
385365

drivers/edac/skx_common.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@
8383
#define NUM_RRL_SET 3
8484
/* Max RRL registers per set. */
8585
#define NUM_RRL_REG 6
86+
/* Max correctable error count registers. */
87+
#define NUM_CECNT_REG 4
8688

8789
/* Modes of RRL register set. */
8890
enum rrl_mode {
@@ -99,16 +101,23 @@ enum rrl_mode {
99101
/* RRL registers per {,sub-,pseudo-}channel. */
100102
struct reg_rrl {
101103
/* RRL register parts. */
102-
int set_num;
104+
int set_num, reg_num;
103105
enum rrl_mode modes[NUM_RRL_SET];
104106
u32 offsets[NUM_RRL_SET][NUM_RRL_REG];
105107
/* RRL register widths in byte per set. */
106108
u8 widths[NUM_RRL_REG];
107109
/* RRL control bits of the first register per set. */
110+
u32 v_mask;
108111
u32 uc_mask;
112+
u32 over_mask;
109113
u32 en_patspr_mask;
110114
u32 noover_mask;
111115
u32 en_mask;
116+
117+
/* CORRERRCNT register parts. */
118+
int cecnt_num;
119+
u32 cecnt_offsets[NUM_CECNT_REG];
120+
u8 cecnt_widths[NUM_CECNT_REG];
112121
};
113122

114123
/*

0 commit comments

Comments
 (0)