qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH  0/3] Implement Sstc extension
@ 2022-03-04  3:20 Atish Patra
  2022-03-04  3:20 ` [RFC PATCH 1/3] target/riscv: Rename timer & timecmp to mtimer and mtimecmp Atish Patra
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Atish Patra @ 2022-03-04  3:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alistair Francis, Bin Meng, Atish Patra, Palmer Dabbelt,
	qemu-riscv

This series implements Sstc extension[1] which was ratified recently.

The first patch is a prepartory patches while PATCH 2 adds stimecmp
support while PATCH 3 adds vstimecmp support. This series is based on
the ISA extension[2] & privilege version update series[3].

The series can also be found at
https://github.com/atishp04/qemu/tree/sstc_v1

It is tested on RV32 & RV64 with additional OpenSBI[4] & Linux kernel[5]
patches.

[1] https://drive.google.com/file/d/1m84Re2yK8m_vbW7TspvevCDR82MOBaSX/view
[2] https://lore.kernel.org/all/20220222220704.2294924-1-atishp@rivosinc.com/
[3] https://www.mail-archive.com/qemu-devel@nongnu.org/msg870659.html
[4] https://github.com/atishp04/opensbi/tree/sstc_v1
[5] https://github.com/atishp04/linux/tree/sstc_v2

Atish Patra (3):
target/riscv: Rename timer & timecmp to mtimer and mtimecmp
target/riscv: Add stimecmp support
target/riscv: Add vstimecmp support

hw/intc/riscv_aclint.c     |  20 ++--
hw/timer/ibex_timer.c      |  14 +--
target/riscv/cpu.c         |   7 ++
target/riscv/cpu.h         |  12 ++-
target/riscv/cpu_bits.h    |   8 ++
target/riscv/cpu_helper.c  |  11 ++-
target/riscv/csr.c         | 183 +++++++++++++++++++++++++++++++++++++
target/riscv/machine.c     |   4 +-
target/riscv/meson.build   |   3 +-
target/riscv/time_helper.c | 113 +++++++++++++++++++++++
target/riscv/time_helper.h |  30 ++++++
11 files changed, 381 insertions(+), 24 deletions(-)
create mode 100644 target/riscv/time_helper.c
create mode 100644 target/riscv/time_helper.h

--
2.30.2



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC PATCH 1/3] target/riscv: Rename timer & timecmp to mtimer and mtimecmp
  2022-03-04  3:20 [RFC PATCH 0/3] Implement Sstc extension Atish Patra
@ 2022-03-04  3:20 ` Atish Patra
  2022-03-04  4:05   ` Anup Patel
  2022-03-04  3:20 ` [RFC PATCH 2/3] target/riscv: Add stimecmp support Atish Patra
  2022-03-04  3:20 ` [RFC PATCH 3/3] target/riscv: Add vstimecmp support Atish Patra
  2 siblings, 1 reply; 7+ messages in thread
From: Atish Patra @ 2022-03-04  3:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alistair Francis, Bin Meng, Atish Patra, Palmer Dabbelt,
	qemu-riscv

Currently, the aclint and ibex timer devices uses the "timer" &
"timecmp" to generate the m-mode timer interrupt. In future,
we will have timer interrupt injected to S/VS mode directly.
No functionality change introduced in this patch.

Add a prefix "m" these enviornment variables to indicate its
true purpose.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
---
 hw/intc/riscv_aclint.c | 20 ++++++++++----------
 hw/timer/ibex_timer.c  | 14 +++++++-------
 target/riscv/cpu.h     |  4 ++--
 target/riscv/machine.c |  2 +-
 4 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
index f1a5d3d284fd..642794a06865 100644
--- a/hw/intc/riscv_aclint.c
+++ b/hw/intc/riscv_aclint.c
@@ -59,8 +59,8 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
 
     uint64_t rtc_r = cpu_riscv_read_rtc(timebase_freq);
 
-    cpu->env.timecmp = value;
-    if (cpu->env.timecmp <= rtc_r) {
+    cpu->env.mtimecmp = value;
+    if (cpu->env.mtimecmp <= rtc_r) {
         /*
          * If we're setting an MTIMECMP value in the "past",
          * immediately raise the timer interrupt
@@ -71,7 +71,7 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
 
     /* otherwise, set up the future timer interrupt */
     qemu_irq_lower(mtimer->timer_irqs[hartid - mtimer->hartid_base]);
-    diff = cpu->env.timecmp - rtc_r;
+    diff = cpu->env.mtimecmp - rtc_r;
     /* back to ns (note args switched in muldiv64) */
     uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
 
@@ -96,7 +96,7 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
         next = MIN(next, INT64_MAX);
     }
 
-    timer_mod(cpu->env.timer, next);
+    timer_mod(cpu->env.mtimer, next);
 }
 
 /*
@@ -127,11 +127,11 @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr,
                           "aclint-mtimer: invalid hartid: %zu", hartid);
         } else if ((addr & 0x7) == 0) {
             /* timecmp_lo */
-            uint64_t timecmp = env->timecmp;
+            uint64_t timecmp = env->mtimecmp;
             return timecmp & 0xFFFFFFFF;
         } else if ((addr & 0x7) == 4) {
             /* timecmp_hi */
-            uint64_t timecmp = env->timecmp;
+            uint64_t timecmp = env->mtimecmp;
             return (timecmp >> 32) & 0xFFFFFFFF;
         } else {
             qemu_log_mask(LOG_UNIMP,
@@ -168,14 +168,14 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
                           "aclint-mtimer: invalid hartid: %zu", hartid);
         } else if ((addr & 0x7) == 0) {
             /* timecmp_lo */
-            uint64_t timecmp_hi = env->timecmp >> 32;
+            uint64_t timecmp_hi = env->mtimecmp >> 32;
             riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
                 timecmp_hi << 32 | (value & 0xFFFFFFFF),
                 mtimer->timebase_freq);
             return;
         } else if ((addr & 0x7) == 4) {
             /* timecmp_hi */
-            uint64_t timecmp_lo = env->timecmp;
+            uint64_t timecmp_lo = env->mtimecmp;
             riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
                 value << 32 | (timecmp_lo & 0xFFFFFFFF),
                 mtimer->timebase_freq);
@@ -304,9 +304,9 @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size,
 
         cb->s = RISCV_ACLINT_MTIMER(dev);
         cb->num = i;
-        env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+        env->mtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                   &riscv_aclint_mtimer_cb, cb);
-        env->timecmp = 0;
+        env->mtimecmp = 0;
 
         qdev_connect_gpio_out(dev, i,
                               qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER));
diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
index 8c2ca364daab..4c34f9e08282 100644
--- a/hw/timer/ibex_timer.c
+++ b/hw/timer/ibex_timer.c
@@ -73,9 +73,9 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
     }
 
     /* Update the CPUs mtimecmp */
-    cpu->env.timecmp = value;
+    cpu->env.mtimecmp = value;
 
-    if (cpu->env.timecmp <= now) {
+    if (cpu->env.mtimecmp <= now) {
         /*
          * If the mtimecmp was in the past raise the interrupt now.
          */
@@ -91,7 +91,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
     qemu_irq_lower(s->m_timer_irq);
     qemu_set_irq(s->irq, false);
 
-    diff = cpu->env.timecmp - now;
+    diff = cpu->env.mtimecmp - now;
     next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                                  muldiv64(diff,
                                           NANOSECONDS_PER_SECOND,
@@ -99,9 +99,9 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
 
     if (next < qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) {
         /* We overflowed the timer, just set it as large as we can */
-        timer_mod(cpu->env.timer, 0x7FFFFFFFFFFFFFFF);
+        timer_mod(cpu->env.mtimer, 0x7FFFFFFFFFFFFFFF);
     } else {
-        timer_mod(cpu->env.timer, next);
+        timer_mod(cpu->env.mtimer, next);
     }
 }
 
@@ -122,9 +122,9 @@ static void ibex_timer_reset(DeviceState *dev)
 
     CPUState *cpu = qemu_get_cpu(0);
     CPURISCVState *env = cpu->env_ptr;
-    env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+    env->mtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                               &ibex_timer_cb, s);
-    env->timecmp = 0;
+    env->mtimecmp = 0;
 
     s->timer_ctrl = 0x00000000;
     s->timer_cfg0 = 0x00010000;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5d914bd34550..94234c59ffa8 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -265,7 +265,7 @@ struct CPURISCVState {
     /* temporary htif regs */
     uint64_t mfromhost;
     uint64_t mtohost;
-    uint64_t timecmp;
+    uint64_t mtimecmp;
 
     /* physical memory protection */
     pmp_table_t pmp_state;
@@ -316,7 +316,7 @@ struct CPURISCVState {
     float_status fp_status;
 
     /* Fields from here on are preserved across CPU reset. */
-    QEMUTimer *timer; /* Internal timer */
+    QEMUTimer *mtimer; /* Internal timer for M-mode interrupt */
 
     hwaddr kernel_addr;
     hwaddr fdt_addr;
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index ebc33c9e2781..be3022082a46 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -303,7 +303,7 @@ const VMStateDescription vmstate_riscv_cpu = {
         VMSTATE_UINTTL(env.mscratch, RISCVCPU),
         VMSTATE_UINT64(env.mfromhost, RISCVCPU),
         VMSTATE_UINT64(env.mtohost, RISCVCPU),
-        VMSTATE_UINT64(env.timecmp, RISCVCPU),
+        VMSTATE_UINT64(env.mtimecmp, RISCVCPU),
 
         VMSTATE_END_OF_LIST()
     },
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH  2/3] target/riscv: Add stimecmp support
  2022-03-04  3:20 [RFC PATCH 0/3] Implement Sstc extension Atish Patra
  2022-03-04  3:20 ` [RFC PATCH 1/3] target/riscv: Rename timer & timecmp to mtimer and mtimecmp Atish Patra
