Skip to content

Commit c59f9c0

Browse files
jimsnow-intelsuryasaimadhu
authored andcommitted
EDAC, sb_edac: Virtualize several hard-coded functions
SAD limit, interleave mode and DRAM related functionalities are now virtualized, so that overriding them is easier. Signed-off-by: Jim Snow <[email protected]> Acked-by: Tony Luck <[email protected]> Cc: Mauro Carvalho Chehab <[email protected]> Cc: linux-edac <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] [ Rebase to 4.4-rc3. ] Signed-off-by: Hubert Chrzaniuk <[email protected]> Signed-off-by: Borislav Petkov <[email protected]>
1 parent 768ce42 commit c59f9c0

File tree

1 file changed

+48
-11
lines changed

1 file changed

+48
-11
lines changed

drivers/edac/sb_edac.c

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,12 @@ static const u32 ibridge_dram_rule[] = {
6565
0xd8, 0xe0, 0xe8, 0xf0, 0xf8,
6666
};
6767

68-
#define SAD_LIMIT(reg) ((GET_BITFIELD(reg, 6, 25) << 26) | 0x3ffffff)
69-
#define DRAM_ATTR(reg) GET_BITFIELD(reg, 2, 3)
70-
#define INTERLEAVE_MODE(reg) GET_BITFIELD(reg, 1, 1)
7168
#define DRAM_RULE_ENABLE(reg) GET_BITFIELD(reg, 0, 0)
7269
#define A7MODE(reg) GET_BITFIELD(reg, 26, 26)
7370

