From: Alistair Francis <[email protected]>

The RISC-V spec states that

"""
But when bit 9 of mvien is one, bit SEIP in mip is read-only and does
not include the value of bit 9 of mvip. Rather, the value of mip.SEIP
is simply the supervisor external interrupt signal from the hart’s
external interrupt controller (APLIC or IMSIC).
"""

As such let's mark the mip.SEIP in rmw_mip64().

Cc: [email protected]
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/2828
Signed-off-by: Alistair Francis <[email protected]>
Reviewed-by: Chao Liu <[email protected]>
Reviewed-by: Nutty Liu <[email protected]>
Message-ID: <[email protected]>
Signed-off-by: Alistair Francis <[email protected]>
(cherry picked from commit 175afdb0d155a7429e2ac0c568c1c807953444a4)
Signed-off-by: Michael Tokarev <[email protected]>

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 76e77ae2d1..7d4191c792 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3633,6 +3633,14 @@ static RISCVException rmw_mip64(CPURISCVState *env, int 
csrno,
     uint64_t old_mip, mask = wr_mask & delegable_ints;
     uint32_t gin;
 
+    /*
+     * When mvien[9]=1, mip.SEIP is read-only and reflects only
+     * the external interrupt signal from the interrupt controller.
+     */
+    if (env->mvien & MIP_SEIP) {
+        mask &= ~MIP_SEIP;
+    }
+
     if (mask & MIP_SEIP) {
         env->software_seip = new_val & MIP_SEIP;
         new_val |= env->external_seip * MIP_SEIP;
-- 
2.47.3


Reply via email to