diff mbox series

[1/2] target/riscv/csr.c: Add functional of hvictl CSR

Message ID 20240212171156.47293-1-irina.ryapolova@syntacore.com (mailing list archive)
State New, archived
Headers show
Series [1/2] target/riscv/csr.c: Add functional of hvictl CSR | expand

Commit Message

Irina Ryapolova Feb. 12, 2024, 5:11 p.m. UTC
CSR hvictl (Hypervisor Virtual Interrupt Control) provides further flexibility
for injecting interrupts into VS level in situations not fully supported by the
facilities described thus far, but only with more active involvement of the hypervisor.
(See riscv-interrupts-1.0: Interrupts at VS level)

Signed-off-by: Irina Ryapolova <irina.ryapolova@syntacore.com>
---
 target/riscv/csr.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

Comments

Alistair Francis Feb. 15, 2024, 9:42 a.m. UTC | #1
On Tue, Feb 13, 2024 at 3:13 AM Irina Ryapolova
<irina.ryapolova@syntacore.com> wrote:
>
> CSR hvictl (Hypervisor Virtual Interrupt Control) provides further flexibility
> for injecting interrupts into VS level in situations not fully supported by the
> facilities described thus far, but only with more active involvement of the hypervisor.
> (See riscv-interrupts-1.0: Interrupts at VS level)
>
> Signed-off-by: Irina Ryapolova <irina.ryapolova@syntacore.com>
> ---
>  target/riscv/csr.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 674ea075a4..0c21145eaf 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -3585,6 +3585,21 @@ static int read_hvictl(CPURISCVState *env, int csrno, target_ulong *val)
>  static int write_hvictl(CPURISCVState *env, int csrno, target_ulong val)
>  {
>      env->hvictl = val & HVICTL_VALID_MASK;
> +    if (env->hvictl & HVICTL_VTI)
> +    {
> +        uint32_t hviid = get_field(env->hvictl, HVICTL_IID);
> +        uint32_t hviprio = get_field(env->hvictl, HVICTL_IPRIO);
> +        /* the pair IID = 9, IPRIO = 0 generally to represent no interrupt in hvictl. */
> +        if (!(hviid == IRQ_S_EXT && hviprio == 0)) {
> +            uint64_t new_val = BIT(hviid) ;
> +             if (new_val & S_MODE_INTERRUPTS) {
> +                rmw_hvip64(env, csrno, NULL, new_val << 1, new_val << 1);
> +            } else if (new_val & LOCAL_INTERRUPTS) {
> +                rmw_hvip64(env, csrno, NULL, new_val, new_val);

I'm not sure I follow what is happening here, the section in the spec
is tricky to comprehend.

Do you mind being a little more descriptive in the commit message as
to exactly what we are supporting here?

Alistair


> +            }
> +        }
> +    }
> +
>      return RISCV_EXCP_NONE;
>  }
>
> --
> 2.25.1
>
>
diff mbox series

Patch

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 674ea075a4..0c21145eaf 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3585,6 +3585,21 @@  static int read_hvictl(CPURISCVState *env, int csrno, target_ulong *val)
 static int write_hvictl(CPURISCVState *env, int csrno, target_ulong val)
 {
     env->hvictl = val & HVICTL_VALID_MASK;
+    if (env->hvictl & HVICTL_VTI)
+    {
+        uint32_t hviid = get_field(env->hvictl, HVICTL_IID);
+        uint32_t hviprio = get_field(env->hvictl, HVICTL_IPRIO);
+        /* the pair IID = 9, IPRIO = 0 generally to represent no interrupt in hvictl. */
+        if (!(hviid == IRQ_S_EXT && hviprio == 0)) {
+            uint64_t new_val = BIT(hviid) ;
+             if (new_val & S_MODE_INTERRUPTS) {
+                rmw_hvip64(env, csrno, NULL, new_val << 1, new_val << 1);
+            } else if (new_val & LOCAL_INTERRUPTS) {
+                rmw_hvip64(env, csrno, NULL, new_val, new_val);
+            }
+        }
+    }
+    
     return RISCV_EXCP_NONE;
 }