aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Petri <git@rpls.de>2022-02-01 20:26:51 +0100
committerPeter Maydell <peter.maydell@linaro.org>2022-02-08 10:56:28 +0000
commit77cd997161cc853c758b68eebb52827d56bc020e (patch)
tree1d9488f860a15d153f1021f848112e3f8f1c663c
parentc737d868047f6ae91325adcd3a40f509753a1d85 (diff)
downloadqemu-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.c8
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;
}