xref: /openbmc/qemu/target/loongarch/loongarch-qmp-cmds.c (revision e452053097371880910c744a5d42ae2df058a4a7)
1 /*
2  * QEMU LoongArch CPU (monitor definitions)
3  *
4  * SPDX-FileCopyrightText: 2021 Loongson Technology Corporation Limited
5  *
6  * SPDX-License-Identifier: GPL-2.0-or-later
7  */
8 
9 #include "qemu/osdep.h"
10 #include "qemu/target-info.h"
11 #include "qapi/error.h"
12 #include "qapi/qapi-commands-machine.h"
13 #include "cpu.h"
14 #include "qobject/qdict.h"
15 #include "qapi/qobject-input-visitor.h"
16 #include "qom/qom-qobject.h"
17 
loongarch_cpu_add_definition(gpointer data,gpointer user_data)18 static void loongarch_cpu_add_definition(gpointer data, gpointer user_data)
19 {
20     ObjectClass *oc = data;
21     CpuDefinitionInfoList **cpu_list = user_data;
22     CpuDefinitionInfo *info = g_new0(CpuDefinitionInfo, 1);
23     const char *typename = object_class_get_name(oc);
24 
25     info->name = cpu_model_from_type(typename);
26     info->q_typename = g_strdup(typename);
27 
28     QAPI_LIST_PREPEND(*cpu_list, info);
29 }
30 
qmp_query_cpu_definitions(Error ** errp)31 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
32 {
33     CpuDefinitionInfoList *cpu_list = NULL;
34     GSList *list;
35 
36     list = object_class_get_list(target_cpu_type(), false);
37     g_slist_foreach(list, loongarch_cpu_add_definition, &cpu_list);
38     g_slist_free(list);
39 
40     return cpu_list;
41 }
42 
43 static const char *cpu_model_advertised_features[] = {
44     "lsx", "lasx", "lbt", "pmu", "kvm-pv-ipi", "kvm-steal-time", NULL
45 };
46 
qmp_query_cpu_model_expansion(CpuModelExpansionType type,CpuModelInfo * model,Error ** errp)47 CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
48                                                      CpuModelInfo *model,
49                                                      Error **errp)
50 {
51     Visitor *visitor;
52     bool ok;
53     CpuModelExpansionInfo *expansion_info;
54     QDict *qdict_out;
55     ObjectClass *oc;
56     Object *obj;
57     const char *name;
58     int i;
59 
60     if (type != CPU_MODEL_EXPANSION_TYPE_STATIC) {
61         error_setg(errp, "The requested expansion type is not supported");
62         return NULL;
63     }
64 
65     if (model->props) {
66         visitor = qobject_input_visitor_new(model->props);
67         if (!visit_start_struct(visitor, "model.props", NULL, 0, errp)) {
68             visit_free(visitor);
69             return NULL;
70         }
71 
72         ok = visit_check_struct(visitor, errp);
73         visit_end_struct(visitor, NULL);
74         visit_free(visitor);
75         if (!ok) {
76             return NULL;
77         }
78     }
79 
80     oc = cpu_class_by_name(TYPE_LOONGARCH_CPU, model->name);
81     if (!oc) {
82         error_setg(errp, "The CPU type '%s' is not a recognized LoongArch CPU type",
83                    model->name);
84         return NULL;
85     }
86 
87     obj = object_new(object_class_get_name(oc));
88 
89     expansion_info = g_new0(CpuModelExpansionInfo, 1);
90     expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
91     expansion_info->model->name = g_strdup(model->name);
92 
93     qdict_out = qdict_new();
94 
95     i = 0;
96     while ((name = cpu_model_advertised_features[i++]) != NULL) {
97         ObjectProperty *prop = object_property_find(obj, name);
98         if (prop) {
99             QObject *value;
100 
101             assert(prop->get);
102             value = object_property_get_qobject(obj, name, &error_abort);
103 
104             qdict_put_obj(qdict_out, name, value);
105         }
106     }
107 
108     if (!qdict_size(qdict_out)) {
109         qobject_unref(qdict_out);
110     } else {
111         expansion_info->model->props = QOBJECT(qdict_out);
112     }
113 
114     object_unref(obj);
115 
116     return expansion_info;
117 }
118