[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20220127204115.384161-22-yazen.ghannam@amd.com>
Date: Thu, 27 Jan 2022 20:41:12 +0000
From: Yazen Ghannam <yazen.ghannam@....com>
To: <linux-edac@...r.kernel.org>
CC: <linux-kernel@...r.kernel.org>, <bp@...en8.de>,
<mchehab@...nel.org>, <tony.luck@...el.com>, <james.morse@....com>,
<rric@...nel.org>, <Smita.KoralahalliChannabasappa@....com>,
Yazen Ghannam <yazen.ghannam@....com>
Subject: [PATCH v4 21/24] EDAC/amd64: Update CS ID calculation to match reference code
Redo the current CS ID calculations to match the reference code. Helper
functions are introduced that will be expanded for future DF versions.
Use u16 type for dst_fabric_id and component_id_mask values to
accommodate larger bitfields in future DF versions.
Signed-off-by: Yazen Ghannam <yazen.ghannam@....com>
---
Link:
https://lore.kernel.org/r/20211028175728.121452-27-yazen.ghannam@amd.com
v3->v4:
* Remove leading whitespace in function pointers.
v2->v3:
* Was patch 27 in v2.
v1->v2:
* Moved from arch/x86 to EDAC.
* Added functions to data_fabric_ops.
drivers/edac/amd64_edac.c | 52 ++++++++++++++++++++++++++-------------
1 file changed, 35 insertions(+), 17 deletions(-)
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index ac7919010063..e293aefd486e 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -1092,6 +1092,8 @@ struct addr_ctx {
struct data_fabric_ops {
u64 (*get_hi_addr_offset)(struct addr_ctx *ctx);
+ u16 (*get_dst_fabric_id)(struct addr_ctx *ctx);
+ u16 (*get_component_id_mask)(struct addr_ctx *ctx);
u8 (*get_die_id_shift)(struct addr_ctx *ctx);
u8 (*get_socket_id_shift)(struct addr_ctx *ctx);
int (*get_intlv_mode)(struct addr_ctx *ctx);
@@ -1213,6 +1215,16 @@ static u8 get_socket_id_shift_df2(struct addr_ctx *ctx)
return (ctx->reg_fab_id_mask0 >> 28) & 0xF;
}
+static u16 get_dst_fabric_id_df2(struct addr_ctx *ctx)
+{
+ return ctx->reg_limit_addr & 0xFF;
+}
+
+static u16 get_component_id_mask_df2(struct addr_ctx *ctx)
+{
+ return (~(ctx->socket_id_mask | ctx->die_id_mask)) & 0xFF;
+}
+
struct data_fabric_ops df2_ops = {
.get_hi_addr_offset = get_hi_addr_offset_df2,
.get_intlv_mode = get_intlv_mode_df2,
@@ -1222,6 +1234,8 @@ struct data_fabric_ops df2_ops = {
.get_masks = get_masks_df2,
.get_die_id_shift = get_die_id_shift_df2,
.get_socket_id_shift = get_socket_id_shift_df2,
+ .get_dst_fabric_id = get_dst_fabric_id_df2,
+ .get_component_id_mask = get_component_id_mask_df2,
};
struct data_fabric_ops *df_ops;
@@ -1310,38 +1324,42 @@ static void get_intlv_num_chan(struct addr_ctx *ctx)
}
}
-static int calculate_cs_id(struct addr_ctx *ctx)
+static u8 calc_level_bits(u8 id, u8 level_mask, u8 shift, u8 mask, u8 num_bits)
{
- u8 die_id_bit = 0, sock_id_bit, cs_mask = 0;
+ return (((id & level_mask) >> shift) & mask) << num_bits;
+}
- /* If interleaved over more than 1 channel: */
- if (ctx->intlv_num_chan) {
- die_id_bit = ctx->intlv_num_chan;
- cs_mask = (1 << die_id_bit) - 1;
- ctx->cs_id = ctx->cs_fabric_id & cs_mask;
- }
+static int calculate_cs_id(struct addr_ctx *ctx)
+{
+ u16 dst_fabric_id = df_ops->get_dst_fabric_id(ctx);
+ u16 mask, num_intlv_bits = ctx->intlv_num_chan;
- /* Return early if no die interleaving and no socket interleaving. */
- if (!(ctx->intlv_num_dies || ctx->intlv_num_sockets))
- return 0;
+ mask = df_ops->get_component_id_mask(ctx);
+ ctx->cs_id = (ctx->cs_fabric_id & mask) - (dst_fabric_id & mask);
- sock_id_bit = die_id_bit;
+ mask = (1 << num_intlv_bits) - 1;
+ ctx->cs_id &= mask;
/* If interleaved over more than 1 die: */
if (ctx->intlv_num_dies) {
u8 die_id_shift = df_ops->get_die_id_shift(ctx);
- sock_id_bit = die_id_bit + ctx->intlv_num_dies;
- ctx->cs_id |= ((ctx->cs_fabric_id & ctx->die_id_mask)
- >> die_id_shift) << die_id_bit;
+ mask = (1 << ctx->intlv_num_dies) - 1;
+
+ ctx->cs_id |= calc_level_bits(ctx->cs_fabric_id, ctx->die_id_mask,
+ die_id_shift, mask, num_intlv_bits);
+
+ num_intlv_bits += ctx->intlv_num_dies;
}
/* If interleaved over more than 1 socket: */
if (ctx->intlv_num_sockets) {
u8 socket_id_shift = df_ops->get_socket_id_shift(ctx);
- ctx->cs_id |= ((ctx->cs_fabric_id & ctx->socket_id_mask)
- >> socket_id_shift) << sock_id_bit;
+ mask = (1 << ctx->intlv_num_sockets) - 1;
+
+ ctx->cs_id |= calc_level_bits(ctx->cs_fabric_id, ctx->socket_id_mask,
+ socket_id_shift, mask, num_intlv_bits);
}
return 0;
--
2.25.1
Powered by blists - more mailing lists