Messages in this thread Patch in this message | | | From | Yazen Ghannam <> | Subject | [PATCH v2 08/31] EDAC/amd64: Define function to read DRAM address map registers | Date | Wed, 23 Jun 2021 19:19:39 +0000 |
| |
Move the reading of the base and limit registers into a helper function. Save the raw values in the context struct as they will be parsed later.
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com> --- Link: https://lkml.kernel.org/r/20210507190140.18854-5-Yazen.Ghannam@amd.com
v1->v2: * Moved from arch/x86 to EDAC.
drivers/edac/amd64_edac.c | 58 +++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 24 deletions(-)
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 389f0621e885..867ab32caab2 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1083,6 +1083,8 @@ static struct df_reg df_regs[] = { struct addr_ctx { u64 ret_addr; u32 reg_dram_offset; + u32 reg_base_addr; + u32 reg_limit_addr; u16 nid; u8 inst_id; u8 map_num; @@ -1139,6 +1141,30 @@ static int remove_dram_offset(struct addr_ctx *ctx) return 0; } +static int get_dram_addr_map(struct addr_ctx *ctx) +{ + struct df_reg reg = df_regs[DRAM_BASE_ADDR]; + + reg.offset += ctx->map_num * 8; + + if (amd_df_indirect_read(ctx->nid, reg, ctx->inst_id, &ctx->reg_base_addr)) + return -EINVAL; + + /* Check if address range is valid. */ + if (!(ctx->reg_base_addr & BIT(0))) { + pr_debug("Invalid DramBaseAddress range: 0x%x.\n", ctx->reg_base_addr); + return -EINVAL; + } + + reg = df_regs[DRAM_LIMIT_ADDR]; + reg.offset += ctx->map_num * 8; + + if (amd_df_indirect_read(ctx->nid, reg, ctx->inst_id, &ctx->reg_limit_addr)) + return -EINVAL; + + return 0; +} + static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) { u64 dram_base_addr, dram_limit_addr, dram_hole_base; @@ -1152,8 +1178,6 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr u8 cs_mask, cs_id = 0; bool hash_enabled = false; - struct df_reg reg; - struct addr_ctx ctx; memset(&ctx, 0, sizeof(ctx)); @@ -1170,22 +1194,13 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr if (remove_dram_offset(&ctx)) goto out_err; - reg = df_regs[DRAM_BASE_ADDR]; - reg.offset += ctx.map_num * 8; - if (amd_df_indirect_read(nid, reg, umc, &tmp)) - goto out_err; - - /* Check if address range is valid. */ - if (!(tmp & BIT(0))) { - pr_err("%s: Invalid DramBaseAddress range: 0x%x.\n", - __func__, tmp); + if (get_dram_addr_map(&ctx)) goto out_err; - } - lgcy_mmio_hole_en = tmp & BIT(1); - intlv_num_chan = (tmp >> 4) & 0xF; - intlv_addr_sel = (tmp >> 8) & 0x7; - dram_base_addr = (tmp & GENMASK_ULL(31, 12)) << 16; + lgcy_mmio_hole_en = ctx.reg_base_addr & BIT(1); + intlv_num_chan = (ctx.reg_base_addr >> 4) & 0xF; + intlv_addr_sel = (ctx.reg_base_addr >> 8) & 0x7; + dram_base_addr = (ctx.reg_base_addr & GENMASK_ULL(31, 12)) << 16; /* {0, 1, 2, 3} map to address bits {8, 9, 10, 11} respectively */ if (intlv_addr_sel > 3) { @@ -1194,14 +1209,9 @@ static int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr goto out_err; } - reg = df_regs[DRAM_LIMIT_ADDR]; - reg.offset += ctx.map_num * 8; - if (amd_df_indirect_read(nid, reg, umc, &tmp)) - goto out_err; - - intlv_num_sockets = (tmp >> 8) & 0x1; - intlv_num_dies = (tmp >> 10) & 0x3; - dram_limit_addr = ((tmp & GENMASK_ULL(31, 12)) << 16) | GENMASK_ULL(27, 0); + intlv_num_sockets = (ctx.reg_limit_addr >> 8) & 0x1; + intlv_num_dies = (ctx.reg_limit_addr >> 10) & 0x3; + dram_limit_addr = ((ctx.reg_limit_addr & GENMASK_ULL(31, 12)) << 16) | GENMASK_ULL(27, 0); intlv_addr_bit = intlv_addr_sel + 8; -- 2.25.1
| |