target/riscv: Implement the stval/mtval illegal instruction
authorAlistair Francis <alistair.francis@wdc.com>
Mon, 20 Dec 2021 06:49:16 +0000 (16:49 +1000)
committerAlistair Francis <alistair.francis@wdc.com>
Sat, 8 Jan 2022 05:46:10 +0000 (15:46 +1000)
The stval and mtval registers can optionally contain the faulting
instruction on an illegal instruction exception. This patch adds support
for setting the stval and mtval registers.

The RISC-V spec states that "The stval register can optionally also be
used to return the faulting instruction bits on an illegal instruction
exception...". In this case we are always writing the value on an
illegal instruction.

This doesn't match all CPUs (some CPUs won't write the data), but in
QEMU let's just populate the value on illegal instructions. This won't
break any guest software, but will provide more information to guests.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Message-id: 20211220064916.107241-4-alistair.francis@opensource.wdc.com

target/riscv/cpu.h
target/riscv/cpu_helper.c
target/riscv/translate.c

index 9ee01f761f1873d1ae3b2e2fc76df459fca876b0..4d630867650a73a91efe8410ac8dbcdf5ec4c32e 100644 (file)
@@ -132,6 +132,8 @@ struct CPURISCVState {
     target_ulong frm;
 
     target_ulong badaddr;
+    uint32_t bins;
+
     target_ulong guest_phys_fault_addr;
 
     target_ulong priv_ver;
index ddacb8533a14f40fed2f9f34a06887109137f877..434a83e66a00335da52f5bfe8aeb2aa136d664c3 100644 (file)
@@ -1038,6 +1038,9 @@ void riscv_cpu_do_interrupt(CPUState *cs)
             write_gva = true;
             tval = env->badaddr;
             break;
+        case RISCV_EXCP_ILLEGAL_INST:
+            tval = env->bins;
+            break;
         default:
             break;
         }
index 9e4f9c334207847961b0a7002f584ea7b2792b2b..615048ec87e4743a1e172f200160c8463dcd0181 100644 (file)
@@ -208,6 +208,9 @@ static void generate_exception_mtval(DisasContext *ctx, int excp)
 
 static void gen_exception_illegal(DisasContext *ctx)
 {
+    tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
+                   offsetof(CPURISCVState, bins));
+
     generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
 }