@ 2022-03-04  3:20 ` Atish Patra
  2022-03-04  3:20 ` [RFC PATCH 3/3] target/riscv: Add vstimecmp support Atish Patra
  2 siblings, 0 replies; 7+ messages in thread
From: Atish Patra @ 2022-03-04  3:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alistair Francis, Bin Meng, Atish Patra, Palmer Dabbelt,
	qemu-riscv

stimecmp allows the supervisor mode to update stimecmp CSR directly
to program the next timer interrupt. This CSR is part of the Sstc
extension which was ratified recently.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
---
 target/riscv/cpu.c         |  7 +++
 target/riscv/cpu.h         |  5 ++
 target/riscv/cpu_bits.h    |  4 ++
 target/riscv/csr.c         | 84 +++++++++++++++++++++++++++++++++
 target/riscv/machine.c     |  1 +
 target/riscv/meson.build   |  3 +-
 target/riscv/time_helper.c | 97 ++++++++++++++++++++++++++++++++++++++
 target/riscv/time_helper.h | 30 ++++++++++++
 8 files changed, 230 insertions(+), 1 deletion(-)
 create mode 100644 target/riscv/time_helper.c
 create mode 100644 target/riscv/time_helper.h

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5d24a191c059..c609ed3c5834 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -23,6 +23,7 @@
 #include "qemu/log.h"
 #include "cpu.h"
 #include "internals.h"
+#include "time_helper.h"
 #include "exec/exec-all.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
@@ -751,6 +752,10 @@ static void riscv_cpu_init(Object *obj)
     qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq,
                       IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
 #endif /* CONFIG_USER_ONLY */
+
+    if (cpu->cfg.ext_sstc) {
+        riscv_timer_init(cpu);
+    }
 }
 
 static Property riscv_cpu_properties[] = {
@@ -776,6 +781,7 @@ static Property riscv_cpu_properties[] = {
     DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
     DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
     DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
+    DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
 
     DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
     DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
@@ -898,6 +904,7 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int max_str_len)
         { "svpbmt", cpu->cfg.ext_svpbmt   },
         { "svinval", cpu->cfg.ext_svinval },
         { "svnapot", cpu->cfg.ext_svnapot },
+        { "sstc", cpu->cfg.ext_sstc },
     };
 
     for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 94234c59ffa8..fa90ab9f473b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -267,6 +267,9 @@ struct CPURISCVState {
     uint64_t mtohost;
     uint64_t mtimecmp;
 
+    /* Sstc CSRs */
+    uint64_t stimecmp;
+
     /* physical memory protection */
     pmp_table_t pmp_state;
     target_ulong mseccfg;
@@ -317,6 +320,7 @@ struct CPURISCVState {
 
     /* Fields from here on are preserved across CPU reset. */
     QEMUTimer *mtimer; /* Internal timer for M-mode interrupt */
+    QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
 
     hwaddr kernel_addr;
     hwaddr fdt_addr;
@@ -371,6 +375,7 @@ struct RISCVCPUConfig {
     bool ext_svinval;
     bool ext_svnapot;
     bool ext_svpbmt;
+    bool ext_sstc;
     bool ext_zfh;
     bool ext_zfhmin;
     bool ext_zve32f;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index bb47cf7e77a2..34496ac5aa80 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -212,6 +212,10 @@
 #define CSR_STVAL           0x143
 #define CSR_SIP             0x144
 
+/* Sstc supervisor CSRs */
+#define CSR_STIMECMP        0x14D
+#define CSR_STIMECMPH       0x15D
+
 /* Supervisor Protection and Translation */
 #define CSR_SPTBR           0x180
 #define CSR_SATP            0x180
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index b16881615997..ad7a8db2dd0d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -20,8 +20,10 @@
 #include "qemu/osdep.h"
 #include "qemu/log.h"
 #include "cpu.h"
+#include "time_helper.h"
 #include "qemu/main-loop.h"
 #include "exec/exec-all.h"
+#include "hw/intc/riscv_aclint.h"
 
 /* CSR function table public API */
 void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
@@ -519,6 +521,78 @@ static RISCVException read_timeh(CPURISCVState *env, int csrno,
     return RISCV_EXCP_NONE;
 }
 
+static RISCVException sstc(CPURISCVState *env, int csrno)
+{
+    CPUState *cs = env_cpu(env);
+    RISCVCPU *cpu = RISCV_CPU(cs);
+
+    if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
+        return RISCV_EXCP_ILLEGAL_INST;
+    }
+
+    if (env->priv == PRV_M) {
+        return RISCV_EXCP_NONE;
+    }
+
+    if (env->priv != PRV_S) {
+        return RISCV_EXCP_ILLEGAL_INST;
+    }
+
+    /*
+     * No need of separate function for rv32 as menvcfg stores both menvcfg
+     * menvcfgh for RV32.
+     */
+    if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
+          get_field(env->menvcfg, MENVCFG_STCE))) {
+        return RISCV_EXCP_ILLEGAL_INST;
+    }
+
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_stimecmp(CPURISCVState *env, int csrno,
+                                    target_ulong *val)
+{
+    *val = env->stimecmp;
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
+                                    target_ulong *val)
+{
+    *val = env->stimecmp >> 32;
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
+                                    target_ulong val)
+{
+    RISCVCPU *cpu = env_archcpu(env);
+
+    if (riscv_cpu_mxl(env) == MXL_RV32) {
+        uint64_t stimecmp_hi = env->stimecmp >> 32;
+        env->stimecmp = (stimecmp_hi << 32) | (val & 0xFFFFFFFF);
+    } else {
+        env->stimecmp = val;
+        riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP);
+    }
+
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
+                                    target_ulong val)
+{
+    RISCVCPU *cpu = env_archcpu(env);
+    uint64_t timer_val = 0;
+
+    timer_val = (uint64_t)val << 32 | (env->stimecmp & 0xFFFFFFFF);
+    env->stimecmp = timer_val;
+    riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP);
+
+    return RISCV_EXCP_NONE;
+}
+
 /* Machine constants */
 
 #define M_MODE_INTERRUPTS  ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP))
