Lines Matching +full:interface +full:- +full:node
25 (interface in qgraph terms) and the framework takes care of
28 Following the above example, an interface would be ``sdhci``,
29 so the sdhci-test should only care of linking its qgraph node with
30 that interface. In this way, if the command line of a sdhci driver
31 is changed, only the respective qgraph driver node has to be adjusted.
34 ---------------
43 A node can be of four types:
45 - **QNODE_MACHINE**: for example ``arm/raspi2b``
46 - **QNODE_DRIVER**: for example ``generic-sdhci``
47 - **QNODE_INTERFACE**: for example ``sdhci`` (interface for all ``-sdhci``
49 An interface is not explicitly created, it will be automatically
50 instantiated when a node consumes or produces it.
51 An interface is simply a struct that abstracts the various drivers
54 - **QNODE_TEST**: for example ``sdhci-test``. A test consumes an interface
59 - QNODE_MACHINE: each machine struct must have a ``QGuestAllocator`` and
60 implement ``get_driver()`` to return the allocator mapped to the interface
63 - QNODE_DRIVER: driver names must be unique, and machines and nodes
72 - ``X CONSUMES Y``: ``Y`` can be plugged into ``X``
73 - ``X PRODUCES Y``: ``X`` provides the interface ``Y``
74 - ``X CONTAINS Y``: ``Y`` is part of ``X`` component
81 - All nodes and edges are created in their respective
83 - The framework starts QEMU and asks for a list of available devices
86 - The framework walks the graph starting from the available machines and
88 - Once a test is found, the path is walked again and all drivers are
89 allocated accordingly and the final interface is passed to the test
90 - The test is executed
91 - Unused objects are cleaned and the path discovery is continued
99 Command line is built by using node names and optional arguments
104 - ``in node`` : created from the node name. For example, machines will
105 have ``-M <machine>`` to its command line, while devices
106 ``-device <device>``. It is automatically done by the framework.
107 - ``after node`` : added as additional argument to the node name.
114 after the destination node pointed by
118 - ``before node`` : added as additional argument to the node name.
122 is going to add attributes before the destination node
124 helpful to commands that are not node-representable,
125 such as ``-fdsev`` or ``-netdev``.
137 .before_cmd_line = "-drive id=drv0,if=none,file=null-co://,"
138 "file.read-zeroes=on,format=raw",
139 .after_cmd_line = "-device scsi-hd,bus=vs0.0,drive=drv0",
144 qos_node_create_driver("virtio-scsi-device",
146 qos_node_consumes("virtio-scsi-device", "virtio-bus", &opts);
149 ``-drive id=drv0,if=none,file=null-co://, -device virtio-scsi-device,id=vs0 -device scsi-hd,bus=vs0…
156 up its qgraph node correctly. It can also happen if the necessary machine type
162 $ QTEST_QEMU_BINARY=build/qemu-system-x86_64 build/tests/qtest/qos-test --verbose
164 # src='virtio-net'
165 # |-> dest='virtio-net-tests/vhost-user/multiqueue' type=2 (node=0x559142109e30)
166 # |-> dest='virtio-net-tests/vhost-user/migrate' type=2 (node=0x559142109d00)
167 # src='virtio-net-pci'
168 # |-> dest='virtio-net' type=1 (node=0x55914210d740)
169 # src='pci-bus'
170 # |-> dest='virtio-net-pci' type=2 (node=0x55914210d880)
171 # src='pci-bus-pc'
172 # |-> dest='pci-bus' type=1 (node=0x559142103f40)
173 # src='i440FX-pcihost'
174 # |-> dest='pci-bus-pc' type=0 (node=0x55914210ac70)
176 # |-> dest='i440FX-pcihost' type=0 (node=0x5591421117f0)
178 # |-> dest='x86_64/pc' type=0 (node=0x559142111600)
179 # |-> dest='arm/raspi2b' type=0 (node=0x559142110740)
183 # name='virtio-net-tests/announce-self' type=3 cmd_line='(null)' [available]
184 # name='arm/raspi2b' type=0 cmd_line='-M raspi2b ' [UNAVAILABLE]
188 The ``virtio-net-tests/announce-self`` test is listed as "available" in the
190 qgraph path in the "ALL QGRAPH EDGES" output as follows: '' -> 'x86_64/pc' ->
191 'i440FX-pcihost' -> 'pci-bus-pc' -> 'pci-bus' -> 'virtio-net-pci' ->
192 'virtio-net'. The root of the qgraph is '' and the depth first search begins
195 The ``arm/raspi2b`` machine node is listed as "UNAVAILABLE". Although it is
196 reachable from the root via '' -> 'arm/raspi2b' the node is unavailable because
198 because we used the ``qemu-system-x86_64`` binary which does not support ARM
205 availability of each node in the path in the "ALL QGRAPH NODES" output. The
206 first unavailable node in the path is the reason why the test is unavailable.
210 Creating a new driver and its interface
211 ---------------------------------------
215 - ``sdhci-test`` aims to test the ``read[q,w], writeq`` functions
217 - The current ``sdhci`` device is supported by both ``x86_64/pc`` and ``ARM``
218 (in this example we focus on the ``arm-raspi2b``) machines.
219 - QEMU offers 2 types of drivers: ``QSDHCI_MemoryMapped`` for ``ARM`` and
225 - Create the ``x86_64/pc`` machine node. This machine uses the
226 ``pci-bus`` architecture so it ``contains`` a PCI driver,
227 ``pci-bus-pc``. The actual path is
229 ``x86_64/pc --contains--> 1440FX-pcihost --contains-->
230 pci-bus-pc --produces--> pci-bus``.
233 we do not focus on the PCI interface implementation.
234 - Create the ``sdhci-pci`` driver node, representing ``QSDHCI_PCI``.
236 so it must ``consume`` the ``pci-bus`` generic interface (which abstracts
239 ``sdhci-pci --consumes--> pci-bus``
240 - Create an ``arm/raspi2b`` machine node. This machine ``contains``
241 a ``generic-sdhci`` memory mapped ``sdhci`` driver node, representing
244 ``arm/raspi2b --contains--> generic-sdhci``
245 - Create the ``sdhci`` interface node. This interface offers the
247 The interface is produced by ``sdhci-pci`` and ``generic-sdhci``,
248 the available architecture-specific drivers.
250 ``sdhci-pci --produces--> sdhci``
252 ``generic-sdhci --produces--> sdhci``
253 - Create the ``sdhci-test`` test node. The test ``consumes`` the
254 ``sdhci`` interface, using its API. It doesn't need to look at
257 ``sdhci-test --consumes--> sdhci``
259 ``arm-raspi2b`` machine, simplified from
260 ``tests/qtest/libqos/arm-raspi2-machine.c``::
270 static void *raspi2_get_driver(void *object, const char *interface)
273 if (!g_strcmp0(interface, "memory")) {
274 return &machine->alloc;
277 fprintf(stderr, "%s not present in arm/raspi2b\n", interface);
285 if (!g_strcmp0(device, "generic-sdhci")) {
286 return &machine->sdhci.obj;
297 alloc_init(&machine->alloc, ...);
299 /* Get node(s) contained inside (CONTAINS) */
300 machine->obj.get_device = raspi2_get_device;
302 /* Get node(s) produced (PRODUCES) */
303 machine->obj.get_driver = raspi2_get_driver;
306 machine->obj.destructor = raspi2_destructor;
307 qos_init_sdhci_mm(&machine->sdhci, ...);
308 return &machine->obj;
313 /* arm/raspi2b --contains--> generic-sdhci */
316 qos_node_contains("arm/raspi2b", "generic-sdhci", NULL);
322 ``tests/qtest/libqos/x86_64_pc-machine.c``::
343 if (!g_strcmp0(device, "pci-bus-pc")) {
344 return &host->pci.obj;
346 fprintf(stderr, "%s not present in i440FX-pcihost\n", device);
352 static void *pc_get_driver(void *object, const char *interface)
355 if (!g_strcmp0(interface, "memory")) {
356 return &machine->alloc;
359 fprintf(stderr, "%s not present in x86_64/pc\n", interface);
366 if (!g_strcmp0(device, "i440FX-pcihost")) {
367 return &machine->bridge.obj;
378 /* Get node(s) contained inside (CONTAINS) */
379 machine->obj.get_device = pc_get_device;
381 /* Get node(s) produced (PRODUCES) */
382 machine->obj.get_driver = pc_get_driver;
385 machine->obj.destructor = pc_destructor;
386 pc_alloc_init(&machine->alloc, qts, ALLOC_NO_FLAGS);
388 /* Get node(s) contained inside (CONTAINS) */
389 machine->bridge.obj.get_device = i440FX_host_get_device;
391 return &machine->obj;
396 /* x86_64/pc --contains--> 1440FX-pcihost --contains-->
397 * pci-bus-pc [--produces--> pci-bus (in pci.h)] */
399 qos_node_contains("x86_64/pc", "i440FX-pcihost", NULL);
403 qos_node_create_driver("i440FX-pcihost", NULL);
404 qos_node_contains("i440FX-pcihost", "pci-bus-pc", NULL);
411 /* Interface node, offers the sdhci API */
423 /* other driver-specific fields */
430 /* other driver-specific fields */
435 static void *sdhci_mm_get_driver(void *obj, const char *interface)
438 if (!g_strcmp0(interface, "sdhci")) {
439 return &smm->sdhci;
441 fprintf(stderr, "%s not present in generic-sdhci\n", interface);
448 /* Get node contained inside (CONTAINS) */
449 sdhci->obj.get_driver = sdhci_mm_get_driver;
451 /* SDHCI interface API */
452 sdhci->sdhci.readw = sdhci_mm_readw;
453 sdhci->sdhci.readq = sdhci_mm_readq;
454 sdhci->sdhci.writeq = sdhci_mm_writeq;
455 sdhci->qts = qts;
461 const char *interface)
464 if (!g_strcmp0(interface, "sdhci")) {
465 return &spci->sdhci;
468 fprintf(stderr, "%s not present in sdhci-pci\n", interface);
480 qpci_device_init(&spci->dev, bus, addr);
482 /* SDHCI interface API */
483 spci->sdhci.readw = sdhci_pci_readw;
484 spci->sdhci.readq = sdhci_pci_readq;
485 spci->sdhci.writeq = sdhci_pci_writeq;
487 /* Get node(s) produced (PRODUCES) */
488 spci->obj.get_driver = sdhci_pci_get_driver;
490 spci->obj.start_hw = sdhci_pci_start_hw;
491 spci->obj.destructor = sdhci_destructor;
492 return &spci->obj;
501 /* generic-sdhci */
502 /* generic-sdhci --produces--> sdhci */
503 qos_node_create_driver("generic-sdhci", NULL);
504 qos_node_produces("generic-sdhci", "sdhci");
506 /* sdhci-pci */
507 /* sdhci-pci --produces--> sdhci
508 * sdhci-pci --consumes--> pci-bus */
509 qos_node_create_driver("sdhci-pci", sdhci_pci_create);
510 qos_node_produces("sdhci-pci", "sdhci");
511 qos_node_consumes("sdhci-pci", "pci-bus", &opts);
518 x86_64/pc --contains--> 1440FX-pcihost --contains--> pci-bus-pc
520 sdhci-pci --consumes--> pci-bus <--produces--+
522 +--produces--+
528 +--produces-- +
530 arm/raspi2b --contains--> generic-sdhci
534 x86_64/pc --contains--> 1440FX-pcihost --contains--> pci-bus-pc
536 sdhci-pci <--consumed by-- pci-bus <--produces--+
538 +--produces--+
544 +--produces-- +
546 arm/raspi2b --contains--> generic-sdhci
549 -----------------
552 ``sdhci-test``, taken from ``tests/qtest/sdhci-test.c``::
558 capab = s->readq(s, SDHC_CAPAB);
569 check_capab_sdma(s, s->props.capab.sdma);
574 /* sdhci-test --consumes--> sdhci */
580 Here a new test is created, consuming ``sdhci`` interface node
584 x86_64/pc --contains--> 1440FX-pcihost --contains--> pci-bus-pc
586 sdhci-pci --consumes--> pci-bus <--produces--+
588 +--produces--+
591 sdhci <--consumes-- sdhci-test
594 +--produces-- +
596 arm/raspi2b --contains--> generic-sdhci
600 x86_64/pc --contains--> 1440FX-pcihost --contains--> pci-bus-pc
602 sdhci-pci <--consumed by-- pci-bus <--produces--+
604 +--produces--+
607 sdhci --consumed by--> sdhci-test
610 +--produces-- +
612 arm/raspi2b --contains--> generic-sdhci
615 ``QTEST_QEMU_BINARY=./qemu-system-x86_64``
617 ``/x86_64/pc/1440FX-pcihost/pci-bus-pc/pci-bus/sdhci-pc/sdhci/sdhci-test``
619 and for the binary ``QTEST_QEMU_BINARY=./qemu-system-arm``:
621 ``/arm/raspi2b/generic-sdhci/sdhci/sdhci-test``
623 Additional examples are also in ``test-qgraph.c``
626 --------------------
628 .. kernel-doc:: tests/qtest/libqos/qgraph.h