2 * virtio-scmi nodes for testing
4 * SPDX-FileCopyrightText: Linaro Ltd
5 * SPDX-FileCopyrightText: Red Hat, Inc.
6 * SPDX-License-Identifier: GPL-2.0-or-later
8 * Based on virtio-gpio.c, doing basically the same thing.
11 #include "qemu/osdep.h"
12 #include "standard-headers/linux/virtio_config.h"
13 #include "../libqtest.h"
14 #include "qemu/module.h"
16 #include "virtio-scmi.h"
18 static QGuestAllocator
*alloc
;
20 static void virtio_scmi_cleanup(QVhostUserSCMI
*scmi
)
22 QVirtioDevice
*vdev
= scmi
->vdev
;
25 for (i
= 0; i
< 2; i
++) {
26 qvirtqueue_cleanup(vdev
->bus
, scmi
->queues
[i
], alloc
);
32 * This handles the VirtIO setup from the point of view of the driver
33 * frontend and therefore doesn't present any vhost specific features
34 * and in fact masks of the re-used bit.
36 static void virtio_scmi_setup(QVhostUserSCMI
*scmi
)
38 QVirtioDevice
*vdev
= scmi
->vdev
;
42 features
= qvirtio_get_features(vdev
);
43 features
&= ~QVIRTIO_F_BAD_FEATURE
;
44 qvirtio_set_features(vdev
, features
);
46 scmi
->queues
= g_new(QVirtQueue
*, 2);
47 for (i
= 0; i
< 2; i
++) {
48 scmi
->queues
[i
] = qvirtqueue_setup(vdev
, alloc
, i
);
50 qvirtio_set_driver_ok(vdev
);
53 static void *qvirtio_scmi_get_driver(QVhostUserSCMI
*v_scmi
,
54 const char *interface
)
56 if (!g_strcmp0(interface
, "vhost-user-scmi")) {
59 if (!g_strcmp0(interface
, "virtio")) {
63 g_assert_not_reached();
66 static void *qvirtio_scmi_device_get_driver(void *object
,
67 const char *interface
)
69 QVhostUserSCMIDevice
*v_scmi
= object
;
70 return qvirtio_scmi_get_driver(&v_scmi
->scmi
, interface
);
73 /* virtio-scmi (mmio) */
74 static void qvirtio_scmi_device_destructor(QOSGraphObject
*obj
)
76 QVhostUserSCMIDevice
*scmi_dev
= (QVhostUserSCMIDevice
*) obj
;
77 virtio_scmi_cleanup(&scmi_dev
->scmi
);
80 static void qvirtio_scmi_device_start_hw(QOSGraphObject
*obj
)
82 QVhostUserSCMIDevice
*scmi_dev
= (QVhostUserSCMIDevice
*) obj
;
83 virtio_scmi_setup(&scmi_dev
->scmi
);
86 static void *virtio_scmi_device_create(void *virtio_dev
,
87 QGuestAllocator
*t_alloc
,
90 QVhostUserSCMIDevice
*virtio_device
= g_new0(QVhostUserSCMIDevice
, 1);
91 QVhostUserSCMI
*interface
= &virtio_device
->scmi
;
93 interface
->vdev
= virtio_dev
;
96 virtio_device
->obj
.get_driver
= qvirtio_scmi_device_get_driver
;
97 virtio_device
->obj
.start_hw
= qvirtio_scmi_device_start_hw
;
98 virtio_device
->obj
.destructor
= qvirtio_scmi_device_destructor
;
100 return &virtio_device
->obj
;
103 /* virtio-scmi-pci */
104 static void qvirtio_scmi_pci_destructor(QOSGraphObject
*obj
)
106 QVhostUserSCMIPCI
*scmi_pci
= (QVhostUserSCMIPCI
*) obj
;
107 QOSGraphObject
*pci_vobj
= &scmi_pci
->pci_vdev
.obj
;
109 virtio_scmi_cleanup(&scmi_pci
->scmi
);
110 qvirtio_pci_destructor(pci_vobj
);
113 static void qvirtio_scmi_pci_start_hw(QOSGraphObject
*obj
)
115 QVhostUserSCMIPCI
*scmi_pci
= (QVhostUserSCMIPCI
*) obj
;
116 QOSGraphObject
*pci_vobj
= &scmi_pci
->pci_vdev
.obj
;
118 qvirtio_pci_start_hw(pci_vobj
);
119 virtio_scmi_setup(&scmi_pci
->scmi
);
122 static void *qvirtio_scmi_pci_get_driver(void *object
, const char *interface
)
124 QVhostUserSCMIPCI
*v_scmi
= object
;
126 if (!g_strcmp0(interface
, "pci-device")) {
127 return v_scmi
->pci_vdev
.pdev
;
129 return qvirtio_scmi_get_driver(&v_scmi
->scmi
, interface
);
132 static void *virtio_scmi_pci_create(void *pci_bus
, QGuestAllocator
*t_alloc
,
135 QVhostUserSCMIPCI
*virtio_spci
= g_new0(QVhostUserSCMIPCI
, 1);
136 QVhostUserSCMI
*interface
= &virtio_spci
->scmi
;
137 QOSGraphObject
*obj
= &virtio_spci
->pci_vdev
.obj
;
139 virtio_pci_init(&virtio_spci
->pci_vdev
, pci_bus
, addr
);
140 interface
->vdev
= &virtio_spci
->pci_vdev
.vdev
;
143 obj
->get_driver
= qvirtio_scmi_pci_get_driver
;
144 obj
->start_hw
= qvirtio_scmi_pci_start_hw
;
145 obj
->destructor
= qvirtio_scmi_pci_destructor
;
150 static void virtio_scmi_register_nodes(void)
153 .devfn
= QPCI_DEVFN(4, 0),
156 QOSGraphEdgeOptions edge_opts
= { };
158 /* vhost-user-scmi-device */
159 edge_opts
.extra_device_opts
= "id=scmi,chardev=chr-vhost-user-test "
160 "-global virtio-mmio.force-legacy=false";
161 qos_node_create_driver("vhost-user-scmi-device",
162 virtio_scmi_device_create
);
163 qos_node_consumes("vhost-user-scmi-device", "virtio-bus", &edge_opts
);
164 qos_node_produces("vhost-user-scmi-device", "vhost-user-scmi");
166 /* virtio-scmi-pci */
167 edge_opts
.extra_device_opts
= "id=scmi,addr=04.0,chardev=chr-vhost-user-test";
168 add_qpci_address(&edge_opts
, &addr
);
169 qos_node_create_driver("vhost-user-scmi-pci", virtio_scmi_pci_create
);
170 qos_node_consumes("vhost-user-scmi-pci", "pci-bus", &edge_opts
);
171 qos_node_produces("vhost-user-scmi-pci", "vhost-user-scmi");
174 libqos_init(virtio_scmi_register_nodes
);