From 2584ab8ee57a3f6dd03fb833841d52fc87b82742 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Sun, 14 Jun 2020 22:23:24 -0400 Subject: [PATCH] target/riscv: Drop support for ISA spec version 1.09.1 The RISC-V ISA spec version 1.09.1 has been deprecated in QEMU since 4.1. It's not commonly used so let's remove support for it. Backports commit 1a9540d1f1a9c5022d9273d0244e5809679dd33b from qemu --- qemu/target/riscv/cpu.h | 1 - qemu/target/riscv/cpu_helper.c | 82 ++++------ qemu/target/riscv/csr.c | 140 ++++-------------- .../riscv/insn_trans/trans_privileged.inc.c | 21 +-- qemu/target/riscv/op_helper.c | 17 +-- 5 files changed, 65 insertions(+), 196 deletions(-) diff --git a/qemu/target/riscv/cpu.h b/qemu/target/riscv/cpu.h index b6502c81..db9bbefc 100644 --- a/qemu/target/riscv/cpu.h +++ b/qemu/target/riscv/cpu.h @@ -76,7 +76,6 @@ enum { RISCV_FEATURE_MISA }; -#define PRIV_VERSION_1_09_1 0x00010901 #define PRIV_VERSION_1_10_0 0x00011000 #define PRIV_VERSION_1_11_0 0x00011100 diff --git a/qemu/target/riscv/cpu_helper.c b/qemu/target/riscv/cpu_helper.c index 5f7010a6..36d34121 100644 --- a/qemu/target/riscv/cpu_helper.c +++ b/qemu/target/riscv/cpu_helper.c @@ -358,57 +358,36 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical, mxr = get_field(env->vsstatus, MSTATUS_MXR); } - if (env->priv_ver >= PRIV_VERSION_1_10_0) { - if (first_stage == true) { - if (use_background) { - base = (hwaddr)get_field(env->vsatp, SATP_PPN) << PGSHIFT; - vm = get_field(env->vsatp, SATP_MODE); - } else { - base = (hwaddr)get_field(env->satp, SATP_PPN) << PGSHIFT; - vm = get_field(env->satp, SATP_MODE); - } - widened = 0; + if (first_stage == true) { + if (use_background) { + base = (hwaddr)get_field(env->vsatp, SATP_PPN) << PGSHIFT; + vm = get_field(env->vsatp, SATP_MODE); } else { - base = (hwaddr)get_field(env->hgatp, HGATP_PPN) << PGSHIFT; - vm = get_field(env->hgatp, HGATP_MODE); - widened = 2; + base = (hwaddr)get_field(env->satp, SATP_PPN) << PGSHIFT; + vm = get_field(env->satp, SATP_MODE); } - sum = get_field(env->mstatus, MSTATUS_SUM); - switch (vm) { - case VM_1_10_SV32: - levels = 2; ptidxbits = 10; ptesize = 4; break; - case VM_1_10_SV39: - levels = 3; ptidxbits = 9; ptesize = 8; break; - case VM_1_10_SV48: - levels = 4; ptidxbits = 9; ptesize = 8; break; - case VM_1_10_SV57: - levels = 5; ptidxbits = 9; ptesize = 8; break; - case VM_1_10_MBARE: - *physical = addr; - *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - return TRANSLATE_SUCCESS; - default: - g_assert_not_reached(); - } - } else { widened = 0; - base = (hwaddr)(env->sptbr) << PGSHIFT; - sum = !get_field(env->mstatus, MSTATUS_PUM); - vm = get_field(env->mstatus, MSTATUS_VM); - switch (vm) { - case VM_1_09_SV32: - levels = 2; ptidxbits = 10; ptesize = 4; break; - case VM_1_09_SV39: - levels = 3; ptidxbits = 9; ptesize = 8; break; - case VM_1_09_SV48: - levels = 4; ptidxbits = 9; ptesize = 8; break; - case VM_1_09_MBARE: - *physical = addr; - *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - return TRANSLATE_SUCCESS; - default: - g_assert_not_reached(); - } + } else { + base = (hwaddr)get_field(env->hgatp, HGATP_PPN) << PGSHIFT; + vm = get_field(env->hgatp, HGATP_MODE); + widened = 2; + } + sum = get_field(env->mstatus, MSTATUS_SUM); + switch (vm) { + case VM_1_10_SV32: + levels = 2; ptidxbits = 10; ptesize = 4; break; + case VM_1_10_SV39: + levels = 3; ptidxbits = 9; ptesize = 8; break; + case VM_1_10_SV48: + levels = 4; ptidxbits = 9; ptesize = 8; break; + case VM_1_10_SV57: + levels = 5; ptidxbits = 9; ptesize = 8; break; + case VM_1_10_MBARE: + *physical = addr; + *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + return TRANSLATE_SUCCESS; + default: + g_assert_not_reached(); } CPUState *cs = env_cpu(env); @@ -582,7 +561,6 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address, int page_fault_exceptions; if (first_stage) { page_fault_exceptions = - (env->priv_ver >= PRIV_VERSION_1_10_0) && get_field(env->satp, SATP_MODE) != VM_1_10_MBARE && !pmp_violation; } else { @@ -933,8 +911,7 @@ void riscv_cpu_do_interrupt(CPUState *cs) } s = env->mstatus; - s = set_field(s, MSTATUS_SPIE, env->priv_ver >= PRIV_VERSION_1_10_0 ? - get_field(s, MSTATUS_SIE) : get_field(s, MSTATUS_UIE << env->priv)); + s = set_field(s, MSTATUS_SPIE, get_field(s, MSTATUS_SIE)); s = set_field(s, MSTATUS_SPP, env->priv); s = set_field(s, MSTATUS_SIE, 0); env->mstatus = s; @@ -971,8 +948,7 @@ void riscv_cpu_do_interrupt(CPUState *cs) } s = env->mstatus; - s = set_field(s, MSTATUS_MPIE, env->priv_ver >= PRIV_VERSION_1_10_0 ? - get_field(s, MSTATUS_MIE) : get_field(s, MSTATUS_UIE << env->priv)); + s = set_field(s, MSTATUS_MPIE, get_field(s, MSTATUS_MIE)); s = set_field(s, MSTATUS_MPP, env->priv); s = set_field(s, MSTATUS_MIE, 0); env->mstatus = s; diff --git a/qemu/target/riscv/csr.c b/qemu/target/riscv/csr.c index fbdb28bc..3adf1b00 100644 --- a/qemu/target/riscv/csr.c +++ b/qemu/target/riscv/csr.c @@ -55,26 +55,6 @@ static int fs(CPURISCVState *env, int csrno) static int ctr(CPURISCVState *env, int csrno) { #if !defined(CONFIG_USER_ONLY) - /* - * The counters are always enabled on newer priv specs, as the CSR has - * changed from controlling that the counters can be read to controlling - * that the counters increment. - */ - if (env->priv_ver > PRIV_VERSION_1_09_1) { - return 0; - } - - uint32_t ctr_en = ~0u; - - if (env->priv < PRV_M) { - ctr_en &= env->mcounteren; - } - if (env->priv < PRV_S) { - ctr_en &= env->scounteren; - } - if (!(ctr_en & (1u << (csrno & 31)))) { - return -1; - } #endif return 0; } @@ -293,9 +273,6 @@ static const target_ulong delegable_excps = (1ULL << (RISCV_EXCP_INST_GUEST_PAGE_FAULT)) | (1ULL << (RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT)) | (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)); -static const target_ulong sstatus_v1_9_mask = SSTATUS_SIE | SSTATUS_SPIE | - SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS | - SSTATUS_SUM | SSTATUS_SD; static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS | SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD; @@ -304,20 +281,11 @@ static const target_ulong hip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP; static const target_ulong vsip_writable_mask = MIP_VSSIP; #if defined(TARGET_RISCV32) -static const char valid_vm_1_09[16] = { - [VM_1_09_MBARE] = 1, - [VM_1_09_SV32] = 1, -}; static const char valid_vm_1_10[16] = { [VM_1_10_MBARE] = 1, [VM_1_10_SV32] = 1 }; #elif defined(TARGET_RISCV64) -static const char valid_vm_1_09[16] = { - [VM_1_09_MBARE] = 1, - [VM_1_09_SV39] = 1, - [VM_1_09_SV48] = 1, -}; static const char valid_vm_1_10[16] = { [VM_1_10_MBARE] = 1, [VM_1_10_SV39] = 1, @@ -347,8 +315,7 @@ static int read_mstatus(CPURISCVState *env, int csrno, target_ulong *val) static int validate_vm(CPURISCVState *env, target_ulong vm) { - return (env->priv_ver >= PRIV_VERSION_1_10_0) ? - valid_vm_1_10[vm & 0xf] : valid_vm_1_09[vm & 0xf]; + return valid_vm_1_10[vm & 0xf]; } static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) @@ -357,35 +324,22 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) target_ulong mask = 0; /* flush tlb on mstatus fields that affect VM */ - if (env->priv_ver <= PRIV_VERSION_1_09_1) { - if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV | - MSTATUS_MPRV | MSTATUS_SUM | MSTATUS_VM)) { - tlb_flush(env_cpu(env)); - } - mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE | - MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM | - MSTATUS_MPP | MSTATUS_MXR | - (validate_vm(env, get_field(val, MSTATUS_VM)) ? - MSTATUS_VM : 0); + if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV | + MSTATUS_MPRV | MSTATUS_SUM)) { + tlb_flush(env_cpu(env)); } - if (env->priv_ver >= PRIV_VERSION_1_10_0) { - if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | - MSTATUS_MPRV | MSTATUS_SUM)) { - tlb_flush(env_cpu(env)); - } - mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE | - MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM | - MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR | - MSTATUS_TW; + mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE | + MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM | + MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR | + MSTATUS_TW; #if defined(TARGET_RISCV64) - /* - * RV32: MPV and MTL are not in mstatus. The current plan is to - * add them to mstatush. For now, we just don't support it. - */ - mask |= MSTATUS_MPP | MSTATUS_MPV; + /* + * RV32: MPV and MTL are not in mstatus. The current plan is to + * add them to mstatush. For now, we just don't support it. + */ + mask |= MSTATUS_MTL | MSTATUS_MPV; #endif - } mstatus = (mstatus & ~mask) | (val & mask); @@ -534,18 +488,12 @@ static int write_mtvec(CPURISCVState *env, int csrno, target_ulong val) static int read_mcounteren(CPURISCVState *env, int csrno, target_ulong *val) { - if (env->priv_ver < PRIV_VERSION_1_10_0) { - return -1; - } *val = env->mcounteren; return 0; } static int write_mcounteren(CPURISCVState *env, int csrno, target_ulong val) { - if (env->priv_ver < PRIV_VERSION_1_10_0) { - return -1; - } env->mcounteren = val; return 0; } @@ -553,8 +501,7 @@ static int write_mcounteren(CPURISCVState *env, int csrno, target_ulong val) /* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */ static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val) { - if (env->priv_ver > PRIV_VERSION_1_09_1 - && env->priv_ver < PRIV_VERSION_1_11_0) { + if (env->priv_ver < PRIV_VERSION_1_11_0) { return -1; } *val = env->mcounteren; @@ -564,32 +511,13 @@ static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val) /* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */ static int write_mscounteren(CPURISCVState *env, int csrno, target_ulong val) { - if (env->priv_ver > PRIV_VERSION_1_09_1 - && env->priv_ver < PRIV_VERSION_1_11_0) { + if (env->priv_ver < PRIV_VERSION_1_11_0) { return -1; } env->mcounteren = val; return 0; } -static int read_mucounteren(CPURISCVState *env, int csrno, target_ulong *val) -{ - if (env->priv_ver > PRIV_VERSION_1_09_1) { - return -1; - } - *val = env->scounteren; - return 0; -} - -static int write_mucounteren(CPURISCVState *env, int csrno, target_ulong val) -{ - if (env->priv_ver > PRIV_VERSION_1_09_1) { - return -1; - } - env->scounteren = val; - return 0; -} - /* Machine Trap Handling */ static int read_mscratch(CPURISCVState *env, int csrno, target_ulong *val) { @@ -666,16 +594,14 @@ static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value, /* Supervisor Trap Setup */ static int read_sstatus(CPURISCVState *env, int csrno, target_ulong *val) { - target_ulong mask = ((env->priv_ver >= PRIV_VERSION_1_10_0) ? - sstatus_v1_10_mask : sstatus_v1_9_mask); + target_ulong mask = (sstatus_v1_10_mask); *val = env->mstatus & mask; return 0; } static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val) { - target_ulong mask = ((env->priv_ver >= PRIV_VERSION_1_10_0) ? - sstatus_v1_10_mask : sstatus_v1_9_mask); + target_ulong mask = (sstatus_v1_10_mask); target_ulong newval = (env->mstatus & ~mask) | (val & mask); return write_mstatus(env, CSR_MSTATUS, newval); } @@ -725,18 +651,12 @@ static int write_stvec(CPURISCVState *env, int csrno, target_ulong val) static int read_scounteren(CPURISCVState *env, int csrno, target_ulong *val) { - if (env->priv_ver < PRIV_VERSION_1_10_0) { - return -1; - } *val = env->scounteren; return 0; } static int write_scounteren(CPURISCVState *env, int csrno, target_ulong val) { - if (env->priv_ver < PRIV_VERSION_1_10_0) { - return -1; - } env->scounteren = val; return 0; } @@ -815,15 +735,15 @@ static int read_satp(CPURISCVState *env, int csrno, target_ulong *val) { if (!riscv_feature(env, RISCV_FEATURE_MMU)) { *val = 0; - } else if (env->priv_ver >= PRIV_VERSION_1_10_0) { - if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) { - return -1; - } else { - *val = env->satp; - } - } else { - *val = env->sptbr; + return 0; } + + if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) { + return -1; + } else { + *val = env->satp; + } + return 0; } @@ -832,13 +752,7 @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val) if (!riscv_feature(env, RISCV_FEATURE_MMU)) { return 0; } - if (env->priv_ver <= PRIV_VERSION_1_09_1 && (val ^ env->sptbr)) { - tlb_flush(env_cpu(env)); - env->sptbr = val & (((target_ulong) - 1 << (TARGET_PHYS_ADDR_SPACE_BITS - PGSHIFT)) - 1); - } - if (env->priv_ver >= PRIV_VERSION_1_10_0 && - validate_vm(env, get_field(val, SATP_MODE)) && + if (validate_vm(env, get_field(val, SATP_MODE)) && ((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN))) { if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) { @@ -1314,8 +1228,6 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_MSTATUSH] = { any, read_mstatush, write_mstatush }, #endif - /* Legacy Counter Setup (priv v1.9.1) */ - [CSR_MUCOUNTEREN] = { any, read_mucounteren, write_mucounteren }, [CSR_MSCOUNTEREN] = { any, read_mscounteren, write_mscounteren }, /* Machine Trap Handling */ diff --git a/qemu/target/riscv/insn_trans/trans_privileged.inc.c b/qemu/target/riscv/insn_trans/trans_privileged.inc.c index f68379a8..0e4e639a 100644 --- a/qemu/target/riscv/insn_trans/trans_privileged.inc.c +++ b/qemu/target/riscv/insn_trans/trans_privileged.inc.c @@ -88,24 +88,15 @@ static bool trans_wfi(DisasContext *ctx, arg_wfi *a) static bool trans_sfence_vma(DisasContext *ctx, arg_sfence_vma *a) { #ifndef CONFIG_USER_ONLY - if (ctx->priv_ver >= PRIV_VERSION_1_10_0) { - TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - gen_helper_tlb_flush(tcg_ctx, tcg_ctx->cpu_env); - return true; - } + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + gen_helper_tlb_flush(tcg_ctx, tcg_ctx->cpu_env); + return true; #endif return false; } static bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a) { -#ifndef CONFIG_USER_ONLY - if (ctx->priv_ver <= PRIV_VERSION_1_09_1) { - TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - gen_helper_tlb_flush(tcg_ctx, tcg_ctx->cpu_env); - return true; - } -#endif return false; } @@ -113,8 +104,7 @@ static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a) { #ifndef CONFIG_USER_ONLY TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - if (ctx->priv_ver >= PRIV_VERSION_1_10_0 && - has_ext(ctx, RVH)) { + if (has_ext(ctx, RVH)) { /* Hpervisor extensions exist */ /* * if (env->priv == PRV_M || @@ -134,8 +124,7 @@ static bool trans_hfence_bvma(DisasContext *ctx, arg_sfence_vma *a) { #ifndef CONFIG_USER_ONLY TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - if (ctx->priv_ver >= PRIV_VERSION_1_10_0 && - has_ext(ctx, RVH)) { + if (has_ext(ctx, RVH)) { /* Hpervisor extensions exist */ /* * if (env->priv == PRV_M || diff --git a/qemu/target/riscv/op_helper.c b/qemu/target/riscv/op_helper.c index f00c59c7..b1269ced 100644 --- a/qemu/target/riscv/op_helper.c +++ b/qemu/target/riscv/op_helper.c @@ -83,8 +83,7 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb) riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC()); } - if (env->priv_ver >= PRIV_VERSION_1_10_0 && - get_field(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) { + if (get_field(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) { riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); } @@ -118,10 +117,8 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb) } else { prev_priv = get_field(mstatus, MSTATUS_SPP); - mstatus = set_field(mstatus, - env->priv_ver >= PRIV_VERSION_1_10_0 ? - MSTATUS_SIE : MSTATUS_UIE << prev_priv, - get_field(mstatus, MSTATUS_SPIE)); + mstatus = set_field(mstatus, MSTATUS_SIE, + get_field(mstatus, MSTATUS_SPIE)); mstatus = set_field(mstatus, MSTATUS_SPIE, 1); mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U); env->mstatus = mstatus; @@ -146,10 +143,8 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb) target_ulong mstatus = env->mstatus; target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP); target_ulong prev_virt = MSTATUS_MPV_ISSET(env); - mstatus = set_field(mstatus, - env->priv_ver >= PRIV_VERSION_1_10_0 ? - MSTATUS_MIE : MSTATUS_UIE << prev_priv, - get_field(mstatus, MSTATUS_MPIE)); + mstatus = set_field(mstatus, MSTATUS_MIE, + get_field(mstatus, MSTATUS_MPIE)); mstatus = set_field(mstatus, MSTATUS_MPIE, 1); mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U); #ifdef TARGET_RISCV32 @@ -176,7 +171,6 @@ void helper_wfi(CPURISCVState *env) CPUState *cs = env_cpu(env); if ((env->priv == PRV_S && - env->priv_ver >= PRIV_VERSION_1_10_0 && get_field(env->mstatus, MSTATUS_TW)) || riscv_cpu_virt_enabled(env)) { riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); @@ -192,7 +186,6 @@ void helper_tlb_flush(CPURISCVState *env) CPUState *cs = env_cpu(env); if (!(env->priv >= PRV_S) || (env->priv == PRV_S && - env->priv_ver >= PRIV_VERSION_1_10_0 && get_field(env->mstatus, MSTATUS_TVM))) { riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); } else {