target/ppc: finalize pre-EBB PMU logic
There are still PMU exclusive bits to handle in fire_PMC_interrupt() before implementing the EBB support. Let's finalize it now to avoid dealing with PMU and EBB logic at the same time in the next patches. fire_PMC_interrupt() will fire an Performance Monitor alert depending on MMCR0_PMAE. If we are required to freeze the timers (MMCR0_FCECE) we'll also need to update summaries and delete the existing overflow timers. In all cases we're going to update the cycle counters. Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> Message-Id: <20220225101140.1054160-3-danielhb413@gmail.com> Signed-off-by: Cédric Le Goater <clg@kaod.org>
This commit is contained in:
parent
33edcde7c8
commit
adc4eda103
@ -222,6 +222,20 @@ static void pmu_update_overflow_timers(CPUPPCState *env)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pmu_delete_timers(CPUPPCState *env)
|
||||||
|
{
|
||||||
|
QEMUTimer *pmc_overflow_timer;
|
||||||
|
int sprn;
|
||||||
|
|
||||||
|
for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC6; sprn++) {
|
||||||
|
pmc_overflow_timer = get_cyc_overflow_timer(env, sprn);
|
||||||
|
|
||||||
|
if (pmc_overflow_timer) {
|
||||||
|
timer_del(pmc_overflow_timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
|
void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
|
||||||
{
|
{
|
||||||
bool hflags_pmcc0 = (value & MMCR0_PMCC0) != 0;
|
bool hflags_pmcc0 = (value & MMCR0_PMCC0) != 0;
|
||||||
@ -271,8 +285,26 @@ static void fire_PMC_interrupt(PowerPCCPU *cpu)
|
|||||||
{
|
{
|
||||||
CPUPPCState *env = &cpu->env;
|
CPUPPCState *env = &cpu->env;
|
||||||
|
|
||||||
if (!(env->spr[SPR_POWER_MMCR0] & MMCR0_EBE)) {
|
pmu_update_cycles(env);
|
||||||
return;
|
|
||||||
|
if (env->spr[SPR_POWER_MMCR0] & MMCR0_FCECE) {
|
||||||
|
env->spr[SPR_POWER_MMCR0] &= ~MMCR0_FCECE;
|
||||||
|
env->spr[SPR_POWER_MMCR0] |= MMCR0_FC;
|
||||||
|
|
||||||
|
/* Changing MMCR0_FC requires a new HFLAGS_INSN_CNT calc */
|
||||||
|
pmu_update_summaries(env);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete all pending timers if we need to freeze
|
||||||
|
* the PMC. We'll restart them when the PMC starts
|
||||||
|
* running again.
|
||||||
|
*/
|
||||||
|
pmu_delete_timers(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMAE) {
|
||||||
|
env->spr[SPR_POWER_MMCR0] &= ~MMCR0_PMAE;
|
||||||
|
env->spr[SPR_POWER_MMCR0] |= MMCR0_PMAO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PMC interrupt not implemented yet */
|
/* PMC interrupt not implemented yet */
|
||||||
|
Loading…
Reference in New Issue
Block a user