qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation
@ 2023-03-22 22:19 Daniel Henrique Barboza
  2023-03-22 22:19 ` [PATCH for-8.1 v4 01/25] target/riscv/cpu.c: add riscv_cpu_validate_v() Daniel Henrique Barboza
                   ` (24 more replies)
  0 siblings, 25 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

Hi,

In this version I simplified the logic used in write_misa() after
reviews from Weiwei Li. The patch that handled RVV activation was
removed, making RVV a regular MISA bit to activate/deactivate.

We're also checking whether one of the IMAFD extensions got disabled
during write_misa() and, if that's the case, we'll clear RVG.

Series is based on top of Alistair's riscv-to-apply.next.

Patches acked: 1-5.

Changes from v3:
- patch 11:
  - remove c/u/s cpu->cfg assignment from rv64_thead_c906_cpu_init()
- patch 14:
  - add RVG in set_misa() call inside rv64_thead_c906_cpu_init()
  - remove cpu->cfg.ext_g assignment from rv64_thead_c906_cpu_init()
- patch 15:
  - remove ext_zfinx verification from riscv_cpu_enable_g()
- patch 25:
  - do not call riscv_cpu_enable_g() in write_misa()
  - enable/disable RVG extensions manually in write_misa()
- patch 26: removed
- v3 link: https://lists.gnu.org/archive/html/qemu-devel/2023-03/msg05097.html


Daniel Henrique Barboza (25):
  target/riscv/cpu.c: add riscv_cpu_validate_v()
  target/riscv/cpu.c: remove set_vext_version()
  target/riscv/cpu.c: remove set_priv_version()
  target/riscv: add PRIV_VERSION_LATEST
  target/riscv/cpu.c: add priv_spec validate/disable_exts helpers
  target/riscv/cpu.c: add riscv_cpu_validate_misa_mxl()
  target/riscv: move pmp and epmp validations to
    validate_set_extensions()
  target/riscv/cpu.c: validate extensions before riscv_timer_init()
  target/riscv/cpu.c: remove cfg setup from riscv_cpu_init()
  target/riscv/cpu.c: avoid set_misa() in validate_set_extensions()
  target/riscv/cpu.c: set cpu config in set_misa()
  target/riscv/cpu.c: redesign register_cpu_props()
  target/riscv: put env->misa_ext <-> cpu->cfg code into helpers
  target/riscv: add RVG
  target/riscv/cpu.c: split RVG code from validate_set_extensions()
  target/riscv/cpu.c: add riscv_cpu_validate_misa_ext()
  target/riscv: move riscv_cpu_validate_v() to validate_misa_ext()
  target/riscv: error out on priv failure for RVH
  target/riscv: write env->misa_ext* in register_generic_cpu_props()
  target/riscv: make validate_misa_ext() use a misa_ext val
  target/riscv: split riscv_cpu_validate_set_extensions()
  target/riscv: use misa_ext val in riscv_cpu_validate_extensions()
  target/riscv: rework write_misa()
  target/riscv: update cpu->cfg misa bits in commit_cpu_cfg()
  target/riscv: handle RVG updates in write_misa()

 target/riscv/cpu.c | 654 ++++++++++++++++++++++++++++-----------------
 target/riscv/cpu.h |  14 +-
 target/riscv/csr.c |  72 +++--
 3 files changed, 463 insertions(+), 277 deletions(-)

-- 
2.39.2



^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 01/25] target/riscv/cpu.c: add riscv_cpu_validate_v()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-22 22:19 ` [PATCH for-8.1 v4 02/25] target/riscv/cpu.c: remove set_vext_version() Daniel Henrique Barboza
                   ` (23 subsequent siblings)
  24 siblings, 0 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

The RVV verification will error out if fails and it's being done at the
end of riscv_cpu_validate_set_extensions(). Let's put it in its own
function and do it earlier.

We'll move it out of riscv_cpu_validate_set_extensions() in the near future,
but for now this is enough to clean the code a bit.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
---
 target/riscv/cpu.c | 86 ++++++++++++++++++++++++++--------------------
 1 file changed, 49 insertions(+), 37 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1e97473af2..18591aa53a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -802,6 +802,46 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
     }
 }
 
+static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
+                                 Error **errp)
+{
+    int vext_version = VEXT_VERSION_1_00_0;
+
+    if (!is_power_of_2(cfg->vlen)) {
+        error_setg(errp, "Vector extension VLEN must be power of 2");
+        return;
+    }
+    if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) {
+        error_setg(errp,
+                   "Vector extension implementation only supports VLEN "
+                   "in the range [128, %d]", RV_VLEN_MAX);
+        return;
+    }
+    if (!is_power_of_2(cfg->elen)) {
+        error_setg(errp, "Vector extension ELEN must be power of 2");
+        return;
+    }
+    if (cfg->elen > 64 || cfg->elen < 8) {
+        error_setg(errp,
+                   "Vector extension implementation only supports ELEN "
+                   "in the range [8, 64]");
+        return;
+    }
+    if (cfg->vext_spec) {
+        if (!g_strcmp0(cfg->vext_spec, "v1.0")) {
+            vext_version = VEXT_VERSION_1_00_0;
+        } else {
+            error_setg(errp, "Unsupported vector spec version '%s'",
+                       cfg->vext_spec);
+            return;
+        }
+    } else {
+        qemu_log("vector version is not specified, "
+                 "use the default value v1.0\n");
+    }
+    set_vext_version(env, vext_version);
+}
+
 /*
  * Check consistency between chosen extensions while setting
  * cpu->cfg accordingly, doing a set_misa() in the end.
@@ -809,6 +849,7 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
 static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
 {
     CPURISCVState *env = &cpu->env;
+    Error *local_err = NULL;
     uint32_t ext = 0;
 
     /* Do some ISA extension error checking */
@@ -939,6 +980,14 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
         }
     }
 
+    if (cpu->cfg.ext_v) {
+        riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
+        if (local_err != NULL) {
+            error_propagate(errp, local_err);
+            return;
+        }
+    }
+
     if (cpu->cfg.ext_zk) {
         cpu->cfg.ext_zkn = true;
         cpu->cfg.ext_zkr = true;
@@ -993,44 +1042,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
         ext |= RVH;
     }
     if (cpu->cfg.ext_v) {
-        int vext_version = VEXT_VERSION_1_00_0;
         ext |= RVV;
-        if (!is_power_of_2(cpu->cfg.vlen)) {
-            error_setg(errp,
-                       "Vector extension VLEN must be power of 2");
-            return;
-        }
-        if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) {
-            error_setg(errp,
-                       "Vector extension implementation only supports VLEN "
-                       "in the range [128, %d]", RV_VLEN_MAX);
-            return;
-        }
-        if (!is_power_of_2(cpu->cfg.elen)) {
-            error_setg(errp,
-                       "Vector extension ELEN must be power of 2");
-            return;
-        }
-        if (cpu->cfg.elen > 64 || cpu->cfg.elen < 8) {
-            error_setg(errp,
-                       "Vector extension implementation only supports ELEN "
-                       "in the range [8, 64]");
-            return;
-        }
-        if (cpu->cfg.vext_spec) {
-            if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) {
-                vext_version = VEXT_VERSION_1_00_0;
-            } else {
-                error_setg(errp,
-                           "Unsupported vector spec version '%s'",
-                           cpu->cfg.vext_spec);
-                return;
-            }
-        } else {
-            qemu_log("vector version is not specified, "
-                     "use the default value v1.0\n");
-        }
-        set_vext_version(env, vext_version);
     }
     if (cpu->cfg.ext_j) {
         ext |= RVJ;
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 02/25] target/riscv/cpu.c: remove set_vext_version()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
  2023-03-22 22:19 ` [PATCH for-8.1 v4 01/25] target/riscv/cpu.c: add riscv_cpu_validate_v() Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-22 22:19 ` [PATCH for-8.1 v4 03/25] target/riscv/cpu.c: remove set_priv_version() Daniel Henrique Barboza
                   ` (22 subsequent siblings)
  24 siblings, 0 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

This setter is doing nothing else but setting env->vext_ver. Assign the
value directly.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
---
 target/riscv/cpu.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 18591aa53a..2752efe1eb 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -245,11 +245,6 @@ static void set_priv_version(CPURISCVState *env, int priv_ver)
     env->priv_ver = priv_ver;
 }
 
-static void set_vext_version(CPURISCVState *env, int vext_ver)
-{
-    env->vext_ver = vext_ver;
-}
-
 #ifndef CONFIG_USER_ONLY
 static uint8_t satp_mode_from_str(const char *satp_mode_str)
 {
@@ -839,7 +834,7 @@ static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
         qemu_log("vector version is not specified, "
                  "use the default value v1.0\n");
     }
-    set_vext_version(env, vext_version);
+    env->vext_ver = vext_version;
 }
 
 /*
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 03/25] target/riscv/cpu.c: remove set_priv_version()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
  2023-03-22 22:19 ` [PATCH for-8.1 v4 01/25] target/riscv/cpu.c: add riscv_cpu_validate_v() Daniel Henrique Barboza
  2023-03-22 22:19 ` [PATCH for-8.1 v4 02/25] target/riscv/cpu.c: remove set_vext_version() Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-22 22:19 ` [PATCH for-8.1 v4 04/25] target/riscv: add PRIV_VERSION_LATEST Daniel Henrique Barboza
                   ` (21 subsequent siblings)
  24 siblings, 0 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

The setter is doing nothing special. Just set env->priv_ver directly.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
---
 target/riscv/cpu.c | 30 +++++++++++++-----------------
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 2752efe1eb..18032dfd4e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -240,11 +240,6 @@ static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
     env->misa_ext_mask = env->misa_ext = ext;
 }
 
-static void set_priv_version(CPURISCVState *env, int priv_ver)
-{
-    env->priv_ver = priv_ver;
-}
-
 #ifndef CONFIG_USER_ONLY
 static uint8_t satp_mode_from_str(const char *satp_mode_str)
 {
@@ -343,7 +338,7 @@ static void riscv_any_cpu_init(Object *obj)
                                     VM_1_10_SV32 : VM_1_10_SV57);
 #endif
 
-    set_priv_version(env, PRIV_VERSION_1_12_0);
+    env->priv_ver = PRIV_VERSION_1_12_0;
     register_cpu_props(obj);
 }
 
@@ -355,7 +350,7 @@ static void rv64_base_cpu_init(Object *obj)
     set_misa(env, MXL_RV64, 0);
     register_cpu_props(obj);
     /* Set latest version of privileged specification */
-    set_priv_version(env, PRIV_VERSION_1_12_0);
+    env->priv_ver = PRIV_VERSION_1_12_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
@@ -366,7 +361,7 @@ static void rv64_sifive_u_cpu_init(Object *obj)
     CPURISCVState *env = &RISCV_CPU(obj)->env;
     set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
     register_cpu_props(obj);
-    set_priv_version(env, PRIV_VERSION_1_10_0);
+    env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
 #endif
@@ -379,7 +374,7 @@ static void rv64_sifive_e_cpu_init(Object *obj)
 
     set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
     register_cpu_props(obj);
-    set_priv_version(env, PRIV_VERSION_1_10_0);
+    env->priv_ver = PRIV_VERSION_1_10_0;
     cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -392,7 +387,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
 
     set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
-    set_priv_version(env, PRIV_VERSION_1_11_0);
+    env->priv_ver = PRIV_VERSION_1_11_0;
 
     cpu->cfg.ext_g = true;
     cpu->cfg.ext_c = true;
@@ -431,7 +426,7 @@ static void rv128_base_cpu_init(Object *obj)
     set_misa(env, MXL_RV128, 0);
     register_cpu_props(obj);
     /* Set latest version of privileged specification */
-    set_priv_version(env, PRIV_VERSION_1_12_0);
+    env->priv_ver = PRIV_VERSION_1_12_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
@@ -444,7 +439,7 @@ static void rv32_base_cpu_init(Object *obj)
     set_misa(env, MXL_RV32, 0);
     register_cpu_props(obj);
     /* Set latest version of privileged specification */
-    set_priv_version(env, PRIV_VERSION_1_12_0);
+    env->priv_ver = PRIV_VERSION_1_12_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
 #endif
@@ -454,8 +449,9 @@ static void rv32_sifive_u_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
     set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+
     register_cpu_props(obj);
-    set_priv_version(env, PRIV_VERSION_1_10_0);
+    env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
 #endif
@@ -468,7 +464,7 @@ static void rv32_sifive_e_cpu_init(Object *obj)
 
     set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
     register_cpu_props(obj);
-    set_priv_version(env, PRIV_VERSION_1_10_0);
+    env->priv_ver = PRIV_VERSION_1_10_0;
     cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -482,7 +478,7 @@ static void rv32_ibex_cpu_init(Object *obj)
 
     set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
     register_cpu_props(obj);
-    set_priv_version(env, PRIV_VERSION_1_11_0);
+    env->priv_ver = PRIV_VERSION_1_11_0;
     cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -497,7 +493,7 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
 
     set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
     register_cpu_props(obj);
-    set_priv_version(env, PRIV_VERSION_1_10_0);
+    env->priv_ver = PRIV_VERSION_1_10_0;
     cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -1160,7 +1156,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
     }
 
     if (priv_version >= PRIV_VERSION_1_10_0) {
-        set_priv_version(env, priv_version);
+        env->priv_ver = priv_version;
     }
 
     /* Force disable extensions if priv spec version does not match */
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 04/25] target/riscv: add PRIV_VERSION_LATEST
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (2 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 03/25] target/riscv/cpu.c: remove set_priv_version() Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-22 22:19 ` [PATCH for-8.1 v4 05/25] target/riscv/cpu.c: add priv_spec validate/disable_exts helpers Daniel Henrique Barboza
                   ` (20 subsequent siblings)
  24 siblings, 0 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza, Richard Henderson

All these generic CPUs are using the latest priv available, at this
moment PRIV_VERSION_1_12_0:

- riscv_any_cpu_init()
- rv32_base_cpu_init()
- rv64_base_cpu_init()
- rv128_base_cpu_init()

Create a new PRIV_VERSION_LATEST enum and use it in those cases. I'll
make it easier to update everything at once when a new priv version is
available.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
---
 target/riscv/cpu.c | 8 ++++----
 target/riscv/cpu.h | 2 ++
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 18032dfd4e..1ee322001b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -338,7 +338,7 @@ static void riscv_any_cpu_init(Object *obj)
                                     VM_1_10_SV32 : VM_1_10_SV57);
 #endif
 
-    env->priv_ver = PRIV_VERSION_1_12_0;
+    env->priv_ver = PRIV_VERSION_LATEST;
     register_cpu_props(obj);
 }
 
@@ -350,7 +350,7 @@ static void rv64_base_cpu_init(Object *obj)
     set_misa(env, MXL_RV64, 0);
     register_cpu_props(obj);
     /* Set latest version of privileged specification */
-    env->priv_ver = PRIV_VERSION_1_12_0;
+    env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
@@ -426,7 +426,7 @@ static void rv128_base_cpu_init(Object *obj)
     set_misa(env, MXL_RV128, 0);
     register_cpu_props(obj);
     /* Set latest version of privileged specification */
-    env->priv_ver = PRIV_VERSION_1_12_0;
+    env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
 #endif
@@ -439,7 +439,7 @@ static void rv32_base_cpu_init(Object *obj)
     set_misa(env, MXL_RV32, 0);
     register_cpu_props(obj);
     /* Set latest version of privileged specification */
-    env->priv_ver = PRIV_VERSION_1_12_0;
+    env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
 #endif
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 638e47c75a..76f81c6b68 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -88,6 +88,8 @@ enum {
     PRIV_VERSION_1_10_0 = 0,
     PRIV_VERSION_1_11_0,
     PRIV_VERSION_1_12_0,
+
+    PRIV_VERSION_LATEST = PRIV_VERSION_1_12_0,
 };
 
 #define VEXT_VERSION_1_00_0 0x00010000
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 05/25] target/riscv/cpu.c: add priv_spec validate/disable_exts helpers
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (3 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 04/25] target/riscv: add PRIV_VERSION_LATEST Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-22 22:19 ` [PATCH for-8.1 v4 06/25] target/riscv/cpu.c: add riscv_cpu_validate_misa_mxl() Daniel Henrique Barboza
                   ` (19 subsequent siblings)
  24 siblings, 0 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

We're doing env->priv_spec validation and assignment at the start of
riscv_cpu_realize(), which is fine, but then we're doing a force disable
on extensions that aren't compatible with the priv version.

This second step is being done too early. The disabled extensions might be
re-enabled again in riscv_cpu_validate_set_extensions() by accident. A
better place to put this code is at the end of
riscv_cpu_validate_set_extensions() after all the validations are
completed.

Add a new helper, riscv_cpu_disable_priv_spec_isa_exts(), to disable the
extesions after the validation is done. While we're at it, create a
riscv_cpu_validate_priv_spec() helper to host all env->priv_spec related
validation to unclog riscv_cpu_realize a bit.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
---
 target/riscv/cpu.c | 91 ++++++++++++++++++++++++++++------------------
 1 file changed, 56 insertions(+), 35 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1ee322001b..17b301967c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -833,6 +833,52 @@ static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
     env->vext_ver = vext_version;
 }
 
+static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp)
+{
+    CPURISCVState *env = &cpu->env;
+    int priv_version = -1;
+
+    if (cpu->cfg.priv_spec) {
+        if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
+            priv_version = PRIV_VERSION_1_12_0;
+        } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
+            priv_version = PRIV_VERSION_1_11_0;
+        } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
+            priv_version = PRIV_VERSION_1_10_0;
+        } else {
+            error_setg(errp,
+                       "Unsupported privilege spec version '%s'",
+                       cpu->cfg.priv_spec);
+            return;
+        }
+
+        env->priv_ver = priv_version;
+    }
+}
+
+static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
+{
+    CPURISCVState *env = &cpu->env;
+    int i;
+
+    /* Force disable extensions if priv spec version does not match */
+    for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
+        if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) &&
+            (env->priv_ver < isa_edata_arr[i].min_version)) {
+            isa_ext_update_enabled(cpu, &isa_edata_arr[i], false);
+#ifndef CONFIG_USER_ONLY
+            warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
+                        " because privilege spec version does not match",
+                        isa_edata_arr[i].name, env->mhartid);
+#else
+            warn_report("disabling %s extension because "
+                        "privilege spec version does not match",
+                        isa_edata_arr[i].name);
+#endif
+        }
+    }
+}
+
 /*
  * Check consistency between chosen extensions while setting
  * cpu->cfg accordingly, doing a set_misa() in the end.
@@ -1002,6 +1048,12 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
         cpu->cfg.ext_zksh = true;
     }
 
+    /*
+     * Disable isa extensions based on priv spec after we
+     * validated and set everything we need.
+     */
+    riscv_cpu_disable_priv_spec_isa_exts(cpu);
+
     if (cpu->cfg.ext_i) {
         ext |= RVI;
     }
@@ -1131,7 +1183,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
     CPURISCVState *env = &cpu->env;
     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
     CPUClass *cc = CPU_CLASS(mcc);
-    int i, priv_version = -1;
     Error *local_err = NULL;
 
     cpu_exec_realizefn(cs, &local_err);
@@ -1140,40 +1191,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    if (cpu->cfg.priv_spec) {
-        if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
-            priv_version = PRIV_VERSION_1_12_0;
-        } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
-            priv_version = PRIV_VERSION_1_11_0;
-        } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
-            priv_version = PRIV_VERSION_1_10_0;
-        } else {
-            error_setg(errp,
-                       "Unsupported privilege spec version '%s'",
-                       cpu->cfg.priv_spec);
-            return;
-        }
-    }
-
-    if (priv_version >= PRIV_VERSION_1_10_0) {
-        env->priv_ver = priv_version;
-    }
-
-    /* Force disable extensions if priv spec version does not match */
-    for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
-        if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) &&
-            (env->priv_ver < isa_edata_arr[i].min_version)) {
-            isa_ext_update_enabled(cpu, &isa_edata_arr[i], false);
-#ifndef CONFIG_USER_ONLY
-            warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
-                        " because privilege spec version does not match",
-                        isa_edata_arr[i].name, env->mhartid);
-#else
-            warn_report("disabling %s extension because "
-                        "privilege spec version does not match",
-                        isa_edata_arr[i].name);
-#endif
-        }
+    riscv_cpu_validate_priv_spec(cpu, &local_err);
+    if (local_err != NULL) {
+        error_propagate(errp, local_err);
+        return;
     }
 
     if (cpu->cfg.epmp && !cpu->cfg.pmp) {
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 06/25] target/riscv/cpu.c: add riscv_cpu_validate_misa_mxl()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (4 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 05/25] target/riscv/cpu.c: add priv_spec validate/disable_exts helpers Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-23  1:35   ` LIU Zhiwei
  2023-03-22 22:19 ` [PATCH for-8.1 v4 07/25] target/riscv: move pmp and epmp validations to validate_set_extensions() Daniel Henrique Barboza
                   ` (18 subsequent siblings)
  24 siblings, 1 reply; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

