diff mbox series

[2/4] hw/intc: riscv_aclint: Fix mtime write for sstc extension

Message ID 20250319192153.28549-3-jim.shu@sifive.com (mailing list archive)
State New
Headers show
Series Several sstc extension fixes | expand

Commit Message

Jim Shu March 19, 2025, 7:21 p.m. UTC
When changing the mtime value, the period of [s|vs]timecmp timers
should also be updated like the period of mtimecmp timer.

Signed-off-by: Jim Shu <jim.shu@sifive.com>
---
 hw/intc/riscv_aclint.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Alistair Francis April 4, 2025, 3:11 a.m. UTC | #1
On Thu, Mar 20, 2025 at 5:24 AM Jim Shu <jim.shu@sifive.com> wrote:
>
> When changing the mtime value, the period of [s|vs]timecmp timers
> should also be updated like the period of mtimecmp timer.

Why should they be updated?

Alistair

>
> Signed-off-by: Jim Shu <jim.shu@sifive.com>
> ---
>  hw/intc/riscv_aclint.c | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
> index db374a7c2d..5f4a17e177 100644
> --- a/hw/intc/riscv_aclint.c
> +++ b/hw/intc/riscv_aclint.c
> @@ -28,6 +28,7 @@
>  #include "qemu/module.h"
>  #include "hw/sysbus.h"
>  #include "target/riscv/cpu.h"
> +#include "target/riscv/time_helper.h"
>  #include "hw/qdev-properties.h"
>  #include "hw/intc/riscv_aclint.h"
>  #include "qemu/timer.h"
> @@ -240,6 +241,10 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
>              riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu),
>                                                mtimer->hartid_base + i,
>                                                mtimer->timecmp[i]);
> +            riscv_timer_write_timecmp(env, env->stimer, env->stimecmp, 0, MIP_STIP);
> +            riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
> +                                      env->htimedelta, MIP_VSTIP);
> +
>          }
>          return;
>      }
> --
> 2.17.1
>
>
Jim Shu April 7, 2025, 10:06 a.m. UTC | #2
The period of the stimecmp timer is the time until the next S-mode
timer IRQ. The value is calculated as "stimecmp - time". [1]
It is equal to "stimecmp - mtime" since the time CSR is a read-only
shadow of the memory-mapped mtime register.
Thus, changing mtime value will update the period of stimecmp timer.

Similarly, the period of vstimecmp timer is calculated as "vstimecmp -
(mtime + htimedelta)" [2], so changing mtime value will update the
period of vstimecmp timer.

[1] RISC-V Priv spec ch 9.1.1. Supervisor Timer (stimecmp) Register
A supervisor timer interrupt becomes pending, as reflected in the STIP
bit in the mip and sip registers whenever time contains a value
greater than or equal to stimecmp.
[2] RISC-V Priv spec ch19.2.1. Virtual Supervisor Timer (vstimecmp) Register
A virtual supervisor timer interrupt becomes pending, as reflected in
the VSTIP bit in the hip register, whenever (time + htimedelta),
truncated to 64 bits, contains a value greater than or equal to
vstimecmp

I will add the explaination in the commit log in the v2 patchset, thanks.


Jim Shu

On Fri, Apr 4, 2025 at 11:12 AM Alistair Francis <alistair23@gmail.com> wrote:
>
> On Thu, Mar 20, 2025 at 5:24 AM Jim Shu <jim.shu@sifive.com> wrote:
> >
> > When changing the mtime value, the period of [s|vs]timecmp timers
> > should also be updated like the period of mtimecmp timer.
>
> Why should they be updated?
>
> Alistair
>
> >
> > Signed-off-by: Jim Shu <jim.shu@sifive.com>
> > ---
> >  hw/intc/riscv_aclint.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
> > index db374a7c2d..5f4a17e177 100644
> > --- a/hw/intc/riscv_aclint.c
> > +++ b/hw/intc/riscv_aclint.c
> > @@ -28,6 +28,7 @@
> >  #include "qemu/module.h"
> >  #include "hw/sysbus.h"
> >  #include "target/riscv/cpu.h"
> > +#include "target/riscv/time_helper.h"
> >  #include "hw/qdev-properties.h"
> >  #include "hw/intc/riscv_aclint.h"
> >  #include "qemu/timer.h"
> > @@ -240,6 +241,10 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
> >              riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu),
> >                                                mtimer->hartid_base + i,
> >                                                mtimer->timecmp[i]);
> > +            riscv_timer_write_timecmp(env, env->stimer, env->stimecmp, 0, MIP_STIP);
> > +            riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
> > +                                      env->htimedelta, MIP_VSTIP);
> > +
> >          }
> >          return;
> >      }
> > --
> > 2.17.1
> >
> >
diff mbox series

Patch

diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
index db374a7c2d..5f4a17e177 100644
--- a/hw/intc/riscv_aclint.c
+++ b/hw/intc/riscv_aclint.c
@@ -28,6 +28,7 @@ 
 #include "qemu/module.h"
 #include "hw/sysbus.h"
 #include "target/riscv/cpu.h"
+#include "target/riscv/time_helper.h"
 #include "hw/qdev-properties.h"
 #include "hw/intc/riscv_aclint.h"
 #include "qemu/timer.h"
@@ -240,6 +241,10 @@  static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
             riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu),
                                               mtimer->hartid_base + i,
                                               mtimer->timecmp[i]);
+            riscv_timer_write_timecmp(env, env->stimer, env->stimecmp, 0, MIP_STIP);
+            riscv_timer_write_timecmp(env, env->vstimer, env->vstimecmp,
+                                      env->htimedelta, MIP_VSTIP);
+
         }
         return;
     }