[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH target-arm v3 5/8] target-arm: Implement pmccntr_syn
From: |
Peter Crosthwaite |
Subject: |
[Qemu-devel] [PATCH target-arm v3 5/8] target-arm: Implement pmccntr_sync function |
Date: |
Mon, 18 Aug 2014 01:14:42 -0700 |
From: Alistair Francis <address@hidden>
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 <address@hidden>
Signed-off-by: Peter Crosthwaite <address@hidden>
---
Changed since v2:
Move prototype further up cpu.h
Remembering that the c15_ccnt register stores the last time
the counter was reset if enabled. If disabled it stores the
counter value (when it was disabled).
The three use cases are as below:
--
Starts enabled/disabled and is staying enabled/disabled
--
The two calls to pmccntr_sync cancel each other out.
Each call implements this logic:
env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt
Which expands to:
env->cp15.c15_ccnt = temp_ticks -
(temp_ticks - env->cp15.c15_ccnt)
env->cp15.c15_ccnt = env->cp15.c15_ccnt
--
Starts enabled, gets disabled
--
The logic is run during the first call while during
the second call it is not. That means that c15_ccnt
changes from storing the last time the counter was
reset, to storing the absolute value of the counter.
--
Starts disabled, gets enabled
--
During the fist call no changes are made, while during
the second call the register is changed. This changes it
from storing the absolute value to storing the last time
the counter was reset.
target-arm/cpu.h | 11 +++++++++++
target-arm/helper.c | 23 +++++++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index b84fff7..5bc2afe 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -352,6 +352,17 @@ int cpu_arm_signal_handler(int host_signum, void *pinfo,
int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
int mmu_idx);
+/**
+ * pmccntr_sync
+ * @cpu: ARMCPU
+ *
+ * Syncronises the counter in the PMCCNTR. This must always be called twice,
+ * once before any action that might effect 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)
+ */
+void pmccntr_sync(CPUARMState *env);
+
/* SCTLR bit meanings. Several bits have been reused in newer
* versions of the architecture; in that case we define constants
* for both old and new bit meanings. Code which tests against those
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 0318816..60b8310 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -591,6 +591,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)
{
@@ -675,6 +692,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,
--
2.0.1.1.gfbfc394
- [Qemu-devel] [PATCH target-arm v3 0/8] target-arm: Extend PMCCNTR for ARMv8, Peter Crosthwaite, 2014/08/18
- [Qemu-devel] [PATCH target-arm v3 1/8] target-arm: Make the ARM PMCCNTR register 64-bit, Peter Crosthwaite, 2014/08/18
- [Qemu-devel] [PATCH target-arm v3 2/8] arm: Implement PMCCNTR 32b read-modify-write, Peter Crosthwaite, 2014/08/18
- [Qemu-devel] [PATCH target-arm v3 3/8] target-arm: Implement PMCCNTR_EL0 and related registers, Peter Crosthwaite, 2014/08/18
- [Qemu-devel] [PATCH target-arm v3 4/8] target-arm: Add arm_ccnt_enabled function, Peter Crosthwaite, 2014/08/18
- [Qemu-devel] [PATCH target-arm v3 5/8] target-arm: Implement pmccntr_sync function,
Peter Crosthwaite <=
- [Qemu-devel] [PATCH target-arm v3 6/8] target-arm: Remove old code and replace with new functions, Peter Crosthwaite, 2014/08/18
- [Qemu-devel] [PATCH target-arm v3 7/8] target-arm: Implement pmccfiltr_write function, Peter Crosthwaite, 2014/08/18
- [Qemu-devel] [PATCH target-arm v3 8/8] target-arm: Call pmccntr_sync() when swapping ELs, Peter Crosthwaite, 2014/08/18