Let's remove more code that is open coded in riscv_cpu_realize() and put
it into a helper. Let's also add an error message instead of just
asserting out if env->misa_mxl_max != env->misa_mlx.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 51 ++++++++++++++++++++++++++++++----------------
 1 file changed, 33 insertions(+), 18 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 17b301967c..1a298e5e55 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -879,6 +879,33 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
     }
 }
 
+static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
+{
+    RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
+    CPUClass *cc = CPU_CLASS(mcc);
+    CPURISCVState *env = &cpu->env;
+
+    /* Validate that MISA_MXL is set properly. */
+    switch (env->misa_mxl_max) {
+#ifdef TARGET_RISCV64
+    case MXL_RV64:
+    case MXL_RV128:
+        cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
+        break;
+#endif
+    case MXL_RV32:
+        cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
+        break;
+    default:
+        g_assert_not_reached();
+    }
+
+    if (env->misa_mxl_max != env->misa_mxl) {
+        error_setg(errp, "misa_mxl_max must be equal to misa_mxl");
+        return;
+    }
+}
+
 /*
  * Check consistency between chosen extensions while setting
  * cpu->cfg accordingly, doing a set_misa() in the end.
@@ -1180,9 +1207,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
 {
     CPUState *cs = CPU(dev);
     RISCVCPU *cpu = RISCV_CPU(dev);
-    CPURISCVState *env = &cpu->env;
     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
-    CPUClass *cc = CPU_CLASS(mcc);
     Error *local_err = NULL;
 
     cpu_exec_realizefn(cs, &local_err);
@@ -1197,6 +1222,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
         return;
     }
 
+    riscv_cpu_validate_misa_mxl(cpu, &local_err);
+    if (local_err != NULL) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
     if (cpu->cfg.epmp && !cpu->cfg.pmp) {
         /*
          * Enhanced PMP should only be available
@@ -1213,22 +1244,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
     }
 #endif /* CONFIG_USER_ONLY */
 
-    /* Validate that MISA_MXL is set properly. */
-    switch (env->misa_mxl_max) {
-#ifdef TARGET_RISCV64
-    case MXL_RV64:
-    case MXL_RV128:
-        cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
-        break;
-#endif
-    case MXL_RV32:
-        cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
-        break;
-    default:
-        g_assert_not_reached();
-    }
-    assert(env->misa_mxl_max == env->misa_mxl);
-
     riscv_cpu_validate_set_extensions(cpu, &local_err);
     if (local_err != NULL) {
         error_propagate(errp, local_err);
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 07/25] target/riscv: move pmp and epmp validations to validate_set_extensions()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (5 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 06/25] target/riscv/cpu.c: add riscv_cpu_validate_misa_mxl() Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-23  1:42   ` LIU Zhiwei
  2023-03-22 22:19 ` [PATCH for-8.1 v4 08/25] target/riscv/cpu.c: validate extensions before riscv_timer_init() Daniel Henrique Barboza
                   ` (17 subsequent siblings)
  24 siblings, 1 reply; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

In the near future, write_misa() will use a variation of what we have
now as riscv_cpu_validate_set_extensions(). The pmp and epmp validation
will be required in write_misa() and it's already required here in
riscv_cpu_realize(), so move it to riscv_cpu_validate_set_extensions().

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1a298e5e55..7458845fec 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -916,6 +916,15 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
     Error *local_err = NULL;
     uint32_t ext = 0;
 
+    if (cpu->cfg.epmp && !cpu->cfg.pmp) {
+        /*
+         * Enhanced PMP should only be available
+         * on harts with PMP support
+         */
+        error_setg(errp, "Invalid configuration: EPMP requires PMP support");
+        return;
+    }
+
     /* Do some ISA extension error checking */
     if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
                             cpu->cfg.ext_a && cpu->cfg.ext_f &&
@@ -1228,16 +1237,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    if (cpu->cfg.epmp && !cpu->cfg.pmp) {
-        /*
-         * Enhanced PMP should only be available
-         * on harts with PMP support
-         */
-        error_setg(errp, "Invalid configuration: EPMP requires PMP support");
-        return;
-    }
-
-
 #ifndef CONFIG_USER_ONLY
     if (cpu->cfg.ext_sstc) {
         riscv_timer_init(cpu);
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 08/25] target/riscv/cpu.c: validate extensions before riscv_timer_init()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (6 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 07/25] target/riscv: move pmp and epmp validations to validate_set_extensions() Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-23  1:52   ` LIU Zhiwei
  2023-03-22 22:19 ` [PATCH for-8.1 v4 09/25] target/riscv/cpu.c: remove cfg setup from riscv_cpu_init() Daniel Henrique Barboza
                   ` (16 subsequent siblings)
  24 siblings, 1 reply; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

There is no need to init timers if we're not even sure that our
extensions are valid. Execute riscv_cpu_validate_set_extensions() before
riscv_timer_init().

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7458845fec..fef55d7d79 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1237,12 +1237,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-#ifndef CONFIG_USER_ONLY
-    if (cpu->cfg.ext_sstc) {
-        riscv_timer_init(cpu);
-    }
-#endif /* CONFIG_USER_ONLY */
-
     riscv_cpu_validate_set_extensions(cpu, &local_err);
     if (local_err != NULL) {
         error_propagate(errp, local_err);
@@ -1250,6 +1244,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
     }
 
 #ifndef CONFIG_USER_ONLY
+    if (cpu->cfg.ext_sstc) {
+        riscv_timer_init(cpu);
+    }
+
     if (cpu->cfg.pmu_num) {
         if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) {
             cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 09/25] target/riscv/cpu.c: remove cfg setup from riscv_cpu_init()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (7 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 08/25] target/riscv/cpu.c: validate extensions before riscv_timer_init() Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-23  2:02   ` LIU Zhiwei
  2023-03-22 22:19 ` [PATCH for-8.1 v4 10/25] target/riscv/cpu.c: avoid set_misa() in validate_set_extensions() Daniel Henrique Barboza
                   ` (15 subsequent siblings)
  24 siblings, 1 reply; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

We have 4 config settings being done in riscv_cpu_init(): ext_ifencei,
ext_icsr, mmu and pmp. This is also the constructor of the "riscv-cpu"
device, which happens to be the parent device of every RISC-V cpu.

The result is that these 4 configs are being set every time, and every
other CPU should always account for them. CPUs such as sifive_e need to
disable settings that aren't enabled simply because the parent class
happens to be enabling it.

Moving all configurations from the parent class to each CPU will
centralize the config of each CPU into its own init(), which is clearer
than having to account to whatever happens to be set in the parent
device. These settings are also being set in register_cpu_props() when
no 'misa_ext' is set, so for these CPUs we don't need changes. Named
CPUs will receive all cfgs that the parent were setting into their
init().

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 60 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 48 insertions(+), 12 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index fef55d7d79..c7b6e7b84b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -325,7 +325,8 @@ static void set_satp_mode_default_map(RISCVCPU *cpu)
 
 static void riscv_any_cpu_init(Object *obj)
 {
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
+    RISCVCPU *cpu = RISCV_CPU(obj);
+    CPURISCVState *env = &cpu->env;
 #if defined(TARGET_RISCV32)
     set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
 #elif defined(TARGET_RISCV64)
@@ -340,6 +341,12 @@ static void riscv_any_cpu_init(Object *obj)
 
     env->priv_ver = PRIV_VERSION_LATEST;
     register_cpu_props(obj);
+
+    /* inherited from parent obj via riscv_cpu_init() */
+    cpu->cfg.ext_ifencei = true;
+    cpu->cfg.ext_icsr = true;
+    cpu->cfg.mmu = true;
+    cpu->cfg.pmp = true;
 }
 
 #if defined(TARGET_RISCV64)
@@ -358,13 +365,20 @@ static void rv64_base_cpu_init(Object *obj)
 
 static void rv64_sifive_u_cpu_init(Object *obj)
 {
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
+    RISCVCPU *cpu = RISCV_CPU(obj);
+    CPURISCVState *env = &cpu->env;
     set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
     register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
 #endif
+
+    /* inherited from parent obj via riscv_cpu_init() */
+    cpu->cfg.ext_ifencei = true;
+    cpu->cfg.ext_icsr = true;
+    cpu->cfg.mmu = true;
+    cpu->cfg.pmp = true;
 }
 
 static void rv64_sifive_e_cpu_init(Object *obj)
@@ -375,10 +389,14 @@ static void rv64_sifive_e_cpu_init(Object *obj)
     set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
     register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_10_0;
-    cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
 #endif
+
+    /* inherited from parent obj via riscv_cpu_init() */
+    cpu->cfg.ext_ifencei = true;
+    cpu->cfg.ext_icsr = true;
+    cpu->cfg.pmp = true;
 }
 
 static void rv64_thead_c906_cpu_init(Object *obj)
@@ -411,6 +429,10 @@ static void rv64_thead_c906_cpu_init(Object *obj)
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_SV39);
 #endif
+
+    /* inherited from parent obj via riscv_cpu_init() */
+    cpu->cfg.ext_ifencei = true;
+    cpu->cfg.pmp = true;
 }
 
 static void rv128_base_cpu_init(Object *obj)
@@ -447,7 +469,8 @@ static void rv32_base_cpu_init(Object *obj)
 
 static void rv32_sifive_u_cpu_init(Object *obj)
 {
-    CPURISCVState *env = &RISCV_CPU(obj)->env;
+    RISCVCPU *cpu = RISCV_CPU(obj);
+    CPURISCVState *env = &cpu->env;
     set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
 
     register_cpu_props(obj);
@@ -455,6 +478,12 @@ static void rv32_sifive_u_cpu_init(Object *obj)
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
 #endif
+
+    /* inherited from parent obj via riscv_cpu_init() */
+    cpu->cfg.ext_ifencei = true;
+    cpu->cfg.ext_icsr = true;
+    cpu->cfg.mmu = true;
+    cpu->cfg.pmp = true;
 }
 
 static void rv32_sifive_e_cpu_init(Object *obj)
@@ -465,10 +494,14 @@ static void rv32_sifive_e_cpu_init(Object *obj)
     set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
     register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_10_0;
-    cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
 #endif
+
+    /* inherited from parent obj via riscv_cpu_init() */
+    cpu->cfg.ext_ifencei = true;
+    cpu->cfg.ext_icsr = true;
+    cpu->cfg.pmp = true;
 }
 
 static void rv32_ibex_cpu_init(Object *obj)
@@ -479,11 +512,15 @@ static void rv32_ibex_cpu_init(Object *obj)
     set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
     register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_11_0;
-    cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
 #endif
     cpu->cfg.epmp = true;
+
+    /* inherited from parent obj via riscv_cpu_init() */
+    cpu->cfg.ext_ifencei = true;
+    cpu->cfg.ext_icsr = true;
+    cpu->cfg.pmp = true;
 }
 
 static void rv32_imafcu_nommu_cpu_init(Object *obj)
@@ -494,10 +531,14 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
     set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
     register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_10_0;
-    cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
 #endif
+
+    /* inherited from parent obj via riscv_cpu_init() */
+    cpu->cfg.ext_ifencei = true;
+    cpu->cfg.ext_icsr = true;
+    cpu->cfg.pmp = true;
 }
 #endif
 
@@ -1384,11 +1425,6 @@ static void riscv_cpu_init(Object *obj)
 {
     RISCVCPU *cpu = RISCV_CPU(obj);
 
-    cpu->cfg.ext_ifencei = true;
-    cpu->cfg.ext_icsr = true;
-    cpu->cfg.mmu = true;
-    cpu->cfg.pmp = true;
-
     cpu_set_cpustate_pointers(cpu);
 
 #ifndef CONFIG_USER_ONLY
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 10/25] target/riscv/cpu.c: avoid set_misa() in validate_set_extensions()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (8 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 09/25] target/riscv/cpu.c: remove cfg setup from riscv_cpu_init() Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-23  2:04   ` LIU Zhiwei
  2023-03-22 22:19 ` [PATCH for-8.1 v4 11/25] target/riscv/cpu.c: set cpu config in set_misa() Daniel Henrique Barboza
                   ` (14 subsequent siblings)
  24 siblings, 1 reply; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

set_misa() will be tuned up to do more than it's already doing and it
will be redundant to what riscv_cpu_validate_set_extensions() does.

Note that we don't ever change env->misa_mlx in this function, so
set_misa() can be replaced by just assigning env->misa_ext and
env->misa_ext_mask to 'ext'.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c7b6e7b84b..36c55abda0 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -949,7 +949,8 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
 
 /*
  * Check consistency between chosen extensions while setting
- * cpu->cfg accordingly, doing a set_misa() in the end.
+ * cpu->cfg accordingly, setting env->misa_ext and
+ * misa_ext_mask in the end.
  */
 static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
 {
@@ -1168,7 +1169,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
         ext |= RVJ;
     }
 
-    set_misa(env, env->misa_mxl, ext);
+    env->misa_ext_mask = env->misa_ext = ext;
 }
 
 #ifndef CONFIG_USER_ONLY
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 11/25] target/riscv/cpu.c: set cpu config in set_misa()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (9 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 10/25] target/riscv/cpu.c: avoid set_misa() in validate_set_extensions() Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-23  2:14   ` LIU Zhiwei
  2023-03-22 22:19 ` [PATCH for-8.1 v4 12/25] target/riscv/cpu.c: redesign register_cpu_props() Daniel Henrique Barboza
                   ` (13 subsequent siblings)
  24 siblings, 1 reply; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

set_misa() is setting all 'misa' related env states and nothing else.
But other functions, namely riscv_cpu_validate_set_extensions(), uses
the config object to do its job.

This creates a need to set the single letter extensions in the cfg
object to keep both in sync. At this moment this is being done by
register_cpu_props(), forcing every CPU to do a call to this function.

Let's beef up set_misa() and make the function do the sync for us. This
will relieve named CPUs to having to call register_cpu_props(), which
will then be redesigned to a more specialized role next.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 43 ++++++++++++++++++++++++++++++++-----------
 target/riscv/cpu.h |  4 ++--
 2 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 36c55abda0..df5c0bda70 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -236,8 +236,40 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
 
 static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
 {
+    RISCVCPU *cpu;
+
     env->misa_mxl_max = env->misa_mxl = mxl;
     env->misa_ext_mask = env->misa_ext = ext;
+
+    /*
+     * ext = 0 will only be a thing during cpu_init() functions
+     * as a way of setting an extension-agnostic CPU. We do
+     * not support clearing misa_ext* and the ext_N flags in
+     * RISCVCPUConfig in regular circunstances.
+     */
+    if (ext == 0) {
+        return;
+    }
+
+    /*
+     * We can't use riscv_cpu_cfg() in this case because it is
+     * a read-only inline and we're going to change the values
+     * of cpu->cfg.
+     */
+    cpu = env_archcpu(env);
+
+    cpu->cfg.ext_i = ext & RVI;
+    cpu->cfg.ext_e = ext & RVE;
+    cpu->cfg.ext_m = ext & RVM;
+    cpu->cfg.ext_a = ext & RVA;
+    cpu->cfg.ext_f = ext & RVF;
+    cpu->cfg.ext_d = ext & RVD;
+    cpu->cfg.ext_v = ext & RVV;
+    cpu->cfg.ext_c = ext & RVC;
+    cpu->cfg.ext_s = ext & RVS;
+    cpu->cfg.ext_u = ext & RVU;
+    cpu->cfg.ext_h = ext & RVH;
+    cpu->cfg.ext_j = ext & RVJ;
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -340,7 +372,6 @@ static void riscv_any_cpu_init(Object *obj)
 #endif
 
     env->priv_ver = PRIV_VERSION_LATEST;
-    register_cpu_props(obj);
 
     /* inherited from parent obj via riscv_cpu_init() */
     cpu->cfg.ext_ifencei = true;
@@ -368,7 +399,6 @@ static void rv64_sifive_u_cpu_init(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
     CPURISCVState *env = &cpu->env;
     set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
-    register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
@@ -387,7 +417,6 @@ static void rv64_sifive_e_cpu_init(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
 
     set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
-    register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -408,9 +437,6 @@ static void rv64_thead_c906_cpu_init(Object *obj)
     env->priv_ver = PRIV_VERSION_1_11_0;
 
     cpu->cfg.ext_g = true;
-    cpu->cfg.ext_c = true;
-    cpu->cfg.ext_u = true;
-    cpu->cfg.ext_s = true;
     cpu->cfg.ext_icsr = true;
     cpu->cfg.ext_zfh = true;
     cpu->cfg.mmu = true;
@@ -472,8 +498,6 @@ static void rv32_sifive_u_cpu_init(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
     CPURISCVState *env = &cpu->env;
     set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
-
-    register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
@@ -492,7 +516,6 @@ static void rv32_sifive_e_cpu_init(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
 
     set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
-    register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -510,7 +533,6 @@ static void rv32_ibex_cpu_init(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
 
     set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
-    register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_11_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
@@ -529,7 +551,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
 
     set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
-    register_cpu_props(obj);
     env->priv_ver = PRIV_VERSION_1_10_0;
 #ifndef CONFIG_USER_ONLY
     set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 76f81c6b68..ebe0fff668 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -66,8 +66,8 @@
 #define RV(x) ((target_ulong)1 << (x - 'A'))
 
 /*
- * Consider updating register_cpu_props() when adding
- * new MISA bits here.
+ * Consider updating set_misa() when adding new
+ * MISA bits here.
  */
 #define RVI RV('I')
 #define RVE RV('E') /* E and I are mutually exclusive */
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 12/25] target/riscv/cpu.c: redesign register_cpu_props()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (10 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 11/25] target/riscv/cpu.c: set cpu config in set_misa() Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-23  3:22   ` LIU Zhiwei
  2023-03-22 22:19 ` [PATCH for-8.1 v4 13/25] target/riscv: put env->misa_ext <-> cpu->cfg code into helpers Daniel Henrique Barboza
                   ` (12 subsequent siblings)
  24 siblings, 1 reply; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

Now that the function is a no-op if 'env.misa_ext != 0', and no one that
are setting misa_ext != 0 is calling it because set_misa() is setting
the cpu cfg accordingly, remove the now deprecated code and rename the
function to register_generic_cpu_props().

This function is now doing exactly what the name says: it is creating
user-facing properties to allow changes in the CPU cfg via the QEMU
command line, setting default values if no user input is provided.

