On Sun, Apr 6, 2025 at 5:03 PM Paolo Bonzini <pbonzini@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 <pbonzini@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@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
>