@@ -547,6 +547,50 @@ static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
}
#ifndef CONFIG_USER_ONLY
+
+#define PMCCFILTR_NSH 0x8000000
+#define PMCCFILTR_P 0x80000000
+#define PMCCFILTR_U 0x40000000
+
+#define PMXEVTYPER_P 0x80000000
+#define PMXEVTYPER_U 0x40000000
+
+static inline bool arm_ccnt_enabled(CPUARMState *env)
+{
+ /* This does not support checking for the secure/non-secure
+ * components of the PMCCFILTR_EL0 register
+ */
+
+ if (!(env->cp15.c9_pmcr & PMCRE)) {
+ return false;
+ }
+
+ switch (arm_current_pl(env)) {
+ case 2:
+ if (!(env->cp15.pmccfiltr_el0 & PMCCFILTR_NSH)) {
+ return false;
+ } else {
+ break;
+ }
+ case 1:
+ if (env->cp15.pmccfiltr_el0 & PMCCFILTR_P ||
+ env->cp15.c9_pmxevtyper & PMXEVTYPER_P) {
+ return false;
+ } else {
+ break;
+ }
+ case 0:
+ if (env->cp15.pmccfiltr_el0 & PMCCFILTR_U ||
+ env->cp15.c9_pmxevtyper & PMXEVTYPER_U) {
+ return false;
+ } else {
+ break;
+ }
+ }
+
+ return true;
+}
+
static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{