xref: /openbmc/qemu/tests/qtest/libqos/qos_external.c (revision e93ded1bf6c94ab95015b33e188bc8b0b0c32670)
1f62a0bffSAlexander Bulekov /*
2f62a0bffSAlexander Bulekov  * libqos driver framework
3f62a0bffSAlexander Bulekov  *
4f62a0bffSAlexander Bulekov  * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
5f62a0bffSAlexander Bulekov  *
6f62a0bffSAlexander Bulekov  * This library is free software; you can redistribute it and/or
7f62a0bffSAlexander Bulekov  * modify it under the terms of the GNU Lesser General Public
8dc0ad02dSThomas Huth  * License version 2.1 as published by the Free Software Foundation.
9f62a0bffSAlexander Bulekov  *
10f62a0bffSAlexander Bulekov  * This library is distributed in the hope that it will be useful,
11f62a0bffSAlexander Bulekov  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12f62a0bffSAlexander Bulekov  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13f62a0bffSAlexander Bulekov  * Lesser General Public License for more details.
14f62a0bffSAlexander Bulekov  *
15f62a0bffSAlexander Bulekov  * You should have received a copy of the GNU Lesser General Public
16f62a0bffSAlexander Bulekov  * License along with this library; if not, see <http://www.gnu.org/licenses/>
17f62a0bffSAlexander Bulekov  */
18f62a0bffSAlexander Bulekov 
19f62a0bffSAlexander Bulekov #include "qemu/osdep.h"
20f62a0bffSAlexander Bulekov #include <getopt.h>
21907b5105SMarc-André Lureau #include "../libqtest.h"
22f62a0bffSAlexander Bulekov #include "qapi/qmp/qdict.h"
23f62a0bffSAlexander Bulekov #include "qapi/qmp/qbool.h"
24f62a0bffSAlexander Bulekov #include "qapi/qmp/qstring.h"
25f62a0bffSAlexander Bulekov #include "qemu/module.h"
26f62a0bffSAlexander Bulekov #include "qapi/qmp/qlist.h"
27*b243c73cSXuzhou Cheng #include "libqos-malloc.h"
28a2ce7dbdSPaolo Bonzini #include "qgraph.h"
29a2ce7dbdSPaolo Bonzini #include "qgraph_internal.h"
30a2ce7dbdSPaolo Bonzini #include "qos_external.h"
31f62a0bffSAlexander Bulekov 
machine_apply_to_node(const char * name)32a56f3cdbSMarkus Armbruster static void machine_apply_to_node(const char *name)
33f62a0bffSAlexander Bulekov {
34a56f3cdbSMarkus Armbruster     char *machine_name = g_strconcat(qtest_get_arch(), "/", name, NULL);
35a56f3cdbSMarkus Armbruster 
36a56f3cdbSMarkus Armbruster     qos_graph_node_set_availability(machine_name, true);
37a56f3cdbSMarkus Armbruster     g_free(machine_name);
38f62a0bffSAlexander Bulekov }
39a56f3cdbSMarkus Armbruster 
machines_apply_to_node(MachineInfoList * mach_info)40a56f3cdbSMarkus Armbruster void machines_apply_to_node(MachineInfoList *mach_info)
41a56f3cdbSMarkus Armbruster {
42a56f3cdbSMarkus Armbruster     MachineInfoList *tail;
43a56f3cdbSMarkus Armbruster 
44a56f3cdbSMarkus Armbruster     for (tail = mach_info; tail; tail = tail->next) {
45a56f3cdbSMarkus Armbruster         machine_apply_to_node(tail->value->name);
46a56f3cdbSMarkus Armbruster         if (tail->value->alias) {
47a56f3cdbSMarkus Armbruster             machine_apply_to_node(tail->value->alias);
48a56f3cdbSMarkus Armbruster         }
49a56f3cdbSMarkus Armbruster     }
50a56f3cdbSMarkus Armbruster }
51a56f3cdbSMarkus Armbruster 
type_apply_to_node(const char * name,bool is_abstract)52a56f3cdbSMarkus Armbruster static void type_apply_to_node(const char *name, bool is_abstract)
53a56f3cdbSMarkus Armbruster {
54f62a0bffSAlexander Bulekov     qos_graph_node_set_availability(name, true);
55f62a0bffSAlexander Bulekov     if (is_abstract) {
56f62a0bffSAlexander Bulekov         qos_delete_cmd_line(name);
57f62a0bffSAlexander Bulekov     }
58f62a0bffSAlexander Bulekov }
59f62a0bffSAlexander Bulekov 
types_apply_to_node(ObjectTypeInfoList * type_info)60a56f3cdbSMarkus Armbruster void types_apply_to_node(ObjectTypeInfoList *type_info)
61f62a0bffSAlexander Bulekov {
62a56f3cdbSMarkus Armbruster     ObjectTypeInfoList *tail;
63f62a0bffSAlexander Bulekov 
64a56f3cdbSMarkus Armbruster     for (tail = type_info; tail; tail = tail->next) {
65a56f3cdbSMarkus Armbruster         type_apply_to_node(tail->value->name, tail->value->abstract);
66f62a0bffSAlexander Bulekov     }
67f62a0bffSAlexander Bulekov }
68f62a0bffSAlexander Bulekov 
get_machine_allocator(QOSGraphObject * obj)69f6528054SMarkus Armbruster static QGuestAllocator *get_machine_allocator(QOSGraphObject *obj)
70f62a0bffSAlexander Bulekov {
71f62a0bffSAlexander Bulekov     return obj->get_driver(obj, "memory");
72f62a0bffSAlexander Bulekov }
73f62a0bffSAlexander Bulekov 
74f62a0bffSAlexander Bulekov /**
75f62a0bffSAlexander Bulekov  * allocate_objects(): given an array of nodes @arg,
76f62a0bffSAlexander Bulekov  * walks the path invoking all constructors and
77f62a0bffSAlexander Bulekov  * passing the corresponding parameter in order to
78f62a0bffSAlexander Bulekov  * continue the objects allocation.
79f62a0bffSAlexander Bulekov  * Once the test is reached, return the object it consumes.
80f62a0bffSAlexander Bulekov  *
81f62a0bffSAlexander Bulekov  * Since the machine and QEDGE_CONSUMED_BY nodes allocate
82f62a0bffSAlexander Bulekov  * memory in the constructor, g_test_queue_destroy is used so
83f62a0bffSAlexander Bulekov  * that after execution they can be safely free'd.  (The test's
84f62a0bffSAlexander Bulekov  * ->before callback is also welcome to use g_test_queue_destroy).
85f62a0bffSAlexander Bulekov  *
86f62a0bffSAlexander Bulekov  * Note: as specified in walk_path() too, @arg is an array of
87f62a0bffSAlexander Bulekov  * char *, where arg[0] is a pointer to the command line
88f62a0bffSAlexander Bulekov  * string that will be used to properly start QEMU when executing
89f62a0bffSAlexander Bulekov  * the test, and the remaining elements represent the actual objects
90f62a0bffSAlexander Bulekov  * that will be allocated.
91f62a0bffSAlexander Bulekov  */
allocate_objects(QTestState * qts,char ** path,QGuestAllocator ** p_alloc)92f62a0bffSAlexander Bulekov void *allocate_objects(QTestState *qts, char **path, QGuestAllocator **p_alloc)
93f62a0bffSAlexander Bulekov {
94f62a0bffSAlexander Bulekov     int current = 0;
95f62a0bffSAlexander Bulekov     QGuestAllocator *alloc;
96f62a0bffSAlexander Bulekov     QOSGraphObject *parent = NULL;
97f62a0bffSAlexander Bulekov     QOSGraphEdge *edge;
98f62a0bffSAlexander Bulekov     QOSGraphNode *node;
99f62a0bffSAlexander Bulekov     void *edge_arg;
100f62a0bffSAlexander Bulekov     void *obj;
101f62a0bffSAlexander Bulekov 
102f62a0bffSAlexander Bulekov     node = qos_graph_get_node(path[current]);
103f62a0bffSAlexander Bulekov     g_assert(node->type == QNODE_MACHINE);
104f62a0bffSAlexander Bulekov 
105f62a0bffSAlexander Bulekov     obj = qos_machine_new(node, qts);
106f62a0bffSAlexander Bulekov     qos_object_queue_destroy(obj);
107f62a0bffSAlexander Bulekov 
108f62a0bffSAlexander Bulekov     alloc = get_machine_allocator(obj);
109f62a0bffSAlexander Bulekov     if (p_alloc) {
110f62a0bffSAlexander Bulekov         *p_alloc = alloc;
111f62a0bffSAlexander Bulekov     }
112f62a0bffSAlexander Bulekov 
113f62a0bffSAlexander Bulekov     for (;;) {
114f62a0bffSAlexander Bulekov         if (node->type != QNODE_INTERFACE) {
115f62a0bffSAlexander Bulekov             qos_object_start_hw(obj);
116f62a0bffSAlexander Bulekov             parent = obj;
117f62a0bffSAlexander Bulekov         }
118f62a0bffSAlexander Bulekov 
119f62a0bffSAlexander Bulekov         /* follow edge and get object for next node constructor */
120f62a0bffSAlexander Bulekov         current++;
121f62a0bffSAlexander Bulekov         edge = qos_graph_get_edge(path[current - 1], path[current]);
122f62a0bffSAlexander Bulekov         node = qos_graph_get_node(path[current]);
123f62a0bffSAlexander Bulekov 
124f62a0bffSAlexander Bulekov         if (node->type == QNODE_TEST) {
125f62a0bffSAlexander Bulekov             g_assert(qos_graph_edge_get_type(edge) == QEDGE_CONSUMED_BY);
126f62a0bffSAlexander Bulekov             return obj;
127f62a0bffSAlexander Bulekov         }
128f62a0bffSAlexander Bulekov 
129f62a0bffSAlexander Bulekov         switch (qos_graph_edge_get_type(edge)) {
130f62a0bffSAlexander Bulekov         case QEDGE_PRODUCES:
131f62a0bffSAlexander Bulekov             obj = parent->get_driver(parent, path[current]);
132f62a0bffSAlexander Bulekov             break;
133f62a0bffSAlexander Bulekov 
134f62a0bffSAlexander Bulekov         case QEDGE_CONSUMED_BY:
135f62a0bffSAlexander Bulekov             edge_arg = qos_graph_edge_get_arg(edge);
136f62a0bffSAlexander Bulekov             obj = qos_driver_new(node, obj, alloc, edge_arg);
137f62a0bffSAlexander Bulekov             qos_object_queue_destroy(obj);
138f62a0bffSAlexander Bulekov             break;
139f62a0bffSAlexander Bulekov 
140f62a0bffSAlexander Bulekov         case QEDGE_CONTAINS:
141f62a0bffSAlexander Bulekov             obj = parent->get_device(parent, path[current]);
142f62a0bffSAlexander Bulekov             break;
143f62a0bffSAlexander Bulekov         }
144f62a0bffSAlexander Bulekov     }
145f62a0bffSAlexander Bulekov }
146f62a0bffSAlexander Bulekov 
147