Add MMU_GUEST_IDX and MMU_GUEST_DA_IDX. Provide is_guest_mmu idx() and mmu_idx_to_plv to calculate plv with new mmu_idx.
Signed-off-by: SignKirigami <[email protected]> Signed-off-by: Hengyu Yu <[email protected]> --- target/loongarch/cpu.h | 18 ++++++++++++++++++ .../tcg/insn_trans/trans_privileged.c.inc | 2 +- target/loongarch/tcg/tcg_cpu.c | 7 +++++++ target/loongarch/tcg/translate.c | 3 +++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 183210efd8..9eea1badaf 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -513,6 +513,24 @@ struct LoongArchCPUClass { #define MMU_KERNEL_IDX MMU_PLV_KERNEL #define MMU_USER_IDX MMU_PLV_USER #define MMU_DA_IDX 4 +#define MMU_GUEST_IDX 5 +#define MMU_GUEST_DA_IDX 9 + +static inline bool is_guest_mmu_idx(int mmu_idx) +{ + return mmu_idx >= MMU_GUEST_IDX; +} + +static inline int mmu_idx_to_plv(int mmu_idx) +{ + if (mmu_idx == MMU_DA_IDX || mmu_idx == MMU_GUEST_DA_IDX) { + return 0; + } + if (is_guest_mmu_idx(mmu_idx)) { + return mmu_idx - MMU_GUEST_IDX; + } + return mmu_idx; +} static inline CPUSysState *env_sys(CPULoongArchState *env) { diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc index 6728ce5ec9..7ee3bb8e27 100644 --- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc +++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc @@ -249,7 +249,7 @@ TRANS64(iocsrwr_d, IOCSR, gen_iocsrwr, gen_helper_iocsrwr_d) static void check_mmu_idx(DisasContext *ctx) { - if (ctx->mem_idx != MMU_DA_IDX) { + if (ctx->mem_idx != MMU_DA_IDX && ctx->mem_idx != MMU_GUEST_DA_IDX) { tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4); ctx->base.is_jmp = DISAS_EXIT; } diff --git a/target/loongarch/tcg/tcg_cpu.c b/target/loongarch/tcg/tcg_cpu.c index 14fa5f5809..b60d9e7cf8 100644 --- a/target/loongarch/tcg/tcg_cpu.c +++ b/target/loongarch/tcg/tcg_cpu.c @@ -309,6 +309,13 @@ static int loongarch_cpu_mmu_index(CPUState *cs, bool ifetch) CPULoongArchState *env = cpu_env(cs); CPUSysState *sys = env_sys(env); + if (env_vm_level(env) == VM_LEVEL1) { + if (FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PG)) { + return MMU_GUEST_IDX + FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV); + } + return MMU_GUEST_DA_IDX; + } + if (FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PG)) { return FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV); } diff --git a/target/loongarch/tcg/translate.c b/target/loongarch/tcg/translate.c index 124dce6269..4ab06b48da 100644 --- a/target/loongarch/tcg/translate.c +++ b/target/loongarch/tcg/translate.c @@ -129,6 +129,9 @@ static void loongarch_tr_init_disas_context(DisasContextBase *dcbase, } else { ctx->mem_idx = MMU_DA_IDX; } + if (ctx->base.tb->flags & HW_FLAGS_GUEST_MODE) { + ctx->mem_idx += MMU_GUEST_IDX; + } /* Bound the number of insns to execute to those left on the page. */ bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; -- 2.55.0
