qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2 3/3] hw/timer: ibex_timer.c: Add support for writes to mti


From: Philippe Mathieu-Daudé
Subject: Re: [PATCH v2 3/3] hw/timer: ibex_timer.c: Add support for writes to mtime
Date: Thu, 22 Sep 2022 23:45:49 +0200
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Thunderbird/91.13.1

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 <tkng@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);

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]