summaryrefslogtreecommitdiff
path: root/target-arm/helper.c
diff options
context:
space:
mode:
authorAlistair Francis <alistair.francis@xilinx.com>2014-08-29 15:00:29 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-08-29 15:00:29 +0100
commitec7b4ce4c7864337a336721721d48456b4b5b51d (patch)
tree26c82a0cf879258fafd58dcb5515a3d89a0c2f7b /target-arm/helper.c
parent87124fdea443322924be00eb79430a6243cf0747 (diff)
downloadqemu-ec7b4ce4c7864337a336721721d48456b4b5b51d.tar.gz
target-arm: Implement pmccntr_sync function
This is used to synchronise the PMCCNTR counter and swap its state between enabled and disabled if required. It must always be called twice, both before and after any logic that could change the state of the PMCCNTR counter. Signed-off-by: Alistair Francis <alistair.francis@xilinx.com> Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> Message-id: 62811d4c0f7b1384f7aab62ea2fcfda3dcb0db50.1409025949.git.peter.crosthwaite@xilinx.com [PMM: fixed minor typos in pmccntr_sync doc comment] Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-arm/helper.c')
-rw-r--r--target-arm/helper.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c
index e6c82ab0b8..fa79dfa614 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -560,6 +560,23 @@ static inline bool arm_ccnt_enabled(CPUARMState *env)
return true;
}
+void pmccntr_sync(CPUARMState *env)
+{
+ uint64_t temp_ticks;
+
+ temp_ticks = muldiv64(qemu_clock_get_us(QEMU_CLOCK_VIRTUAL),
+ get_ticks_per_sec(), 1000000);
+
+ if (env->cp15.c9_pmcr & PMCRD) {
+ /* Increment once every 64 processor clock cycles */
+ temp_ticks /= 64;
+ }
+
+ if (arm_ccnt_enabled(env)) {
+ env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt;
+ }
+}
+
static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
@@ -644,6 +661,12 @@ static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
pmccntr_write(env, ri, deposit64(cur_val, 0, 32, value));
}
+#else /* CONFIG_USER_ONLY */
+
+void pmccntr_sync(CPUARMState *env)
+{
+}
+
#endif
static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,