EDAC, {skx,i10nm}: Make some configurations CPU model specific
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: Qiuxu Zhuo <qiuxu.zhuo@intel.com> Signed-off-by: Tony Luck <tony.luck@intel.com> Reviewed-by: Borislav Petkov <bp@suse.de> Link: https://lore.kernel.org/r/20200427083246.GB11036@zn.tnic
This commit is contained in:
parent
8f3d9f3542
commit
ee5340abab
|
@ -122,10 +122,16 @@ static int i10nm_get_all_munits(void)
|
|||
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[] = {
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, NULL),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, NULL),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, NULL),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &i10nm_cfg),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &i10nm_cfg),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &i10nm_cfg),
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, i10nm_cpuids);
|
||||
|
@ -234,6 +240,7 @@ static int __init i10nm_init(void)
|
|||
{
|
||||
u8 mc = 0, src_id = 0, node_id = 0;
|
||||
const struct x86_cpu_id *id;
|
||||
struct res_config *cfg;
|
||||
const char *owner;
|
||||
struct skx_dev *d;
|
||||
int rc, i, off[3] = {0xd0, 0xc8, 0xcc};
|
||||
|
@ -249,11 +256,13 @@ static int __init i10nm_init(void)
|
|||
if (!id)
|
||||
return -ENODEV;
|
||||
|
||||
cfg = (struct res_config *)id->driver_data;
|
||||
|
||||
rc = skx_get_hi_lo(0x09a2, off, &tolm, &tohm);
|
||||
if (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)
|
||||
goto fail;
|
||||
if (rc == 0) {
|
||||
|
|
|
@ -157,8 +157,14 @@ fail:
|
|||
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[] = {
|
||||
X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, NULL),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &skx_cfg),
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, skx_cpuids);
|
||||
|
@ -641,6 +647,7 @@ static inline void teardown_skx_debug(void) {}
|
|||
static int __init skx_init(void)
|
||||
{
|
||||
const struct x86_cpu_id *id;
|
||||
struct res_config *cfg;
|
||||
const struct munit *m;
|
||||
const char *owner;
|
||||
int rc = 0, i, off[3] = {0xd0, 0xd4, 0xd8};
|
||||
|
@ -657,11 +664,13 @@ static int __init skx_init(void)
|
|||
if (!id)
|
||||
return -ENODEV;
|
||||
|
||||
cfg = (struct res_config *)id->driver_data;
|
||||
|
||||
rc = skx_get_hi_lo(0x2034, off, &skx_tolm, &skx_tohm);
|
||||
if (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)
|
||||
goto fail;
|
||||
if (rc == 0) {
|
||||
|
|
|
@ -197,12 +197,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 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,
|
||||
struct list_head **list)
|
||||
int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list)
|
||||
{
|
||||
struct pci_dev *pdev, *prev;
|
||||
struct skx_dev *d;
|
||||
|
@ -211,7 +210,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type,
|
|||
|
||||
prev = NULL;
|
||||
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)
|
||||
break;
|
||||
ndev++;
|
||||
|
@ -221,7 +220,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (pci_read_config_dword(pdev, off, ®)) {
|
||||
if (pci_read_config_dword(pdev, cfg->busno_cfg_offset, ®)) {
|
||||
kfree(d);
|
||||
pci_dev_put(pdev);
|
||||
skx_printk(KERN_ERR, "Failed to read bus idx\n");
|
||||
|
@ -230,7 +229,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[1] = GET_BITFIELD(reg, 8, 15);
|
||||
if (type == SKX) {
|
||||
if (cfg->type == SKX) {
|
||||
d->seg = pci_domain_nr(pdev->bus);
|
||||
d->bus[2] = GET_BITFIELD(reg, 16, 23);
|
||||
d->bus[3] = GET_BITFIELD(reg, 24, 31);
|
||||
|
|
|
@ -112,6 +112,14 @@ struct decoded_addr {
|
|||
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 bool (*skx_decode_f)(struct decoded_addr *res);
|
||||
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);
|
|||
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_all_bus_mappings(unsigned int did, int off, enum type,
|
||||
struct list_head **list);
|
||||
int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list);
|
||||
|
||||
int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm);
|
||||
|
||||
|
|
Loading…
Reference in New Issue