74-
static char *get_dram_attr(u32 reg)
71+
static char *show_dram_attr(u32 attr)
7572
{
76-
switch(DRAM_ATTR(reg)) {
73+
switch (attr) {
7774
case 0:
7875
return "DRAM";
7976
case 1:
@@ -273,6 +270,10 @@ struct sbridge_info {
273270
u64 (*get_tolm)(struct sbridge_pvt *pvt);
274271
u64 (*get_tohm)(struct sbridge_pvt *pvt);
275272
u64 (*rir_limit)(u32 reg);
273+
u64 (*sad_limit)(u32 reg);
274+
u32 (*interleave_mode)(u32 reg);
275+
char* (*show_interleave_mode)(u32 reg);
276+
u32 (*dram_attr)(u32 reg);
276277
const u32 *dram_rule;
277278
const u32 *interleave_list;
278279
const struct interleave_pkg *interleave_pkg;
@@ -718,6 +719,26 @@ static u64 rir_limit(u32 reg)
718719
return ((u64)GET_BITFIELD(reg, 1, 10) << 29) | 0x1fffffff;
719720
}
720721

722+
static u64 sad_limit(u32 reg)
723+
{
724+
return (GET_BITFIELD(reg, 6, 25) << 26) | 0x3ffffff;
725+
}
726+
727+
static u32 interleave_mode(u32 reg)
728+
{
729+
return GET_BITFIELD(reg, 1, 1);
730+
}
731+
732+
char *show_interleave_mode(u32 reg)
733+
{
734+
return interleave_mode(reg) ? "8:6" : "[8:6]XOR[18:16]";
735+
}
736+
737+
static u32 dram_attr(u32 reg)
738+
{
739+
return GET_BITFIELD(reg, 2, 3);
740+
}
741+
721742
static enum mem_type get_memory_type(struct sbridge_pvt *pvt)
722743
{
723744
u32 reg;
@@ -1069,7 +1090,7 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
10691090
/* SAD_LIMIT Address range is 45:26 */
10701091
pci_read_config_dword(pvt->pci_sad0, pvt->info.dram_rule[n_sads],
10711092
&reg);
1072-
limit = SAD_LIMIT(reg);
1093+
limit = pvt->info.sad_limit(reg);
10731094

10741095
if (!DRAM_RULE_ENABLE(reg))
10751096
continue;
@@ -1081,10 +1102,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
10811102
gb = div_u64_rem(tmp_mb, 1024, &mb);
10821103
edac_dbg(0, "SAD#%d %s up to %u.%03u GB (0x%016Lx) Interleave: %s reg=0x%08x\n",
10831104
n_sads,
1084-
get_dram_attr(reg),
1105+
show_dram_attr(pvt->info.dram_attr(reg)),
10851106
gb, (mb*1000)/1024,
10861107
((u64)tmp_mb) << 20L,
1087-
INTERLEAVE_MODE(reg) ? "8:6" : "[8:6]XOR[18:16]",
1108+
pvt->info.show_interleave_mode(reg),
10881109
reg);
10891110
prv = limit;
10901111

@@ -1248,7 +1269,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
12481269
if (!DRAM_RULE_ENABLE(reg))
12491270
continue;
12501271

1251-
limit = SAD_LIMIT(reg);
1272+
limit = pvt->info.sad_limit(reg);
12521273
if (limit <= prv) {
12531274
sprintf(msg, "Can't discover the memory socket");
12541275
return -EINVAL;
@@ -1262,8 +1283,8 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
12621283
return -EINVAL;
12631284
}
12641285
dram_rule = reg;
1265-
*area_type = get_dram_attr(dram_rule);
1266-
interleave_mode = INTERLEAVE_MODE(dram_rule);
1286+
*area_type = show_dram_attr(pvt->info.dram_attr(dram_rule));
1287+
interleave_mode = pvt->info.interleave_mode(dram_rule);
12671288

12681289
pci_read_config_dword(pvt->pci_sad0, pvt->info.interleave_list[n_sads],
12691290
&reg);
@@ -2401,6 +2422,10 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
24012422
pvt->info.get_memory_type = get_memory_type;
24022423
pvt->info.get_node_id = get_node_id;
24032424
pvt->info.rir_limit = rir_limit;
2425+
pvt->info.sad_limit = sad_limit;
2426+
pvt->info.interleave_mode = interleave_mode;
2427+
pvt->info.show_interleave_mode = show_interleave_mode;
2428+
pvt->info.dram_attr = dram_attr;
24042429
pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
24052430
pvt->info.interleave_list = ibridge_interleave_list;
24062431
pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
@@ -2421,6 +2446,10 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
24212446
pvt->info.get_memory_type = get_memory_type;
24222447
pvt->info.get_node_id = get_node_id;
24232448
pvt->info.rir_limit = rir_limit;
2449+
pvt->info.sad_limit = sad_limit;
2450+
pvt->info.interleave_mode = interleave_mode;
2451+
pvt->info.show_interleave_mode = show_interleave_mode;
2452+
pvt->info.dram_attr = dram_attr;
24242453
pvt->info.max_sad = ARRAY_SIZE(sbridge_dram_rule);
24252454
pvt->info.interleave_list = sbridge_interleave_list;
24262455
pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list);
@@ -2441,6 +2470,10 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
24412470
pvt->info.get_memory_type = haswell_get_memory_type;
24422471
pvt->info.get_node_id = haswell_get_node_id;
24432472
pvt->info.rir_limit = haswell_rir_limit;
2473+
pvt->info.sad_limit = sad_limit;
2474+
pvt->info.interleave_mode = interleave_mode;
2475+
pvt->info.show_interleave_mode = show_interleave_mode;
2476+
pvt->info.dram_attr = dram_attr;
24442477
pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
24452478
pvt->info.interleave_list = ibridge_interleave_list;
24462479
pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
@@ -2461,6 +2494,10 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
24612494
pvt->info.get_memory_type = haswell_get_memory_type;
24622495
pvt->info.get_node_id = haswell_get_node_id;
24632496
pvt->info.rir_limit = haswell_rir_limit;
2497+
pvt->info.sad_limit = sad_limit;
2498+
pvt->info.interleave_mode = interleave_mode;
2499+
pvt->info.show_interleave_mode = show_interleave_mode;
2500+
pvt->info.dram_attr = dram_attr;
24642501
pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
24652502
pvt->info.interleave_list = ibridge_interleave_list;
24662503
pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);

0 commit comments

Comments
 (0)