qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V3 0/6] Support RISC-V migration
@ 2020-10-23  9:12 Yifei Jiang
  2020-10-23  9:12 ` [PATCH V3 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit Yifei Jiang
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Yifei Jiang @ 2020-10-23  9:12 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: zhang.zhanghailiang, sagark, kbastian, victor.zhangxiaofeng,
	richard.henderson, Yifei Jiang, Alistair.Francis, yinyipeng1,
	palmer, wu.wubin, dengkai1

This patches supported RISC-V migration based on tcg accel. And we have
verified related migration features such as snapshot and live migration.

A few weeks ago, we submitted RFC patches about supporting RISC-V migration
based on kvm accel: https://www.spinics.net/lists/kvm/msg223605.html.
And we found that tcg accelerated migration can be supported with a few
changes. Most of the devices have already implemented the migration
interface, so, to achieve the tcg accelerated migration, we just need to
add vmstate of both cpu and sifive_plic.

Changes since v2:
1. Move vmstate_riscv_cpu declaration to internals.h.
2. Merge m/vsstatus and m/vsstatush into one uint64_t unit.

Changes since v1:
1. Add license head to target/riscv/machine.c.
2. Regenerate some state of PMP at post_load hook.

Yifei Jiang (6):
  target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit
  target/riscv: Add basic vmstate description of CPU
  target/riscv: Add PMP state description
  target/riscv: Add H extension state description
  target/riscv: Add V extension state description
  target/riscv: Add sifive_plic vmstate

 hw/intc/sifive_plic.c     |  26 ++++-
 hw/intc/sifive_plic.h     |   1 +
 target/riscv/cpu.c        |  16 ++--
 target/riscv/cpu.h        |  16 +---
 target/riscv/cpu_bits.h   |  16 ++--
 target/riscv/cpu_helper.c |  72 ++++++--------
 target/riscv/csr.c        |  28 +++---
 target/riscv/internals.h  |   4 +
 target/riscv/machine.c    | 196 ++++++++++++++++++++++++++++++++++++++
 target/riscv/meson.build  |   3 +-
 target/riscv/op_helper.c  |  49 +++++-----
 target/riscv/pmp.c        |  29 +++---
 target/riscv/pmp.h        |   2 +
 13 files changed, 331 insertions(+), 127 deletions(-)
 create mode 100644 target/riscv/machine.c

-- 
2.19.1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH V3 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit
  2020-10-23  9:12 [PATCH V3 0/6] Support RISC-V migration Yifei Jiang
@ 2020-10-23  9:12 ` Yifei Jiang
  2020-10-23  9:41   ` Jiangyifei
  2020-10-23 23:50   ` Alistair Francis
  2020-10-23  9:12 ` [PATCH V3 2/6] target/riscv: Add basic vmstate description of CPU Yifei Jiang
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 14+ messages in thread
From: Yifei Jiang @ 2020-10-23  9:12 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: zhang.zhanghailiang, sagark, kbastian, victor.zhangxiaofeng,
	richard.henderson, Yifei Jiang, Alistair.Francis, yinyipeng1,
	palmer, wu.wubin, dengkai1

mstatus/mstatush and vsstatus/vsstatush are two halved for RISCV32.
This patch expands mstatus and vsstatus to uint64_t instead of
target_ulong so that it can be saved as one unit and reduce some
ifdefs in the code.

Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
---
 target/riscv/cpu.c        |  8 +++--
 target/riscv/cpu.h        | 16 ++-------
 target/riscv/cpu_bits.h   | 16 ++++-----
 target/riscv/cpu_helper.c | 72 ++++++++++++++++-----------------------
 target/riscv/csr.c        | 28 ++++++++-------
 target/riscv/op_helper.c  | 49 +++++++++++++-------------
 6 files changed, 82 insertions(+), 107 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0bbfd7f457..dd05a220c7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -216,13 +216,15 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
     qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc      ", env->pc);
 #ifndef CONFIG_USER_ONLY
     qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
-    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
+    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", (target_ulong)env->mstatus);
 #ifdef TARGET_RISCV32
-    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ", env->mstatush);
+    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ",
+                 (target_ulong)(env->mstatus >> 32));
 #endif
     if (riscv_has_ext(env, RVH)) {
         qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
-        qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ", env->vsstatus);
+        qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ",
+                     (target_ulong)env->vsstatus);
     }
     qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip     ", env->mip);
     qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie     ", env->mie);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index de275782e6..57050f2268 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -140,14 +140,10 @@ struct CPURISCVState {
     target_ulong resetvec;
 
     target_ulong mhartid;
-    target_ulong mstatus;
+    uint64_t mstatus;
 
     target_ulong mip;
 
-#ifdef TARGET_RISCV32
-    target_ulong mstatush;
-#endif
-
     uint32_t miclaim;
 
     target_ulong mie;
@@ -179,16 +175,13 @@ struct CPURISCVState {
     uint64_t htimedelta;
 
     /* Virtual CSRs */
-    target_ulong vsstatus;
+    uint64_t vsstatus;
     target_ulong vstvec;
     target_ulong vsscratch;
     target_ulong vsepc;
     target_ulong vscause;
     target_ulong vstval;
     target_ulong vsatp;
-#ifdef TARGET_RISCV32
-    target_ulong vsstatush;
-#endif
 
     target_ulong mtval2;
     target_ulong mtinst;
@@ -200,10 +193,7 @@ struct CPURISCVState {
     target_ulong scause_hs;
     target_ulong stval_hs;
     target_ulong satp_hs;
-    target_ulong mstatus_hs;
-#ifdef TARGET_RISCV32
-    target_ulong mstatush_hs;
-#endif
+    uint64_t mstatus_hs;
 
     target_ulong scounteren;
     target_ulong mcounteren;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index bd36062877..62ca6b6f89 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -5,9 +5,14 @@
 
 #define get_field(reg, mask) (((reg) & \
                  (target_ulong)(mask)) / ((mask) & ~((mask) << 1)))
+#define get_field64(reg, mask) (((reg) & \
+                   (uint64_t)(mask)) / ((mask) & ~((mask) << 1)))
 #define set_field(reg, mask, val) (((reg) & ~(target_ulong)(mask)) | \
                  (((target_ulong)(val) * ((mask) & ~((mask) << 1))) & \
                  (target_ulong)(mask)))
+#define set_field64(reg, mask, val) (((reg) & ~(uint64_t)(mask)) | \
+                   (((uint64_t)(val) * ((mask) & ~((mask) << 1))) & \
+                   (uint64_t)(mask)))
 
 /* Floating point round mode */
 #define FSR_RD_SHIFT        5
@@ -381,19 +386,10 @@
 #define MSTATUS_TVM         0x00100000 /* since: priv-1.10 */
 #define MSTATUS_TW          0x20000000 /* since: priv-1.10 */
 #define MSTATUS_TSR         0x40000000 /* since: priv-1.10 */
-#if defined(TARGET_RISCV64)
 #define MSTATUS_GVA         0x4000000000ULL
 #define MSTATUS_MPV         0x8000000000ULL
-#elif defined(TARGET_RISCV32)
-#define MSTATUS_GVA         0x00000040
-#define MSTATUS_MPV         0x00000080
-#endif
 
-#ifdef TARGET_RISCV32
-# define MSTATUS_MPV_ISSET(env)  get_field(env->mstatush, MSTATUS_MPV)
-#else
-# define MSTATUS_MPV_ISSET(env)  get_field(env->mstatus, MSTATUS_MPV)
-#endif
+#define MSTATUS_MPV_ISSET(env)  get_field64(env->mstatus, MSTATUS_MPV)
 
 #define MSTATUS64_UXL       0x0000000300000000ULL
 #define MSTATUS64_SXL       0x0000000C00000000ULL
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 904899054d..0430cbe4e3 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -39,9 +39,9 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 {
     target_ulong irqs;
 
-    target_ulong mstatus_mie = get_field(env->mstatus, MSTATUS_MIE);
-    target_ulong mstatus_sie = get_field(env->mstatus, MSTATUS_SIE);
-    target_ulong hs_mstatus_sie = get_field(env->mstatus_hs, MSTATUS_SIE);
+    target_ulong mstatus_mie = get_field64(env->mstatus, MSTATUS_MIE);
+    target_ulong mstatus_sie = get_field64(env->mstatus, MSTATUS_SIE);
+    target_ulong hs_mstatus_sie = get_field64(env->mstatus_hs, MSTATUS_SIE);
 
     target_ulong pending = env->mip & env->mie &
                                ~(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP);
@@ -110,14 +110,20 @@ bool riscv_cpu_fp_enabled(CPURISCVState *env)
 
 void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
 {
-    target_ulong mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
-                                MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE;
+    uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
+                            MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE;
     bool current_virt = riscv_cpu_virt_enabled(env);
 
     g_assert(riscv_has_ext(env, RVH));
 
 #if defined(TARGET_RISCV64)
     mstatus_mask |= MSTATUS64_UXL;
+#elif defined(TARGET_RISCV32)
+    /*
+     * The upper 32 bits of env->mstatus is mstatush
+     * register in RISCV32. We need to backup it.
+     */
+    mstatus_mask |= (~0ULL << 32);
 #endif
 
     if (current_virt) {
@@ -126,11 +132,6 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
         env->mstatus &= ~mstatus_mask;
         env->mstatus |= env->mstatus_hs;
 
-#if defined(TARGET_RISCV32)
-        env->vsstatush = env->mstatush;
-        env->mstatush |= env->mstatush_hs;
-#endif
-
         env->vstvec = env->stvec;
         env->stvec = env->stvec_hs;
 
@@ -154,11 +155,6 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
         env->mstatus &= ~mstatus_mask;
         env->mstatus |= env->vsstatus;
 
-#if defined(TARGET_RISCV32)
-        env->mstatush_hs = env->mstatush;
-        env->mstatush |= env->vsstatush;
-#endif
-
         env->stvec_hs = env->stvec;
         env->stvec = env->vstvec;
 
@@ -347,8 +343,8 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
     }
 
     if (mode == PRV_M && access_type != MMU_INST_FETCH) {
-        if (get_field(env->mstatus, MSTATUS_MPRV)) {
-            mode = get_field(env->mstatus, MSTATUS_MPP);
+        if (get_field64(env->mstatus, MSTATUS_MPRV)) {
+            mode = get_field64(env->mstatus, MSTATUS_MPP);
         }
     }
 
@@ -370,9 +366,9 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
     int levels, ptidxbits, ptesize, vm, sum, mxr, widened;
 
     if (first_stage == true) {
-        mxr = get_field(env->mstatus, MSTATUS_MXR);
+        mxr = get_field64(env->mstatus, MSTATUS_MXR);
     } else {
-        mxr = get_field(env->vsstatus, MSTATUS_MXR);
+        mxr = get_field64(env->vsstatus, MSTATUS_MXR);
     }
 
     if (first_stage == true) {
@@ -389,7 +385,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
         vm = get_field(env->hgatp, HGATP_MODE);
         widened = 2;
     }
-    sum = get_field(env->mstatus, MSTATUS_SUM);
+    sum = get_field64(env->mstatus, MSTATUS_SUM);
     switch (vm) {
     case VM_1_10_SV32:
       levels = 2; ptidxbits = 10; ptesize = 4; break;
@@ -712,14 +708,14 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
                   __func__, address, access_type, mmu_idx);
 
     if (mode == PRV_M && access_type != MMU_INST_FETCH) {
-        if (get_field(env->mstatus, MSTATUS_MPRV)) {
-            mode = get_field(env->mstatus, MSTATUS_MPP);
+        if (get_field64(env->mstatus, MSTATUS_MPRV)) {
+            mode = get_field64(env->mstatus, MSTATUS_MPP);
         }
     }
 
     if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
         access_type != MMU_INST_FETCH &&
-        get_field(env->mstatus, MSTATUS_MPRV) &&
+        get_field64(env->mstatus, MSTATUS_MPRV) &&
         MSTATUS_MPV_ISSET(env)) {
         riscv_cpu_set_two_stage_lookup(env, true);
     }
@@ -780,7 +776,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
     /* We did the two stage lookup based on MPRV, unset the lookup */
     if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
         access_type != MMU_INST_FETCH &&
-        get_field(env->mstatus, MSTATUS_MPRV) &&
+        get_field64(env->mstatus, MSTATUS_MPRV) &&
         MSTATUS_MPV_ISSET(env)) {
         riscv_cpu_set_two_stage_lookup(env, false);
     }
@@ -844,7 +840,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
     bool force_hs_execp = riscv_cpu_force_hs_excep_enabled(env);
-    target_ulong s;
+    uint64_t s;
 
     /* cs->exception is 32-bits wide unlike mcause which is XLEN-bits wide
      * so we mask off the MSB and separate into trap type and cause.
@@ -932,7 +928,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
                 /* Trap into HS mode, from virt */
                 riscv_cpu_swap_hypervisor_regs(env);
                 env->hstatus = set_field(env->hstatus, HSTATUS_SPVP,
-                                         get_field(env->mstatus, SSTATUS_SPP));
+                                         get_field64(env->mstatus, SSTATUS_SPP));
                 env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
                                          riscv_cpu_virt_enabled(env));
 
@@ -952,9 +948,9 @@ void riscv_cpu_do_interrupt(CPUState *cs)
         }
 
         s = env->mstatus;
-        s = set_field(s, MSTATUS_SPIE, get_field(s, MSTATUS_SIE));
-        s = set_field(s, MSTATUS_SPP, env->priv);
-        s = set_field(s, MSTATUS_SIE, 0);
+        s = set_field64(s, MSTATUS_SPIE, get_field64(s, MSTATUS_SIE));
+        s = set_field64(s, MSTATUS_SPP, env->priv);
+        s = set_field64(s, MSTATUS_SIE, 0);
         env->mstatus = s;
         env->scause = cause | ((target_ulong)async << (TARGET_LONG_BITS - 1));
         env->sepc = env->pc;
@@ -969,19 +965,11 @@ void riscv_cpu_do_interrupt(CPUState *cs)
             if (riscv_cpu_virt_enabled(env)) {
                 riscv_cpu_swap_hypervisor_regs(env);
             }
-#ifdef TARGET_RISCV32
-            env->mstatush = set_field(env->mstatush, MSTATUS_MPV,
+            env->mstatus = set_field64(env->mstatus, MSTATUS_MPV,
                                        riscv_cpu_virt_enabled(env));
             if (riscv_cpu_virt_enabled(env) && tval) {
-                env->mstatush = set_field(env->mstatush, MSTATUS_GVA, 1);
-            }
-#else
-            env->mstatus = set_field(env->mstatus, MSTATUS_MPV,
-                                      riscv_cpu_virt_enabled(env));
-            if (riscv_cpu_virt_enabled(env) && tval) {
-                env->mstatus = set_field(env->mstatus, MSTATUS_GVA, 1);
+                env->mstatus = set_field64(env->mstatus, MSTATUS_GVA, 1);
             }
-#endif
 
             mtval2 = env->guest_phys_fault_addr;
 
@@ -991,9 +979,9 @@ void riscv_cpu_do_interrupt(CPUState *cs)
         }
 
         s = env->mstatus;
-        s = set_field(s, MSTATUS_MPIE, get_field(s, MSTATUS_MIE));
-        s = set_field(s, MSTATUS_MPP, env->priv);
-        s = set_field(s, MSTATUS_MIE, 0);
+        s = set_field64(s, MSTATUS_MPIE, get_field64(s, MSTATUS_MIE));
+        s = set_field64(s, MSTATUS_MPP, env->priv);
+        s = set_field64(s, MSTATUS_MIE, 0);
         env->mstatus = s;
         env->mcause = cause | ~(((target_ulong)-1) >> async);
         env->mepc = env->pc;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index aaef6c6f20..d4b6371719 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -446,8 +446,8 @@ static int validate_vm(CPURISCVState *env, target_ulong vm)
 
 static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
 {
-    target_ulong mstatus = env->mstatus;
-    target_ulong mask = 0;
+    uint64_t mstatus = env->mstatus;
+    uint64_t mask = 0;
     int dirty;
 
     /* flush tlb on mstatus fields that affect VM */
@@ -471,7 +471,7 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
 
     dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) |
             ((mstatus & MSTATUS_XS) == MSTATUS_XS);
-    mstatus = set_field(mstatus, MSTATUS_SD, dirty);
+    mstatus = set_field64(mstatus, MSTATUS_SD, dirty);
     env->mstatus = mstatus;
 
     return 0;
@@ -480,19 +480,20 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
 #ifdef TARGET_RISCV32
 static int read_mstatush(CPURISCVState *env, int csrno, target_ulong *val)
 {
-    *val = env->mstatush;
+    *val = env->mstatus >> 32;
     return 0;
 }
 
 static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
 {
-    if ((val ^ env->mstatush) & (MSTATUS_MPV)) {
+    uint64_t valh = (uint64_t)val << 32;
+    uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
+
+    if ((valh ^ env->mstatus) & (MSTATUS_MPV)) {
         tlb_flush(env_cpu(env));
     }
 
-    val &= MSTATUS_MPV | MSTATUS_GVA;
-
-    env->mstatush = val;
+    env->mstatus = (env->mstatus & ~mask) | (valh & mask);
 
     return 0;
 }
@@ -718,14 +719,14 @@ static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value,
 static int read_sstatus(CPURISCVState *env, int csrno, target_ulong *val)
 {
     target_ulong mask = (sstatus_v1_10_mask);
-    *val = env->mstatus & mask;
+    *val = (target_ulong)env->mstatus & mask;
     return 0;
 }
 
 static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
 {
     target_ulong mask = (sstatus_v1_10_mask);
-    target_ulong newval = (env->mstatus & ~mask) | (val & mask);
+    target_ulong newval = ((target_ulong)env->mstatus & ~mask) | (val & mask);
     return write_mstatus(env, CSR_MSTATUS, newval);
 }
 
@@ -861,7 +862,7 @@ static int read_satp(CPURISCVState *env, int csrno, target_ulong *val)
         return 0;
     }
 
-    if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+    if (env->priv == PRV_S && get_field64(env->mstatus, MSTATUS_TVM)) {
         return -RISCV_EXCP_ILLEGAL_INST;
     } else {
         *val = env->satp;
@@ -878,7 +879,7 @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
     if (validate_vm(env, get_field(val, SATP_MODE)) &&
         ((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN)))
     {
-        if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+        if (env->priv == PRV_S && get_field64(env->mstatus, MSTATUS_TVM)) {
             return -RISCV_EXCP_ILLEGAL_INST;
         } else {
             if((val ^ env->satp) & SATP_ASID) {
@@ -1105,7 +1106,8 @@ static int read_vsstatus(CPURISCVState *env, int csrno, target_ulong *val)
 
 static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
 {
-    env->vsstatus = val;
+    uint64_t mask = (target_ulong)-1;
+    env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
     return 0;
 }
 
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 9b9ada45a9..18cdffc738 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -79,7 +79,8 @@ target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
 
 target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
 {
-    target_ulong prev_priv, prev_virt, mstatus;
+    uint64_t mstatus;
+    target_ulong prev_priv, prev_virt;
 
     if (!(env->priv >= PRV_S)) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
@@ -90,7 +91,7 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
         riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
     }
 
-    if (get_field(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) {
+    if (get_field64(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
     }
 
@@ -105,14 +106,14 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
         /* We support Hypervisor extensions and virtulisation is disabled */
         target_ulong hstatus = env->hstatus;
 
-        prev_priv = get_field(mstatus, MSTATUS_SPP);
+        prev_priv = get_field64(mstatus, MSTATUS_SPP);
         prev_virt = get_field(hstatus, HSTATUS_SPV);
 
         hstatus = set_field(hstatus, HSTATUS_SPV, 0);
-        mstatus = set_field(mstatus, MSTATUS_SPP, 0);
-        mstatus = set_field(mstatus, SSTATUS_SIE,
-                            get_field(mstatus, SSTATUS_SPIE));
-        mstatus = set_field(mstatus, SSTATUS_SPIE, 1);
+        mstatus = set_field64(mstatus, MSTATUS_SPP, 0);
+        mstatus = set_field64(mstatus, SSTATUS_SIE,
+                              get_field64(mstatus, SSTATUS_SPIE));
+        mstatus = set_field64(mstatus, SSTATUS_SPIE, 1);
 
         env->mstatus = mstatus;
         env->hstatus = hstatus;
@@ -123,12 +124,12 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
 
         riscv_cpu_set_virt_enabled(env, prev_virt);
     } else {
-        prev_priv = get_field(mstatus, MSTATUS_SPP);
+        prev_priv = get_field64(mstatus, MSTATUS_SPP);
 
-        mstatus = set_field(mstatus, MSTATUS_SIE,
-                            get_field(mstatus, MSTATUS_SPIE));
-        mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
-        mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
+        mstatus = set_field64(mstatus, MSTATUS_SIE,
+                              get_field64(mstatus, MSTATUS_SPIE));
+        mstatus = set_field64(mstatus, MSTATUS_SPIE, 1);
+        mstatus = set_field64(mstatus, MSTATUS_SPP, PRV_U);
         env->mstatus = mstatus;
     }
 
@@ -148,18 +149,14 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
         riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
     }
 
-    target_ulong mstatus = env->mstatus;
-    target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
+    uint64_t mstatus = env->mstatus;
+    target_ulong prev_priv = get_field64(mstatus, MSTATUS_MPP);
     target_ulong prev_virt = MSTATUS_MPV_ISSET(env);
-    mstatus = set_field(mstatus, MSTATUS_MIE,
-                        get_field(mstatus, MSTATUS_MPIE));
-    mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
-    mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
-#ifdef TARGET_RISCV32
-    env->mstatush = set_field(env->mstatush, MSTATUS_MPV, 0);
-#else
-    mstatus = set_field(mstatus, MSTATUS_MPV, 0);
-#endif
+    mstatus = set_field64(mstatus, MSTATUS_MIE,
+                          get_field64(mstatus, MSTATUS_MPIE));
+    mstatus = set_field64(mstatus, MSTATUS_MPIE, 1);
+    mstatus = set_field64(mstatus, MSTATUS_MPP, PRV_U);
+    mstatus = set_field64(mstatus, MSTATUS_MPV, 0);
     env->mstatus = mstatus;
     riscv_cpu_set_mode(env, prev_priv);
 
@@ -179,7 +176,7 @@ void helper_wfi(CPURISCVState *env)
     CPUState *cs = env_cpu(env);
 
     if ((env->priv == PRV_S &&
-        get_field(env->mstatus, MSTATUS_TW)) ||
+        get_field64(env->mstatus, MSTATUS_TW)) ||
         riscv_cpu_virt_enabled(env)) {
         riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
     } else {
@@ -194,7 +191,7 @@ void helper_tlb_flush(CPURISCVState *env)
     CPUState *cs = env_cpu(env);
     if (!(env->priv >= PRV_S) ||
         (env->priv == PRV_S &&
-         get_field(env->mstatus, MSTATUS_TVM))) {
+         get_field64(env->mstatus, MSTATUS_TVM))) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
     } else if (riscv_has_ext(env, RVH) && riscv_cpu_virt_enabled(env) &&
                get_field(env->hstatus, HSTATUS_VTVM)) {
@@ -224,7 +221,7 @@ void helper_hyp_tlb_flush(CPURISCVState *env)
 void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
 {
     if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) &&
-        get_field(env->mstatus, MSTATUS_TVM)) {
+        get_field64(env->mstatus, MSTATUS_TVM)) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
     }
 
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V3 2/6] target/riscv: Add basic vmstate description of CPU
  2020-10-23  9:12 [PATCH V3 0/6] Support RISC-V migration Yifei Jiang
  2020-10-23  9:12 ` [PATCH V3 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit Yifei Jiang
@ 2020-10-23  9:12 ` Yifei Jiang
  2020-10-23 23:52   ` Alistair Francis
  2020-10-23  9:12 ` [PATCH V3 3/6] target/riscv: Add PMP state description Yifei Jiang
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Yifei Jiang @ 2020-10-23  9:12 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: zhang.zhanghailiang, sagark, kbastian, victor.zhangxiaofeng,
	richard.henderson, Yifei Jiang, Alistair.Francis, yinyipeng1,
	palmer, wu.wubin, dengkai1

Add basic CPU state description to the newly created machine.c

Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
---
 target/riscv/cpu.c       |  8 +----
 target/riscv/internals.h |  4 +++
 target/riscv/machine.c   | 74 ++++++++++++++++++++++++++++++++++++++++
 target/riscv/meson.build |  3 +-
 4 files changed, 81 insertions(+), 8 deletions(-)
 create mode 100644 target/riscv/machine.c

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index dd05a220c7..6a0264fc6b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -22,6 +22,7 @@
 #include "qemu/ctype.h"
 #include "qemu/log.h"
 #include "cpu.h"
+#include "internals.h"
 #include "exec/exec-all.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
@@ -498,13 +499,6 @@ static void riscv_cpu_init(Object *obj)
     cpu_set_cpustate_pointers(cpu);
 }
 
-#ifndef CONFIG_USER_ONLY
-static const VMStateDescription vmstate_riscv_cpu = {
-    .name = "cpu",
-    .unmigratable = 1,
-};
-#endif
-
 static Property riscv_cpu_properties[] = {
     DEFINE_PROP_BOOL("i", RISCVCPU, cfg.ext_i, true),
     DEFINE_PROP_BOOL("e", RISCVCPU, cfg.ext_e, false),
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index f1a546dba6..b15ad394bb 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -38,6 +38,10 @@ target_ulong fclass_d(uint64_t frs1);
 #define SEW32 2
 #define SEW64 3
 
+#ifndef CONFIG_USER_ONLY
+extern const VMStateDescription vmstate_riscv_cpu;
+#endif
+
 static inline uint64_t nanbox_s(float32 f)
 {
     return f | MAKE_64BIT_MASK(32, 32);
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
new file mode 100644
index 0000000000..32edbcba7c
--- /dev/null
+++ b/target/riscv/machine.c
@@ -0,0 +1,74 @@
+/*
+ * RISC-V VMState Description
+ *
+ * Copyright (c) 2020 Huawei Technologies Co., Ltd
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "qemu/error-report.h"
+#include "sysemu/kvm.h"
+#include "migration/cpu.h"
+
+const VMStateDescription vmstate_riscv_cpu = {
+    .name = "cpu",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
+        VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
+        VMSTATE_UINTTL(env.pc, RISCVCPU),
+        VMSTATE_UINTTL(env.load_res, RISCVCPU),
+        VMSTATE_UINTTL(env.load_val, RISCVCPU),
+        VMSTATE_UINTTL(env.frm, RISCVCPU),
+        VMSTATE_UINTTL(env.badaddr, RISCVCPU),
+        VMSTATE_UINTTL(env.guest_phys_fault_addr, RISCVCPU),
+        VMSTATE_UINTTL(env.priv_ver, RISCVCPU),
+        VMSTATE_UINTTL(env.vext_ver, RISCVCPU),
+        VMSTATE_UINTTL(env.misa, RISCVCPU),
+        VMSTATE_UINTTL(env.misa_mask, RISCVCPU),
+        VMSTATE_UINT32(env.features, RISCVCPU),
+        VMSTATE_UINTTL(env.priv, RISCVCPU),
+        VMSTATE_UINTTL(env.virt, RISCVCPU),
+        VMSTATE_UINTTL(env.resetvec, RISCVCPU),
+        VMSTATE_UINTTL(env.mhartid, RISCVCPU),
+        VMSTATE_UINT64(env.mstatus, RISCVCPU),
+        VMSTATE_UINTTL(env.mip, RISCVCPU),
+        VMSTATE_UINT32(env.miclaim, RISCVCPU),
+        VMSTATE_UINTTL(env.mie, RISCVCPU),
+        VMSTATE_UINTTL(env.mideleg, RISCVCPU),
+        VMSTATE_UINTTL(env.sptbr, RISCVCPU),
+        VMSTATE_UINTTL(env.satp, RISCVCPU),
+        VMSTATE_UINTTL(env.sbadaddr, RISCVCPU),
+        VMSTATE_UINTTL(env.mbadaddr, RISCVCPU),
+        VMSTATE_UINTTL(env.medeleg, RISCVCPU),
+        VMSTATE_UINTTL(env.stvec, RISCVCPU),
+        VMSTATE_UINTTL(env.sepc, RISCVCPU),
+        VMSTATE_UINTTL(env.scause, RISCVCPU),
+        VMSTATE_UINTTL(env.mtvec, RISCVCPU),
+        VMSTATE_UINTTL(env.mepc, RISCVCPU),
+        VMSTATE_UINTTL(env.mcause, RISCVCPU),
+        VMSTATE_UINTTL(env.mtval, RISCVCPU),
+        VMSTATE_UINTTL(env.scounteren, RISCVCPU),
+        VMSTATE_UINTTL(env.mcounteren, RISCVCPU),
+        VMSTATE_UINTTL(env.sscratch, RISCVCPU),
+        VMSTATE_UINTTL(env.mscratch, RISCVCPU),
+        VMSTATE_UINT64(env.mfromhost, RISCVCPU),
+        VMSTATE_UINT64(env.mtohost, RISCVCPU),
+        VMSTATE_UINT64(env.timecmp, RISCVCPU),
+
+        VMSTATE_END_OF_LIST()
+    }
+};
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index abd647fea1..14a5c62dac 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -27,7 +27,8 @@ riscv_ss.add(files(
 riscv_softmmu_ss = ss.source_set()
 riscv_softmmu_ss.add(files(
   'pmp.c',
-  'monitor.c'
+  'monitor.c',
+  'machine.c'
 ))
 
 target_arch += {'riscv': riscv_ss}
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V3 3/6] target/riscv: Add PMP state description
  2020-10-23  9:12 [PATCH V3 0/6] Support RISC-V migration Yifei Jiang
  2020-10-23  9:12 ` [PATCH V3 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit Yifei Jiang
  2020-10-23  9:12 ` [PATCH V3 2/6] target/riscv: Add basic vmstate description of CPU Yifei Jiang
@ 2020-10-23  9:12 ` Yifei Jiang
  2020-10-23 23:59   ` Alistair Francis
  2020-10-23  9:12 ` [PATCH V3 4/6] target/riscv: Add H extension " Yifei Jiang
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Yifei Jiang @ 2020-10-23  9:12 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: zhang.zhanghailiang, sagark, kbastian, victor.zhangxiaofeng,
	richard.henderson, Yifei Jiang, Alistair.Francis, yinyipeng1,
	palmer, wu.wubin, dengkai1

In the case of supporting PMP feature, add PMP state description
to vmstate_riscv_cpu.

'vmstate_pmp_addr' and 'num_rules' could be regenerated by
pmp_update_rule(). But there exists the problem of updating
num_rules repeatedly in pmp_update_rule(). So here extracts
pmp_update_rule_addr() and pmp_update_rule_nums() to update
'vmstate_pmp_addr' and 'num_rules' respectively.

Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
---
 target/riscv/machine.c | 50 ++++++++++++++++++++++++++++++++++++++++++
 target/riscv/pmp.c     | 29 ++++++++++++++----------
 target/riscv/pmp.h     |  2 ++
 3 files changed, 70 insertions(+), 11 deletions(-)

diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 32edbcba7c..fc1461d88e 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -22,6 +22,52 @@
 #include "sysemu/kvm.h"
 #include "migration/cpu.h"
 
+static bool pmp_needed(void *opaque)
+{
+    RISCVCPU *cpu = opaque;
+    CPURISCVState *env = &cpu->env;
+
+    return riscv_feature(env, RISCV_FEATURE_PMP);
+}
+
+static int pmp_post_load(void *opaque, int version_id)
+{
+    RISCVCPU *cpu = opaque;
+    CPURISCVState *env = &cpu->env;
+    int i;
+
+    for (i = 0; i < MAX_RISCV_PMPS; i++) {
+        pmp_update_rule_addr(env, i);
+    }
+    pmp_update_rule_nums(env);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_pmp_entry = {
+    .name = "cpu/pmp/entry",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINTTL(addr_reg, pmp_entry_t),
+        VMSTATE_UINT8(cfg_reg, pmp_entry_t),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_pmp = {
+    .name = "cpu/pmp",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = pmp_needed,
+    .post_load = pmp_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_STRUCT_ARRAY(env.pmp_state.pmp, RISCVCPU, MAX_RISCV_PMPS,
+                             0, vmstate_pmp_entry, pmp_entry_t),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 const VMStateDescription vmstate_riscv_cpu = {
     .name = "cpu",
     .version_id = 1,
@@ -70,5 +116,9 @@ const VMStateDescription vmstate_riscv_cpu = {
         VMSTATE_UINT64(env.timecmp, RISCVCPU),
 
         VMSTATE_END_OF_LIST()
+    },
+    .subsections = (const VMStateDescription * []) {
+        &vmstate_pmp,
+        NULL
     }
 };
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index c394e867f8..2eda8e1e2f 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -136,18 +136,8 @@ static void pmp_decode_napot(target_ulong a, target_ulong *sa, target_ulong *ea)
     }
 }
 
-
-/* Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea'
- *   end address values.
- *   This function is called relatively infrequently whereas the check that
- *   an address is within a pmp rule is called often, so optimise that one
- */
-static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
+void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
 {
-    int i;
-
-    env->pmp_state.num_rules = 0;
-
     uint8_t this_cfg = env->pmp_state.pmp[pmp_index].cfg_reg;
     target_ulong this_addr = env->pmp_state.pmp[pmp_index].addr_reg;
     target_ulong prev_addr = 0u;
@@ -186,7 +176,13 @@ static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
 
     env->pmp_state.addr[pmp_index].sa = sa;
     env->pmp_state.addr[pmp_index].ea = ea;
+}
 
+void pmp_update_rule_nums(CPURISCVState *env)
+{
+    int i;
+
+    env->pmp_state.num_rules = 0;
     for (i = 0; i < MAX_RISCV_PMPS; i++) {
         const uint8_t a_field =
             pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
@@ -196,6 +192,17 @@ static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
     }
 }
 
+/* Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea'
+ *   end address values.
+ *   This function is called relatively infrequently whereas the check that
+ *   an address is within a pmp rule is called often, so optimise that one
+ */
+static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
+{
+    pmp_update_rule_addr(env, pmp_index);
+    pmp_update_rule_nums(env);
+}
+
 static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong addr)
 {
     int result = 0;
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index 6a8f072871..6c6b4c9bef 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -62,5 +62,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
     target_ulong size, pmp_priv_t priv, target_ulong mode);
 bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
                          target_ulong *tlb_size);
+void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
+void pmp_update_rule_nums(CPURISCVState *env);
 
 #endif
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V3 4/6] target/riscv: Add H extension state description
  2020-10-23  9:12 [PATCH V3 0/6] Support RISC-V migration Yifei Jiang
                   ` (2 preceding siblings ...)
  2020-10-23  9:12 ` [PATCH V3 3/6] target/riscv: Add PMP state description Yifei Jiang
