Skip to content

Commit 4bd4d32

Browse files
qzhuo2aegl
authored andcommitted
EDAC/i10nm: Add detection of memory levels for ICX/SPR servers
Current i10nm_edac driver is only for system configured in 1-level memory. If the system is configured in 2-level memory, the driver doesn't report the 1st level memory DIMM for the error address, even if the error occurs in the 1st level memory. Both Ice Lake servers and Sapphire Rapids servers can be configured in 2-level memory. Add detection of memory levels to i10nm_edac for the two kinds of servers so that the driver can report the 2nd level memory DIMM or the 1st level memory DIMM according to error source. Signed-off-by: Qiuxu Zhuo <[email protected]> Signed-off-by: Tony Luck <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 2f4348e commit 4bd4d32

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

drivers/edac/i10nm_base.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
pci_read_config_dword((d)->uracu, 0xd0, &(reg))
2525
#define I10NM_GET_IMC_BAR(d, i, reg) \
2626
pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg))
27+
#define I10NM_GET_SAD(d, offset, i, reg)\
28+
pci_read_config_dword((d)->sad_all, (offset) + (i) * 8, &(reg))
2729
#define I10NM_GET_DIMMMTR(m, i, j) \
2830
readl((m)->mbase + 0x2080c + (i) * (m)->chan_mmio_sz + (j) * 4)
2931
#define I10NM_GET_MCDDRTCFG(m, i, j) \
@@ -38,6 +40,10 @@
3840
#define I10NM_GET_IMC_MMIO_SIZE(reg) ((GET_BITFIELD(reg, 13, 23) - \
3941
GET_BITFIELD(reg, 0, 10) + 1) << 12)
4042

43+
#define I10NM_MAX_SAD 16
44+
#define I10NM_SAD_ENABLE(reg) GET_BITFIELD(reg, 0, 0)
45+
#define I10NM_SAD_NM_CACHEABLE(reg) GET_BITFIELD(reg, 5, 5)
46+
4147
static struct list_head *i10nm_edac_list;
4248

4349
static struct pci_dev *pci_get_dev_wrapper(int dom, unsigned int bus,
@@ -63,6 +69,31 @@ static struct pci_dev *pci_get_dev_wrapper(int dom, unsigned int bus,
6369
return pdev;
6470
}
6571

72+
static bool i10nm_check_2lm(struct res_config *cfg)
73+
{
74+
struct skx_dev *d;
75+
u32 reg;
76+
int i;
77+
78+
list_for_each_entry(d, i10nm_edac_list, list) {
79+
d->sad_all = pci_get_dev_wrapper(d->seg, d->bus[1],
80+
PCI_SLOT(cfg->sad_all_devfn),
81+
PCI_FUNC(cfg->sad_all_devfn));
82+
if (!d->sad_all)
83+
continue;
84+
85+
for (i = 0; i < I10NM_MAX_SAD; i++) {
86+
I10NM_GET_SAD(d, cfg->sad_all_offset, i, reg);
87+
if (I10NM_SAD_ENABLE(reg) && I10NM_SAD_NM_CACHEABLE(reg)) {
88+
edac_dbg(2, "2-level memory configuration.\n");
89+
return true;
90+
}
91+
}
92+
}
93+
94+
return false;
95+
}
96+
6697
static int i10nm_get_all_munits(void)
6798
{
6899
struct pci_dev *mdev;
@@ -132,13 +163,17 @@ static struct res_config i10nm_cfg0 = {
132163
.decs_did = 0x3452,
133164
.busno_cfg_offset = 0xcc,
134165
.ddr_chan_mmio_sz = 0x4000,
166+
.sad_all_devfn = PCI_DEVFN(29, 0),
167+
.sad_all_offset = 0x108,
135168
};
136169

137170
static struct res_config i10nm_cfg1 = {
138171
.type = I10NM,
139172
.decs_did = 0x3452,
140173
.busno_cfg_offset = 0xd0,
141174
.ddr_chan_mmio_sz = 0x4000,
175+
.sad_all_devfn = PCI_DEVFN(29, 0),
176+
.sad_all_offset = 0x108,
142177
};
143178

144179
static struct res_config spr_cfg = {
@@ -147,6 +182,8 @@ static struct res_config spr_cfg = {
147182
.busno_cfg_offset = 0xd0,
148183
.ddr_chan_mmio_sz = 0x8000,
149184
.support_ddr5 = true,
185+
.sad_all_devfn = PCI_DEVFN(10, 0),
186+
.sad_all_offset = 0x300,
150187
};
151188

152189
static const struct x86_cpu_id i10nm_cpuids[] = {
@@ -296,6 +333,8 @@ static int __init i10nm_init(void)
296333
return -ENODEV;
297334
}
298335

336+
skx_set_mem_cfg(i10nm_check_2lm(cfg));
337+
299338
rc = i10nm_get_all_munits();
300339
if (rc < 0)
301340
goto fail;

drivers/edac/skx_common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ struct res_config {
133133
/* Per DDR channel memory-mapped I/O size */
134134
int ddr_chan_mmio_sz;
135135
bool support_ddr5;
136+
/* SAD device number and function number */
137+
unsigned int sad_all_devfn;
138+
int sad_all_offset;
136139
};
137140

138141
typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci,

0 commit comments

Comments
 (0)