Note that there's the possibility of a CPU to set a certain misa value
and, at the same, also want user-facing flags and defaults from this
function. This is not the case since commit 26b2bc58599c ("target/riscv:
Don't expose the CPU properties on names CPUs"), but given that this is
also a possibility, clarify in the function that using this function
will overwrite existing values in cpu->cfg.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 48 ++++++++++------------------------------------
 1 file changed, 10 insertions(+), 38 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index df5c0bda70..0e56a1c01f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -221,7 +221,7 @@ static const char * const riscv_intr_names[] = {
     "reserved"
 };
 
-static void register_cpu_props(Object *obj);
+static void register_generic_cpu_props(Object *obj);
 
 const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
 {
@@ -386,7 +386,7 @@ static void rv64_base_cpu_init(Object *obj)
     CPURISCVState *env = &RISCV_CPU(obj)->env;
     /* We set this in the realise function */
     set_misa(env, MXL_RV64, 0);
-    register_cpu_props(obj);
+    register_generic_cpu_props(obj);
     /* Set latest version of privileged specification */
     env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
@@ -472,7 +472,7 @@ static void rv128_base_cpu_init(Object *obj)
     CPURISCVState *env = &RISCV_CPU(obj)->env;
     /* We set this in the realise function */
     set_misa(env, MXL_RV128, 0);
-    register_cpu_props(obj);
+    register_generic_cpu_props(obj);
     /* Set latest version of privileged specification */
     env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
@@ -485,7 +485,7 @@ static void rv32_base_cpu_init(Object *obj)
     CPURISCVState *env = &RISCV_CPU(obj)->env;
     /* We set this in the realise function */
     set_misa(env, MXL_RV32, 0);
-    register_cpu_props(obj);
+    register_generic_cpu_props(obj);
     /* Set latest version of privileged specification */
     env->priv_ver = PRIV_VERSION_LATEST;
 #ifndef CONFIG_USER_ONLY
@@ -572,7 +572,7 @@ static void riscv_host_cpu_init(Object *obj)
 #elif defined(TARGET_RISCV64)
     set_misa(env, MXL_RV64, 0);
 #endif
-    register_cpu_props(obj);
+    register_generic_cpu_props(obj);
 }
 #endif
 
@@ -1554,44 +1554,16 @@ static Property riscv_cpu_extensions[] = {
 };
 
 /*
- * Register CPU props based on env.misa_ext. If a non-zero
- * value was set, register only the required cpu->cfg.ext_*
- * properties and leave. env.misa_ext = 0 means that we want
- * all the default properties to be registered.
+ * Register generic CPU props with user-facing flags declared
+ * in riscv_cpu_extensions[].
+ *
+ * Note that this will overwrite existing values in cpu->cfg.
  */
-static void register_cpu_props(Object *obj)
+static void register_generic_cpu_props(Object *obj)
 {
-    RISCVCPU *cpu = RISCV_CPU(obj);
-    uint32_t misa_ext = cpu->env.misa_ext;
     Property *prop;
     DeviceState *dev = DEVICE(obj);
 
-    /*
-     * If misa_ext is not zero, set cfg properties now to
-     * allow them to be read during riscv_cpu_realize()
-     * later on.
-     */
-    if (cpu->env.misa_ext != 0) {
-        cpu->cfg.ext_i = misa_ext & RVI;
-        cpu->cfg.ext_e = misa_ext & RVE;
-        cpu->cfg.ext_m = misa_ext & RVM;
-        cpu->cfg.ext_a = misa_ext & RVA;
-        cpu->cfg.ext_f = misa_ext & RVF;
-        cpu->cfg.ext_d = misa_ext & RVD;
-        cpu->cfg.ext_v = misa_ext & RVV;
-        cpu->cfg.ext_c = misa_ext & RVC;
-        cpu->cfg.ext_s = misa_ext & RVS;
-        cpu->cfg.ext_u = misa_ext & RVU;
-        cpu->cfg.ext_h = misa_ext & RVH;
-        cpu->cfg.ext_j = misa_ext & RVJ;
-
-        /*
-         * We don't want to set the default riscv_cpu_extensions
-         * in this case.
-         */
-        return;
-    }
-
     for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
         qdev_property_add_static(dev, prop);
     }
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 13/25] target/riscv: put env->misa_ext <-> cpu->cfg code into helpers
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (11 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 12/25] target/riscv/cpu.c: redesign register_cpu_props() Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-22 22:19 ` [PATCH for-8.1 v4 14/25] target/riscv: add RVG Daniel Henrique Barboza
                   ` (11 subsequent siblings)
  24 siblings, 0 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

The extremely tedious code that sets cpu->cfg based on misa_ext, and
vice-versa, is scattered around riscv_cpu_validate_set_extensions() and
set_misa().

Introduce helpers to do this work, cleaning up the logic of both
functions a bit. While we're at it, add a note in cpu.h informing that
any future change in MISA RV* bits should also be reflected in the
helpers as well.

We'll want to keep env->misa_ext changes in sync with cpu->cfg during
realize() in the next patches, and both helpers will have a role to play
in that.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 120 ++++++++++++++++++++++++---------------------
 target/riscv/cpu.h |   3 +-
 2 files changed, 65 insertions(+), 58 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0e56a1c01f..c4f18d0436 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -234,10 +234,69 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
     }
 }
 
-static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
+static uint32_t riscv_get_misa_ext_with_cpucfg(RISCVCPUConfig *cfg)
 {
-    RISCVCPU *cpu;
+    uint32_t ext = 0;
 
+    if (cfg->ext_i) {
+        ext |= RVI;
+    }
+    if (cfg->ext_e) {
+        ext |= RVE;
+    }
+    if (cfg->ext_m) {
+        ext |= RVM;
+    }
+    if (cfg->ext_a) {
+        ext |= RVA;
+    }
+    if (cfg->ext_f) {
+        ext |= RVF;
+    }
+    if (cfg->ext_d) {
+        ext |= RVD;
+    }
+    if (cfg->ext_c) {
+        ext |= RVC;
+    }
+    if (cfg->ext_s) {
+        ext |= RVS;
+    }
+    if (cfg->ext_u) {
+        ext |= RVU;
+    }
+    if (cfg->ext_h) {
+        ext |= RVH;
+    }
+    if (cfg->ext_v) {
+        ext |= RVV;
+    }
+    if (cfg->ext_j) {
+        ext |= RVJ;
+    }
+
+    return ext;
+}
+
+static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg,
+                                       uint32_t misa_ext)
+{
+    cfg->ext_i = misa_ext & RVI;
+    cfg->ext_e = misa_ext & RVE;
+    cfg->ext_m = misa_ext & RVM;
+    cfg->ext_a = misa_ext & RVA;
+    cfg->ext_f = misa_ext & RVF;
+    cfg->ext_d = misa_ext & RVD;
+    cfg->ext_v = misa_ext & RVV;
+    cfg->ext_c = misa_ext & RVC;
+    cfg->ext_s = misa_ext & RVS;
+    cfg->ext_u = misa_ext & RVU;
+    cfg->ext_h = misa_ext & RVH;
+    cfg->ext_j = misa_ext & RVJ;
+}
+
+static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
+{
     env->misa_mxl_max = env->misa_mxl = mxl;
     env->misa_ext_mask = env->misa_ext = ext;
 
@@ -251,25 +310,7 @@ static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
         return;
     }
 
-    /*
-     * We can't use riscv_cpu_cfg() in this case because it is
-     * a read-only inline and we're going to change the values
-     * of cpu->cfg.
-     */
-    cpu = env_archcpu(env);
-
-    cpu->cfg.ext_i = ext & RVI;
-    cpu->cfg.ext_e = ext & RVE;
-    cpu->cfg.ext_m = ext & RVM;
-    cpu->cfg.ext_a = ext & RVA;
-    cpu->cfg.ext_f = ext & RVF;
-    cpu->cfg.ext_d = ext & RVD;
-    cpu->cfg.ext_v = ext & RVV;
-    cpu->cfg.ext_c = ext & RVC;
-    cpu->cfg.ext_s = ext & RVS;
-    cpu->cfg.ext_u = ext & RVU;
-    cpu->cfg.ext_h = ext & RVH;
-    cpu->cfg.ext_j = ext & RVJ;
+    riscv_set_cpucfg_with_misa(&env_archcpu(env)->cfg, ext);
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -1153,42 +1194,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
      */
     riscv_cpu_disable_priv_spec_isa_exts(cpu);
 
-    if (cpu->cfg.ext_i) {
-        ext |= RVI;
-    }
-    if (cpu->cfg.ext_e) {
-        ext |= RVE;
-    }
-    if (cpu->cfg.ext_m) {
-        ext |= RVM;
-    }
-    if (cpu->cfg.ext_a) {
-        ext |= RVA;
-    }
-    if (cpu->cfg.ext_f) {
-        ext |= RVF;
-    }
-    if (cpu->cfg.ext_d) {
-        ext |= RVD;
-    }
-    if (cpu->cfg.ext_c) {
-        ext |= RVC;
-    }
-    if (cpu->cfg.ext_s) {
-        ext |= RVS;
-    }
-    if (cpu->cfg.ext_u) {
-        ext |= RVU;
-    }
-    if (cpu->cfg.ext_h) {
-        ext |= RVH;
-    }
-    if (cpu->cfg.ext_v) {
-        ext |= RVV;
-    }
-    if (cpu->cfg.ext_j) {
-        ext |= RVJ;
-    }
+    ext = riscv_get_misa_ext_with_cpucfg(&cpu->cfg);
 
     env->misa_ext_mask = env->misa_ext = ext;
 }
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index ebe0fff668..2263629332 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -66,7 +66,8 @@
 #define RV(x) ((target_ulong)1 << (x - 'A'))
 
 /*
- * Consider updating set_misa() when adding new
+ * Consider updating riscv_get_misa_ext_with_cpucfg()
+ * and riscv_set_cpucfg_with_misa() when adding new
  * MISA bits here.
  */
 #define RVI RV('I')
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 14/25] target/riscv: add RVG
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (12 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 13/25] target/riscv: put env->misa_ext <-> cpu->cfg code into helpers Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-24 14:43   ` liweiwei
  2023-03-22 22:19 ` [PATCH for-8.1 v4 15/25] target/riscv/cpu.c: split RVG code from validate_set_extensions() Daniel Henrique Barboza
                   ` (10 subsequent siblings)
  24 siblings, 1 reply; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

The 'G' bit in misa_ext is a virtual extension that enables a set of
extensions (i, m, a, f, d, icsr and ifencei). We're already have code to
handle it but no bit definition. Add it.

Add RVG to set_misa() in rv64_thead_c906_cpu_init() and remove the
manual cpu->cfg.ext_g assignment while we're at it.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 8 ++++++--
 target/riscv/cpu.h | 1 +
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c4f18d0436..f41888baa0 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -274,6 +274,9 @@ static uint32_t riscv_get_misa_ext_with_cpucfg(RISCVCPUConfig *cfg)
     if (cfg->ext_j) {
         ext |= RVJ;
     }
+    if (cfg->ext_g) {
+        ext |= RVG;
+    }
 
     return ext;
 }
@@ -293,6 +296,7 @@ static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg,
     cfg->ext_u = misa_ext & RVU;
     cfg->ext_h = misa_ext & RVH;
     cfg->ext_j = misa_ext & RVJ;
+    cfg->ext_g = misa_ext & RVG;
 }
 
 static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
@@ -474,10 +478,10 @@ static void rv64_thead_c906_cpu_init(Object *obj)
     CPURISCVState *env = &RISCV_CPU(obj)->env;
     RISCVCPU *cpu = RISCV_CPU(obj);
 
-    set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+    set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD |
+                            RVC | RVS | RVU | RVG);
     env->priv_ver = PRIV_VERSION_1_11_0;
 
-    cpu->cfg.ext_g = true;
     cpu->cfg.ext_icsr = true;
     cpu->cfg.ext_zfh = true;
     cpu->cfg.mmu = true;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 2263629332..dbb4df9df0 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -82,6 +82,7 @@
 #define RVU RV('U')
 #define RVH RV('H')
 #define RVJ RV('J')
+#define RVG RV('G')
 
 
 /* Privileged specification version */
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 15/25] target/riscv/cpu.c: split RVG code from validate_set_extensions()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (13 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 14/25] target/riscv: add RVG Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-24 14:47   ` liweiwei
  2023-03-22 22:19 ` [PATCH for-8.1 v4 16/25] target/riscv/cpu.c: add riscv_cpu_validate_misa_ext() Daniel Henrique Barboza
                   ` (9 subsequent siblings)
  24 siblings, 1 reply; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

We can set all RVG related extensions during realize time, before
validate_set_extensions() itself. Put it in a separated function so the
validate function already uses the updated state.

Note that we're setting both cfg->ext_N and env->misa_ext bits, instead
of just setting cfg->ext_N. The intention here is to start syncing all
misa_ext operations with its cpu->cfg flags, in preparation to allow for
the validate function to operate using a misa_ext. This doesn't make any
difference for the current code state, but will be a requirement for
write_misa() later on.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 60 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 45 insertions(+), 15 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index f41888baa0..a7bad518be 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -281,6 +281,36 @@ static uint32_t riscv_get_misa_ext_with_cpucfg(RISCVCPUConfig *cfg)
     return ext;
 }
 
+static void riscv_cpu_enable_g(RISCVCPU *cpu, Error **errp)
+{
+    CPURISCVState *env = &cpu->env;
+    RISCVCPUConfig *cfg = &cpu->cfg;
+
+    if (!(cfg->ext_i && cfg->ext_m && cfg->ext_a &&
+          cfg->ext_f && cfg->ext_d &&
+          cfg->ext_icsr && cfg->ext_ifencei)) {
+
+        warn_report("Setting G will also set IMAFD_Zicsr_Zifencei");
+        cfg->ext_i = true;
+        env->misa_ext |= RVI;
+
+        cfg->ext_m = true;
+        env->misa_ext |= RVM;
+
+        cfg->ext_a = true;
+        env->misa_ext |= RVA;
+
+        cfg->ext_f = true;
+        env->misa_ext |= RVF;
+
+        cfg->ext_d = true;
+        env->misa_ext |= RVD;
+
+        cfg->ext_icsr = true;
+        cfg->ext_ifencei = true;
+    }
+}
+
 static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg,
                                        uint32_t misa_ext)
 {
@@ -1033,21 +1063,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
         return;
     }
 
-    /* Do some ISA extension error checking */
-    if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
-                            cpu->cfg.ext_a && cpu->cfg.ext_f &&
-                            cpu->cfg.ext_d &&
-                            cpu->cfg.ext_icsr && cpu->cfg.ext_ifencei)) {
-        warn_report("Setting G will also set IMAFD_Zicsr_Zifencei");
-        cpu->cfg.ext_i = true;
-        cpu->cfg.ext_m = true;
-        cpu->cfg.ext_a = true;
-        cpu->cfg.ext_f = true;
-        cpu->cfg.ext_d = true;
-        cpu->cfg.ext_icsr = true;
-        cpu->cfg.ext_ifencei = true;
-    }
-
     if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
         error_setg(errp,
                    "I and E extensions are incompatible");
@@ -1290,6 +1305,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
     CPUState *cs = CPU(dev);
     RISCVCPU *cpu = RISCV_CPU(dev);
     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
+    CPURISCVState *env = &cpu->env;
     Error *local_err = NULL;
 
     cpu_exec_realizefn(cs, &local_err);
@@ -1310,6 +1326,20 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
         return;
     }
 
+    if (cpu->cfg.ext_g) {
+        riscv_cpu_enable_g(cpu, &local_err);
+        if (local_err != NULL) {
+            error_propagate(errp, local_err);
+            return;
+        }
+
+        /*
+         * Sync env->misa_ext_mask with the new
+         * env->misa_ext val.
+         */
+        env->misa_ext_mask = env->misa_ext;
+    }
+
     riscv_cpu_validate_set_extensions(cpu, &local_err);
     if (local_err != NULL) {
         error_propagate(errp, local_err);
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 16/25] target/riscv/cpu.c: add riscv_cpu_validate_misa_ext()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (14 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 15/25] target/riscv/cpu.c: split RVG code from validate_set_extensions() Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-22 22:19 ` [PATCH for-8.1 v4 17/25] target/riscv: move riscv_cpu_validate_v() to validate_misa_ext() Daniel Henrique Barboza
                   ` (8 subsequent siblings)
  24 siblings, 0 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

Even after taking RVG off from riscv_cpu_validate_set_extensions(), the
function is still doing too much. It is validating misa bits, then
validating named extensions, and if the validation succeeds it's doing
more changes in both cpu->cfg and MISA bits.

It works for the support we have today, since we'll error out during
realize() time. This is not enough to support write_misa() though - we
don't want to error out if userspace writes something odd in the CSR.

This patch starts splitting riscv_cpu_validate_set_extensions() into a
three step process: validate misa_ext, validate cpu->cfg, then commit
the configuration. This separation will allow us to use these functions
in write_misa() without having to worry about saving CPU state during
runtime because the function changed state but failed to validate.

riscv_cpu_validate_misa_ext() will host all validations related to misa
bits only. Validations using misa bits + name extensions will remain in
validate_set_extensions().

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 77 ++++++++++++++++++++++++++--------------------
 1 file changed, 43 insertions(+), 34 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a7bad518be..f9710dd786 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1016,6 +1016,43 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
     }
 }
 
+static void riscv_cpu_validate_misa_ext(RISCVCPU *cpu, Error **errp)
+{
+    if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
+        error_setg(errp,
+                   "I and E extensions are incompatible");
+        return;
+    }
+
+    if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) {
+        error_setg(errp,
+                   "Either I or E extension must be set");
+        return;
+    }
+
+    if (cpu->cfg.ext_s && !cpu->cfg.ext_u) {
+        error_setg(errp,
+                   "Setting S extension without U extension is illegal");
+        return;
+    }
+
+    if (cpu->cfg.ext_h && !cpu->cfg.ext_i) {
+        error_setg(errp,
+                   "H depends on an I base integer ISA with 32 x registers");
+        return;
+    }
+
+    if (cpu->cfg.ext_h && !cpu->cfg.ext_s) {
+        error_setg(errp, "H extension implicitly requires S-mode");
+        return;
+    }
+
+    if (cpu->cfg.ext_d && !cpu->cfg.ext_f) {
+        error_setg(errp, "D extension requires F extension");
+        return;
+    }
+}
+
 static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
 {
     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
@@ -1063,35 +1100,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
         return;
     }
 
-    if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
-        error_setg(errp,
-                   "I and E extensions are incompatible");
-        return;
-    }
-
-    if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) {
-        error_setg(errp,
-                   "Either I or E extension must be set");
-        return;
-    }
-
-    if (cpu->cfg.ext_s && !cpu->cfg.ext_u) {
-        error_setg(errp,
-                   "Setting S extension without U extension is illegal");
-        return;
-    }
-
-    if (cpu->cfg.ext_h && !cpu->cfg.ext_i) {
-        error_setg(errp,
-                   "H depends on an I base integer ISA with 32 x registers");
-        return;
-    }
-
-    if (cpu->cfg.ext_h && !cpu->cfg.ext_s) {
-        error_setg(errp, "H extension implicitly requires S-mode");
-        return;
-    }
-
     if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) {
         error_setg(errp, "F extension requires Zicsr");
         return;
@@ -1111,11 +1119,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
         return;
     }
 
-    if (cpu->cfg.ext_d && !cpu->cfg.ext_f) {
-        error_setg(errp, "D extension requires F extension");
-        return;
-    }
-
     /* The V vector extension depends on the Zve64d extension */
     if (cpu->cfg.ext_v) {
         cpu->cfg.ext_zve64d = true;
@@ -1340,6 +1343,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
         env->misa_ext_mask = env->misa_ext;
     }
 
+    riscv_cpu_validate_misa_ext(cpu, &local_err);
+    if (local_err != NULL) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
     riscv_cpu_validate_set_extensions(cpu, &local_err);
     if (local_err != NULL) {
         error_propagate(errp, local_err);
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 17/25] target/riscv: move riscv_cpu_validate_v() to validate_misa_ext()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (15 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 16/25] target/riscv/cpu.c: add riscv_cpu_validate_misa_ext() Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-22 22:19 ` [PATCH for-8.1 v4 18/25] target/riscv: error out on priv failure for RVH Daniel Henrique Barboza
                   ` (7 subsequent siblings)
  24 siblings, 0 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

