diff options
author | Peter Maydell | 2015-07-06 12:04:54 +0200 |
---|---|---|
committer | Peter Maydell | 2015-07-06 12:04:54 +0200 |
commit | 261ccf426a6df854ba398be92413476919dd67f9 (patch) | |
tree | e72d79039c7a01270f4869331f5aecd2840dc264 /hw/timer/arm_mptimer.c | |
parent | Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging (diff) | |
parent | arm_mptimer: Respect IT bit state (diff) | |
download | qemu-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.c | 13 |
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. */ |