From f75ca6603ce38f2e1a606e151eb5a8bc19ac2e2e Mon Sep 17 00:00:00 2001 From: Mingle Chen Date: Wed, 5 Apr 2023 15:09:34 +0100 Subject: [PATCH] Implement experimental riscv instructions --- target/riscv/helper.h | 2 ++ target/riscv/insn32-cheri.decode | 6 ++-- target/riscv/insn_trans/trans_cheri.c.inc | 40 +++++++++++++++++++++++ target/riscv/op_helper_cheri.c | 8 +++++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 09c54114a85..48fb4ce99e4 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -77,6 +77,8 @@ DEF_HELPER_3(lr_c_cap, void, env, i32, i32) DEF_HELPER_3(sc_c_modedep, tl, env, i32, i32) DEF_HELPER_3(sc_c_ddc, tl, env, i32, i32) DEF_HELPER_3(sc_c_cap, tl, env, i32, i32) +/* experimental instruction helpers*/ +DEF_HELPER_2(ctestdereferenceable, tl, env, i32) #endif #ifdef CONFIG_TCG_LOG_INSTR diff --git a/target/riscv/insn32-cheri.decode b/target/riscv/insn32-cheri.decode index 79bbc61aa6e..d7cb3bacca3 100644 --- a/target/riscv/insn32-cheri.decode +++ b/target/riscv/insn32-cheri.decode @@ -57,6 +57,8 @@ ccopytype 0011110 ..... ..... 000 ..... 1011011 @r ccseal 0011111 ..... ..... 000 ..... 1011011 @r ctestsubset 0100000 ..... ..... 000 ..... 1011011 @r cseqx 0100001 ..... ..... 000 ..... 1011011 @r +candaddr 0100010 ..... ..... 000 ..... 1011011 @r + # 1111011 unused # 1111100 Used for Stores (see below) # 1111101 Used for Loads (see below) @@ -85,9 +87,9 @@ cgetaddr 1111111 01111 ..... 000 ..... 1011011 @r2 # fpclear 1111111 10000 ..... 000 ..... 1011011 @r2 csealentry 1111111 10001 ..... 000 ..... 1011011 @r2 cloadtags 1111111 10010 ..... 000 ..... 1011011 @r2 +ctestdereferenceable 1111111 10011 ..... 000 ..... 1011011 @r2 jalr_pcc 1111111 10100 ..... 000 ..... 1011011 @r2 - - +candpermuserdata 1111111 10101 ..... 000 ..... 1011011 @r2 # There is an existing @sfence_vma format with rs1+rs2 fields, but let's define a new name @r_2source ....... ..... ..... ... ..... ....... %rs2 %rs1 diff --git a/target/riscv/insn_trans/trans_cheri.c.inc b/target/riscv/insn_trans/trans_cheri.c.inc index dae1d785f21..1d50ab6c39d 100644 --- a/target/riscv/insn_trans/trans_cheri.c.inc +++ b/target/riscv/insn_trans/trans_cheri.c.inc @@ -166,6 +166,9 @@ TRANSLATE_INT_CAP(cgetsealed) TRANSLATE_INT_CAP(cloadtags) +// experimental ctestdereferenceable +TRANSLATE_INT_CAP(ctestdereferenceable) + // Two operand (int int) static inline bool trans_crrl(DisasContext *ctx, arg_crrl *a) { @@ -181,6 +184,40 @@ TRANSLATE_CAP_CAP(ccleartag) TRANSLATE_CAP_CAP(cmove) TRANSLATE_CAP_CAP(csealentry) +// experimental candpermuserdata + +/* User-defined permission bits. */ +#define CAP_PERM_SW0 (1 << 15) /* 0x00008000 */ +#define CAP_PERM_SW1 (1 << 16) /* 0x00010000 */ +#define CAP_PERM_SW2 (1 << 17) /* 0x00020000 */ +#define CAP_PERM_SW3 (1 << 18) /* 0x00040000 */ +#define CAP_PERM_SW_VMEM CAP_PERM_SW1 + +#define CAP_PERMS_SWALL \ + (CAP_PERM_SW0 | CAP_PERM_SW1 | CAP_PERM_SW2 | CAP_PERM_SW3) + +#define CAP_PERMS_USERSPACE \ + (CAP_PERM_GLOBAL | CAP_PERM_LOAD | CAP_PERM_LOAD_CAP | CAP_PERM_CINVOKE | \ + (CAP_PERMS_SWALL & ~CAP_PERM_SW_VMEM)) + +#define CAP_PERMS_USERSPACE_DATA \ + (CAP_PERMS_USERSPACE | CAP_PERM_STORE | CAP_PERM_STORE_CAP | \ + CAP_PERM_STORE_LOCAL) + +static inline bool trans_candpermuserdata(DisasContext *ctx, + arg_candpermuserdata *a) +{ + TCGv_i32 source_regnum = tcg_const_i32(a->rs1); + TCGv_i32 dest_regnum = tcg_const_i32(a->rd); + TCGv gpr = tcg_temp_new(); + gen_set_gpr(gpr, CAP_PERMS_USERSPACE_DATA & ~CAP_PERM_SW_VMEM); + gen_helper_candperm(cpu_env, dest_regnum, source_regnum, gpr); + tcg_temp_free(gpr); + tcg_temp_free_i32(dest_regnum); + tcg_temp_free_i32(source_regnum); + return true; +} + // Three operand (cap cap cap) TRANSLATE_CAP_CAP_CAP(cbuildcap) TRANSLATE_CAP_CAP_CAP(ccopytype) @@ -215,6 +252,9 @@ TRANSLATE_CAP_CAP_INT(csetboundsexact) TRANSLATE_CAP_CAP_INT(csetflags) TRANSLATE_CAP_CAP_INT(csetoffset) +// Add experimental CAndAddr instruction +TRANSLATE_CAP_CAP_INT(candaddr) + // Three operand (int cap cap) TRANSLATE_INT_CAP_CAP(csub) TRANSLATE_INT_CAP_CAP(ctestsubset) diff --git a/target/riscv/op_helper_cheri.c b/target/riscv/op_helper_cheri.c index 8588b5415e6..4398fdba3a5 100644 --- a/target/riscv/op_helper_cheri.c +++ b/target/riscv/op_helper_cheri.c @@ -453,3 +453,11 @@ target_ulong HELPER(sc_c_cap)(CPUArchState *env, uint32_t addr_reg, uint32_t val { return sc_c_impl(env, addr_reg, val_reg, /*offset=*/0, GETPC()); } + +/* Helpers for experimental instructions. */ +target_ulong HELPER(ctestdereferenceable)(CPUArchState *env, uint32_t addr_reg) +{ + const cap_register_t *cbp = get_readonly_capreg(env, addr_reg); + + return cbp->cr_tag && cap_is_unsealed(cbp) && cap_cursor_in_bounds(cbp); +}