riscv_cpu_validate_v() consists of checking RVV related attributes, such
as vlen and elen, and setting env->vext_spec.

This can be done during riscv_cpu_validate_misa_ext() time, allowing us
to fail earlier if RVV constrains are not met.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index f9710dd786..399f63b42f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1018,6 +1018,9 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
 
 static void riscv_cpu_validate_misa_ext(RISCVCPU *cpu, Error **errp)
 {
+    CPURISCVState *env = &cpu->env;
+    Error *local_err = NULL;
+
     if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
         error_setg(errp,
                    "I and E extensions are incompatible");
@@ -1051,6 +1054,14 @@ static void riscv_cpu_validate_misa_ext(RISCVCPU *cpu, Error **errp)
         error_setg(errp, "D extension requires F extension");
         return;
     }
+
+    if (cpu->cfg.ext_v) {
+        riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
+        if (local_err != NULL) {
+            error_propagate(errp, local_err);
+            return;
+        }
+    }
 }
 
 static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
@@ -1088,7 +1099,6 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
 static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
 {
     CPURISCVState *env = &cpu->env;
-    Error *local_err = NULL;
     uint32_t ext = 0;
 
     if (cpu->cfg.epmp && !cpu->cfg.pmp) {
@@ -1179,14 +1189,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
         }
     }
 
-    if (cpu->cfg.ext_v) {
-        riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
-        if (local_err != NULL) {
-            error_propagate(errp, local_err);
-            return;
-        }
-    }
-
     if (cpu->cfg.ext_zk) {
         cpu->cfg.ext_zkn = true;
         cpu->cfg.ext_zkr = true;
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 18/25] target/riscv: error out on priv failure for RVH
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (16 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 17/25] target/riscv: move riscv_cpu_validate_v() to validate_misa_ext() Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-24 14:56   ` liweiwei
  2023-03-22 22:19 ` [PATCH for-8.1 v4 19/25] target/riscv: write env->misa_ext* in register_generic_cpu_props() Daniel Henrique Barboza
                   ` (6 subsequent siblings)
  24 siblings, 1 reply; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

riscv_cpu_disable_priv_spec_isa_exts(), at the end of
riscv_cpu_validate_set_extensions(), will disable cpu->cfg.ext_h and
cpu->cfg.ext_v if priv_ver check fails.

This check can be done in riscv_cpu_validate_misa_ext(). The difference
here is that we're not silently disable it: we'll error out. Silently
disabling a MISA extension after all the validation is completed can can
cause inconsistencies that we don't have to deal with. Verify ealier and
fail faster.

Note that we're ignoring RVV priv_ver validation since its minimal priv
is also the minimal value we support. RVH will error out if enabled
under priv_ver under 1_12_0.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 399f63b42f..d2eb2b3ba1 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1055,6 +1055,20 @@ static void riscv_cpu_validate_misa_ext(RISCVCPU *cpu, Error **errp)
         return;
     }
 
+    /*
+     * Check for priv spec version. RVH is 1_12_0, RVV is 1_10_0.
+     * We don't support anything under 1_10_0 so skip checking
+     * priv for RVV.
+     *
+     * We're hardcoding it here to avoid looping into the
+     * 50+ entries of isa_edata_arr[] just to check the RVH
+     * entry.
+     */
+    if (cpu->cfg.ext_h && env->priv_ver < PRIV_VERSION_1_12_0) {
+        error_setg(errp, "H extension requires priv spec 1.12.0");
+        return;
+    }
+
     if (cpu->cfg.ext_v) {
         riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
         if (local_err != NULL) {
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 19/25] target/riscv: write env->misa_ext* in register_generic_cpu_props()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (17 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 18/25] target/riscv: error out on priv failure for RVH Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-22 22:19 ` [PATCH for-8.1 v4 20/25] target/riscv: make validate_misa_ext() use a misa_ext val Daniel Henrique Barboza
                   ` (5 subsequent siblings)
  24 siblings, 0 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

In the process of creating the user-facing flags in
register_generic_cpu_props() we're also setting default values for the
cpu->cfg flags that represents MISA bits.

Leaving it as is will cause a discrepancy between users of this function
(at this moment the non-named CPUs) and named CPUs. Named CPUs are using
set_misa() with a non-zero 'ext' value, writing cpu->cfg in the process.
They'll reach riscv_cpu_realize() in a state where env->misa_ext will
reflect cpu->cfg, allowing functions to choose whether to use
env->misa_ext or cpu->cfg to validate MISA bits.

If we guarantee that env->misa_ext will always reflect cpu->cfg at the
start of riscv_cpu_realize(), functions will be able to no longer rely
on cpu->cfg for MISA validation. This happens to be one blocker we have
to properly support write_misa().

Sync env->misa_ext* in register_generic_cpu_props(). After that, there
will be no more places where env->misa_ext needs to be sync back with
cpu->cfg, so remove the now obsolete code at the end of
riscv_cpu_validate_set_extensions().

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d2eb2b3ba1..f1e82a8dda 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1107,14 +1107,10 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
 
 /*
  * Check consistency between chosen extensions while setting
- * cpu->cfg accordingly, setting env->misa_ext and
- * misa_ext_mask in the end.
+ * cpu->cfg accordingly.
  */
 static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
 {
-    CPURISCVState *env = &cpu->env;
-    uint32_t ext = 0;
-
     if (cpu->cfg.epmp && !cpu->cfg.pmp) {
         /*
          * Enhanced PMP should only be available
@@ -1231,10 +1227,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
      * validated and set everything we need.
      */
     riscv_cpu_disable_priv_spec_isa_exts(cpu);
-
-    ext = riscv_get_misa_ext_with_cpucfg(&cpu->cfg);
-
-    env->misa_ext_mask = env->misa_ext = ext;
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -1345,6 +1337,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
         return;
     }
 
+    /*
+     * This is the last point where env->misa_ext* can
+     * be changed.
+     */
     if (cpu->cfg.ext_g) {
         riscv_cpu_enable_g(cpu, &local_err);
         if (local_err != NULL) {
@@ -1622,10 +1618,12 @@ static Property riscv_cpu_extensions[] = {
  * Register generic CPU props with user-facing flags declared
  * in riscv_cpu_extensions[].
  *
- * Note that this will overwrite existing values in cpu->cfg.
+ * Note that this will overwrite existing values in cpu->cfg
+ * and MISA.
  */
 static void register_generic_cpu_props(Object *obj)
 {
+    RISCVCPU *cpu = RISCV_CPU(obj);
     Property *prop;
     DeviceState *dev = DEVICE(obj);
 
@@ -1636,6 +1634,10 @@ static void register_generic_cpu_props(Object *obj)
 #ifndef CONFIG_USER_ONLY
     riscv_add_satp_mode_properties(obj);
 #endif
+
+    /* Keep env->misa_ext and misa_ext_mask updated */
+    cpu->env.misa_ext = riscv_get_misa_ext_with_cpucfg(&cpu->cfg);
+    cpu->env.misa_ext_mask = cpu->env.misa_ext;
 }
 
 static Property riscv_cpu_properties[] = {
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 20/25] target/riscv: make validate_misa_ext() use a misa_ext val
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (18 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 19/25] target/riscv: write env->misa_ext* in register_generic_cpu_props() Daniel Henrique Barboza
@ 2023-03-22 22:19 ` Daniel Henrique Barboza
  2023-03-22 22:20 ` [PATCH for-8.1 v4 21/25] target/riscv: split riscv_cpu_validate_set_extensions() Daniel Henrique Barboza
                   ` (4 subsequent siblings)
  24 siblings, 0 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

We have all MISA specific validations in riscv_cpu_validate_misa_ext(),
and we have a guarantee that env->misa_ext will always be in sync with
cpu->cfg at this point during realize time, so let's convert it to use a
'misa_ext' parameter instead of reading cpu->cfg.

This will prepare the function to be used in write_misa() where we won't
have an updated cpu->cfg object to work with. riscv_cpu_validate_v() is
changed to receive a const pointer to the cpu->cfg object via
riscv_cpu_cfg().

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index f1e82a8dda..bd90e1d329 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -930,7 +930,8 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
     }
 }
 
-static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
+static void riscv_cpu_validate_v(CPURISCVState *env,
+                                 const RISCVCPUConfig *cfg,
                                  Error **errp)
 {
     int vext_version = VEXT_VERSION_1_00_0;
@@ -1016,41 +1017,43 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
     }
 }
 
