On Wed, Jul 24, 2024 at 9:32 AM Atish Patra <ati...@rivosinc.com> wrote: > > In addition to the implied rule, a preferred rule will be useful > where an ISA extension may require a list of ISA extension to be > enabled to use all the features defined in that extension. All > these extensions may not be implied in the ISA.
This seems practically the same as an implied rule, I'm not sure we need a separate list of rules Alistair > > This patch just introduces a new preferred rule which allows > to enable multiple extensions together without burdening the qemu > commandline user. > > Signed-off-by: Atish Patra <ati...@rivosinc.com> > --- > target/riscv/cpu.c | 4 ++++ > target/riscv/cpu.h | 17 ++++++++++++++ > target/riscv/tcg/tcg-cpu.c | 57 > ++++++++++++++++++++++++++++++++++++++++------ > 3 files changed, 71 insertions(+), 7 deletions(-) > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > index 393d1d67120e..22ba43c7ff2a 100644 > --- a/target/riscv/cpu.c > +++ b/target/riscv/cpu.c > @@ -2665,6 +2665,10 @@ RISCVCPUImpliedExtsRule > *riscv_multi_ext_implied_rules[] = { > NULL > }; > > +RISCVCPUPreferredExtsRule *riscv_multi_ext_preferred_rules[] = { > + NULL > +}; > + > static Property riscv_cpu_properties[] = { > DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true), > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index af25550a4a54..d775866344f5 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -142,10 +142,27 @@ typedef struct riscv_cpu_implied_exts_rule { > const uint32_t implied_multi_exts[]; > } RISCVCPUImpliedExtsRule; > > +typedef struct riscv_cpu_preferred_exts_rule { > +#ifndef CONFIG_USER_ONLY > + /* > + * Bitmask indicates the rule enabled status for the harts. > + * This enhancement is only available in system-mode QEMU, > + * as we don't have a good way (e.g. mhartid) to distinguish > + * the SMP cores in user-mode QEMU. > + */ > + unsigned long *enabled; > +#endif > + /* multi extension offset. */ > + const uint32_t ext; > + const uint32_t preferred_multi_exts[]; > +} RISCVCPUPreferredExtsRule; > + > extern RISCVCPUImpliedExtsRule *riscv_misa_ext_implied_rules[]; > extern RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[]; > +extern RISCVCPUPreferredExtsRule *riscv_multi_ext_preferred_rules[]; > > #define RISCV_IMPLIED_EXTS_RULE_END -1 > +#define RISCV_PREFRRED_EXTS_RULE_END RISCV_IMPLIED_EXTS_RULE_END > > #define MMU_USER_IDX 3 > > diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c > index 1c9a87029423..d8f74720815a 100644 > --- a/target/riscv/tcg/tcg-cpu.c > +++ b/target/riscv/tcg/tcg-cpu.c > @@ -32,6 +32,7 @@ > #include "hw/core/accel-cpu.h" > #include "hw/core/tcg-cpu-ops.h" > #include "tcg/tcg.h" > +#include <stdio.h> > #ifndef CONFIG_USER_ONLY > #include "hw/boards.h" > #endif > @@ -733,6 +734,7 @@ static void riscv_cpu_validate_profiles(RISCVCPU *cpu) > static void riscv_cpu_init_ext_rules(void) > { > RISCVCPUImpliedExtsRule *rule; > + RISCVCPUPreferredExtsRule *prule; > #ifndef CONFIG_USER_ONLY > MachineState *ms = MACHINE(qdev_get_machine()); > #endif > @@ -760,22 +762,40 @@ static void riscv_cpu_init_ext_rules(void) > GUINT_TO_POINTER(rule->ext), (gpointer)rule); > } > > + for (i = 0; (prule = riscv_multi_ext_preferred_rules[i]); i++) { > +#ifndef CONFIG_USER_ONLY > + prule->enabled = bitmap_new(ms->smp.cpus); > +#endif > + g_hash_table_insert(multi_ext_enabling_rules, > + GUINT_TO_POINTER(prule->ext), (gpointer)prule); > + } > + > initialized = true; > } > > static void cpu_enable_ext_rule(RISCVCPU *cpu, > - RISCVCPUImpliedExtsRule *rule) > + RISCVCPUImpliedExtsRule *rule, > + RISCVCPUPreferredExtsRule *prule) > { > CPURISCVState *env = &cpu->env; > RISCVCPUImpliedExtsRule *ir; > + RISCVCPUPreferredExtsRule *pr; > bool enabled = false; > int i; > > #ifndef CONFIG_USER_ONLY > - enabled = test_bit(cpu->env.mhartid, rule->enabled); > + if (rule) { > + enabled = test_bit(cpu->env.mhartid, rule->enabled); > + } else if (prule) { > + enabled = test_bit(cpu->env.mhartid, prule->enabled); > + } else { > + return; > + } > #endif > + if (enabled) > + return; > > - if (!enabled) { > + if (rule) { > /* Enable the implied MISAs. */ > if (rule->implied_misa_exts) { > riscv_cpu_set_misa_ext(env, > @@ -787,7 +807,7 @@ static void cpu_enable_ext_rule(RISCVCPU *cpu, > GUINT_TO_POINTER(misa_bits[i])); > > if (ir) { > - cpu_enable_ext_rule(cpu, ir); > + cpu_enable_ext_rule(cpu, ir, NULL); > } > } > } > @@ -803,12 +823,27 @@ static void cpu_enable_ext_rule(RISCVCPU *cpu, > rule->implied_multi_exts[i])); > > if (ir) { > - cpu_enable_ext_rule(cpu, ir); > + cpu_enable_ext_rule(cpu, ir, NULL); > } > } > > #ifndef CONFIG_USER_ONLY > bitmap_set(rule->enabled, cpu->env.mhartid, 1); > +#endif > + } else if (prule) { > + /* Enable the preferred extensions. */ > + for (i = 0; > + prule->preferred_multi_exts[i] != RISCV_PREFRRED_EXTS_RULE_END; > i++) { > + cpu_cfg_ext_auto_update(cpu, prule->preferred_multi_exts[i], > true); > + pr = g_hash_table_lookup(multi_ext_enabling_rules, > + GUINT_TO_POINTER( > + prule->preferred_multi_exts[i])); > + if (pr) { > + cpu_enable_ext_rule(cpu, NULL, prule); > + } > + } > +#ifndef CONFIG_USER_ONLY > + bitmap_set(prule->enabled, cpu->env.mhartid, 1); > #endif > } > } > @@ -847,6 +882,7 @@ static void cpu_enable_zc_implied_rules(RISCVCPU *cpu) > static void riscv_cpu_enable_ext_rules(RISCVCPU *cpu) > { > RISCVCPUImpliedExtsRule *rule; > + RISCVCPUPreferredExtsRule *prule; > int i; > > /* Enable the implied extensions for Zc. */ > @@ -855,14 +891,21 @@ static void riscv_cpu_enable_ext_rules(RISCVCPU *cpu) > /* Enable the implied MISAs. */ > for (i = 0; (rule = riscv_misa_ext_implied_rules[i]); i++) { > if (riscv_has_ext(&cpu->env, rule->ext)) { > - cpu_enable_ext_rule(cpu, rule); > + cpu_enable_ext_rule(cpu, rule, NULL); > } > } > > /* Enable the implied extensions. */ > for (i = 0; (rule = riscv_multi_ext_implied_rules[i]); i++) { > if (isa_ext_is_enabled(cpu, rule->ext)) { > - cpu_enable_ext_rule(cpu, rule); > + cpu_enable_ext_rule(cpu, rule, NULL); > + } > + } > + > + /* Enable the preferred extensions. */ > + for (i = 0; (prule = riscv_multi_ext_preferred_rules[i]); i++) { > + if (isa_ext_is_enabled(cpu, prule->ext)) { > + cpu_enable_ext_rule(cpu, NULL, prule); > } > } > } > > -- > 2.34.1 > >