aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/riscv/tcg/tcg-cpu.c64
1 files changed, 50 insertions, 14 deletions
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 104e91846a..2e462e7d11 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -549,6 +549,11 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
riscv_cpu_disable_priv_spec_isa_exts(cpu);
}
+static bool riscv_cpu_is_generic(Object *cpu_obj)
+{
+ return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
+}
+
/*
* We'll get here via the following path:
*
@@ -632,13 +637,27 @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
target_ulong misa_bit = misa_ext_cfg->misa_bit;
RISCVCPU *cpu = RISCV_CPU(obj);
CPURISCVState *env = &cpu->env;
- bool value;
+ bool generic_cpu = riscv_cpu_is_generic(obj);
+ bool prev_val, value;
if (!visit_type_bool(v, name, &value, errp)) {
return;
}
+ prev_val = env->misa_ext & misa_bit;
+
+ if (value == prev_val) {
+ return;
+ }
+
if (value) {
+ if (!generic_cpu) {
+ g_autofree char *cpuname = riscv_cpu_get_name(cpu);
+ error_setg(errp, "'%s' CPU does not allow enabling extensions",
+ cpuname);
+ return;
+ }
+
env->misa_ext |= misa_bit;
env->misa_ext_mask |= misa_bit;
} else {
@@ -688,6 +707,7 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
*/
static void riscv_cpu_add_misa_properties(Object *cpu_obj)
{
+ bool use_def_vals = riscv_cpu_is_generic(cpu_obj);
int i;
for (i = 0; i < ARRAY_SIZE(misa_ext_cfgs); i++) {
@@ -706,7 +726,9 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
cpu_set_misa_ext_cfg,
NULL, (void *)misa_cfg);
object_property_set_description(cpu_obj, name, desc);
- object_property_set_bool(cpu_obj, name, misa_cfg->enabled, NULL);
+ if (use_def_vals) {
+ object_property_set_bool(cpu_obj, name, misa_cfg->enabled, NULL);
+ }
}
}
@@ -714,17 +736,32 @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
const RISCVCPUMultiExtConfig *multi_ext_cfg = opaque;
- bool value;
+ RISCVCPU *cpu = RISCV_CPU(obj);
+ bool generic_cpu = riscv_cpu_is_generic(obj);
+ bool prev_val, value;
if (!visit_type_bool(v, name, &value, errp)) {
return;
}
- isa_ext_update_enabled(RISCV_CPU(obj), multi_ext_cfg->offset, value);
-
g_hash_table_insert(multi_ext_user_opts,
GUINT_TO_POINTER(multi_ext_cfg->offset),
(gpointer)value);
+
+ prev_val = isa_ext_is_enabled(cpu, multi_ext_cfg->offset);
+
+ if (value == prev_val) {
+ return;
+ }
+
+ if (value && !generic_cpu) {
+ g_autofree char *cpuname = riscv_cpu_get_name(cpu);
+ error_setg(errp, "'%s' CPU does not allow enabling extensions",
+ cpuname);
+ return;
+ }
+
+ isa_ext_update_enabled(cpu, multi_ext_cfg->offset, value);
}
static void cpu_get_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
@@ -739,11 +776,17 @@ static void cpu_get_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
static void cpu_add_multi_ext_prop(Object *cpu_obj,
const RISCVCPUMultiExtConfig *multi_cfg)
{
+ bool generic_cpu = riscv_cpu_is_generic(cpu_obj);
+
object_property_add(cpu_obj, multi_cfg->name, "bool",
cpu_get_multi_ext_cfg,
cpu_set_multi_ext_cfg,
NULL, (void *)multi_cfg);
+ if (!generic_cpu) {
+ return;
+ }
+
/*
* Set def val directly instead of using
* object_property_set_bool() to save the set()
@@ -828,20 +871,13 @@ static bool riscv_cpu_has_max_extensions(Object *cpu_obj)
return object_dynamic_cast(cpu_obj, TYPE_RISCV_CPU_MAX) != NULL;
}
-static bool riscv_cpu_has_user_properties(Object *cpu_obj)
-{
- return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
-}
-
static void tcg_cpu_instance_init(CPUState *cs)
{
RISCVCPU *cpu = RISCV_CPU(cs);
Object *obj = OBJECT(cpu);
- if (riscv_cpu_has_user_properties(obj)) {
- multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
- riscv_cpu_add_user_properties(obj);
- }
+ multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
+ riscv_cpu_add_user_properties(obj);
if (riscv_cpu_has_max_extensions(obj)) {
riscv_init_max_cpu_extensions(obj);