Re: [PATCH v9 1/2] target/riscv: Update [m|h]tinst CSR in riscv_cpu_do_interrupt()

2022-07-03 Thread dramforever
On 7/4/22 10:17, Alistair Francis wrote:
> On Thu, Jun 30, 2022 at 4:13 PM Anup Patel  wrote:
>> We should write transformed instruction encoding of the trapped
>> instruction in [m|h]tinst CSR at time of taking trap as defined
>> by the RISC-V privileged specification v1.12.
>>
>> Reviewed-by: Alistair Francis 
>> Signed-off-by: Anup Patel 
> @dramforever do you want to give an Ack or Reviewed-by?
>
> Alistair

Acked-By: dramforever 

dramforever





Re: [PATCH v9 1/2] target/riscv: Update [m|h]tinst CSR in riscv_cpu_do_interrupt()

2022-07-03 Thread Alistair Francis
On Thu, Jun 30, 2022 at 4:13 PM Anup Patel  wrote:
>
> We should write transformed instruction encoding of the trapped
> instruction in [m|h]tinst CSR at time of taking trap as defined
> by the RISC-V privileged specification v1.12.
>
> Reviewed-by: Alistair Francis 
> Signed-off-by: Anup Patel 

@dramforever do you want to give an Ack or Reviewed-by?

Alistair



[PATCH v9 1/2] target/riscv: Update [m|h]tinst CSR in riscv_cpu_do_interrupt()

2022-06-30 Thread Anup Patel
We should write transformed instruction encoding of the trapped
instruction in [m|h]tinst CSR at time of taking trap as defined
by the RISC-V privileged specification v1.12.

Reviewed-by: Alistair Francis 
Signed-off-by: Anup Patel 
---
 target/riscv/cpu.h|   5 +
 target/riscv/cpu_helper.c | 252 +-
 target/riscv/instmap.h|  45 +++
 3 files changed, 296 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5c7acc055a..ffb1a18873 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -285,6 +285,11 @@ struct CPUArchState {
 /* Signals whether the current exception occurred with two-stage address
translation active. */
 bool two_stage_lookup;
+/*
+ * Signals whether the current exception occurred while doing two-stage
+ * address translation for the VS-stage page table walk.
+ */
+bool two_stage_indirect_lookup;
 
 target_ulong scounteren;
 target_ulong mcounteren;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index be28615e23..c59cfddac2 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -22,6 +22,7 @@
 #include "qemu/main-loop.h"
 #include "cpu.h"
 #include "exec/exec-all.h"
+#include "instmap.h"
 #include "tcg/tcg-op.h"
 #include "trace.h"
 #include "semihosting/common-semi.h"
@@ -1057,7 +1058,8 @@ restart:
 
 static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
 MMUAccessType access_type, bool pmp_violation,
-bool first_stage, bool two_stage)
+bool first_stage, bool two_stage,
+bool two_stage_indirect)
 {
 CPUState *cs = env_cpu(env);
 int page_fault_exceptions, vm;
@@ -1107,6 +1109,7 @@ static void raise_mmu_exception(CPURISCVState *env, 
target_ulong address,
 }
 env->badaddr = address;
 env->two_stage_lookup = two_stage;
+env->two_stage_indirect_lookup = two_stage_indirect;
 }
 
 hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
@@ -1152,6 +1155,7 @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr 
physaddr,
 env->badaddr = addr;
 env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
 riscv_cpu_two_stage_lookup(mmu_idx);
+env->two_stage_indirect_lookup = false;
 cpu_loop_exit_restore(cs, retaddr);
 }
 
@@ -1177,6 +1181,7 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr 
addr,
 env->badaddr = addr;
 env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
 riscv_cpu_two_stage_lookup(mmu_idx);
+env->two_stage_indirect_lookup = false;
 cpu_loop_exit_restore(cs, retaddr);
 }
 
@@ -1192,6 +1197,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 bool pmp_violation = false;
 bool first_stage_error = true;
 bool two_stage_lookup = false;
+bool two_stage_indirect_error = false;
 int ret = TRANSLATE_FAIL;
 int mode = mmu_idx;
 /* default TLB page size */
@@ -1229,6 +1235,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
  */
 if (ret == TRANSLATE_G_STAGE_FAIL) {
 first_stage_error = false;
+two_stage_indirect_error = true;
 access_type = MMU_DATA_LOAD;
 }
 
@@ -1312,12 +1319,218 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, 
int size,
 raise_mmu_exception(env, address, access_type, pmp_violation,
 first_stage_error,
 riscv_cpu_virt_enabled(env) ||
-riscv_cpu_two_stage_lookup(mmu_idx));
+riscv_cpu_two_stage_lookup(mmu_idx),
+two_stage_indirect_error);
 cpu_loop_exit_restore(cs, retaddr);
 }
 
 return true;
 }
+
+static target_ulong riscv_transformed_insn(CPURISCVState *env,
+   target_ulong insn,
+   target_ulong taddr)
+{
+target_ulong xinsn = 0;
+target_ulong access_rs1 = 0, access_imm = 0, access_size = 0;
+
+/*
+ * Only Quadrant 0 and Quadrant 2 of RVC instruction space need to
+ * be uncompressed. The Quadrant 1 of RVC instruction space need
+ * not be transformed because these instructions won't generate
+ * any load/store trap.
+ */
+
+if ((insn & 0x3) != 0x3) {
+/* Transform 16bit instruction into 32bit instruction */
+switch (GET_C_OP(insn)) {
+case OPC_RISC_C_OP_QUAD0: /* Quadrant 0 */
+switch (GET_C_FUNC(insn)) {
+case OPC_RISC_C_FUNC_FLD_LQ:
+if (riscv_cpu_xlen(env) != 128) { /* C.FLD (RV32/64) */
+xinsn = OPC_RISC_FLD;
+xinsn = SET_RD(xinsn, GET_C_RS2S(insn));
+access_rs1 = GET_C_RS1S(insn);
+