target/riscv: Add additional xlen for address when MPRV=1
As specified in privilege spec:"When MPRV=1, load and store memory addresses are treated as though the current XLEN were set to MPP’s XLEN". So the xlen for address may be different from current xlen. Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Message-Id: <20230614032547.35895-2-liweiwei@iscas.ac.cn> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
029f5feed6
commit
3a610f5430
|
@ -500,6 +500,7 @@ FIELD(TB_FLAGS, ITRIGGER, 22, 1)
|
||||||
/* Virtual mode enabled */
|
/* Virtual mode enabled */
|
||||||
FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
|
FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
|
||||||
FIELD(TB_FLAGS, PRIV, 24, 2)
|
FIELD(TB_FLAGS, PRIV, 24, 2)
|
||||||
|
FIELD(TB_FLAGS, AXL, 26, 2)
|
||||||
|
|
||||||
#ifdef TARGET_RISCV32
|
#ifdef TARGET_RISCV32
|
||||||
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
|
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
|
||||||
|
@ -516,13 +517,20 @@ static inline const RISCVCPUConfig *riscv_cpu_cfg(CPURISCVState *env)
|
||||||
return &env_archcpu(env)->cfg;
|
return &env_archcpu(env)->cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TARGET_RISCV32)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
#define cpu_recompute_xl(env) ((void)(env), MXL_RV32)
|
static inline int cpu_address_mode(CPURISCVState *env)
|
||||||
#else
|
{
|
||||||
static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
|
int mode = env->priv;
|
||||||
|
|
||||||
|
if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
|
||||||
|
mode = get_field(env->mstatus, MSTATUS_MPP);
|
||||||
|
}
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline RISCVMXL cpu_get_xl(CPURISCVState *env, target_ulong mode)
|
||||||
{
|
{
|
||||||
RISCVMXL xl = env->misa_mxl;
|
RISCVMXL xl = env->misa_mxl;
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
|
||||||
/*
|
/*
|
||||||
* When emulating a 32-bit-only cpu, use RV32.
|
* When emulating a 32-bit-only cpu, use RV32.
|
||||||
* When emulating a 64-bit cpu, and MXL has been reduced to RV32,
|
* When emulating a 64-bit cpu, and MXL has been reduced to RV32,
|
||||||
|
@ -530,7 +538,7 @@ static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
|
||||||
* back to RV64 for lower privs.
|
* back to RV64 for lower privs.
|
||||||
*/
|
*/
|
||||||
if (xl != MXL_RV32) {
|
if (xl != MXL_RV32) {
|
||||||
switch (env->priv) {
|
switch (mode) {
|
||||||
case PRV_M:
|
case PRV_M:
|
||||||
break;
|
break;
|
||||||
case PRV_U:
|
case PRV_U:
|
||||||
|
@ -541,11 +549,38 @@ static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return xl;
|
return xl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(TARGET_RISCV32)
|
||||||
|
#define cpu_recompute_xl(env) ((void)(env), MXL_RV32)
|
||||||
|
#else
|
||||||
|
static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
|
||||||
|
{
|
||||||
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
return cpu_get_xl(env, env->priv);
|
||||||
|
#else
|
||||||
|
return env->misa_mxl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(TARGET_RISCV32)
|
||||||
|
#define cpu_address_xl(env) ((void)(env), MXL_RV32)
|
||||||
|
#else
|
||||||
|
static inline RISCVMXL cpu_address_xl(CPURISCVState *env)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
return env->xl;
|
||||||
|
#else
|
||||||
|
int mode = cpu_address_mode(env);
|
||||||
|
|
||||||
|
return cpu_get_xl(env, mode);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline int riscv_cpu_xlen(CPURISCVState *env)
|
static inline int riscv_cpu_xlen(CPURISCVState *env)
|
||||||
{
|
{
|
||||||
return 16 << env->xl;
|
return 16 << env->xl;
|
||||||
|
|
|
@ -135,6 +135,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
|
||||||
flags = FIELD_DP32(flags, TB_FLAGS, FS, fs);
|
flags = FIELD_DP32(flags, TB_FLAGS, FS, fs);
|
||||||
flags = FIELD_DP32(flags, TB_FLAGS, VS, vs);
|
flags = FIELD_DP32(flags, TB_FLAGS, VS, vs);
|
||||||
flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
|
flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
|
||||||
|
flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env));
|
||||||
if (env->cur_pmmask != 0) {
|
if (env->cur_pmmask != 0) {
|
||||||
flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
|
flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ typedef struct DisasContext {
|
||||||
target_ulong priv_ver;
|
target_ulong priv_ver;
|
||||||
RISCVMXL misa_mxl_max;
|
RISCVMXL misa_mxl_max;
|
||||||
RISCVMXL xl;
|
RISCVMXL xl;
|
||||||
|
RISCVMXL address_xl;
|
||||||
uint32_t misa_ext;
|
uint32_t misa_ext;
|
||||||
uint32_t opcode;
|
uint32_t opcode;
|
||||||
RISCVExtStatus mstatus_fs;
|
RISCVExtStatus mstatus_fs;
|
||||||
|
@ -129,6 +130,14 @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext)
|
||||||
#define get_xl(ctx) ((ctx)->xl)
|
#define get_xl(ctx) ((ctx)->xl)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TARGET_RISCV32
|
||||||
|
#define get_address_xl(ctx) MXL_RV32
|
||||||
|
#elif defined(CONFIG_USER_ONLY)
|
||||||
|
#define get_address_xl(ctx) MXL_RV64
|
||||||
|
#else
|
||||||
|
#define get_address_xl(ctx) ((ctx)->address_xl)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The word size for this machine mode. */
|
/* The word size for this machine mode. */
|
||||||
static inline int __attribute__((unused)) get_xlen(DisasContext *ctx)
|
static inline int __attribute__((unused)) get_xlen(DisasContext *ctx)
|
||||||
{
|
{
|
||||||
|
@ -575,12 +584,13 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm)
|
||||||
tcg_gen_addi_tl(addr, src1, imm);
|
tcg_gen_addi_tl(addr, src1, imm);
|
||||||
if (ctx->pm_mask_enabled) {
|
if (ctx->pm_mask_enabled) {
|
||||||
tcg_gen_andc_tl(addr, addr, pm_mask);
|
tcg_gen_andc_tl(addr, addr, pm_mask);
|
||||||
} else if (get_xl(ctx) == MXL_RV32) {
|
} else if (get_address_xl(ctx) == MXL_RV32) {
|
||||||
tcg_gen_ext32u_tl(addr, addr);
|
tcg_gen_ext32u_tl(addr, addr);
|
||||||
}
|
}
|
||||||
if (ctx->pm_base_enabled) {
|
if (ctx->pm_base_enabled) {
|
||||||
tcg_gen_or_tl(addr, addr, pm_base);
|
tcg_gen_or_tl(addr, addr, pm_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1177,6 +1187,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
|
||||||
ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
|
ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
|
||||||
ctx->misa_mxl_max = env->misa_mxl_max;
|
ctx->misa_mxl_max = env->misa_mxl_max;
|
||||||
ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
|
ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
|
||||||
|
ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL);
|
||||||
ctx->cs = cs;
|
ctx->cs = cs;
|
||||||
ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
|
ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
|
||||||
ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
|
ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
|
||||||
|
|
Loading…
Reference in New Issue