提交 115b8aa5 编写于 作者: Y Youquan Song 提交者: Caspar Zhang

EDAC, {skx,i10nm}: Make some configurations CPU model specific

fix #29307272

commit ee5340abab3babb91c1807cea47de4468b2dfc91 upstream

The device ID for configuration agent PCI device and the offset for
bus number configuration register can be CPU model specific. So add
a new structure res_config to make them configurable and pass res_config
to {skx,i10nm}_init() and skx_get_all_bus_mappings() for use.
Signed-off-by: NQiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: NTony Luck <tony.luck@intel.com>
Reviewed-by: NBorislav Petkov <bp@suse.de>
Link: https://lore.kernel.org/r/20200427083246.GB11036@zn.tnicSigned-off-by: NYouquan Song <youquan.song@intel.com>
Signed-off-by: NWetp Zhang <wetp.zy@linux.alibaba.com>
Reviewed-by: NArtie Ding <artie.ding@linux.alibaba.com>
上级 f030656c
...@@ -122,10 +122,16 @@ static int i10nm_get_all_munits(void) ...@@ -122,10 +122,16 @@ static int i10nm_get_all_munits(void)
return 0; return 0;
} }
static struct res_config i10nm_cfg = {
.type = I10NM,
.decs_did = 0x3452,
.busno_cfg_offset = 0xcc,
};
static const struct x86_cpu_id i10nm_cpuids[] = { static const struct x86_cpu_id i10nm_cpuids[] = {
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_TREMONT_X, 0, 0 }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_TREMONT_X, 0, (kernel_ulong_t)&i10nm_cfg},
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_X, 0, 0 }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_X, 0, (kernel_ulong_t)&i10nm_cfg},
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_XEON_D, 0, 0 }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_XEON_D, 0, (kernel_ulong_t)&i10nm_cfg},
{ } { }
}; };
MODULE_DEVICE_TABLE(x86cpu, i10nm_cpuids); MODULE_DEVICE_TABLE(x86cpu, i10nm_cpuids);
...@@ -235,6 +241,7 @@ static int __init i10nm_init(void) ...@@ -235,6 +241,7 @@ static int __init i10nm_init(void)
{ {
u8 mc = 0, src_id = 0, node_id = 0; u8 mc = 0, src_id = 0, node_id = 0;
const struct x86_cpu_id *id; const struct x86_cpu_id *id;
struct res_config *cfg;
const char *owner; const char *owner;
struct skx_dev *d; struct skx_dev *d;
int rc, i, off[3] = {0xd0, 0xc8, 0xcc}; int rc, i, off[3] = {0xd0, 0xc8, 0xcc};
...@@ -250,11 +257,13 @@ static int __init i10nm_init(void) ...@@ -250,11 +257,13 @@ static int __init i10nm_init(void)
if (!id) if (!id)
return -ENODEV; return -ENODEV;
cfg = (struct res_config *)id->driver_data;
rc = skx_get_hi_lo(0x09a2, off, &tolm, &tohm); rc = skx_get_hi_lo(0x09a2, off, &tolm, &tohm);
if (rc) if (rc)
return rc; return rc;
rc = skx_get_all_bus_mappings(0x3452, 0xcc, I10NM, &i10nm_edac_list); rc = skx_get_all_bus_mappings(cfg, &i10nm_edac_list);
if (rc < 0) if (rc < 0)
goto fail; goto fail;
if (rc == 0) { if (rc == 0) {
......
...@@ -157,8 +157,14 @@ static int get_all_munits(const struct munit *m) ...@@ -157,8 +157,14 @@ static int get_all_munits(const struct munit *m)
return -ENODEV; return -ENODEV;
} }
static struct res_config skx_cfg = {
.type = SKX,
.decs_did = 0x2016,
.busno_cfg_offset = 0xcc,
};
static const struct x86_cpu_id skx_cpuids[] = { static const struct x86_cpu_id skx_cpuids[] = {
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_X, 0, 0 }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_X, 0, (kernel_ulong_t)&skx_cfg},
{ } { }
}; };
MODULE_DEVICE_TABLE(x86cpu, skx_cpuids); MODULE_DEVICE_TABLE(x86cpu, skx_cpuids);
...@@ -642,6 +648,7 @@ static inline void teardown_skx_debug(void) {} ...@@ -642,6 +648,7 @@ static inline void teardown_skx_debug(void) {}
static int __init skx_init(void) static int __init skx_init(void)
{ {
const struct x86_cpu_id *id; const struct x86_cpu_id *id;
struct res_config *cfg;
const struct munit *m; const struct munit *m;
const char *owner; const char *owner;
int rc = 0, i, off[3] = {0xd0, 0xd4, 0xd8}; int rc = 0, i, off[3] = {0xd0, 0xd4, 0xd8};
...@@ -658,11 +665,13 @@ static int __init skx_init(void) ...@@ -658,11 +665,13 @@ static int __init skx_init(void)
if (!id) if (!id)
return -ENODEV; return -ENODEV;
cfg = (struct res_config *)id->driver_data;
rc = skx_get_hi_lo(0x2034, off, &skx_tolm, &skx_tohm); rc = skx_get_hi_lo(0x2034, off, &skx_tolm, &skx_tohm);
if (rc) if (rc)
return rc; return rc;
rc = skx_get_all_bus_mappings(0x2016, 0xcc, SKX, &skx_edac_list); rc = skx_get_all_bus_mappings(cfg, &skx_edac_list);
if (rc < 0) if (rc < 0)
goto fail; goto fail;
if (rc == 0) { if (rc == 0) {
......
...@@ -178,12 +178,11 @@ static int get_width(u32 mtr) ...@@ -178,12 +178,11 @@ static int get_width(u32 mtr)
} }
/* /*
* We use the per-socket device @did to count how many sockets are present, * We use the per-socket device @cfg->did to count how many sockets are present,
* and to detemine which PCI buses are associated with each socket. Allocate * and to detemine which PCI buses are associated with each socket. Allocate
* and build the full list of all the skx_dev structures that we need here. * and build the full list of all the skx_dev structures that we need here.
*/ */
int skx_get_all_bus_mappings(unsigned int did, int off, enum type type, int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list)
struct list_head **list)
{ {
struct pci_dev *pdev, *prev; struct pci_dev *pdev, *prev;
struct skx_dev *d; struct skx_dev *d;
...@@ -192,7 +191,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type, ...@@ -192,7 +191,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type,
prev = NULL; prev = NULL;
for (;;) { for (;;) {
pdev = pci_get_device(PCI_VENDOR_ID_INTEL, did, prev); pdev = pci_get_device(PCI_VENDOR_ID_INTEL, cfg->decs_did, prev);
if (!pdev) if (!pdev)
break; break;
ndev++; ndev++;
...@@ -202,7 +201,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type, ...@@ -202,7 +201,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type,
return -ENOMEM; return -ENOMEM;
} }
if (pci_read_config_dword(pdev, off, &reg)) { if (pci_read_config_dword(pdev, cfg->busno_cfg_offset, &reg)) {
kfree(d); kfree(d);
pci_dev_put(pdev); pci_dev_put(pdev);
skx_printk(KERN_ERR, "Failed to read bus idx\n"); skx_printk(KERN_ERR, "Failed to read bus idx\n");
...@@ -211,7 +210,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type, ...@@ -211,7 +210,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type,
d->bus[0] = GET_BITFIELD(reg, 0, 7); d->bus[0] = GET_BITFIELD(reg, 0, 7);
d->bus[1] = GET_BITFIELD(reg, 8, 15); d->bus[1] = GET_BITFIELD(reg, 8, 15);
if (type == SKX) { if (cfg->type == SKX) {
d->seg = pci_domain_nr(pdev->bus); d->seg = pci_domain_nr(pdev->bus);
d->bus[2] = GET_BITFIELD(reg, 16, 23); d->bus[2] = GET_BITFIELD(reg, 16, 23);
d->bus[3] = GET_BITFIELD(reg, 24, 31); d->bus[3] = GET_BITFIELD(reg, 24, 31);
......
...@@ -112,6 +112,14 @@ struct decoded_addr { ...@@ -112,6 +112,14 @@ struct decoded_addr {
int bank_group; int bank_group;
}; };
struct res_config {
enum type type;
/* Configuration agent device ID */
unsigned int decs_did;
/* Default bus number configuration register offset */
int busno_cfg_offset;
};
typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci); typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci);
typedef bool (*skx_decode_f)(struct decoded_addr *res); typedef bool (*skx_decode_f)(struct decoded_addr *res);
typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len); typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len);
...@@ -123,8 +131,7 @@ void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log); ...@@ -123,8 +131,7 @@ void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log);
int skx_get_src_id(struct skx_dev *d, int off, u8 *id); int skx_get_src_id(struct skx_dev *d, int off, u8 *id);
int skx_get_node_id(struct skx_dev *d, u8 *id); int skx_get_node_id(struct skx_dev *d, u8 *id);
int skx_get_all_bus_mappings(unsigned int did, int off, enum type, int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list);
struct list_head **list);
int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm); int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册