diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2022-09-23 13:34:11 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2022-09-29 17:31:52 +0100 |
commit | 80d2b43b2ff367f38ae4c9616b1ed261ecf801b6 (patch) | |
tree | 2a1ca500b89092a79c288983958c4a8ea4dc6c09 /target | |
parent | 7f4fbfb5dc08fe3fb6829bde8e4072d6cb214931 (diff) | |
download | qemu-80d2b43b2ff367f38ae4c9616b1ed261ecf801b6.zip qemu-80d2b43b2ff367f38ae4c9616b1ed261ecf801b6.tar.gz qemu-80d2b43b2ff367f38ae4c9616b1ed261ecf801b6.tar.bz2 |
target/arm: Make writes to MDCR_EL3 use PMU start/finish calls
In commit 01765386a88868 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
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/helper.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/target/arm/helper.c b/target/arm/helper.c index fadeed0..24c592f 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -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, |