[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 05/14] target/riscv: Add MXL/SXL/UXL to TB_FLAGS
From: |
Richard Henderson |
Subject: |
[PATCH v3 05/14] target/riscv: Add MXL/SXL/UXL to TB_FLAGS |
Date: |
Sat, 16 Oct 2021 10:14:03 -0700 |
Begin adding support for switching XLEN at runtime. Extract the
effective XLEN from MISA and MSTATUS and store for use during translation.
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/riscv/cpu.h | 2 ++
target/riscv/cpu.c | 8 ++++++++
target/riscv/cpu_helper.c | 33 +++++++++++++++++++++++++++++++++
target/riscv/csr.c | 3 +++
target/riscv/translate.c | 2 +-
5 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d0e82135a9..c24bc9a039 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -395,6 +395,8 @@ FIELD(TB_FLAGS, VILL, 8, 1)
/* Is a Hypervisor instruction load/store allowed? */
FIELD(TB_FLAGS, HLSX, 9, 1)
FIELD(TB_FLAGS, MSTATUS_HS_FS, 10, 2)
+/* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
+FIELD(TB_FLAGS, XL, 12, 2)
#ifdef TARGET_RISCV32
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1857670a69..4e1920d5f0 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -355,6 +355,14 @@ static void riscv_cpu_reset(DeviceState *dev)
env->misa_mxl = env->misa_mxl_max;
env->priv = PRV_M;
env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
+ if (env->misa_mxl > MXL_RV32) {
+ /*
+ * The reset status of SXL/UXL is undefined, but mstatus is WARL
+ * and we must ensure that the value after init is valid for read.
+ */
+ env->mstatus = set_field(env->mstatus, MSTATUS64_SXL, env->misa_mxl);
+ env->mstatus = set_field(env->mstatus, MSTATUS64_UXL, env->misa_mxl);
+ }
env->mcause = 0;
env->pc = env->resetvec;
env->two_stage_lookup = false;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 403f54171d..429afd1f48 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -35,6 +35,37 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
#endif
}
+static RISCVMXL cpu_get_xl(CPURISCVState *env)
+{
+#if defined(TARGET_RISCV32)
+ return MXL_RV32;
+#elif defined(CONFIG_USER_ONLY)
+ return MXL_RV64;
+#else
+ RISCVMXL xl = riscv_cpu_mxl(env);
+
+ /*
+ * When emulating a 32-bit-only cpu, use RV32.
+ * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
+ * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
+ * back to RV64 for lower privs.
+ */
+ if (xl != MXL_RV32) {
+ switch (env->priv) {
+ case PRV_M:
+ break;
+ case PRV_U:
+ xl = get_field(env->mstatus, MSTATUS64_UXL);
+ break;
+ default: /* PRV_S | PRV_H */
+ xl = get_field(env->mstatus, MSTATUS64_SXL);
+ break;
+ }
+ }
+ return xl;
+#endif
+}
+
void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
target_ulong *cs_base, uint32_t *pflags)
{
@@ -78,6 +109,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong
*pc,
}
#endif
+ flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
+
*pflags = flags;
}
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 9c0753bc8b..c4a479ddd2 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -526,6 +526,9 @@ static RISCVException write_mstatus(CPURISCVState *env, int
csrno,
mstatus = set_field(mstatus, MSTATUS32_SD, dirty);
} else {
mstatus = set_field(mstatus, MSTATUS64_SD, dirty);
+ /* SXL and UXL fields are for now read only */
+ mstatus = set_field(mstatus, MSTATUS64_SXL, MXL_RV64);
+ mstatus = set_field(mstatus, MSTATUS64_UXL, MXL_RV64);
}
env->mstatus = mstatus;
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 422f8ab8d0..7e7bb67d15 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -539,7 +539,6 @@ static void riscv_tr_init_disas_context(DisasContextBase
*dcbase, CPUState *cs)
#else
ctx->virt_enabled = false;
#endif
- ctx->xl = env->misa_mxl;
ctx->misa_ext = env->misa_ext;
ctx->frm = -1; /* unknown rounding mode */
ctx->ext_ifencei = cpu->cfg.ext_ifencei;
@@ -551,6 +550,7 @@ static void riscv_tr_init_disas_context(DisasContextBase
*dcbase, CPUState *cs)
ctx->lmul = FIELD_EX32(tb_flags, TB_FLAGS, LMUL);
ctx->mlen = 1 << (ctx->sew + 3 - ctx->lmul);
ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
+ ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
ctx->cs = cs;
ctx->w = false;
ctx->ntemp = 0;
--
2.25.1
- [PATCH v3 00/14] target/riscv: Rationalize XLEN and operand length, Richard Henderson, 2021/10/16
- [PATCH v3 02/14] target/riscv: Create RISCVMXL enumeration, Richard Henderson, 2021/10/16
- [PATCH v3 01/14] target/riscv: Move cpu_get_tb_cpu_state out of line, Richard Henderson, 2021/10/16
- [PATCH v3 03/14] target/riscv: Split misa.mxl and misa.ext, Richard Henderson, 2021/10/16
- [PATCH v3 07/14] target/riscv: Properly check SEW in amo_op, Richard Henderson, 2021/10/16
- [PATCH v3 04/14] target/riscv: Replace riscv_cpu_is_32bit with riscv_cpu_mxl, Richard Henderson, 2021/10/16
- [PATCH v3 05/14] target/riscv: Add MXL/SXL/UXL to TB_FLAGS,
Richard Henderson <=
- [PATCH v3 08/14] target/riscv: Replace is_32bit with get_xl/get_xlen, Richard Henderson, 2021/10/16
- [PATCH v3 11/14] target/riscv: Adjust trans_rev8_32 for riscv64, Richard Henderson, 2021/10/16
- [PATCH v3 10/14] target/riscv: Use gen_arith_per_ol for RVM, Richard Henderson, 2021/10/16
- [PATCH v3 09/14] target/riscv: Replace DisasContext.w with DisasContext.ol, Richard Henderson, 2021/10/16
- [PATCH v3 06/14] target/riscv: Use REQUIRE_64BIT in amo_check64, Richard Henderson, 2021/10/16
- [PATCH v3 14/14] target/riscv: Compute mstatus.sd on demand, Richard Henderson, 2021/10/16