From: Peter Maydell <peter.maydell@linaro.org> To: qemu-devel@nongnu.org Subject: [PULL 47/51] hw/timer/armv7m_systick: Use clock inputs instead of system_clock_scale Date: Wed, 1 Sep 2021 11:36:49 +0100 [thread overview] Message-ID: <20210901103653.13435-48-peter.maydell@linaro.org> (raw) In-Reply-To: <20210901103653.13435-1-peter.maydell@linaro.org> Now that all users of the systick devices wire up the clock inputs, use those instead of the system_clock_scale and the hardwired 1MHz value for the reference clock. This will fix various board models where we were incorrectly providing a 1MHz reference clock instead of some other value or instead of providing no reference clock at all. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Damien Hedde <damien.hedde@greensocs.com> Message-id: 20210812093356.1946-22-peter.maydell@linaro.org --- hw/timer/armv7m_systick.c | 112 ++++++++++++++++++++++++++++---------- 1 file changed, 84 insertions(+), 28 deletions(-) diff --git a/hw/timer/armv7m_systick.c b/hw/timer/armv7m_systick.c index e43f74114e8..21f6d0fd24f 100644 --- a/hw/timer/armv7m_systick.c +++ b/hw/timer/armv7m_systick.c @@ -18,25 +18,30 @@ #include "qemu/timer.h" #include "qemu/log.h" #include "qemu/module.h" +#include "qapi/error.h" #include "trace.h" -/* qemu timers run at 1GHz. We want something closer to 1MHz. */ -#define SYSTICK_SCALE 1000ULL - #define SYSTICK_ENABLE (1 << 0) #define SYSTICK_TICKINT (1 << 1) #define SYSTICK_CLKSOURCE (1 << 2) #define SYSTICK_COUNTFLAG (1 << 16) +#define SYSCALIB_NOREF (1U << 31) +#define SYSCALIB_SKEW (1U << 30) +#define SYSCALIB_TENMS ((1U << 24) - 1) + int system_clock_scale; -/* Conversion factor from qemu timer to SysTick frequencies. */ -static inline int64_t systick_scale(SysTickState *s) +static void systick_set_period_from_clock(SysTickState *s) { + /* + * Set the ptimer period from whichever clock is selected. + * Must be called from within a ptimer transaction block. + */ if (s->control & SYSTICK_CLKSOURCE) { - return system_clock_scale; + ptimer_set_period_from_clock(s->ptimer, s->cpuclk, 1); } else { - return 1000; + ptimer_set_period_from_clock(s->ptimer, s->refclk, 1); } } @@ -83,7 +88,28 @@ static MemTxResult systick_read(void *opaque, hwaddr addr, uint64_t *data, val = ptimer_get_count(s->ptimer); break; case 0xc: /* SysTick Calibration Value. */ - val = 10000; + /* + * In real hardware it is possible to make this register report + * a different value from what the reference clock is actually + * running at. We don't model that (which usually happens due + * to integration errors in the real hardware) and instead always + * report the theoretical correct value as described in the + * knowledgebase article at + * https://developer.arm.com/documentation/ka001325/latest + * If necessary, we could implement an extra QOM property on this + * device to force the STCALIB value to something different from + * the "correct" value. + */ + if (!clock_has_source(s->refclk)) { + val = SYSCALIB_NOREF; + break; + } + val = clock_ns_to_ticks(s->refclk, 10 * SCALE_MS) - 1; + val &= SYSCALIB_TENMS; + if (clock_ticks_to_ns(s->refclk, val + 1) != 10 * SCALE_MS) { + /* report that tick count does not yield exactly 10ms */ + val |= SYSCALIB_SKEW; + } break; default: val = 0; @@ -115,6 +141,11 @@ static MemTxResult systick_write(void *opaque, hwaddr addr, { uint32_t oldval; + if (!clock_has_source(s->refclk)) { + /* This bit is always 1 if there is no external refclk */ + value |= SYSTICK_CLKSOURCE; + } + ptimer_transaction_begin(s->ptimer); oldval = s->control; s->control &= 0xfffffff8; @@ -122,19 +153,14 @@ static MemTxResult systick_write(void *opaque, hwaddr addr, if ((oldval ^ value) & SYSTICK_ENABLE) { if (value & SYSTICK_ENABLE) { - /* - * Always reload the period in case board code has - * changed system_clock_scale. If we ever replace that - * global with a more sensible API then we might be able - * to set the period only when it actually changes. - */ - ptimer_set_period(s->ptimer, systick_scale(s)); ptimer_run(s->ptimer, 0); } else { ptimer_stop(s->ptimer); } - } else if ((oldval ^ value) & SYSTICK_CLKSOURCE) { - ptimer_set_period(s->ptimer, systick_scale(s)); + } + + if ((oldval ^ value) & SYSTICK_CLKSOURCE) { + systick_set_period_from_clock(s); } ptimer_transaction_commit(s->ptimer); break; @@ -177,20 +203,42 @@ static void systick_reset(DeviceState *dev) { SysTickState *s = SYSTICK(dev); - /* - * Forgetting to set system_clock_scale is always a board code - * bug. We can't check this earlier because for some boards - * (like stellaris) it is not yet configured at the point where - * the systick device is realized. - */ - assert(system_clock_scale != 0); - ptimer_transaction_begin(s->ptimer); s->control = 0; + if (!clock_has_source(s->refclk)) { + /* This bit is always 1 if there is no external refclk */ + s->control |= SYSTICK_CLKSOURCE; + } ptimer_stop(s->ptimer); ptimer_set_count(s->ptimer, 0); ptimer_set_limit(s->ptimer, 0, 0); - ptimer_set_period(s->ptimer, systick_scale(s)); + systick_set_period_from_clock(s); + ptimer_transaction_commit(s->ptimer); +} + +static void systick_cpuclk_update(void *opaque, ClockEvent event) +{ + SysTickState *s = SYSTICK(opaque); + + if (!(s->control & SYSTICK_CLKSOURCE)) { + /* currently using refclk, we can ignore cpuclk changes */ + } + + ptimer_transaction_begin(s->ptimer); + ptimer_set_period_from_clock(s->ptimer, s->cpuclk, 1); + ptimer_transaction_commit(s->ptimer); +} + +static void systick_refclk_update(void *opaque, ClockEvent event) +{ + SysTickState *s = SYSTICK(opaque); + + if (s->control & SYSTICK_CLKSOURCE) { + /* currently using cpuclk, we can ignore refclk changes */ + } + + ptimer_transaction_begin(s->ptimer); + ptimer_set_period_from_clock(s->ptimer, s->refclk, 1); ptimer_transaction_commit(s->ptimer); } @@ -203,8 +251,10 @@ static void systick_instance_init(Object *obj) sysbus_init_mmio(sbd, &s->iomem); sysbus_init_irq(sbd, &s->irq); - s->refclk = qdev_init_clock_in(DEVICE(obj), "refclk", NULL, NULL, 0); - s->cpuclk = qdev_init_clock_in(DEVICE(obj), "cpuclk", NULL, NULL, 0); + s->refclk = qdev_init_clock_in(DEVICE(obj), "refclk", + systick_refclk_update, s, ClockUpdate); + s->cpuclk = qdev_init_clock_in(DEVICE(obj), "cpuclk", + systick_cpuclk_update, s, ClockUpdate); } static void systick_realize(DeviceState *dev, Error **errp) @@ -215,6 +265,12 @@ static void systick_realize(DeviceState *dev, Error **errp) PTIMER_POLICY_NO_COUNTER_ROUND_DOWN | PTIMER_POLICY_NO_IMMEDIATE_RELOAD | PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT); + + if (!clock_has_source(s->cpuclk)) { + error_setg(errp, "systick: cpuclk must be connected"); + return; + } + /* It's OK not to connect the refclk */ } static const VMStateDescription vmstate_systick = { -- 2.20.1
next prev parent reply other threads:[~2021-09-01 11:21 UTC|newest] Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-09-01 10:36 [PULL 00/51] target-arm queue Peter Maydell 2021-09-01 10:36 ` [PULL 01/51] tests: Remove uses of deprecated raspi2/raspi3 machine names Peter Maydell 2021-09-01 10:36 ` [PULL 02/51] hw/arm/raspi: Remove deprecated raspi2/raspi3 aliases Peter Maydell 2021-09-01 10:36 ` [PULL 03/51] hw/intc/arm_gicv3_dist: Rename 64-bit accessors with 'q' suffix Peter Maydell 2021-09-01 10:36 ` [PULL 04/51] hw/intc/arm_gicv3: Replace mis-used MEMTX_* constants by booleans Peter Maydell 2021-09-01 10:36 ` [PULL 05/51] hw: Add compat machines for 6.2 Peter Maydell 2021-09-01 10:36 ` [PULL 06/51] target/arm: Implement MVE VADD (floating-point) Peter Maydell 2021-09-01 10:36 ` [PULL 07/51] target/arm: Implement MVE VSUB, VMUL, VABD, VMAXNM, VMINNM Peter Maydell 2021-09-01 10:36 ` [PULL 08/51] target/arm: Implement MVE VCADD Peter Maydell 2021-09-01 10:36 ` [PULL 09/51] target/arm: Implement MVE VFMA and VFMS Peter Maydell 2021-09-01 10:36 ` [PULL 10/51] target/arm: Implement MVE VCMUL and VCMLA Peter Maydell 2021-09-01 10:36 ` [PULL 11/51] target/arm: Implement MVE VMAXNMA and VMINNMA Peter Maydell 2021-09-01 10:36 ` [PULL 12/51] target/arm: Implement MVE scalar fp insns Peter Maydell 2021-09-01 10:36 ` [PULL 13/51] target/arm: Implement MVE fp-with-scalar VFMA, VFMAS Peter Maydell 2021-09-01 10:36 ` [PULL 14/51] softfloat: Remove assertion preventing silencing of NaN in default-NaN mode Peter Maydell 2021-09-01 10:36 ` [PULL 15/51] target/arm: Implement MVE FP max/min across vector Peter Maydell 2021-09-01 10:36 ` [PULL 16/51] target/arm: Implement MVE fp vector comparisons Peter Maydell 2021-09-01 10:36 ` [PULL 17/51] target/arm: Implement MVE fp scalar comparisons Peter Maydell 2021-09-01 10:36 ` [PULL 18/51] target/arm: Implement MVE VCVT between floating and fixed point Peter Maydell 2021-09-01 10:36 ` [PULL 19/51] target/arm: Implement MVE VCVT between fp and integer Peter Maydell 2021-09-01 10:36 ` [PULL 20/51] target/arm: Implement MVE VCVT with specified rounding mode Peter Maydell 2021-09-01 10:36 ` [PULL 21/51] target/arm: Implement MVE VCVT between single and half precision Peter Maydell 2021-09-01 10:36 ` [PULL 22/51] target/arm: Implement MVE VRINT insns Peter Maydell 2021-09-01 10:36 ` [PULL 23/51] target/arm: Enable MVE in Cortex-M55 Peter Maydell 2021-09-01 10:36 ` [PULL 24/51] target-arm: Add support for Fujitsu A64FX Peter Maydell 2021-09-01 10:36 ` [PULL 25/51] hw/arm/virt: target-arm: Add A64FX processor support to virt machine Peter Maydell 2021-09-01 10:36 ` [PULL 26/51] tests/arm-cpu-features: Add A64FX processor related tests Peter Maydell 2021-09-01 10:36 ` [PULL 27/51] arm: Move M-profile RAS register block into its own device Peter Maydell 2021-09-01 10:36 ` [PULL 28/51] arm: Move systick device creation from NVIC to ARMv7M object Peter Maydell 2021-09-01 10:36 ` [PULL 29/51] arm: Move system PPB container handling to armv7m Peter Maydell 2021-09-01 10:36 ` [PULL 30/51] hw/timer/armv7m_systick: Add usual QEMU interface comment Peter Maydell 2021-09-01 10:36 ` [PULL 31/51] hw/timer/armv7m_systick: Add input clocks Peter Maydell 2021-09-01 10:36 ` [PULL 32/51] hw/arm/armv7m: Create " Peter Maydell 2021-09-01 10:36 ` [PULL 33/51] armsse: Wire up systick cpuclk clock Peter Maydell 2021-09-01 10:36 ` [PULL 34/51] hw/arm/mps2.c: Connect up armv7m clocks Peter Maydell 2021-09-01 10:36 ` [PULL 35/51] clock: Provide builtin multiplier/divider Peter Maydell 2021-09-01 10:36 ` [PULL 36/51] hw/arm: Don't allocate separate MemoryRegions in stm32 SoC realize Peter Maydell 2021-09-01 10:36 ` [PULL 37/51] hw/arm/stm32f100: Wire up sysclk and refclk Peter Maydell 2021-09-01 10:36 ` [PULL 38/51] hw/arm/stm32f205: " Peter Maydell 2021-09-01 10:36 ` [PULL 39/51] hw/arm/stm32f405: " Peter Maydell 2021-09-01 10:36 ` [PULL 40/51] hw/arm/stm32vldiscovery: Delete trailing blank line Peter Maydell 2021-09-01 10:36 ` [PULL 41/51] hw/arm/nrf51: Wire up sysclk Peter Maydell 2021-09-01 10:36 ` [PULL 42/51] hw/arm/stellaris: split stellaris_sys_init() Peter Maydell 2021-09-01 10:36 ` [PULL 43/51] hw/arm/stellaris: Wire sysclk up to armv7m Peter Maydell 2021-09-01 10:36 ` [PULL 44/51] hw/arm/msf2_soc: Don't allocate separate MemoryRegions Peter Maydell 2021-09-01 10:36 ` [PULL 45/51] hw/arm/msf2: Use Clock input to MSF2_SOC instead of m3clk property Peter Maydell 2021-09-01 10:36 ` [PULL 46/51] hw/arm/msf2-soc: Wire up refclk Peter Maydell 2021-09-01 10:36 ` Peter Maydell [this message] 2021-09-01 10:36 ` [PULL 48/51] hw/arm/stellaris: Fix code style issues in GPTM code Peter Maydell 2021-09-01 10:36 ` [PULL 49/51] hw/arm/stellaris: Split stellaris-gptm into its own file Peter Maydell 2021-09-01 10:36 ` [PULL 50/51] hw/timer/stellaris-gptm: Use Clock input instead of system_clock_scale Peter Maydell 2021-09-01 10:36 ` [PULL 51/51] arm: Remove system_clock_scale global Peter Maydell 2021-09-02 7:48 ` [PULL 00/51] target-arm queue Peter Maydell
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210901103653.13435-48-peter.maydell@linaro.org \ --to=peter.maydell@linaro.org \ --cc=qemu-devel@nongnu.org \ --subject='Re: [PULL 47/51] hw/timer/armv7m_systick: Use clock inputs instead of system_clock_scale' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.