@@ -1485,6 +1559,12 @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
     uint64_t old_mip, mask = wr_mask & delegable_ints & ~env->miclaim;
     uint32_t gin;
 
+    if (cpu->cfg.ext_sstc && (env->priv == PRV_M) &&
+        get_field(env->menvcfg, MENVCFG_STCE)) {
+        /* sstc extension forbids STIP & VSTIP to be writeable in mip */
+        mask = mask & ~(MIP_STIP | MIP_VSTIP);
+    }
+
     if (mask) {
         old_mip = riscv_cpu_update_mip(cpu, mask, (new_val & mask));
     } else {
@@ -3265,6 +3345,10 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
     [CSR_SCAUSE]   = { "scause",   smode, read_scause,   write_scause   },
     [CSR_STVAL]    = { "stval",    smode, read_stval,   write_stval   },
     [CSR_SIP]      = { "sip",      smode, NULL,    NULL, rmw_sip        },
+    [CSR_STIMECMP] = { "stimecmp", sstc, read_stimecmp, write_stimecmp,
+                                         NULL, NULL, NULL, PRIV_VERSION_1_12_0},
+    [CSR_STIMECMPH] = { "stimecmph", sstc, read_stimecmph, write_stimecmph,
+                                         NULL, NULL, NULL, PRIV_VERSION_1_12_0},
 
     /* Supervisor Protection and Translation */
     [CSR_SATP]     = { "satp",     smode, read_satp,    write_satp      },
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index be3022082a46..2f2e16c72607 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -304,6 +304,7 @@ const VMStateDescription vmstate_riscv_cpu = {
         VMSTATE_UINT64(env.mfromhost, RISCVCPU),
         VMSTATE_UINT64(env.mtohost, RISCVCPU),
         VMSTATE_UINT64(env.mtimecmp, RISCVCPU),
+        VMSTATE_UINT64(env.stimecmp, RISCVCPU),
 
         VMSTATE_END_OF_LIST()
     },
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 91f0ac32ff3d..b51d9d5858cc 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -19,7 +19,8 @@ riscv_ss.add(files(
   'vector_helper.c',
   'bitmanip_helper.c',
   'translate.c',
-  'm128_helper.c'
+  'm128_helper.c',
+  'time_helper.c'
 ))
 riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c'))
 
diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
new file mode 100644
index 000000000000..105a051caace
--- /dev/null
+++ b/target/riscv/time_helper.c
@@ -0,0 +1,97 @@
+/*
+ * RISC-V timer helper implementation.
+ *
+ * Copyright (c) 2022 Rivos Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "cpu_bits.h"
+#include "time_helper.h"
+#include "hw/intc/riscv_aclint.h"
+
+static void riscv_stimer_cb(void *opaque)
+{
+    RISCVCPU *cpu = opaque;
+    riscv_cpu_update_mip(cpu, MIP_STIP, BOOL_TO_MASK(1));
+}
+
+/*
+ * Called when timecmp is written to update the QEMU timer or immediately
+ * trigger timer interrupt if mtimecmp <= current timer value.
+ */
+void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
+                               uint64_t timecmp, uint64_t delta,
+                               uint32_t timer_irq)
+{
+    uint64_t diff, ns_diff, next;
+    CPURISCVState *env = &cpu->env;
+    uint32_t timebase_freq = env->rdtime_fn_arg;
+    uint64_t rtc_r = env->rdtime_fn(timebase_freq) + delta;
+
+    if (timecmp <= rtc_r) {
+        /*
+         * If we're setting an stimecmp value in the "past",
+         * immediately raise the timer interrupt
+         */
+        riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(1));
+        return;
+    }
+
+    /* Clear the [V]STIP bit in mip */
+    riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
+
+    /* otherwise, set up the future timer interrupt */
+    diff = timecmp - rtc_r;
+    /* back to ns (note args switched in muldiv64) */
+    ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
+
+    /*
+     * check if ns_diff overflowed and check if the addition would potentially
+     * overflow
+     */
+    if ((NANOSECONDS_PER_SECOND > timebase_freq && ns_diff < diff) ||
+        ns_diff > INT64_MAX) {
+        next = INT64_MAX;
+    } else {
+        /*
+         * as it is very unlikely qemu_clock_get_ns will return a value
+         * greater than INT64_MAX, no additional check is needed for an
+         * unsigned integer overflow.
+         */
+        next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns_diff;
+        /*
+         * if ns_diff is INT64_MAX next may still be outside the range
+         * of a signed integer.
+         */
+        next = MIN(next, INT64_MAX);
+    }
+
+    timer_mod(timer, next);
+}
+
+void riscv_timer_init(RISCVCPU *cpu)
+{
+    CPURISCVState *env;
+
+    if (!cpu) {
+        return;
+    }
+
+    env = &cpu->env;
+    env->stimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_stimer_cb, cpu);
+    env->stimecmp = 0;
+
+}
diff --git a/target/riscv/time_helper.h b/target/riscv/time_helper.h
new file mode 100644
index 000000000000..7b3cdcc35020
--- /dev/null
+++ b/target/riscv/time_helper.h
@@ -0,0 +1,30 @@
+/*
+ * RISC-V timer header file.
+ *
+ * Copyright (c) 2022 Rivos Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef RISCV_TIME_HELPER_H
+#define RISCV_TIME_HELPER_H
+
+#include "cpu.h"
+#include "qemu/timer.h"
+
+void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
+                               uint64_t timecmp, uint64_t delta,
+                               uint32_t timer_irq);
+void riscv_timer_init(RISCVCPU *cpu);
+
+#endif
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH  3/3] target/riscv: Add vstimecmp support
  2022-03-04  3:20 [RFC PATCH 0/3] Implement Sstc extension Atish Patra
  2022-03-04  3:20 ` [RFC PATCH 1/3] target/riscv: Rename timer & timecmp to mtimer and mtimecmp Atish Patra
  2022-03-04  3:20 ` [RFC PATCH 2/3] target/riscv: Add stimecmp support Atish Patra
@ 2022-03-04  3:20 ` Atish Patra
  2 siblings, 0 replies; 7+ messages in thread
From: Atish Patra @ 2022-03-04  3:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alistair Francis, Bin Meng, Atish Patra, Palmer Dabbelt,
	qemu-riscv

vstimecmp CSR allows the guest OS or to program the next guest timer
interrupt directly. Thus, hypervisor no longer need to inject the
timer interrupt to the guest if vstimecmp is used. This was ratified
as a part of the Sstc extension.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
---
 target/riscv/cpu.h         |   3 ++
 target/riscv/cpu_bits.h    |   4 ++
 target/riscv/cpu_helper.c  |  11 ++--
 target/riscv/csr.c         | 103 ++++++++++++++++++++++++++++++++++++-
 target/riscv/machine.c     |   1 +
 target/riscv/time_helper.c |  16 ++++++
 6 files changed, 133 insertions(+), 5 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index fa90ab9f473b..62cbb7be666f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -269,6 +269,7 @@ struct CPURISCVState {
 
     /* Sstc CSRs */
     uint64_t stimecmp;
