@@ -811,12 +811,11 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
/*
* Check consistency between chosen extensions while setting
- * cpu->cfg accordingly, doing a set_misa() in the end.
+ * cpu->cfg accordingly.
*/
static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
{
CPURISCVState *env = &cpu->env;
- uint32_t ext = 0;
/* Do some ISA extension error checking */
if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
@@ -831,6 +830,9 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
cpu->cfg.ext_d = true;
cpu->cfg.ext_icsr = true;
cpu->cfg.ext_ifencei = true;
+
+ env->misa_ext |= RVI | RVM | RVA | RVF | RVD;
+ env->misa_ext_mask = env->misa_ext;
}
if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
@@ -1022,39 +1024,8 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
cpu->cfg.ext_zksh = true;
}
- if (cpu->cfg.ext_i) {
- ext |= RVI;
- }
- if (cpu->cfg.ext_e) {
- ext |= RVE;
- }
- if (cpu->cfg.ext_m) {
- ext |= RVM;
- }
- if (cpu->cfg.ext_a) {
- ext |= RVA;
- }
- if (cpu->cfg.ext_f) {
- ext |= RVF;
- }
- if (cpu->cfg.ext_d) {
- ext |= RVD;
- }
- if (cpu->cfg.ext_c) {
- ext |= RVC;
- }
- if (cpu->cfg.ext_s) {
- ext |= RVS;
- }
- if (cpu->cfg.ext_u) {
- ext |= RVU;
- }
- if (cpu->cfg.ext_h) {
- ext |= RVH;
- }
if (cpu->cfg.ext_v) {
int vext_version = VEXT_VERSION_1_00_0;
- ext |= RVV;
if (!is_power_of_2(cpu->cfg.vlen)) {
error_setg(errp,
"Vector extension VLEN must be power of 2");
@@ -1092,11 +1063,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
}
set_vext_version(env, vext_version);
}
- if (cpu->cfg.ext_j) {
- ext |= RVJ;
- }
-
- set_misa(env, env->misa_mxl, ext);
}
#ifndef CONFIG_USER_ONLY
@@ -1181,6 +1147,50 @@ static void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
#endif
}
+static void riscv_cpu_sync_misa_cfg(CPURISCVState *env)
+{
+ uint32_t ext = 0;
+
+ if (riscv_cpu_cfg(env)->ext_i) {
+ ext |= RVI;
+ }
+ if (riscv_cpu_cfg(env)->ext_e) {
+ ext |= RVE;
+ }
+ if (riscv_cpu_cfg(env)->ext_m) {
+ ext |= RVM;
+ }
+ if (riscv_cpu_cfg(env)->ext_a) {
+ ext |= RVA;
+ }
+ if (riscv_cpu_cfg(env)->ext_f) {
+ ext |= RVF;
+ }
+ if (riscv_cpu_cfg(env)->ext_d) {
+ ext |= RVD;
+ }
+ if (riscv_cpu_cfg(env)->ext_c) {
+ ext |= RVC;
+ }
+ if (riscv_cpu_cfg(env)->ext_s) {
+ ext |= RVS;
+ }
+ if (riscv_cpu_cfg(env)->ext_u) {
+ ext |= RVU;
+ }
+ if (riscv_cpu_cfg(env)->ext_h) {
+ ext |= RVH;
+ }
+ if (riscv_cpu_cfg(env)->ext_v) {
+ ext |= RVV;
+ }
+ if (riscv_cpu_cfg(env)->ext_j) {
+ ext |= RVJ;
+ }
+
+ env->misa_ext = env->misa_ext_mask = ext;
+}
+
static void riscv_cpu_realize(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
@@ -1216,6 +1226,14 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
set_priv_version(env, priv_version);
}
+ /*
+ * We can't be sure of whether we set defaults during cpu_init()
+ * or whether the user enabled/disabled some bits via cpu->cfg
+ * flags. Sync env->misa_ext with cpu->cfg now to allow us to
+ * use just env->misa_ext later.
+ */
+ riscv_cpu_sync_misa_cfg(env);
+
/* Force disable extensions if priv spec version does not match */
for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) &&