@ 2020-10-23  9:12 ` Yifei Jiang
  2020-10-24  0:00   ` Alistair Francis
  2020-10-23  9:12 ` [PATCH V3 5/6] target/riscv: Add V " Yifei Jiang
  2020-10-23  9:12 ` [PATCH V3 6/6] target/riscv: Add sifive_plic vmstate Yifei Jiang
  5 siblings, 1 reply; 14+ messages in thread
From: Yifei Jiang @ 2020-10-23  9:12 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: zhang.zhanghailiang, sagark, kbastian, victor.zhangxiaofeng,
	richard.henderson, Yifei Jiang, Alistair.Francis, yinyipeng1,
	palmer, wu.wubin, dengkai1

In the case of supporting H extension, add H extension description
to vmstate_riscv_cpu.

Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
---
 target/riscv/machine.c | 47 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index fc1461d88e..ae60050898 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -68,6 +68,52 @@ static const VMStateDescription vmstate_pmp = {
     }
 };
 
+static bool hyper_needed(void *opaque)
+{
+    RISCVCPU *cpu = opaque;
+    CPURISCVState *env = &cpu->env;
+
+    return riscv_has_ext(env, RVH);
+}
+
+static const VMStateDescription vmstate_hyper = {
+    .name = "cpu/hyper",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = hyper_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINTTL(env.hstatus, RISCVCPU),
+        VMSTATE_UINTTL(env.hedeleg, RISCVCPU),
+        VMSTATE_UINTTL(env.hideleg, RISCVCPU),
+        VMSTATE_UINTTL(env.hcounteren, RISCVCPU),
+        VMSTATE_UINTTL(env.htval, RISCVCPU),
+        VMSTATE_UINTTL(env.htinst, RISCVCPU),
+        VMSTATE_UINTTL(env.hgatp, RISCVCPU),
+        VMSTATE_UINT64(env.htimedelta, RISCVCPU),
+
+        VMSTATE_UINT64(env.vsstatus, RISCVCPU),
+        VMSTATE_UINTTL(env.vstvec, RISCVCPU),
+        VMSTATE_UINTTL(env.vsscratch, RISCVCPU),
+        VMSTATE_UINTTL(env.vsepc, RISCVCPU),
+        VMSTATE_UINTTL(env.vscause, RISCVCPU),
+        VMSTATE_UINTTL(env.vstval, RISCVCPU),
+        VMSTATE_UINTTL(env.vsatp, RISCVCPU),
+
+        VMSTATE_UINTTL(env.mtval2, RISCVCPU),
+        VMSTATE_UINTTL(env.mtinst, RISCVCPU),
+
+        VMSTATE_UINTTL(env.stvec_hs, RISCVCPU),
+        VMSTATE_UINTTL(env.sscratch_hs, RISCVCPU),
+        VMSTATE_UINTTL(env.sepc_hs, RISCVCPU),
+        VMSTATE_UINTTL(env.scause_hs, RISCVCPU),
+        VMSTATE_UINTTL(env.stval_hs, RISCVCPU),
+        VMSTATE_UINTTL(env.satp_hs, RISCVCPU),
+        VMSTATE_UINT64(env.mstatus_hs, RISCVCPU),
+
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 const VMStateDescription vmstate_riscv_cpu = {
     .name = "cpu",
     .version_id = 1,
@@ -119,6 +165,7 @@ const VMStateDescription vmstate_riscv_cpu = {
     },
     .subsections = (const VMStateDescription * []) {
         &vmstate_pmp,
+        &vmstate_hyper,
         NULL
     }
 };
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V3 5/6] target/riscv: Add V extension state description
  2020-10-23  9:12 [PATCH V3 0/6] Support RISC-V migration Yifei Jiang
                   ` (3 preceding siblings ...)
  2020-10-23  9:12 ` [PATCH V3 4/6] target/riscv: Add H extension " Yifei Jiang
