target/riscv: Add Hypervisor virtual CSRs accesses
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Palmer Dabbelt <palmer@sifive.com>
Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index bee639e..3fa8d2c 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -273,6 +273,7 @@
SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
static const target_ulong hip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
+static const target_ulong vsip_writable_mask = MIP_VSSIP;
#if defined(TARGET_RISCV32)
static const char valid_vm_1_09[16] = {
@@ -878,6 +879,111 @@
return 0;
}
+/* Virtual CSR Registers */
+static int read_vsstatus(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ *val = env->vsstatus;
+ return 0;
+}
+
+static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
+{
+ env->vsstatus = val;
+ return 0;
+}
+
+static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
+ target_ulong new_value, target_ulong write_mask)
+{
+ int ret = rmw_mip(env, 0, ret_value, new_value,
+ write_mask & env->mideleg & vsip_writable_mask);
+ return ret;
+}
+
+static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ *val = env->mie & env->mideleg & VS_MODE_INTERRUPTS;
+ return 0;
+}
+
+static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
+{
+ target_ulong newval = (env->mie & ~env->mideleg) | (val & env->mideleg & MIP_VSSIP);
+ return write_mie(env, CSR_MIE, newval);
+}
+
+static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ *val = env->vstvec;
+ return 0;
+}
+
+static int write_vstvec(CPURISCVState *env, int csrno, target_ulong val)
+{
+ env->vstvec = val;
+ return 0;
+}
+
+static int read_vsscratch(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ *val = env->vsscratch;
+ return 0;
+}
+
+static int write_vsscratch(CPURISCVState *env, int csrno, target_ulong val)
+{
+ env->vsscratch = val;
+ return 0;
+}
+
+static int read_vsepc(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ *val = env->vsepc;
+ return 0;
+}
+
+static int write_vsepc(CPURISCVState *env, int csrno, target_ulong val)
+{
+ env->vsepc = val;
+ return 0;
+}
+
+static int read_vscause(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ *val = env->vscause;
+ return 0;
+}
+
+static int write_vscause(CPURISCVState *env, int csrno, target_ulong val)
+{
+ env->vscause = val;
+ return 0;
+}
+
+static int read_vstval(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ *val = env->vstval;
+ return 0;
+}
+
+static int write_vstval(CPURISCVState *env, int csrno, target_ulong val)
+{
+ env->vstval = val;
+ return 0;
+}
+
+static int read_vsatp(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ *val = env->vsatp;
+ return 0;
+}
+
+static int write_vsatp(CPURISCVState *env, int csrno, target_ulong val)
+{
+ env->vsatp = val;
+ return 0;
+}
+
/* Physical Memory Protection */
static int read_pmpcfg(CPURISCVState *env, int csrno, target_ulong *val)
{
@@ -1091,6 +1197,16 @@
[CSR_HTINST] = { hmode, read_htinst, write_htinst },
[CSR_HGATP] = { hmode, read_hgatp, write_hgatp },
+ [CSR_VSSTATUS] = { hmode, read_vsstatus, write_vsstatus },
+ [CSR_VSIP] = { hmode, NULL, NULL, rmw_vsip },
+ [CSR_VSIE] = { hmode, read_vsie, write_vsie },
+ [CSR_VSTVEC] = { hmode, read_vstvec, write_vstvec },
+ [CSR_VSSCRATCH] = { hmode, read_vsscratch, write_vsscratch },
+ [CSR_VSEPC] = { hmode, read_vsepc, write_vsepc },
+ [CSR_VSCAUSE] = { hmode, read_vscause, write_vscause },
+ [CSR_VSTVAL] = { hmode, read_vstval, write_vstval },
+ [CSR_VSATP] = { hmode, read_vsatp, write_vsatp },
+
/* Physical Memory Protection */
[CSR_PMPCFG0 ... CSR_PMPADDR9] = { pmp, read_pmpcfg, write_pmpcfg },
[CSR_PMPADDR0 ... CSR_PMPADDR15] = { pmp, read_pmpaddr, write_pmpaddr },