Add CPU properties to control the SPMP and sspmpen extensions from the QEMU 
command line.

SPMP can be enabled with:
  -cpu <model>,spmp=true
Note: This automatically enables smpmpdeleg, sscsrind, and smcsrind.

The sspmpen extension can be enabled with:
  -cpu <model>,sspmpen=true
Note: This automatically enables SPMP and its depedencies.

Signed-off-by: Luis Cunha <[email protected]>
---
 target/riscv/cpu.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5383e07dbd..29bfce6581 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1656,6 +1656,84 @@ static const PropertyInfo prop_pmp_granularity = {
     .set = prop_pmp_granularity_set,
 };
 
+static void prop_spmp_set(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp)
+{
+    RISCVCPU *cpu = RISCV_CPU(obj);
+    bool value;
+
+    visit_type_bool(v, name, &value, errp);
+
+    if (cpu->cfg.spmp != value && riscv_cpu_is_vendor(obj)) {
+        cpu_set_prop_err(cpu, name, errp);
+        return;
+    }
+
+    cpu_option_add_user_setting(name, value);
+    cpu->cfg.spmp = value;
+    cpu->cfg.ext_smpmpdeleg = value;
+
+    /* Enable necessary extensions */
+    if (value) {
+        cpu->cfg.ext_sscsrind = true;
+        cpu->cfg.ext_smcsrind = true;
+    }
+}
+
+static void prop_spmp_get(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp)
+{
+    bool value = RISCV_CPU(obj)->cfg.spmp;
+
+    visit_type_bool(v, name, &value, errp);
+}
+
+static const PropertyInfo prop_spmp = {
+    .type = "bool",
+    .description = "spmp",
+    .get = prop_spmp_get,
+    .set = prop_spmp_set,
+};
+
+static void prop_sspmpen_set(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp)
+{
+    RISCVCPU *cpu = RISCV_CPU(obj);
+    bool value;
+
+    visit_type_bool(v, name, &value, errp);
+
+    if (cpu->cfg.spmp != value && riscv_cpu_is_vendor(obj)) {
+        cpu_set_prop_err(cpu, name, errp);
+        return;
+    }
+
+    cpu_option_add_user_setting(name, value);
+    cpu->cfg.ext_sspmpen = value;
+
+    /* Enable necessary extensions */
+    if (value) {
+        cpu->cfg.spmp = true;
+        cpu->cfg.ext_sscsrind = true;
+        cpu->cfg.ext_smcsrind = true;
+    }
+}
+
+static void prop_sspmpen_get(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp)
+{
+    bool value = RISCV_CPU(obj)->cfg.ext_sspmpen;
+
+    visit_type_bool(v, name, &value, errp);
+}
+
+static const PropertyInfo prop_ext_sspmpen = {
+    .type = "bool",
+    .description = "ext_sspmpen",
+    .get = prop_sspmpen_get,
+    .set = prop_sspmpen_set,
+};
+
 static int priv_spec_from_str(const char *priv_spec_str)
 {
     int priv_version = -1;
@@ -2657,6 +2735,8 @@ static const Property riscv_cpu_properties[] = {
     {.name = "pmp", .info = &prop_pmp},
     {.name = "num-pmp-regions", .info = &prop_num_pmp_regions},
     {.name = "pmp-granularity", .info = &prop_pmp_granularity},
+    {.name = "spmp", .info = &prop_spmp},
+    {.name = "sspmpen", .info = &prop_ext_sspmpen},
 
     {.name = "priv_spec", .info = &prop_priv_spec},
     {.name = "vext_spec", .info = &prop_vext_spec},
-- 
2.43.0


Reply via email to