-static void riscv_cpu_validate_misa_ext(RISCVCPU *cpu, Error **errp)
+
+static void riscv_cpu_validate_misa_ext(CPURISCVState *env,
+                                        uint32_t misa_ext,
+                                        Error **errp)
 {
-    CPURISCVState *env = &cpu->env;
     Error *local_err = NULL;
 
-    if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
+    if (misa_ext & RVI && misa_ext & RVE) {
         error_setg(errp,
                    "I and E extensions are incompatible");
         return;
     }
 
-    if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) {
+    if (!(misa_ext & RVI) && !(misa_ext & RVE)) {
         error_setg(errp,
                    "Either I or E extension must be set");
         return;
     }
 
-    if (cpu->cfg.ext_s && !cpu->cfg.ext_u) {
+    if (misa_ext & RVS && !(misa_ext & RVU)) {
         error_setg(errp,
                    "Setting S extension without U extension is illegal");
         return;
     }
 
-    if (cpu->cfg.ext_h && !cpu->cfg.ext_i) {
+    if (misa_ext & RVH && !(misa_ext & RVI)) {
         error_setg(errp,
                    "H depends on an I base integer ISA with 32 x registers");
         return;
     }
 
-    if (cpu->cfg.ext_h && !cpu->cfg.ext_s) {
+    if (misa_ext & RVH && !(misa_ext & RVS)) {
         error_setg(errp, "H extension implicitly requires S-mode");
         return;
     }
 
-    if (cpu->cfg.ext_d && !cpu->cfg.ext_f) {
+    if (misa_ext & RVD && !(misa_ext & RVF)) {
         error_setg(errp, "D extension requires F extension");
         return;
     }
@@ -1064,13 +1067,13 @@ static void riscv_cpu_validate_misa_ext(RISCVCPU *cpu, Error **errp)
      * 50+ entries of isa_edata_arr[] just to check the RVH
      * entry.
      */
-    if (cpu->cfg.ext_h && env->priv_ver < PRIV_VERSION_1_12_0) {
+    if (misa_ext & RVH && env->priv_ver < PRIV_VERSION_1_12_0) {
         error_setg(errp, "H extension requires priv spec 1.12.0");
         return;
     }
 
-    if (cpu->cfg.ext_v) {
-        riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
+    if (misa_ext & RVV) {
+        riscv_cpu_validate_v(env, riscv_cpu_cfg(env), &local_err);
         if (local_err != NULL) {
             error_propagate(errp, local_err);
             return;
@@ -1355,7 +1358,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
         env->misa_ext_mask = env->misa_ext;
     }
 
-    riscv_cpu_validate_misa_ext(cpu, &local_err);
+    riscv_cpu_validate_misa_ext(env, env->misa_ext, &local_err);
     if (local_err != NULL) {
         error_propagate(errp, local_err);
         return;
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 21/25] target/riscv: split riscv_cpu_validate_set_extensions()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (19 preceding siblings ...)
  2023-03-22 22:19 ` [PATCH for-8.1 v4 20/25] target/riscv: make validate_misa_ext() use a misa_ext val Daniel Henrique Barboza
@ 2023-03-22 22:20 ` Daniel Henrique Barboza
  2023-03-22 22:20 ` [PATCH for-8.1 v4 22/25] target/riscv: use misa_ext val in riscv_cpu_validate_extensions() Daniel Henrique Barboza
                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

We're now ready to split riscv_cpu_validate_set_extensions() in two.
None of these steps are going to touch env->misa_ext*.

riscv_cpu_validate_extensions() will take care of all validations based
on cpu->cfg values. cpu->cfg changes that are required for the
validation are being tolerated here. This is the case of extensions such
as ext_zfh enabling ext_zfhmin.

The RVV chain enablement (ext_zve64d, ext_zve64f and ext_zve32f) is also
being tolerated because the risk of failure is being mitigated by the
RVV -> RVD && RVF dependency in validate_misa_ext() done prior.

In an ideal world we would have all these extensions declared as object
properties, with getters and setters, and we would be able to, e.g.,
enable ext_zfhmin as soon as ext_zfh is enabled. This would avoid
cpu->cfg changes during riscv_cpu_validate_extensions(). Easier said
than done, not just because of the hundreds of lines involved in it, but
also because we want these properties to be available just for generic
CPUs (named CPUs don't want these properties exposed for users). For now
we'll work with that we have.

riscv_cpu_commit_cpu_cfg() is the last step of the validation where more
cpu->cfg properties are set and disabling of extensions due to priv spec
happens. We're already validated everything we wanted, so any cpu->cfg
change made here is valid.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index bd90e1d329..ed02332093 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1109,10 +1109,10 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
 }
 
 /*
- * Check consistency between chosen extensions while setting
- * cpu->cfg accordingly.
+ * Check consistency between chosen extensions. No changes
+ * in env->misa_ext are made.
  */
-static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
+static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp)
 {
     if (cpu->cfg.epmp && !cpu->cfg.pmp) {
         /*
@@ -1201,7 +1201,10 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
             return;
         }
     }
+}
 
+static void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu)
+{
     if (cpu->cfg.ext_zk) {
         cpu->cfg.ext_zkn = true;
         cpu->cfg.ext_zkr = true;
@@ -1364,12 +1367,14 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    riscv_cpu_validate_set_extensions(cpu, &local_err);
+    riscv_cpu_validate_extensions(cpu, &local_err);
     if (local_err != NULL) {
         error_propagate(errp, local_err);
         return;
     }
 
+    riscv_cpu_commit_cpu_cfg(cpu);
+
 #ifndef CONFIG_USER_ONLY
     if (cpu->cfg.ext_sstc) {
         riscv_timer_init(cpu);
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 22/25] target/riscv: use misa_ext val in riscv_cpu_validate_extensions()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (20 preceding siblings ...)
  2023-03-22 22:20 ` [PATCH for-8.1 v4 21/25] target/riscv: split riscv_cpu_validate_set_extensions() Daniel Henrique Barboza
@ 2023-03-22 22:20 ` Daniel Henrique Barboza
  2023-03-24 15:06   ` liweiwei
  2023-03-22 22:20 ` [PATCH for-8.1 v4 23/25] target/riscv: rework write_misa() Daniel Henrique Barboza
                   ` (2 subsequent siblings)
  24 siblings, 1 reply; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

Similar to what we did with riscv_cpu_validate_misa_ext(), let's read
all MISA bits from a misa_ext val instead of reading from the cpu->cfg
object.

This will allow write_misa() to use riscv_cpu_validate_extensions().

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ed02332093..0e6b8fb45e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1109,10 +1109,13 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
 }
 
 /*
- * Check consistency between chosen extensions. No changes
- * in env->misa_ext are made.
+ * Check consistency between cpu->cfg extensions and a
+ * candidate misa_ext value. No changes in env->misa_ext
+ * are made.
  */
-static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp)
+static void riscv_cpu_validate_extensions(RISCVCPU *cpu,
+                                          uint32_t misa_ext,
+                                          Error **errp)
 {
     if (cpu->cfg.epmp && !cpu->cfg.pmp) {
         /*
@@ -1123,12 +1126,12 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp)
         return;
     }
 
-    if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) {
+    if (misa_ext & RVF && !cpu->cfg.ext_icsr) {
         error_setg(errp, "F extension requires Zicsr");
         return;
     }
 
-    if ((cpu->cfg.ext_zawrs) && !cpu->cfg.ext_a) {
+    if ((cpu->cfg.ext_zawrs) && !(misa_ext & RVA)) {
         error_setg(errp, "Zawrs extension requires A extension");
         return;
     }
@@ -1137,13 +1140,13 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp)
         cpu->cfg.ext_zfhmin = true;
     }
 
-    if (cpu->cfg.ext_zfhmin && !cpu->cfg.ext_f) {
+    if (cpu->cfg.ext_zfhmin && !(misa_ext & RVF)) {
         error_setg(errp, "Zfh/Zfhmin extensions require F extension");
         return;
     }
 
     /* The V vector extension depends on the Zve64d extension */
-    if (cpu->cfg.ext_v) {
+    if (misa_ext & RVV) {
         cpu->cfg.ext_zve64d = true;
     }
 
@@ -1157,12 +1160,12 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp)
         cpu->cfg.ext_zve32f = true;
     }
 
-    if (cpu->cfg.ext_zve64d && !cpu->cfg.ext_d) {
+    if (cpu->cfg.ext_zve64d && !(misa_ext & RVD)) {
         error_setg(errp, "Zve64d/V extensions require D extension");
         return;
     }
 
-    if (cpu->cfg.ext_zve32f && !cpu->cfg.ext_f) {
+    if (cpu->cfg.ext_zve32f && !(misa_ext & RVF)) {
         error_setg(errp, "Zve32f/Zve64f extensions require F extension");
         return;
     }
@@ -1195,7 +1198,7 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp)
             error_setg(errp, "Zfinx extension requires Zicsr");
             return;
         }
-        if (cpu->cfg.ext_f) {
+        if (misa_ext & RVF) {
             error_setg(errp,
                        "Zfinx cannot be supported together with F extension");
             return;
@@ -1367,7 +1370,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    riscv_cpu_validate_extensions(cpu, &local_err);
+    riscv_cpu_validate_extensions(cpu, env->misa_ext, &local_err);
     if (local_err != NULL) {
         error_propagate(errp, local_err);
         return;
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 23/25] target/riscv: rework write_misa()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (21 preceding siblings ...)
  2023-03-22 22:20 ` [PATCH for-8.1 v4 22/25] target/riscv: use misa_ext val in riscv_cpu_validate_extensions() Daniel Henrique Barboza
@ 2023-03-22 22:20 ` Daniel Henrique Barboza
  2023-03-24 15:09   ` liweiwei
  2023-03-22 22:20 ` [PATCH for-8.1 v4 24/25] target/riscv: update cpu->cfg misa bits in commit_cpu_cfg() Daniel Henrique Barboza
  2023-03-22 22:20 ` [PATCH for-8.1 v4 25/25] target/riscv: handle RVG updates in write_misa() Daniel Henrique Barboza
  24 siblings, 1 reply; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

write_misa() must use as much common logic as possible. We want to open
code just the bits that are exclusive to the CSR write operation and TCG
internals.

Rewrite write_misa() to work as follows:

- mask the write using misa_ext_mask to avoid enabling unsupported
  extensions;

- suppress RVC if the next insn isn't aligned;

- handle RVE. This is done by filtering all bits but RVE from 'val'.
  Setting RVE will forcefully set only RVE - assuming it gets
  validated afterwards;

- emulate the steps done by realize(): validate the candidate misa_ext
  val, then validate the configuration with the candidate misa_ext val,
  and finally commit the changes to cpu->cfg.

If any of the validation steps fails, the write operation is a no-op.

Let's keep write_misa() as experimental for now until this logic gains
enough mileage.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 12 ++++------
 target/riscv/cpu.h |  6 +++++
 target/riscv/csr.c | 59 ++++++++++++++++++++++++++--------------------
 3 files changed, 45 insertions(+), 32 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0e6b8fb45e..41b17ba0c3 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1018,9 +1018,8 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
 }
 
 
-static void riscv_cpu_validate_misa_ext(CPURISCVState *env,
-                                        uint32_t misa_ext,
-                                        Error **errp)
+void riscv_cpu_validate_misa_ext(CPURISCVState *env, uint32_t misa_ext,
+                                 Error **errp)
 {
     Error *local_err = NULL;
 
@@ -1113,9 +1112,8 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
  * candidate misa_ext value. No changes in env->misa_ext
  * are made.
  */
-static void riscv_cpu_validate_extensions(RISCVCPU *cpu,
-                                          uint32_t misa_ext,
-                                          Error **errp)
+void riscv_cpu_validate_extensions(RISCVCPU *cpu, uint32_t misa_ext,
+                                   Error **errp)
 {
     if (cpu->cfg.epmp && !cpu->cfg.pmp) {
         /*
@@ -1206,7 +1204,7 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu,
     }
 }
 
-static void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu)
+void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu)
 {
     if (cpu->cfg.ext_zk) {
         cpu->cfg.ext_zkn = true;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index dbb4df9df0..ca2ba6a647 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -593,6 +593,12 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 char *riscv_isa_string(RISCVCPU *cpu);
 void riscv_cpu_list(void);
 
+void riscv_cpu_validate_misa_ext(CPURISCVState *env, uint32_t misa_ext,
+                                 Error **errp);
+void riscv_cpu_validate_extensions(RISCVCPU *cpu, uint32_t misa_ext,
+                                   Error **errp);
+void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu);
+
 #define cpu_list riscv_cpu_list
 #define cpu_mmu_index riscv_cpu_mmu_index
 
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d522efc0b6..8d5e8f9ad1 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1343,39 +1343,17 @@ static RISCVException read_misa(CPURISCVState *env, int csrno,
 static RISCVException write_misa(CPURISCVState *env, int csrno,
                                  target_ulong val)
 {
+    RISCVCPU *cpu = env_archcpu(env);
+    Error *local_err = NULL;
+
     if (!riscv_cpu_cfg(env)->misa_w) {
         /* drop write to misa */
         return RISCV_EXCP_NONE;
     }
 
-    /* 'I' or 'E' must be present */
-    if (!(val & (RVI | RVE))) {
-        /* It is not, drop write to misa */
-        return RISCV_EXCP_NONE;
-    }
-
-    /* 'E' excludes all other extensions */
-    if (val & RVE) {
-        /*
-         * when we support 'E' we can do "val = RVE;" however
-         * for now we just drop writes if 'E' is present.
-         */
-        return RISCV_EXCP_NONE;
-    }
-
-    /*
-     * misa.MXL writes are not supported by QEMU.
-     * Drop writes to those bits.
-     */
-
     /* Mask extensions that are not supported by this hart */
     val &= env->misa_ext_mask;
 
-    /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
-    if ((val & RVD) && !(val & RVF)) {
-        val &= ~RVD;
-    }
-
     /*
      * Suppress 'C' if next instruction is not aligned
      * TODO: this should check next_pc
@@ -1389,6 +1367,37 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
         return RISCV_EXCP_NONE;
     }
 
+    /*
+     * We'll handle special cases in separate. If one
+     * of these bits are enabled we'll handle them and
+     * end the CSR write.
+     */
+    if (val & RVE && !(env->misa_ext & RVE)) {
+        /*
+         * RVE must be enabled by itself. Clear all other
+         * misa_env bits and let the validation do its
+         * job.
+         */
+        val &= RVE;
+    }
+
+    /*
+     * This flow is similar to what riscv_cpu_realize() does,
+     * with the difference that we will update env->misa_ext
+     * value if everything is ok.
+     */
+    riscv_cpu_validate_misa_ext(env, val, &local_err);
+    if (local_err != NULL) {
+        return RISCV_EXCP_NONE;
+    }
+
+    riscv_cpu_validate_extensions(cpu, val, &local_err);
+    if (local_err != NULL) {
+        return RISCV_EXCP_NONE;
+    }
+
+    riscv_cpu_commit_cpu_cfg(cpu);
+
     if (!(val & RVF)) {
         env->mstatus &= ~MSTATUS_FS;
     }
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 24/25] target/riscv: update cpu->cfg misa bits in commit_cpu_cfg()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (22 preceding siblings ...)
  2023-03-22 22:20 ` [PATCH for-8.1 v4 23/25] target/riscv: rework write_misa() Daniel Henrique Barboza
@ 2023-03-22 22:20 ` Daniel Henrique Barboza
  2023-03-24 15:14   ` liweiwei
  2023-03-22 22:20 ` [PATCH for-8.1 v4 25/25] target/riscv: handle RVG updates in write_misa() Daniel Henrique Barboza
  24 siblings, 1 reply; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

write_misa() is able to use the same validation workflow
riscv_cpu_realize() uses. But it's still not capable of updating
cpu->cfg misa props yet.

We have no way of blocking future (and current) code from checking
env->misa_ext (via riscv_has_ext()) or reading cpu->cfg directly, so our
best alternative is to keep everything in sync.

riscv_cpu_commit_cpu_cfg() now receives an extra 'misa_ext' parameter.
If this val is different from the existing env->misa_ext, update
env->misa and cpu->cfg with the new value. riscv_cpu_realize() will
ignore this code since env->misa_ext isn't touched during validation,
but write_misa() will use it to keep cpu->cfg in sync with the new
env->misa_ext value.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c | 16 ++++++++++++++--
 target/riscv/cpu.h |  2 +-
 target/riscv/csr.c |  3 +--
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 41b17ba0c3..88806d1050 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1204,8 +1204,20 @@ void riscv_cpu_validate_extensions(RISCVCPU *cpu, uint32_t misa_ext,
     }
 }
 
-void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu)
+void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu, uint32_t misa_ext)
 {
+    CPURISCVState *env = &cpu->env;
+
+    /*
+     * write_misa() needs to update cpu->cfg with the new
+     * MISA bits. This is a no-op for the riscv_cpu_realize()
+     * path.
+     */
+    if (env->misa_ext != misa_ext) {
+        env->misa_ext = misa_ext;
+        riscv_set_cpucfg_with_misa(&cpu->cfg, misa_ext);
+    }
+
     if (cpu->cfg.ext_zk) {
         cpu->cfg.ext_zkn = true;
         cpu->cfg.ext_zkr = true;
@@ -1374,7 +1386,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
         return;
     }
 
-    riscv_cpu_commit_cpu_cfg(cpu);
+    riscv_cpu_commit_cpu_cfg(cpu, env->misa_ext);
 
 #ifndef CONFIG_USER_ONLY
     if (cpu->cfg.ext_sstc) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index ca2ba6a647..befc3b8fff 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -597,7 +597,7 @@ void riscv_cpu_validate_misa_ext(CPURISCVState *env, uint32_t misa_ext,
                                  Error **errp);
 void riscv_cpu_validate_extensions(RISCVCPU *cpu, uint32_t misa_ext,
                                    Error **errp);
-void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu);
+void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu, uint32_t misa_ext);
 
 #define cpu_list riscv_cpu_list
 #define cpu_mmu_index riscv_cpu_mmu_index
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 8d5e8f9ad1..839862f1a8 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1396,7 +1396,7 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
         return RISCV_EXCP_NONE;
     }
 
-    riscv_cpu_commit_cpu_cfg(cpu);
+    riscv_cpu_commit_cpu_cfg(cpu, val);
 
     if (!(val & RVF)) {
         env->mstatus &= ~MSTATUS_FS;
@@ -1404,7 +1404,6 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
 
     /* flush translation cache */
     tb_flush(env_cpu(env));
-    env->misa_ext = val;
     env->xl = riscv_cpu_mxl(env);
     return RISCV_EXCP_NONE;
 }
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH for-8.1 v4 25/25] target/riscv: handle RVG updates in write_misa()
  2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
                   ` (23 preceding siblings ...)
  2023-03-22 22:20 ` [PATCH for-8.1 v4 24/25] target/riscv: update cpu->cfg misa bits in commit_cpu_cfg() Daniel Henrique Barboza
@ 2023-03-22 22:20 ` Daniel Henrique Barboza
  24 siblings, 0 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-22 22:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu,
	palmer, Daniel Henrique Barboza

RVG is enabled when IMAFD_Zicsr_Zifencei is also enabled. Change
write_misa() to enable IMAFD if G is being written in the CSR.

Likewise, RVG should be disabled if any of IMAFD got disabled during the
process. Clear RVG in this case.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/csr.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 839862f1a8..1c0f438dfb 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1381,6 +1381,14 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
         val &= RVE;
     }
 
+    if (val & RVG && !(env->misa_ext & RVG)) {
+        /*
+         * If the write wants to enable RVG, enable all its
+         * dependencies as well.
+         */
+        val |= RVI | RVM | RVA | RVF | RVD;
+    }
+
     /*
      * This flow is similar to what riscv_cpu_realize() does,
      * with the difference that we will update env->misa_ext
@@ -1396,6 +1404,12 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
         return RISCV_EXCP_NONE;
     }
 
+    if (!(val & RVI && val & RVM && val & RVA &&
+          val & RVF && val & RVD)) {
+        /* Disable RVG if any of its dependencies were disabled */
+        val &= ~RVG;
+    }
+
     riscv_cpu_commit_cpu_cfg(cpu, val);
 
     if (!(val & RVF)) {
-- 
2.39.2



^ permalink raw reply related	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 06/25] target/riscv/cpu.c: add riscv_cpu_validate_misa_mxl()
  2023-03-22 22:19 ` [PATCH for-8.1 v4 06/25] target/riscv/cpu.c: add riscv_cpu_validate_misa_mxl() Daniel Henrique Barboza
@ 2023-03-23  1:35   ` LIU Zhiwei
  0 siblings, 0 replies; 42+ messages in thread
From: LIU Zhiwei @ 2023-03-23  1:35 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, palmer


On 2023/3/23 6:19, Daniel Henrique Barboza wrote:
> Let's remove more code that is open coded in riscv_cpu_realize() and put
> it into a helper. Let's also add an error message instead of just
> asserting out if env->misa_mxl_max != env->misa_mlx.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   target/riscv/cpu.c | 51 ++++++++++++++++++++++++++++++----------------
>   1 file changed, 33 insertions(+), 18 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 17b301967c..1a298e5e55 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -879,6 +879,33 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
>       }
>   }
>   
> +static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
> +{
> +    RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
> +    CPUClass *cc = CPU_CLASS(mcc);
> +    CPURISCVState *env = &cpu->env;
> +
> +    /* Validate that MISA_MXL is set properly. */
> +    switch (env->misa_mxl_max) {
> +#ifdef TARGET_RISCV64
> +    case MXL_RV64:
> +    case MXL_RV128:
> +        cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
> +        break;
> +#endif
> +    case MXL_RV32:
> +        cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
> +
> +    if (env->misa_mxl_max != env->misa_mxl) {
> +        error_setg(errp, "misa_mxl_max must be equal to misa_mxl");
> +        return;
> +    }
> +}
> +
>   /*
>    * Check consistency between chosen extensions while setting
>    * cpu->cfg accordingly, doing a set_misa() in the end.
> @@ -1180,9 +1207,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
>   {
>       CPUState *cs = CPU(dev);
>       RISCVCPU *cpu = RISCV_CPU(dev);
> -    CPURISCVState *env = &cpu->env;
>       RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
> -    CPUClass *cc = CPU_CLASS(mcc);
>       Error *local_err = NULL;
>   
>       cpu_exec_realizefn(cs, &local_err);
> @@ -1197,6 +1222,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
>           return;
>       }
>   
> +    riscv_cpu_validate_misa_mxl(cpu, &local_err);
> +    if (local_err != NULL) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +
>       if (cpu->cfg.epmp && !cpu->cfg.pmp) {
>           /*
>            * Enhanced PMP should only be available
> @@ -1213,22 +1244,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
>       }
>   #endif /* CONFIG_USER_ONLY */
>   
> -    /* Validate that MISA_MXL is set properly. */
> -    switch (env->misa_mxl_max) {
> -#ifdef TARGET_RISCV64
> -    case MXL_RV64:
> -    case MXL_RV128:
> -        cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
> -        break;
> -#endif
> -    case MXL_RV32:
> -        cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
> -        break;
> -    default:
> -        g_assert_not_reached();
> -    }
> -    assert(env->misa_mxl_max == env->misa_mxl);
> -

Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>

Zhiwei

>       riscv_cpu_validate_set_extensions(cpu, &local_err);
>       if (local_err != NULL) {
>           error_propagate(errp, local_err);


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 07/25] target/riscv: move pmp and epmp validations to validate_set_extensions()
  2023-03-22 22:19 ` [PATCH for-8.1 v4 07/25] target/riscv: move pmp and epmp validations to validate_set_extensions() Daniel Henrique Barboza
@ 2023-03-23  1:42   ` LIU Zhiwei
  0 siblings, 0 replies; 42+ messages in thread
From: LIU Zhiwei @ 2023-03-23  1:42 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, palmer


On 2023/3/23 6:19, Daniel Henrique Barboza wrote:
> In the near future, write_misa() will use a variation of what we have
> now as riscv_cpu_validate_set_extensions(). The pmp and epmp validation
> will be required in write_misa()

I don't know why pmp and epmp should be checked in write_misa().
As write_misa can't alter the pmp and epmp setting, the check for 
pmp/epmp should only be at cpu object initialization time for one time.

Zhiwei

> and it's already required here in
> riscv_cpu_realize(), so move it to riscv_cpu_validate_set_extensions().
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   target/riscv/cpu.c | 19 +++++++++----------
>   1 file changed, 9 insertions(+), 10 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 1a298e5e55..7458845fec 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -916,6 +916,15 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
>       Error *local_err = NULL;
>       uint32_t ext = 0;
>   
> +    if (cpu->cfg.epmp && !cpu->cfg.pmp) {
> +        /*
> +         * Enhanced PMP should only be available
> +         * on harts with PMP support
> +         */
> +        error_setg(errp, "Invalid configuration: EPMP requires PMP support");
> +        return;
> +    }
> +
>       /* Do some ISA extension error checking */
>       if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
>                               cpu->cfg.ext_a && cpu->cfg.ext_f &&
> @@ -1228,16 +1237,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
>           return;
>       }
>   
> -    if (cpu->cfg.epmp && !cpu->cfg.pmp) {
> -        /*
> -         * Enhanced PMP should only be available
> -         * on harts with PMP support
> -         */
> -        error_setg(errp, "Invalid configuration: EPMP requires PMP support");
> -        return;
> -    }
> -
> -
>   #ifndef CONFIG_USER_ONLY
>       if (cpu->cfg.ext_sstc) {
>           riscv_timer_init(cpu);


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 08/25] target/riscv/cpu.c: validate extensions before riscv_timer_init()
  2023-03-22 22:19 ` [PATCH for-8.1 v4 08/25] target/riscv/cpu.c: validate extensions before riscv_timer_init() Daniel Henrique Barboza
@ 2023-03-23  1:52   ` LIU Zhiwei
  0 siblings, 0 replies; 42+ messages in thread
From: LIU Zhiwei @ 2023-03-23  1:52 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, palmer


On 2023/3/23 6:19, Daniel Henrique Barboza wrote:
> There is no need to init timers if we're not even sure that our
> extensions are valid. Execute riscv_cpu_validate_set_extensions() before
> riscv_timer_init().
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   target/riscv/cpu.c | 10 ++++------
>   1 file changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7458845fec..fef55d7d79 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1237,12 +1237,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
>           return;
>       }
>   
> -#ifndef CONFIG_USER_ONLY
> -    if (cpu->cfg.ext_sstc) {
> -        riscv_timer_init(cpu);
> -    }
> -#endif /* CONFIG_USER_ONLY */
> -
>       riscv_cpu_validate_set_extensions(cpu, &local_err);
>       if (local_err != NULL) {
>           error_propagate(errp, local_err);
> @@ -1250,6 +1244,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
>       }
>   
>   #ifndef CONFIG_USER_ONLY
> +    if (cpu->cfg.ext_sstc) {
> +        riscv_timer_init(cpu);
> +    }
> +

Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>

Zhiwei

>       if (cpu->cfg.pmu_num) {
>           if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) {
>               cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 09/25] target/riscv/cpu.c: remove cfg setup from riscv_cpu_init()
  2023-03-22 22:19 ` [PATCH for-8.1 v4 09/25] target/riscv/cpu.c: remove cfg setup from riscv_cpu_init() Daniel Henrique Barboza
@ 2023-03-23  2:02   ` LIU Zhiwei
  0 siblings, 0 replies; 42+ messages in thread
From: LIU Zhiwei @ 2023-03-23  2:02 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, palmer


On 2023/3/23 6:19, Daniel Henrique Barboza wrote:
> We have 4 config settings being done in riscv_cpu_init(): ext_ifencei,
> ext_icsr, mmu and pmp. This is also the constructor of the "riscv-cpu"
> device, which happens to be the parent device of every RISC-V cpu.
>
> The result is that these 4 configs are being set every time, and every
> other CPU should always account for them. CPUs such as sifive_e need to
> disable settings that aren't enabled simply because the parent class
> happens to be enabling it.
>
> Moving all configurations from the parent class to each CPU will
> centralize the config of each CPU into its own init(), which is clearer
> than having to account to whatever happens to be set in the parent
> device. These settings are also being set in register_cpu_props() when
> no 'misa_ext' is set, so for these CPUs we don't need changes. Named
> CPUs will receive all cfgs that the parent were setting into their
> init().
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   target/riscv/cpu.c | 60 ++++++++++++++++++++++++++++++++++++----------
>   1 file changed, 48 insertions(+), 12 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index fef55d7d79..c7b6e7b84b 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -325,7 +325,8 @@ static void set_satp_mode_default_map(RISCVCPU *cpu)
>   
>   static void riscv_any_cpu_init(Object *obj)
>   {
> -    CPURISCVState *env = &RISCV_CPU(obj)->env;
> +    RISCVCPU *cpu = RISCV_CPU(obj);
> +    CPURISCVState *env = &cpu->env;
>   #if defined(TARGET_RISCV32)
>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
>   #elif defined(TARGET_RISCV64)
> @@ -340,6 +341,12 @@ static void riscv_any_cpu_init(Object *obj)
>   
>       env->priv_ver = PRIV_VERSION_LATEST;
>       register_cpu_props(obj);
> +
> +    /* inherited from parent obj via riscv_cpu_init() */
> +    cpu->cfg.ext_ifencei = true;
> +    cpu->cfg.ext_icsr = true;
> +    cpu->cfg.mmu = true;
> +    cpu->cfg.pmp = true;
>   }
>   
>   #if defined(TARGET_RISCV64)
> @@ -358,13 +365,20 @@ static void rv64_base_cpu_init(Object *obj)
>   
>   static void rv64_sifive_u_cpu_init(Object *obj)
>   {
> -    CPURISCVState *env = &RISCV_CPU(obj)->env;
> +    RISCVCPU *cpu = RISCV_CPU(obj);
> +    CPURISCVState *env = &cpu->env;
>       set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
>       register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_10_0;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
>   #endif
> +
> +    /* inherited from parent obj via riscv_cpu_init() */
> +    cpu->cfg.ext_ifencei = true;
> +    cpu->cfg.ext_icsr = true;
> +    cpu->cfg.mmu = true;
> +    cpu->cfg.pmp = true;
>   }
>   
>   static void rv64_sifive_e_cpu_init(Object *obj)
> @@ -375,10 +389,14 @@ static void rv64_sifive_e_cpu_init(Object *obj)
>       set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
>       register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_10_0;
> -    cpu->cfg.mmu = false;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>   #endif
> +
> +    /* inherited from parent obj via riscv_cpu_init() */
> +    cpu->cfg.ext_ifencei = true;
> +    cpu->cfg.ext_icsr = true;
> +    cpu->cfg.pmp = true;
>   }
>   
>   static void rv64_thead_c906_cpu_init(Object *obj)
> @@ -411,6 +429,10 @@ static void rv64_thead_c906_cpu_init(Object *obj)
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(cpu, VM_1_10_SV39);
>   #endif
> +
> +    /* inherited from parent obj via riscv_cpu_init() */
> +    cpu->cfg.ext_ifencei = true;
> +    cpu->cfg.pmp = true;
>   }
>   
>   static void rv128_base_cpu_init(Object *obj)
> @@ -447,7 +469,8 @@ static void rv32_base_cpu_init(Object *obj)
>   
>   static void rv32_sifive_u_cpu_init(Object *obj)
>   {
> -    CPURISCVState *env = &RISCV_CPU(obj)->env;
> +    RISCVCPU *cpu = RISCV_CPU(obj);
> +    CPURISCVState *env = &cpu->env;
>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
>   
>       register_cpu_props(obj);
> @@ -455,6 +478,12 @@ static void rv32_sifive_u_cpu_init(Object *obj)
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
>   #endif
> +
> +    /* inherited from parent obj via riscv_cpu_init() */
> +    cpu->cfg.ext_ifencei = true;
> +    cpu->cfg.ext_icsr = true;
> +    cpu->cfg.mmu = true;
> +    cpu->cfg.pmp = true;
>   }
>   
>   static void rv32_sifive_e_cpu_init(Object *obj)
> @@ -465,10 +494,14 @@ static void rv32_sifive_e_cpu_init(Object *obj)
>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
>       register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_10_0;
> -    cpu->cfg.mmu = false;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>   #endif
> +
> +    /* inherited from parent obj via riscv_cpu_init() */
> +    cpu->cfg.ext_ifencei = true;
> +    cpu->cfg.ext_icsr = true;
> +    cpu->cfg.pmp = true;
>   }
>   
>   static void rv32_ibex_cpu_init(Object *obj)
> @@ -479,11 +512,15 @@ static void rv32_ibex_cpu_init(Object *obj)
>       set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
>       register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_11_0;
> -    cpu->cfg.mmu = false;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>   #endif
>       cpu->cfg.epmp = true;
> +
> +    /* inherited from parent obj via riscv_cpu_init() */
> +    cpu->cfg.ext_ifencei = true;
> +    cpu->cfg.ext_icsr = true;
> +    cpu->cfg.pmp = true;
>   }
>   
>   static void rv32_imafcu_nommu_cpu_init(Object *obj)
> @@ -494,10 +531,14 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
>       register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_10_0;
> -    cpu->cfg.mmu = false;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>   #endif
> +
> +    /* inherited from parent obj via riscv_cpu_init() */
> +    cpu->cfg.ext_ifencei = true;
> +    cpu->cfg.ext_icsr = true;
> +    cpu->cfg.pmp = true;
>   }
>   #endif
>   
> @@ -1384,11 +1425,6 @@ static void riscv_cpu_init(Object *obj)
>   {
>       RISCVCPU *cpu = RISCV_CPU(obj);
>   
> -    cpu->cfg.ext_ifencei = true;
> -    cpu->cfg.ext_icsr = true;
> -    cpu->cfg.mmu = true;
> -    cpu->cfg.pmp = true;
> -

Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>

Zhiwei

>       cpu_set_cpustate_pointers(cpu);
>   
>   #ifndef CONFIG_USER_ONLY


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 10/25] target/riscv/cpu.c: avoid set_misa() in validate_set_extensions()
  2023-03-22 22:19 ` [PATCH for-8.1 v4 10/25] target/riscv/cpu.c: avoid set_misa() in validate_set_extensions() Daniel Henrique Barboza
@ 2023-03-23  2:04   ` LIU Zhiwei
  0 siblings, 0 replies; 42+ messages in thread
