qemu-devel
[Top][All Lists]
Advanced

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

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


From: Irina Ryapolova
Subject: [PATCH v3 1/2] target/riscv/csr.c: Add functional of hvictl CSR
Date: Sun, 24 Mar 2024 18:09:48 +0300

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
Changes for v3:
  -applied patch in master
---
 target/riscv/csr.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 726096444f..4c2cbcd59f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3613,6 +3613,21 @@ static RISCVException 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;
 }
 
-- 
2.25.1




reply via email to

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