aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Müller <muellerd@fb.com>2021-02-10 09:41:22 -0800
committerPeter Maydell <peter.maydell@linaro.org>2021-02-11 19:48:09 +0000
commitd3c1183ffeb71ca3a783eae3d7e1c51e71e8a621 (patch)
tree691981f17d285a37bc7b580db06d93a520e6b623
parent4565d826163d2e3a4ca3a5ebf3904e6b3b04a487 (diff)
downloadqemu-arm-d3c1183ffeb71ca3a783eae3d7e1c51e71e8a621.tar.gz
target/arm: Correctly initialize MDCR_EL2.HPMNpull-target-arm-20210211-1
When working with performance monitoring counters, we look at MDCR_EL2.HPMN as part of the check whether a counter is enabled. This check fails, because MDCR_EL2.HPMN is reset to 0, meaning that no counters are "enabled" for < EL2. That's in violation of the Arm specification, which states that > On a Warm reset, this field [MDCR_EL2.HPMN] resets to the value in > PMCR_EL0.N That's also what a comment in the code acknowledges, but the necessary adjustment seems to have been forgotten when support for more counters was added. This change fixes the issue by setting the reset value to PMCR.N, which is four. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--target/arm/helper.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 2c27077fb2..0e1a3b9421 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -38,6 +38,7 @@
#endif
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
+#define PMCR_NUM_COUNTERS 4 /* QEMU IMPDEF choice */
#ifndef CONFIG_USER_ONLY
@@ -5735,13 +5736,11 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
.writefn = gt_hyp_ctl_write, .raw_writefn = raw_write },
#endif
/* The only field of MDCR_EL2 that has a defined architectural reset value
- * is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N; but we
- * don't implement any PMU event counters, so using zero as a reset
- * value for MDCR_EL2 is okay
+ * is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N.
*/
{ .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
- .access = PL2_RW, .resetvalue = 0,
+ .access = PL2_RW, .resetvalue = PMCR_NUM_COUNTERS,
.fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2), },
{ .name = "HPFAR", .state = ARM_CP_STATE_AA32,
.cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
@@ -6672,7 +6671,7 @@ static void define_pmu_regs(ARMCPU *cpu)
* field as main ID register, and we implement four counters in
* addition to the cycle count register.
*/
- unsigned int i, pmcrn = 4;
+ unsigned int i, pmcrn = PMCR_NUM_COUNTERS;
ARMCPRegInfo pmcr = {
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
.access = PL0_RW,