On 5 November 2018 at 18:51, Aaron Lindsay <aa...@os.amperecomputing.com> wrote: > This commit doesn't add any supported events, but provides the framework > for adding them. We store the pm_event structs in a simple array, and > provide the mapping from the event numbers to array indexes in the > supported_event_map array. Because the value of PMCEID[01] depends upon > which events are supported at runtime, generate it dynamically. > > Signed-off-by: Aaron Lindsay <alind...@codeaurora.org> > --- > target/arm/cpu.c | 20 +++++++++++++------- > target/arm/cpu.h | 10 ++++++++++ > target/arm/cpu64.c | 4 ---- > target/arm/helper.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 65 insertions(+), 11 deletions(-) > > diff --git a/target/arm/cpu.c b/target/arm/cpu.c > index 9e54c56379..d1c766d180 100644 > --- a/target/arm/cpu.c > +++ b/target/arm/cpu.c > @@ -957,9 +957,19 @@ static void arm_cpu_realizefn(DeviceState *dev, Error > **errp) > if (!cpu->has_pmu) { > unset_feature(env, ARM_FEATURE_PMU); > cpu->id_aa64dfr0 &= ~0xf00; > - } else if (!kvm_enabled()) { > - arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0); > - arm_register_el_change_hook(cpu, &pmu_post_el_change, 0); > + } > + if (arm_feature(env, ARM_FEATURE_PMU)) { > + uint64_t pmceid = get_pmceid(&cpu->env); > + cpu->pmceid0 = extract64(pmceid, 0, 32); > + cpu->pmceid1 = extract64(pmceid, 32, 32); > + > + if (!kvm_enabled()) { > + arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0); > + arm_register_el_change_hook(cpu, &pmu_post_el_change, 0); > + } > + } else { > + cpu->pmceid0 = 0x00000000; > + cpu->pmceid1 = 0x00000000; > }
This now sets one of the ID registers for "we have no PMU" in the first "if (!cpu->has_pmu)" statement (id_aa64dfr0), and some of them (pmceid0, pcmeid1) in this else clause at the end. We should put them all in the same place. > > if (!arm_feature(env, ARM_FEATURE_EL2)) { > @@ -1601,8 +1611,6 @@ static void cortex_a7_initfn(Object *obj) > cpu->id_pfr0 = 0x00001131; > cpu->id_pfr1 = 0x00011011; > cpu->id_dfr0 = 0x02010555; > - cpu->pmceid0 = 0x00000000; > - cpu->pmceid1 = 0x00000000; > cpu->id_afr0 = 0x00000000; > cpu->id_mmfr0 = 0x10101105; > cpu->id_mmfr1 = 0x40000000; > @@ -1647,8 +1655,6 @@ static void cortex_a15_initfn(Object *obj) > cpu->id_pfr0 = 0x00001131; > cpu->id_pfr1 = 0x00011011; > cpu->id_dfr0 = 0x02010555; > - cpu->pmceid0 = 0x0000000; > - cpu->pmceid1 = 0x00000000; > cpu->id_afr0 = 0x00000000; > cpu->id_mmfr0 = 0x10201105; > cpu->id_mmfr1 = 0x20000000; > diff --git a/target/arm/cpu.h b/target/arm/cpu.h > index 92282cd976..f991ff370e 100644 > --- a/target/arm/cpu.h > +++ b/target/arm/cpu.h > @@ -991,6 +991,16 @@ void pmu_op_finish(CPUARMState *env); > void pmu_pre_el_change(ARMCPU *cpu, void *ignored); > void pmu_post_el_change(ARMCPU *cpu, void *ignored); > > +/* > + * get_pmceid > + * @env: CPUARMState > + * > + * Return the PMCEID[01] register values corresponding to the counters which > + * are supported given the current configuration (0 is low 32, 1 is high 32 > + * bits) > + */ > +uint64_t get_pmceid(CPUARMState *env); This doesn't look like the right API, because in AArch64 PMCEID0_EL0 and PMCEID1_EL0 are both 64-bit registers, so you can't fit them both into a single uint64_t. thanks -- PMM