+    uint64_t vstimecmp;
 
     /* physical memory protection */
     pmp_table_t pmp_state;
@@ -321,6 +322,8 @@ struct CPURISCVState {
     /* Fields from here on are preserved across CPU reset. */
     QEMUTimer *mtimer; /* Internal timer for M-mode interrupt */
     QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
+    QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
+    bool vstime_irq;
 
     hwaddr kernel_addr;
     hwaddr fdt_addr;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 34496ac5aa80..16d8aa24efe1 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -269,6 +269,10 @@
 #define CSR_VSIP            0x244
 #define CSR_VSATP           0x280
 
+/* Sstc virtual CSRs */
+#define CSR_VSTIMECMP       0x24D
+#define CSR_VSTIMECMPH      0x25D
+
 #define CSR_MTINST          0x34a
 #define CSR_MTVAL2          0x34b
 
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 746335bfd6b9..fe3b8cb72bc7 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -344,8 +344,9 @@ static uint64_t riscv_cpu_all_pending(CPURISCVState *env)
 {
     uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN);
     uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
+    uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0;
 
-    return (env->mip | vsgein) & env->mie;
+    return (env->mip | vsgein | vstip) & env->mie;
 }
 
 int riscv_cpu_mirq_pending(CPURISCVState *env)
@@ -600,7 +601,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value)
 {
     CPURISCVState *env = &cpu->env;
     CPUState *cs = CPU(cpu);
-    uint64_t gein, vsgein = 0, old = env->mip;
+    uint64_t gein, vsgein = 0, vstip = 0, old = env->mip;
     bool locked = false;
 
     if (riscv_cpu_virt_enabled(env)) {
@@ -608,6 +609,10 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value)
         vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
     }
 
+    /* No need to update mip for VSTIP */
+    mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask;
+    vstip = env->vstime_irq ? MIP_VSTIP : 0;
+
     if (!qemu_mutex_iothread_locked()) {
         locked = true;
         qemu_mutex_lock_iothread();
@@ -615,7 +620,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value)
 
     env->mip = (env->mip & ~mask) | (value & mask);
 
-    if (env->mip | vsgein) {
+    if (env->mip | vsgein | vstip) {
         cpu_interrupt(cs, CPU_INTERRUPT_HARD);
     } else {
         cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index ad7a8db2dd0d..8ef9306ce494 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -550,17 +550,100 @@ static RISCVException sstc(CPURISCVState *env, int csrno)
     return RISCV_EXCP_NONE;
 }
 
+static RISCVException sstc_hmode(CPURISCVState *env, int csrno)
+{
+    CPUState *cs = env_cpu(env);
+    RISCVCPU *cpu = RISCV_CPU(cs);
+
+    if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
+        return RISCV_EXCP_ILLEGAL_INST;
+    }
+
+    if (env->priv == PRV_M) {
+        return RISCV_EXCP_NONE;
+    }
+
+    if (!(get_field(env->mcounteren, COUNTEREN_TM) &
+          get_field(env->menvcfg, MENVCFG_STCE))) {
+        return RISCV_EXCP_ILLEGAL_INST;
+    }
+
+    if (!(get_field(env->hcounteren, COUNTEREN_TM) &
+          get_field(env->henvcfg, HENVCFG_STCE))) {
+        return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+    }
+
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,
+                                    target_ulong *val)
+{
+    *val = env->vstimecmp;
+
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
+                                    target_ulong *val)
+{
+    *val = env->vstimecmp >> 32;
+
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
+                                    target_ulong val)
+{
+    RISCVCPU *cpu = env_archcpu(env);
+
+    if (riscv_cpu_mxl(env) == MXL_RV32) {
+        uint64_t vstimecmp_hi = env->vstimecmp >> 32;
+        env->vstimecmp = (vstimecmp_hi << 32) | (val & 0xFFFFFFFF);
+    } else {
+        env->vstimecmp = val;
+        riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
+                                  env->htimedelta, MIP_VSTIP);
+    }
+
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,
+                                    target_ulong val)
+{
+    RISCVCPU *cpu = env_archcpu(env);
+    uint64_t timer_val = 0;
+
+    timer_val = (uint64_t)val << 32 | (env->vstimecmp & 0xFFFFFFFF);
+    env->vstimecmp = timer_val;
+    riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
+                              env->htimedelta, MIP_VSTIP);
+
+    return RISCV_EXCP_NONE;
+}
+
 static RISCVException read_stimecmp(CPURISCVState *env, int csrno,
                                     target_ulong *val)
 {
-    *val = env->stimecmp;
+    if (riscv_cpu_virt_enabled(env)) {
+        *val = env->vstimecmp;
+    } else {
+        *val = env->stimecmp;
+    }
+
     return RISCV_EXCP_NONE;
 }
 
 static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
                                     target_ulong *val)
 {
-    *val = env->stimecmp >> 32;
+    if (riscv_cpu_virt_enabled(env)) {
+        *val = env->vstimecmp >> 32;
+    } else {
+        *val = env->stimecmp >> 32;
+    }
+
     return RISCV_EXCP_NONE;
 }
 
