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; > > +} >