On Dec 05 08:43, Aaron Lindsay wrote: > Signed-off-by: Aaron Lindsay <aa...@os.amperecomputing.com> > --- > target/arm/cpu.h | 4 ++-- > target/arm/helper.c | 18 ++++++++++++++++-- > 2 files changed, 18 insertions(+), 4 deletions(-) > > diff --git a/target/arm/cpu.h b/target/arm/cpu.h > index 304e6e47b3..4216fe22db 100644 > --- a/target/arm/cpu.h > +++ b/target/arm/cpu.h > @@ -837,8 +837,8 @@ struct ARMCPU { > uint32_t id_pfr0; > uint32_t id_pfr1; > uint32_t id_dfr0; > - uint32_t pmceid0; > - uint32_t pmceid1; > + uint64_t pmceid0; > + uint64_t pmceid1; > uint32_t id_afr0; > uint32_t id_mmfr0; > uint32_t id_mmfr1; > diff --git a/target/arm/helper.c b/target/arm/helper.c > index 71be6fb578..fb6939e99c 100644 > --- a/target/arm/helper.c > +++ b/target/arm/helper.c > @@ -5256,6 +5256,20 @@ void register_cp_regs_for_features(ARMCPU *cpu) > } else { > define_arm_cp_regs(cpu, not_v7_cp_reginfo); > } > + if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4) {
After further discussion on my last version, this should be if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 && FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) { to guard against defining these registers for implementation-defined PMUs. > + ARMCPRegInfo v81_pmu_regs[] = { > + { .name = "PMCEID2", .state = ARM_CP_STATE_AA32, > + .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4, > + .access = PL0_R, .accessfn = pmreg_access, .type = > ARM_CP_CONST, > + .resetvalue = extract64(cpu->pmceid0, 32, 32) }, > + { .name = "PMCEID3", .state = ARM_CP_STATE_AA32, > + .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5, > + .access = PL0_R, .accessfn = pmreg_access, .type = > ARM_CP_CONST, > + .resetvalue = extract64(cpu->pmceid1, 32, 32) }, > + REGINFO_SENTINEL > + }; > + define_arm_cp_regs(cpu, v81_pmu_regs); > + } > if (arm_feature(env, ARM_FEATURE_V8)) { > /* AArch64 ID registers, which all have impdef reset values. > * Note that within the ID register ranges the unused slots > @@ -5432,7 +5446,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) > { .name = "PMCEID0", .state = ARM_CP_STATE_AA32, > .cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 6, > .access = PL0_R, .accessfn = pmreg_access, .type = > ARM_CP_CONST, > - .resetvalue = cpu->pmceid0 }, > + .resetvalue = extract64(cpu->pmceid0, 0, 32) }, > { .name = "PMCEID0_EL0", .state = ARM_CP_STATE_AA64, > .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 6, > .access = PL0_R, .accessfn = pmreg_access, .type = > ARM_CP_CONST, > @@ -5440,7 +5454,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) > { .name = "PMCEID1", .state = ARM_CP_STATE_AA32, > .cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 7, > .access = PL0_R, .accessfn = pmreg_access, .type = > ARM_CP_CONST, > - .resetvalue = cpu->pmceid1 }, > + .resetvalue = extract64(cpu->pmceid1, 0, 32) }, > { .name = "PMCEID1_EL0", .state = ARM_CP_STATE_AA64, > .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7, > .access = PL0_R, .accessfn = pmreg_access, .type = > ARM_CP_CONST, > -- > 2.19.1 >