diff mbox series

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

Message ID 20240320164259.19205-1-irina.ryapolova@syntacore.com
State New
Headers show
Series [v2,1/2] target/riscv/csr.c: Add functional of hvictl CSR | expand

Commit Message

Irina Ryapolova March 20, 2024, 4:42 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.

A hypervisor must use hvictl for any of the following:
• asserting for VS level a major interrupt not supported by hvien and hvip;
• implementing configurability of priorities at VS level for major interrupts beyond those sup-
ported by hviprio1 and hviprio2; or
• emulating an external interrupt controller for a virtual hart without the use of an IMSIC’s
guest interrupt file, while also supporting configurable priorities both for external interrupts
and for major interrupts to the virtual hart.

All hvictl fields together can affect the value of CSR vstopi (Virtual Supervisor Top Interrupt)
and therefore the interrupt identity reported in vscause when an interrupt traps to VS-mode.
When hvictl.VTI = 1, the absence of an interrupt for VS level can be indicated only by setting
hvictl.IID = 9. Software might want to use the pair IID = 9, IPRIO = 0 generally to represent
no interrupt in hvictl.

(See riscv-interrupts-1.0: Interrupts at VS level)

Signed-off-by: Irina Ryapolova <irina.ryapolova@syntacore.com>
---
Changes for v2:
  -added more information in commit message
---
 target/riscv/csr.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

Comments

Daniel Henrique Barboza March 20, 2024, 9:02 p.m. UTC | #1
Hi,

This patch doesn't apply in master or alistair/riscv-to-apply.next. Can you
please re-send?


Thanks,


Daniel


On 3/20/24 13:42, Irina Ryapolova 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.
> 
> A hypervisor must use hvictl for any of the following:
> • asserting for VS level a major interrupt not supported by hvien and hvip;
> • implementing configurability of priorities at VS level for major interrupts beyond those sup-
> ported by hviprio1 and hviprio2; or
> • emulating an external interrupt controller for a virtual hart without the use of an IMSIC’s
> guest interrupt file, while also supporting configurable priorities both for external interrupts
> and for major interrupts to the virtual hart.
> 
> All hvictl fields together can affect the value of CSR vstopi (Virtual Supervisor Top Interrupt)
> and therefore the interrupt identity reported in vscause when an interrupt traps to VS-mode.
> When hvictl.VTI = 1, the absence of an interrupt for VS level can be indicated only by setting
> hvictl.IID = 9. Software might want to use the pair IID = 9, IPRIO = 0 generally to represent
> no interrupt in hvictl.
> 
> (See riscv-interrupts-1.0: Interrupts at VS level)
> 
> Signed-off-by: Irina Ryapolova <irina.ryapolova@syntacore.com>
> ---
> Changes for v2:
>    -added more information in commit message
> ---
>   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);
> +            }
> +        }
> +    }
> +
>       return RISCV_EXCP_NONE;
>   }
>
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;
 }