diff mbox series

[v1,2/4] target/riscv: Implement the mtval illegal instruction

Message ID 1df1097f91c1d8e1817200ac1feefb5407ccb842.1532559484.git.alistair.francis@wdc.com
State New
Headers show
Series RISC-V: Populate mtval and stval | expand

Commit Message

Alistair Francis July 25, 2018, 11:04 p.m. UTC
The mtval register can optionally contain the faulting instruction
on an illegal instruction exception. This patch adds support for setting
the mtval register based on the CPU feature.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.h       |  4 +++-
 target/riscv/helper.c    | 13 +++++++++++--
 target/riscv/translate.c | 12 ++++++++++++
 3 files changed, 26 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0243f73129..1bc46aa952 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -85,7 +85,8 @@ 
    is currently no bit in misa to indicate whether an MMU exists or not
    so a cpu features bitfield is required */
 enum {
-    RISCV_FEATURE_MMU
+    RISCV_FEATURE_MMU,
+    RISCV_FEATURE_MTVAL_INST
 };
 
 #define USER_VERSION_2_02_0 0x00020200
@@ -113,6 +114,7 @@  struct CPURISCVState {
     target_ulong frm;
 
     target_ulong badaddr;
+    target_ulong bins;
 
     target_ulong user_ver;
     target_ulong priv_ver;
diff --git a/target/riscv/helper.c b/target/riscv/helper.c
index b4a3f80872..bd78bcff28 100644
--- a/target/riscv/helper.c
+++ b/target/riscv/helper.c
@@ -491,9 +491,18 @@  void riscv_cpu_do_interrupt(CPUState *cs)
                     ": badaddr 0x" TARGET_FMT_lx, env->mhartid, env->badaddr);
             }
             env->mtval = env->badaddr;
+        } else if (cs->exception_index & RISCV_EXCP_ILLEGAL_INST) {
+            if (riscv_feature(env, RISCV_FEATURE_MTVAL_INST)) {
+                /* The mtval register can optionally also be used to
+                 * return the faulting instruction bits on an illegal
+                 * instruction exception.
+                 */
+                env->mtval = env->bins;
+            } else {
+                env->mtval = 0;
+            }
         } else {
-            /* otherwise we must clear mbadaddr/mtval
-             * todo: support populating mtval on illegal instructions */
+            /* Otherwise we must clear mbadaddr/mtval */
             env->mtval = 0;
         }
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 0b6be74f2d..1fe8b9c982 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -102,6 +102,15 @@  static void gen_exception_debug(void)
 
 static void gen_exception_illegal(DisasContext *ctx)
 {
+#if defined(TARGET_RISCV64)
+    TCGv_i64 helper_tmp = tcg_const_i64(ctx->opcode);
+    tcg_gen_st_tl(helper_tmp, cpu_env, offsetof(CPURISCVState, bins));
+    tcg_temp_free_i64(helper_tmp);
+#else
+    TCGv_i32 helper_tmp = tcg_const_i32(ctx->opcode);
+    tcg_gen_st_tl(helper_tmp, cpu_env, offsetof(CPURISCVState, bins));
+    tcg_temp_free_i32(helper_tmp);
+#endif
     generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
 }
 
@@ -1287,6 +1296,9 @@  static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
     tcg_gen_movi_tl(rs1_pass, rs1);
     tcg_gen_movi_tl(csr_store, csr); /* copy into temp reg to feed to helper */
 
+    /* Store the opcode code incase we need it for mtval/stval. */
+    env->bins = ctx->opcode;
+
 #ifndef CONFIG_USER_ONLY
     /* Extract funct7 value and check whether it matches SFENCE.VMA */
     if ((opc == OPC_RISC_ECALL) && ((csr >> 5) == 9)) {