diff options
-rw-r--r-- | target/riscv/riscv-qmp-cmds.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c index 2170562..5b2d186 100644 --- a/target/riscv/riscv-qmp-cmds.c +++ b/target/riscv/riscv-qmp-cmds.c @@ -27,6 +27,9 @@ #include "qapi/error.h" #include "qapi/qapi-commands-machine-target.h" #include "qapi/qmp/qdict.h" +#include "qapi/qmp/qerror.h" +#include "qapi/qobject-input-visitor.h" +#include "qapi/visitor.h" #include "qom/qom-qobject.h" #include "cpu-qom.h" #include "cpu.h" @@ -83,14 +86,58 @@ static void riscv_obj_add_multiext_props(Object *obj, QDict *qdict_out, } } +static void riscv_cpuobj_validate_qdict_in(Object *obj, QObject *props, + const QDict *qdict_in, + Error **errp) +{ + const QDictEntry *qe; + Visitor *visitor; + Error *local_err = NULL; + + visitor = qobject_input_visitor_new(props); + if (!visit_start_struct(visitor, NULL, NULL, 0, &local_err)) { + goto err; + } + + for (qe = qdict_first(qdict_in); qe; qe = qdict_next(qdict_in, qe)) { + object_property_find_err(obj, qe->key, &local_err); + if (local_err) { + goto err; + } + + object_property_set(obj, qe->key, visitor, &local_err); + if (local_err) { + goto err; + } + } + + visit_check_struct(visitor, &local_err); + if (local_err) { + goto err; + } + + riscv_cpu_finalize_features(RISCV_CPU(obj), &local_err); + if (local_err) { + goto err; + } + + visit_end_struct(visitor, NULL); + +err: + error_propagate(errp, local_err); + visit_free(visitor); +} + CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, CpuModelInfo *model, Error **errp) { CpuModelExpansionInfo *expansion_info; + const QDict *qdict_in = NULL; QDict *qdict_out; ObjectClass *oc; Object *obj; + Error *local_err = NULL; if (type != CPU_MODEL_EXPANSION_TYPE_FULL) { error_setg(errp, "The requested expansion type is not supported"); @@ -104,8 +151,26 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, return NULL; } + if (model->props) { + qdict_in = qobject_to(QDict, model->props); + if (!qdict_in) { + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict"); + return NULL; + } + } + obj = object_new(object_class_get_name(oc)); + if (qdict_in) { + riscv_cpuobj_validate_qdict_in(obj, model->props, qdict_in, + &local_err); + if (local_err) { + error_propagate(errp, local_err); + object_unref(obj); + return NULL; + } + } + expansion_info = g_new0(CpuModelExpansionInfo, 1); expansion_info->model = g_malloc0(sizeof(*expansion_info->model)); expansion_info->model->name = g_strdup(model->name); |