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>
This commit is contained in:
Alistair Francis 2020-01-31 17:02:07 -08:00 committed by Palmer Dabbelt
parent ff2cc1294c
commit 8747c9eeb2
No known key found for this signature in database
GPG Key ID: 2E1319F35FBB1889
1 changed files with 116 additions and 0 deletions

View File

@ -273,6 +273,7 @@ static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
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 @@ static int write_hgatp(CPURISCVState *env, int csrno, target_ulong val)
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 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
[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 },