提交 6b81ee37 编写于 作者: Q Qiuxu Zhuo 提交者: Youquan Song

EDAC/i10nm: Add detection of memory levels for ICX/SPR servers

mainline inclusion
from mainline-v5.14-rc1
commit 4bd4d32e
category: feature
bugzilla: https://gitee.com/openeuler/intel-kernel/issues/I5HAC1
CVE: NA

Intel-SIG: commit 4bd4d32e EDAC/i10nm: Add detection of memory levels for ICX/SPR
 servers.
Backport to add EDAC 2LM support.

--------------------------------

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: NQiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: NTony Luck <tony.luck@intel.com>
Link: https://lore.kernel.org/r/20210611170123.1057025-3-tony.luck@intel.comSigned-off-by: NYouquan Song <youquan.song@intel.com>
上级 f82dbd0e
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
pci_read_config_dword((d)->uracu, 0xd0, &(reg)) pci_read_config_dword((d)->uracu, 0xd0, &(reg))
#define I10NM_GET_IMC_BAR(d, i, reg) \ #define I10NM_GET_IMC_BAR(d, i, reg) \
pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg)) pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg))
#define I10NM_GET_SAD(d, offset, i, reg)\
pci_read_config_dword((d)->sad_all, (offset) + (i) * 8, &(reg))
#define I10NM_GET_DIMMMTR(m, i, j) \ #define I10NM_GET_DIMMMTR(m, i, j) \
readl((m)->mbase + 0x2080c + (i) * (m)->chan_mmio_sz + (j) * 4) readl((m)->mbase + 0x2080c + (i) * (m)->chan_mmio_sz + (j) * 4)
#define I10NM_GET_MCDDRTCFG(m, i) \ #define I10NM_GET_MCDDRTCFG(m, i) \
...@@ -50,6 +52,10 @@ ...@@ -50,6 +52,10 @@
#define RETRY_RD_ERR_LOG_NOOVER_UC (BIT(14) | BIT(1)) #define RETRY_RD_ERR_LOG_NOOVER_UC (BIT(14) | BIT(1))
#define RETRY_RD_ERR_LOG_OVER_UC_V (BIT(2) | BIT(1) | BIT(0)) #define RETRY_RD_ERR_LOG_OVER_UC_V (BIT(2) | BIT(1) | BIT(0))
#define I10NM_MAX_SAD 16
#define I10NM_SAD_ENABLE(reg) GET_BITFIELD(reg, 0, 0)
#define I10NM_SAD_NM_CACHEABLE(reg) GET_BITFIELD(reg, 5, 5)
static struct list_head *i10nm_edac_list; static struct list_head *i10nm_edac_list;
static struct res_config *res_cfg; static struct res_config *res_cfg;
...@@ -186,6 +192,31 @@ static struct pci_dev *pci_get_dev_wrapper(int dom, unsigned int bus, ...@@ -186,6 +192,31 @@ static struct pci_dev *pci_get_dev_wrapper(int dom, unsigned int bus,
return pdev; return pdev;
} }
static bool i10nm_check_2lm(struct res_config *cfg)
{
struct skx_dev *d;
u32 reg;
int i;
list_for_each_entry(d, i10nm_edac_list, list) {
d->sad_all = pci_get_dev_wrapper(d->seg, d->bus[1],
PCI_SLOT(cfg->sad_all_devfn),
PCI_FUNC(cfg->sad_all_devfn));
if (!d->sad_all)
continue;
for (i = 0; i < I10NM_MAX_SAD; i++) {
I10NM_GET_SAD(d, cfg->sad_all_offset, i, reg);
if (I10NM_SAD_ENABLE(reg) && I10NM_SAD_NM_CACHEABLE(reg)) {
edac_dbg(2, "2-level memory configuration.\n");
return true;
}
}
}
return false;
}
static int i10nm_get_all_munits(void) static int i10nm_get_all_munits(void)
{ {
struct pci_dev *mdev; struct pci_dev *mdev;
...@@ -255,6 +286,8 @@ static struct res_config i10nm_cfg0 = { ...@@ -255,6 +286,8 @@ static struct res_config i10nm_cfg0 = {
.decs_did = 0x3452, .decs_did = 0x3452,
.busno_cfg_offset = 0xcc, .busno_cfg_offset = 0xcc,
.ddr_chan_mmio_sz = 0x4000, .ddr_chan_mmio_sz = 0x4000,
.sad_all_devfn = PCI_DEVFN(29, 0),
.sad_all_offset = 0x108,
.offsets_scrub = offsets_scrub_icx, .offsets_scrub = offsets_scrub_icx,
.offsets_demand = offsets_demand_icx, .offsets_demand = offsets_demand_icx,
}; };
...@@ -264,6 +297,8 @@ static struct res_config i10nm_cfg1 = { ...@@ -264,6 +297,8 @@ static struct res_config i10nm_cfg1 = {
.decs_did = 0x3452, .decs_did = 0x3452,
.busno_cfg_offset = 0xd0, .busno_cfg_offset = 0xd0,
.ddr_chan_mmio_sz = 0x4000, .ddr_chan_mmio_sz = 0x4000,
.sad_all_devfn = PCI_DEVFN(29, 0),
.sad_all_offset = 0x108,
.offsets_scrub = offsets_scrub_icx, .offsets_scrub = offsets_scrub_icx,
.offsets_demand = offsets_demand_icx, .offsets_demand = offsets_demand_icx,
}; };
...@@ -274,6 +309,8 @@ static struct res_config spr_cfg = { ...@@ -274,6 +309,8 @@ static struct res_config spr_cfg = {
.busno_cfg_offset = 0xd0, .busno_cfg_offset = 0xd0,
.ddr_chan_mmio_sz = 0x8000, .ddr_chan_mmio_sz = 0x8000,
.support_ddr5 = true, .support_ddr5 = true,
.sad_all_devfn = PCI_DEVFN(10, 0),
.sad_all_offset = 0x300,
.offsets_scrub = offsets_scrub_spr, .offsets_scrub = offsets_scrub_spr,
.offsets_demand = offsets_demand_spr, .offsets_demand = offsets_demand_spr,
}; };
...@@ -429,6 +466,8 @@ static int __init i10nm_init(void) ...@@ -429,6 +466,8 @@ static int __init i10nm_init(void)
return -ENODEV; return -ENODEV;
} }
skx_set_mem_cfg(i10nm_check_2lm(cfg));
rc = i10nm_get_all_munits(); rc = i10nm_get_all_munits();
if (rc < 0) if (rc < 0)
goto fail; goto fail;
......
...@@ -135,6 +135,9 @@ struct res_config { ...@@ -135,6 +135,9 @@ struct res_config {
/* Per DDR channel memory-mapped I/O size */ /* Per DDR channel memory-mapped I/O size */
int ddr_chan_mmio_sz; int ddr_chan_mmio_sz;
bool support_ddr5; bool support_ddr5;
/* SAD device number and function number */
unsigned int sad_all_devfn;
int sad_all_offset;
/* Offsets of retry_rd_err_log registers */ /* Offsets of retry_rd_err_log registers */
u32 *offsets_scrub; u32 *offsets_scrub;
u32 *offsets_demand; u32 *offsets_demand;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册