On Tue, Dec 19, 2023 at 12:09 AM Daniel Henrique Barboza <dbarb...@ventanamicro.com> wrote: > > The TCG emulation implements all the extensions described in the > RVA22U64 profile, both mandatory and optional. The mandatory extensions > will be enabled via the profile flag. We'll leave the optional > extensions to be enabled by hand. > > Given that this is the first profile we're implementing in TCG we'll > need some ground work first: > > - all profiles declared in riscv_profiles[] will be exposed to users. > TCG is the main accelerator we're considering when adding profile > support in QEMU, so for now it's safe to assume that all profiles in > riscv_profiles[] will be relevant to TCG; > > - we'll not support user profile settings for vendor CPUs. The flags > will still be exposed but users won't be able to change them; > > - profile support, albeit available for all non-vendor CPUs, will be > based on top of the new 'rv64i' CPU. Setting a profile to 'true' means > enable all mandatory extensions of this profile, setting it to 'false' > will disable all mandatory profile extensions of the CPU, which will > obliterate preset defaults. This is not a problem for a bare CPU like > rv64i but it can allow for silly scenarios when using other CPUs. E.g. > an user can do "-cpu rv64,rva22u64=false" and have a bunch of default > rv64 extensions disabled. The recommended way of using profiles is the > rv64i CPU, but users are free to experiment. > > For now we'll handle multi-letter extensions only. MISA extensions need > additional steps that we'll take care later. At this point we can boot a > Linux buildroot using rva22u64 using the following options: > > -cpu rv64i,rva22u64=true,sv39=true,g=true,c=true,s=true > > Note that being an usermode/application profile we still need to > explicitly set 's=true' to enable Supervisor mode to boot Linux. > > 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 | 80 ++++++++++++++++++++++++++++++++++++++ > 1 file changed, 80 insertions(+) > > diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c > index 3319ba8e4e..83d4dd00cf 100644 > --- a/target/riscv/tcg/tcg-cpu.c > +++ b/target/riscv/tcg/tcg-cpu.c > @@ -127,6 +127,19 @@ static bool cpu_cfg_offset_is_named_feat(uint32_t > ext_offset) > return false; > } > > +static void riscv_cpu_enable_named_feat(RISCVCPU *cpu, uint32_t feat_offset) > +{ > + switch (feat_offset) { > + case CPU_CFG_OFFSET(zic64b): > + cpu->cfg.cbom_blocksize = 64; > + cpu->cfg.cbop_blocksize = 64; > + cpu->cfg.cboz_blocksize = 64; > + break; > + default: > + g_assert_not_reached(); > + } > +} > + > static void cpu_bump_multi_ext_priv_ver(CPURISCVState *env, > uint32_t ext_offset) > { > @@ -885,6 +898,71 @@ static void riscv_cpu_add_misa_properties(Object > *cpu_obj) > } > } > > +static void cpu_set_profile(Object *obj, Visitor *v, const char *name, > + void *opaque, Error **errp) > +{ > + RISCVCPUProfile *profile = opaque; > + RISCVCPU *cpu = RISCV_CPU(obj); > + bool value; > + int i, ext_offset; > + > + if (riscv_cpu_is_vendor(obj)) { > + error_setg(errp, "Profile %s is not available for vendor CPUs", > + profile->name); > + return; > + } > + > + if (cpu->env.misa_mxl != MXL_RV64) { > + error_setg(errp, "Profile %s only available for 64 bit CPUs", > + profile->name); > + return; > + } > + > + if (!visit_type_bool(v, name, &value, errp)) { > + return; > + } > + > + profile->user_set = true; > + profile->enabled = value; > + > + for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) { > + ext_offset = profile->ext_offsets[i]; > + > + if (profile->enabled) { > + if (cpu_cfg_offset_is_named_feat(ext_offset)) { > + riscv_cpu_enable_named_feat(cpu, ext_offset); > + } > + > + cpu_bump_multi_ext_priv_ver(&cpu->env, ext_offset); > + } > + > + g_hash_table_insert(multi_ext_user_opts, > + GUINT_TO_POINTER(ext_offset), > + (gpointer)profile->enabled); > + isa_ext_update_enabled(cpu, ext_offset, profile->enabled); > + } > +} > + > +static void cpu_get_profile(Object *obj, Visitor *v, const char *name, > + void *opaque, Error **errp) > +{ > + RISCVCPUProfile *profile = opaque; > + bool value = profile->enabled; > + > + visit_type_bool(v, name, &value, errp); > +} > + > +static void riscv_cpu_add_profiles(Object *cpu_obj) > +{ > + for (int i = 0; riscv_profiles[i] != NULL; i++) { > + const RISCVCPUProfile *profile = riscv_profiles[i]; > + > + object_property_add(cpu_obj, profile->name, "bool", > + cpu_get_profile, cpu_set_profile, > + NULL, (void *)profile); > + } > +} > + > static bool cpu_ext_is_deprecated(const char *ext_name) > { > return isupper(ext_name[0]); > @@ -1012,6 +1090,8 @@ static void riscv_cpu_add_user_properties(Object *obj) > > riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_deprecated_exts); > > + riscv_cpu_add_profiles(obj); > + > for (Property *prop = riscv_cpu_options; prop && prop->name; prop++) { > qdev_property_add_static(DEVICE(obj), prop); > } > -- > 2.43.0 > >