diff options
author | Aaron Lindsay | 2019-01-21 11:23:13 +0100 |
---|---|---|
committer | Peter Maydell | 2019-01-21 11:38:55 +0100 |
commit | 5d05b9d462666ed21b7fef61aa45dec9aaa9f0ff (patch) | |
tree | 6ba7952d1335c704d8af79b58be6d589e15ce1c9 /target/arm/cpu.h | |
parent | migration: Add post_save function to VMStateDescription (diff) | |
download | qemu-5d05b9d462666ed21b7fef61aa45dec9aaa9f0ff.tar.gz qemu-5d05b9d462666ed21b7fef61aa45dec9aaa9f0ff.tar.xz qemu-5d05b9d462666ed21b7fef61aa45dec9aaa9f0ff.zip |
target/arm: Reorganize PMCCNTR accesses
pmccntr_read and pmccntr_write contained duplicate code that was already
being handled by pmccntr_sync. Consolidate the duplicated code into two
functions: pmccntr_op_start and pmccntr_op_finish. Add a companion to
c15_ccnt in CPUARMState so that we can simultaneously save both the
architectural register value and the last underlying cycle count - this
ensures time isn't lost and will also allow us to access the 'old'
architectural register value in order to detect overflows in later
patches.
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
Signed-off-by: Aaron Lindsay <aclindsa@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20181211151945.29137-3-aaron@os.amperecomputing.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/cpu.h')
-rw-r--r-- | target/arm/cpu.h | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 8fc5c8223e..fdbb401a11 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -473,10 +473,20 @@ typedef struct CPUARMState { uint64_t oslsr_el1; /* OS Lock Status */ uint64_t mdcr_el2; uint64_t mdcr_el3; - /* If the counter is enabled, this stores the last time the counter - * was reset. Otherwise it stores the counter value + /* Stores the architectural value of the counter *the last time it was + * updated* by pmccntr_op_start. Accesses should always be surrounded + * by pmccntr_op_start/pmccntr_op_finish to guarantee the latest + * architecturally-correct value is being read/set. */ uint64_t c15_ccnt; + /* Stores the delta between the architectural value and the underlying + * cycle count during normal operation. It is used to update c15_ccnt + * to be the correct architectural value before accesses. During + * accesses, c15_ccnt_delta contains the underlying count being used + * for the access, after which it reverts to the delta value in + * pmccntr_op_finish. + */ + uint64_t c15_ccnt_delta; uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */ uint64_t vpidr_el2; /* Virtualization Processor ID Register */ uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */ @@ -971,15 +981,26 @@ int cpu_arm_signal_handler(int host_signum, void *pinfo, void *puc); /** - * pmccntr_sync + * pmccntr_op_start/finish + * @env: CPUARMState + * + * Convert the counter in the PMCCNTR between its delta form (the typical mode + * when it's enabled) and the guest-visible value. These two calls must always + * surround any action which might affect the counter. + */ +void pmccntr_op_start(CPUARMState *env); +void pmccntr_op_finish(CPUARMState *env); + +/** + * pmu_op_start/finish * @env: CPUARMState * - * Synchronises the counter in the PMCCNTR. This must always be called twice, - * once before any action that might affect the timer and again afterwards. - * The function is used to swap the state of the register if required. - * This only happens when not in user mode (!CONFIG_USER_ONLY) + * Convert all PMU counters between their delta form (the typical mode when + * they are enabled) and the guest-visible values. These two calls must + * surround any action which might affect the counters. */ -void pmccntr_sync(CPUARMState *env); +void pmu_op_start(CPUARMState *env); +void pmu_op_finish(CPUARMState *env); /* SCTLR bit meanings. Several bits have been reused in newer * versions of the architecture; in that case we define constants |