On Sun, Apr 6, 2025 at 5:03 PM Paolo Bonzini <pbonz...@redhat.com> wrote: > > Profile CPUs reuse the instance_init function for bare CPUs; make them > proper subclasses instead. Enabling a profile is now done based on the > RISCVCPUDef struct: even though there is room for only one in RISCVCPUDef, > subclasses check that the parent class's profile is enabled through the > parent profile mechanism. > > Signed-off-by: Paolo Bonzini <pbonz...@redhat.com>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > target/riscv/cpu.h | 1 + > target/riscv/cpu.c | 85 +++++++++++++++++++++++++--------------------- > 2 files changed, 48 insertions(+), 38 deletions(-) > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index d247b9007a6..54dc4cc85d0 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -543,6 +543,7 @@ struct ArchCPU { > > typedef struct RISCVCPUDef { > RISCVMXL misa_mxl_max; /* max mxl for this cpu */ > + RISCVCPUProfile *profile; > uint32_t misa_ext; > int priv_spec; > int32_t vext_spec; > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > index 002f5a15ba2..d3d5c048d02 100644 > --- a/target/riscv/cpu.c > +++ b/target/riscv/cpu.c > @@ -1495,6 +1495,10 @@ static void riscv_cpu_init(Object *obj) > cpu->env.vext_ver = VEXT_VERSION_1_00_0; > cpu->cfg.max_satp_mode = -1; > > + if (mcc->def->profile) { > + mcc->def->profile->enabled = true; > + } > + > env->misa_ext_mask = env->misa_ext = mcc->def->misa_ext; > riscv_cpu_cfg_merge(&cpu->cfg, &mcc->def->cfg); > > @@ -2967,36 +2971,6 @@ static const Property riscv_cpu_properties[] = { > DEFINE_PROP_BOOL("x-misa-w", RISCVCPU, cfg.misa_w, false), > }; > > -#if defined(TARGET_RISCV64) > -static void rva22u64_profile_cpu_init(Object *obj) > -{ > - rv64i_bare_cpu_init(obj); > - > - RVA22U64.enabled = true; > -} > - > -static void rva22s64_profile_cpu_init(Object *obj) > -{ > - rv64i_bare_cpu_init(obj); > - > - RVA22S64.enabled = true; > -} > - > -static void rva23u64_profile_cpu_init(Object *obj) > -{ > - rv64i_bare_cpu_init(obj); > - > - RVA23U64.enabled = true; > -} > - > -static void rva23s64_profile_cpu_init(Object *obj) > -{ > - rv64i_bare_cpu_init(obj); > - > - RVA23S64.enabled = true; > -} > -#endif > - > static const gchar *riscv_gdb_arch_name(CPUState *cs) > { > RISCVCPU *cpu = RISCV_CPU(cs); > @@ -3063,6 +3037,32 @@ static void riscv_cpu_common_class_init(ObjectClass > *c, void *data) > device_class_set_props(dc, riscv_cpu_properties); > } > > +static bool profile_extends(RISCVCPUProfile *trial, RISCVCPUProfile *parent) > +{ > + RISCVCPUProfile *curr; > + if (!parent) { > + return true; > + } > + > + curr = trial; > + while (curr) { > + if (curr == parent) { > + return true; > + } > + curr = curr->u_parent; > + } > + > + curr = trial; > + while (curr) { > + if (curr == parent) { > + return true; > + } > + curr = curr->s_parent; > + } > + > + return false; > +} > + > static void riscv_cpu_class_base_init(ObjectClass *c, void *data) > { > RISCVCPUClass *mcc = RISCV_CPU_CLASS(c); > @@ -3077,6 +3077,11 @@ static void riscv_cpu_class_base_init(ObjectClass *c, > void *data) > if (data) { > const RISCVCPUDef *def = data; > mcc->def->bare |= def->bare; > + if (def->profile) { > + assert(profile_extends(def->profile, mcc->def->profile)); > + assert(mcc->def->bare); > + mcc->def->profile = def->profile; > + } > if (def->misa_mxl_max) { > assert(def->misa_mxl_max <= MXL_RV128); > mcc->def->misa_mxl_max = def->misa_mxl_max; > @@ -3243,19 +3248,22 @@ void riscv_isa_write_fdt(RISCVCPU *cpu, void *fdt, > char *nodename) > }), \ > } > > -#define DEFINE_PROFILE_CPU(type_name, misa_mxl_max_, initfn) \ > +#define DEFINE_RISCV_CPU(type_name, parent_type_name, ...) \ > { \ > .name = (type_name), \ > - .parent = TYPE_RISCV_BARE_CPU, \ > - .instance_init = (initfn), \ > + .parent = (parent_type_name), \ > .class_data = (void*) &((const RISCVCPUDef) { \ > - .misa_mxl_max = (misa_mxl_max_), \ > .priv_spec = RISCV_PROFILE_ATTR_UNUSED, \ > .vext_spec = RISCV_PROFILE_ATTR_UNUSED, \ > .cfg.max_satp_mode = -1, \ > + __VA_ARGS__ \ > }), \ > } > > +#define DEFINE_PROFILE_CPU(type_name, parent_type_name, profile_) \ > + DEFINE_RISCV_CPU(type_name, parent_type_name, \ > + .profile = &(profile_)) > + > static const TypeInfo riscv_cpu_type_infos[] = { > { > .name = TYPE_RISCV_CPU, > @@ -3334,10 +3342,11 @@ static const TypeInfo riscv_cpu_type_infos[] = { > #endif /* CONFIG_TCG */ > DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I, MXL_RV64, > rv64i_bare_cpu_init), > DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64E, MXL_RV64, > rv64e_bare_cpu_init), > - DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22U64, MXL_RV64, > rva22u64_profile_cpu_init), > - DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22S64, MXL_RV64, > rva22s64_profile_cpu_init), > - DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA23U64, MXL_RV64, > rva23u64_profile_cpu_init), > - DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA23S64, MXL_RV64, > rva23s64_profile_cpu_init), > + > + DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22U64, TYPE_RISCV_CPU_RV64I, > RVA22U64), > + DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22S64, TYPE_RISCV_CPU_RV64I, > RVA22S64), > + DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA23U64, TYPE_RISCV_CPU_RV64I, > RVA23U64), > + DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA23S64, TYPE_RISCV_CPU_RV64I, > RVA23S64), > #endif /* TARGET_RISCV64 */ > }; > > -- > 2.49.0 >