On 11/20/18 1:26 PM, Aaron Lindsay wrote: > Setup a QEMUTimer to get a callback when we expect counters to next > overflow and trigger an interrupt at that time. > > Signed-off-by: Aaron Lindsay <alind...@codeaurora.org> > Signed-off-by: Aaron Lindsay <alind...@os.amperecomputing.com> > --- > target/arm/cpu.c | 12 +++++ > target/arm/cpu.h | 7 +++ > target/arm/helper.c | 126 +++++++++++++++++++++++++++++++++++++++++--- > 3 files changed, 139 insertions(+), 6 deletions(-) > > diff --git a/target/arm/cpu.c b/target/arm/cpu.c > index 208a08e867..7311a48e3c 100644 > --- a/target/arm/cpu.c > +++ b/target/arm/cpu.c > @@ -827,6 +827,13 @@ static void arm_cpu_finalizefn(Object *obj) > QLIST_REMOVE(hook, node); > g_free(hook); > } > +#ifndef CONFIG_USER_ONLY > + if (arm_feature(&cpu->env, ARM_FEATURE_PMU) && cpu->pmu_timer) {
No need for two tests here. Just check cpu->pmu_timer. (If it's set for any reason it should be freed, surely.) > @@ -1305,7 +1338,18 @@ void pmccntr_op_start(CPUARMState *env) > eff_cycles /= 64; > } > > - env->cp15.c15_ccnt = eff_cycles - env->cp15.c15_ccnt_delta; > + uint64_t new_pmccntr = eff_cycles - env->cp15.c15_ccnt_delta; > + > + unsigned int overflow_bit = (env->cp15.c9_pmcr & PMCRLC) ? 63 : 31; > + uint64_t overflow_mask = (uint64_t)1 << overflow_bit; > + if (!(new_pmccntr & overflow_mask) && > + (env->cp15.c15_ccnt & overflow_mask)) { Fyi, this expression is env->cp15.c15_ccnt & ~new_pmccntr & overflow_mask > + env->cp15.c9_pmovsr |= (1 << 31); > + new_pmccntr &= ~overflow_mask; Why this line? You just checked that overflow_mask was unset in new_pmccntr above. > @@ -1318,13 +1362,28 @@ void pmccntr_op_start(CPUARMState *env) > void pmccntr_op_finish(CPUARMState *env) > { > if (pmu_counter_enabled(env, 31)) { > - uint64_t prev_cycles = env->cp15.c15_ccnt_delta; > +#ifndef CONFIG_USER_ONLY > + uint64_t delta; > + if (env->cp15.c9_pmcr & PMCRLC) { > + delta = UINT64_MAX - env->cp15.c15_ccnt + 1; > + } else { > + delta = UINT32_MAX - (uint32_t)env->cp15.c15_ccnt + 1; > + } FWIW, this is the same as delta = -env->cp15.c15_ccnt; if (!(env->cp15.c9_pmcr & PMCRLC)) { delta = (uint32_t)delta; } r~