On Fri, 23 Aug 2019 16:38:10 PDT (-0700), Alistair Francis wrote:
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/csr.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 68 insertions(+)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 471f23a1d0..388775d45a 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -98,6 +98,20 @@ static int smode(CPURISCVState *env, int csrno)
> return -!riscv_has_ext(env, RVS);
> }
>
> +static int hmode(CPURISCVState *env, int csrno)
> +{
> + if (riscv_has_ext(env, RVS) &&
> + riscv_has_ext(env, RVH)) {
> + /* Hypervisor extension is supported */
> + if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
> + env->priv == PRV_M) {
> + return 0;
> + }
> + }
> +
> + return -1;
> +}
> +
> static int pmp(CPURISCVState *env, int csrno)
> {
> return -!riscv_feature(env, RISCV_FEATURE_PMP);
> @@ -754,6 +768,55 @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
> return 0;
> }
>
> +/* Hypervisor Extensions */
> +static int read_hstatus(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> + *val = env->hstatus;
> + return 0;
> +}
> +
> +static int write_hstatus(CPURISCVState *env, int csrno, target_ulong val)
> +{
> + env->hstatus = val;
> + return 0;
> +}
> +
> +static int read_hedeleg(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> + *val = env->hedeleg;
> + return 0;
> +}
> +
> +static int write_hedeleg(CPURISCVState *env, int csrno, target_ulong val)
> +{
> + env->hedeleg = val;
> + return 0;
> +}
> +
> +static int read_hideleg(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> + *val = env->hideleg;
> + return 0;
> +}
> +
> +static int write_hideleg(CPURISCVState *env, int csrno, target_ulong val)
> +{
> + env->hideleg = val;
> + return 0;
> +}
> +
> +static int read_hgatp(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> + *val = env->hgatp;
> + return 0;
> +}
> +
> +static int write_hgatp(CPURISCVState *env, int csrno, target_ulong val)
> +{
> + env->hgatp = val;
> + return 0;
> +}
> +
> /* Physical Memory Protection */
> static int read_pmpcfg(CPURISCVState *env, int csrno, target_ulong *val)
> {
> @@ -950,6 +1013,11 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> /* Supervisor Protection and Translation */
> [CSR_SATP] = { smode, read_satp, write_satp },
>
> + [CSR_HSTATUS] = { hmode, read_hstatus, write_hstatus },
> + [CSR_HEDELEG] = { hmode, read_hedeleg, write_hedeleg },
> + [CSR_HIDELEG] = { hmode, read_hideleg, write_hideleg },
> + [CSR_HGATP] = { hmode, read_hgatp, write_hgatp },
> +
> /* Physical Memory Protection */
> [CSR_PMPCFG0 ... CSR_PMPADDR9] = { pmp, read_pmpcfg, write_pmpcfg },
> [CSR_PMPADDR0 ... CSR_PMPADDR15] = { pmp, read_pmpaddr, write_pmpaddr },
Reviewed-by: Palmer Dabbelt <palmer@sifive.com>