diff options
Diffstat (limited to 'target')
| -rw-r--r-- | target/riscv/cpu.c | 69 | ||||
| -rw-r--r-- | target/riscv/cpu_helper.c | 9 | ||||
| -rw-r--r-- | target/riscv/helper.h | 5 | ||||
| -rw-r--r-- | target/riscv/insn32.decode | 8 | ||||
| -rw-r--r-- | target/riscv/insn_trans/trans_privileged.inc.c | 38 | ||||
| -rw-r--r-- | target/riscv/insn_trans/trans_rvf.inc.c | 17 | ||||
| -rw-r--r-- | target/riscv/insn_trans/trans_rvh.inc.c | 37 | ||||
| -rw-r--r-- | target/riscv/op_helper.c | 13 | ||||
| -rw-r--r-- | target/riscv/pmp.c | 14 | ||||
| -rw-r--r-- | target/riscv/translate.c | 1 |
10 files changed, 113 insertions, 98 deletions
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 3a6d202d03..391a0b9eec 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -126,9 +126,7 @@ static void riscv_any_cpu_init(Object *obj) set_resetvec(env, DEFAULT_RSTVEC); } -#if defined(TARGET_RISCV32) - -static void riscv_base32_cpu_init(Object *obj) +static void riscv_base_cpu_init(Object *obj) { CPURISCVState *env = &RISCV_CPU(obj)->env; /* We set this in the realise function */ @@ -136,63 +134,38 @@ static void riscv_base32_cpu_init(Object *obj) set_resetvec(env, DEFAULT_RSTVEC); } -static void rv32gcsu_priv1_10_0_cpu_init(Object *obj) +static void rvxx_sifive_u_cpu_init(Object *obj) { CPURISCVState *env = &RISCV_CPU(obj)->env; - set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); + set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); set_priv_version(env, PRIV_VERSION_1_10_0); - set_resetvec(env, DEFAULT_RSTVEC); + set_resetvec(env, 0x1004); } -static void rv32imcu_nommu_cpu_init(Object *obj) +static void rvxx_sifive_e_cpu_init(Object *obj) { CPURISCVState *env = &RISCV_CPU(obj)->env; - set_misa(env, RV32 | RVI | RVM | RVC | RVU); + set_misa(env, RVXLEN | RVI | RVM | RVA | RVC | RVU); set_priv_version(env, PRIV_VERSION_1_10_0); - set_resetvec(env, 0x8090); + set_resetvec(env, 0x1004); qdev_prop_set_bit(DEVICE(obj), "mmu", false); } -static void rv32imacu_nommu_cpu_init(Object *obj) -{ - CPURISCVState *env = &RISCV_CPU(obj)->env; - set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU); - set_priv_version(env, PRIV_VERSION_1_10_0); - set_resetvec(env, DEFAULT_RSTVEC); - qdev_prop_set_bit(DEVICE(obj), "mmu", false); -} +#if defined(TARGET_RISCV32) -static void rv32imafcu_nommu_cpu_init(Object *obj) +static void rv32_ibex_cpu_init(Object *obj) { CPURISCVState *env = &RISCV_CPU(obj)->env; - set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVC | RVU); + set_misa(env, RV32 | RVI | RVM | RVC | RVU); set_priv_version(env, PRIV_VERSION_1_10_0); - set_resetvec(env, DEFAULT_RSTVEC); + set_resetvec(env, 0x8090); qdev_prop_set_bit(DEVICE(obj), "mmu", false); } -#elif defined(TARGET_RISCV64) - -static void riscv_base64_cpu_init(Object *obj) -{ - CPURISCVState *env = &RISCV_CPU(obj)->env; - /* We set this in the realise function */ - set_misa(env, 0); - set_resetvec(env, DEFAULT_RSTVEC); -} - -static void rv64gcsu_priv1_10_0_cpu_init(Object *obj) -{ - CPURISCVState *env = &RISCV_CPU(obj)->env; - set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); - set_priv_version(env, PRIV_VERSION_1_10_0); - set_resetvec(env, DEFAULT_RSTVEC); -} - -static void rv64imacu_nommu_cpu_init(Object *obj) +static void rv32_imafcu_nommu_cpu_init(Object *obj) { CPURISCVState *env = &RISCV_CPU(obj)->env; - set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU); + set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVC | RVU); set_priv_version(env, PRIV_VERSION_1_10_0); set_resetvec(env, DEFAULT_RSTVEC); qdev_prop_set_bit(DEVICE(obj), "mmu", false); @@ -603,15 +576,15 @@ static const TypeInfo riscv_cpu_type_infos[] = { }, DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init), #if defined(TARGET_RISCV32) - DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base32_cpu_init), - DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init), - DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init), - DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init), - DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init), + DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init), + DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init), + DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_sifive_e_cpu_init), + DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init), + DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_sifive_u_cpu_init), #elif defined(TARGET_RISCV64) - DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base64_cpu_init), - DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init), - DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init), + DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init), + DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_sifive_e_cpu_init), + DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_sifive_u_cpu_init), #endif }; diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 62fe1ecc8f..75d2ae3434 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -435,8 +435,13 @@ restart: hwaddr vbase; /* Do the second stage translation on the base PTE address. */ - get_physical_address(env, &vbase, &vbase_prot, base, access_type, - mmu_idx, false, true); + int vbase_ret = get_physical_address(env, &vbase, &vbase_prot, + base, MMU_DATA_LOAD, + mmu_idx, false, true); + + if (vbase_ret != TRANSLATE_SUCCESS) { + return vbase_ret; + } pte_addr = vbase + idx * ptesize; } else { diff --git a/target/riscv/helper.h b/target/riscv/helper.h index debb22a480..b36be978d5 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -76,3 +76,8 @@ DEF_HELPER_2(mret, tl, env, tl) DEF_HELPER_1(wfi, void, env) DEF_HELPER_1(tlb_flush, void, env) #endif + +/* Hypervisor functions */ +#ifndef CONFIG_USER_ONLY +DEF_HELPER_1(hyp_tlb_flush, void, env) +#endif diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index b883672e63..4c8d1215ce 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -64,7 +64,7 @@ @r2 ....... ..... ..... ... ..... ....... %rs1 %rd @hfence_gvma ....... ..... ..... ... ..... ....... %rs2 %rs1 -@hfence_bvma ....... ..... ..... ... ..... ....... %rs2 %rs1 +@hfence_vvma ....... ..... ..... ... ..... ....... %rs2 %rs1 @sfence_vma ....... ..... ..... ... ..... ....... %rs2 %rs1 @sfence_vm ....... ..... ..... ... ..... ....... %rs1 @@ -77,8 +77,6 @@ uret 0000000 00010 00000 000 00000 1110011 sret 0001000 00010 00000 000 00000 1110011 mret 0011000 00010 00000 000 00000 1110011 wfi 0001000 00101 00000 000 00000 1110011 -hfence_gvma 0110001 ..... ..... 000 00000 1110011 @hfence_gvma -hfence_bvma 0010001 ..... ..... 000 00000 1110011 @hfence_bvma sfence_vma 0001001 ..... ..... 000 00000 1110011 @sfence_vma sfence_vm 0001000 00100 ..... 000 00000 1110011 @sfence_vm @@ -207,3 +205,7 @@ fcvt_w_d 1100001 00000 ..... ... ..... 1010011 @r2_rm fcvt_wu_d 1100001 00001 ..... ... ..... 1010011 @r2_rm fcvt_d_w 1101001 00000 ..... ... ..... 1010011 @r2_rm fcvt_d_wu 1101001 00001 ..... ... ..... 1010011 @r2_rm + +# *** RV32H Base Instruction Set *** +hfence_gvma 0110001 ..... ..... 000 00000 1110011 @hfence_gvma +hfence_vvma 0010001 ..... ..... 000 00000 1110011 @hfence_vvma diff --git a/target/riscv/insn_trans/trans_privileged.inc.c b/target/riscv/insn_trans/trans_privileged.inc.c index 5f26e0f5ea..2a61a853bf 100644 --- a/target/riscv/insn_trans/trans_privileged.inc.c +++ b/target/riscv/insn_trans/trans_privileged.inc.c @@ -95,41 +95,3 @@ static bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a) { return false; } - -static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a) -{ -#ifndef CONFIG_USER_ONLY - if (has_ext(ctx, RVH)) { - /* Hpervisor extensions exist */ - /* - * if (env->priv == PRV_M || - * (env->priv == PRV_S && - * !riscv_cpu_virt_enabled(env) && - * get_field(ctx->mstatus_fs, MSTATUS_TVM))) { - */ - gen_helper_tlb_flush(cpu_env); - return true; - /* } */ - } -#endif - return false; -} - -static bool trans_hfence_bvma(DisasContext *ctx, arg_sfence_vma *a) -{ -#ifndef CONFIG_USER_ONLY - if (has_ext(ctx, RVH)) { - /* Hpervisor extensions exist */ - /* - * if (env->priv == PRV_M || - * (env->priv == PRV_S && - * !riscv_cpu_virt_enabled(env) && - * get_field(ctx->mstatus_fs, MSTATUS_TVM))) { - */ - gen_helper_tlb_flush(cpu_env); - return true; - /* } */ - } -#endif - return false; -} diff --git a/target/riscv/insn_trans/trans_rvf.inc.c b/target/riscv/insn_trans/trans_rvf.inc.c index e23cd639a6..3bfd8881e7 100644 --- a/target/riscv/insn_trans/trans_rvf.inc.c +++ b/target/riscv/insn_trans/trans_rvf.inc.c @@ -23,6 +23,20 @@ return false; \ } while (0) +/* + * RISC-V requires NaN-boxing of narrower width floating + * point values. This applies when a 32-bit value is + * assigned to a 64-bit FP register. Thus this does not + * apply when the RVD extension is not present. + */ +static void gen_nanbox_fpr(DisasContext *ctx, int regno) +{ + if (has_ext(ctx, RVD)) { + tcg_gen_ori_i64(cpu_fpr[regno], cpu_fpr[regno], + MAKE_64BIT_MASK(32, 32)); + } +} + static bool trans_flw(DisasContext *ctx, arg_flw *a) { TCGv t0 = tcg_temp_new(); @@ -32,8 +46,7 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a) tcg_gen_addi_tl(t0, t0, a->imm); tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL); - /* RISC-V requires NaN-boxing of narrower width floating point values */ - tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], 0xffffffff00000000ULL); + gen_nanbox_fpr(ctx, a->rd); tcg_temp_free(t0); mark_fs_dirty(ctx); diff --git a/target/riscv/insn_trans/trans_rvh.inc.c b/target/riscv/insn_trans/trans_rvh.inc.c new file mode 100644 index 0000000000..263b652d90 --- /dev/null +++ b/target/riscv/insn_trans/trans_rvh.inc.c @@ -0,0 +1,37 @@ +/* + * RISC-V translation routines for the RVXI Base Integer Instruction Set. + * + * Copyright (c) 2020 Western Digital + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a) +{ + REQUIRE_EXT(ctx, RVH); +#ifndef CONFIG_USER_ONLY + gen_helper_hyp_tlb_flush(cpu_env); + return true; +#endif + return false; +} + +static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a) +{ + REQUIRE_EXT(ctx, RVH); +#ifndef CONFIG_USER_ONLY + gen_helper_hyp_tlb_flush(cpu_env); + return true; +#endif + return false; +} diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index b0c49efc4a..7cccd42a1e 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -194,4 +194,17 @@ void helper_tlb_flush(CPURISCVState *env) } } +void helper_hyp_tlb_flush(CPURISCVState *env) +{ + CPUState *cs = env_cpu(env); + + if (env->priv == PRV_M || + (env->priv == PRV_S && !riscv_cpu_virt_enabled(env))) { + tlb_flush(cs); + return; + } + + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); +} + #endif /* !CONFIG_USER_ONLY */ diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c index 0e6b640fbd..9418660f1b 100644 --- a/target/riscv/pmp.c +++ b/target/riscv/pmp.c @@ -233,12 +233,16 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, return true; } - /* - * if size is unknown (0), assume that all bytes - * from addr to the end of the page will be accessed. - */ if (size == 0) { - pmp_size = -(addr | TARGET_PAGE_MASK); + if (riscv_feature(env, RISCV_FEATURE_MMU)) { + /* + * If size is unknown (0), assume that all bytes + * from addr to the end of the page will be accessed. + */ + pmp_size = -(addr | TARGET_PAGE_MASK); + } else { + pmp_size = sizeof(target_ulong); + } } else { pmp_size = size; } diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 43bf7e39a6..ce71ca7a92 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -711,6 +711,7 @@ static bool gen_shift(DisasContext *ctx, arg_r *a, #include "insn_trans/trans_rva.inc.c" #include "insn_trans/trans_rvf.inc.c" #include "insn_trans/trans_rvd.inc.c" +#include "insn_trans/trans_rvh.inc.c" #include "insn_trans/trans_privileged.inc.c" /* Include the auto-generated decoder for 16 bit insn */ |