@@ -569,6 +652,10 @@ static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
 {
     RISCVCPU *cpu = env_archcpu(env);
 
+    if (riscv_cpu_virt_enabled(env)) {
+        return write_vstimecmp(env, csrno, val);
+    }
+
     if (riscv_cpu_mxl(env) == MXL_RV32) {
         uint64_t stimecmp_hi = env->stimecmp >> 32;
         env->stimecmp = (stimecmp_hi << 32) | (val & 0xFFFFFFFF);
@@ -586,6 +673,10 @@ static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
     RISCVCPU *cpu = env_archcpu(env);
     uint64_t timer_val = 0;
 
+    if (riscv_cpu_virt_enabled(env)) {
+        return write_vstimecmph(env, csrno, val);
+    }
+
     timer_val = (uint64_t)val << 32 | (env->stimecmp & 0xFFFFFFFF);
     env->stimecmp = timer_val;
     riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP);
@@ -1574,6 +1665,7 @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
     if (csrno != CSR_HVIP) {
         gin = get_field(env->hstatus, HSTATUS_VGEIN);
         old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0;
+        old_mip |= env->vstime_irq ? MIP_VSTIP : 0;
     }
 
     if (ret_val) {
@@ -3349,6 +3441,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
                                          NULL, NULL, NULL, PRIV_VERSION_1_12_0},
     [CSR_STIMECMPH] = { "stimecmph", sstc, read_stimecmph, write_stimecmph,
                                          NULL, NULL, NULL, PRIV_VERSION_1_12_0},
+    [CSR_VSTIMECMP] = { "vstimecmp", sstc_hmode, read_vstimecmp,
+                                         write_vstimecmp, NULL, NULL, NULL,
+                                         PRIV_VERSION_1_12_0},
+    [CSR_VSTIMECMPH] = { "vstimecmph", sstc_hmode, read_vstimecmph,
+                                         write_vstimecmph, NULL, NULL, NULL,
+                                         PRIV_VERSION_1_12_0},
+
 
     /* Supervisor Protection and Translation */
     [CSR_SATP]     = { "satp",     smode, read_satp,    write_satp      },
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 2f2e16c72607..cefaff31acd2 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -92,6 +92,7 @@ static const VMStateDescription vmstate_hyper = {
         VMSTATE_UINTTL(env.hgeie, RISCVCPU),
         VMSTATE_UINTTL(env.hgeip, RISCVCPU),
         VMSTATE_UINT64(env.htimedelta, RISCVCPU),
+        VMSTATE_UINT64(env.vstimecmp, RISCVCPU),
 
         VMSTATE_UINTTL(env.hvictl, RISCVCPU),
         VMSTATE_UINT8_ARRAY(env.hviprio, RISCVCPU, 64),
diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
index 105a051caace..435be68cc12f 100644
--- a/target/riscv/time_helper.c
+++ b/target/riscv/time_helper.c
@@ -22,6 +22,14 @@
 #include "time_helper.h"
 #include "hw/intc/riscv_aclint.h"
 
+static void riscv_vstimer_cb(void *opaque)
+{
+    RISCVCPU *cpu = opaque;
+    CPURISCVState *env = &cpu->env;
+    env->vstime_irq = 1;
+    riscv_cpu_update_mip(cpu, MIP_VSTIP, BOOL_TO_MASK(1));
+}
+
 static void riscv_stimer_cb(void *opaque)
 {
     RISCVCPU *cpu = opaque;
@@ -46,10 +54,16 @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
          * If we're setting an stimecmp value in the "past",
          * immediately raise the timer interrupt
          */
+        if (timer_irq == MIP_VSTIP) {
+            env->vstime_irq = 1;
+        }
         riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(1));
         return;
     }
 
+    if (timer_irq == MIP_VSTIP) {
+        env->vstime_irq = 0;
+    }
     /* Clear the [V]STIP bit in mip */
     riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
 
@@ -94,4 +108,6 @@ void riscv_timer_init(RISCVCPU *cpu)
     env->stimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_stimer_cb, cpu);
     env->stimecmp = 0;
 
+    env->vstimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_vstimer_cb, cpu);
+    env->vstimecmp = 0;
 }
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH 1/3] target/riscv: Rename timer & timecmp to mtimer and mtimecmp
  2022-03-04  3:20 ` [RFC PATCH 1/3] target/riscv: Rename timer & timecmp to mtimer and mtimecmp Atish Patra
@ 2022-03-04  4:05   ` Anup Patel
  2022-03-08 21:32     ` Alistair Francis
  0 siblings, 1 reply; 7+ messages in thread
From: Anup Patel @ 2022-03-04  4:05 UTC (permalink / raw)
  To: Atish Patra
  Cc: Palmer Dabbelt, Bin Meng, Alistair Francis, QEMU Developers,
	open list:RISC-V

On Fri, Mar 4, 2022 at 8:50 AM Atish Patra <atishp@rivosinc.com> wrote:
>
> Currently, the aclint and ibex timer devices uses the "timer" &
> "timecmp" to generate the m-mode timer interrupt. In future,
> we will have timer interrupt injected to S/VS mode directly.
> No functionality change introduced in this patch.

s/have timer/have a timer/

>
> Add a prefix "m" these enviornment variables to indicate its
> true purpose.

s/enviornment/environment/

>
> Signed-off-by: Atish Patra <atishp@rivosinc.com>

I suggest we should remove mtimecmp and mtimer from
target/riscv because mtimer is a memory mapped device.

Regards,
Anup

> ---
>  hw/intc/riscv_aclint.c | 20 ++++++++++----------
>  hw/timer/ibex_timer.c  | 14 +++++++-------
>  target/riscv/cpu.h     |  4 ++--
>  target/riscv/machine.c |  2 +-
>  4 files changed, 20 insertions(+), 20 deletions(-)
>
> diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
> index f1a5d3d284fd..642794a06865 100644
> --- a/hw/intc/riscv_aclint.c
> +++ b/hw/intc/riscv_aclint.c
> @@ -59,8 +59,8 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
>
>      uint64_t rtc_r = cpu_riscv_read_rtc(timebase_freq);
>
> -    cpu->env.timecmp = value;
> -    if (cpu->env.timecmp <= rtc_r) {
> +    cpu->env.mtimecmp = value;
> +    if (cpu->env.mtimecmp <= rtc_r) {
>          /*
>           * If we're setting an MTIMECMP value in the "past",
>           * immediately raise the timer interrupt
> @@ -71,7 +71,7 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
>
>      /* otherwise, set up the future timer interrupt */
>      qemu_irq_lower(mtimer->timer_irqs[hartid - mtimer->hartid_base]);
> -    diff = cpu->env.timecmp - rtc_r;
> +    diff = cpu->env.mtimecmp - rtc_r;
>      /* back to ns (note args switched in muldiv64) */
>      uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
>
> @@ -96,7 +96,7 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
>          next = MIN(next, INT64_MAX);
>      }
>
> -    timer_mod(cpu->env.timer, next);
> +    timer_mod(cpu->env.mtimer, next);
>  }
>
>  /*
> @@ -127,11 +127,11 @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr,
>                            "aclint-mtimer: invalid hartid: %zu", hartid);
>          } else if ((addr & 0x7) == 0) {
>              /* timecmp_lo */
> -            uint64_t timecmp = env->timecmp;
> +            uint64_t timecmp = env->mtimecmp;
>              return timecmp & 0xFFFFFFFF;
>          } else if ((addr & 0x7) == 4) {
>              /* timecmp_hi */
> -            uint64_t timecmp = env->timecmp;
> +            uint64_t timecmp = env->mtimecmp;
>              return (timecmp >> 32) & 0xFFFFFFFF;
>          } else {
>              qemu_log_mask(LOG_UNIMP,
> @@ -168,14 +168,14 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
>                            "aclint-mtimer: invalid hartid: %zu", hartid);
>          } else if ((addr & 0x7) == 0) {
>              /* timecmp_lo */
> -            uint64_t timecmp_hi = env->timecmp >> 32;
> +            uint64_t timecmp_hi = env->mtimecmp >> 32;
>              riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
>                  timecmp_hi << 32 | (value & 0xFFFFFFFF),
>                  mtimer->timebase_freq);
>              return;
>          } else if ((addr & 0x7) == 4) {
>              /* timecmp_hi */
> -            uint64_t timecmp_lo = env->timecmp;
> +            uint64_t timecmp_lo = env->mtimecmp;
>              riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
>                  value << 32 | (timecmp_lo & 0xFFFFFFFF),
>                  mtimer->timebase_freq);
> @@ -304,9 +304,9 @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size,
>
>          cb->s = RISCV_ACLINT_MTIMER(dev);
>          cb->num = i;
> -        env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> +        env->mtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
>                                    &riscv_aclint_mtimer_cb, cb);
> -        env->timecmp = 0;
> +        env->mtimecmp = 0;
>
>          qdev_connect_gpio_out(dev, i,
>                                qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER));
> diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
> index 8c2ca364daab..4c34f9e08282 100644
> --- a/hw/timer/ibex_timer.c
> +++ b/hw/timer/ibex_timer.c
> @@ -73,9 +73,9 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
>      }
>
>      /* Update the CPUs mtimecmp */
> -    cpu->env.timecmp = value;
> +    cpu->env.mtimecmp = value;
>
> -    if (cpu->env.timecmp <= now) {
> +    if (cpu->env.mtimecmp <= now) {
>          /*
>           * If the mtimecmp was in the past raise the interrupt now.
>           */
> @@ -91,7 +91,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
>      qemu_irq_lower(s->m_timer_irq);
>      qemu_set_irq(s->irq, false);
>
> -    diff = cpu->env.timecmp - now;
> +    diff = cpu->env.mtimecmp - now;
>      next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
>                                   muldiv64(diff,
>                                            NANOSECONDS_PER_SECOND,
> @@ -99,9 +99,9 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
>
>      if (next < qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) {
>          /* We overflowed the timer, just set it as large as we can */
> -        timer_mod(cpu->env.timer, 0x7FFFFFFFFFFFFFFF);
> +        timer_mod(cpu->env.mtimer, 0x7FFFFFFFFFFFFFFF);
>      } else {
> -        timer_mod(cpu->env.timer, next);
> +        timer_mod(cpu->env.mtimer, next);
>      }
>  }
>
> @@ -122,9 +122,9 @@ static void ibex_timer_reset(DeviceState *dev)
>
>      CPUState *cpu = qemu_get_cpu(0);
>      CPURISCVState *env = cpu->env_ptr;
> -    env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> +    env->mtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
>                                &ibex_timer_cb, s);
> -    env->timecmp = 0;
> +    env->mtimecmp = 0;
>
>      s->timer_ctrl = 0x00000000;
>      s->timer_cfg0 = 0x00010000;
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 5d914bd34550..94234c59ffa8 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -265,7 +265,7 @@ struct CPURISCVState {
>      /* temporary htif regs */
>      uint64_t mfromhost;
>      uint64_t mtohost;
> -    uint64_t timecmp;
> +    uint64_t mtimecmp;
>
>      /* physical memory protection */
>      pmp_table_t pmp_state;
> @@ -316,7 +316,7 @@ struct CPURISCVState {
>      float_status fp_status;
>
>      /* Fields from here on are preserved across CPU reset. */
> -    QEMUTimer *timer; /* Internal timer */
> +    QEMUTimer *mtimer; /* Internal timer for M-mode interrupt */
>
>      hwaddr kernel_addr;
>      hwaddr fdt_addr;
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index ebc33c9e2781..be3022082a46 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -303,7 +303,7 @@ const VMStateDescription vmstate_riscv_cpu = {
>          VMSTATE_UINTTL(env.mscratch, RISCVCPU),
>          VMSTATE_UINT64(env.mfromhost, RISCVCPU),
>          VMSTATE_UINT64(env.mtohost, RISCVCPU),
> -        VMSTATE_UINT64(env.timecmp, RISCVCPU),
> +        VMSTATE_UINT64(env.mtimecmp, RISCVCPU),
>
>          VMSTATE_END_OF_LIST()
>      },
> --
> 2.30.2
>
>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH 1/3] target/riscv: Rename timer & timecmp to mtimer and mtimecmp
  2022-03-04  4:05   ` Anup Patel
