On Thu, Sep 22, 2022 at 2:45 PM Philippe Mathieu-Daudé <f4...@amsat.org>
wrote:

> On 22/9/22 17:58, Tyler Ng wrote:
> > 1. Adds fields to hold the value of mtime in timer_upper0 and
> timer_lower0.
> >
> > 2. Changes the read and write functions to use the mtime fields.
> >
> > 3. Updates the value of mtime in update_mtime() by extrapolating the
> > time elapsed. This will need to change if/when the prescalar is
> > implemented.
> >
> > 4. Adds a qtest for the ibex timer.
> >
> > Signed-off-by: Tyler Ng <t...@rivosinc.com>
> > ---
> >   hw/timer/ibex_timer.c         |  98 +++++++++++++------
> >   include/hw/timer/ibex_timer.h |   6 ++
> >   tests/qtest/ibex-timer-test.c | 178 ++++++++++++++++++++++++++++++++++
> >   tests/qtest/meson.build       |   3 +-
> >   4 files changed, 256 insertions(+), 29 deletions(-)
> >   create mode 100644 tests/qtest/ibex-timer-test.c
>
> > -static void ibex_timer_update_irqs(IbexTimerState *s)
> > +/*
> > + * The goal of this function is to:
> > + * 1. Check if the timer is enabled. If not, return false,
> > + * 2. Calculate the amount of time that has passed since.
> > + * 3. Extrapolate the number of ticks that have passed, and add it to
> `mtime`.
> > + * 4. Return true.
> > + */
> > +static bool update_mtime(IbexTimerState *s)
> >   {
> > -    uint64_t value = s->timer_compare_lower0 |
> > -                         ((uint64_t)s->timer_compare_upper0 << 32);
> > -    uint64_t next, diff;
> > -    uint64_t now = cpu_riscv_read_rtc(s->timebase_freq);
> > -
> >       if (!(s->timer_ctrl & R_CTRL_ACTIVE_MASK)) {
> > -        /* Timer isn't active */
> > +        return false;
> > +    }
> > +    /* Get the time then extrapolate the number of ticks that have
> elapsed */
> > +    uint64_t mtime = get_mtime(s);
> > +    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> > +    int64_t elapsed = now - s->timer_last_update;
> > +    if (elapsed < 0) {
> > +        /* We jumped back in time. */
> > +        mtime -= muldiv64((uint64_t)(-elapsed), s->timebase_freq,
> > +                           NANOSECONDS_PER_SECOND);
> > +    } else {
> > +        mtime += muldiv64(elapsed, s->timebase_freq,
> NANOSECONDS_PER_SECOND);
> > +    }
> > +    s->timer_lower0 = mtime & 0xffffffff;
> > +    s->timer_upper0 = (mtime >> 32) & 0xffffffff;
>
> Could use extract64(mtime, 0, 32) and extract64(mtime, 32, 32);
>
>
Didn't know about this function, thanks.


> > +    /* update last-checkpoint timestamp */
> > +    s->timer_last_update = now;
> > +    return true;
> > +}
>

Reply via email to