On Sat, Sep 2, 2023 at 5:49 AM Daniel Henrique Barboza <dbarb...@ventanamicro.com> wrote: > > During realize() time we're activating a lot of extensions based on some > criteria, e.g.: > > if (cpu->cfg.ext_zk) { > cpu->cfg.ext_zkn = true; > cpu->cfg.ext_zkr = true; > cpu->cfg.ext_zkt = true; > } > > This practice resulted in at least one case where we ended up enabling > something we shouldn't: RVC enabling zca/zcd/zcf when using a CPU that > has priv_spec older than 1.12.0. > > We're also not considering user choice. There's no way of doing it now > but this is about to change in the next few patches. > > cpu_cfg_ext_auto_update() will check for priv version mismatches before > enabling extensions. If we have a mismatch between the current priv > version and the extension we want to enable, do not enable it. In the > near future, this same function will also consider user choice when > deciding if we're going to enable/disable an extension or not. > > For now let's use it to handle zca/zcd/zcf enablement if RVC is enabled. > > Signed-off-by: Daniel Henrique Barboza <dbarb...@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > target/riscv/cpu.c | 43 ++++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 40 insertions(+), 3 deletions(-) > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > index 43c68e1792..a4876df5f4 100644 > --- a/target/riscv/cpu.c > +++ b/target/riscv/cpu.c > @@ -177,6 +177,43 @@ static void isa_ext_update_enabled(RISCVCPU *cpu, > uint32_t ext_offset, > *ext_enabled = en; > } > > +static int cpu_cfg_ext_get_min_version(uint32_t ext_offset) > +{ > + int i; > + > + for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) { > + if (isa_edata_arr[i].ext_enable_offset != ext_offset) { > + continue; > + } > + > + return isa_edata_arr[i].min_version; > + } > + > + g_assert_not_reached(); > +} > + > +static void cpu_cfg_ext_auto_update(RISCVCPU *cpu, uint32_t ext_offset, > + bool value) > +{ > + CPURISCVState *env = &cpu->env; > + bool prev_val = isa_ext_is_enabled(cpu, ext_offset); > + int min_version; > + > + if (prev_val == value) { > + return; > + } > + > + if (value && env->priv_ver != PRIV_VERSION_LATEST) { > + /* Do not enable it if priv_ver is older than min_version */ > + min_version = cpu_cfg_ext_get_min_version(ext_offset); > + if (env->priv_ver < min_version) { > + return; > + } > + } > + > + isa_ext_update_enabled(cpu, ext_offset, value); > +} > + > const char * const riscv_int_regnames[] = { > "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1", > "x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3", > @@ -1268,12 +1305,12 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, > Error **errp) > > /* zca, zcd and zcf has a PRIV 1.12.0 restriction */ > if (riscv_has_ext(env, RVC) && env->priv_ver >= PRIV_VERSION_1_12_0) { > - cpu->cfg.ext_zca = true; > + cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zca), true); > if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) { > - cpu->cfg.ext_zcf = true; > + cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcf), true); > } > if (riscv_has_ext(env, RVD)) { > - cpu->cfg.ext_zcd = true; > + cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zcd), true); > } > } > > -- > 2.41.0 > >