From 7d7508b495c38f2f1c592ea79183910a31836e30 Mon Sep 17 00:00:00 2001 From: LIU Zhiwei Date: Thu, 16 Jul 2020 02:06:19 +0800 Subject: [PATCH 011/107] target/riscv: rvv-1.0: add mstatus VS field Signed-off-by: LIU Zhiwei Signed-off-by: Frank Chang Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis --- target/riscv/cpu.h | 7 +++++++ target/riscv/cpu_bits.h | 1 + target/riscv/cpu_helper.c | 15 ++++++++++++++- target/riscv/csr.c | 25 ++++++++++++++++++++++++- 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index dc4271be2a..8fd7c01567 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -336,6 +336,7 @@ int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request); bool riscv_cpu_fp_enabled(CPURISCVState *env); +bool riscv_cpu_vector_enabled(CPURISCVState *env); bool riscv_cpu_virt_enabled(CPURISCVState *env); void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable); bool riscv_cpu_force_hs_excep_enabled(CPURISCVState *env); @@ -382,6 +383,7 @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong); #define TB_FLAGS_PRIV_MMU_MASK 3 #define TB_FLAGS_PRIV_HYP_ACCESS_MASK (1 << 2) #define TB_FLAGS_MSTATUS_FS MSTATUS_FS +#define TB_FLAGS_MSTATUS_VS MSTATUS_VS typedef CPURISCVState CPUArchState; typedef RISCVCPU ArchCPU; @@ -437,6 +439,7 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, #ifdef CONFIG_USER_ONLY flags |= TB_FLAGS_MSTATUS_FS; + flags |= TB_FLAGS_MSTATUS_VS; #else flags |= cpu_mmu_index(env, 0); if (riscv_cpu_fp_enabled(env)) { @@ -451,6 +454,10 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, flags = FIELD_DP32(flags, TB_FLAGS, HLSX, 1); } } + + if (riscv_cpu_vector_enabled(env)) { + flags |= env->mstatus & MSTATUS_VS; + } #endif *pflags = flags; diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index caf4599207..f88aae628f 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -371,6 +371,7 @@ #define MSTATUS_UBE 0x00000040 #define MSTATUS_MPIE 0x00000080 #define MSTATUS_SPP 0x00000100 +#define MSTATUS_VS 0x00000600 #define MSTATUS_MPP 0x00001800 #define MSTATUS_FS 0x00006000 #define MSTATUS_XS 0x00018000 diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 21c54ef561..8605e23a7b 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -109,11 +109,24 @@ bool riscv_cpu_fp_enabled(CPURISCVState *env) return false; } +/* Return true is vector support is currently enabled */ +bool riscv_cpu_vector_enabled(CPURISCVState *env) +{ + if (env->mstatus & MSTATUS_VS) { + if (riscv_cpu_virt_enabled(env) && !(env->mstatus_hs & MSTATUS_VS)) { + return false; + } + return true; + } + + return false; +} + void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env) { uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS | MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE | - MSTATUS64_UXL; + MSTATUS64_UXL | MSTATUS_VS; bool current_virt = riscv_cpu_virt_enabled(env); g_assert(riscv_has_ext(env, RVH)); diff --git a/target/riscv/csr.c b/target/riscv/csr.c index d2585395bf..f99fc60bd3 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -260,6 +260,7 @@ static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val) return -RISCV_EXCP_ILLEGAL_INST; } env->mstatus |= MSTATUS_FS; + env->mstatus |= MSTATUS_VS; #endif env->frm = (val & FSR_RD) >> FSR_RD_SHIFT; if (vs(env, csrno) >= 0) { @@ -290,6 +291,13 @@ static int read_vxrm(CPURISCVState *env, int csrno, target_ulong *val) static int write_vxrm(CPURISCVState *env, int csrno, target_ulong val) { +#if !defined(CONFIG_USER_ONLY) + if (!env->debugger && !riscv_cpu_vector_enabled(env)) { + return -RISCV_EXCP_ILLEGAL_INST; + } + env->mstatus |= MSTATUS_VS; +#endif + env->vxrm = val; return 0; } @@ -302,6 +310,13 @@ static int read_vxsat(CPURISCVState *env, int csrno, target_ulong *val) static int write_vxsat(CPURISCVState *env, int csrno, target_ulong val) { +#if !defined(CONFIG_USER_ONLY) + if (!env->debugger && !riscv_cpu_vector_enabled(env)) { + return -RISCV_EXCP_ILLEGAL_INST; + } + env->mstatus |= MSTATUS_VS; +#endif + env->vxsat = val; return 0; } @@ -314,6 +329,13 @@ static int read_vstart(CPURISCVState *env, int csrno, target_ulong *val) static int write_vstart(CPURISCVState *env, int csrno, target_ulong val) { +#if !defined(CONFIG_USER_ONLY) + if (!env->debugger && !riscv_cpu_vector_enabled(env)) { + return -RISCV_EXCP_ILLEGAL_INST; + } + env->mstatus |= MSTATUS_VS; +#endif + env->vstart = val; return 0; } @@ -478,7 +500,7 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE | MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM | MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR | - MSTATUS_TW; + MSTATUS_TW | MSTATUS_VS; if (!riscv_cpu_is_32bit(env)) { /* @@ -491,6 +513,7 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) mstatus = (mstatus & ~mask) | (val & mask); dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) | + ((mstatus & MSTATUS_VS) == MSTATUS_VS) | ((mstatus & MSTATUS_XS) == MSTATUS_XS); mstatus = set_field(mstatus, MSTATUS_SD, dirty); env->mstatus = mstatus; -- 2.33.1