aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/arm/cpu.h18
-rw-r--r--target/arm/helper.c22
2 files changed, 39 insertions, 1 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e043932fcb..cfa9fd6c1b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3519,6 +3519,13 @@ static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
}
+static inline bool isar_feature_aa32_pmu_8_4(const ARMISARegisters *id)
+{
+ /* 0xf means "non-standard IMPDEF PMU" */
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 5 &&
+ FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
+}
+
/*
* 64-bit feature tests via id registers.
*/
@@ -3704,6 +3711,12 @@ static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
}
+static inline bool isar_feature_aa64_pmu_8_4(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
+ FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
+}
+
/*
* Feature tests for "does this exist in either 32-bit or 64-bit?"
*/
@@ -3722,6 +3735,11 @@ static inline bool isar_feature_any_pmu_8_1(const ARMISARegisters *id)
return isar_feature_aa64_pmu_8_1(id) || isar_feature_aa32_pmu_8_1(id);
}
+static inline bool isar_feature_any_pmu_8_4(const ARMISARegisters *id)
+{
+ return isar_feature_aa64_pmu_8_4(id) || isar_feature_aa32_pmu_8_4(id);
+}
+
/*
* Forward to the above feature tests given an ARMCPU pointer.
*/
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 2fe09c1d60..72c9c7e694 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1130,6 +1130,12 @@ static bool pmu_8_1_events_supported(CPUARMState *env)
return cpu_isar_feature(any_pmu_8_1, env_archcpu(env));
}
+static bool pmu_8_4_events_supported(CPUARMState *env)
+{
+ /* For events which are supported in any v8.1 PMU */
+ return cpu_isar_feature(any_pmu_8_4, env_archcpu(env));
+}
+
static uint64_t zero_event_get_count(CPUARMState *env)
{
/* For events which on QEMU never fire, so their count is always zero */
@@ -1170,6 +1176,11 @@ static const pm_event pm_events[] = {
.get_count = zero_event_get_count,
.ns_per_count = zero_event_ns_per,
},
+ { .number = 0x03c, /* STALL */
+ .supported = pmu_8_4_events_supported,
+ .get_count = zero_event_get_count,
+ .ns_per_count = zero_event_ns_per,
+ },
};
/*
@@ -1178,7 +1189,7 @@ static const pm_event pm_events[] = {
* should first be updated to something sparse instead of the current
* supported_event_map[] array.
*/
-#define MAX_EVENT_ID 0x24
+#define MAX_EVENT_ID 0x3c
#define UNSUPPORTED_EVENT UINT16_MAX
static uint16_t supported_event_map[MAX_EVENT_ID + 1];
@@ -6414,6 +6425,15 @@ static void define_pmu_regs(ARMCPU *cpu)
};
define_arm_cp_regs(cpu, v81_pmu_regs);
}
+ if (cpu_isar_feature(any_pmu_8_4, cpu)) {
+ static const ARMCPRegInfo v84_pmmir = {
+ .name = "PMMIR_EL1", .state = ARM_CP_STATE_BOTH,
+ .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 6,
+ .access = PL1_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
+ .resetvalue = 0
+ };
+ define_one_arm_cp_reg(cpu, &v84_pmmir);
+ }
}
/* We don't know until after realize whether there's a GICv3