summaryrefslogtreecommitdiffstats
path: root/hw/timer/arm_mptimer.c
diff options
context:
space:
mode:
authorPeter Maydell2015-07-06 12:04:54 +0200
committerPeter Maydell2015-07-06 12:04:54 +0200
commit261ccf426a6df854ba398be92413476919dd67f9 (patch)
treee72d79039c7a01270f4869331f5aecd2840dc264 /hw/timer/arm_mptimer.c
parentMerge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging (diff)
parentarm_mptimer: Respect IT bit state (diff)
downloadqemu-261ccf426a6df854ba398be92413476919dd67f9.tar.gz
qemu-261ccf426a6df854ba398be92413476919dd67f9.tar.xz
qemu-261ccf426a6df854ba398be92413476919dd67f9.zip
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20150706' into staging
target-arm queue: * TLBI ALLEI1IS should operate on all CPUs, not just this one * Fix interval interrupt of cadence ttc in decrement mode * Implement YIELD insn to yield in ARM and Thumb translators * ARM GIC: reset all registers * arm_mptimer: fix timer shutdown and mode change * arm_mptimer: respect IT bit state # gpg: Signature made Mon Jul 6 10:58:27 2015 BST using RSA key ID 14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" * remotes/pmaydell/tags/pull-target-arm-20150706: arm_mptimer: Respect IT bit state arm_mptimer: Fix timer shutdown and mode change hw/intc/arm_gic_common.c: Reset all registers target-arm: Implement YIELD insn to yield in ARM and Thumb translators target-arm: Split DISAS_YIELD from DISAS_WFE Fix interval interrupt of cadence ttc when timer is in decrement mode target-arm: fix write helper for TLBI ALLE1IS Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/timer/arm_mptimer.c')
-rw-r--r--hw/timer/arm_mptimer.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
index 8b93b3c1ae..3e59c2a288 100644
--- a/hw/timer/arm_mptimer.c
+++ b/hw/timer/arm_mptimer.c
@@ -38,7 +38,7 @@ static inline int get_current_cpu(ARMMPTimerState *s)
static inline void timerblock_update_irq(TimerBlock *tb)
{
- qemu_set_irq(tb->irq, tb->status);
+ qemu_set_irq(tb->irq, tb->status && (tb->control & 4));
}
/* Return conversion factor from mpcore timer ticks to qemu timer ticks. */
@@ -122,11 +122,18 @@ static void timerblock_write(void *opaque, hwaddr addr,
case 8: /* Control. */
old = tb->control;
tb->control = value;
- if (((old & 1) == 0) && (value & 1)) {
- if (tb->count == 0 && (tb->control & 2)) {
+ if (value & 1) {
+ if ((old & 1) && (tb->count != 0)) {
+ /* Do nothing if timer is ticking right now. */
+ break;
+ }
+ if (tb->control & 2) {
tb->count = tb->load;
}
timerblock_reload(tb, 1);
+ } else if (old & 1) {
+ /* Shutdown the timer. */
+ timer_del(tb->timer);
}
break;
case 12: /* Interrupt status. */