target/arm: Make writes to MDCR_EL3 use PMU start/finish calls

In commit 01765386a8 we fixed a bug where we weren't correctly
bracketing changes to some registers with pmu_op_start() and
pmu_op_finish() calls for changes which affect whether the PMU
counters might be enabled.  However, we missed the case of writes to
the AArch64 MDCR_EL3 register, because (unlike its AArch32
counterpart) they are currently done directly to the CPU state struct
without going through the sdcr_write() function.

Give MDCR_EL3 a writefn which handles the PMU start/finish calls.
The SDCR writefn then simplfies to "call the MDCR_EL3 writefn after
masking off the bits which don't exist in the AArch32 register".

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220923123412.1214041-3-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell 2022-09-23 13:34:11 +01:00
parent 7f4fbfb5dc
commit 80d2b43b2f
1 changed files with 14 additions and 4 deletions

View File

@ -4756,8 +4756,8 @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
}
}
static void sdcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
static void mdcr_el3_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
/*
* Some MDCR_EL3 bits affect whether PMU counters are running:
@ -4769,12 +4769,19 @@ static void sdcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
if (pmu_op) {
pmu_op_start(env);
}
env->cp15.mdcr_el3 = value & SDCR_VALID_MASK;
env->cp15.mdcr_el3 = value;
if (pmu_op) {
pmu_op_finish(env);
}
}
static void sdcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
/* Not all bits defined for MDCR_EL3 exist in the AArch32 SDCR */
mdcr_el3_write(env, ri, value & SDCR_VALID_MASK);
}
static void mdcr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
@ -5122,9 +5129,12 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
.access = PL2_RW,
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_FIQ]) },
{ .name = "MDCR_EL3", .state = ARM_CP_STATE_AA64,
.type = ARM_CP_IO,
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 3, .opc2 = 1,
.resetvalue = 0,
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el3) },
.access = PL3_RW,
.writefn = mdcr_el3_write,
.fieldoffset = offsetof(CPUARMState, cp15.mdcr_el3) },
{ .name = "SDCR", .type = ARM_CP_ALIAS | ARM_CP_IO,
.cp = 15, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 1,
.access = PL1_RW, .accessfn = access_trap_aa32s_el1,