target/arm: Implement FEAT_PMUv3p5 cycle counter disable bits

FEAT_PMUv3p5 introduces new bits which disable the cycle
counter from counting:
 * MDCR_EL2.HCCD disables the counter when in EL2
 * MDCR_EL3.SCCD disables the counter when Secure

Add the code to support these bits.

(Note that there is a third documented counter-disable
bit, MDCR_EL3.MCCD, which disables the counter when in
EL3. This is not present until FEAT_PMUv3p7, so is
out of scope for now.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20220822132358.3524971-9-peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Peter Maydell 2022-08-22 14:23:56 +01:00 committed by Richard Henderson
parent a793bcd027
commit 0b42f4fab9
2 changed files with 37 additions and 4 deletions

View file

@ -1084,8 +1084,8 @@ static CPAccessResult pmreg_access_ccntr(CPUARMState *env,
* We use these to decide whether we need to wrap a write to MDCR_EL2
* or MDCR_EL3 in pmu_op_start()/pmu_op_finish() calls.
*/
#define MDCR_EL2_PMU_ENABLE_BITS (MDCR_HPME | MDCR_HPMD | MDCR_HPMN)
#define MDCR_EL3_PMU_ENABLE_BITS (MDCR_SPME)
#define MDCR_EL2_PMU_ENABLE_BITS (MDCR_HPME | MDCR_HPMD | MDCR_HPMN | MDCR_HCCD)
#define MDCR_EL3_PMU_ENABLE_BITS (MDCR_SPME | MDCR_SCCD)
/* Returns true if the counter (pass 31 for PMCCNTR) should count events using
* the current EL, security state, and register configuration.
@ -1120,8 +1120,21 @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
prohibited = prohibited || !(env->cp15.mdcr_el3 & MDCR_SPME);
}
if (prohibited && counter == 31) {
prohibited = env->cp15.c9_pmcr & PMCRDP;
if (counter == 31) {
/*
* The cycle counter defaults to running. PMCR.DP says "disable
* the cycle counter when event counting is prohibited".
* Some MDCR bits disable the cycle counter specifically.
*/
prohibited = prohibited && env->cp15.c9_pmcr & PMCRDP;
if (cpu_isar_feature(any_pmuv3p5, env_archcpu(env))) {
if (secure) {
prohibited = prohibited || (env->cp15.mdcr_el3 & MDCR_SCCD);
}
if (el == 2) {
prohibited = prohibited || (mdcr_el2 & MDCR_HCCD);
}
}
}
if (counter == 31) {