From: LIU Zhiwei @ 2023-03-23  2:04 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, palmer


On 2023/3/23 6:19, Daniel Henrique Barboza wrote:
> set_misa() will be tuned up to do more than it's already doing and it
> will be redundant to what riscv_cpu_validate_set_extensions() does.
>
> Note that we don't ever change env->misa_mlx
typo.
> in this function, so
> set_misa() can be replaced by just assigning env->misa_ext and
> env->misa_ext_mask to 'ext'.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   target/riscv/cpu.c | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index c7b6e7b84b..36c55abda0 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -949,7 +949,8 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
>   
>   /*
>    * Check consistency between chosen extensions while setting
> - * cpu->cfg accordingly, doing a set_misa() in the end.
> + * cpu->cfg accordingly, setting env->misa_ext and
> + * misa_ext_mask in the end.
>    */
>   static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
>   {
> @@ -1168,7 +1169,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
>           ext |= RVJ;
>       }
>   
> -    set_misa(env, env->misa_mxl, ext);
> +    env->misa_ext_mask = env->misa_ext = ext;

Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>

Zhiwei

>   }
>   
>   #ifndef CONFIG_USER_ONLY


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 11/25] target/riscv/cpu.c: set cpu config in set_misa()
  2023-03-22 22:19 ` [PATCH for-8.1 v4 11/25] target/riscv/cpu.c: set cpu config in set_misa() Daniel Henrique Barboza
@ 2023-03-23  2:14   ` LIU Zhiwei
  2023-03-23  2:18     ` LIU Zhiwei
  2023-03-23 23:23     ` Daniel Henrique Barboza
  0 siblings, 2 replies; 42+ messages in thread
From: LIU Zhiwei @ 2023-03-23  2:14 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, palmer


On 2023/3/23 6:19, Daniel Henrique Barboza wrote:
> set_misa() is setting all 'misa' related env states and nothing else.
> But other functions, namely riscv_cpu_validate_set_extensions(), uses
> the config object to do its job.
>
> This creates a need to set the single letter extensions in the cfg
> object to keep both in sync. At this moment this is being done by
> register_cpu_props(), forcing every CPU to do a call to this function.
>
> Let's beef up set_misa() and make the function do the sync for us. This
> will relieve named CPUs to having to call register_cpu_props(), which
> will then be redesigned to a more specialized role next.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   target/riscv/cpu.c | 43 ++++++++++++++++++++++++++++++++-----------
>   target/riscv/cpu.h |  4 ++--
>   2 files changed, 34 insertions(+), 13 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 36c55abda0..df5c0bda70 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -236,8 +236,40 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
>   
>   static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
>   {
> +    RISCVCPU *cpu;
> +
>       env->misa_mxl_max = env->misa_mxl = mxl;
>       env->misa_ext_mask = env->misa_ext = ext;
> +
> +    /*
> +     * ext = 0 will only be a thing during cpu_init() functions
> +     * as a way of setting an extension-agnostic CPU. We do
> +     * not support clearing misa_ext* and the ext_N flags in
> +     * RISCVCPUConfig in regular circunstances.
> +     */
> +    if (ext == 0) {
> +        return;
> +    }
> +
> +    /*
> +     * We can't use riscv_cpu_cfg() in this case because it is
> +     * a read-only inline and we're going to change the values
> +     * of cpu->cfg.
> +     */
> +    cpu = env_archcpu(env);
> +
> +    cpu->cfg.ext_i = ext & RVI;
> +    cpu->cfg.ext_e = ext & RVE;
> +    cpu->cfg.ext_m = ext & RVM;
> +    cpu->cfg.ext_a = ext & RVA;
> +    cpu->cfg.ext_f = ext & RVF;
> +    cpu->cfg.ext_d = ext & RVD;
> +    cpu->cfg.ext_v = ext & RVV;
> +    cpu->cfg.ext_c = ext & RVC;
> +    cpu->cfg.ext_s = ext & RVS;
> +    cpu->cfg.ext_u = ext & RVU;
> +    cpu->cfg.ext_h = ext & RVH;
> +    cpu->cfg.ext_j = ext & RVJ;
>   }
>   
>   #ifndef CONFIG_USER_ONLY
> @@ -340,7 +372,6 @@ static void riscv_any_cpu_init(Object *obj)
>   #endif
>   
>       env->priv_ver = PRIV_VERSION_LATEST;
> -    register_cpu_props(obj);

This patch will break the original logic. We can only can a empty CPU here.

>   
>       /* inherited from parent obj via riscv_cpu_init() */
>       cpu->cfg.ext_ifencei = true;
> @@ -368,7 +399,6 @@ static void rv64_sifive_u_cpu_init(Object *obj)
>       RISCVCPU *cpu = RISCV_CPU(obj);
>       CPURISCVState *env = &cpu->env;
>       set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> -    register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_10_0;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
> @@ -387,7 +417,6 @@ static void rv64_sifive_e_cpu_init(Object *obj)
>       RISCVCPU *cpu = RISCV_CPU(obj);
>   
>       set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
> -    register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_10_0;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
> @@ -408,9 +437,6 @@ static void rv64_thead_c906_cpu_init(Object *obj)
>       env->priv_ver = PRIV_VERSION_1_11_0;
>   
>       cpu->cfg.ext_g = true;
> -    cpu->cfg.ext_c = true;
> -    cpu->cfg.ext_u = true;
> -    cpu->cfg.ext_s = true;

Why specially for these configurations?

Zhiwei

>       cpu->cfg.ext_icsr = true;
>       cpu->cfg.ext_zfh = true;
>       cpu->cfg.mmu = true;
> @@ -472,8 +498,6 @@ static void rv32_sifive_u_cpu_init(Object *obj)
>       RISCVCPU *cpu = RISCV_CPU(obj);
>       CPURISCVState *env = &cpu->env;
>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> -
> -    register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_10_0;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
> @@ -492,7 +516,6 @@ static void rv32_sifive_e_cpu_init(Object *obj)
>       RISCVCPU *cpu = RISCV_CPU(obj);
>   
>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
> -    register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_10_0;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
> @@ -510,7 +533,6 @@ static void rv32_ibex_cpu_init(Object *obj)
>       RISCVCPU *cpu = RISCV_CPU(obj);
>   
>       set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
> -    register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_11_0;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
> @@ -529,7 +551,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
>       RISCVCPU *cpu = RISCV_CPU(obj);
>   
>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
> -    register_cpu_props(obj);
>       env->priv_ver = PRIV_VERSION_1_10_0;
>   #ifndef CONFIG_USER_ONLY
>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 76f81c6b68..ebe0fff668 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -66,8 +66,8 @@
>   #define RV(x) ((target_ulong)1 << (x - 'A'))
>   
>   /*
> - * Consider updating register_cpu_props() when adding
> - * new MISA bits here.
> + * Consider updating set_misa() when adding new
> + * MISA bits here.
>    */
>   #define RVI RV('I')
>   #define RVE RV('E') /* E and I are mutually exclusive */


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 11/25] target/riscv/cpu.c: set cpu config in set_misa()
  2023-03-23  2:14   ` LIU Zhiwei
@ 2023-03-23  2:18     ` LIU Zhiwei
  2023-03-23 23:23     ` Daniel Henrique Barboza
  1 sibling, 0 replies; 42+ messages in thread
From: LIU Zhiwei @ 2023-03-23  2:18 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, palmer


On 2023/3/23 10:14, LIU Zhiwei wrote:
>
> On 2023/3/23 6:19, Daniel Henrique Barboza wrote:
>> set_misa() is setting all 'misa' related env states and nothing else.
>> But other functions, namely riscv_cpu_validate_set_extensions(), uses
>> the config object to do its job.
>>
>> This creates a need to set the single letter extensions in the cfg
>> object to keep both in sync. At this moment this is being done by
>> register_cpu_props(), forcing every CPU to do a call to this function.
>>
>> Let's beef up set_misa() and make the function do the sync for us. This
>> will relieve named CPUs to having to call register_cpu_props(), which
>> will then be redesigned to a more specialized role next.
>>
>> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>> ---
>>   target/riscv/cpu.c | 43 ++++++++++++++++++++++++++++++++-----------
>>   target/riscv/cpu.h |  4 ++--
>>   2 files changed, 34 insertions(+), 13 deletions(-)
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index 36c55abda0..df5c0bda70 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -236,8 +236,40 @@ const char *riscv_cpu_get_trap_name(target_ulong 
>> cause, bool async)
>>     static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
>>   {
>> +    RISCVCPU *cpu;
>> +
>>       env->misa_mxl_max = env->misa_mxl = mxl;
>>       env->misa_ext_mask = env->misa_ext = ext;
>> +
>> +    /*
>> +     * ext = 0 will only be a thing during cpu_init() functions
>> +     * as a way of setting an extension-agnostic CPU. We do
>> +     * not support clearing misa_ext* and the ext_N flags in
>> +     * RISCVCPUConfig in regular circunstances.
>> +     */
>> +    if (ext == 0) {
>> +        return;
>> +    }
>> +
>> +    /*
>> +     * We can't use riscv_cpu_cfg() in this case because it is
>> +     * a read-only inline and we're going to change the values
>> +     * of cpu->cfg.
>> +     */
>> +    cpu = env_archcpu(env);
>> +
>> +    cpu->cfg.ext_i = ext & RVI;
>> +    cpu->cfg.ext_e = ext & RVE;
>> +    cpu->cfg.ext_m = ext & RVM;
>> +    cpu->cfg.ext_a = ext & RVA;
>> +    cpu->cfg.ext_f = ext & RVF;
>> +    cpu->cfg.ext_d = ext & RVD;
>> +    cpu->cfg.ext_v = ext & RVV;
>> +    cpu->cfg.ext_c = ext & RVC;
>> +    cpu->cfg.ext_s = ext & RVS;
>> +    cpu->cfg.ext_u = ext & RVU;
>> +    cpu->cfg.ext_h = ext & RVH;
>> +    cpu->cfg.ext_j = ext & RVJ;
>>   }
>>     #ifndef CONFIG_USER_ONLY
>> @@ -340,7 +372,6 @@ static void riscv_any_cpu_init(Object *obj)
>>   #endif
>>         env->priv_ver = PRIV_VERSION_LATEST;
>> -    register_cpu_props(obj);
>
> This patch will break the original logic. We can only can a empty CPU 
> here.

Oops. I mistook it as a general cpu. Just ignore this comment.

Zhiwei

>
>>         /* inherited from parent obj via riscv_cpu_init() */
>>       cpu->cfg.ext_ifencei = true;
>> @@ -368,7 +399,6 @@ static void rv64_sifive_u_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       CPURISCVState *env = &cpu->env;
>>       set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS 
>> | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
>> @@ -387,7 +417,6 @@ static void rv64_sifive_e_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>         set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> @@ -408,9 +437,6 @@ static void rv64_thead_c906_cpu_init(Object *obj)
>>       env->priv_ver = PRIV_VERSION_1_11_0;
>>         cpu->cfg.ext_g = true;
>> -    cpu->cfg.ext_c = true;
>> -    cpu->cfg.ext_u = true;
>> -    cpu->cfg.ext_s = true;
>
> Why specially for these configurations?
>
> Zhiwei
>
>>       cpu->cfg.ext_icsr = true;
>>       cpu->cfg.ext_zfh = true;
>>       cpu->cfg.mmu = true;
>> @@ -472,8 +498,6 @@ static void rv32_sifive_u_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       CPURISCVState *env = &cpu->env;
>>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS 
>> | RVU);
>> -
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
>> @@ -492,7 +516,6 @@ static void rv32_sifive_e_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>         set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> @@ -510,7 +533,6 @@ static void rv32_ibex_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>         set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_11_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> @@ -529,7 +551,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>         set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
>> index 76f81c6b68..ebe0fff668 100644
>> --- a/target/riscv/cpu.h
>> +++ b/target/riscv/cpu.h
>> @@ -66,8 +66,8 @@
>>   #define RV(x) ((target_ulong)1 << (x - 'A'))
>>     /*
>> - * Consider updating register_cpu_props() when adding
>> - * new MISA bits here.
>> + * Consider updating set_misa() when adding new
>> + * MISA bits here.
>>    */
>>   #define RVI RV('I')
>>   #define RVE RV('E') /* E and I are mutually exclusive */


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 12/25] target/riscv/cpu.c: redesign register_cpu_props()
  2023-03-22 22:19 ` [PATCH for-8.1 v4 12/25] target/riscv/cpu.c: redesign register_cpu_props() Daniel Henrique Barboza
@ 2023-03-23  3:22   ` LIU Zhiwei
  0 siblings, 0 replies; 42+ messages in thread
From: LIU Zhiwei @ 2023-03-23  3:22 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, palmer

Hi Daniel,

I want to share my opinions about the cpu->cfg and misa.


Two suggestions:

1) The cpu->cfg should be set only once in cpu initialization 
phrase(cpu_init_fn or cpu_realize_fn), and never changes any more in 
other times(for example write_misa).

2) Set the misa only when cpu->cfg is ready.


In my mind, we should setting the misa and cfg in this way.

1) setting cfg  and misa_mxl in xxx_cpu_init.  Don't call set_misa here.

2) register and setting cfg for general cpus by the infrastructure.

3) check the cfg in cpu_realize_fn stage in a special function. Don't 
change cpu->cfg, just pass it as a parameter.

4)  expand the cpu->cfg, such as for RVG.

5)  setting the misa and misa_max

6) when write_misa, construct a cfg for the new misa value. If the cfg 
is legal after checking it against with the cpu->cfg, write it directly 
into misa. Don't change the cpu->cfg here.


Best Regards,
Zhiwei

On 2023/3/23 6:19, Daniel Henrique Barboza wrote:
> Now that the function is a no-op if 'env.misa_ext != 0', and no one that
> are setting misa_ext != 0 is calling it because set_misa() is setting
> the cpu cfg accordingly, remove the now deprecated code and rename the
> function to register_generic_cpu_props().
>
> This function is now doing exactly what the name says: it is creating
> user-facing properties to allow changes in the CPU cfg via the QEMU
> command line, setting default values if no user input is provided.
>
> Note that there's the possibility of a CPU to set a certain misa value
> and, at the same, also want user-facing flags and defaults from this
> function. This is not the case since commit 26b2bc58599c ("target/riscv:
> Don't expose the CPU properties on names CPUs"), but given that this is
> also a possibility, clarify in the function that using this function
> will overwrite existing values in cpu->cfg.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   target/riscv/cpu.c | 48 ++++++++++------------------------------------
>   1 file changed, 10 insertions(+), 38 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index df5c0bda70..0e56a1c01f 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -221,7 +221,7 @@ static const char * const riscv_intr_names[] = {
>       "reserved"
>   };
>   
> -static void register_cpu_props(Object *obj);
> +static void register_generic_cpu_props(Object *obj);
>   
>   const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
>   {
> @@ -386,7 +386,7 @@ static void rv64_base_cpu_init(Object *obj)
>       CPURISCVState *env = &RISCV_CPU(obj)->env;
>       /* We set this in the realise function */
>       set_misa(env, MXL_RV64, 0);
> -    register_cpu_props(obj);
> +    register_generic_cpu_props(obj);
>       /* Set latest version of privileged specification */
>       env->priv_ver = PRIV_VERSION_LATEST;
>   #ifndef CONFIG_USER_ONLY
> @@ -472,7 +472,7 @@ static void rv128_base_cpu_init(Object *obj)
>       CPURISCVState *env = &RISCV_CPU(obj)->env;
>       /* We set this in the realise function */
>       set_misa(env, MXL_RV128, 0);
> -    register_cpu_props(obj);
> +    register_generic_cpu_props(obj);
>       /* Set latest version of privileged specification */
>       env->priv_ver = PRIV_VERSION_LATEST;
>   #ifndef CONFIG_USER_ONLY
> @@ -485,7 +485,7 @@ static void rv32_base_cpu_init(Object *obj)
>       CPURISCVState *env = &RISCV_CPU(obj)->env;
>       /* We set this in the realise function */
>       set_misa(env, MXL_RV32, 0);
> -    register_cpu_props(obj);
> +    register_generic_cpu_props(obj);
>       /* Set latest version of privileged specification */
>       env->priv_ver = PRIV_VERSION_LATEST;
>   #ifndef CONFIG_USER_ONLY
> @@ -572,7 +572,7 @@ static void riscv_host_cpu_init(Object *obj)
>   #elif defined(TARGET_RISCV64)
>       set_misa(env, MXL_RV64, 0);
>   #endif
> -    register_cpu_props(obj);
> +    register_generic_cpu_props(obj);
>   }
>   #endif
>   
> @@ -1554,44 +1554,16 @@ static Property riscv_cpu_extensions[] = {
>   };
>   
>   /*
> - * Register CPU props based on env.misa_ext. If a non-zero
> - * value was set, register only the required cpu->cfg.ext_*
> - * properties and leave. env.misa_ext = 0 means that we want
> - * all the default properties to be registered.
> + * Register generic CPU props with user-facing flags declared
> + * in riscv_cpu_extensions[].
> + *
> + * Note that this will overwrite existing values in cpu->cfg.
>    */
> -static void register_cpu_props(Object *obj)
> +static void register_generic_cpu_props(Object *obj)
>   {
> -    RISCVCPU *cpu = RISCV_CPU(obj);
> -    uint32_t misa_ext = cpu->env.misa_ext;
>       Property *prop;
>       DeviceState *dev = DEVICE(obj);
>   
> -    /*
> -     * If misa_ext is not zero, set cfg properties now to
> -     * allow them to be read during riscv_cpu_realize()
> -     * later on.
> -     */
> -    if (cpu->env.misa_ext != 0) {
> -        cpu->cfg.ext_i = misa_ext & RVI;
> -        cpu->cfg.ext_e = misa_ext & RVE;
> -        cpu->cfg.ext_m = misa_ext & RVM;
> -        cpu->cfg.ext_a = misa_ext & RVA;
> -        cpu->cfg.ext_f = misa_ext & RVF;
> -        cpu->cfg.ext_d = misa_ext & RVD;
> -        cpu->cfg.ext_v = misa_ext & RVV;
> -        cpu->cfg.ext_c = misa_ext & RVC;
> -        cpu->cfg.ext_s = misa_ext & RVS;
> -        cpu->cfg.ext_u = misa_ext & RVU;
> -        cpu->cfg.ext_h = misa_ext & RVH;
> -        cpu->cfg.ext_j = misa_ext & RVJ;
> -
> -        /*
> -         * We don't want to set the default riscv_cpu_extensions
> -         * in this case.
> -         */
> -        return;
> -    }
> -
>       for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
>           qdev_property_add_static(dev, prop);
>       }


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 11/25] target/riscv/cpu.c: set cpu config in set_misa()
  2023-03-23  2:14   ` LIU Zhiwei
  2023-03-23  2:18     ` LIU Zhiwei
@ 2023-03-23 23:23     ` Daniel Henrique Barboza
  1 sibling, 0 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-23 23:23 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, palmer



