[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v4 08/20] target/riscv: Create current pm fields in env
From: |
LIU Zhiwei |
Subject: |
[PATCH v4 08/20] target/riscv: Create current pm fields in env |
Date: |
Thu, 11 Nov 2021 23:51:37 +0800 |
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
target/riscv/cpu.c | 1 +
target/riscv/cpu.h | 4 ++++
target/riscv/cpu_helper.c | 43 +++++++++++++++++++++++++++++++++++++++
target/riscv/csr.c | 19 +++++++++++++++++
target/riscv/machine.c | 10 +++++++++
5 files changed, 77 insertions(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0d2d175fa2..4f01abc989 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -393,6 +393,7 @@ static void riscv_cpu_reset(DeviceState *dev)
/* mmte is supposed to have pm.current hardwired to 1 */
env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
#endif
+ riscv_cpu_update_mask(env);
cs->exception_index = RISCV_EXCP_NONE;
env->load_res = -1;
set_default_nan_mode(1, &env->fp_status);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 8befff0166..fa5a6ba1c8 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -250,6 +250,8 @@ struct CPURISCVState {
target_ulong upmmask;
target_ulong upmbase;
#endif
+ target_ulong cur_pmmask;
+ target_ulong cur_pmbase;
float_status fp_status;
@@ -441,6 +443,8 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu,
target_ulong vtype)
void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
target_ulong *cs_base, uint32_t *pflags);
+void riscv_cpu_update_mask(CPURISCVState *env);
+
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
target_ulong *ret_value,
target_ulong new_value, target_ulong write_mask);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 79aba9c880..8320f56d9f 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -133,6 +133,48 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong
*pc,
*pflags = flags;
}
+void riscv_cpu_update_mask(CPURISCVState *env)
+{
+ target_ulong mask = -1, base = 0;
+ /*
+ * TODO: Current RVJ spec does not specify
+ * how the extension interacts with XLEN.
+ */
+#ifndef CONFIG_USER_ONLY
+ if (riscv_has_ext(env, RVJ)) {
+ switch (env->priv) {
+ case PRV_M:
+ if (env->mmte & M_PM_ENABLE) {
+ mask = env->mpmmask;
+ base = env->mpmbase;
+ }
+ break;
+ case PRV_S:
+ if (env->mmte & S_PM_ENABLE) {
+ mask = env->spmmask;
+ base = env->spmbase;
+ }
+ break;
+ case PRV_U:
+ if (env->mmte & U_PM_ENABLE) {
+ mask = env->upmmask;
+ base = env->upmbase;
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ }
+#endif
+ if (cpu_get_xl(env) == MXL_RV32) {
+ env->cur_pmmask = mask & UINT32_MAX;
+ env->cur_pmbase = base & UINT32_MAX;
+ } else {
+ env->cur_pmmask = mask;
+ env->cur_pmbase = base;
+ }
+}
+
#ifndef CONFIG_USER_ONLY
static int riscv_cpu_local_irq_pending(CPURISCVState *env)
{
@@ -331,6 +373,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong
newpriv)
}
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
env->priv = newpriv;
+ riscv_cpu_update_mask(env);
/*
* Clear the load reservation - otherwise a reservation placed in one
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 74c0b788fd..6bb2d09519 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1496,6 +1496,7 @@ static RISCVException write_mmte(CPURISCVState *env, int
csrno,
/* hardwiring pm.instruction bit to 0, since it's not supported yet */
wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
env->mmte = wpri_val | PM_EXT_DIRTY;
+ riscv_cpu_update_mask(env);
/* Set XS and SD bits, since PM CSRs are dirty */
mstatus = env->mstatus | MSTATUS_XS;
@@ -1571,6 +1572,9 @@ static RISCVException write_mpmmask(CPURISCVState *env,
int csrno,
uint64_t mstatus;
env->mpmmask = val;
+ if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
+ env->cur_pmmask = val;
+ }
env->mmte |= PM_EXT_DIRTY;
/* Set XS and SD bits, since PM CSRs are dirty */
@@ -1596,6 +1600,9 @@ static RISCVException write_spmmask(CPURISCVState *env,
int csrno,
return RISCV_EXCP_NONE;
}
env->spmmask = val;
+ if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
+ env->cur_pmmask = val;
+ }
env->mmte |= PM_EXT_DIRTY;
/* Set XS and SD bits, since PM CSRs are dirty */
@@ -1621,6 +1628,9 @@ static RISCVException write_upmmask(CPURISCVState *env,
int csrno,
return RISCV_EXCP_NONE;
}
env->upmmask = val;
+ if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
+ env->cur_pmmask = val;
+ }
env->mmte |= PM_EXT_DIRTY;
/* Set XS and SD bits, since PM CSRs are dirty */
@@ -1642,6 +1652,9 @@ static RISCVException write_mpmbase(CPURISCVState *env,
int csrno,
uint64_t mstatus;
env->mpmbase = val;
+ if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
+ env->cur_pmbase = val;
+ }
env->mmte |= PM_EXT_DIRTY;
/* Set XS and SD bits, since PM CSRs are dirty */
@@ -1667,6 +1680,9 @@ static RISCVException write_spmbase(CPURISCVState *env,
int csrno,
return RISCV_EXCP_NONE;
}
env->spmbase = val;
+ if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
+ env->cur_pmbase = val;
+ }
env->mmte |= PM_EXT_DIRTY;
/* Set XS and SD bits, since PM CSRs are dirty */
@@ -1692,6 +1708,9 @@ static RISCVException write_upmbase(CPURISCVState *env,
int csrno,
return RISCV_EXCP_NONE;
}
env->upmbase = val;
+ if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
+ env->cur_pmbase = val;
+ }
env->mmte |= PM_EXT_DIRTY;
/* Set XS and SD bits, since PM CSRs are dirty */
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 7b4c739564..19e982d3f0 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -164,10 +164,20 @@ static const VMStateDescription vmstate_hyper = {
}
};
+static int riscv_cpu_post_load(void *opaque, int version_id)
+{
+ RISCVCPU *cpu = opaque;
+ CPURISCVState *env = &cpu->env;
+
+ riscv_cpu_update_mask(env);
+ return 0;
+}
+
const VMStateDescription vmstate_riscv_cpu = {
.name = "cpu",
.version_id = 3,
.minimum_version_id = 3,
+ .post_load = riscv_cpu_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
--
2.25.1
- [PATCH v4 03/20] target/riscv: Ignore the pc bits above XLEN, (continued)
- [PATCH v4 03/20] target/riscv: Ignore the pc bits above XLEN, LIU Zhiwei, 2021/11/11
- [PATCH v4 04/20] target/riscv: Extend pc for runtime pc write, LIU Zhiwei, 2021/11/11
- [PATCH v4 05/20] target/riscv: Use gdb xml according to max mxlen, LIU Zhiwei, 2021/11/11
- [PATCH v4 06/20] target/riscv: Relax debug check for pm write, LIU Zhiwei, 2021/11/11
- [PATCH v4 07/20] target/riscv: Adjust csr write mask with XLEN, LIU Zhiwei, 2021/11/11
- [PATCH v4 08/20] target/riscv: Create current pm fields in env,
LIU Zhiwei <=
- [PATCH v4 09/20] target/riscv: Alloc tcg global for cur_pm[mask|base], LIU Zhiwei, 2021/11/11
- [PATCH v4 10/20] target/riscv: Calculate address according to XLEN, LIU Zhiwei, 2021/11/11
- [PATCH v4 11/20] target/riscv: Split pm_enabled into mask and base, LIU Zhiwei, 2021/11/11
- [PATCH v4 12/20] target/riscv: Split out the vill from vtype, LIU Zhiwei, 2021/11/11
- [PATCH v4 13/20] target/riscv: Fix RESERVED field length in VTYPE, LIU Zhiwei, 2021/11/11