qemu-riscv
[Top][All Lists]
Advanced

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

[RFC PATCH 13/13] target/riscv: Changing the width of U-mode CSR


From: LIU Zhiwei
Subject: [RFC PATCH 13/13] target/riscv: Changing the width of U-mode CSR
Date: Thu, 5 Aug 2021 10:53:12 +0800

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/csr.c | 42 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 37 insertions(+), 5 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 9a4ed18ac5..dc9807c0ff 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -297,7 +297,7 @@ static RISCVException read_vxrm(CPURISCVState *env, int 
csrno,
 static RISCVException write_vxrm(CPURISCVState *env, int csrno,
                                  target_ulong val)
 {
-    env->vxrm = val;
+    env->vxrm = riscv_cpu_is_uxl32(env) ? val & UINT32_MAX : val;
     return RISCV_EXCP_NONE;
 }
 
@@ -311,7 +311,7 @@ static RISCVException read_vxsat(CPURISCVState *env, int 
csrno,
 static RISCVException write_vxsat(CPURISCVState *env, int csrno,
                                   target_ulong val)
 {
-    env->vxsat = val;
+    env->vxsat = riscv_cpu_is_uxl32(env) ? val & UINT32_MAX : val;
     return RISCV_EXCP_NONE;
 }
 
@@ -325,7 +325,7 @@ static RISCVException read_vstart(CPURISCVState *env, int 
csrno,
 static RISCVException write_vstart(CPURISCVState *env, int csrno,
                                    target_ulong val)
 {
-    env->vstart = val;
+    env->vstart = riscv_cpu_is_uxl32(env) ? val & UINT32_MAX : val;
     return RISCV_EXCP_NONE;
 }
 
@@ -493,6 +493,36 @@ static int validate_vm(CPURISCVState *env, target_ulong vm)
     }
 }
 
+static void uxl32_switch(CPURISCVState *env, target_ulong val)
+{
+    uint32_t old = get_field(env->mstatus, MSTATUS64_UXL);
+    uint32_t new = get_field(val, MSTATUS64_UXL);
+
+    if (old == new) {
+        return;
+    }
+
+    /*
+     * For the read-only bits of the previous-width CSR, the bits at the
+     * same positions in the temporary register are set to zeros.
+     */
+    if (env->misa & RVV) {
+        env->vl = 0;
+        env->vtype = 0;
+    }
+
+    /*
+     * If the new width W is narrower than the previous width, the
+     * least-significant W bits of the temporary register are retained and
+     * the more-significant bits are discarded.
+     */
+    if ((old == 2) && (new == 1)) {
+        if (env->misa & RVV) {
+            env->vtype &= UINT32_MAX;
+        }
+    }
+}
+
 static RISCVException write_mstatus(CPURISCVState *env, int csrno,
                                     target_ulong val)
 {
@@ -502,13 +532,13 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
 
     /* flush tlb on mstatus fields that affect VM */
     if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
-            MSTATUS_MPRV | MSTATUS_SUM)) {
+            MSTATUS_MPRV | MSTATUS_SUM | MSTATUS64_UXL)) {
         tlb_flush(env_cpu(env));
     }
     mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
         MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
         MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
-        MSTATUS_TW;
+        MSTATUS_TW | MSTATUS64_UXL;
 
     if (!riscv_cpu_is_32bit(env)) {
         /*
@@ -518,6 +548,8 @@ static RISCVException write_mstatus(CPURISCVState *env, int 
csrno,
         mask |= MSTATUS_MPV | MSTATUS_GVA;
     }
 
+    uxl32_switch(env, val);
+
     mstatus = (mstatus & ~mask) | (val & mask);
 
     dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) |
-- 
2.17.1




reply via email to

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