On 3/22/23 23:14, LIU Zhiwei wrote:
> 
> On 2023/3/23 6:19, Daniel Henrique Barboza wrote:
>> set_misa() is setting all 'misa' related env states and nothing else.
>> But other functions, namely riscv_cpu_validate_set_extensions(), uses
>> the config object to do its job.
>>
>> This creates a need to set the single letter extensions in the cfg
>> object to keep both in sync. At this moment this is being done by
>> register_cpu_props(), forcing every CPU to do a call to this function.
>>
>> Let's beef up set_misa() and make the function do the sync for us. This
>> will relieve named CPUs to having to call register_cpu_props(), which
>> will then be redesigned to a more specialized role next.
>>
>> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>> ---
>>   target/riscv/cpu.c | 43 ++++++++++++++++++++++++++++++++-----------
>>   target/riscv/cpu.h |  4 ++--
>>   2 files changed, 34 insertions(+), 13 deletions(-)
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index 36c55abda0..df5c0bda70 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -236,8 +236,40 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
>>   static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
>>   {
>> +    RISCVCPU *cpu;
>> +
>>       env->misa_mxl_max = env->misa_mxl = mxl;
>>       env->misa_ext_mask = env->misa_ext = ext;
>> +
>> +    /*
>> +     * ext = 0 will only be a thing during cpu_init() functions
>> +     * as a way of setting an extension-agnostic CPU. We do
>> +     * not support clearing misa_ext* and the ext_N flags in
>> +     * RISCVCPUConfig in regular circunstances.
>> +     */
>> +    if (ext == 0) {
>> +        return;
>> +    }
>> +
>> +    /*
>> +     * We can't use riscv_cpu_cfg() in this case because it is
>> +     * a read-only inline and we're going to change the values
>> +     * of cpu->cfg.
>> +     */
>> +    cpu = env_archcpu(env);
>> +
>> +    cpu->cfg.ext_i = ext & RVI;
>> +    cpu->cfg.ext_e = ext & RVE;
>> +    cpu->cfg.ext_m = ext & RVM;
>> +    cpu->cfg.ext_a = ext & RVA;
>> +    cpu->cfg.ext_f = ext & RVF;
>> +    cpu->cfg.ext_d = ext & RVD;
>> +    cpu->cfg.ext_v = ext & RVV;
>> +    cpu->cfg.ext_c = ext & RVC;
>> +    cpu->cfg.ext_s = ext & RVS;
>> +    cpu->cfg.ext_u = ext & RVU;
>> +    cpu->cfg.ext_h = ext & RVH;
>> +    cpu->cfg.ext_j = ext & RVJ;
>>   }
>>   #ifndef CONFIG_USER_ONLY
>> @@ -340,7 +372,6 @@ static void riscv_any_cpu_init(Object *obj)
>>   #endif
>>       env->priv_ver = PRIV_VERSION_LATEST;
>> -    register_cpu_props(obj);
> 
> This patch will break the original logic. We can only can a empty CPU here.
> 
>>       /* inherited from parent obj via riscv_cpu_init() */
>>       cpu->cfg.ext_ifencei = true;
>> @@ -368,7 +399,6 @@ static void rv64_sifive_u_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       CPURISCVState *env = &cpu->env;
>>       set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
>> @@ -387,7 +417,6 @@ static void rv64_sifive_e_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> @@ -408,9 +437,6 @@ static void rv64_thead_c906_cpu_init(Object *obj)
>>       env->priv_ver = PRIV_VERSION_1_11_0;
>>       cpu->cfg.ext_g = true;
>> -    cpu->cfg.ext_c = true;
>> -    cpu->cfg.ext_u = true;
>> -    cpu->cfg.ext_s = true;
> 
> Why specially for these configurations?

Because there is a set_misa() call right before:

set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);

And since set_misa() is now syncing with cpu->cfg these are unneeded. There
are no other cases like that in other cpu_init() functions. I'll make sure to
mention this in the commit message in the next version.

Patch 14 is going to do the same thing for ext_g in this same function.


Thanks,

Daniel

> 
> Zhiwei
> 
>>       cpu->cfg.ext_icsr = true;
>>       cpu->cfg.ext_zfh = true;
>>       cpu->cfg.mmu = true;
>> @@ -472,8 +498,6 @@ static void rv32_sifive_u_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       CPURISCVState *env = &cpu->env;
>>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
>> -
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
>> @@ -492,7 +516,6 @@ static void rv32_sifive_e_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> @@ -510,7 +533,6 @@ static void rv32_ibex_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_11_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> @@ -529,7 +551,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
>>       RISCVCPU *cpu = RISCV_CPU(obj);
>>       set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
>> -    register_cpu_props(obj);
>>       env->priv_ver = PRIV_VERSION_1_10_0;
>>   #ifndef CONFIG_USER_ONLY
>>       set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
>> index 76f81c6b68..ebe0fff668 100644
>> --- a/target/riscv/cpu.h
>> +++ b/target/riscv/cpu.h
>> @@ -66,8 +66,8 @@
>>   #define RV(x) ((target_ulong)1 << (x - 'A'))
>>   /*
>> - * Consider updating register_cpu_props() when adding
>> - * new MISA bits here.
>> + * Consider updating set_misa() when adding new
>> + * MISA bits here.
>>    */
>>   #define RVI RV('I')
>>   #define RVE RV('E') /* E and I are mutually exclusive */


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 14/25] target/riscv: add RVG
  2023-03-22 22:19 ` [PATCH for-8.1 v4 14/25] target/riscv: add RVG Daniel Henrique Barboza
@ 2023-03-24 14:43   ` liweiwei
  0 siblings, 0 replies; 42+ messages in thread
From: liweiwei @ 2023-03-24 14:43 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer


On 2023/3/23 06:19, Daniel Henrique Barboza wrote:
> The 'G' bit in misa_ext is a virtual extension that enables a set of
> extensions (i, m, a, f, d, icsr and ifencei). We're already have code to
> handle it but no bit definition. Add it.
>
> Add RVG to set_misa() in rv64_thead_c906_cpu_init() and remove the
> manual cpu->cfg.ext_g assignment while we're at it.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   target/riscv/cpu.c | 8 ++++++--
>   target/riscv/cpu.h | 1 +
>   2 files changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index c4f18d0436..f41888baa0 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -274,6 +274,9 @@ static uint32_t riscv_get_misa_ext_with_cpucfg(RISCVCPUConfig *cfg)
>       if (cfg->ext_j) {
>           ext |= RVJ;
>       }
> +    if (cfg->ext_g) {
> +        ext |= RVG;
> +    }
>   
>       return ext;
>   }
> @@ -293,6 +296,7 @@ static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg,
>       cfg->ext_u = misa_ext & RVU;
>       cfg->ext_h = misa_ext & RVH;
>       cfg->ext_j = misa_ext & RVJ;
> +    cfg->ext_g = misa_ext & RVG;
>   }
>   
>   static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
> @@ -474,10 +478,10 @@ static void rv64_thead_c906_cpu_init(Object *obj)
>       CPURISCVState *env = &RISCV_CPU(obj)->env;
>       RISCVCPU *cpu = RISCV_CPU(obj);
>   
> -    set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> +    set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD |
> +                            RVC | RVS | RVU | RVG);
>       env->priv_ver = PRIV_VERSION_1_11_0;
>   
> -    cpu->cfg.ext_g = true;
>       cpu->cfg.ext_icsr = true;

Assignment for ext_icsr and ext_ifencei also can be deleted when RVG is set.

Regards,

Weiwei Li

>       cpu->cfg.ext_zfh = true;
>       cpu->cfg.mmu = true;
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 2263629332..dbb4df9df0 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -82,6 +82,7 @@
>   #define RVU RV('U')
>   #define RVH RV('H')
>   #define RVJ RV('J')
> +#define RVG RV('G')
>   
>   
>   /* Privileged specification version */



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 15/25] target/riscv/cpu.c: split RVG code from validate_set_extensions()
  2023-03-22 22:19 ` [PATCH for-8.1 v4 15/25] target/riscv/cpu.c: split RVG code from validate_set_extensions() Daniel Henrique Barboza
@ 2023-03-24 14:47   ` liweiwei
  0 siblings, 0 replies; 42+ messages in thread
From: liweiwei @ 2023-03-24 14:47 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, liweiwei, zhiwei_liu, palmer


On 2023/3/23 06:19, Daniel Henrique Barboza wrote:
> We can set all RVG related extensions during realize time, before
> validate_set_extensions() itself. Put it in a separated function so the
> validate function already uses the updated state.
>
> Note that we're setting both cfg->ext_N and env->misa_ext bits, instead
> of just setting cfg->ext_N. The intention here is to start syncing all
> misa_ext operations with its cpu->cfg flags, in preparation to allow for
> the validate function to operate using a misa_ext. This doesn't make any
> difference for the current code state, but will be a requirement for
> write_misa() later on.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   target/riscv/cpu.c | 60 ++++++++++++++++++++++++++++++++++------------
>   1 file changed, 45 insertions(+), 15 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index f41888baa0..a7bad518be 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -281,6 +281,36 @@ static uint32_t riscv_get_misa_ext_with_cpucfg(RISCVCPUConfig *cfg)
>       return ext;
>   }
>   
> +static void riscv_cpu_enable_g(RISCVCPU *cpu, Error **errp)
> +{
> +    CPURISCVState *env = &cpu->env;
> +    RISCVCPUConfig *cfg = &cpu->cfg;
> +
> +    if (!(cfg->ext_i && cfg->ext_m && cfg->ext_a &&
> +          cfg->ext_f && cfg->ext_d &&
> +          cfg->ext_icsr && cfg->ext_ifencei)) {
> +
> +        warn_report("Setting G will also set IMAFD_Zicsr_Zifencei");
> +        cfg->ext_i = true;
> +        env->misa_ext |= RVI;
> +
> +        cfg->ext_m = true;
> +        env->misa_ext |= RVM;
> +
> +        cfg->ext_a = true;
> +        env->misa_ext |= RVA;
> +
> +        cfg->ext_f = true;
> +        env->misa_ext |= RVF;
> +
> +        cfg->ext_d = true;
> +        env->misa_ext |= RVD;
> +
> +        cfg->ext_icsr = true;
> +        cfg->ext_ifencei = true;
> +    }
> +}
> +
>   static void riscv_set_cpucfg_with_misa(RISCVCPUConfig *cfg,
>                                          uint32_t misa_ext)
>   {
> @@ -1033,21 +1063,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
>           return;
>       }
>   
> -    /* Do some ISA extension error checking */
> -    if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
> -                            cpu->cfg.ext_a && cpu->cfg.ext_f &&
> -                            cpu->cfg.ext_d &&
> -                            cpu->cfg.ext_icsr && cpu->cfg.ext_ifencei)) {
> -        warn_report("Setting G will also set IMAFD_Zicsr_Zifencei");
> -        cpu->cfg.ext_i = true;
> -        cpu->cfg.ext_m = true;
> -        cpu->cfg.ext_a = true;
> -        cpu->cfg.ext_f = true;
> -        cpu->cfg.ext_d = true;
> -        cpu->cfg.ext_icsr = true;
> -        cpu->cfg.ext_ifencei = true;
> -    }
> -
>       if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
>           error_setg(errp,
>                      "I and E extensions are incompatible");
> @@ -1290,6 +1305,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
>       CPUState *cs = CPU(dev);
>       RISCVCPU *cpu = RISCV_CPU(dev);
>       RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
> +    CPURISCVState *env = &cpu->env;
>       Error *local_err = NULL;
>   
>       cpu_exec_realizefn(cs, &local_err);
> @@ -1310,6 +1326,20 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
>           return;
>       }
>   
> +    if (cpu->cfg.ext_g) {
> +        riscv_cpu_enable_g(cpu, &local_err);
> +        if (local_err != NULL) {
> +            error_propagate(errp, local_err);
> +            return;
> +        }
> +
> +        /*
> +         * Sync env->misa_ext_mask with the new
> +         * env->misa_ext val.
> +         */
> +        env->misa_ext_mask = env->misa_ext;

This sync can also be done in  riscv_cpu_enable_g.

Regards,

Weiwei Li

> +    }
> +
>       riscv_cpu_validate_set_extensions(cpu, &local_err);
>       if (local_err != NULL) {
>           error_propagate(errp, local_err);



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 18/25] target/riscv: error out on priv failure for RVH
  2023-03-22 22:19 ` [PATCH for-8.1 v4 18/25] target/riscv: error out on priv failure for RVH Daniel Henrique Barboza
@ 2023-03-24 14:56   ` liweiwei
  2023-03-28 14:33     ` Daniel Henrique Barboza
  0 siblings, 1 reply; 42+ messages in thread
From: liweiwei @ 2023-03-24 14:56 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: liweiwei, qemu-riscv, alistair.francis, bmeng, zhiwei_liu, palmer


On 2023/3/23 06:19, Daniel Henrique Barboza wrote:
> riscv_cpu_disable_priv_spec_isa_exts(), at the end of
> riscv_cpu_validate_set_extensions(), will disable cpu->cfg.ext_h and
> cpu->cfg.ext_v if priv_ver check fails.
>
> This check can be done in riscv_cpu_validate_misa_ext(). The difference
> here is that we're not silently disable it: we'll error out. Silently
> disabling a MISA extension after all the validation is completed can can
> cause inconsistencies that we don't have to deal with. Verify ealier and
> fail faster.
>
> Note that we're ignoring RVV priv_ver validation since its minimal priv
> is also the minimal value we support. RVH will error out if enabled
> under priv_ver under 1_12_0.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   target/riscv/cpu.c | 14 ++++++++++++++
>   1 file changed, 14 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 399f63b42f..d2eb2b3ba1 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1055,6 +1055,20 @@ static void riscv_cpu_validate_misa_ext(RISCVCPU *cpu, Error **errp)
>           return;
>       }
>   
> +    /*
> +     * Check for priv spec version. RVH is 1_12_0, RVV is 1_10_0.
> +     * We don't support anything under 1_10_0 so skip checking
> +     * priv for RVV.
> +     *
> +     * We're hardcoding it here to avoid looping into the
> +     * 50+ entries of isa_edata_arr[] just to check the RVH
> +     * entry.
> +     */
> +    if (cpu->cfg.ext_h && env->priv_ver < PRIV_VERSION_1_12_0) {
> +        error_setg(errp, "H extension requires priv spec 1.12.0");
> +        return;
> +    }
The other multi-letter extensions are directly disabled for lower priv 
version with warning message.

Whether we should do the similar action here?

Regards,

Weiwei Li

> +
>       if (cpu->cfg.ext_v) {
>           riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
>           if (local_err != NULL) {



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 22/25] target/riscv: use misa_ext val in riscv_cpu_validate_extensions()
  2023-03-22 22:20 ` [PATCH for-8.1 v4 22/25] target/riscv: use misa_ext val in riscv_cpu_validate_extensions() Daniel Henrique Barboza
@ 2023-03-24 15:06   ` liweiwei
  0 siblings, 0 replies; 42+ messages in thread
From: liweiwei @ 2023-03-24 15:06 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: liweiwei, qemu-riscv, alistair.francis, bmeng, zhiwei_liu, palmer


On 2023/3/23 06:20, Daniel Henrique Barboza wrote:
> Similar to what we did with riscv_cpu_validate_misa_ext(), let's read
> all MISA bits from a misa_ext val instead of reading from the cpu->cfg
> object.
>
> This will allow write_misa() to use riscv_cpu_validate_extensions().
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   target/riscv/cpu.c | 25 ++++++++++++++-----------
>   1 file changed, 14 insertions(+), 11 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index ed02332093..0e6b8fb45e 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1109,10 +1109,13 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
>   }
>   
>   /*
> - * Check consistency between chosen extensions. No changes
> - * in env->misa_ext are made.
> + * Check consistency between cpu->cfg extensions and a
> + * candidate misa_ext value. No changes in env->misa_ext
> + * are made.
>    */
> -static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp)
> +static void riscv_cpu_validate_extensions(RISCVCPU *cpu,
> +                                          uint32_t misa_ext,
> +                                          Error **errp)
>   {
>       if (cpu->cfg.epmp && !cpu->cfg.pmp) {
>           /*
> @@ -1123,12 +1126,12 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp)
>           return;
>       }
>   
> -    if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) {
> +    if (misa_ext & RVF && !cpu->cfg.ext_icsr) {
>           error_setg(errp, "F extension requires Zicsr");
>           return;
>       }

This check needn't be done for write_misa. Similar to several other checks.

Maybe we can take them out as a new function to share between 
validate_extensions and write_misa.

In fact, only a few check should be done for write_misa when 
multi-letter extensions require single-letter extensions.

Regards,

Weiwei Li

>   
> -    if ((cpu->cfg.ext_zawrs) && !cpu->cfg.ext_a) {
> +    if ((cpu->cfg.ext_zawrs) && !(misa_ext & RVA)) {
>           error_setg(errp, "Zawrs extension requires A extension");
>           return;
>       }
> @@ -1137,13 +1140,13 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp)
>           cpu->cfg.ext_zfhmin = true;
>       }
>   
> -    if (cpu->cfg.ext_zfhmin && !cpu->cfg.ext_f) {
> +    if (cpu->cfg.ext_zfhmin && !(misa_ext & RVF)) {
>           error_setg(errp, "Zfh/Zfhmin extensions require F extension");
>           return;
>       }
>   
>       /* The V vector extension depends on the Zve64d extension */
> -    if (cpu->cfg.ext_v) {
> +    if (misa_ext & RVV) {
>           cpu->cfg.ext_zve64d = true;
>       }
>   
> @@ -1157,12 +1160,12 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp)
>           cpu->cfg.ext_zve32f = true;
>       }
>   
> -    if (cpu->cfg.ext_zve64d && !cpu->cfg.ext_d) {
> +    if (cpu->cfg.ext_zve64d && !(misa_ext & RVD)) {
>           error_setg(errp, "Zve64d/V extensions require D extension");
>           return;
>       }
>   
> -    if (cpu->cfg.ext_zve32f && !cpu->cfg.ext_f) {
> +    if (cpu->cfg.ext_zve32f && !(misa_ext & RVF)) {
>           error_setg(errp, "Zve32f/Zve64f extensions require F extension");
>           return;
>       }
> @@ -1195,7 +1198,7 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu, Error **errp)
>               error_setg(errp, "Zfinx extension requires Zicsr");
>               return;
>           }
> -        if (cpu->cfg.ext_f) {
> +        if (misa_ext & RVF) {
>               error_setg(errp,
>                          "Zfinx cannot be supported together with F extension");
>               return;
> @@ -1367,7 +1370,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
>           return;
>       }
>   
> -    riscv_cpu_validate_extensions(cpu, &local_err);
> +    riscv_cpu_validate_extensions(cpu, env->misa_ext, &local_err);
>       if (local_err != NULL) {
>           error_propagate(errp, local_err);
>           return;



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 23/25] target/riscv: rework write_misa()
  2023-03-22 22:20 ` [PATCH for-8.1 v4 23/25] target/riscv: rework write_misa() Daniel Henrique Barboza
