* [PATCH V4 0/6] Support RISC-V migration
@ 2020-10-26 11:55 Yifei Jiang
2020-10-26 11:55 ` [PATCH V4 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit Yifei Jiang
` (6 more replies)
0 siblings, 7 replies; 11+ messages in thread
From: Yifei Jiang @ 2020-10-26 11:55 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 v3
1. Apply Alistair's patch to exend get/set_field():
https://www.mail-archive.com/qemu-devel@nongnu.org/msg753575.html
2. Remake the patch: Merge m/vsstatus and m/vsstatush into one uint64_t
unit.
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 | 24 +++--
target/riscv/cpu_bits.h | 19 +---
target/riscv/cpu_helper.c | 35 ++-----
target/riscv/csr.c | 18 ++--
target/riscv/internals.h | 4 +
target/riscv/machine.c | 196 ++++++++++++++++++++++++++++++++++++++
target/riscv/meson.build | 3 +-
target/riscv/op_helper.c | 11 +--
target/riscv/pmp.c | 29 +++---
target/riscv/pmp.h | 2 +
13 files changed, 290 insertions(+), 94 deletions(-)
create mode 100644 target/riscv/machine.c
--
2.19.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH V4 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit
2020-10-26 11:55 [PATCH V4 0/6] Support RISC-V migration Yifei Jiang
@ 2020-10-26 11:55 ` Yifei Jiang
2020-10-27 18:45 ` Richard Henderson
2020-10-27 20:26 ` Alistair Francis
2020-10-26 11:55 ` [PATCH V4 2/6] target/riscv: Add basic vmstate description of CPU Yifei Jiang
` (5 subsequent siblings)
6 siblings, 2 replies; 11+ messages in thread
From: Yifei Jiang @ 2020-10-26 11:55 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>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.c | 8 +++++---
target/riscv/cpu.h | 24 +++++++++++-------------
target/riscv/cpu_bits.h | 19 ++++---------------
target/riscv/cpu_helper.c | 35 +++++++----------------------------
target/riscv/csr.c | 18 ++++++++++--------
target/riscv/op_helper.c | 11 ++++-------
6 files changed, 41 insertions(+), 74 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..e430670b60 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -140,14 +140,14 @@ struct CPURISCVState {
target_ulong resetvec;
target_ulong mhartid;
- target_ulong mstatus;
+ /*
+ * For RV32 this is 32-bit mstatus and 32-bit mstatush.
+ * For RV64 this is a 64-bit mstatus.
+ */
+ uint64_t mstatus;
target_ulong mip;
-#ifdef TARGET_RISCV32
- target_ulong mstatush;
-#endif
-
uint32_t miclaim;
target_ulong mie;
@@ -179,16 +179,17 @@ struct CPURISCVState {
uint64_t htimedelta;
/* Virtual CSRs */
- target_ulong vsstatus;
+ /*
+ * For RV32 this is 32-bit vsstatus and 32-bit vsstatush.
+ * For RV64 this is a 64-bit 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 +201,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..daedad8691 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -4,10 +4,10 @@
#define TARGET_RISCV_CPU_BITS_H
#define get_field(reg, mask) (((reg) & \
- (target_ulong)(mask)) / ((mask) & ~((mask) << 1)))
-#define set_field(reg, mask, val) (((reg) & ~(target_ulong)(mask)) | \
- (((target_ulong)(val) * ((mask) & ~((mask) << 1))) & \
- (target_ulong)(mask)))
+ (uint64_t)(mask)) / ((mask) & ~((mask) << 1)))
+#define set_field(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 +381,8 @@
#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 MSTATUS64_UXL 0x0000000300000000ULL
#define MSTATUS64_SXL 0x0000000C00000000ULL
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 904899054d..109ee4bad6 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -110,27 +110,19 @@ 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 |
+ MSTATUS64_UXL;
bool current_virt = riscv_cpu_virt_enabled(env);
g_assert(riscv_has_ext(env, RVH));
-#if defined(TARGET_RISCV64)
- mstatus_mask |= MSTATUS64_UXL;
-#endif
-
if (current_virt) {
/* Current V=1 and we are about to change to V=0 */
env->vsstatus = env->mstatus & mstatus_mask;
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 +146,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;
@@ -720,7 +707,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
access_type != MMU_INST_FETCH &&
get_field(env->mstatus, MSTATUS_MPRV) &&
- MSTATUS_MPV_ISSET(env)) {
+ get_field(env->mstatus, MSTATUS_MPV)) {
riscv_cpu_set_two_stage_lookup(env, true);
}
@@ -781,7 +768,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
access_type != MMU_INST_FETCH &&
get_field(env->mstatus, MSTATUS_MPRV) &&
- MSTATUS_MPV_ISSET(env)) {
+ get_field(env->mstatus, MSTATUS_MPV)) {
riscv_cpu_set_two_stage_lookup(env, false);
}
@@ -844,7 +831,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.
@@ -969,19 +956,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,
- 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));
+ riscv_cpu_virt_enabled(env));
if (riscv_cpu_virt_enabled(env) && tval) {
env->mstatus = set_field(env->mstatus, MSTATUS_GVA, 1);
}
-#endif
mtval2 = env->guest_phys_fault_addr;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index aaef6c6f20..e33f6cdc11 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 */
@@ -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;
}
@@ -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..e0b45e5eb7 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());
@@ -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;
+ uint64_t mstatus = env->mstatus;
target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
- target_ulong prev_virt = MSTATUS_MPV_ISSET(env);
+ target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV);
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
env->mstatus = mstatus;
riscv_cpu_set_mode(env, prev_priv);
--
2.19.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH V4 2/6] target/riscv: Add basic vmstate description of CPU
2020-10-26 11:55 [PATCH V4 0/6] Support RISC-V migration Yifei Jiang
2020-10-26 11:55 ` [PATCH V4 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit Yifei Jiang
@ 2020-10-26 11:55 ` Yifei Jiang
2020-10-26 11:55 ` [PATCH V4 3/6] target/riscv: Add PMP state description Yifei Jiang
` (4 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Yifei Jiang @ 2020-10-26 11:55 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>
Reviewed-by: Alistair Francis <alistair.francis@wdc.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] 11+ messages in thread
* [PATCH V4 3/6] target/riscv: Add PMP state description
2020-10-26 11:55 [PATCH V4 0/6] Support RISC-V migration Yifei Jiang
2020-10-26 11:55 ` [PATCH V4 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit Yifei Jiang
2020-10-26 11:55 ` [PATCH V4 2/6] target/riscv: Add basic vmstate description of CPU Yifei Jiang
@ 2020-10-26 11:55 ` Yifei Jiang
2020-10-26 11:55 ` [PATCH V4 4/6] target/riscv: Add H extension " Yifei Jiang
` (3 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Yifei Jiang @ 2020-10-26 11:55 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>
Reviewed-by: Alistair Francis <alistair.francis@wdc.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] 11+ messages in thread
* [PATCH V4 4/6] target/riscv: Add H extension state description
2020-10-26 11:55 [PATCH V4 0/6] Support RISC-V migration Yifei Jiang
` (2 preceding siblings ...)
2020-10-26 11:55 ` [PATCH V4 3/6] target/riscv: Add PMP state description Yifei Jiang
@ 2020-10-26 11:55 ` Yifei Jiang
2020-10-26 11:55 ` [PATCH V4 5/6] target/riscv: Add V " Yifei Jiang
` (2 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Yifei Jiang @ 2020-10-26 11:55 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>
Reviewed-by: Alistair Francis <alistair.francis@wdc.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] 11+ messages in thread
* [PATCH V4 5/6] target/riscv: Add V extension state description
2020-10-26 11:55 [PATCH V4 0/6] Support RISC-V migration Yifei Jiang
` (3 preceding siblings ...)
2020-10-26 11:55 ` [PATCH V4 4/6] target/riscv: Add H extension " Yifei Jiang
@ 2020-10-26 11:55 ` Yifei Jiang
2020-10-26 11:55 ` [PATCH V4 6/6] target/riscv: Add sifive_plic vmstate Yifei Jiang
2020-10-27 20:26 ` [PATCH V4 0/6] Support RISC-V migration Alistair Francis
6 siblings, 0 replies; 11+ messages in thread
From: Yifei Jiang @ 2020-10-26 11:55 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>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
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] 11+ messages in thread
* [PATCH V4 6/6] target/riscv: Add sifive_plic vmstate
2020-10-26 11:55 [PATCH V4 0/6] Support RISC-V migration Yifei Jiang
` (4 preceding siblings ...)
2020-10-26 11:55 ` [PATCH V4 5/6] target/riscv: Add V " Yifei Jiang
@ 2020-10-26 11:55 ` Yifei Jiang
2020-10-27 20:26 ` [PATCH V4 0/6] Support RISC-V migration Alistair Francis
6 siblings, 0 replies; 11+ messages in thread
From: Yifei Jiang @ 2020-10-26 11:55 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>
Reviewed-by: Alistair Francis <alistair.francis@wdc.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] 11+ messages in thread
* Re: [PATCH V4 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit
2020-10-27 18:45 ` Richard Henderson
@ 2020-10-27 18:40 ` Alistair Francis
0 siblings, 0 replies; 11+ messages in thread
From: Alistair Francis @ 2020-10-27 18:40 UTC (permalink / raw)
To: Richard Henderson
Cc: open list:RISC-V, Zhanghailiang, Sagar Karandikar,
Bastian Koppelmann, Zhangxiaofeng (F),
qemu-devel@nongnu.org Developers, Yifei Jiang, yinyipeng,
Alistair Francis, Palmer Dabbelt, Wubin (H), dengkai (A)
On Tue, Oct 27, 2020 at 11:47 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 10/26/20 4:55 AM, Yifei Jiang wrote:
> > - qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
> > + qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", (target_ulong)env->mstatus);
>
> This is truncating mstatus to target_ulong, i.e. breaking the output for
> riscv32. You should use PRIx64 and print the whole 64-bit value.
That is what we want to do though. For RV32 the mstatus CSR is only
32-bits, where the upper 32-bit are stored in mstatush (the top
32-bits of QEMU's internal mstatus).
Alistair
>
>
> r~
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH V4 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit
2020-10-26 11:55 ` [PATCH V4 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit Yifei Jiang
@ 2020-10-27 18:45 ` Richard Henderson
2020-10-27 18:40 ` Alistair Francis
2020-10-27 20:26 ` Alistair Francis
1 sibling, 1 reply; 11+ messages in thread
From: Richard Henderson @ 2020-10-27 18:45 UTC (permalink / raw)
To: Yifei Jiang, qemu-devel, qemu-riscv
Cc: zhang.zhanghailiang, sagark, kbastian, victor.zhangxiaofeng,
Alistair.Francis, yinyipeng1, palmer, wu.wubin, dengkai1
On 10/26/20 4:55 AM, Yifei Jiang wrote:
> - qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
> + qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", (target_ulong)env->mstatus);
This is truncating mstatus to target_ulong, i.e. breaking the output for
riscv32. You should use PRIx64 and print the whole 64-bit value.
r~
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH V4 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit
2020-10-26 11:55 ` [PATCH V4 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit Yifei Jiang
2020-10-27 18:45 ` Richard Henderson
@ 2020-10-27 20:26 ` Alistair Francis
1 sibling, 0 replies; 11+ messages in thread
From: Alistair Francis @ 2020-10-27 20:26 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 Mon, Oct 26, 2020 at 4:58 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>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/cpu.c | 8 +++++---
> target/riscv/cpu.h | 24 +++++++++++-------------
> target/riscv/cpu_bits.h | 19 ++++---------------
> target/riscv/cpu_helper.c | 35 +++++++----------------------------
> target/riscv/csr.c | 18 ++++++++++--------
> target/riscv/op_helper.c | 11 ++++-------
> 6 files changed, 41 insertions(+), 74 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..e430670b60 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -140,14 +140,14 @@ struct CPURISCVState {
> target_ulong resetvec;
>
> target_ulong mhartid;
> - target_ulong mstatus;
> + /*
> + * For RV32 this is 32-bit mstatus and 32-bit mstatush.
> + * For RV64 this is a 64-bit mstatus.
> + */
> + uint64_t mstatus;
>
> target_ulong mip;
>
> -#ifdef TARGET_RISCV32
> - target_ulong mstatush;
> -#endif
> -
> uint32_t miclaim;
>
> target_ulong mie;
> @@ -179,16 +179,17 @@ struct CPURISCVState {
> uint64_t htimedelta;
>
> /* Virtual CSRs */
> - target_ulong vsstatus;
> + /*
> + * For RV32 this is 32-bit vsstatus and 32-bit vsstatush.
> + * For RV64 this is a 64-bit 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 +201,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..daedad8691 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -4,10 +4,10 @@
> #define TARGET_RISCV_CPU_BITS_H
>
> #define get_field(reg, mask) (((reg) & \
> - (target_ulong)(mask)) / ((mask) & ~((mask) << 1)))
> -#define set_field(reg, mask, val) (((reg) & ~(target_ulong)(mask)) | \
> - (((target_ulong)(val) * ((mask) & ~((mask) << 1))) & \
> - (target_ulong)(mask)))
> + (uint64_t)(mask)) / ((mask) & ~((mask) << 1)))
> +#define set_field(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 +381,8 @@
> #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 MSTATUS64_UXL 0x0000000300000000ULL
> #define MSTATUS64_SXL 0x0000000C00000000ULL
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 904899054d..109ee4bad6 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -110,27 +110,19 @@ 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 |
> + MSTATUS64_UXL;
> bool current_virt = riscv_cpu_virt_enabled(env);
>
> g_assert(riscv_has_ext(env, RVH));
>
> -#if defined(TARGET_RISCV64)
> - mstatus_mask |= MSTATUS64_UXL;
> -#endif
> -
> if (current_virt) {
> /* Current V=1 and we are about to change to V=0 */
> env->vsstatus = env->mstatus & mstatus_mask;
> 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 +146,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;
>
> @@ -720,7 +707,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
> access_type != MMU_INST_FETCH &&
> get_field(env->mstatus, MSTATUS_MPRV) &&
> - MSTATUS_MPV_ISSET(env)) {
> + get_field(env->mstatus, MSTATUS_MPV)) {
> riscv_cpu_set_two_stage_lookup(env, true);
> }
>
> @@ -781,7 +768,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
> access_type != MMU_INST_FETCH &&
> get_field(env->mstatus, MSTATUS_MPRV) &&
> - MSTATUS_MPV_ISSET(env)) {
> + get_field(env->mstatus, MSTATUS_MPV)) {
> riscv_cpu_set_two_stage_lookup(env, false);
> }
>
> @@ -844,7 +831,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.
> @@ -969,19 +956,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,
> - 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));
> + riscv_cpu_virt_enabled(env));
> if (riscv_cpu_virt_enabled(env) && tval) {
> env->mstatus = set_field(env->mstatus, MSTATUS_GVA, 1);
> }
> -#endif
>
> mtval2 = env->guest_phys_fault_addr;
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index aaef6c6f20..e33f6cdc11 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 */
> @@ -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;
> }
> @@ -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..e0b45e5eb7 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());
> @@ -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;
> + uint64_t mstatus = env->mstatus;
> target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
> - target_ulong prev_virt = MSTATUS_MPV_ISSET(env);
> + target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV);
> 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
> env->mstatus = mstatus;
> riscv_cpu_set_mode(env, prev_priv);
>
> --
> 2.19.1
>
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH V4 0/6] Support RISC-V migration
2020-10-26 11:55 [PATCH V4 0/6] Support RISC-V migration Yifei Jiang
` (5 preceding siblings ...)
2020-10-26 11:55 ` [PATCH V4 6/6] target/riscv: Add sifive_plic vmstate Yifei Jiang
@ 2020-10-27 20:26 ` Alistair Francis
6 siblings, 0 replies; 11+ messages in thread
From: Alistair Francis @ 2020-10-27 20:26 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 Mon, Oct 26, 2020 at 4:58 AM Yifei Jiang <jiangyifei@huawei.com> wrote:
>
> 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 v3
> 1. Apply Alistair's patch to exend get/set_field():
> https://www.mail-archive.com/qemu-devel@nongnu.org/msg753575.html
> 2. Remake the patch: Merge m/vsstatus and m/vsstatush into one uint64_t
> unit.
>
> 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
Thanks!
Applied to riscv-to-apply.next
Alistair
>
> hw/intc/sifive_plic.c | 26 ++++-
> hw/intc/sifive_plic.h | 1 +
> target/riscv/cpu.c | 16 ++--
> target/riscv/cpu.h | 24 +++--
> target/riscv/cpu_bits.h | 19 +---
> target/riscv/cpu_helper.c | 35 ++-----
> target/riscv/csr.c | 18 ++--
> target/riscv/internals.h | 4 +
> target/riscv/machine.c | 196 ++++++++++++++++++++++++++++++++++++++
> target/riscv/meson.build | 3 +-
> target/riscv/op_helper.c | 11 +--
> target/riscv/pmp.c | 29 +++---
> target/riscv/pmp.h | 2 +
> 13 files changed, 290 insertions(+), 94 deletions(-)
> create mode 100644 target/riscv/machine.c
>
> --
> 2.19.1
>
>
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2020-10-27 20:39 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-26 11:55 [PATCH V4 0/6] Support RISC-V migration Yifei Jiang
2020-10-26 11:55 ` [PATCH V4 1/6] target/riscv: Merge m/vsstatus and m/vsstatush into one uint64_t unit Yifei Jiang
2020-10-27 18:45 ` Richard Henderson
2020-10-27 18:40 ` Alistair Francis
2020-10-27 20:26 ` Alistair Francis
2020-10-26 11:55 ` [PATCH V4 2/6] target/riscv: Add basic vmstate description of CPU Yifei Jiang
2020-10-26 11:55 ` [PATCH V4 3/6] target/riscv: Add PMP state description Yifei Jiang
2020-10-26 11:55 ` [PATCH V4 4/6] target/riscv: Add H extension " Yifei Jiang
2020-10-26 11:55 ` [PATCH V4 5/6] target/riscv: Add V " Yifei Jiang
2020-10-26 11:55 ` [PATCH V4 6/6] target/riscv: Add sifive_plic vmstate Yifei Jiang
2020-10-27 20:26 ` [PATCH V4 0/6] Support RISC-V migration 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).