diff options
author | Richard Petri <git@rpls.de> | 2022-02-01 20:26:51 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2022-02-08 10:56:28 +0000 |
commit | 77cd997161cc853c758b68eebb52827d56bc020e (patch) | |
tree | 1d9488f860a15d153f1021f848112e3f8f1c663c | |
parent | c737d868047f6ae91325adcd3a40f509753a1d85 (diff) | |
download | qemu-77cd997161cc853c758b68eebb52827d56bc020e.zip qemu-77cd997161cc853c758b68eebb52827d56bc020e.tar.gz qemu-77cd997161cc853c758b68eebb52827d56bc020e.tar.bz2 |
hw/timer/armv7m_systick: Update clock source before enabling timer
Starting the SysTick timer and changing the clock source a the same time
will result in an error, if the previous clock period was zero. For exmaple,
on the mps2-tz platforms, no refclk is present. Right after reset, the
configured ptimer period is zero, and trying to enabling it will turn it off
right away. E.g., code running on the platform setting
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
should change the clock source and enable the timer on real hardware, but
resulted in an error in qemu.
Signed-off-by: Richard Petri <git@rpls.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20220201192650.289584-1-git@rpls.de
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/timer/armv7m_systick.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/hw/timer/armv7m_systick.c b/hw/timer/armv7m_systick.c index 3bd951d..5dfe39a 100644 --- a/hw/timer/armv7m_systick.c +++ b/hw/timer/armv7m_systick.c @@ -149,6 +149,10 @@ static MemTxResult systick_write(void *opaque, hwaddr addr, s->control &= 0xfffffff8; s->control |= value & 7; + if ((oldval ^ value) & SYSTICK_CLKSOURCE) { + systick_set_period_from_clock(s); + } + if ((oldval ^ value) & SYSTICK_ENABLE) { if (value & SYSTICK_ENABLE) { ptimer_run(s->ptimer, 0); @@ -156,10 +160,6 @@ static MemTxResult systick_write(void *opaque, hwaddr addr, ptimer_stop(s->ptimer); } } - - if ((oldval ^ value) & SYSTICK_CLKSOURCE) { - systick_set_period_from_clock(s); - } ptimer_transaction_commit(s->ptimer); break; } |