@ 2020-10-23  9:12 ` Yifei Jiang
  2020-10-24  0:01   ` Alistair Francis
  2020-10-23  9:12 ` [PATCH V3 6/6] target/riscv: Add sifive_plic vmstate Yifei Jiang
  5 siblings, 1 reply; 14+ messages in thread
From: Yifei Jiang @ 2020-10-23  9:12 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: zhang.zhanghailiang, sagark, kbastian, victor.zhangxiaofeng,
	richard.henderson, Yifei Jiang, Alistair.Francis, yinyipeng1,
	palmer, wu.wubin, dengkai1

In the case of supporting V extension, add V extension description
to vmstate_riscv_cpu.

Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/machine.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index ae60050898..44d4015bd6 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -76,6 +76,30 @@ static bool hyper_needed(void *opaque)
     return riscv_has_ext(env, RVH);
 }
 
+static bool vector_needed(void *opaque)
+{
+    RISCVCPU *cpu = opaque;
+    CPURISCVState *env = &cpu->env;
+
+    return riscv_has_ext(env, RVV);
+}
+
+static const VMStateDescription vmstate_vector = {
+    .name = "cpu/vector",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = vector_needed,
+    .fields = (VMStateField[]) {
+            VMSTATE_UINT64_ARRAY(env.vreg, RISCVCPU, 32 * RV_VLEN_MAX / 64),
+            VMSTATE_UINTTL(env.vxrm, RISCVCPU),
+            VMSTATE_UINTTL(env.vxsat, RISCVCPU),
+            VMSTATE_UINTTL(env.vl, RISCVCPU),
+            VMSTATE_UINTTL(env.vstart, RISCVCPU),
+            VMSTATE_UINTTL(env.vtype, RISCVCPU),
+            VMSTATE_END_OF_LIST()
+        }
+};
+
 static const VMStateDescription vmstate_hyper = {
     .name = "cpu/hyper",
     .version_id = 1,
@@ -166,6 +190,7 @@ const VMStateDescription vmstate_riscv_cpu = {
     .subsections = (const VMStateDescription * []) {
         &vmstate_pmp,
         &vmstate_hyper,
+        &vmstate_vector,
         NULL
     }
 };
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V3 6/6] target/riscv: Add sifive_plic vmstate
  2020-10-23  9:12 [PATCH V3 0/6] Support RISC-V migration Yifei Jiang
                   ` (4 preceding siblings ...)
  2020-10-23  9:12 ` [PATCH V3 5/6] target/riscv: Add V " Yifei Jiang
@ 2020-10-23  9:12 ` Yifei Jiang
  2020-10-24  0:02   ` Alistair Francis
  5 siblings, 1 reply; 14+ messages in thread
From: Yifei Jiang @ 2020-10-23  9:12 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: zhang.zhanghailiang, sagark, kbastian, victor.zhangxiaofeng,
	richard.henderson, Yifei Jiang, Alistair.Francis, yinyipeng1,
	palmer, wu.wubin, dengkai1

Add sifive_plic vmstate for supporting sifive_plic migration.
Current vmstate framework only supports one structure parameter
as num field to describe variable length arrays, so introduce
num_enables.

Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
---
 hw/intc/sifive_plic.c | 26 +++++++++++++++++++++++++-
 hw/intc/sifive_plic.h |  1 +
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index f42fd695d8..97a1a27a9a 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -30,6 +30,7 @@
 #include "hw/intc/sifive_plic.h"
 #include "target/riscv/cpu.h"
 #include "sysemu/sysemu.h"
+#include "migration/vmstate.h"
 
 #define RISCV_DEBUG_PLIC 0
 
@@ -448,11 +449,12 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
                           TYPE_SIFIVE_PLIC, plic->aperture_size);
     parse_hart_config(plic);
     plic->bitfield_words = (plic->num_sources + 31) >> 5;
+    plic->num_enables = plic->bitfield_words * plic->num_addrs;
     plic->source_priority = g_new0(uint32_t, plic->num_sources);
     plic->target_priority = g_new(uint32_t, plic->num_addrs);
     plic->pending = g_new0(uint32_t, plic->bitfield_words);
     plic->claimed = g_new0(uint32_t, plic->bitfield_words);
-    plic->enable = g_new0(uint32_t, plic->bitfield_words * plic->num_addrs);
+    plic->enable = g_new0(uint32_t, plic->num_enables);
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &plic->mmio);
     qdev_init_gpio_in(dev, sifive_plic_irq_request, plic->num_sources);
 
@@ -472,12 +474,34 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
     msi_nonbroken = true;
 }
 
+static const VMStateDescription vmstate_sifive_plic = {
+    .name = "riscv_sifive_plic",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+            VMSTATE_VARRAY_UINT32(source_priority, SiFivePLICState,
+                                  num_sources, 0,
+                                  vmstate_info_uint32, uint32_t),
+            VMSTATE_VARRAY_UINT32(target_priority, SiFivePLICState,
+                                  num_addrs, 0,
+                                  vmstate_info_uint32, uint32_t),
+            VMSTATE_VARRAY_UINT32(pending, SiFivePLICState, bitfield_words, 0,
+                                  vmstate_info_uint32, uint32_t),
+            VMSTATE_VARRAY_UINT32(claimed, SiFivePLICState, bitfield_words, 0,
+                                  vmstate_info_uint32, uint32_t),
+            VMSTATE_VARRAY_UINT32(enable, SiFivePLICState, num_enables, 0,
+                                  vmstate_info_uint32, uint32_t),
+            VMSTATE_END_OF_LIST()
+        }
+};
+
 static void sifive_plic_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     device_class_set_props(dc, sifive_plic_properties);
     dc->realize = sifive_plic_realize;
+    dc->vmsd = &vmstate_sifive_plic;
 }
 
 static const TypeInfo sifive_plic_info = {
diff --git a/hw/intc/sifive_plic.h b/hw/intc/sifive_plic.h
index b75b1f145d..1e451a270c 100644
--- a/hw/intc/sifive_plic.h
+++ b/hw/intc/sifive_plic.h
@@ -52,6 +52,7 @@ struct SiFivePLICState {
     uint32_t num_addrs;
     uint32_t num_harts;
     uint32_t bitfield_words;
+    uint32_t num_enables;
     PLICAddr *addr_config;
     uint32_t *source_priority;
     uint32_t *target_priority;
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* RE: [PATCH V3 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit
  2020-10-23  9:12 ` [PATCH V3 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit Yifei Jiang
@ 2020-10-23  9:41   ` Jiangyifei
  2020-10-23 23:50   ` Alistair Francis
  1 sibling, 0 replies; 14+ messages in thread
From: Jiangyifei @ 2020-10-23  9:41 UTC (permalink / raw)
  To: Alistair.Francis
  Cc: qemu-riscv, Zhanghailiang, sagark, kbastian, Zhangxiaofeng (F),
	richard.henderson, qemu-devel, palmer, yinyipeng, Wubin (H),
	dengkai (A)


> -----Original Message-----
> From: Jiangyifei
> Sent: Friday, October 23, 2020 5:12 PM
> To: qemu-devel@nongnu.org; qemu-riscv@nongnu.org
> Cc: palmer@dabbelt.com; Alistair.Francis@wdc.com;
> sagark@eecs.berkeley.edu; kbastian@mail.uni-paderborn.de;
> richard.henderson@linaro.org; Zhangxiaofeng (F)
> <victor.zhangxiaofeng@huawei.com>; Wubin (H) <wu.wubin@huawei.com>;
> Zhanghailiang <zhang.zhanghailiang@huawei.com>; dengkai (A)
> <dengkai1@huawei.com>; yinyipeng <yinyipeng1@huawei.com>; Jiangyifei
> <jiangyifei@huawei.com>
> Subject: [PATCH V3 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into
> one uint64_t unit
> 
> mstatus/mstatush and vsstatus/vsstatush are two halved for RISCV32.
> This patch expands mstatus and vsstatus to uint64_t instead of target_ulong
> so that it can be saved as one unit and reduce some ifdefs in the code.
> 
> Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
> Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
> ---
......
>  static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
> {
> -    if ((val ^ env->mstatush) & (MSTATUS_MPV)) {
> +    uint64_t valh = (uint64_t)val << 32;
> +    uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
> +
> +    if ((valh ^ env->mstatus) & (MSTATUS_MPV)) {
>          tlb_flush(env_cpu(env));
>      }
> 
> -    val &= MSTATUS_MPV | MSTATUS_GVA;
> -
> -    env->mstatush = val;
> +    env->mstatus = (env->mstatus & ~mask) | (valh & mask);
> 
>      return 0;
>  }

Hi Alistair,

It's a little different here.

Previously, except for MPV and GVA, other bits were cleared.
Now, except for MPV and GVA, other bits are reserved.
Refer to write_mstatus () and specification, I think it's better now.
How does it sound?

Yifei



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit
  2020-10-23  9:12 ` [PATCH V3 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit Yifei Jiang
  2020-10-23  9:41   ` Jiangyifei
@ 2020-10-23 23:50   ` Alistair Francis
  1 sibling, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2020-10-23 23:50 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: open list:RISC-V, Zhanghailiang, Sagar Karandikar,
	Bastian Koppelmann, Zhangxiaofeng (F),
	Richard Henderson, qemu-devel@nongnu.org Developers,
	Alistair Francis, yinyipeng, Palmer Dabbelt, Wubin (H),
	dengkai (A)

On Fri, Oct 23, 2020 at 2:17 AM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> mstatus/mstatush and vsstatus/vsstatush are two halved for RISCV32.
> This patch expands mstatus and vsstatus to uint64_t instead of
> target_ulong so that it can be saved as one unit and reduce some
> ifdefs in the code.
>
> Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
> Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>

Argh. I just sent a similar patch. I was hoping to save you having to do this.

Sorry about that.

I'm happy to apply yours as it was first.

> ---
>  target/riscv/cpu.c        |  8 +++--
>  target/riscv/cpu.h        | 16 ++-------
>  target/riscv/cpu_bits.h   | 16 ++++-----
>  target/riscv/cpu_helper.c | 72 ++++++++++++++++-----------------------
>  target/riscv/csr.c        | 28 ++++++++-------
>  target/riscv/op_helper.c  | 49 +++++++++++++-------------
>  6 files changed, 82 insertions(+), 107 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0bbfd7f457..dd05a220c7 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -216,13 +216,15 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
>      qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc      ", env->pc);
>  #ifndef CONFIG_USER_ONLY
>      qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
> -    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
> +    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", (target_ulong)env->mstatus);
>  #ifdef TARGET_RISCV32
> -    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ", env->mstatush);
> +    qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ",
> +                 (target_ulong)(env->mstatus >> 32));
>  #endif
>      if (riscv_has_ext(env, RVH)) {
>          qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
> -        qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ", env->vsstatus);
> +        qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ",
> +                     (target_ulong)env->vsstatus);
>      }
>      qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip     ", env->mip);
>      qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie     ", env->mie);
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index de275782e6..57050f2268 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -140,14 +140,10 @@ struct CPURISCVState {
>      target_ulong resetvec;
>
>      target_ulong mhartid;
> -    target_ulong mstatus;
> +    uint64_t mstatus;
>
>      target_ulong mip;
>
> -#ifdef TARGET_RISCV32
> -    target_ulong mstatush;
> -#endif
> -
>      uint32_t miclaim;
>
>      target_ulong mie;
> @@ -179,16 +175,13 @@ struct CPURISCVState {
>      uint64_t htimedelta;
>
>      /* Virtual CSRs */
> -    target_ulong vsstatus;
> +    uint64_t vsstatus;
>      target_ulong vstvec;
>      target_ulong vsscratch;
>      target_ulong vsepc;
>      target_ulong vscause;
>      target_ulong vstval;
>      target_ulong vsatp;
> -#ifdef TARGET_RISCV32
> -    target_ulong vsstatush;
> -#endif
>
>      target_ulong mtval2;
>      target_ulong mtinst;
> @@ -200,10 +193,7 @@ struct CPURISCVState {
>      target_ulong scause_hs;
>      target_ulong stval_hs;
>      target_ulong satp_hs;
> -    target_ulong mstatus_hs;
> -#ifdef TARGET_RISCV32
> -    target_ulong mstatush_hs;
> -#endif
> +    uint64_t mstatus_hs;
>
>      target_ulong scounteren;
>      target_ulong mcounteren;
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index bd36062877..62ca6b6f89 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -5,9 +5,14 @@
>
>  #define get_field(reg, mask) (((reg) & \
>                   (target_ulong)(mask)) / ((mask) & ~((mask) << 1)))
> +#define get_field64(reg, mask) (((reg) & \
> +                   (uint64_t)(mask)) / ((mask) & ~((mask) << 1)))
>  #define set_field(reg, mask, val) (((reg) & ~(target_ulong)(mask)) | \
>                   (((target_ulong)(val) * ((mask) & ~((mask) << 1))) & \
>                   (target_ulong)(mask)))
> +#define set_field64(reg, mask, val) (((reg) & ~(uint64_t)(mask)) | \
> +                   (((uint64_t)(val) * ((mask) & ~((mask) << 1))) & \
> +                   (uint64_t)(mask)))

We should just be able to change the existing ones to use uint64_t.

>
>  /* Floating point round mode */
>  #define FSR_RD_SHIFT        5
> @@ -381,19 +386,10 @@
>  #define MSTATUS_TVM         0x00100000 /* since: priv-1.10 */
>  #define MSTATUS_TW          0x20000000 /* since: priv-1.10 */
>  #define MSTATUS_TSR         0x40000000 /* since: priv-1.10 */
> -#if defined(TARGET_RISCV64)
>  #define MSTATUS_GVA         0x4000000000ULL
>  #define MSTATUS_MPV         0x8000000000ULL
> -#elif defined(TARGET_RISCV32)
> -#define MSTATUS_GVA         0x00000040
> -#define MSTATUS_MPV         0x00000080
> -#endif
>
> -#ifdef TARGET_RISCV32
> -# define MSTATUS_MPV_ISSET(env)  get_field(env->mstatush, MSTATUS_MPV)
> -#else
> -# define MSTATUS_MPV_ISSET(env)  get_field(env->mstatus, MSTATUS_MPV)
> -#endif
> +#define MSTATUS_MPV_ISSET(env)  get_field64(env->mstatus, MSTATUS_MPV)

I think also just remove this macro and replace it with
get_field64(env->mstatus, MSTATUS_MPV).

>
>  #define MSTATUS64_UXL       0x0000000300000000ULL
>  #define MSTATUS64_SXL       0x0000000C00000000ULL
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 904899054d..0430cbe4e3 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -39,9 +39,9 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
>  {
>      target_ulong irqs;
>
> -    target_ulong mstatus_mie = get_field(env->mstatus, MSTATUS_MIE);
> -    target_ulong mstatus_sie = get_field(env->mstatus, MSTATUS_SIE);
> -    target_ulong hs_mstatus_sie = get_field(env->mstatus_hs, MSTATUS_SIE);
> +    target_ulong mstatus_mie = get_field64(env->mstatus, MSTATUS_MIE);
> +    target_ulong mstatus_sie = get_field64(env->mstatus, MSTATUS_SIE);
> +    target_ulong hs_mstatus_sie = get_field64(env->mstatus_hs, MSTATUS_SIE);
>
>      target_ulong pending = env->mip & env->mie &
>                                 ~(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP);
> @@ -110,14 +110,20 @@ bool riscv_cpu_fp_enabled(CPURISCVState *env)
>
>  void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
>  {
> -    target_ulong mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
> -                                MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE;
> +    uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
> +                            MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE;
>      bool current_virt = riscv_cpu_virt_enabled(env);
>
>      g_assert(riscv_has_ext(env, RVH));
>
>  #if defined(TARGET_RISCV64)
>      mstatus_mask |= MSTATUS64_UXL;
> +#elif defined(TARGET_RISCV32)
> +    /*
> +     * The upper 32 bits of env->mstatus is mstatush
> +     * register in RISCV32. We need to backup it.
> +     */
> +    mstatus_mask |= (~0ULL << 32);

I don't think we need this. This should just follow the standard mstatus mask.

>  #endif
>
>      if (current_virt) {
> @@ -126,11 +132,6 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
>          env->mstatus &= ~mstatus_mask;
>          env->mstatus |= env->mstatus_hs;
>
> -#if defined(TARGET_RISCV32)
> -        env->vsstatush = env->mstatush;
> -        env->mstatush |= env->mstatush_hs;
> -#endif
> -
>          env->vstvec = env->stvec;
>          env->stvec = env->stvec_hs;
>
> @@ -154,11 +155,6 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
>          env->mstatus &= ~mstatus_mask;
>          env->mstatus |= env->vsstatus;
>
> -#if defined(TARGET_RISCV32)
> -        env->mstatush_hs = env->mstatush;
> -        env->mstatush |= env->vsstatush;
> -#endif
> -
>          env->stvec_hs = env->stvec;
>          env->stvec = env->vstvec;
>
> @@ -347,8 +343,8 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
>      }
>
>      if (mode == PRV_M && access_type != MMU_INST_FETCH) {
> -        if (get_field(env->mstatus, MSTATUS_MPRV)) {
> -            mode = get_field(env->mstatus, MSTATUS_MPP);
> +        if (get_field64(env->mstatus, MSTATUS_MPRV)) {
> +            mode = get_field64(env->mstatus, MSTATUS_MPP);
>          }
>      }
>
> @@ -370,9 +366,9 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
>      int levels, ptidxbits, ptesize, vm, sum, mxr, widened;
>
>      if (first_stage == true) {
> -        mxr = get_field(env->mstatus, MSTATUS_MXR);
> +        mxr = get_field64(env->mstatus, MSTATUS_MXR);
>      } else {
> -        mxr = get_field(env->vsstatus, MSTATUS_MXR);
> +        mxr = get_field64(env->vsstatus, MSTATUS_MXR);
>      }
>
>      if (first_stage == true) {
> @@ -389,7 +385,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
>          vm = get_field(env->hgatp, HGATP_MODE);
>          widened = 2;
>      }
> -    sum = get_field(env->mstatus, MSTATUS_SUM);
> +    sum = get_field64(env->mstatus, MSTATUS_SUM);
>      switch (vm) {
>      case VM_1_10_SV32:
>        levels = 2; ptidxbits = 10; ptesize = 4; break;
> @@ -712,14 +708,14 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>                    __func__, address, access_type, mmu_idx);
>
>      if (mode == PRV_M && access_type != MMU_INST_FETCH) {
> -        if (get_field(env->mstatus, MSTATUS_MPRV)) {
> -            mode = get_field(env->mstatus, MSTATUS_MPP);
> +        if (get_field64(env->mstatus, MSTATUS_MPRV)) {
> +            mode = get_field64(env->mstatus, MSTATUS_MPP);
>          }
>      }
>
>      if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
>          access_type != MMU_INST_FETCH &&
> -        get_field(env->mstatus, MSTATUS_MPRV) &&
> +        get_field64(env->mstatus, MSTATUS_MPRV) &&
>          MSTATUS_MPV_ISSET(env)) {
>          riscv_cpu_set_two_stage_lookup(env, true);
>      }
> @@ -780,7 +776,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>      /* We did the two stage lookup based on MPRV, unset the lookup */
>      if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
>          access_type != MMU_INST_FETCH &&
> -        get_field(env->mstatus, MSTATUS_MPRV) &&
> +        get_field64(env->mstatus, MSTATUS_MPRV) &&
>          MSTATUS_MPV_ISSET(env)) {
>          riscv_cpu_set_two_stage_lookup(env, false);
>      }
> @@ -844,7 +840,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
>      RISCVCPU *cpu = RISCV_CPU(cs);
>      CPURISCVState *env = &cpu->env;
>      bool force_hs_execp = riscv_cpu_force_hs_excep_enabled(env);
> -    target_ulong s;
> +    uint64_t s;
>
>      /* cs->exception is 32-bits wide unlike mcause which is XLEN-bits wide
>       * so we mask off the MSB and separate into trap type and cause.
> @@ -932,7 +928,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
>                  /* Trap into HS mode, from virt */
>                  riscv_cpu_swap_hypervisor_regs(env);
>                  env->hstatus = set_field(env->hstatus, HSTATUS_SPVP,
> -                                         get_field(env->mstatus, SSTATUS_SPP));
> +                                         get_field64(env->mstatus, SSTATUS_SPP));
>                  env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
>                                           riscv_cpu_virt_enabled(env));
>
> @@ -952,9 +948,9 @@ void riscv_cpu_do_interrupt(CPUState *cs)
>          }
>
>          s = env->mstatus;
> -        s = set_field(s, MSTATUS_SPIE, get_field(s, MSTATUS_SIE));
> -        s = set_field(s, MSTATUS_SPP, env->priv);
> -        s = set_field(s, MSTATUS_SIE, 0);
> +        s = set_field64(s, MSTATUS_SPIE, get_field64(s, MSTATUS_SIE));
> +        s = set_field64(s, MSTATUS_SPP, env->priv);
> +        s = set_field64(s, MSTATUS_SIE, 0);
>          env->mstatus = s;
>          env->scause = cause | ((target_ulong)async << (TARGET_LONG_BITS - 1));
>          env->sepc = env->pc;
> @@ -969,19 +965,11 @@ void riscv_cpu_do_interrupt(CPUState *cs)
>              if (riscv_cpu_virt_enabled(env)) {
>                  riscv_cpu_swap_hypervisor_regs(env);
>              }
> -#ifdef TARGET_RISCV32
> -            env->mstatush = set_field(env->mstatush, MSTATUS_MPV,
> +            env->mstatus = set_field64(env->mstatus, MSTATUS_MPV,
>                                         riscv_cpu_virt_enabled(env));
>              if (riscv_cpu_virt_enabled(env) && tval) {
> -                env->mstatush = set_field(env->mstatush, MSTATUS_GVA, 1);
> -            }
> -#else
> -            env->mstatus = set_field(env->mstatus, MSTATUS_MPV,
> -                                      riscv_cpu_virt_enabled(env));
> -            if (riscv_cpu_virt_enabled(env) && tval) {
> -                env->mstatus = set_field(env->mstatus, MSTATUS_GVA, 1);
> +                env->mstatus = set_field64(env->mstatus, MSTATUS_GVA, 1);
>              }
> -#endif
>
>              mtval2 = env->guest_phys_fault_addr;
>
> @@ -991,9 +979,9 @@ void riscv_cpu_do_interrupt(CPUState *cs)
>          }
>
>          s = env->mstatus;
> -        s = set_field(s, MSTATUS_MPIE, get_field(s, MSTATUS_MIE));
> -        s = set_field(s, MSTATUS_MPP, env->priv);
> -        s = set_field(s, MSTATUS_MIE, 0);
> +        s = set_field64(s, MSTATUS_MPIE, get_field64(s, MSTATUS_MIE));
> +        s = set_field64(s, MSTATUS_MPP, env->priv);
> +        s = set_field64(s, MSTATUS_MIE, 0);
>          env->mstatus = s;
>          env->mcause = cause | ~(((target_ulong)-1) >> async);
>          env->mepc = env->pc;
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index aaef6c6f20..d4b6371719 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -446,8 +446,8 @@ static int validate_vm(CPURISCVState *env, target_ulong vm)
>
>  static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
>  {
> -    target_ulong mstatus = env->mstatus;
> -    target_ulong mask = 0;
> +    uint64_t mstatus = env->mstatus;
> +    uint64_t mask = 0;
>      int dirty;
>
>      /* flush tlb on mstatus fields that affect VM */
> @@ -471,7 +471,7 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
>
>      dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) |
>              ((mstatus & MSTATUS_XS) == MSTATUS_XS);
> -    mstatus = set_field(mstatus, MSTATUS_SD, dirty);
> +    mstatus = set_field64(mstatus, MSTATUS_SD, dirty);
>      env->mstatus = mstatus;
>
>      return 0;
> @@ -480,19 +480,20 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
>  #ifdef TARGET_RISCV32
>  static int read_mstatush(CPURISCVState *env, int csrno, target_ulong *val)
>  {
> -    *val = env->mstatush;
> +    *val = env->mstatus >> 32;
>      return 0;
>  }
>
>  static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
>  {
> -    if ((val ^ env->mstatush) & (MSTATUS_MPV)) {
> +    uint64_t valh = (uint64_t)val << 32;
> +    uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
> +
> +    if ((valh ^ env->mstatus) & (MSTATUS_MPV)) {
>          tlb_flush(env_cpu(env));
>      }
>
> -    val &= MSTATUS_MPV | MSTATUS_GVA;
> -
> -    env->mstatush = val;
> +    env->mstatus = (env->mstatus & ~mask) | (valh & mask);

Looks good!

>
>      return 0;
>  }
> @@ -718,14 +719,14 @@ static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value,
>  static int read_sstatus(CPURISCVState *env, int csrno, target_ulong *val)
>  {
>      target_ulong mask = (sstatus_v1_10_mask);
> -    *val = env->mstatus & mask;
> +    *val = (target_ulong)env->mstatus & mask;

I don't think you need all of these casts.

Alistair

>      return 0;
>  }
>
>  static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
>  {
>      target_ulong mask = (sstatus_v1_10_mask);
> -    target_ulong newval = (env->mstatus & ~mask) | (val & mask);
> +    target_ulong newval = ((target_ulong)env->mstatus & ~mask) | (val & mask);
>      return write_mstatus(env, CSR_MSTATUS, newval);
>  }
>
> @@ -861,7 +862,7 @@ static int read_satp(CPURISCVState *env, int csrno, target_ulong *val)
>          return 0;
>      }
>
> -    if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
> +    if (env->priv == PRV_S && get_field64(env->mstatus, MSTATUS_TVM)) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      } else {
>          *val = env->satp;
> @@ -878,7 +879,7 @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
>      if (validate_vm(env, get_field(val, SATP_MODE)) &&
>          ((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN)))
>      {
> -        if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
> +        if (env->priv == PRV_S && get_field64(env->mstatus, MSTATUS_TVM)) {
>              return -RISCV_EXCP_ILLEGAL_INST;
>          } else {
>              if((val ^ env->satp) & SATP_ASID) {
> @@ -1105,7 +1106,8 @@ static int read_vsstatus(CPURISCVState *env, int csrno, target_ulong *val)
>
>  static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
>  {
> -    env->vsstatus = val;
> +    uint64_t mask = (target_ulong)-1;
> +    env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
>      return 0;
>  }
>
> diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
> index 9b9ada45a9..18cdffc738 100644
> --- a/target/riscv/op_helper.c
> +++ b/target/riscv/op_helper.c
> @@ -79,7 +79,8 @@ target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
>
>  target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
>  {
> -    target_ulong prev_priv, prev_virt, mstatus;
> +    uint64_t mstatus;
> +    target_ulong prev_priv, prev_virt;
>
>      if (!(env->priv >= PRV_S)) {
>          riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
> @@ -90,7 +91,7 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
>          riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
>      }
>
> -    if (get_field(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) {
> +    if (get_field64(env->mstatus, MSTATUS_TSR) && !(env->priv >= PRV_M)) {
>          riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
>      }
>
> @@ -105,14 +106,14 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
>          /* We support Hypervisor extensions and virtulisation is disabled */
>          target_ulong hstatus = env->hstatus;
>
> -        prev_priv = get_field(mstatus, MSTATUS_SPP);
> +        prev_priv = get_field64(mstatus, MSTATUS_SPP);
>          prev_virt = get_field(hstatus, HSTATUS_SPV);
>
>          hstatus = set_field(hstatus, HSTATUS_SPV, 0);
> -        mstatus = set_field(mstatus, MSTATUS_SPP, 0);
> -        mstatus = set_field(mstatus, SSTATUS_SIE,
> -                            get_field(mstatus, SSTATUS_SPIE));
> -        mstatus = set_field(mstatus, SSTATUS_SPIE, 1);
> +        mstatus = set_field64(mstatus, MSTATUS_SPP, 0);
> +        mstatus = set_field64(mstatus, SSTATUS_SIE,
> +                              get_field64(mstatus, SSTATUS_SPIE));
> +        mstatus = set_field64(mstatus, SSTATUS_SPIE, 1);
>
>          env->mstatus = mstatus;
>          env->hstatus = hstatus;
> @@ -123,12 +124,12 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
>
>          riscv_cpu_set_virt_enabled(env, prev_virt);
>      } else {
> -        prev_priv = get_field(mstatus, MSTATUS_SPP);
> +        prev_priv = get_field64(mstatus, MSTATUS_SPP);
>
> -        mstatus = set_field(mstatus, MSTATUS_SIE,
> -                            get_field(mstatus, MSTATUS_SPIE));
> -        mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
> -        mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
> +        mstatus = set_field64(mstatus, MSTATUS_SIE,
> +                              get_field64(mstatus, MSTATUS_SPIE));
> +        mstatus = set_field64(mstatus, MSTATUS_SPIE, 1);
> +        mstatus = set_field64(mstatus, MSTATUS_SPP, PRV_U);
>          env->mstatus = mstatus;
>      }
>
> @@ -148,18 +149,14 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
>          riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
>      }
>
> -    target_ulong mstatus = env->mstatus;
> -    target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
> +    uint64_t mstatus = env->mstatus;
> +    target_ulong prev_priv = get_field64(mstatus, MSTATUS_MPP);
>      target_ulong prev_virt = MSTATUS_MPV_ISSET(env);
> -    mstatus = set_field(mstatus, MSTATUS_MIE,
> -                        get_field(mstatus, MSTATUS_MPIE));
> -    mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
> -    mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
> -#ifdef TARGET_RISCV32
> -    env->mstatush = set_field(env->mstatush, MSTATUS_MPV, 0);
> -#else
> -    mstatus = set_field(mstatus, MSTATUS_MPV, 0);
> -#endif
> +    mstatus = set_field64(mstatus, MSTATUS_MIE,
> +                          get_field64(mstatus, MSTATUS_MPIE));
> +    mstatus = set_field64(mstatus, MSTATUS_MPIE, 1);
> +    mstatus = set_field64(mstatus, MSTATUS_MPP, PRV_U);
> +    mstatus = set_field64(mstatus, MSTATUS_MPV, 0);
>      env->mstatus = mstatus;
>      riscv_cpu_set_mode(env, prev_priv);
>
> @@ -179,7 +176,7 @@ void helper_wfi(CPURISCVState *env)
>      CPUState *cs = env_cpu(env);
>
>      if ((env->priv == PRV_S &&
> -        get_field(env->mstatus, MSTATUS_TW)) ||
> +        get_field64(env->mstatus, MSTATUS_TW)) ||
>          riscv_cpu_virt_enabled(env)) {
>          riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
>      } else {
> @@ -194,7 +191,7 @@ void helper_tlb_flush(CPURISCVState *env)
>      CPUState *cs = env_cpu(env);
>      if (!(env->priv >= PRV_S) ||
>          (env->priv == PRV_S &&
> -         get_field(env->mstatus, MSTATUS_TVM))) {
> +         get_field64(env->mstatus, MSTATUS_TVM))) {
>          riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
>      } else if (riscv_has_ext(env, RVH) && riscv_cpu_virt_enabled(env) &&
>                 get_field(env->hstatus, HSTATUS_VTVM)) {
> @@ -224,7 +221,7 @@ void helper_hyp_tlb_flush(CPURISCVState *env)
>  void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
>  {
>      if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) &&
> -        get_field(env->mstatus, MSTATUS_TVM)) {
> +        get_field64(env->mstatus, MSTATUS_TVM)) {
>          riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
>      }
>
> --
> 2.19.1
>
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3 2/6] target/riscv: Add basic vmstate description of CPU
  2020-10-23  9:12 ` [PATCH V3 2/6] target/riscv: Add basic vmstate description of CPU Yifei Jiang
@ 2020-10-23 23:52   ` Alistair Francis
  0 siblings, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2020-10-23 23:52 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: open list:RISC-V, Zhanghailiang, Sagar Karandikar,
	Bastian Koppelmann, Zhangxiaofeng (F),
	Richard Henderson, qemu-devel@nongnu.org Developers,
	Alistair Francis, yinyipeng, Palmer Dabbelt, Wubin (H),
	dengkai (A)

On Fri, Oct 23, 2020 at 2:13 AM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> Add basic CPU state description to the newly created machine.c
>
> Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
> Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.c       |  8 +----
>  target/riscv/internals.h |  4 +++
>  target/riscv/machine.c   | 74 ++++++++++++++++++++++++++++++++++++++++
>  target/riscv/meson.build |  3 +-
>  4 files changed, 81 insertions(+), 8 deletions(-)
>  create mode 100644 target/riscv/machine.c
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index dd05a220c7..6a0264fc6b 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -22,6 +22,7 @@
>  #include "qemu/ctype.h"
>  #include "qemu/log.h"
>  #include "cpu.h"
> +#include "internals.h"
>  #include "exec/exec-all.h"
>  #include "qapi/error.h"
>  #include "qemu/error-report.h"
> @@ -498,13 +499,6 @@ static void riscv_cpu_init(Object *obj)
>      cpu_set_cpustate_pointers(cpu);
>  }
>
> -#ifndef CONFIG_USER_ONLY
> -static const VMStateDescription vmstate_riscv_cpu = {
> -    .name = "cpu",
> -    .unmigratable = 1,
> -};
> -#endif
> -
>  static Property riscv_cpu_properties[] = {
>      DEFINE_PROP_BOOL("i", RISCVCPU, cfg.ext_i, true),
>      DEFINE_PROP_BOOL("e", RISCVCPU, cfg.ext_e, false),
> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
> index f1a546dba6..b15ad394bb 100644
> --- a/target/riscv/internals.h
> +++ b/target/riscv/internals.h
> @@ -38,6 +38,10 @@ target_ulong fclass_d(uint64_t frs1);
>  #define SEW32 2
>  #define SEW64 3
>
> +#ifndef CONFIG_USER_ONLY
> +extern const VMStateDescription vmstate_riscv_cpu;
> +#endif
> +
>  static inline uint64_t nanbox_s(float32 f)
>  {
>      return f | MAKE_64BIT_MASK(32, 32);
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> new file mode 100644
> index 0000000000..32edbcba7c
> --- /dev/null
> +++ b/target/riscv/machine.c
> @@ -0,0 +1,74 @@
> +/*
> + * RISC-V VMState Description
> + *
> + * Copyright (c) 2020 Huawei Technologies Co., Ltd
> + *
> + * 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 <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "cpu.h"
> +#include "qemu/error-report.h"
> +#include "sysemu/kvm.h"
> +#include "migration/cpu.h"
> +
> +const VMStateDescription vmstate_riscv_cpu = {
> +    .name = "cpu",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
> +        VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
> +        VMSTATE_UINTTL(env.pc, RISCVCPU),
> +        VMSTATE_UINTTL(env.load_res, RISCVCPU),
> +        VMSTATE_UINTTL(env.load_val, RISCVCPU),
> +        VMSTATE_UINTTL(env.frm, RISCVCPU),
> +        VMSTATE_UINTTL(env.badaddr, RISCVCPU),
> +        VMSTATE_UINTTL(env.guest_phys_fault_addr, RISCVCPU),
> +        VMSTATE_UINTTL(env.priv_ver, RISCVCPU),
> +        VMSTATE_UINTTL(env.vext_ver, RISCVCPU),
> +        VMSTATE_UINTTL(env.misa, RISCVCPU),
> +        VMSTATE_UINTTL(env.misa_mask, RISCVCPU),
> +        VMSTATE_UINT32(env.features, RISCVCPU),
> +        VMSTATE_UINTTL(env.priv, RISCVCPU),
> +        VMSTATE_UINTTL(env.virt, RISCVCPU),
> +        VMSTATE_UINTTL(env.resetvec, RISCVCPU),
> +        VMSTATE_UINTTL(env.mhartid, RISCVCPU),
> +        VMSTATE_UINT64(env.mstatus, RISCVCPU),
> +        VMSTATE_UINTTL(env.mip, RISCVCPU),
> +        VMSTATE_UINT32(env.miclaim, RISCVCPU),
> +        VMSTATE_UINTTL(env.mie, RISCVCPU),
> +        VMSTATE_UINTTL(env.mideleg, RISCVCPU),
> +        VMSTATE_UINTTL(env.sptbr, RISCVCPU),
> +        VMSTATE_UINTTL(env.satp, RISCVCPU),
> +        VMSTATE_UINTTL(env.sbadaddr, RISCVCPU),
> +        VMSTATE_UINTTL(env.mbadaddr, RISCVCPU),
> +        VMSTATE_UINTTL(env.medeleg, RISCVCPU),
> +        VMSTATE_UINTTL(env.stvec, RISCVCPU),
> +        VMSTATE_UINTTL(env.sepc, RISCVCPU),
> +        VMSTATE_UINTTL(env.scause, RISCVCPU),
> +        VMSTATE_UINTTL(env.mtvec, RISCVCPU),
> +        VMSTATE_UINTTL(env.mepc, RISCVCPU),
> +        VMSTATE_UINTTL(env.mcause, RISCVCPU),
> +        VMSTATE_UINTTL(env.mtval, RISCVCPU),
> +        VMSTATE_UINTTL(env.scounteren, RISCVCPU),
> +        VMSTATE_UINTTL(env.mcounteren, RISCVCPU),
> +        VMSTATE_UINTTL(env.sscratch, RISCVCPU),
> +        VMSTATE_UINTTL(env.mscratch, RISCVCPU),
> +        VMSTATE_UINT64(env.mfromhost, RISCVCPU),
> +        VMSTATE_UINT64(env.mtohost, RISCVCPU),
> +        VMSTATE_UINT64(env.timecmp, RISCVCPU),
> +
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> index abd647fea1..14a5c62dac 100644
> --- a/target/riscv/meson.build
> +++ b/target/riscv/meson.build
> @@ -27,7 +27,8 @@ riscv_ss.add(files(
>  riscv_softmmu_ss = ss.source_set()
>  riscv_softmmu_ss.add(files(
>    'pmp.c',
> -  'monitor.c'
> +  'monitor.c',
> +  'machine.c'
>  ))
>
>  target_arch += {'riscv': riscv_ss}
> --
> 2.19.1
>
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3 3/6] target/riscv: Add PMP state description
  2020-10-23  9:12 ` [PATCH V3 3/6] target/riscv: Add PMP state description Yifei Jiang
@ 2020-10-23 23:59   ` Alistair Francis
  0 siblings, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2020-10-23 23:59 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: open list:RISC-V, Zhanghailiang, Sagar Karandikar,
	Bastian Koppelmann, Zhangxiaofeng (F),
	Richard Henderson, qemu-devel@nongnu.org Developers,
	Alistair Francis, yinyipeng, Palmer Dabbelt, Wubin (H),
	dengkai (A)

On Fri, Oct 23, 2020 at 2:16 AM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> In the case of supporting PMP feature, add PMP state description
> to vmstate_riscv_cpu.
>
> 'vmstate_pmp_addr' and 'num_rules' could be regenerated by
> pmp_update_rule(). But there exists the problem of updating
> num_rules repeatedly in pmp_update_rule(). So here extracts
> pmp_update_rule_addr() and pmp_update_rule_nums() to update
> 'vmstate_pmp_addr' and 'num_rules' respectively.
>
> Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
> Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/machine.c | 50 ++++++++++++++++++++++++++++++++++++++++++
>  target/riscv/pmp.c     | 29 ++++++++++++++----------
>  target/riscv/pmp.h     |  2 ++
>  3 files changed, 70 insertions(+), 11 deletions(-)
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index 32edbcba7c..fc1461d88e 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -22,6 +22,52 @@
>  #include "sysemu/kvm.h"
>  #include "migration/cpu.h"
>
> +static bool pmp_needed(void *opaque)
> +{
> +    RISCVCPU *cpu = opaque;
> +    CPURISCVState *env = &cpu->env;
> +
> +    return riscv_feature(env, RISCV_FEATURE_PMP);
> +}
> +
> +static int pmp_post_load(void *opaque, int version_id)
> +{
> +    RISCVCPU *cpu = opaque;
> +    CPURISCVState *env = &cpu->env;
> +    int i;
> +
> +    for (i = 0; i < MAX_RISCV_PMPS; i++) {
> +        pmp_update_rule_addr(env, i);
> +    }
> +    pmp_update_rule_nums(env);
> +
> +    return 0;
> +}
> +
> +static const VMStateDescription vmstate_pmp_entry = {
> +    .name = "cpu/pmp/entry",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_UINTTL(addr_reg, pmp_entry_t),
> +        VMSTATE_UINT8(cfg_reg, pmp_entry_t),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +static const VMStateDescription vmstate_pmp = {
> +    .name = "cpu/pmp",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .needed = pmp_needed,
> +    .post_load = pmp_post_load,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_STRUCT_ARRAY(env.pmp_state.pmp, RISCVCPU, MAX_RISCV_PMPS,
> +                             0, vmstate_pmp_entry, pmp_entry_t),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
>  const VMStateDescription vmstate_riscv_cpu = {
>      .name = "cpu",
>      .version_id = 1,
> @@ -70,5 +116,9 @@ const VMStateDescription vmstate_riscv_cpu = {
>          VMSTATE_UINT64(env.timecmp, RISCVCPU),
>
>          VMSTATE_END_OF_LIST()
> +    },
> +    .subsections = (const VMStateDescription * []) {
> +        &vmstate_pmp,
> +        NULL
>      }
>  };
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index c394e867f8..2eda8e1e2f 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -136,18 +136,8 @@ static void pmp_decode_napot(target_ulong a, target_ulong *sa, target_ulong *ea)
>      }
>  }
>
> -
> -/* Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea'
> - *   end address values.
> - *   This function is called relatively infrequently whereas the check that
> - *   an address is within a pmp rule is called often, so optimise that one
> - */
> -static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
> +void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
>  {
> -    int i;
> -
> -    env->pmp_state.num_rules = 0;
> -
>      uint8_t this_cfg = env->pmp_state.pmp[pmp_index].cfg_reg;
>      target_ulong this_addr = env->pmp_state.pmp[pmp_index].addr_reg;
>      target_ulong prev_addr = 0u;
> @@ -186,7 +176,13 @@ static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
>
>      env->pmp_state.addr[pmp_index].sa = sa;
>      env->pmp_state.addr[pmp_index].ea = ea;
> +}
>
> +void pmp_update_rule_nums(CPURISCVState *env)
> +{
> +    int i;
> +
> +    env->pmp_state.num_rules = 0;
>      for (i = 0; i < MAX_RISCV_PMPS; i++) {
>          const uint8_t a_field =
>              pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
> @@ -196,6 +192,17 @@ static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
>      }
>  }
>
> +/* Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea'
> + *   end address values.
> + *   This function is called relatively infrequently whereas the check that
> + *   an address is within a pmp rule is called often, so optimise that one
> + */
> +static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
> +{
> +    pmp_update_rule_addr(env, pmp_index);
> +    pmp_update_rule_nums(env);
> +}
> +
>  static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong addr)
>  {
>      int result = 0;
> diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
> index 6a8f072871..6c6b4c9bef 100644
> --- a/target/riscv/pmp.h
> +++ b/target/riscv/pmp.h
> @@ -62,5 +62,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
>      target_ulong size, pmp_priv_t priv, target_ulong mode);
>  bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
>                           target_ulong *tlb_size);
> +void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
> +void pmp_update_rule_nums(CPURISCVState *env);
>
>  #endif
> --
> 2.19.1
>
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3 4/6] target/riscv: Add H extension state description
  2020-10-23  9:12 ` [PATCH V3 4/6] target/riscv: Add H extension " Yifei Jiang
@ 2020-10-24  0:00   ` Alistair Francis
  0 siblings, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2020-10-24  0:00 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: open list:RISC-V, Zhanghailiang, Sagar Karandikar,
	Bastian Koppelmann, Zhangxiaofeng (F),
	Richard Henderson, qemu-devel@nongnu.org Developers,
	Alistair Francis, yinyipeng, Palmer Dabbelt, Wubin (H),
	dengkai (A)

On Fri, Oct 23, 2020 at 2:16 AM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> In the case of supporting H extension, add H extension description
> to vmstate_riscv_cpu.
>
> Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
> Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/machine.c | 47 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index fc1461d88e..ae60050898 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -68,6 +68,52 @@ static const VMStateDescription vmstate_pmp = {
>      }
>  };
>
> +static bool hyper_needed(void *opaque)
> +{
> +    RISCVCPU *cpu = opaque;
> +    CPURISCVState *env = &cpu->env;
> +
> +    return riscv_has_ext(env, RVH);
> +}
> +
> +static const VMStateDescription vmstate_hyper = {
> +    .name = "cpu/hyper",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .needed = hyper_needed,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_UINTTL(env.hstatus, RISCVCPU),
> +        VMSTATE_UINTTL(env.hedeleg, RISCVCPU),
> +        VMSTATE_UINTTL(env.hideleg, RISCVCPU),
> +        VMSTATE_UINTTL(env.hcounteren, RISCVCPU),
> +        VMSTATE_UINTTL(env.htval, RISCVCPU),
> +        VMSTATE_UINTTL(env.htinst, RISCVCPU),
> +        VMSTATE_UINTTL(env.hgatp, RISCVCPU),
> +        VMSTATE_UINT64(env.htimedelta, RISCVCPU),
> +
> +        VMSTATE_UINT64(env.vsstatus, RISCVCPU),
> +        VMSTATE_UINTTL(env.vstvec, RISCVCPU),
> +        VMSTATE_UINTTL(env.vsscratch, RISCVCPU),
> +        VMSTATE_UINTTL(env.vsepc, RISCVCPU),
> +        VMSTATE_UINTTL(env.vscause, RISCVCPU),
> +        VMSTATE_UINTTL(env.vstval, RISCVCPU),
> +        VMSTATE_UINTTL(env.vsatp, RISCVCPU),
> +
> +        VMSTATE_UINTTL(env.mtval2, RISCVCPU),
> +        VMSTATE_UINTTL(env.mtinst, RISCVCPU),
> +
> +        VMSTATE_UINTTL(env.stvec_hs, RISCVCPU),
> +        VMSTATE_UINTTL(env.sscratch_hs, RISCVCPU),
> +        VMSTATE_UINTTL(env.sepc_hs, RISCVCPU),
> +        VMSTATE_UINTTL(env.scause_hs, RISCVCPU),
> +        VMSTATE_UINTTL(env.stval_hs, RISCVCPU),
> +        VMSTATE_UINTTL(env.satp_hs, RISCVCPU),
> +        VMSTATE_UINT64(env.mstatus_hs, RISCVCPU),
> +
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
>  const VMStateDescription vmstate_riscv_cpu = {
>      .name = "cpu",
>      .version_id = 1,
> @@ -119,6 +165,7 @@ const VMStateDescription vmstate_riscv_cpu = {
>      },
>      .subsections = (const VMStateDescription * []) {
>          &vmstate_pmp,
> +        &vmstate_hyper,
>          NULL
>      }
>  };
> --
> 2.19.1
>
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3 5/6] target/riscv: Add V extension state description
  2020-10-23  9:12 ` [PATCH V3 5/6] target/riscv: Add V " Yifei Jiang
@ 2020-10-24  0:01   ` Alistair Francis
  0 siblings, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2020-10-24  0:01 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: open list:RISC-V, Zhanghailiang, Sagar Karandikar,
	Bastian Koppelmann, Zhangxiaofeng (F),
	Richard Henderson, qemu-devel@nongnu.org Developers,
	Alistair Francis, yinyipeng, Palmer Dabbelt, Wubin (H),
	dengkai (A)

On Fri, Oct 23, 2020 at 2:18 AM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> In the case of supporting V extension, add V extension description
> to vmstate_riscv_cpu.
>
> Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
> Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/machine.c | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index ae60050898..44d4015bd6 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -76,6 +76,30 @@ static bool hyper_needed(void *opaque)
>      return riscv_has_ext(env, RVH);
>  }
>
> +static bool vector_needed(void *opaque)
> +{
> +    RISCVCPU *cpu = opaque;
> +    CPURISCVState *env = &cpu->env;
> +
> +    return riscv_has_ext(env, RVV);
> +}
> +
> +static const VMStateDescription vmstate_vector = {
> +    .name = "cpu/vector",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .needed = vector_needed,
> +    .fields = (VMStateField[]) {
> +            VMSTATE_UINT64_ARRAY(env.vreg, RISCVCPU, 32 * RV_VLEN_MAX / 64),
> +            VMSTATE_UINTTL(env.vxrm, RISCVCPU),
> +            VMSTATE_UINTTL(env.vxsat, RISCVCPU),
> +            VMSTATE_UINTTL(env.vl, RISCVCPU),
> +            VMSTATE_UINTTL(env.vstart, RISCVCPU),
> +            VMSTATE_UINTTL(env.vtype, RISCVCPU),
> +            VMSTATE_END_OF_LIST()
> +        }
> +};
> +
>  static const VMStateDescription vmstate_hyper = {
>      .name = "cpu/hyper",
>      .version_id = 1,
> @@ -166,6 +190,7 @@ const VMStateDescription vmstate_riscv_cpu = {
>      .subsections = (const VMStateDescription * []) {
>          &vmstate_pmp,
>          &vmstate_hyper,
> +        &vmstate_vector,
>          NULL
>      }
>  };
> --
> 2.19.1
>
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3 6/6] target/riscv: Add sifive_plic vmstate
  2020-10-23  9:12 ` [PATCH V3 6/6] target/riscv: Add sifive_plic vmstate Yifei Jiang
@ 2020-10-24  0:02   ` Alistair Francis
  0 siblings, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2020-10-24  0:02 UTC (permalink / raw)
  To: Yifei Jiang
  Cc: open list:RISC-V, Zhanghailiang, Sagar Karandikar,
	Bastian Koppelmann, Zhangxiaofeng (F),
	Richard Henderson, qemu-devel@nongnu.org Developers,
	Alistair Francis, yinyipeng, Palmer Dabbelt, Wubin (H),
	dengkai (A)

On Fri, Oct 23, 2020 at 2:13 AM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> Add sifive_plic vmstate for supporting sifive_plic migration.
> Current vmstate framework only supports one structure parameter
> as num field to describe variable length arrays, so introduce
> num_enables.
>
> Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
> Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  hw/intc/sifive_plic.c | 26 +++++++++++++++++++++++++-
>  hw/intc/sifive_plic.h |  1 +
>  2 files changed, 26 insertions(+), 1 deletion(-)
>
> diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
> index f42fd695d8..97a1a27a9a 100644
> --- a/hw/intc/sifive_plic.c
> +++ b/hw/intc/sifive_plic.c
> @@ -30,6 +30,7 @@
>  #include "hw/intc/sifive_plic.h"
>  #include "target/riscv/cpu.h"
>  #include "sysemu/sysemu.h"
> +#include "migration/vmstate.h"
>
>  #define RISCV_DEBUG_PLIC 0
>
> @@ -448,11 +449,12 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
>                            TYPE_SIFIVE_PLIC, plic->aperture_size);
>      parse_hart_config(plic);
>      plic->bitfield_words = (plic->num_sources + 31) >> 5;
> +    plic->num_enables = plic->bitfield_words * plic->num_addrs;
>      plic->source_priority = g_new0(uint32_t, plic->num_sources);
>      plic->target_priority = g_new(uint32_t, plic->num_addrs);
>      plic->pending = g_new0(uint32_t, plic->bitfield_words);
>      plic->claimed = g_new0(uint32_t, plic->bitfield_words);
> -    plic->enable = g_new0(uint32_t, plic->bitfield_words * plic->num_addrs);
> +    plic->enable = g_new0(uint32_t, plic->num_enables);
>      sysbus_init_mmio(SYS_BUS_DEVICE(dev), &plic->mmio);
>      qdev_init_gpio_in(dev, sifive_plic_irq_request, plic->num_sources);
>
> @@ -472,12 +474,34 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
>      msi_nonbroken = true;
>  }
>
> +static const VMStateDescription vmstate_sifive_plic = {
> +    .name = "riscv_sifive_plic",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .fields = (VMStateField[]) {
> +            VMSTATE_VARRAY_UINT32(source_priority, SiFivePLICState,
> +                                  num_sources, 0,
> +                                  vmstate_info_uint32, uint32_t),
> +            VMSTATE_VARRAY_UINT32(target_priority, SiFivePLICState,
> +                                  num_addrs, 0,
> +                                  vmstate_info_uint32, uint32_t),
> +            VMSTATE_VARRAY_UINT32(pending, SiFivePLICState, bitfield_words, 0,
> +                                  vmstate_info_uint32, uint32_t),
> +            VMSTATE_VARRAY_UINT32(claimed, SiFivePLICState, bitfield_words, 0,
> +                                  vmstate_info_uint32, uint32_t),
> +            VMSTATE_VARRAY_UINT32(enable, SiFivePLICState, num_enables, 0,
> +                                  vmstate_info_uint32, uint32_t),
> +            VMSTATE_END_OF_LIST()
> +        }
> +};
> +
>  static void sifive_plic_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
>
>      device_class_set_props(dc, sifive_plic_properties);
>      dc->realize = sifive_plic_realize;
> +    dc->vmsd = &vmstate_sifive_plic;
>  }
>
>  static const TypeInfo sifive_plic_info = {
> diff --git a/hw/intc/sifive_plic.h b/hw/intc/sifive_plic.h
> index b75b1f145d..1e451a270c 100644
> --- a/hw/intc/sifive_plic.h
> +++ b/hw/intc/sifive_plic.h
> @@ -52,6 +52,7 @@ struct SiFivePLICState {
>      uint32_t num_addrs;
>      uint32_t num_harts;
>      uint32_t bitfield_words;
> +    uint32_t num_enables;
>      PLICAddr *addr_config;
>      uint32_t *source_priority;
>      uint32_t *target_priority;
> --
> 2.19.1
>
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2020-10-24  0:15 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-23  9:12 [PATCH V3 0/6] Support RISC-V migration Yifei Jiang
2020-10-23  9:12 ` [PATCH V3 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit Yifei Jiang
2020-10-23  9:41   ` Jiangyifei
2020-10-23 23:50   ` Alistair Francis
2020-10-23  9:12 ` [PATCH V3 2/6] target/riscv: Add basic vmstate description of CPU Yifei Jiang
2020-10-23 23:52   ` Alistair Francis
2020-10-23  9:12 ` [PATCH V3 3/6] target/riscv: Add PMP state description Yifei Jiang
2020-10-23 23:59   ` Alistair Francis
2020-10-23  9:12 ` [PATCH V3 4/6] target/riscv: Add H extension " Yifei Jiang
2020-10-24  0:00   ` Alistair Francis
2020-10-23  9:12 ` [PATCH V3 5/6] target/riscv: Add V " Yifei Jiang
2020-10-24  0:01   ` Alistair Francis
2020-10-23  9:12 ` [PATCH V3 6/6] target/riscv: Add sifive_plic vmstate Yifei Jiang
2020-10-24  0:02   ` Alistair Francis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).