@ 2023-03-24 15:09   ` liweiwei
  0 siblings, 0 replies; 42+ messages in thread
From: liweiwei @ 2023-03-24 15:09 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: liweiwei, qemu-riscv, alistair.francis, bmeng, zhiwei_liu, palmer


On 2023/3/23 06:20, Daniel Henrique Barboza wrote:
> write_misa() must use as much common logic as possible. We want to open
> code just the bits that are exclusive to the CSR write operation and TCG
> internals.
>
> Rewrite write_misa() to work as follows:
>
> - mask the write using misa_ext_mask to avoid enabling unsupported
>    extensions;
>
> - suppress RVC if the next insn isn't aligned;
>
> - handle RVE. This is done by filtering all bits but RVE from 'val'.
>    Setting RVE will forcefully set only RVE - assuming it gets
>    validated afterwards;
>
> - emulate the steps done by realize(): validate the candidate misa_ext
>    val, then validate the configuration with the candidate misa_ext val,
>    and finally commit the changes to cpu->cfg.
>
> If any of the validation steps fails, the write operation is a no-op.
>
> Let's keep write_misa() as experimental for now until this logic gains
> enough mileage.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   target/riscv/cpu.c | 12 ++++------
>   target/riscv/cpu.h |  6 +++++
>   target/riscv/csr.c | 59 ++++++++++++++++++++++++++--------------------
>   3 files changed, 45 insertions(+), 32 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0e6b8fb45e..41b17ba0c3 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1018,9 +1018,8 @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
>   }
>   
>   
> -static void riscv_cpu_validate_misa_ext(CPURISCVState *env,
> -                                        uint32_t misa_ext,
> -                                        Error **errp)
> +void riscv_cpu_validate_misa_ext(CPURISCVState *env, uint32_t misa_ext,
> +                                 Error **errp)
>   {
>       Error *local_err = NULL;
>   
> @@ -1113,9 +1112,8 @@ static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
>    * candidate misa_ext value. No changes in env->misa_ext
>    * are made.
>    */
> -static void riscv_cpu_validate_extensions(RISCVCPU *cpu,
> -                                          uint32_t misa_ext,
> -                                          Error **errp)
> +void riscv_cpu_validate_extensions(RISCVCPU *cpu, uint32_t misa_ext,
> +                                   Error **errp)
>   {
>       if (cpu->cfg.epmp && !cpu->cfg.pmp) {
>           /*
> @@ -1206,7 +1204,7 @@ static void riscv_cpu_validate_extensions(RISCVCPU *cpu,
>       }
>   }
>   
> -static void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu)
> +void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu)
>   {
>       if (cpu->cfg.ext_zk) {
>           cpu->cfg.ext_zkn = true;
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index dbb4df9df0..ca2ba6a647 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -593,6 +593,12 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>   char *riscv_isa_string(RISCVCPU *cpu);
>   void riscv_cpu_list(void);
>   
> +void riscv_cpu_validate_misa_ext(CPURISCVState *env, uint32_t misa_ext,
> +                                 Error **errp);
> +void riscv_cpu_validate_extensions(RISCVCPU *cpu, uint32_t misa_ext,
> +                                   Error **errp);
> +void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu);
> +
>   #define cpu_list riscv_cpu_list
>   #define cpu_mmu_index riscv_cpu_mmu_index
>   
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index d522efc0b6..8d5e8f9ad1 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1343,39 +1343,17 @@ static RISCVException read_misa(CPURISCVState *env, int csrno,
>   static RISCVException write_misa(CPURISCVState *env, int csrno,
>                                    target_ulong val)
>   {
> +    RISCVCPU *cpu = env_archcpu(env);
> +    Error *local_err = NULL;
> +
>       if (!riscv_cpu_cfg(env)->misa_w) {
>           /* drop write to misa */
>           return RISCV_EXCP_NONE;
>       }
>   
> -    /* 'I' or 'E' must be present */
> -    if (!(val & (RVI | RVE))) {
> -        /* It is not, drop write to misa */
> -        return RISCV_EXCP_NONE;
> -    }
> -
> -    /* 'E' excludes all other extensions */
> -    if (val & RVE) {
> -        /*
> -         * when we support 'E' we can do "val = RVE;" however
> -         * for now we just drop writes if 'E' is present.
> -         */
> -        return RISCV_EXCP_NONE;
> -    }
> -
> -    /*
> -     * misa.MXL writes are not supported by QEMU.
> -     * Drop writes to those bits.
> -     */
> -
>       /* Mask extensions that are not supported by this hart */
>       val &= env->misa_ext_mask;
>   
> -    /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
> -    if ((val & RVD) && !(val & RVF)) {
> -        val &= ~RVD;
> -    }
> -
>       /*
>        * Suppress 'C' if next instruction is not aligned
>        * TODO: this should check next_pc
> @@ -1389,6 +1367,37 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
>           return RISCV_EXCP_NONE;
>       }
>   
> +    /*
> +     * We'll handle special cases in separate. If one
> +     * of these bits are enabled we'll handle them and
> +     * end the CSR write.
> +     */
> +    if (val & RVE && !(env->misa_ext & RVE)) {
> +        /*
> +         * RVE must be enabled by itself. Clear all other
> +         * misa_env bits and let the validation do its
> +         * job.
> +         */
> +        val &= RVE;

It can just be val = RVE here.

Regards,

Weiwei Li

> +    }
> +
> +    /*
> +     * This flow is similar to what riscv_cpu_realize() does,
> +     * with the difference that we will update env->misa_ext
> +     * value if everything is ok.
> +     */
> +    riscv_cpu_validate_misa_ext(env, val, &local_err);
> +    if (local_err != NULL) {
> +        return RISCV_EXCP_NONE;
> +    }
> +
> +    riscv_cpu_validate_extensions(cpu, val, &local_err);
> +    if (local_err != NULL) {
> +        return RISCV_EXCP_NONE;
> +    }
> +
> +    riscv_cpu_commit_cpu_cfg(cpu);
> +
>       if (!(val & RVF)) {
>           env->mstatus &= ~MSTATUS_FS;
>       }



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 24/25] target/riscv: update cpu->cfg misa bits in commit_cpu_cfg()
  2023-03-22 22:20 ` [PATCH for-8.1 v4 24/25] target/riscv: update cpu->cfg misa bits in commit_cpu_cfg() Daniel Henrique Barboza
@ 2023-03-24 15:14   ` liweiwei
  0 siblings, 0 replies; 42+ messages in thread
From: liweiwei @ 2023-03-24 15:14 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: liweiwei, qemu-riscv, alistair.francis, bmeng, zhiwei_liu, palmer

[-- Attachment #1: Type: text/plain, Size: 3635 bytes --]


On 2023/3/23 06:20, Daniel Henrique Barboza wrote:
> write_misa() is able to use the same validation workflow
> riscv_cpu_realize() uses. But it's still not capable of updating
> cpu->cfg misa props yet.
>
> We have no way of blocking future (and current) code from checking
> env->misa_ext (via riscv_has_ext()) or reading cpu->cfg directly, so our
> best alternative is to keep everything in sync.
>
> riscv_cpu_commit_cpu_cfg() now receives an extra 'misa_ext' parameter.
> If this val is different from the existing env->misa_ext, update
> env->misa and cpu->cfg with the new value. riscv_cpu_realize() will
> ignore this code since env->misa_ext isn't touched during validation,
> but write_misa() will use it to keep cpu->cfg in sync with the new
> env->misa_ext value.
>
> Signed-off-by: Daniel Henrique Barboza<dbarboza@ventanamicro.com>
> ---
>   target/riscv/cpu.c | 16 ++++++++++++++--
>   target/riscv/cpu.h |  2 +-
>   target/riscv/csr.c |  3 +--
>   3 files changed, 16 insertions(+), 5 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 41b17ba0c3..88806d1050 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1204,8 +1204,20 @@ void riscv_cpu_validate_extensions(RISCVCPU *cpu, uint32_t misa_ext,
>       }
>   }
>   
> -void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu)
> +void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu, uint32_t misa_ext)
>   {
> +    CPURISCVState *env = &cpu->env;
> +
> +    /*
> +     * write_misa() needs to update cpu->cfg with the new
> +     * MISA bits. This is a no-op for the riscv_cpu_realize()
> +     * path.
> +     */
> +    if (env->misa_ext != misa_ext) {
> +        env->misa_ext = misa_ext;
> +        riscv_set_cpucfg_with_misa(&cpu->cfg, misa_ext);
> +    }
> +
>       if (cpu->cfg.ext_zk) {
>           cpu->cfg.ext_zkn = true;
>           cpu->cfg.ext_zkr = true;

These zk* related assignment and riscv_cpu_disable_priv_spec_isa_exts() 
can be moved to other places.

They needn't be done for write_misa.

Regards,

Weiwei Li

> @@ -1374,7 +1386,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
>           return;
>       }
>   
> -    riscv_cpu_commit_cpu_cfg(cpu);
> +    riscv_cpu_commit_cpu_cfg(cpu, env->misa_ext);
>   
>   #ifndef CONFIG_USER_ONLY
>       if (cpu->cfg.ext_sstc) {
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index ca2ba6a647..befc3b8fff 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -597,7 +597,7 @@ void riscv_cpu_validate_misa_ext(CPURISCVState *env, uint32_t misa_ext,
>                                    Error **errp);
>   void riscv_cpu_validate_extensions(RISCVCPU *cpu, uint32_t misa_ext,
>                                      Error **errp);
> -void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu);
> +void riscv_cpu_commit_cpu_cfg(RISCVCPU *cpu, uint32_t misa_ext);
>   
>   #define cpu_list riscv_cpu_list
>   #define cpu_mmu_index riscv_cpu_mmu_index
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 8d5e8f9ad1..839862f1a8 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1396,7 +1396,7 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
>           return RISCV_EXCP_NONE;
>       }
>   
> -    riscv_cpu_commit_cpu_cfg(cpu);
> +    riscv_cpu_commit_cpu_cfg(cpu, val);
>   
>       if (!(val & RVF)) {
>           env->mstatus &= ~MSTATUS_FS;
> @@ -1404,7 +1404,6 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
>   
>       /* flush translation cache */
>       tb_flush(env_cpu(env));
> -    env->misa_ext = val;
>       env->xl = riscv_cpu_mxl(env);
>       return RISCV_EXCP_NONE;
>   }

[-- Attachment #2: Type: text/html, Size: 4196 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH for-8.1 v4 18/25] target/riscv: error out on priv failure for RVH
  2023-03-24 14:56   ` liweiwei
@ 2023-03-28 14:33     ` Daniel Henrique Barboza
  0 siblings, 0 replies; 42+ messages in thread
From: Daniel Henrique Barboza @ 2023-03-28 14:33 UTC (permalink / raw)
  To: liweiwei, qemu-devel
  Cc: qemu-riscv, alistair.francis, bmeng, zhiwei_liu, palmer



On 3/24/23 11:56, liweiwei wrote:
> 
> On 2023/3/23 06:19, Daniel Henrique Barboza wrote:
>> riscv_cpu_disable_priv_spec_isa_exts(), at the end of
>> riscv_cpu_validate_set_extensions(), will disable cpu->cfg.ext_h and
>> cpu->cfg.ext_v if priv_ver check fails.
>>
>> This check can be done in riscv_cpu_validate_misa_ext(). The difference
>> here is that we're not silently disable it: we'll error out. Silently
>> disabling a MISA extension after all the validation is completed can can
>> cause inconsistencies that we don't have to deal with. Verify ealier and
>> fail faster.
>>
>> Note that we're ignoring RVV priv_ver validation since its minimal priv
>> is also the minimal value we support. RVH will error out if enabled
>> under priv_ver under 1_12_0.
>>
>> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>> ---
>>   target/riscv/cpu.c | 14 ++++++++++++++
>>   1 file changed, 14 insertions(+)
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index 399f63b42f..d2eb2b3ba1 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -1055,6 +1055,20 @@ static void riscv_cpu_validate_misa_ext(RISCVCPU *cpu, Error **errp)
>>           return;
>>       }
>> +    /*
>> +     * Check for priv spec version. RVH is 1_12_0, RVV is 1_10_0.
>> +     * We don't support anything under 1_10_0 so skip checking
>> +     * priv for RVV.
>> +     *
>> +     * We're hardcoding it here to avoid looping into the
>> +     * 50+ entries of isa_edata_arr[] just to check the RVH
>> +     * entry.
>> +     */
>> +    if (cpu->cfg.ext_h && env->priv_ver < PRIV_VERSION_1_12_0) {
>> +        error_setg(errp, "H extension requires priv spec 1.12.0");
>> +        return;
>> +    }
> The other multi-letter extensions are directly disabled for lower priv version with warning message.
> 
> Whether we should do the similar action here?

I'd rather error out in all cases, to be honest. cpu_init() functions should be
responsible for choosing an adequate priv spec level for the extensions it wants
to use.


Thanks,


Daniel

> 
> Regards,
> 
> Weiwei Li
> 
>> +
>>       if (cpu->cfg.ext_v) {
>>           riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
>>           if (local_err != NULL) {
> 


^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2023-03-28 14:33 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-22 22:19 [PATCH for-8.1 v4 00/25] target/riscv: rework CPU extensions validation Daniel Henrique Barboza
2023-03-22 22:19 ` [PATCH for-8.1 v4 01/25] target/riscv/cpu.c: add riscv_cpu_validate_v() Daniel Henrique Barboza
2023-03-22 22:19 ` [PATCH for-8.1 v4 02/25] target/riscv/cpu.c: remove set_vext_version() Daniel Henrique Barboza
2023-03-22 22:19 ` [PATCH for-8.1 v4 03/25] target/riscv/cpu.c: remove set_priv_version() Daniel Henrique Barboza
2023-03-22 22:19 ` [PATCH for-8.1 v4 04/25] target/riscv: add PRIV_VERSION_LATEST Daniel Henrique Barboza
2023-03-22 22:19 ` [PATCH for-8.1 v4 05/25] target/riscv/cpu.c: add priv_spec validate/disable_exts helpers Daniel Henrique Barboza
2023-03-22 22:19 ` [PATCH for-8.1 v4 06/25] target/riscv/cpu.c: add riscv_cpu_validate_misa_mxl() Daniel Henrique Barboza
2023-03-23  1:35   ` LIU Zhiwei
2023-03-22 22:19 ` [PATCH for-8.1 v4 07/25] target/riscv: move pmp and epmp validations to validate_set_extensions() Daniel Henrique Barboza
2023-03-23  1:42   ` LIU Zhiwei
2023-03-22 22:19 ` [PATCH for-8.1 v4 08/25] target/riscv/cpu.c: validate extensions before riscv_timer_init() Daniel Henrique Barboza
2023-03-23  1:52   ` LIU Zhiwei
2023-03-22 22:19 ` [PATCH for-8.1 v4 09/25] target/riscv/cpu.c: remove cfg setup from riscv_cpu_init() Daniel Henrique Barboza
2023-03-23  2:02   ` LIU Zhiwei
2023-03-22 22:19 ` [PATCH for-8.1 v4 10/25] target/riscv/cpu.c: avoid set_misa() in validate_set_extensions() Daniel Henrique Barboza
2023-03-23  2:04   ` LIU Zhiwei
2023-03-22 22:19 ` [PATCH for-8.1 v4 11/25] target/riscv/cpu.c: set cpu config in set_misa() Daniel Henrique Barboza
2023-03-23  2:14   ` LIU Zhiwei
2023-03-23  2:18     ` LIU Zhiwei
2023-03-23 23:23     ` Daniel Henrique Barboza
2023-03-22 22:19 ` [PATCH for-8.1 v4 12/25] target/riscv/cpu.c: redesign register_cpu_props() Daniel Henrique Barboza
2023-03-23  3:22   ` LIU Zhiwei
2023-03-22 22:19 ` [PATCH for-8.1 v4 13/25] target/riscv: put env->misa_ext <-> cpu->cfg code into helpers Daniel Henrique Barboza
2023-03-22 22:19 ` [PATCH for-8.1 v4 14/25] target/riscv: add RVG Daniel Henrique Barboza
2023-03-24 14:43   ` liweiwei
2023-03-22 22:19 ` [PATCH for-8.1 v4 15/25] target/riscv/cpu.c: split RVG code from validate_set_extensions() Daniel Henrique Barboza
2023-03-24 14:47   ` liweiwei
2023-03-22 22:19 ` [PATCH for-8.1 v4 16/25] target/riscv/cpu.c: add riscv_cpu_validate_misa_ext() Daniel Henrique Barboza
2023-03-22 22:19 ` [PATCH for-8.1 v4 17/25] target/riscv: move riscv_cpu_validate_v() to validate_misa_ext() Daniel Henrique Barboza
2023-03-22 22:19 ` [PATCH for-8.1 v4 18/25] target/riscv: error out on priv failure for RVH Daniel Henrique Barboza
2023-03-24 14:56   ` liweiwei
2023-03-28 14:33     ` Daniel Henrique Barboza
2023-03-22 22:19 ` [PATCH for-8.1 v4 19/25] target/riscv: write env->misa_ext* in register_generic_cpu_props() Daniel Henrique Barboza
2023-03-22 22:19 ` [PATCH for-8.1 v4 20/25] target/riscv: make validate_misa_ext() use a misa_ext val Daniel Henrique Barboza
2023-03-22 22:20 ` [PATCH for-8.1 v4 21/25] target/riscv: split riscv_cpu_validate_set_extensions() Daniel Henrique Barboza
2023-03-22 22:20 ` [PATCH for-8.1 v4 22/25] target/riscv: use misa_ext val in riscv_cpu_validate_extensions() Daniel Henrique Barboza
2023-03-24 15:06   ` liweiwei
2023-03-22 22:20 ` [PATCH for-8.1 v4 23/25] target/riscv: rework write_misa() Daniel Henrique Barboza
2023-03-24 15:09   ` liweiwei
2023-03-22 22:20 ` [PATCH for-8.1 v4 24/25] target/riscv: update cpu->cfg misa bits in commit_cpu_cfg() Daniel Henrique Barboza
2023-03-24 15:14   ` liweiwei
2023-03-22 22:20 ` [PATCH for-8.1 v4 25/25] target/riscv: handle RVG updates in write_misa() Daniel Henrique Barboza

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).