On Sat, Oct 28, 2023 at 8:07 PM Daniel Henrique Barboza <dbarb...@ventanamicro.com> wrote: > > Enabling a profile and then disabling some of its mandatory extensions > is a valid use. It can be useful for debugging and testing. But the > common expected use of enabling a profile is to enable all its mandatory > extensions. > > Add an user warning when mandatory extensions from an enabled profile > are disabled in the command line, like we're already doing with RVG. > > After this patch, this will throw warnings: > > -cpu rv64,rva22u64=true,zihintpause=false,zicbom=false,zicboz=false > > qemu-system-riscv64: warning: Profile rva22u64 mandates disabled extension > zihintpause > qemu-system-riscv64: warning: Profile rva22u64 mandates disabled extension > zicbom > qemu-system-riscv64: warning: Profile rva22u64 mandates disabled extension > zicboz > > Note that the following will NOT throw warnings because the profile is > being enabled last, hence all its mandatory extensions will be enabled: > > -cpu rv64,zihintpause=false,zicbom=false,zicboz=false,rva22u64=true > > Signed-off-by: Daniel Henrique Barboza <dbarb...@ventanamicro.com> > Reviewed-by: Andrew Jones <ajo...@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > target/riscv/tcg/tcg-cpu.c | 61 ++++++++++++++++++++++++++++++++++++++ > 1 file changed, 61 insertions(+) > > diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c > index 953e8432d6..5e7855b41b 100644 > --- a/target/riscv/tcg/tcg-cpu.c > +++ b/target/riscv/tcg/tcg-cpu.c > @@ -147,6 +147,27 @@ static int cpu_cfg_ext_get_min_version(uint32_t > ext_offset) > g_assert_not_reached(); > } > > +static const char *cpu_cfg_ext_get_name(uint32_t ext_offset) > +{ > + const RISCVCPUMultiExtConfig *feat; > + const RISCVIsaExtData *edata; > + > + for (edata = isa_edata_arr; edata && edata->name; edata++) { > + if (edata->ext_enable_offset == ext_offset) { > + return edata->name; > + } > + } > + > + for (feat = riscv_cpu_named_features; feat->name != NULL; feat++) { > + if (feat->offset == ext_offset) { > + return feat->name; > + } > + } > + > + g_assert_not_reached(); > +} > + > + > static void cpu_cfg_ext_auto_update(RISCVCPU *cpu, uint32_t ext_offset, > bool value) > { > @@ -631,6 +652,45 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, > Error **errp) > riscv_cpu_disable_priv_spec_isa_exts(cpu); > } > > +static void riscv_cpu_validate_profile(RISCVCPU *cpu, > + RISCVCPUProfile *profile) > +{ > + const char *warn_msg = "Profile %s mandates disabled extension %s"; > + int i; > + > + for (i = 0; misa_bits[i] != 0; i++) { > + uint32_t bit = misa_bits[i]; > + > + if (!(profile->misa_ext & bit)) { > + continue; > + } > + > + if (!riscv_has_ext(&cpu->env, bit)) { > + warn_report(warn_msg, profile->name, > riscv_get_misa_ext_name(bit)); > + } > + } > + > + for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) { > + int ext_offset = profile->ext_offsets[i]; > + > + if (!isa_ext_is_enabled(cpu, ext_offset)) { > + warn_report(warn_msg, profile->name, > + cpu_cfg_ext_get_name(ext_offset)); > + } > + } > +} > + > +static void riscv_cpu_validate_profiles(RISCVCPU *cpu) > +{ > + for (int i = 0; riscv_profiles[i] != NULL; i++) { > + RISCVCPUProfile *profile = riscv_profiles[i]; > + > + if (profile->user_set && profile->enabled) { > + riscv_cpu_validate_profile(cpu, profile); > + } > + } > +} > + > void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp) > { > CPURISCVState *env = &cpu->env; > @@ -649,6 +709,7 @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error > **errp) > } > > riscv_cpu_validate_named_features(cpu); > + riscv_cpu_validate_profiles(cpu); > > if (cpu->cfg.ext_smepmp && !cpu->cfg.pmp) { > /* > -- > 2.41.0 > >