On Mon, 09 Dec 2019 10:12:09 PST (-0800), Alistair Francis wrote:
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/cpu.c | 6 ++++++
> target/riscv/cpu.h | 7 +++++++
> target/riscv/cpu_bits.h | 3 +++
> target/riscv/cpu_helper.c | 7 +++++++
> target/riscv/csr.c | 25 +++++++++++++++++++++++++
> target/riscv/op_helper.c | 4 ++++
> 6 files changed, 52 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index e61cf46a73..ac8f53a49d 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -237,6 +237,9 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
> #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);
> +#ifdef TARGET_RISCV32
> + qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ", *env->mstatush);
> +#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);
> @@ -473,6 +476,9 @@ static void riscv_cpu_init(Object *obj)
>
> #ifndef CONFIG_USER_ONLY
> env->mstatus = &env->mstatus_novirt;
> +# ifdef TARGET_RISCV32
> + env->mstatush = &env->mstatush_novirt;
> +# endif
> #endif
> }
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index b411a1f900..84a07971dc 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -127,6 +127,10 @@ struct CPURISCVState {
>
> target_ulong mip;
>
> +#ifdef TARGET_RISCV32
> + target_ulong *mstatush;
> +#endif
> +
> uint32_t miclaim;
>
> target_ulong mie;
> @@ -153,6 +157,9 @@ struct CPURISCVState {
> * required to handle the Hypervisor register swapping.
> */
> target_ulong mstatus_novirt;
> +#ifdef TARGET_RISCV32
> + target_ulong mstatush_novirt;
> +#endif
>
> /* Hypervisor CSRs */
> target_ulong hstatus;
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index a24654d137..049032f2ae 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -135,6 +135,9 @@
> #define CSR_MTVEC 0x305
> #define CSR_MCOUNTEREN 0x306
>
> +/* 32-bit only */
> +#define CSR_MSTATUSH 0x310
> +
> /* Legacy Counter Setup (priv v1.9.1) */
> /* Update to #define CSR_MCOUNTINHIBIT 0x320 for 1.11.0 */
> #define CSR_MUCOUNTEREN 0x320
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index aa033b8590..c2ad0bbce7 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -938,10 +938,17 @@ 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));
> + *env->mstatush = set_field(*env->mstatush, MSTATUS_MTL,
> + riscv_cpu_force_hs_excep_enabled(env));
> +#else
> *env->mstatus = set_field(*env->mstatus, MSTATUS_MPV,
> riscv_cpu_virt_enabled(env));
> *env->mstatus = set_field(*env->mstatus, MSTATUS_MTL,
> riscv_cpu_force_hs_excep_enabled(env));
> +#endif
>
> mtval2 = env->guest_phys_fault_addr;
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index d028dfb60b..b28058f9d5 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -372,6 +372,27 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
> return 0;
> }
>
> +#ifdef TARGET_RISCV32
> +static int read_mstatush(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> + *val = *env->mstatush;
> + return 0;
> +}
> +
> +static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
> +{
> + if ((val ^ *env->mstatush) & (MSTATUS_MPV)) {
> + tlb_flush(env_cpu(env));
> + }
> +
> + val &= MSTATUS_MPV | MSTATUS_MTL;
> +
> + *env->mstatush = val;
> +
> + return 0;
> +}
> +#endif
> +
> static int read_misa(CPURISCVState *env, int csrno, target_ulong *val)
> {
> *val = env->misa;
> @@ -1215,6 +1236,10 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> [CSR_MTVEC] = { any, read_mtvec, write_mtvec },
> [CSR_MCOUNTEREN] = { any, read_mcounteren, write_mcounteren },
>
> +#if defined(TARGET_RISCV32)
> + [CSR_MSTATUSH] = { any, read_mstatush, write_mstatush },
> +#endif
> +
> /* Legacy Counter Setup (priv v1.9.1) */
> [CSR_MUCOUNTEREN] = { any, read_mucounteren, write_mucounteren },
> [CSR_MSCOUNTEREN] = { any, read_mscounteren, write_mscounteren },
> diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
> index e5128570e6..a0a631d722 100644
> --- a/target/riscv/op_helper.c
> +++ b/target/riscv/op_helper.c
> @@ -153,7 +153,11 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
> get_field(mstatus, MSTATUS_MPIE));
> mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
> mstatus = set_field(mstatus, MSTATUS_MPP, 0);
> +#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);
Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>