From b86f4167630802128d94f3c89043d97d2f4c2546 Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Mon, 1 Apr 2019 15:12:07 -0400 Subject: target/riscv: Do not allow sfence.vma from user mode The 'sfence.vma' instruction is privileged, and should only ever be allowed when executing in supervisor mode or higher. Signed-off-by: Jonathan Behrens Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis Signed-off-by: Palmer Dabbelt --- target/riscv/op_helper.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'target') diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index b7dc18a..644d0fb 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -145,9 +145,10 @@ void helper_tlb_flush(CPURISCVState *env) { RISCVCPU *cpu = riscv_env_get_cpu(env); CPUState *cs = CPU(cpu); - if (env->priv == PRV_S && - env->priv_ver >= PRIV_VERSION_1_10_0 && - get_field(env->mstatus, MSTATUS_TVM)) { + 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 { tlb_flush(cs); -- cgit v1.1 From 6e2716d8ca4edf3597307accef7af36e8ad966eb Mon Sep 17 00:00:00 2001 From: Fabien Chouteau Date: Mon, 25 Mar 2019 12:45:54 +0100 Subject: RISC-V: fix single stepping over ret and other branching instructions This patch introduces wrappers around the tcg_gen_exit_tb() and tcg_gen_lookup_and_goto_ptr() functions that handle single stepping, i.e. call gen_exception_debug() when single stepping is enabled. Theses functions are then used instead of the originals, bringing single stepping handling in places where it was previously ignored such as jalr and system branch instructions (ecall, mret, sret, etc.). Signed-off-by: Fabien Chouteau Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis Signed-off-by: Palmer Dabbelt --- target/riscv/insn_trans/trans_privileged.inc.c | 8 +++---- target/riscv/insn_trans/trans_rvi.inc.c | 6 +++--- target/riscv/translate.c | 30 +++++++++++++++++++++----- 3 files changed, 32 insertions(+), 12 deletions(-) (limited to 'target') diff --git a/target/riscv/insn_trans/trans_privileged.inc.c b/target/riscv/insn_trans/trans_privileged.inc.c index acb6059..664d6ba 100644 --- a/target/riscv/insn_trans/trans_privileged.inc.c +++ b/target/riscv/insn_trans/trans_privileged.inc.c @@ -22,7 +22,7 @@ static bool trans_ecall(DisasContext *ctx, arg_ecall *a) { /* always generates U-level ECALL, fixed in do_interrupt handler */ generate_exception(ctx, RISCV_EXCP_U_ECALL); - tcg_gen_exit_tb(NULL, 0); /* no chaining */ + exit_tb(ctx); /* no chaining */ ctx->base.is_jmp = DISAS_NORETURN; return true; } @@ -30,7 +30,7 @@ static bool trans_ecall(DisasContext *ctx, arg_ecall *a) static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a) { generate_exception(ctx, RISCV_EXCP_BREAKPOINT); - tcg_gen_exit_tb(NULL, 0); /* no chaining */ + exit_tb(ctx); /* no chaining */ ctx->base.is_jmp = DISAS_NORETURN; return true; } @@ -47,7 +47,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a) if (has_ext(ctx, RVS)) { gen_helper_sret(cpu_pc, cpu_env, cpu_pc); - tcg_gen_exit_tb(NULL, 0); /* no chaining */ + exit_tb(ctx); /* no chaining */ ctx->base.is_jmp = DISAS_NORETURN; } else { return false; @@ -68,7 +68,7 @@ static bool trans_mret(DisasContext *ctx, arg_mret *a) #ifndef CONFIG_USER_ONLY tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); gen_helper_mret(cpu_pc, cpu_env, cpu_pc); - tcg_gen_exit_tb(NULL, 0); /* no chaining */ + exit_tb(ctx); /* no chaining */ ctx->base.is_jmp = DISAS_NORETURN; return true; #else diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c index d420a4d..37b0b9d 100644 --- a/target/riscv/insn_trans/trans_rvi.inc.c +++ b/target/riscv/insn_trans/trans_rvi.inc.c @@ -60,7 +60,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a) if (a->rd != 0) { tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn); } - tcg_gen_lookup_and_goto_ptr(); + lookup_and_goto_ptr(ctx); if (misaligned) { gen_set_label(misaligned); @@ -483,7 +483,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a) * however we need to end the translation block */ tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); - tcg_gen_exit_tb(NULL, 0); + exit_tb(ctx); ctx->base.is_jmp = DISAS_NORETURN; return true; } @@ -504,7 +504,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a) gen_io_end(); \ gen_set_gpr(a->rd, dest); \ tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); \ - tcg_gen_exit_tb(NULL, 0); \ + exit_tb(ctx); \ ctx->base.is_jmp = DISAS_NORETURN; \ tcg_temp_free(source1); \ tcg_temp_free(csr_store); \ diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 2ff6b49..840ecbe 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -109,6 +109,26 @@ static void gen_exception_debug(void) tcg_temp_free_i32(helper_tmp); } +/* Wrapper around tcg_gen_exit_tb that handles single stepping */ +static void exit_tb(DisasContext *ctx) +{ + if (ctx->base.singlestep_enabled) { + gen_exception_debug(); + } else { + tcg_gen_exit_tb(NULL, 0); + } +} + +/* Wrapper around tcg_gen_lookup_and_goto_ptr that handles single stepping */ +static void lookup_and_goto_ptr(DisasContext *ctx) +{ + if (ctx->base.singlestep_enabled) { + gen_exception_debug(); + } else { + tcg_gen_lookup_and_goto_ptr(); + } +} + static void gen_exception_illegal(DisasContext *ctx) { generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST); @@ -138,14 +158,14 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) /* chaining is only allowed when the jump is to the same page */ tcg_gen_goto_tb(n); tcg_gen_movi_tl(cpu_pc, dest); + + /* No need to check for single stepping here as use_goto_tb() will + * return false in case of single stepping. + */ tcg_gen_exit_tb(ctx->base.tb, n); } else { tcg_gen_movi_tl(cpu_pc, dest); - if (ctx->base.singlestep_enabled) { - gen_exception_debug(); - } else { - tcg_gen_lookup_and_goto_ptr(); - } + lookup_and_goto_ptr(ctx); } } -- cgit v1.1 From e761799796ac2211b9706753c459e117e7be58fa Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 1 Apr 2019 10:11:48 +0700 Subject: target/riscv: Name the argument sets for all of insn32 formats Signed-off-by: Richard Henderson Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/insn32.decode | 10 +++++++--- target/riscv/translate.c | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) (limited to 'target') diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 6f3ab7a..77f794e 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -34,9 +34,13 @@ %imm_u 12:s20 !function=ex_shift_12 # Argument sets: +&empty &b imm rs2 rs1 &i imm rs1 rd +&j imm rd &r rd rs1 rs2 +&s imm rs1 rs2 +&u imm rd &shift shamt rs1 rd &atomic aq rl rs2 rs1 rd @@ -44,9 +48,9 @@ @r ....... ..... ..... ... ..... ....... &r %rs2 %rs1 %rd @i ............ ..... ... ..... ....... &i imm=%imm_i %rs1 %rd @b ....... ..... ..... ... ..... ....... &b imm=%imm_b %rs2 %rs1 -@s ....... ..... ..... ... ..... ....... imm=%imm_s %rs2 %rs1 -@u .................... ..... ....... imm=%imm_u %rd -@j .................... ..... ....... imm=%imm_j %rd +@s ....... ..... ..... ... ..... ....... &s imm=%imm_s %rs2 %rs1 +@u .................... ..... ....... &u imm=%imm_u %rd +@j .................... ..... ....... &j imm=%imm_j %rd @sh ...... ...... ..... ... ..... ....... &shift shamt=%sh10 %rs1 %rd @csr ............ ..... ... ..... ....... %csr %rs1 %rd diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 840ecbe..9283742 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -687,11 +687,29 @@ static bool gen_shift(DisasContext *ctx, arg_r *a, #include "insn_trans/trans_rvd.inc.c" #include "insn_trans/trans_privileged.inc.c" +/* + * Auto-generated decoder. + * Note that the 16-bit decoder reuses some of the trans_* functions + * initially declared by the 32-bit decoder, which results in duplicate + * declaration warnings. Suppress them. + */ +#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wredundant-decls" +# ifdef __clang__ +# pragma GCC diagnostic ignored "-Wtypedef-redefinition" +# endif +#endif + bool decode_insn16(DisasContext *ctx, uint16_t insn); /* auto-generated decoder*/ #include "decode_insn16.inc.c" #include "insn_trans/trans_rvc.inc.c" +#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE +# pragma GCC diagnostic pop +#endif + static void decode_opc(DisasContext *ctx) { /* check for compressed insn */ -- cgit v1.1 From 81770255581bd210c57b86a6e808628ab8d0c543 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 1 Apr 2019 10:11:49 +0700 Subject: target/riscv: Use --static-decode for decodetree The generated functions are only used within translate.c and do not need to be global, or declared. Signed-off-by: Richard Henderson Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/Makefile.objs | 8 ++++---- target/riscv/translate.c | 3 --- 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'target') diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs index 9c6c109..c7a1b06 100644 --- a/target/riscv/Makefile.objs +++ b/target/riscv/Makefile.objs @@ -7,14 +7,14 @@ decode32-$(TARGET_RISCV64) += $(SRC_PATH)/target/riscv/insn32-64.decode target/riscv/decode_insn32.inc.c: $(decode32-y) $(DECODETREE) $(call quiet-command, \ - $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn32 $(decode32-y), \ - "GEN", $(TARGET_DIR)$@) + $(PYTHON) $(DECODETREE) -o $@ --static-decode decode_insn32 \ + $(decode32-y), "GEN", $(TARGET_DIR)$@) target/riscv/decode_insn16.inc.c: \ $(SRC_PATH)/target/riscv/insn16.decode $(DECODETREE) $(call quiet-command, \ - $(PYTHON) $(DECODETREE) -o $@ --decode decode_insn16 --insnwidth 16 $<, \ - "GEN", $(TARGET_DIR)$@) + $(PYTHON) $(DECODETREE) -o $@ --static-decode decode_insn16 \ + --insnwidth 16 $<, "GEN", $(TARGET_DIR)$@) target/riscv/translate.o: target/riscv/decode_insn32.inc.c \ target/riscv/decode_insn16.inc.c diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 9283742..b091581 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -558,7 +558,6 @@ static int ex_rvc_register(DisasContext *ctx, int reg) return 8 + reg; } -bool decode_insn32(DisasContext *ctx, uint32_t insn); /* Include the auto-generated decoder for 32 bit insn */ #include "decode_insn32.inc.c" @@ -701,8 +700,6 @@ static bool gen_shift(DisasContext *ctx, arg_r *a, # endif #endif -bool decode_insn16(DisasContext *ctx, uint16_t insn); -/* auto-generated decoder*/ #include "decode_insn16.inc.c" #include "insn_trans/trans_rvc.inc.c" -- cgit v1.1 From e1d455dd91c935c714412dafeb24db947429a929 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 1 Apr 2019 10:11:50 +0700 Subject: target/riscv: Merge argument sets for insn32 and insn16 In some cases this allows us to directly use the insn32 translator function. In some cases we still need a shim. Signed-off-by: Richard Henderson Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/insn16.decode | 84 +++++++++++-------- target/riscv/insn_trans/trans_rvc.inc.c | 144 +++----------------------------- 2 files changed, 58 insertions(+), 170 deletions(-) (limited to 'target') diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode index 17cc52c..d0cc778 100644 --- a/target/riscv/insn16.decode +++ b/target/riscv/insn16.decode @@ -40,17 +40,24 @@ %imm_lui 12:s1 2:5 !function=ex_shift_12 +# Argument sets imported from insn32.decode: +&empty !extern +&r rd rs1 rs2 !extern +&i imm rs1 rd !extern +&s imm rs1 rs2 !extern +&j imm rd !extern +&b imm rs2 rs1 !extern +&u imm rd !extern +&shift shamt rs1 rd !extern # Argument sets: &cl rs1 rd &cl_dw uimm rs1 rd -&ci imm rd &ciw nzuimm rd &cs rs1 rs2 &cs_dw uimm rs1 rs2 &cb imm rs1 &cr rd rs2 -&cj imm &c_shift shamt rd &c_ld uimm rd @@ -61,23 +68,24 @@ &cfswsp_sdsp uimm_fswsp uimm_sdsp rs2 # Formats 16: -@cr .... ..... ..... .. &cr rs2=%rs2_5 %rd -@ci ... . ..... ..... .. &ci imm=%imm_ci %rd +@cr .... ..... ..... .. &r rs2=%rs2_5 rs1=%rd %rd +@ci ... . ..... ..... .. &i imm=%imm_ci rs1=%rd %rd @ciw ... ........ ... .. &ciw nzuimm=%nzuimm_ciw rd=%rs2_3 -@cl_d ... ... ... .. ... .. &cl_dw uimm=%uimm_cl_d rs1=%rs1_3 rd=%rs2_3 -@cl_w ... ... ... .. ... .. &cl_dw uimm=%uimm_cl_w rs1=%rs1_3 rd=%rs2_3 +@cl_d ... ... ... .. ... .. &i imm=%uimm_cl_d rs1=%rs1_3 rd=%rs2_3 +@cl_w ... ... ... .. ... .. &i imm=%uimm_cl_w rs1=%rs1_3 rd=%rs2_3 @cl ... ... ... .. ... .. &cl rs1=%rs1_3 rd=%rs2_3 @cs ... ... ... .. ... .. &cs rs1=%rs1_3 rs2=%rs2_3 -@cs_2 ... ... ... .. ... .. &cr rd=%rs1_3 rs2=%rs2_3 -@cs_d ... ... ... .. ... .. &cs_dw uimm=%uimm_cl_d rs1=%rs1_3 rs2=%rs2_3 -@cs_w ... ... ... .. ... .. &cs_dw uimm=%uimm_cl_w rs1=%rs1_3 rs2=%rs2_3 -@cb ... ... ... .. ... .. &cb imm=%imm_cb rs1=%rs1_3 -@cj ... ........... .. &cj imm=%imm_cj - -@c_ld ... . ..... ..... .. &c_ld uimm=%uimm_6bit_ld %rd -@c_lw ... . ..... ..... .. &c_ld uimm=%uimm_6bit_lw %rd -@c_sd ... . ..... ..... .. &c_sd uimm=%uimm_6bit_sd rs2=%rs2_5 -@c_sw ... . ..... ..... .. &c_sd uimm=%uimm_6bit_sw rs2=%rs2_5 +@cs_2 ... ... ... .. ... .. &r rs2=%rs2_3 rs1=%rs1_3 rd=%rs1_3 +@cs_d ... ... ... .. ... .. &s imm=%uimm_cl_d rs1=%rs1_3 rs2=%rs2_3 +@cs_w ... ... ... .. ... .. &s imm=%uimm_cl_w rs1=%rs1_3 rs2=%rs2_3 +@cj ... ........... .. &j imm=%imm_cj +@cb_z ... ... ... .. ... .. &b imm=%imm_cb rs1=%rs1_3 rs2=0 + +@c_ldsp ... . ..... ..... .. &i imm=%uimm_6bit_ld rs1=2 %rd +@c_lwsp ... . ..... ..... .. &i imm=%uimm_6bit_lw rs1=2 %rd +@c_sdsp ... . ..... ..... .. &s imm=%uimm_6bit_sd rs1=2 rs2=%rs2_5 +@c_swsp ... . ..... ..... .. &s imm=%uimm_6bit_sw rs1=2 rs2=%rs2_5 +@c_li ... . ..... ..... .. &i imm=%imm_ci rs1=0 %rd @c_addi16sp_lui ... . ..... ..... .. &caddi16sp_lui %imm_lui %imm_addi16sp %rd @c_flwsp_ldsp ... . ..... ..... .. &cflwsp_ldsp uimm_flwsp=%uimm_6bit_lw \ @@ -85,45 +93,47 @@ @c_fswsp_sdsp ... . ..... ..... .. &cfswsp_sdsp uimm_fswsp=%uimm_6bit_sw \ uimm_sdsp=%uimm_6bit_sd rs2=%rs2_5 -@c_shift ... . .. ... ..... .. &c_shift rd=%rs1_3 shamt=%nzuimm_6bit -@c_shift2 ... . .. ... ..... .. &c_shift rd=%rd shamt=%nzuimm_6bit +@c_shift ... . .. ... ..... .. \ + &shift rd=%rs1_3 rs1=%rs1_3 shamt=%nzuimm_6bit +@c_shift2 ... . .. ... ..... .. \ + &shift rd=%rd rs1=%rd shamt=%nzuimm_6bit -@c_andi ... . .. ... ..... .. &ci imm=%imm_ci rd=%rs1_3 +@c_andi ... . .. ... ..... .. &i imm=%imm_ci rs1=%rs1_3 rd=%rs1_3 # *** RV64C Standard Extension (Quadrant 0) *** c_addi4spn 000 ........ ... 00 @ciw -c_fld 001 ... ... .. ... 00 @cl_d -c_lw 010 ... ... .. ... 00 @cl_w +fld 001 ... ... .. ... 00 @cl_d +lw 010 ... ... .. ... 00 @cl_w c_flw_ld 011 --- ... -- ... 00 @cl #Note: Must parse uimm manually -c_fsd 101 ... ... .. ... 00 @cs_d -c_sw 110 ... ... .. ... 00 @cs_w +fsd 101 ... ... .. ... 00 @cs_d +sw 110 ... ... .. ... 00 @cs_w c_fsw_sd 111 --- ... -- ... 00 @cs #Note: Must parse uimm manually # *** RV64C Standard Extension (Quadrant 1) *** -c_addi 000 . ..... ..... 01 @ci +addi 000 . ..... ..... 01 @ci c_jal_addiw 001 . ..... ..... 01 @ci #Note: parse rd and/or imm manually -c_li 010 . ..... ..... 01 @ci +addi 010 . ..... ..... 01 @c_li c_addi16sp_lui 011 . ..... ..... 01 @c_addi16sp_lui # shares opc with C.LUI c_srli 100 . 00 ... ..... 01 @c_shift c_srai 100 . 01 ... ..... 01 @c_shift -c_andi 100 . 10 ... ..... 01 @c_andi -c_sub 100 0 11 ... 00 ... 01 @cs_2 -c_xor 100 0 11 ... 01 ... 01 @cs_2 -c_or 100 0 11 ... 10 ... 01 @cs_2 -c_and 100 0 11 ... 11 ... 01 @cs_2 +andi 100 . 10 ... ..... 01 @c_andi +sub 100 0 11 ... 00 ... 01 @cs_2 +xor 100 0 11 ... 01 ... 01 @cs_2 +or 100 0 11 ... 10 ... 01 @cs_2 +and 100 0 11 ... 11 ... 01 @cs_2 c_subw 100 1 11 ... 00 ... 01 @cs_2 c_addw 100 1 11 ... 01 ... 01 @cs_2 -c_j 101 ........... 01 @cj -c_beqz 110 ... ... ..... 01 @cb -c_bnez 111 ... ... ..... 01 @cb +jal 101 ........... 01 @cj rd=0 # C.J +beq 110 ... ... ..... 01 @cb_z +bne 111 ... ... ..... 01 @cb_z # *** RV64C Standard Extension (Quadrant 2) *** c_slli 000 . ..... ..... 10 @c_shift2 -c_fldsp 001 . ..... ..... 10 @c_ld -c_lwsp 010 . ..... ..... 10 @c_lw +fld 001 . ..... ..... 10 @c_ldsp +lw 010 . ..... ..... 10 @c_lwsp c_flwsp_ldsp 011 . ..... ..... 10 @c_flwsp_ldsp #C.LDSP:RV64;C.FLWSP:RV32 c_jr_mv 100 0 ..... ..... 10 @cr c_ebreak_jalr_add 100 1 ..... ..... 10 @cr -c_fsdsp 101 ...... ..... 10 @c_sd -c_swsp 110 . ..... ..... 10 @c_sw +fsd 101 ...... ..... 10 @c_sdsp +sw 110 . ..... ..... 10 @c_swsp c_fswsp_sdsp 111 . ..... ..... 10 @c_fswsp_sdsp #C.SDSP:RV64;C.FSWSP:RV32 diff --git a/target/riscv/insn_trans/trans_rvc.inc.c b/target/riscv/insn_trans/trans_rvc.inc.c index 3e5d6fd..e840ac4 100644 --- a/target/riscv/insn_trans/trans_rvc.inc.c +++ b/target/riscv/insn_trans/trans_rvc.inc.c @@ -28,18 +28,6 @@ static bool trans_c_addi4spn(DisasContext *ctx, arg_c_addi4spn *a) return trans_addi(ctx, &arg); } -static bool trans_c_fld(DisasContext *ctx, arg_c_fld *a) -{ - arg_fld arg = { .rd = a->rd, .rs1 = a->rs1, .imm = a->uimm }; - return trans_fld(ctx, &arg); -} - -static bool trans_c_lw(DisasContext *ctx, arg_c_lw *a) -{ - arg_lw arg = { .rd = a->rd, .rs1 = a->rs1, .imm = a->uimm }; - return trans_lw(ctx, &arg); -} - static bool trans_c_flw_ld(DisasContext *ctx, arg_c_flw_ld *a) { #ifdef TARGET_RISCV32 @@ -47,31 +35,17 @@ static bool trans_c_flw_ld(DisasContext *ctx, arg_c_flw_ld *a) REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); - arg_c_lw tmp; - decode_insn16_extract_cl_w(ctx, &tmp, ctx->opcode); - arg_flw arg = { .rd = tmp.rd, .rs1 = tmp.rs1, .imm = tmp.uimm }; + arg_i arg; + decode_insn16_extract_cl_w(ctx, &arg, ctx->opcode); return trans_flw(ctx, &arg); #else /* C.LD ( RV64C/RV128C-only ) */ - arg_c_fld tmp; - decode_insn16_extract_cl_d(ctx, &tmp, ctx->opcode); - arg_ld arg = { .rd = tmp.rd, .rs1 = tmp.rs1, .imm = tmp.uimm }; + arg_i arg; + decode_insn16_extract_cl_d(ctx, &arg, ctx->opcode); return trans_ld(ctx, &arg); #endif } -static bool trans_c_fsd(DisasContext *ctx, arg_c_fsd *a) -{ - arg_fsd arg = { .rs1 = a->rs1, .rs2 = a->rs2, .imm = a->uimm }; - return trans_fsd(ctx, &arg); -} - -static bool trans_c_sw(DisasContext *ctx, arg_c_sw *a) -{ - arg_sw arg = { .rs1 = a->rs1, .rs2 = a->rs2, .imm = a->uimm }; - return trans_sw(ctx, &arg); -} - static bool trans_c_fsw_sd(DisasContext *ctx, arg_c_fsw_sd *a) { #ifdef TARGET_RISCV32 @@ -79,34 +53,22 @@ static bool trans_c_fsw_sd(DisasContext *ctx, arg_c_fsw_sd *a) REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); - arg_c_sw tmp; - decode_insn16_extract_cs_w(ctx, &tmp, ctx->opcode); - arg_fsw arg = { .rs1 = tmp.rs1, .rs2 = tmp.rs2, .imm = tmp.uimm }; + arg_s arg; + decode_insn16_extract_cs_w(ctx, &arg, ctx->opcode); return trans_fsw(ctx, &arg); #else /* C.SD ( RV64C/RV128C-only ) */ - arg_c_fsd tmp; - decode_insn16_extract_cs_d(ctx, &tmp, ctx->opcode); - arg_sd arg = { .rs1 = tmp.rs1, .rs2 = tmp.rs2, .imm = tmp.uimm }; + arg_s arg; + decode_insn16_extract_cs_d(ctx, &arg, ctx->opcode); return trans_sd(ctx, &arg); #endif } -static bool trans_c_addi(DisasContext *ctx, arg_c_addi *a) -{ - if (a->imm == 0) { - /* Hint: insn is valid but does not affect state */ - return true; - } - arg_addi arg = { .rd = a->rd, .rs1 = a->rd, .imm = a->imm }; - return trans_addi(ctx, &arg); -} - static bool trans_c_jal_addiw(DisasContext *ctx, arg_c_jal_addiw *a) { #ifdef TARGET_RISCV32 /* C.JAL */ - arg_c_j tmp; + arg_j tmp; decode_insn16_extract_cj(ctx, &tmp, ctx->opcode); arg_jal arg = { .rd = 1, .imm = tmp.imm }; return trans_jal(ctx, &arg); @@ -117,16 +79,6 @@ static bool trans_c_jal_addiw(DisasContext *ctx, arg_c_jal_addiw *a) #endif } -static bool trans_c_li(DisasContext *ctx, arg_c_li *a) -{ - if (a->rd == 0) { - /* Hint: insn is valid but does not affect state */ - return true; - } - arg_addi arg = { .rd = a->rd, .rs1 = 0, .imm = a->imm }; - return trans_addi(ctx, &arg); -} - static bool trans_c_addi16sp_lui(DisasContext *ctx, arg_c_addi16sp_lui *a) { if (a->rd == 2) { @@ -177,41 +129,10 @@ static bool trans_c_srai(DisasContext *ctx, arg_c_srai *a) return trans_srai(ctx, &arg); } -static bool trans_c_andi(DisasContext *ctx, arg_c_andi *a) -{ - arg_andi arg = { .rd = a->rd, .rs1 = a->rd, .imm = a->imm }; - return trans_andi(ctx, &arg); -} - -static bool trans_c_sub(DisasContext *ctx, arg_c_sub *a) -{ - arg_sub arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 }; - return trans_sub(ctx, &arg); -} - -static bool trans_c_xor(DisasContext *ctx, arg_c_xor *a) -{ - arg_xor arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 }; - return trans_xor(ctx, &arg); -} - -static bool trans_c_or(DisasContext *ctx, arg_c_or *a) -{ - arg_or arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 }; - return trans_or(ctx, &arg); -} - -static bool trans_c_and(DisasContext *ctx, arg_c_and *a) -{ - arg_and arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 }; - return trans_and(ctx, &arg); -} - static bool trans_c_subw(DisasContext *ctx, arg_c_subw *a) { #ifdef TARGET_RISCV64 - arg_subw arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 }; - return trans_subw(ctx, &arg); + return trans_subw(ctx, a); #else return false; #endif @@ -220,31 +141,12 @@ static bool trans_c_subw(DisasContext *ctx, arg_c_subw *a) static bool trans_c_addw(DisasContext *ctx, arg_c_addw *a) { #ifdef TARGET_RISCV64 - arg_addw arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 }; - return trans_addw(ctx, &arg); + return trans_addw(ctx, a); #else return false; #endif } -static bool trans_c_j(DisasContext *ctx, arg_c_j *a) -{ - arg_jal arg = { .rd = 0, .imm = a->imm }; - return trans_jal(ctx, &arg); -} - -static bool trans_c_beqz(DisasContext *ctx, arg_c_beqz *a) -{ - arg_beq arg = { .rs1 = a->rs1, .rs2 = 0, .imm = a->imm }; - return trans_beq(ctx, &arg); -} - -static bool trans_c_bnez(DisasContext *ctx, arg_c_bnez *a) -{ - arg_bne arg = { .rs1 = a->rs1, .rs2 = 0, .imm = a->imm }; - return trans_bne(ctx, &arg); -} - static bool trans_c_slli(DisasContext *ctx, arg_c_slli *a) { int shamt = a->shamt; @@ -261,18 +163,6 @@ static bool trans_c_slli(DisasContext *ctx, arg_c_slli *a) return trans_slli(ctx, &arg); } -static bool trans_c_fldsp(DisasContext *ctx, arg_c_fldsp *a) -{ - arg_fld arg = { .rd = a->rd, .rs1 = 2, .imm = a->uimm }; - return trans_fld(ctx, &arg); -} - -static bool trans_c_lwsp(DisasContext *ctx, arg_c_lwsp *a) -{ - arg_lw arg = { .rd = a->rd, .rs1 = 2, .imm = a->uimm }; - return trans_lw(ctx, &arg); -} - static bool trans_c_flwsp_ldsp(DisasContext *ctx, arg_c_flwsp_ldsp *a) { #ifdef TARGET_RISCV32 @@ -321,18 +211,6 @@ static bool trans_c_ebreak_jalr_add(DisasContext *ctx, arg_c_ebreak_jalr_add *a) return false; } -static bool trans_c_fsdsp(DisasContext *ctx, arg_c_fsdsp *a) -{ - arg_fsd arg = { .rs1 = 2, .rs2 = a->rs2, .imm = a->uimm }; - return trans_fsd(ctx, &arg); -} - -static bool trans_c_swsp(DisasContext *ctx, arg_c_swsp *a) -{ - arg_sw arg = { .rs1 = 2, .rs2 = a->rs2, .imm = a->uimm }; - return trans_sw(ctx, &arg); -} - static bool trans_c_fswsp_sdsp(DisasContext *ctx, arg_c_fswsp_sdsp *a) { #ifdef TARGET_RISCV32 -- cgit v1.1 From 6cafec92f1c862a9754ef6a28be68ba7178a284d Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 1 Apr 2019 10:11:51 +0700 Subject: target/riscv: Merge argument decode for RVC shifti Special handling for IMM==0 is the only difference between RVC shifti and RVI shifti. This can be handled with !function. Signed-off-by: Richard Henderson Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/insn16.decode | 12 ++++----- target/riscv/insn_trans/trans_rvc.inc.c | 47 --------------------------------- target/riscv/translate.c | 6 +++++ 3 files changed, 12 insertions(+), 53 deletions(-) (limited to 'target') diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode index d0cc778..add9cf3 100644 --- a/target/riscv/insn16.decode +++ b/target/riscv/insn16.decode @@ -30,7 +30,7 @@ %imm_cb 12:s1 5:2 2:1 10:2 3:2 !function=ex_shift_1 %imm_cj 12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1 -%nzuimm_6bit 12:1 2:5 +%shimm_6bit 12:1 2:5 !function=ex_rvc_shifti %uimm_6bit_ld 2:3 12:1 5:2 !function=ex_shift_3 %uimm_6bit_lw 2:2 12:1 4:3 !function=ex_shift_2 %uimm_6bit_sd 7:3 10:3 !function=ex_shift_3 @@ -94,9 +94,9 @@ uimm_sdsp=%uimm_6bit_sd rs2=%rs2_5 @c_shift ... . .. ... ..... .. \ - &shift rd=%rs1_3 rs1=%rs1_3 shamt=%nzuimm_6bit + &shift rd=%rs1_3 rs1=%rs1_3 shamt=%shimm_6bit @c_shift2 ... . .. ... ..... .. \ - &shift rd=%rd rs1=%rd shamt=%nzuimm_6bit + &shift rd=%rd rs1=%rd shamt=%shimm_6bit @c_andi ... . .. ... ..... .. &i imm=%imm_ci rs1=%rs1_3 rd=%rs1_3 @@ -114,8 +114,8 @@ addi 000 . ..... ..... 01 @ci c_jal_addiw 001 . ..... ..... 01 @ci #Note: parse rd and/or imm manually addi 010 . ..... ..... 01 @c_li c_addi16sp_lui 011 . ..... ..... 01 @c_addi16sp_lui # shares opc with C.LUI -c_srli 100 . 00 ... ..... 01 @c_shift -c_srai 100 . 01 ... ..... 01 @c_shift +srli 100 . 00 ... ..... 01 @c_shift +srai 100 . 01 ... ..... 01 @c_shift andi 100 . 10 ... ..... 01 @c_andi sub 100 0 11 ... 00 ... 01 @cs_2 xor 100 0 11 ... 01 ... 01 @cs_2 @@ -128,7 +128,7 @@ beq 110 ... ... ..... 01 @cb_z bne 111 ... ... ..... 01 @cb_z # *** RV64C Standard Extension (Quadrant 2) *** -c_slli 000 . ..... ..... 10 @c_shift2 +slli 000 . ..... ..... 10 @c_shift2 fld 001 . ..... ..... 10 @c_ldsp lw 010 . ..... ..... 10 @c_lwsp c_flwsp_ldsp 011 . ..... ..... 10 @c_flwsp_ldsp #C.LDSP:RV64;C.FLWSP:RV32 diff --git a/target/riscv/insn_trans/trans_rvc.inc.c b/target/riscv/insn_trans/trans_rvc.inc.c index e840ac4..dbe9624 100644 --- a/target/riscv/insn_trans/trans_rvc.inc.c +++ b/target/riscv/insn_trans/trans_rvc.inc.c @@ -97,37 +97,6 @@ static bool trans_c_addi16sp_lui(DisasContext *ctx, arg_c_addi16sp_lui *a) return false; } -static bool trans_c_srli(DisasContext *ctx, arg_c_srli *a) -{ - int shamt = a->shamt; - if (shamt == 0) { - /* For RV128 a shamt of 0 means a shift by 64 */ - shamt = 64; - } - /* Ensure, that shamt[5] is zero for RV32 */ - if (shamt >= TARGET_LONG_BITS) { - return false; - } - - arg_srli arg = { .rd = a->rd, .rs1 = a->rd, .shamt = a->shamt }; - return trans_srli(ctx, &arg); -} - -static bool trans_c_srai(DisasContext *ctx, arg_c_srai *a) -{ - int shamt = a->shamt; - if (shamt == 0) { - /* For RV128 a shamt of 0 means a shift by 64 */ - shamt = 64; - } - /* Ensure, that shamt[5] is zero for RV32 */ - if (shamt >= TARGET_LONG_BITS) { - return false; - } - - arg_srai arg = { .rd = a->rd, .rs1 = a->rd, .shamt = a->shamt }; - return trans_srai(ctx, &arg); -} static bool trans_c_subw(DisasContext *ctx, arg_c_subw *a) { @@ -147,22 +116,6 @@ static bool trans_c_addw(DisasContext *ctx, arg_c_addw *a) #endif } -static bool trans_c_slli(DisasContext *ctx, arg_c_slli *a) -{ - int shamt = a->shamt; - if (shamt == 0) { - /* For RV128 a shamt of 0 means a shift by 64 */ - shamt = 64; - } - /* Ensure, that shamt[5] is zero for RV32 */ - if (shamt >= TARGET_LONG_BITS) { - return false; - } - - arg_slli arg = { .rd = a->rd, .rs1 = a->rd, .shamt = a->shamt }; - return trans_slli(ctx, &arg); -} - static bool trans_c_flwsp_ldsp(DisasContext *ctx, arg_c_flwsp_ldsp *a) { #ifdef TARGET_RISCV32 diff --git a/target/riscv/translate.c b/target/riscv/translate.c index b091581..4cdffb2 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -558,6 +558,12 @@ static int ex_rvc_register(DisasContext *ctx, int reg) return 8 + reg; } +static int ex_rvc_shifti(DisasContext *ctx, int imm) +{ + /* For RV128 a shamt of 0 means a shift by 64. */ + return imm ? imm : 64; +} + /* Include the auto-generated decoder for 32 bit insn */ #include "decode_insn32.inc.c" -- cgit v1.1 From c2cfb97c01a3636867c1a4a24f8a99fd8c6bed28 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 1 Apr 2019 10:11:52 +0700 Subject: target/riscv: Use pattern groups in insn16.decode This eliminates about half of the complicated decode bits within insn_trans/trans_rvc.inc.c. Signed-off-by: Richard Henderson Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/insn16.decode | 29 +++++++++++---- target/riscv/insn_trans/trans_rvc.inc.c | 63 --------------------------------- target/riscv/insn_trans/trans_rvi.inc.c | 6 ++++ 3 files changed, 29 insertions(+), 69 deletions(-) (limited to 'target') diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode index add9cf3..3c79edf 100644 --- a/target/riscv/insn16.decode +++ b/target/riscv/insn16.decode @@ -70,7 +70,6 @@ # Formats 16: @cr .... ..... ..... .. &r rs2=%rs2_5 rs1=%rd %rd @ci ... . ..... ..... .. &i imm=%imm_ci rs1=%rd %rd -@ciw ... ........ ... .. &ciw nzuimm=%nzuimm_ciw rd=%rs2_3 @cl_d ... ... ... .. ... .. &i imm=%uimm_cl_d rs1=%rs1_3 rd=%rs2_3 @cl_w ... ... ... .. ... .. &i imm=%uimm_cl_w rs1=%rs1_3 rd=%rs2_3 @cl ... ... ... .. ... .. &cl rs1=%rs1_3 rd=%rs2_3 @@ -86,8 +85,12 @@ @c_sdsp ... . ..... ..... .. &s imm=%uimm_6bit_sd rs1=2 rs2=%rs2_5 @c_swsp ... . ..... ..... .. &s imm=%uimm_6bit_sw rs1=2 rs2=%rs2_5 @c_li ... . ..... ..... .. &i imm=%imm_ci rs1=0 %rd +@c_lui ... . ..... ..... .. &u imm=%imm_lui %rd +@c_jalr ... . ..... ..... .. &i imm=0 rs1=%rd +@c_mv ... . ..... ..... .. &i imm=0 rs1=%rs2_5 %rd -@c_addi16sp_lui ... . ..... ..... .. &caddi16sp_lui %imm_lui %imm_addi16sp %rd +@c_addi4spn ... . ..... ..... .. &i imm=%nzuimm_ciw rs1=2 rd=%rs2_3 +@c_addi16sp ... . ..... ..... .. &i imm=%imm_addi16sp rs1=2 rd=2 @c_flwsp_ldsp ... . ..... ..... .. &cflwsp_ldsp uimm_flwsp=%uimm_6bit_lw \ uimm_ldsp=%uimm_6bit_ld %rd @c_fswsp_sdsp ... . ..... ..... .. &cfswsp_sdsp uimm_fswsp=%uimm_6bit_sw \ @@ -101,7 +104,11 @@ @c_andi ... . .. ... ..... .. &i imm=%imm_ci rs1=%rs1_3 rd=%rs1_3 # *** RV64C Standard Extension (Quadrant 0) *** -c_addi4spn 000 ........ ... 00 @ciw +{ + # Opcode of all zeros is illegal; rd != 0, nzuimm == 0 is reserved. + illegal 000 000 000 00 --- 00 + addi 000 ... ... .. ... 00 @c_addi4spn +} fld 001 ... ... .. ... 00 @cl_d lw 010 ... ... .. ... 00 @cl_w c_flw_ld 011 --- ... -- ... 00 @cl #Note: Must parse uimm manually @@ -113,7 +120,10 @@ c_fsw_sd 111 --- ... -- ... 00 @cs #Note: Must parse uimm manually addi 000 . ..... ..... 01 @ci c_jal_addiw 001 . ..... ..... 01 @ci #Note: parse rd and/or imm manually addi 010 . ..... ..... 01 @c_li -c_addi16sp_lui 011 . ..... ..... 01 @c_addi16sp_lui # shares opc with C.LUI +{ + addi 011 . 00010 ..... 01 @c_addi16sp + lui 011 . ..... ..... 01 @c_lui +} srli 100 . 00 ... ..... 01 @c_shift srai 100 . 01 ... ..... 01 @c_shift andi 100 . 10 ... ..... 01 @c_andi @@ -132,8 +142,15 @@ slli 000 . ..... ..... 10 @c_shift2 fld 001 . ..... ..... 10 @c_ldsp lw 010 . ..... ..... 10 @c_lwsp c_flwsp_ldsp 011 . ..... ..... 10 @c_flwsp_ldsp #C.LDSP:RV64;C.FLWSP:RV32 -c_jr_mv 100 0 ..... ..... 10 @cr -c_ebreak_jalr_add 100 1 ..... ..... 10 @cr +{ + jalr 100 0 ..... 00000 10 @c_jalr rd=0 # C.JR + addi 100 0 ..... ..... 10 @c_mv +} +{ + ebreak 100 1 00000 00000 10 + jalr 100 1 ..... 00000 10 @c_jalr rd=1 # C.JALR + add 100 1 ..... ..... 10 @cr +} fsd 101 ...... ..... 10 @c_sdsp sw 110 . ..... ..... 10 @c_swsp c_fswsp_sdsp 111 . ..... ..... 10 @c_fswsp_sdsp #C.SDSP:RV64;C.FSWSP:RV32 diff --git a/target/riscv/insn_trans/trans_rvc.inc.c b/target/riscv/insn_trans/trans_rvc.inc.c index dbe9624..3fe6ad9 100644 --- a/target/riscv/insn_trans/trans_rvc.inc.c +++ b/target/riscv/insn_trans/trans_rvc.inc.c @@ -18,16 +18,6 @@ * this program. If not, see . */ -static bool trans_c_addi4spn(DisasContext *ctx, arg_c_addi4spn *a) -{ - if (a->nzuimm == 0) { - /* Reserved in ISA */ - return false; - } - arg_addi arg = { .rd = a->rd, .rs1 = 2, .imm = a->nzuimm }; - return trans_addi(ctx, &arg); -} - static bool trans_c_flw_ld(DisasContext *ctx, arg_c_flw_ld *a) { #ifdef TARGET_RISCV32 @@ -79,25 +69,6 @@ static bool trans_c_jal_addiw(DisasContext *ctx, arg_c_jal_addiw *a) #endif } -static bool trans_c_addi16sp_lui(DisasContext *ctx, arg_c_addi16sp_lui *a) -{ - if (a->rd == 2) { - /* C.ADDI16SP */ - arg_addi arg = { .rd = 2, .rs1 = 2, .imm = a->imm_addi16sp }; - return trans_addi(ctx, &arg); - } else if (a->imm_lui != 0) { - /* C.LUI */ - if (a->rd == 0) { - /* Hint: insn is valid but does not affect state */ - return true; - } - arg_lui arg = { .rd = a->rd, .imm = a->imm_lui }; - return trans_lui(ctx, &arg); - } - return false; -} - - static bool trans_c_subw(DisasContext *ctx, arg_c_subw *a) { #ifdef TARGET_RISCV64 @@ -130,40 +101,6 @@ static bool trans_c_flwsp_ldsp(DisasContext *ctx, arg_c_flwsp_ldsp *a) return false; } -static bool trans_c_jr_mv(DisasContext *ctx, arg_c_jr_mv *a) -{ - if (a->rd != 0 && a->rs2 == 0) { - /* C.JR */ - arg_jalr arg = { .rd = 0, .rs1 = a->rd, .imm = 0 }; - return trans_jalr(ctx, &arg); - } else if (a->rd != 0 && a->rs2 != 0) { - /* C.MV */ - arg_add arg = { .rd = a->rd, .rs1 = 0, .rs2 = a->rs2 }; - return trans_add(ctx, &arg); - } - return false; -} - -static bool trans_c_ebreak_jalr_add(DisasContext *ctx, arg_c_ebreak_jalr_add *a) -{ - if (a->rd == 0 && a->rs2 == 0) { - /* C.EBREAK */ - arg_ebreak arg = { }; - return trans_ebreak(ctx, &arg); - } else if (a->rd != 0) { - if (a->rs2 == 0) { - /* C.JALR */ - arg_jalr arg = { .rd = 1, .rs1 = a->rd, .imm = 0 }; - return trans_jalr(ctx, &arg); - } else { - /* C.ADD */ - arg_add arg = { .rd = a->rd, .rs1 = a->rd, .rs2 = a->rs2 }; - return trans_add(ctx, &arg); - } - } - return false; -} - static bool trans_c_fswsp_sdsp(DisasContext *ctx, arg_c_fswsp_sdsp *a) { #ifdef TARGET_RISCV32 diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c index 37b0b9d..b5a5b4a 100644 --- a/target/riscv/insn_trans/trans_rvi.inc.c +++ b/target/riscv/insn_trans/trans_rvi.inc.c @@ -18,6 +18,12 @@ * this program. If not, see . */ +static bool trans_illegal(DisasContext *ctx, arg_empty *a) +{ + gen_exception_illegal(ctx); + return true; +} + static bool trans_lui(DisasContext *ctx, arg_lui *a) { if (a->rd != 0) { -- cgit v1.1 From 0e68e240a9bd3b44a91cd6012f0e2bf2a43b9fe2 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 1 Apr 2019 10:11:53 +0700 Subject: target/riscv: Split RVC32 and RVC64 insns into separate files This eliminates all functions in insn_trans/trans_rvc.inc.c, so the entire file can be removed. Signed-off-by: Richard Henderson Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/Makefile.objs | 9 ++- target/riscv/insn16-32.decode | 28 ++++++++ target/riscv/insn16-64.decode | 30 +++++++++ target/riscv/insn16.decode | 35 +--------- target/riscv/insn_trans/trans_rvc.inc.c | 115 -------------------------------- target/riscv/translate.c | 1 - 6 files changed, 67 insertions(+), 151 deletions(-) create mode 100644 target/riscv/insn16-32.decode create mode 100644 target/riscv/insn16-64.decode delete mode 100644 target/riscv/insn_trans/trans_rvc.inc.c (limited to 'target') diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs index c7a1b06..b1c79bc 100644 --- a/target/riscv/Makefile.objs +++ b/target/riscv/Makefile.objs @@ -5,16 +5,19 @@ DECODETREE = $(SRC_PATH)/scripts/decodetree.py decode32-y = $(SRC_PATH)/target/riscv/insn32.decode decode32-$(TARGET_RISCV64) += $(SRC_PATH)/target/riscv/insn32-64.decode +decode16-y = $(SRC_PATH)/target/riscv/insn16.decode +decode16-$(TARGET_RISCV32) += $(SRC_PATH)/target/riscv/insn16-32.decode +decode16-$(TARGET_RISCV64) += $(SRC_PATH)/target/riscv/insn16-64.decode + target/riscv/decode_insn32.inc.c: $(decode32-y) $(DECODETREE) $(call quiet-command, \ $(PYTHON) $(DECODETREE) -o $@ --static-decode decode_insn32 \ $(decode32-y), "GEN", $(TARGET_DIR)$@) -target/riscv/decode_insn16.inc.c: \ - $(SRC_PATH)/target/riscv/insn16.decode $(DECODETREE) +target/riscv/decode_insn16.inc.c: $(decode16-y) $(DECODETREE) $(call quiet-command, \ $(PYTHON) $(DECODETREE) -o $@ --static-decode decode_insn16 \ - --insnwidth 16 $<, "GEN", $(TARGET_DIR)$@) + --insnwidth 16 $(decode16-y), "GEN", $(TARGET_DIR)$@) target/riscv/translate.o: target/riscv/decode_insn32.inc.c \ target/riscv/decode_insn16.inc.c diff --git a/target/riscv/insn16-32.decode b/target/riscv/insn16-32.decode new file mode 100644 index 0000000..0819b17 --- /dev/null +++ b/target/riscv/insn16-32.decode @@ -0,0 +1,28 @@ +# +# RISC-V translation routines for the RVXI Base Integer Instruction Set. +# +# Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de +# Bastian Koppelmann, kbastian@mail.uni-paderborn.de +# +# 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 . + +# *** RV32C Standard Extension (Quadrant 0) *** +flw 011 ... ... .. ... 00 @cl_w +fsw 111 ... ... .. ... 00 @cs_w + +# *** RV32C Standard Extension (Quadrant 1) *** +jal 001 ........... 01 @cj rd=1 # C.JAL + +# *** RV32C Standard Extension (Quadrant 2) *** +flw 011 . ..... ..... 10 @c_lwsp +fsw 111 . ..... ..... 10 @c_swsp diff --git a/target/riscv/insn16-64.decode b/target/riscv/insn16-64.decode new file mode 100644 index 0000000..055859d --- /dev/null +++ b/target/riscv/insn16-64.decode @@ -0,0 +1,30 @@ +# +# RISC-V translation routines for the RVXI Base Integer Instruction Set. +# +# Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de +# Bastian Koppelmann, kbastian@mail.uni-paderborn.de +# +# 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 . + +# *** RV64C Standard Extension (Quadrant 0) *** +ld 011 ... ... .. ... 00 @cl_d +sd 111 ... ... .. ... 00 @cs_d + +# *** RV64C Standard Extension (Quadrant 1) *** +addiw 001 . ..... ..... 01 @ci +subw 100 1 11 ... 00 ... 01 @cs_2 +addw 100 1 11 ... 01 ... 01 @cs_2 + +# *** RV64C Standard Extension (Quadrant 2) *** +ld 011 . ..... ..... 10 @c_ldsp +sd 111 . ..... ..... 10 @c_sdsp diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode index 3c79edf..433c0e8 100644 --- a/target/riscv/insn16.decode +++ b/target/riscv/insn16.decode @@ -50,30 +50,12 @@ &u imm rd !extern &shift shamt rs1 rd !extern -# Argument sets: -&cl rs1 rd -&cl_dw uimm rs1 rd -&ciw nzuimm rd -&cs rs1 rs2 -&cs_dw uimm rs1 rs2 -&cb imm rs1 -&cr rd rs2 -&c_shift shamt rd - -&c_ld uimm rd -&c_sd uimm rs2 - -&caddi16sp_lui imm_lui imm_addi16sp rd -&cflwsp_ldsp uimm_flwsp uimm_ldsp rd -&cfswsp_sdsp uimm_fswsp uimm_sdsp rs2 # Formats 16: @cr .... ..... ..... .. &r rs2=%rs2_5 rs1=%rd %rd @ci ... . ..... ..... .. &i imm=%imm_ci rs1=%rd %rd @cl_d ... ... ... .. ... .. &i imm=%uimm_cl_d rs1=%rs1_3 rd=%rs2_3 @cl_w ... ... ... .. ... .. &i imm=%uimm_cl_w rs1=%rs1_3 rd=%rs2_3 -@cl ... ... ... .. ... .. &cl rs1=%rs1_3 rd=%rs2_3 -@cs ... ... ... .. ... .. &cs rs1=%rs1_3 rs2=%rs2_3 @cs_2 ... ... ... .. ... .. &r rs2=%rs2_3 rs1=%rs1_3 rd=%rs1_3 @cs_d ... ... ... .. ... .. &s imm=%uimm_cl_d rs1=%rs1_3 rs2=%rs2_3 @cs_w ... ... ... .. ... .. &s imm=%uimm_cl_w rs1=%rs1_3 rs2=%rs2_3 @@ -91,10 +73,6 @@ @c_addi4spn ... . ..... ..... .. &i imm=%nzuimm_ciw rs1=2 rd=%rs2_3 @c_addi16sp ... . ..... ..... .. &i imm=%imm_addi16sp rs1=2 rd=2 -@c_flwsp_ldsp ... . ..... ..... .. &cflwsp_ldsp uimm_flwsp=%uimm_6bit_lw \ - uimm_ldsp=%uimm_6bit_ld %rd -@c_fswsp_sdsp ... . ..... ..... .. &cfswsp_sdsp uimm_fswsp=%uimm_6bit_sw \ - uimm_sdsp=%uimm_6bit_sd rs2=%rs2_5 @c_shift ... . .. ... ..... .. \ &shift rd=%rs1_3 rs1=%rs1_3 shamt=%shimm_6bit @@ -103,7 +81,7 @@ @c_andi ... . .. ... ..... .. &i imm=%imm_ci rs1=%rs1_3 rd=%rs1_3 -# *** RV64C Standard Extension (Quadrant 0) *** +# *** RV32/64C Standard Extension (Quadrant 0) *** { # Opcode of all zeros is illegal; rd != 0, nzuimm == 0 is reserved. illegal 000 000 000 00 --- 00 @@ -111,14 +89,11 @@ } fld 001 ... ... .. ... 00 @cl_d lw 010 ... ... .. ... 00 @cl_w -c_flw_ld 011 --- ... -- ... 00 @cl #Note: Must parse uimm manually fsd 101 ... ... .. ... 00 @cs_d sw 110 ... ... .. ... 00 @cs_w -c_fsw_sd 111 --- ... -- ... 00 @cs #Note: Must parse uimm manually -# *** RV64C Standard Extension (Quadrant 1) *** +# *** RV32/64C Standard Extension (Quadrant 1) *** addi 000 . ..... ..... 01 @ci -c_jal_addiw 001 . ..... ..... 01 @ci #Note: parse rd and/or imm manually addi 010 . ..... ..... 01 @c_li { addi 011 . 00010 ..... 01 @c_addi16sp @@ -131,17 +106,14 @@ sub 100 0 11 ... 00 ... 01 @cs_2 xor 100 0 11 ... 01 ... 01 @cs_2 or 100 0 11 ... 10 ... 01 @cs_2 and 100 0 11 ... 11 ... 01 @cs_2 -c_subw 100 1 11 ... 00 ... 01 @cs_2 -c_addw 100 1 11 ... 01 ... 01 @cs_2 jal 101 ........... 01 @cj rd=0 # C.J beq 110 ... ... ..... 01 @cb_z bne 111 ... ... ..... 01 @cb_z -# *** RV64C Standard Extension (Quadrant 2) *** +# *** RV32/64C Standard Extension (Quadrant 2) *** slli 000 . ..... ..... 10 @c_shift2 fld 001 . ..... ..... 10 @c_ldsp lw 010 . ..... ..... 10 @c_lwsp -c_flwsp_ldsp 011 . ..... ..... 10 @c_flwsp_ldsp #C.LDSP:RV64;C.FLWSP:RV32 { jalr 100 0 ..... 00000 10 @c_jalr rd=0 # C.JR addi 100 0 ..... ..... 10 @c_mv @@ -153,4 +125,3 @@ c_flwsp_ldsp 011 . ..... ..... 10 @c_flwsp_ldsp #C.LDSP:RV64;C.FLWSP:RV32 } fsd 101 ...... ..... 10 @c_sdsp sw 110 . ..... ..... 10 @c_swsp -c_fswsp_sdsp 111 . ..... ..... 10 @c_fswsp_sdsp #C.SDSP:RV64;C.FSWSP:RV32 diff --git a/target/riscv/insn_trans/trans_rvc.inc.c b/target/riscv/insn_trans/trans_rvc.inc.c deleted file mode 100644 index 3fe6ad9..0000000 --- a/target/riscv/insn_trans/trans_rvc.inc.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * RISC-V translation routines for the RVC Compressed Instruction Set. - * - * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu - * Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de - * Bastian Koppelmann, kbastian@mail.uni-paderborn.de - * - * 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 . - */ - -static bool trans_c_flw_ld(DisasContext *ctx, arg_c_flw_ld *a) -{ -#ifdef TARGET_RISCV32 - /* C.FLW ( RV32FC-only ) */ - REQUIRE_FPU; - REQUIRE_EXT(ctx, RVF); - - arg_i arg; - decode_insn16_extract_cl_w(ctx, &arg, ctx->opcode); - return trans_flw(ctx, &arg); -#else - /* C.LD ( RV64C/RV128C-only ) */ - arg_i arg; - decode_insn16_extract_cl_d(ctx, &arg, ctx->opcode); - return trans_ld(ctx, &arg); -#endif -} - -static bool trans_c_fsw_sd(DisasContext *ctx, arg_c_fsw_sd *a) -{ -#ifdef TARGET_RISCV32 - /* C.FSW ( RV32FC-only ) */ - REQUIRE_FPU; - REQUIRE_EXT(ctx, RVF); - - arg_s arg; - decode_insn16_extract_cs_w(ctx, &arg, ctx->opcode); - return trans_fsw(ctx, &arg); -#else - /* C.SD ( RV64C/RV128C-only ) */ - arg_s arg; - decode_insn16_extract_cs_d(ctx, &arg, ctx->opcode); - return trans_sd(ctx, &arg); -#endif -} - -static bool trans_c_jal_addiw(DisasContext *ctx, arg_c_jal_addiw *a) -{ -#ifdef TARGET_RISCV32 - /* C.JAL */ - arg_j tmp; - decode_insn16_extract_cj(ctx, &tmp, ctx->opcode); - arg_jal arg = { .rd = 1, .imm = tmp.imm }; - return trans_jal(ctx, &arg); -#else - /* C.ADDIW */ - arg_addiw arg = { .rd = a->rd, .rs1 = a->rd, .imm = a->imm }; - return trans_addiw(ctx, &arg); -#endif -} - -static bool trans_c_subw(DisasContext *ctx, arg_c_subw *a) -{ -#ifdef TARGET_RISCV64 - return trans_subw(ctx, a); -#else - return false; -#endif -} - -static bool trans_c_addw(DisasContext *ctx, arg_c_addw *a) -{ -#ifdef TARGET_RISCV64 - return trans_addw(ctx, a); -#else - return false; -#endif -} - -static bool trans_c_flwsp_ldsp(DisasContext *ctx, arg_c_flwsp_ldsp *a) -{ -#ifdef TARGET_RISCV32 - /* C.FLWSP */ - arg_flw arg_flw = { .rd = a->rd, .rs1 = 2, .imm = a->uimm_flwsp }; - return trans_flw(ctx, &arg_flw); -#else - /* C.LDSP */ - arg_ld arg_ld = { .rd = a->rd, .rs1 = 2, .imm = a->uimm_ldsp }; - return trans_ld(ctx, &arg_ld); -#endif - return false; -} - -static bool trans_c_fswsp_sdsp(DisasContext *ctx, arg_c_fswsp_sdsp *a) -{ -#ifdef TARGET_RISCV32 - /* C.FSWSP */ - arg_fsw a_fsw = { .rs1 = 2, .rs2 = a->rs2, .imm = a->uimm_fswsp }; - return trans_fsw(ctx, &a_fsw); -#else - /* C.SDSP */ - arg_sd a_sd = { .rs1 = 2, .rs2 = a->rs2, .imm = a->uimm_sdsp }; - return trans_sd(ctx, &a_sd); -#endif -} diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 4cdffb2..8b37e09 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -707,7 +707,6 @@ static bool gen_shift(DisasContext *ctx, arg_r *a, #endif #include "decode_insn16.inc.c" -#include "insn_trans/trans_rvc.inc.c" #ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE # pragma GCC diagnostic pop -- cgit v1.1 From 598aa1160c3d17ab9271daf1f69d093ebada3f25 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 1 Apr 2019 10:11:54 +0700 Subject: target/riscv: Split gen_arith_imm into functional and temp The tcg_gen_fooi_tl functions have some immediate constant folding built in, which match up with some of the riscv asm builtin macros, like mv and not. Signed-off-by: Richard Henderson Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/insn_trans/trans_rvi.inc.c | 14 +++++++------- target/riscv/translate.c | 19 +++++++++++++++++-- 2 files changed, 24 insertions(+), 9 deletions(-) (limited to 'target') diff --git a/target/riscv/insn_trans/trans_rvi.inc.c b/target/riscv/insn_trans/trans_rvi.inc.c index b5a5b4a..6cda078 100644 --- a/target/riscv/insn_trans/trans_rvi.inc.c +++ b/target/riscv/insn_trans/trans_rvi.inc.c @@ -223,7 +223,7 @@ static bool trans_sd(DisasContext *ctx, arg_sd *a) static bool trans_addi(DisasContext *ctx, arg_addi *a) { - return gen_arith_imm(ctx, a, &tcg_gen_add_tl); + return gen_arith_imm_fn(ctx, a, &tcg_gen_addi_tl); } static void gen_slt(TCGv ret, TCGv s1, TCGv s2) @@ -239,25 +239,25 @@ static void gen_sltu(TCGv ret, TCGv s1, TCGv s2) static bool trans_slti(DisasContext *ctx, arg_slti *a) { - return gen_arith_imm(ctx, a, &gen_slt); + return gen_arith_imm_tl(ctx, a, &gen_slt); } static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a) { - return gen_arith_imm(ctx, a, &gen_sltu); + return gen_arith_imm_tl(ctx, a, &gen_sltu); } static bool trans_xori(DisasContext *ctx, arg_xori *a) { - return gen_arith_imm(ctx, a, &tcg_gen_xor_tl); + return gen_arith_imm_fn(ctx, a, &tcg_gen_xori_tl); } static bool trans_ori(DisasContext *ctx, arg_ori *a) { - return gen_arith_imm(ctx, a, &tcg_gen_or_tl); + return gen_arith_imm_fn(ctx, a, &tcg_gen_ori_tl); } static bool trans_andi(DisasContext *ctx, arg_andi *a) { - return gen_arith_imm(ctx, a, &tcg_gen_and_tl); + return gen_arith_imm_fn(ctx, a, &tcg_gen_andi_tl); } static bool trans_slli(DisasContext *ctx, arg_slli *a) { @@ -364,7 +364,7 @@ static bool trans_and(DisasContext *ctx, arg_and *a) #ifdef TARGET_RISCV64 static bool trans_addiw(DisasContext *ctx, arg_addiw *a) { - return gen_arith_imm(ctx, a, &gen_addw); + return gen_arith_imm_tl(ctx, a, &gen_addw); } static bool trans_slliw(DisasContext *ctx, arg_slliw *a) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 8b37e09..313c27b 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -567,8 +567,23 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm) /* Include the auto-generated decoder for 32 bit insn */ #include "decode_insn32.inc.c" -static bool gen_arith_imm(DisasContext *ctx, arg_i *a, - void(*func)(TCGv, TCGv, TCGv)) +static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a, + void (*func)(TCGv, TCGv, target_long)) +{ + TCGv source1; + source1 = tcg_temp_new(); + + gen_get_gpr(source1, a->rs1); + + (*func)(source1, source1, a->imm); + + gen_set_gpr(a->rd, source1); + tcg_temp_free(source1); + return true; +} + +static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a, + void (*func)(TCGv, TCGv, TCGv)) { TCGv source1, source2; source1 = tcg_temp_new(); -- cgit v1.1 From 7f9188e210aff6522a960d9669a583a3a752ddc0 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 1 Apr 2019 10:11:55 +0700 Subject: target/riscv: Remove spaces from register names These extra spaces make the "-d op" dump look weird. Signed-off-by: Richard Henderson Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/cpu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'target') diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index b767570..6a58bc9 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -30,17 +30,17 @@ static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG"; const char * const riscv_int_regnames[] = { - "zero", "ra ", "sp ", "gp ", "tp ", "t0 ", "t1 ", "t2 ", - "s0 ", "s1 ", "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", - "a6 ", "a7 ", "s2 ", "s3 ", "s4 ", "s5 ", "s6 ", "s7 ", - "s8 ", "s9 ", "s10 ", "s11 ", "t3 ", "t4 ", "t5 ", "t6 " + "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", + "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", + "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", + "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6" }; const char * const riscv_fpr_regnames[] = { - "ft0 ", "ft1 ", "ft2 ", "ft3 ", "ft4 ", "ft5 ", "ft6 ", "ft7 ", - "fs0 ", "fs1 ", "fa0 ", "fa1 ", "fa2 ", "fa3 ", "fa4 ", "fa5 ", - "fa6 ", "fa7 ", "fs2 ", "fs3 ", "fs4 ", "fs5 ", "fs6 ", "fs7 ", - "fs8 ", "fs9 ", "fs10", "fs11", "ft8 ", "ft9 ", "ft10", "ft11" + "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", + "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", + "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", + "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11" }; const char * const riscv_excp_names[] = { -- cgit v1.1 From c4e95030ba3532d13aa4e6f0738326f6f2d0c2bf Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Sat, 20 Apr 2019 02:24:01 +0000 Subject: target/riscv: Create settable CPU properties Signed-off-by: Alistair Francis Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/cpu.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ target/riscv/cpu.h | 8 ++++++++ 2 files changed, 57 insertions(+) (limited to 'target') diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 6a58bc9..0399e03 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -23,6 +23,7 @@ #include "cpu.h" #include "exec/exec-all.h" #include "qapi/error.h" +#include "hw/qdev-properties.h" #include "migration/vmstate.h" /* RISC-V CPU definitions */ @@ -296,7 +297,11 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info) static void riscv_cpu_realize(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); + RISCVCPU *cpu = RISCV_CPU(dev); + CPURISCVState *env = &cpu->env; RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev); + int priv_version = PRIV_VERSION_1_10_0; + int user_version = USER_VERSION_2_02_0; Error *local_err = NULL; cpu_exec_realizefn(cs, &local_err); @@ -305,6 +310,41 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) return; } + if (cpu->cfg.priv_spec) { + if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) { + priv_version = PRIV_VERSION_1_10_0; + } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.9.1")) { + priv_version = PRIV_VERSION_1_09_1; + } else { + error_setg(errp, + "Unsupported privilege spec version '%s'", + cpu->cfg.priv_spec); + return; + } + } + + if (cpu->cfg.user_spec) { + if (!g_strcmp0(cpu->cfg.user_spec, "v2.02.0")) { + user_version = USER_VERSION_2_02_0; + } else { + error_setg(errp, + "Unsupported user spec version '%s'", + cpu->cfg.user_spec); + return; + } + } + + set_versions(env, user_version, priv_version); + set_resetvec(env, DEFAULT_RSTVEC); + + if (cpu->cfg.mmu) { + set_feature(env, RISCV_FEATURE_MMU); + } + + if (cpu->cfg.pmp) { + set_feature(env, RISCV_FEATURE_PMP); + } + riscv_cpu_register_gdb_regs_for_features(cs); qemu_init_vcpu(cs); @@ -326,6 +366,14 @@ static const VMStateDescription vmstate_riscv_cpu = { .unmigratable = 1, }; +static Property riscv_cpu_properties[] = { + DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec), + DEFINE_PROP_STRING("user_spec", RISCVCPU, cfg.user_spec), + DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true), + DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true), + DEFINE_PROP_END_OF_LIST(), +}; + static void riscv_cpu_class_init(ObjectClass *c, void *data) { RISCVCPUClass *mcc = RISCV_CPU_CLASS(c); @@ -365,6 +413,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data) #endif /* For now, mark unmigratable: */ cc->vmsd = &vmstate_riscv_cpu; + dc->props = riscv_cpu_properties; } char *riscv_isa_string(RISCVCPU *cpu) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index c17184f..3902138 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -224,6 +224,14 @@ typedef struct RISCVCPU { CPUState parent_obj; /*< public >*/ CPURISCVState env; + + /* Configuration Settings */ + struct { + char *priv_spec; + char *user_spec; + bool mmu; + bool pmp; + } cfg; } RISCVCPU; static inline RISCVCPU *riscv_env_get_cpu(CPURISCVState *env) -- cgit v1.1 From 8903bf6e6d73d03b988b4a8197132de2ad681ff5 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Sat, 20 Apr 2019 02:24:09 +0000 Subject: target/riscv: Add a base 32 and 64 bit CPU At the same time deprecate the ISA string CPUs. It is dobtful anyone specifies the CPUs, but we are keeping them for the Spike machine (which is about to be depreated) so we may as well just mark them as deprecated. Signed-off-by: Alistair Francis Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/cpu.c | 14 ++++++++++++++ target/riscv/cpu.h | 2 ++ 2 files changed, 16 insertions(+) (limited to 'target') diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 0399e03..e298799 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -115,6 +115,12 @@ static void riscv_any_cpu_init(Object *obj) #if defined(TARGET_RISCV32) +static void riscv_base32_cpu_init(Object *obj) +{ + CPURISCVState *env = &RISCV_CPU(obj)->env; + set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); +} + static void rv32gcsu_priv1_09_1_cpu_init(Object *obj) { CPURISCVState *env = &RISCV_CPU(obj)->env; @@ -146,6 +152,12 @@ static void rv32imacu_nommu_cpu_init(Object *obj) #elif defined(TARGET_RISCV64) +static void riscv_base64_cpu_init(Object *obj) +{ + CPURISCVState *env = &RISCV_CPU(obj)->env; + set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU); +} + static void rv64gcsu_priv1_09_1_cpu_init(Object *obj) { CPURISCVState *env = &RISCV_CPU(obj)->env; @@ -479,12 +491,14 @@ 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_RV32GCSU_V1_09_1, rv32gcsu_priv1_09_1_cpu_init), DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_10_0, rv32gcsu_priv1_10_0_cpu_init), DEFINE_CPU(TYPE_RISCV_CPU_RV32IMACU_NOMMU, rv32imacu_nommu_cpu_init), DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init), DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init) #elif defined(TARGET_RISCV64) + DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base64_cpu_init), DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_09_1, rv64gcsu_priv1_09_1_cpu_init), DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_10_0, rv64gcsu_priv1_10_0_cpu_init), DEFINE_CPU(TYPE_RISCV_CPU_RV64IMACU_NOMMU, rv64imacu_nommu_cpu_init), diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 3902138..74e726c 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -48,6 +48,8 @@ #define CPU_RESOLVING_TYPE TYPE_RISCV_CPU #define TYPE_RISCV_CPU_ANY RISCV_CPU_TYPE_NAME("any") +#define TYPE_RISCV_CPU_BASE32 RISCV_CPU_TYPE_NAME("rv32") +#define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64") #define TYPE_RISCV_CPU_RV32GCSU_V1_09_1 RISCV_CPU_TYPE_NAME("rv32gcsu-v1.9.1") #define TYPE_RISCV_CPU_RV32GCSU_V1_10_0 RISCV_CPU_TYPE_NAME("rv32gcsu-v1.10.0") #define TYPE_RISCV_CPU_RV32IMACU_NOMMU RISCV_CPU_TYPE_NAME("rv32imacu-nommu") -- cgit v1.1 From 356d74192a035c71a78a22d24812a6df6099ae40 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Sat, 20 Apr 2019 02:26:45 +0000 Subject: target/riscv: Mark privilege level 2 as reserved Signed-off-by: Alistair Francis Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/cpu_bits.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'target') diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 7180fcc..945aa8d 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -383,7 +383,7 @@ /* Privilege modes */ #define PRV_U 0 #define PRV_S 1 -#define PRV_H 2 +#define PRV_H 2 /* Reserved */ #define PRV_M 3 /* RV32 satp CSR field masks */ -- cgit v1.1 From 0a01f2eecba47a48c9d06e3fb9acbd2a8a842cfc Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Sat, 20 Apr 2019 02:26:54 +0000 Subject: target/riscv: Trigger interrupt on MIP update asynchronously The requirement of holding the iothread_mutex is burdersome when swapping the background and foreground registers in the Hypervisor extension. To avoid the requrirement let's set the interrupt asynchronously. Signed-off-by: Alistair Francis Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/cpu_helper.c | 33 +++++++++++++++++++++++++++------ target/riscv/csr.c | 2 -- 2 files changed, 27 insertions(+), 8 deletions(-) (limited to 'target') diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 41d6db4..7318da2 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -82,10 +82,31 @@ int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts) } } -/* iothread_mutex must be held */ +struct CpuAsyncInfo { + uint32_t new_mip; +}; + +static void riscv_cpu_update_mip_irqs_async(CPUState *target_cpu_state, + run_on_cpu_data data) +{ + CPURISCVState *env = &RISCV_CPU(target_cpu_state)->env; + RISCVCPU *cpu = riscv_env_get_cpu(env); + struct CpuAsyncInfo *info = (struct CpuAsyncInfo *) data.host_ptr; + + if (info->new_mip) { + cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); + } else { + cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); + } + + g_free(info); +} + uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value) { CPURISCVState *env = &cpu->env; + CPUState *cs = CPU(cpu); + struct CpuAsyncInfo *info; uint32_t old, new, cmp = atomic_read(&env->mip); do { @@ -94,11 +115,11 @@ uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value) cmp = atomic_cmpxchg(&env->mip, old, new); } while (old != cmp); - if (new) { - cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); - } else { - cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_HARD); - } + info = g_new(struct CpuAsyncInfo, 1); + info->new_mip = new; + + async_run_on_cpu(cs, riscv_cpu_update_mip_irqs_async, + RUN_ON_CPU_HOST_PTR(info)); return old; } diff --git a/target/riscv/csr.c b/target/riscv/csr.c index e1d91b6..f9d8d15 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -555,9 +555,7 @@ static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value, uint32_t old_mip; if (mask) { - qemu_mutex_lock_iothread(); old_mip = riscv_cpu_update_mip(cpu, mask, (new_value & mask)); - qemu_mutex_unlock_iothread(); } else { old_mip = atomic_read(&env->mip); } -- cgit v1.1 From 16fdb8ff64374ed51b246437e13043039a8eb9f9 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Sat, 20 Apr 2019 02:27:02 +0000 Subject: target/riscv: Improve the scause logic No functional change, just making the code easier to read. Signed-off-by: Alistair Francis Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/cpu_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'target') diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 7318da2..c577a26 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -515,7 +515,7 @@ void riscv_cpu_do_interrupt(CPUState *cs) s = set_field(s, MSTATUS_SPP, env->priv); s = set_field(s, MSTATUS_SIE, 0); env->mstatus = s; - env->scause = cause | ~(((target_ulong)-1) >> async); + env->scause = cause | ((target_ulong)async << (TARGET_LONG_BITS - 1)); env->sepc = env->pc; env->sbadaddr = tval; env->pc = (env->stvec >> 2 << 2) + -- cgit v1.1 From 49aaa3e534f5422a56313bb93c1880e70fc1da7e Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Sat, 20 Apr 2019 02:27:10 +0000 Subject: target/riscv: Add the MPV and MTL mstatus bits Signed-off-by: Alistair Francis Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/cpu_bits.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'target') diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 945aa8d..fe71647 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -316,14 +316,11 @@ /* mstatus CSR bits */ #define MSTATUS_UIE 0x00000001 #define MSTATUS_SIE 0x00000002 -#define MSTATUS_HIE 0x00000004 #define MSTATUS_MIE 0x00000008 #define MSTATUS_UPIE 0x00000010 #define MSTATUS_SPIE 0x00000020 -#define MSTATUS_HPIE 0x00000040 #define MSTATUS_MPIE 0x00000080 #define MSTATUS_SPP 0x00000100 -#define MSTATUS_HPP 0x00000600 #define MSTATUS_MPP 0x00001800 #define MSTATUS_FS 0x00006000 #define MSTATUS_XS 0x00018000 @@ -335,6 +332,8 @@ #define MSTATUS_TVM 0x00100000 /* since: priv-1.10 */ #define MSTATUS_TW 0x20000000 /* since: priv-1.10 */ #define MSTATUS_TSR 0x40000000 /* since: priv-1.10 */ +#define MSTATUS_MTL 0x4000000000ULL +#define MSTATUS_MPV 0x8000000000ULL #define MSTATUS64_UXL 0x0000000300000000ULL #define MSTATUS64_SXL 0x0000000C00000000ULL -- cgit v1.1 From 1f0419cb0475eebdbefea67483e85287f3af07a7 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Sat, 20 Apr 2019 02:27:18 +0000 Subject: target/riscv: Allow setting mstatus virtulisation bits Signed-off-by: Alistair Francis Revieweb-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/csr.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'target') diff --git a/target/riscv/csr.c b/target/riscv/csr.c index f9d8d15..e6d68a9 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -290,7 +290,6 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) { target_ulong mstatus = env->mstatus; target_ulong mask = 0; - target_ulong mpp = get_field(val, MSTATUS_MPP); /* flush tlb on mstatus fields that affect VM */ if (env->priv_ver <= PRIV_VERSION_1_09_1) { @@ -305,7 +304,7 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) MSTATUS_VM : 0); } if (env->priv_ver >= PRIV_VERSION_1_10_0) { - if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | + if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV | MSTATUS_MPRV | MSTATUS_SUM)) { tlb_flush(CPU(riscv_env_get_cpu(env))); } @@ -313,13 +312,13 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM | MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR | MSTATUS_TW; - } - - /* silenty discard mstatus.mpp writes for unsupported modes */ - if (mpp == PRV_H || - (!riscv_has_ext(env, RVS) && mpp == PRV_S) || - (!riscv_has_ext(env, RVU) && mpp == PRV_U)) { - mask &= ~MSTATUS_MPP; +#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; +#endif } mstatus = (mstatus & ~mask) | (val & mask); -- cgit v1.1 From 71f09a5bb48d0c51b87e70158407ec2db4a9c6e2 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Sat, 20 Apr 2019 02:27:26 +0000 Subject: target/riscv: Add Hypervisor CSR macros Add the 1.10.1 Hypervisor CSRs and remove the 1.9.1 spec versions. Signed-off-by: Alistair Francis Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/cpu_bits.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'target') diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index fe71647..52c2169 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -202,6 +202,12 @@ #define CSR_DPC 0x7b1 #define CSR_DSCRATCH 0x7b2 +/* Hpervisor CSRs */ +#define CSR_HSTATUS 0xa00 +#define CSR_HEDELEG 0xa02 +#define CSR_HIDELEG 0xa03 +#define CSR_HGATP 0xa80 + /* Performance Counters */ #define CSR_MHPMCOUNTER3 0xb03 #define CSR_MHPMCOUNTER4 0xb04 @@ -292,9 +298,6 @@ #define CSR_MHPMCOUNTER31H 0xb9f /* Legacy Hypervisor Trap Setup (priv v1.9.1) */ -#define CSR_HSTATUS 0x200 -#define CSR_HEDELEG 0x202 -#define CSR_HIDELEG 0x203 #define CSR_HIE 0x204 #define CSR_HTVEC 0x205 -- cgit v1.1 From d28b15a4d3b1e000ec7bf9090fe870cbc5f1eb2c Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Sat, 20 Apr 2019 02:27:35 +0000 Subject: target/riscv: Add the HSTATUS register masks Signed-off-by: Alistair Francis Reviwed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/cpu_bits.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'target') diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 52c2169..a179137 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -382,6 +382,24 @@ #define SSTATUS_SD SSTATUS64_SD #endif +/* hstatus CSR bits */ +#define HSTATUS_SPRV 0x00000001 +#define HSTATUS_STL 0x00000040 +#define HSTATUS_SPV 0x00000080 +#define HSTATUS_SP2P 0x00000100 +#define HSTATUS_SP2V 0x00000200 +#define HSTATUS_VTVM 0x00100000 +#define HSTATUS_VTSR 0x00400000 + +#define HSTATUS32_WPRI 0xFF8FF87E +#define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL + +#if defined(TARGET_RISCV32) +#define HSTATUS_WPRI HSTATUS32_WPRI +#elif defined(TARGET_RISCV64) +#define HSTATUS_WPRI HSTATUS64_WPRI +#endif + /* Privilege modes */ #define PRV_U 0 #define PRV_S 1 -- cgit v1.1 From e06431108b0b1ef6ca76398d2b0b792ea24ae6bc Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Sat, 20 Apr 2019 02:27:43 +0000 Subject: target/riscv: Add the HGATP register masks Signed-off-by: Alistair Francis Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/cpu_bits.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'target') diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index a179137..dc9d53d 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -208,6 +208,17 @@ #define CSR_HIDELEG 0xa03 #define CSR_HGATP 0xa80 +#if defined(TARGET_RISCV32) +#define HGATP_MODE SATP32_MODE +#define HGATP_ASID SATP32_ASID +#define HGATP_PPN SATP32_PPN +#endif +#if defined(TARGET_RISCV64) +#define HGATP_MODE SATP64_MODE +#define HGATP_ASID SATP64_ASID +#define HGATP_PPN SATP64_PPN +#endif + /* Performance Counters */ #define CSR_MHPMCOUNTER3 0xb03 #define CSR_MHPMCOUNTER4 0xb04 -- cgit v1.1 From 4cc16b3b9282e04fab8e84d136540757e82af019 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 25 Apr 2019 10:26:36 -0700 Subject: target/riscv: Add checks for several RVC reserved operands C.ADDI16SP, C.LWSP, C.JR, C.ADDIW, C.LDSP all have reserved operands that were not diagnosed. Signed-off-by: Richard Henderson Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/insn16-64.decode | 10 ++++++++-- target/riscv/insn16.decode | 7 ++++++- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'target') diff --git a/target/riscv/insn16-64.decode b/target/riscv/insn16-64.decode index 055859d..672e1e9 100644 --- a/target/riscv/insn16-64.decode +++ b/target/riscv/insn16-64.decode @@ -21,10 +21,16 @@ ld 011 ... ... .. ... 00 @cl_d sd 111 ... ... .. ... 00 @cs_d # *** RV64C Standard Extension (Quadrant 1) *** -addiw 001 . ..... ..... 01 @ci +{ + illegal 001 - 00000 ----- 01 # c.addiw, RES rd=0 + addiw 001 . ..... ..... 01 @ci +} subw 100 1 11 ... 00 ... 01 @cs_2 addw 100 1 11 ... 01 ... 01 @cs_2 # *** RV64C Standard Extension (Quadrant 2) *** -ld 011 . ..... ..... 10 @c_ldsp +{ + illegal 011 - 00000 ----- 10 # c.ldsp, RES rd=0 + ld 011 . ..... ..... 10 @c_ldsp +} sd 111 . ..... ..... 10 @c_sdsp diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode index 433c0e8..1cb9387 100644 --- a/target/riscv/insn16.decode +++ b/target/riscv/insn16.decode @@ -96,6 +96,7 @@ sw 110 ... ... .. ... 00 @cs_w addi 000 . ..... ..... 01 @ci addi 010 . ..... ..... 01 @c_li { + illegal 011 0 ----- 00000 01 # c.addi16sp and c.lui, RES nzimm=0 addi 011 . 00010 ..... 01 @c_addi16sp lui 011 . ..... ..... 01 @c_lui } @@ -113,8 +114,12 @@ bne 111 ... ... ..... 01 @cb_z # *** RV32/64C Standard Extension (Quadrant 2) *** slli 000 . ..... ..... 10 @c_shift2 fld 001 . ..... ..... 10 @c_ldsp -lw 010 . ..... ..... 10 @c_lwsp { + illegal 010 - 00000 ----- 10 # c.lwsp, RES rd=0 + lw 010 . ..... ..... 10 @c_lwsp +} +{ + illegal 100 0 00000 00000 10 # c.jr, RES rs1=0 jalr 100 0 ..... 00000 10 @c_jalr rd=0 # C.JR addi 100 0 ..... ..... 10 @c_mv } -- cgit v1.1 From 087b051a51a0c2a5bc1e8d435a484a8896b4176b Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Tue, 7 May 2019 18:36:46 -0400 Subject: target/riscv: More accurate handling of `sip` CSR According to the spec, "All bits besides SSIP, USIP, and UEIP in the sip register are read-only." Further, if an interrupt is not delegated to mode x, then "the corresponding bits in xip [...] should appear to be hardwired to zero. This patch implements both of those requirements. Signed-off-by: Jonathan Behrens Reviewed-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt --- target/riscv/csr.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'target') diff --git a/target/riscv/csr.c b/target/riscv/csr.c index e6d68a9..0f51c7e 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -237,6 +237,7 @@ static const target_ulong sstatus_v1_9_mask = SSTATUS_SIE | SSTATUS_SPIE | 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; +static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP; #if defined(TARGET_RISCV32) static const char valid_vm_1_09[16] = { @@ -682,8 +683,10 @@ static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val) static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask) { - return rmw_mip(env, CSR_MSTATUS, ret_value, new_value, - write_mask & env->mideleg); + int ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value, + write_mask & env->mideleg & sip_writable_mask); + *ret_value &= env->mideleg; + return ret; } /* Supervisor Protection and Translation */ -- cgit v1.1 From 1e0d985fa9136a563168a3da66f3d17820404ee2 Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Wed, 8 May 2019 13:38:35 -0400 Subject: target/riscv: Only flush TLB if SATP.ASID changes There is an analogous change for ARM here: https://patchwork.kernel.org/patch/10649857 Signed-off-by: Jonathan Behrens Reviewed-by: Alistair Francis Signed-off-by: Palmer Dabbelt --- target/riscv/csr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'target') diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 0f51c7e..f9e2910 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -723,7 +723,9 @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val) if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) { return -1; } else { - tlb_flush(CPU(riscv_env_get_cpu(env))); + if((val ^ env->satp) & SATP_ASID) { + tlb_flush(CPU(riscv_env_get_cpu(env))); + } env->satp = val; } } -- cgit v1.1