[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 08/10] target/arm: Implement FEAT_PMUv3p5 cycle counter disabl
From: |
Peter Maydell |
Subject: |
[PATCH v2 08/10] target/arm: Implement FEAT_PMUv3p5 cycle counter disable bits |
Date: |
Mon, 22 Aug 2022 14:23:56 +0100 |
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>
---
v1->v2: Get the MDCR_EL3 bit right; v1 implemented something
more like MDCR_EL3.MCCD.
---
target/arm/cpu.h | 20 ++++++++++++++++++++
target/arm/helper.c | 21 +++++++++++++++++----
2 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 122ec8a47ec..1f6ccc6f217 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1332,6 +1332,8 @@ FIELD(CPTR_EL3, TTA, 20, 1)
FIELD(CPTR_EL3, TAM, 30, 1)
FIELD(CPTR_EL3, TCPAC, 31, 1)
+#define MDCR_SCCD (1U << 23) /* MDCR_EL3 */
+#define MDCR_HCCD (1U << 23) /* MDCR_EL2 */
#define MDCR_EPMAD (1U << 21)
#define MDCR_EDAD (1U << 20)
#define MDCR_SPME (1U << 17) /* MDCR_EL3 */
@@ -3724,6 +3726,13 @@ static inline bool isar_feature_aa32_pmuv3p4(const
ARMISARegisters *id)
FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
}
+static inline bool isar_feature_aa32_pmuv3p5(const ARMISARegisters *id)
+{
+ /* 0xf means "non-standard IMPDEF PMU" */
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 6 &&
+ FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
+}
+
static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id)
{
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, HPDS) != 0;
@@ -4048,6 +4057,12 @@ static inline bool isar_feature_aa64_pmuv3p4(const
ARMISARegisters *id)
FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
}
+static inline bool isar_feature_aa64_pmuv3p5(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 6 &&
+ FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
+}
+
static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0;
@@ -4221,6 +4236,11 @@ static inline bool isar_feature_any_pmuv3p4(const
ARMISARegisters *id)
return isar_feature_aa64_pmuv3p4(id) || isar_feature_aa32_pmuv3p4(id);
}
+static inline bool isar_feature_any_pmuv3p5(const ARMISARegisters *id)
+{
+ return isar_feature_aa64_pmuv3p5(id) || isar_feature_aa32_pmuv3p5(id);
+}
+
static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
{
return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 5212750b378..d22debcd57b 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -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) {
--
2.25.1
- [PATCH v2 00/10] target/arm: Implement FEAT_PMUv3p5, Peter Maydell, 2022/08/22
- [PATCH v2 02/10] target/arm: Correct value returned by pmu_counter_mask(), Peter Maydell, 2022/08/22
- [PATCH v2 01/10] target/arm: Don't corrupt high half of PMOVSR when cycle counter overflows, Peter Maydell, 2022/08/22
- [PATCH v2 03/10] target/arm: Don't mishandle count when enabling or disabling PMU counters, Peter Maydell, 2022/08/22
- [PATCH v2 04/10] target/arm: Ignore PMCR.D when PMCR.LC is set, Peter Maydell, 2022/08/22
- [PATCH v2 05/10] target/arm: Honour MDCR_EL2.HPMD in Secure EL2, Peter Maydell, 2022/08/22
- [PATCH v2 06/10] target/arm: Detect overflow when calculating next PMU interrupt, Peter Maydell, 2022/08/22
- [PATCH v2 07/10] target/arm: Rename pmu_8_n feature test functions, Peter Maydell, 2022/08/22
- [PATCH v2 10/10] target/arm: Report FEAT_PMUv3p5 for TCG '-cpu max', Peter Maydell, 2022/08/22
- [PATCH v2 08/10] target/arm: Implement FEAT_PMUv3p5 cycle counter disable bits,
Peter Maydell <=
- [PATCH v2 09/10] target/arm: Support 64-bit event counters for FEAT_PMUv3p5, Peter Maydell, 2022/08/22
- Re: [PATCH v2 00/10] target/arm: Implement FEAT_PMUv3p5, Richard Henderson, 2022/08/23