@ 2022-03-08 21:32     ` Alistair Francis
  2022-03-08 22:43       ` Atish Patra
  0 siblings, 1 reply; 7+ messages in thread
From: Alistair Francis @ 2022-03-08 21:32 UTC (permalink / raw)
  To: Anup Patel
  Cc: open list:RISC-V, Bin Meng, Atish Patra, QEMU Developers,
	Palmer Dabbelt, Alistair Francis

On Fri, Mar 4, 2022 at 2:08 PM Anup Patel <anup@brainfault.org> wrote:
>
> On Fri, Mar 4, 2022 at 8:50 AM Atish Patra <atishp@rivosinc.com> wrote:
> >
> > Currently, the aclint and ibex timer devices uses the "timer" &
> > "timecmp" to generate the m-mode timer interrupt. In future,
> > we will have timer interrupt injected to S/VS mode directly.
> > No functionality change introduced in this patch.
>
> s/have timer/have a timer/
>
> >
> > Add a prefix "m" these enviornment variables to indicate its
> > true purpose.
>
> s/enviornment/environment/
>
> >
> > Signed-off-by: Atish Patra <atishp@rivosinc.com>
>
> I suggest we should remove mtimecmp and mtimer from
> target/riscv because mtimer is a memory mapped device.

I agree. I guess this is in the CPU as it's per hart, and it's easy to
store here instead of in the timer, but we could convert aclint to use
an array of timers (Ibex only ever has one hart).

That would probably be a closer match to hardware, as the timer is
external to the CPU

Alistair

