mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-02 22:41:07 +00:00
hw/timer/arm_timer.c: Switch to transaction-based ptimer API
Switch the arm_timer.c code away from bottom-half based ptimers to the new transaction-based ptimer API. This just requires adding begin/commit calls around the various arms of arm_timer_write() that modify the ptimer state, and using the new ptimer_init() function to create the timer. Fixes: https://bugs.launchpad.net/qemu/+bug/1777777 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20191008171740.9679-5-peter.maydell@linaro.org
This commit is contained in:
parent
91b37aea0e
commit
5a65f7b5f4
1 changed files with 11 additions and 5 deletions
|
@ -14,7 +14,6 @@
|
|||
#include "hw/irq.h"
|
||||
#include "hw/ptimer.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/log.h"
|
||||
|
||||
|
@ -75,7 +74,10 @@ static uint32_t arm_timer_read(void *opaque, hwaddr offset)
|
|||
}
|
||||
}
|
||||
|
||||
/* Reset the timer limit after settings have changed. */
|
||||
/*
|
||||
* Reset the timer limit after settings have changed.
|
||||
* May only be called from inside a ptimer transaction block.
|
||||
*/
|
||||
static void arm_timer_recalibrate(arm_timer_state *s, int reload)
|
||||
{
|
||||
uint32_t limit;
|
||||
|
@ -102,13 +104,16 @@ static void arm_timer_write(void *opaque, hwaddr offset,
|
|||
switch (offset >> 2) {
|
||||
case 0: /* TimerLoad */
|
||||
s->limit = value;
|
||||
ptimer_transaction_begin(s->timer);
|
||||
arm_timer_recalibrate(s, 1);
|
||||
ptimer_transaction_commit(s->timer);
|
||||
break;
|
||||
case 1: /* TimerValue */
|
||||
/* ??? Linux seems to want to write to this readonly register.
|
||||
Ignore it. */
|
||||
break;
|
||||
case 2: /* TimerControl */
|
||||
ptimer_transaction_begin(s->timer);
|
||||
if (s->control & TIMER_CTRL_ENABLE) {
|
||||
/* Pause the timer if it is running. This may cause some
|
||||
inaccuracy dure to rounding, but avoids a whole lot of other
|
||||
|
@ -128,13 +133,16 @@ static void arm_timer_write(void *opaque, hwaddr offset,
|
|||
/* Restart the timer if still enabled. */
|
||||
ptimer_run(s->timer, (s->control & TIMER_CTRL_ONESHOT) != 0);
|
||||
}
|
||||
ptimer_transaction_commit(s->timer);
|
||||
break;
|
||||
case 3: /* TimerIntClr */
|
||||
s->int_level = 0;
|
||||
break;
|
||||
case 6: /* TimerBGLoad */
|
||||
s->limit = value;
|
||||
ptimer_transaction_begin(s->timer);
|
||||
arm_timer_recalibrate(s, 0);
|
||||
ptimer_transaction_commit(s->timer);
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
|
@ -166,14 +174,12 @@ static const VMStateDescription vmstate_arm_timer = {
|
|||
static arm_timer_state *arm_timer_init(uint32_t freq)
|
||||
{
|
||||
arm_timer_state *s;
|
||||
QEMUBH *bh;
|
||||
|
||||
s = (arm_timer_state *)g_malloc0(sizeof(arm_timer_state));
|
||||
s->freq = freq;
|
||||
s->control = TIMER_CTRL_IE;
|
||||
|
||||
bh = qemu_bh_new(arm_timer_tick, s);
|
||||
s->timer = ptimer_init_with_bh(bh, PTIMER_POLICY_DEFAULT);
|
||||
s->timer = ptimer_init(arm_timer_tick, s, PTIMER_POLICY_DEFAULT);
|
||||
vmstate_register(NULL, -1, &vmstate_arm_timer, s);
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue