@@ -317,6 +317,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);
@@ -360,6 +361,7 @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
#define TB_FLAGS_MMU_MASK 3
#define TB_FLAGS_MSTATUS_FS MSTATUS_FS
+#define TB_FLAGS_MSTATUS_VS MSTATUS_VS
typedef CPURISCVState CPUArchState;
typedef RISCVCPU ArchCPU;
@@ -410,11 +412,15 @@ 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)) {
flags |= env->mstatus & MSTATUS_FS;
}
+ if (riscv_cpu_vector_enabled(env)) {
+ flags |= env->mstatus & MSTATUS_VS;
+ }
#endif
*pflags = flags;
}
@@ -367,6 +367,7 @@
#define MSTATUS_SPIE 0x00000020
#define MSTATUS_MPIE 0x00000080
#define MSTATUS_SPP 0x00000100
+#define MSTATUS_VS 0x00000600
#define MSTATUS_MPP 0x00001800
#define MSTATUS_FS 0x00006000
#define MSTATUS_XS 0x00018000
@@ -108,10 +108,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)
{
target_ulong mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
- MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE;
+ MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE |
+ MSTATUS_VS;
bool current_virt = riscv_cpu_virt_enabled(env);
g_assert(riscv_has_ext(env, RVH));
@@ -180,6 +180,7 @@ static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val)
return -1;
}
env->mstatus |= MSTATUS_FS;
+ env->mstatus |= MSTATUS_VS;
#endif
env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
if (vs(env, csrno) >= 0) {
@@ -210,6 +211,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 -1;
+ }
+ env->mstatus |= MSTATUS_VS;
+#endif
+
env->vxrm = val;
return 0;
}
@@ -222,6 +230,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 -1;
+ }
+ env->mstatus |= MSTATUS_VS;
+#endif
+
env->vxsat = val;
return 0;
}
@@ -234,6 +249,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 -1;
+ }
+ env->mstatus |= MSTATUS_VS;
+#endif
+
env->vstart = val;
return 0;
}
@@ -400,7 +422,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 defined(TARGET_RISCV64)
/*
* RV32: MPV and MTL are not in mstatus. The current plan is to
@@ -412,6 +434,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;