>
> Regards,
> Anup
>
> > ---
> >  hw/intc/riscv_aclint.c | 20 ++++++++++----------
> >  hw/timer/ibex_timer.c  | 14 +++++++-------
> >  target/riscv/cpu.h     |  4 ++--
> >  target/riscv/machine.c |  2 +-
> >  4 files changed, 20 insertions(+), 20 deletions(-)
> >
> > diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
> > index f1a5d3d284fd..642794a06865 100644
> > --- a/hw/intc/riscv_aclint.c
> > +++ b/hw/intc/riscv_aclint.c
> > @@ -59,8 +59,8 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
> >
> >      uint64_t rtc_r = cpu_riscv_read_rtc(timebase_freq);
> >
> > -    cpu->env.timecmp = value;
> > -    if (cpu->env.timecmp <= rtc_r) {
> > +    cpu->env.mtimecmp = value;
> > +    if (cpu->env.mtimecmp <= rtc_r) {
> >          /*
> >           * If we're setting an MTIMECMP value in the "past",
> >           * immediately raise the timer interrupt
> > @@ -71,7 +71,7 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
> >
> >      /* otherwise, set up the future timer interrupt */
> >      qemu_irq_lower(mtimer->timer_irqs[hartid - mtimer->hartid_base]);
> > -    diff = cpu->env.timecmp - rtc_r;
> > +    diff = cpu->env.mtimecmp - rtc_r;
> >      /* back to ns (note args switched in muldiv64) */
> >      uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
> >
> > @@ -96,7 +96,7 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
> >          next = MIN(next, INT64_MAX);
> >      }
> >
> > -    timer_mod(cpu->env.timer, next);
> > +    timer_mod(cpu->env.mtimer, next);
> >  }
> >
> >  /*
> > @@ -127,11 +127,11 @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr,
> >                            "aclint-mtimer: invalid hartid: %zu", hartid);
> >          } else if ((addr & 0x7) == 0) {
> >              /* timecmp_lo */
> > -            uint64_t timecmp = env->timecmp;
> > +            uint64_t timecmp = env->mtimecmp;
> >              return timecmp & 0xFFFFFFFF;
> >          } else if ((addr & 0x7) == 4) {
> >              /* timecmp_hi */
> > -            uint64_t timecmp = env->timecmp;
> > +            uint64_t timecmp = env->mtimecmp;
> >              return (timecmp >> 32) & 0xFFFFFFFF;
> >          } else {
> >              qemu_log_mask(LOG_UNIMP,
> > @@ -168,14 +168,14 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
> >                            "aclint-mtimer: invalid hartid: %zu", hartid);
> >          } else if ((addr & 0x7) == 0) {
> >              /* timecmp_lo */
> > -            uint64_t timecmp_hi = env->timecmp >> 32;
> > +            uint64_t timecmp_hi = env->mtimecmp >> 32;
> >              riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
> >                  timecmp_hi << 32 | (value & 0xFFFFFFFF),
> >                  mtimer->timebase_freq);
> >              return;
> >          } else if ((addr & 0x7) == 4) {
> >              /* timecmp_hi */
> > -            uint64_t timecmp_lo = env->timecmp;
> > +            uint64_t timecmp_lo = env->mtimecmp;
> >              riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
> >                  value << 32 | (timecmp_lo & 0xFFFFFFFF),
> >                  mtimer->timebase_freq);
> > @@ -304,9 +304,9 @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size,
> >
> >          cb->s = RISCV_ACLINT_MTIMER(dev);
> >          cb->num = i;
> > -        env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > +        env->mtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> >                                    &riscv_aclint_mtimer_cb, cb);
> > -        env->timecmp = 0;
> > +        env->mtimecmp = 0;
> >
> >          qdev_connect_gpio_out(dev, i,
> >                                qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER));
> > diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
> > index 8c2ca364daab..4c34f9e08282 100644
> > --- a/hw/timer/ibex_timer.c
> > +++ b/hw/timer/ibex_timer.c
> > @@ -73,9 +73,9 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
> >      }
> >
> >      /* Update the CPUs mtimecmp */
> > -    cpu->env.timecmp = value;
> > +    cpu->env.mtimecmp = value;
> >
> > -    if (cpu->env.timecmp <= now) {
> > +    if (cpu->env.mtimecmp <= now) {
> >          /*
> >           * If the mtimecmp was in the past raise the interrupt now.
> >           */
> > @@ -91,7 +91,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
> >      qemu_irq_lower(s->m_timer_irq);
> >      qemu_set_irq(s->irq, false);
> >
> > -    diff = cpu->env.timecmp - now;
> > +    diff = cpu->env.mtimecmp - now;
> >      next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> >                                   muldiv64(diff,
> >                                            NANOSECONDS_PER_SECOND,
> > @@ -99,9 +99,9 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
> >
> >      if (next < qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) {
> >          /* We overflowed the timer, just set it as large as we can */
> > -        timer_mod(cpu->env.timer, 0x7FFFFFFFFFFFFFFF);
> > +        timer_mod(cpu->env.mtimer, 0x7FFFFFFFFFFFFFFF);
> >      } else {
> > -        timer_mod(cpu->env.timer, next);
> > +        timer_mod(cpu->env.mtimer, next);
> >      }
> >  }
> >
> > @@ -122,9 +122,9 @@ static void ibex_timer_reset(DeviceState *dev)
> >
> >      CPUState *cpu = qemu_get_cpu(0);
> >      CPURISCVState *env = cpu->env_ptr;
> > -    env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > +    env->mtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> >                                &ibex_timer_cb, s);
> > -    env->timecmp = 0;
> > +    env->mtimecmp = 0;
> >
> >      s->timer_ctrl = 0x00000000;
> >      s->timer_cfg0 = 0x00010000;
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 5d914bd34550..94234c59ffa8 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -265,7 +265,7 @@ struct CPURISCVState {
> >      /* temporary htif regs */
> >      uint64_t mfromhost;
> >      uint64_t mtohost;
> > -    uint64_t timecmp;
> > +    uint64_t mtimecmp;
> >
> >      /* physical memory protection */
> >      pmp_table_t pmp_state;
> > @@ -316,7 +316,7 @@ struct CPURISCVState {
> >      float_status fp_status;
> >
> >      /* Fields from here on are preserved across CPU reset. */
> > -    QEMUTimer *timer; /* Internal timer */
> > +    QEMUTimer *mtimer; /* Internal timer for M-mode interrupt */
> >
> >      hwaddr kernel_addr;
> >      hwaddr fdt_addr;
> > diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> > index ebc33c9e2781..be3022082a46 100644
> > --- a/target/riscv/machine.c
> > +++ b/target/riscv/machine.c
> > @@ -303,7 +303,7 @@ const VMStateDescription vmstate_riscv_cpu = {
> >          VMSTATE_UINTTL(env.mscratch, RISCVCPU),
> >          VMSTATE_UINT64(env.mfromhost, RISCVCPU),
> >          VMSTATE_UINT64(env.mtohost, RISCVCPU),
> > -        VMSTATE_UINT64(env.timecmp, RISCVCPU),
> > +        VMSTATE_UINT64(env.mtimecmp, RISCVCPU),
> >
> >          VMSTATE_END_OF_LIST()
> >      },
> > --
> > 2.30.2
> >
> >
>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH 1/3] target/riscv: Rename timer & timecmp to mtimer and mtimecmp
  2022-03-08 21:32     ` Alistair Francis
@ 2022-03-08 22:43       ` Atish Patra
  0 siblings, 0 replies; 7+ messages in thread
From: Atish Patra @ 2022-03-08 22:43 UTC (permalink / raw)
  To: Alistair Francis
  Cc: open list:RISC-V, Anup Patel, Bin Meng, Atish Patra,
	QEMU Developers, Palmer Dabbelt, Alistair Francis

On Tue, Mar 8, 2022 at 1:33 PM Alistair Francis <alistair23@gmail.com> wrote:
>
> On Fri, Mar 4, 2022 at 2:08 PM Anup Patel <anup@brainfault.org> wrote:
> >
> > On Fri, Mar 4, 2022 at 8:50 AM Atish Patra <atishp@rivosinc.com> wrote:
> > >
> > > Currently, the aclint and ibex timer devices uses the "timer" &
> > > "timecmp" to generate the m-mode timer interrupt. In future,
> > > we will have timer interrupt injected to S/VS mode directly.
> > > No functionality change introduced in this patch.
> >
> > s/have timer/have a timer/
> >
> > >
> > > Add a prefix "m" these enviornment variables to indicate its
> > > true purpose.
> >
> > s/enviornment/environment/
> >
> > >
> > > Signed-off-by: Atish Patra <atishp@rivosinc.com>
> >
> > I suggest we should remove mtimecmp and mtimer from
> > target/riscv because mtimer is a memory mapped device.
>
> I agree. I guess this is in the CPU as it's per hart, and it's easy to
> store here instead of in the timer, but we could convert aclint to use
> an array of timers (Ibex only ever has one hart).
>
> That would probably be a closer match to hardware, as the timer is
> external to the CPU
>

ok sure. I will revise that.

> Alistair
>
> >
> > Regards,
> > Anup
> >
> > > ---
> > >  hw/intc/riscv_aclint.c | 20 ++++++++++----------
> > >  hw/timer/ibex_timer.c  | 14 +++++++-------
> > >  target/riscv/cpu.h     |  4 ++--
> > >  target/riscv/machine.c |  2 +-
> > >  4 files changed, 20 insertions(+), 20 deletions(-)
> > >
> > > diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
> > > index f1a5d3d284fd..642794a06865 100644
> > > --- a/hw/intc/riscv_aclint.c
> > > +++ b/hw/intc/riscv_aclint.c
> > > @@ -59,8 +59,8 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
> > >
> > >      uint64_t rtc_r = cpu_riscv_read_rtc(timebase_freq);
> > >
> > > -    cpu->env.timecmp = value;
> > > -    if (cpu->env.timecmp <= rtc_r) {
> > > +    cpu->env.mtimecmp = value;
> > > +    if (cpu->env.mtimecmp <= rtc_r) {
> > >          /*
> > >           * If we're setting an MTIMECMP value in the "past",
> > >           * immediately raise the timer interrupt
> > > @@ -71,7 +71,7 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
> > >
> > >      /* otherwise, set up the future timer interrupt */
> > >      qemu_irq_lower(mtimer->timer_irqs[hartid - mtimer->hartid_base]);
> > > -    diff = cpu->env.timecmp - rtc_r;
> > > +    diff = cpu->env.mtimecmp - rtc_r;
> > >      /* back to ns (note args switched in muldiv64) */
> > >      uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
> > >
> > > @@ -96,7 +96,7 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
> > >          next = MIN(next, INT64_MAX);
> > >      }
> > >
> > > -    timer_mod(cpu->env.timer, next);
> > > +    timer_mod(cpu->env.mtimer, next);
> > >  }
> > >
> > >  /*
> > > @@ -127,11 +127,11 @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr,
> > >                            "aclint-mtimer: invalid hartid: %zu", hartid);
> > >          } else if ((addr & 0x7) == 0) {
> > >              /* timecmp_lo */
> > > -            uint64_t timecmp = env->timecmp;
> > > +            uint64_t timecmp = env->mtimecmp;
> > >              return timecmp & 0xFFFFFFFF;
> > >          } else if ((addr & 0x7) == 4) {
> > >              /* timecmp_hi */
> > > -            uint64_t timecmp = env->timecmp;
> > > +            uint64_t timecmp = env->mtimecmp;
> > >              return (timecmp >> 32) & 0xFFFFFFFF;
> > >          } else {
> > >              qemu_log_mask(LOG_UNIMP,
> > > @@ -168,14 +168,14 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
> > >                            "aclint-mtimer: invalid hartid: %zu", hartid);
> > >          } else if ((addr & 0x7) == 0) {
> > >              /* timecmp_lo */
> > > -            uint64_t timecmp_hi = env->timecmp >> 32;
> > > +            uint64_t timecmp_hi = env->mtimecmp >> 32;
> > >              riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
> > >                  timecmp_hi << 32 | (value & 0xFFFFFFFF),
> > >                  mtimer->timebase_freq);
> > >              return;
> > >          } else if ((addr & 0x7) == 4) {
> > >              /* timecmp_hi */
> > > -            uint64_t timecmp_lo = env->timecmp;
> > > +            uint64_t timecmp_lo = env->mtimecmp;
> > >              riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
> > >                  value << 32 | (timecmp_lo & 0xFFFFFFFF),
> > >                  mtimer->timebase_freq);
> > > @@ -304,9 +304,9 @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size,
> > >
> > >          cb->s = RISCV_ACLINT_MTIMER(dev);
> > >          cb->num = i;
> > > -        env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > > +        env->mtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > >                                    &riscv_aclint_mtimer_cb, cb);
> > > -        env->timecmp = 0;
> > > +        env->mtimecmp = 0;
> > >
> > >          qdev_connect_gpio_out(dev, i,
> > >                                qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER));
> > > diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
> > > index 8c2ca364daab..4c34f9e08282 100644
> > > --- a/hw/timer/ibex_timer.c
> > > +++ b/hw/timer/ibex_timer.c
> > > @@ -73,9 +73,9 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
> > >      }
> > >
> > >      /* Update the CPUs mtimecmp */
> > > -    cpu->env.timecmp = value;
> > > +    cpu->env.mtimecmp = value;
> > >
> > > -    if (cpu->env.timecmp <= now) {
> > > +    if (cpu->env.mtimecmp <= now) {
> > >          /*
> > >           * If the mtimecmp was in the past raise the interrupt now.
> > >           */
> > > @@ -91,7 +91,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
> > >      qemu_irq_lower(s->m_timer_irq);
> > >      qemu_set_irq(s->irq, false);
> > >
> > > -    diff = cpu->env.timecmp - now;
> > > +    diff = cpu->env.mtimecmp - now;
> > >      next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> > >                                   muldiv64(diff,
> > >                                            NANOSECONDS_PER_SECOND,
> > > @@ -99,9 +99,9 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
> > >
> > >      if (next < qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) {
> > >          /* We overflowed the timer, just set it as large as we can */
> > > -        timer_mod(cpu->env.timer, 0x7FFFFFFFFFFFFFFF);
> > > +        timer_mod(cpu->env.mtimer, 0x7FFFFFFFFFFFFFFF);
> > >      } else {
> > > -        timer_mod(cpu->env.timer, next);
> > > +        timer_mod(cpu->env.mtimer, next);
> > >      }
> > >  }
> > >
> > > @@ -122,9 +122,9 @@ static void ibex_timer_reset(DeviceState *dev)
> > >
> > >      CPUState *cpu = qemu_get_cpu(0);
> > >      CPURISCVState *env = cpu->env_ptr;
> > > -    env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > > +    env->mtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > >                                &ibex_timer_cb, s);
> > > -    env->timecmp = 0;
> > > +    env->mtimecmp = 0;
> > >
> > >      s->timer_ctrl = 0x00000000;
> > >      s->timer_cfg0 = 0x00010000;
> > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > > index 5d914bd34550..94234c59ffa8 100644
> > > --- a/target/riscv/cpu.h
> > > +++ b/target/riscv/cpu.h
> > > @@ -265,7 +265,7 @@ struct CPURISCVState {
> > >      /* temporary htif regs */
> > >      uint64_t mfromhost;
> > >      uint64_t mtohost;
> > > -    uint64_t timecmp;
> > > +    uint64_t mtimecmp;
> > >
> > >      /* physical memory protection */
> > >      pmp_table_t pmp_state;
> > > @@ -316,7 +316,7 @@ struct CPURISCVState {
> > >      float_status fp_status;
> > >
> > >      /* Fields from here on are preserved across CPU reset. */
> > > -    QEMUTimer *timer; /* Internal timer */
> > > +    QEMUTimer *mtimer; /* Internal timer for M-mode interrupt */
> > >
> > >      hwaddr kernel_addr;
> > >      hwaddr fdt_addr;
> > > diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> > > index ebc33c9e2781..be3022082a46 100644
> > > --- a/target/riscv/machine.c
> > > +++ b/target/riscv/machine.c
> > > @@ -303,7 +303,7 @@ const VMStateDescription vmstate_riscv_cpu = {
> > >          VMSTATE_UINTTL(env.mscratch, RISCVCPU),
> > >          VMSTATE_UINT64(env.mfromhost, RISCVCPU),
> > >          VMSTATE_UINT64(env.mtohost, RISCVCPU),
> > > -        VMSTATE_UINT64(env.timecmp, RISCVCPU),
> > > +        VMSTATE_UINT64(env.mtimecmp, RISCVCPU),
> > >
> > >          VMSTATE_END_OF_LIST()
> > >      },
> > > --
> > > 2.30.2
> > >
> > >
> >
>


-- 
Regards,
Atish


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-03-08 22:45 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-04  3:20 [RFC PATCH 0/3] Implement Sstc extension Atish Patra
2022-03-04  3:20 ` [RFC PATCH 1/3] target/riscv: Rename timer & timecmp to mtimer and mtimecmp Atish Patra
2022-03-04  4:05   ` Anup Patel
2022-03-08 21:32     ` Alistair Francis
2022-03-08 22:43       ` Atish Patra
2022-03-04  3:20 ` [RFC PATCH 2/3] target/riscv: Add stimecmp support Atish Patra
2022-03-04  3:20 ` [RFC PATCH 3/3] target/riscv: Add vstimecmp support Atish Patra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).