1b6f53ae0SMilan Zamazal /* 2b6f53ae0SMilan Zamazal * virtio-scmi nodes for testing 3b6f53ae0SMilan Zamazal * 4*d6f76422SPhilippe Mathieu-Daudé * Copyright (c) Linaro Ltd. 5b6f53ae0SMilan Zamazal * SPDX-FileCopyrightText: Red Hat, Inc. 6b6f53ae0SMilan Zamazal * SPDX-License-Identifier: GPL-2.0-or-later 7b6f53ae0SMilan Zamazal * 8b6f53ae0SMilan Zamazal * Based on virtio-gpio.c, doing basically the same thing. 9b6f53ae0SMilan Zamazal */ 10b6f53ae0SMilan Zamazal 11b6f53ae0SMilan Zamazal #include "qemu/osdep.h" 12b6f53ae0SMilan Zamazal #include "standard-headers/linux/virtio_config.h" 13b6f53ae0SMilan Zamazal #include "../libqtest.h" 14b6f53ae0SMilan Zamazal #include "qemu/module.h" 15b6f53ae0SMilan Zamazal #include "qgraph.h" 16b6f53ae0SMilan Zamazal #include "virtio-scmi.h" 17b6f53ae0SMilan Zamazal 18b6f53ae0SMilan Zamazal static QGuestAllocator *alloc; 19b6f53ae0SMilan Zamazal 20b6f53ae0SMilan Zamazal static void virtio_scmi_cleanup(QVhostUserSCMI *scmi) 21b6f53ae0SMilan Zamazal { 22b6f53ae0SMilan Zamazal QVirtioDevice *vdev = scmi->vdev; 23b6f53ae0SMilan Zamazal int i; 24b6f53ae0SMilan Zamazal 25b6f53ae0SMilan Zamazal for (i = 0; i < 2; i++) { 26b6f53ae0SMilan Zamazal qvirtqueue_cleanup(vdev->bus, scmi->queues[i], alloc); 27b6f53ae0SMilan Zamazal } 28b6f53ae0SMilan Zamazal g_free(scmi->queues); 29b6f53ae0SMilan Zamazal } 30b6f53ae0SMilan Zamazal 31b6f53ae0SMilan Zamazal /* 32b6f53ae0SMilan Zamazal * This handles the VirtIO setup from the point of view of the driver 33b6f53ae0SMilan Zamazal * frontend and therefore doesn't present any vhost specific features 34b6f53ae0SMilan Zamazal * and in fact masks of the re-used bit. 35b6f53ae0SMilan Zamazal */ 36b6f53ae0SMilan Zamazal static void virtio_scmi_setup(QVhostUserSCMI *scmi) 37b6f53ae0SMilan Zamazal { 38b6f53ae0SMilan Zamazal QVirtioDevice *vdev = scmi->vdev; 39b6f53ae0SMilan Zamazal uint64_t features; 40b6f53ae0SMilan Zamazal int i; 41b6f53ae0SMilan Zamazal 42b6f53ae0SMilan Zamazal features = qvirtio_get_features(vdev); 43b6f53ae0SMilan Zamazal features &= ~QVIRTIO_F_BAD_FEATURE; 44b6f53ae0SMilan Zamazal qvirtio_set_features(vdev, features); 45b6f53ae0SMilan Zamazal 46b6f53ae0SMilan Zamazal scmi->queues = g_new(QVirtQueue *, 2); 47b6f53ae0SMilan Zamazal for (i = 0; i < 2; i++) { 48b6f53ae0SMilan Zamazal scmi->queues[i] = qvirtqueue_setup(vdev, alloc, i); 49b6f53ae0SMilan Zamazal } 50b6f53ae0SMilan Zamazal qvirtio_set_driver_ok(vdev); 51b6f53ae0SMilan Zamazal } 52b6f53ae0SMilan Zamazal 53b6f53ae0SMilan Zamazal static void *qvirtio_scmi_get_driver(QVhostUserSCMI *v_scmi, 54b6f53ae0SMilan Zamazal const char *interface) 55b6f53ae0SMilan Zamazal { 56b6f53ae0SMilan Zamazal if (!g_strcmp0(interface, "vhost-user-scmi")) { 57b6f53ae0SMilan Zamazal return v_scmi; 58b6f53ae0SMilan Zamazal } 59b6f53ae0SMilan Zamazal if (!g_strcmp0(interface, "virtio")) { 60b6f53ae0SMilan Zamazal return v_scmi->vdev; 61b6f53ae0SMilan Zamazal } 62b6f53ae0SMilan Zamazal 63b6f53ae0SMilan Zamazal g_assert_not_reached(); 64b6f53ae0SMilan Zamazal } 65b6f53ae0SMilan Zamazal 66b6f53ae0SMilan Zamazal static void *qvirtio_scmi_device_get_driver(void *object, 67b6f53ae0SMilan Zamazal const char *interface) 68b6f53ae0SMilan Zamazal { 69b6f53ae0SMilan Zamazal QVhostUserSCMIDevice *v_scmi = object; 70b6f53ae0SMilan Zamazal return qvirtio_scmi_get_driver(&v_scmi->scmi, interface); 71b6f53ae0SMilan Zamazal } 72b6f53ae0SMilan Zamazal 73b6f53ae0SMilan Zamazal /* virtio-scmi (mmio) */ 74b6f53ae0SMilan Zamazal static void qvirtio_scmi_device_destructor(QOSGraphObject *obj) 75b6f53ae0SMilan Zamazal { 76b6f53ae0SMilan Zamazal QVhostUserSCMIDevice *scmi_dev = (QVhostUserSCMIDevice *) obj; 77b6f53ae0SMilan Zamazal virtio_scmi_cleanup(&scmi_dev->scmi); 78b6f53ae0SMilan Zamazal } 79b6f53ae0SMilan Zamazal 80b6f53ae0SMilan Zamazal static void qvirtio_scmi_device_start_hw(QOSGraphObject *obj) 81b6f53ae0SMilan Zamazal { 82b6f53ae0SMilan Zamazal QVhostUserSCMIDevice *scmi_dev = (QVhostUserSCMIDevice *) obj; 83b6f53ae0SMilan Zamazal virtio_scmi_setup(&scmi_dev->scmi); 84b6f53ae0SMilan Zamazal } 85b6f53ae0SMilan Zamazal 86b6f53ae0SMilan Zamazal static void *virtio_scmi_device_create(void *virtio_dev, 87b6f53ae0SMilan Zamazal QGuestAllocator *t_alloc, 88b6f53ae0SMilan Zamazal void *addr) 89b6f53ae0SMilan Zamazal { 90b6f53ae0SMilan Zamazal QVhostUserSCMIDevice *virtio_device = g_new0(QVhostUserSCMIDevice, 1); 91b6f53ae0SMilan Zamazal QVhostUserSCMI *interface = &virtio_device->scmi; 92b6f53ae0SMilan Zamazal 93b6f53ae0SMilan Zamazal interface->vdev = virtio_dev; 94b6f53ae0SMilan Zamazal alloc = t_alloc; 95b6f53ae0SMilan Zamazal 96b6f53ae0SMilan Zamazal virtio_device->obj.get_driver = qvirtio_scmi_device_get_driver; 97b6f53ae0SMilan Zamazal virtio_device->obj.start_hw = qvirtio_scmi_device_start_hw; 98b6f53ae0SMilan Zamazal virtio_device->obj.destructor = qvirtio_scmi_device_destructor; 99b6f53ae0SMilan Zamazal 100b6f53ae0SMilan Zamazal return &virtio_device->obj; 101b6f53ae0SMilan Zamazal } 102b6f53ae0SMilan Zamazal 103b6f53ae0SMilan Zamazal /* virtio-scmi-pci */ 104b6f53ae0SMilan Zamazal static void qvirtio_scmi_pci_destructor(QOSGraphObject *obj) 105b6f53ae0SMilan Zamazal { 106b6f53ae0SMilan Zamazal QVhostUserSCMIPCI *scmi_pci = (QVhostUserSCMIPCI *) obj; 107b6f53ae0SMilan Zamazal QOSGraphObject *pci_vobj = &scmi_pci->pci_vdev.obj; 108b6f53ae0SMilan Zamazal 109b6f53ae0SMilan Zamazal virtio_scmi_cleanup(&scmi_pci->scmi); 110b6f53ae0SMilan Zamazal qvirtio_pci_destructor(pci_vobj); 111b6f53ae0SMilan Zamazal } 112b6f53ae0SMilan Zamazal 113b6f53ae0SMilan Zamazal static void qvirtio_scmi_pci_start_hw(QOSGraphObject *obj) 114b6f53ae0SMilan Zamazal { 115b6f53ae0SMilan Zamazal QVhostUserSCMIPCI *scmi_pci = (QVhostUserSCMIPCI *) obj; 116b6f53ae0SMilan Zamazal QOSGraphObject *pci_vobj = &scmi_pci->pci_vdev.obj; 117b6f53ae0SMilan Zamazal 118b6f53ae0SMilan Zamazal qvirtio_pci_start_hw(pci_vobj); 119b6f53ae0SMilan Zamazal virtio_scmi_setup(&scmi_pci->scmi); 120b6f53ae0SMilan Zamazal } 121b6f53ae0SMilan Zamazal 122b6f53ae0SMilan Zamazal static void *qvirtio_scmi_pci_get_driver(void *object, const char *interface) 123b6f53ae0SMilan Zamazal { 124b6f53ae0SMilan Zamazal QVhostUserSCMIPCI *v_scmi = object; 125b6f53ae0SMilan Zamazal 126b6f53ae0SMilan Zamazal if (!g_strcmp0(interface, "pci-device")) { 127b6f53ae0SMilan Zamazal return v_scmi->pci_vdev.pdev; 128b6f53ae0SMilan Zamazal } 129b6f53ae0SMilan Zamazal return qvirtio_scmi_get_driver(&v_scmi->scmi, interface); 130b6f53ae0SMilan Zamazal } 131b6f53ae0SMilan Zamazal 132b6f53ae0SMilan Zamazal static void *virtio_scmi_pci_create(void *pci_bus, QGuestAllocator *t_alloc, 133b6f53ae0SMilan Zamazal void *addr) 134b6f53ae0SMilan Zamazal { 135b6f53ae0SMilan Zamazal QVhostUserSCMIPCI *virtio_spci = g_new0(QVhostUserSCMIPCI, 1); 136b6f53ae0SMilan Zamazal QVhostUserSCMI *interface = &virtio_spci->scmi; 137b6f53ae0SMilan Zamazal QOSGraphObject *obj = &virtio_spci->pci_vdev.obj; 138b6f53ae0SMilan Zamazal 139b6f53ae0SMilan Zamazal virtio_pci_init(&virtio_spci->pci_vdev, pci_bus, addr); 140b6f53ae0SMilan Zamazal interface->vdev = &virtio_spci->pci_vdev.vdev; 141b6f53ae0SMilan Zamazal alloc = t_alloc; 142b6f53ae0SMilan Zamazal 143b6f53ae0SMilan Zamazal obj->get_driver = qvirtio_scmi_pci_get_driver; 144b6f53ae0SMilan Zamazal obj->start_hw = qvirtio_scmi_pci_start_hw; 145b6f53ae0SMilan Zamazal obj->destructor = qvirtio_scmi_pci_destructor; 146b6f53ae0SMilan Zamazal 147b6f53ae0SMilan Zamazal return obj; 148b6f53ae0SMilan Zamazal } 149b6f53ae0SMilan Zamazal 150b6f53ae0SMilan Zamazal static void virtio_scmi_register_nodes(void) 151b6f53ae0SMilan Zamazal { 152b6f53ae0SMilan Zamazal QPCIAddress addr = { 153b6f53ae0SMilan Zamazal .devfn = QPCI_DEVFN(4, 0), 154b6f53ae0SMilan Zamazal }; 155b6f53ae0SMilan Zamazal 156b6f53ae0SMilan Zamazal QOSGraphEdgeOptions edge_opts = { }; 157b6f53ae0SMilan Zamazal 158b6f53ae0SMilan Zamazal /* vhost-user-scmi-device */ 159b6f53ae0SMilan Zamazal edge_opts.extra_device_opts = "id=scmi,chardev=chr-vhost-user-test " 160b6f53ae0SMilan Zamazal "-global virtio-mmio.force-legacy=false"; 161b6f53ae0SMilan Zamazal qos_node_create_driver("vhost-user-scmi-device", 162b6f53ae0SMilan Zamazal virtio_scmi_device_create); 163b6f53ae0SMilan Zamazal qos_node_consumes("vhost-user-scmi-device", "virtio-bus", &edge_opts); 164b6f53ae0SMilan Zamazal qos_node_produces("vhost-user-scmi-device", "vhost-user-scmi"); 165b6f53ae0SMilan Zamazal 166b6f53ae0SMilan Zamazal /* virtio-scmi-pci */ 167b6f53ae0SMilan Zamazal edge_opts.extra_device_opts = "id=scmi,addr=04.0,chardev=chr-vhost-user-test"; 168b6f53ae0SMilan Zamazal add_qpci_address(&edge_opts, &addr); 169b6f53ae0SMilan Zamazal qos_node_create_driver("vhost-user-scmi-pci", virtio_scmi_pci_create); 170b6f53ae0SMilan Zamazal qos_node_consumes("vhost-user-scmi-pci", "pci-bus", &edge_opts); 171b6f53ae0SMilan Zamazal qos_node_produces("vhost-user-scmi-pci", "vhost-user-scmi"); 172b6f53ae0SMilan Zamazal } 173b6f53ae0SMilan Zamazal 174b6f53ae0SMilan Zamazal libqos_init(virtio_scmi_register_nodes); 175