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 <luisccunha8@gmail.com>
---
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