@@ -710,11 +710,14 @@ enum df_types {
DF2,
};
+/* Use "reg_" prefix for raw register values. */
struct addr_ctx {
enum df_types df_type;
u64 ret_addr;
+ u32 reg_dram_offset;
u16 nid;
u8 umc;
+ u8 map_num;
};
static enum df_types get_df_type(struct addr_ctx *ctx)
@@ -722,6 +725,39 @@ static enum df_types get_df_type(struct addr_ctx *ctx)
return DF2;
}
+static int get_dram_offset_reg(struct addr_ctx *ctx)
+{
+ if (amd_df_indirect_read(ctx->nid, df_regs[DRAM_OFFSET], ctx->umc, &ctx->reg_dram_offset))
+ return -EINVAL;
+
+ return 0;
+}
+
+static u64 get_hi_addr_offset(struct addr_ctx *ctx)
+{
+ return (ctx->reg_dram_offset & GENMASK_ULL(31, 20)) << 8;
+}
+
+static int remove_dram_offset(struct addr_ctx *ctx)
+{
+ if (get_dram_offset_reg(ctx))
+ return -EINVAL;
+
+ ctx->map_num = 0;
+
+ /* Remove HiAddrOffset from normalized address, if enabled: */
+ if (ctx->reg_dram_offset & BIT(0)) {
+ u64 hi_addr_offset = get_hi_addr_offset(ctx);
+
+ if (ctx->ret_addr >= hi_addr_offset) {
+ ctx->ret_addr -= hi_addr_offset;
+ ctx->map_num = 1;
+ }
+ }
+
+ return 0;
+}
+
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;
@@ -731,7 +767,7 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)
u8 intlv_num_dies, intlv_num_chan, intlv_num_sockets;
u8 intlv_addr_sel, intlv_addr_bit;
u8 num_intlv_bits, hashed_bit;
- u8 lgcy_mmio_hole_en, base = 0;
+ u8 lgcy_mmio_hole_en;
u8 cs_mask, cs_id = 0;
bool hash_enabled = false;
@@ -749,20 +785,10 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)
ctx.df_type = get_df_type(&ctx);
- if (amd_df_indirect_read(nid, df_regs[DRAM_OFFSET], umc, &tmp))
+ if (remove_dram_offset(&ctx))
goto out_err;
- /* Remove HiAddrOffset from normalized address, if enabled: */
- if (tmp & BIT(0)) {
- u64 hi_addr_offset = (tmp & GENMASK_ULL(31, 20)) << 8;
-
- if (norm_addr >= hi_addr_offset) {
- ctx.ret_addr -= hi_addr_offset;
- base = 1;
- }
- }
-
- reg = base ? df_regs[DRAM_BASE_ADDR_1] : df_regs[DRAM_BASE_ADDR_0];
+ reg = ctx.map_num ? df_regs[DRAM_BASE_ADDR_1] : df_regs[DRAM_BASE_ADDR_0];
if (amd_df_indirect_read(nid, reg, umc, &tmp))
goto out_err;
@@ -785,7 +811,7 @@ int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)
goto out_err;
}
- reg = base ? df_regs[DRAM_LIMIT_ADDR_1] : df_regs[DRAM_LIMIT_ADDR_0];
+ reg = ctx.map_num ? df_regs[DRAM_LIMIT_ADDR_1] : df_regs[DRAM_LIMIT_ADDR_0];
if (amd_df_indirect_read(nid, reg, umc, &tmp))
goto out_err;