xref: /openbmc/qemu/include/hw/virtio/virtio-pci.h (revision 9eb9350c0e519be97716f6b27f664bd0a3c41a36)
1e1b1f534SAlex Bennée /*
2e1b1f534SAlex Bennée  * Virtio PCI Bindings
3e1b1f534SAlex Bennée  *
4e1b1f534SAlex Bennée  * Copyright IBM, Corp. 2007
5e1b1f534SAlex Bennée  * Copyright (c) 2009 CodeSourcery
6e1b1f534SAlex Bennée  *
7e1b1f534SAlex Bennée  * Authors:
8e1b1f534SAlex Bennée  *  Anthony Liguori   <aliguori@us.ibm.com>
9e1b1f534SAlex Bennée  *  Paul Brook        <paul@codesourcery.com>
10e1b1f534SAlex Bennée  *
11e1b1f534SAlex Bennée  * This work is licensed under the terms of the GNU GPL, version 2.  See
12e1b1f534SAlex Bennée  * the COPYING file in the top-level directory.
13e1b1f534SAlex Bennée  */
14e1b1f534SAlex Bennée 
15e1b1f534SAlex Bennée #ifndef QEMU_VIRTIO_PCI_H
16e1b1f534SAlex Bennée #define QEMU_VIRTIO_PCI_H
17e1b1f534SAlex Bennée 
18e1b1f534SAlex Bennée #include "hw/pci/msi.h"
19e1b1f534SAlex Bennée #include "hw/virtio/virtio-bus.h"
20e1b1f534SAlex Bennée #include "qom/object.h"
21e1b1f534SAlex Bennée 
22e1b1f534SAlex Bennée 
23e1b1f534SAlex Bennée /* virtio-pci-bus */
24e1b1f534SAlex Bennée 
25e1b1f534SAlex Bennée typedef struct VirtioBusState VirtioPCIBusState;
26e1b1f534SAlex Bennée typedef struct VirtioBusClass VirtioPCIBusClass;
27e1b1f534SAlex Bennée 
28e1b1f534SAlex Bennée #define TYPE_VIRTIO_PCI_BUS "virtio-pci-bus"
29e1b1f534SAlex Bennée DECLARE_OBJ_CHECKERS(VirtioPCIBusState, VirtioPCIBusClass,
30e1b1f534SAlex Bennée                      VIRTIO_PCI_BUS, TYPE_VIRTIO_PCI_BUS)
31e1b1f534SAlex Bennée 
32e1b1f534SAlex Bennée enum {
33e1b1f534SAlex Bennée     VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT,
34e1b1f534SAlex Bennée     VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT,
35e1b1f534SAlex Bennée     VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT,
36e1b1f534SAlex Bennée     VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT,
37e1b1f534SAlex Bennée     VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT,
38e1b1f534SAlex Bennée     VIRTIO_PCI_FLAG_PAGE_PER_VQ_BIT,
39e1b1f534SAlex Bennée     VIRTIO_PCI_FLAG_ATS_BIT,
40e1b1f534SAlex Bennée     VIRTIO_PCI_FLAG_INIT_DEVERR_BIT,
41e1b1f534SAlex Bennée     VIRTIO_PCI_FLAG_INIT_LNKCTL_BIT,
42e1b1f534SAlex Bennée     VIRTIO_PCI_FLAG_INIT_PM_BIT,
43e1b1f534SAlex Bennée     VIRTIO_PCI_FLAG_INIT_FLR_BIT,
44e1b1f534SAlex Bennée     VIRTIO_PCI_FLAG_AER_BIT,
45e1b1f534SAlex Bennée     VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED_BIT,
465d98e188SJiqian Chen     VIRTIO_PCI_FLAG_PM_NO_SOFT_RESET_BIT,
47e1b1f534SAlex Bennée };
48e1b1f534SAlex Bennée 
49e1b1f534SAlex Bennée /* Need to activate work-arounds for buggy guests at vmstate load. */
50e1b1f534SAlex Bennée #define VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION \
51e1b1f534SAlex Bennée     (1 << VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT)
52e1b1f534SAlex Bennée 
53e1b1f534SAlex Bennée /* Performance improves when virtqueue kick processing is decoupled from the
54e1b1f534SAlex Bennée  * vcpu thread using ioeventfd for some devices. */
55e1b1f534SAlex Bennée #define VIRTIO_PCI_FLAG_USE_IOEVENTFD   (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT)
56e1b1f534SAlex Bennée 
57e1b1f534SAlex Bennée /* virtio version flags */
58e1b1f534SAlex Bennée #define VIRTIO_PCI_FLAG_DISABLE_PCIE (1 << VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT)
59e1b1f534SAlex Bennée 
60e1b1f534SAlex Bennée /* migrate extra state */
61e1b1f534SAlex Bennée #define VIRTIO_PCI_FLAG_MIGRATE_EXTRA (1 << VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT)
62e1b1f534SAlex Bennée 
63e1b1f534SAlex Bennée /* have pio notification for modern device ? */
64e1b1f534SAlex Bennée #define VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY \
65e1b1f534SAlex Bennée     (1 << VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT)
66e1b1f534SAlex Bennée 
67e1b1f534SAlex Bennée /* page per vq flag to be used by split drivers within guests */
68e1b1f534SAlex Bennée #define VIRTIO_PCI_FLAG_PAGE_PER_VQ \
69e1b1f534SAlex Bennée     (1 << VIRTIO_PCI_FLAG_PAGE_PER_VQ_BIT)
70e1b1f534SAlex Bennée 
71e1b1f534SAlex Bennée /* address space translation service */
72e1b1f534SAlex Bennée #define VIRTIO_PCI_FLAG_ATS (1 << VIRTIO_PCI_FLAG_ATS_BIT)
73e1b1f534SAlex Bennée 
74e1b1f534SAlex Bennée /* Init error enabling flags */
75e1b1f534SAlex Bennée #define VIRTIO_PCI_FLAG_INIT_DEVERR (1 << VIRTIO_PCI_FLAG_INIT_DEVERR_BIT)
76e1b1f534SAlex Bennée 
77e1b1f534SAlex Bennée /* Init Link Control register */
78e1b1f534SAlex Bennée #define VIRTIO_PCI_FLAG_INIT_LNKCTL (1 << VIRTIO_PCI_FLAG_INIT_LNKCTL_BIT)
79e1b1f534SAlex Bennée 
80e1b1f534SAlex Bennée /* Init Power Management */
81e1b1f534SAlex Bennée #define VIRTIO_PCI_FLAG_INIT_PM (1 << VIRTIO_PCI_FLAG_INIT_PM_BIT)
82e1b1f534SAlex Bennée 
835d98e188SJiqian Chen /* Init The No_Soft_Reset bit of Power Management */
845d98e188SJiqian Chen #define VIRTIO_PCI_FLAG_PM_NO_SOFT_RESET \
855d98e188SJiqian Chen   (1 << VIRTIO_PCI_FLAG_PM_NO_SOFT_RESET_BIT)
865d98e188SJiqian Chen 
87e1b1f534SAlex Bennée /* Init Function Level Reset capability */
88e1b1f534SAlex Bennée #define VIRTIO_PCI_FLAG_INIT_FLR (1 << VIRTIO_PCI_FLAG_INIT_FLR_BIT)
89e1b1f534SAlex Bennée 
90e1b1f534SAlex Bennée /* Advanced Error Reporting capability */
91e1b1f534SAlex Bennée #define VIRTIO_PCI_FLAG_AER (1 << VIRTIO_PCI_FLAG_AER_BIT)
92e1b1f534SAlex Bennée 
93e1b1f534SAlex Bennée /* Page Aligned Address space Translation Service */
94e1b1f534SAlex Bennée #define VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED \
95e1b1f534SAlex Bennée   (1 << VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED_BIT)
96e1b1f534SAlex Bennée 
97e1b1f534SAlex Bennée typedef struct {
98e1b1f534SAlex Bennée     MSIMessage msg;
99e1b1f534SAlex Bennée     int virq;
100e1b1f534SAlex Bennée     unsigned int users;
101e1b1f534SAlex Bennée } VirtIOIRQFD;
102e1b1f534SAlex Bennée 
103e1b1f534SAlex Bennée /*
104e1b1f534SAlex Bennée  * virtio-pci: This is the PCIDevice which has a virtio-pci-bus.
105e1b1f534SAlex Bennée  */
106e1b1f534SAlex Bennée #define TYPE_VIRTIO_PCI "virtio-pci"
107e1b1f534SAlex Bennée OBJECT_DECLARE_TYPE(VirtIOPCIProxy, VirtioPCIClass, VIRTIO_PCI)
108e1b1f534SAlex Bennée 
109e1b1f534SAlex Bennée struct VirtioPCIClass {
110e1b1f534SAlex Bennée     PCIDeviceClass parent_class;
111e1b1f534SAlex Bennée     DeviceRealize parent_dc_realize;
112e1b1f534SAlex Bennée     void (*realize)(VirtIOPCIProxy *vpci_dev, Error **errp);
113e1b1f534SAlex Bennée };
114e1b1f534SAlex Bennée 
115e1b1f534SAlex Bennée typedef struct VirtIOPCIRegion {
116e1b1f534SAlex Bennée     MemoryRegion mr;
117e1b1f534SAlex Bennée     uint32_t offset;
118e1b1f534SAlex Bennée     uint32_t size;
119e1b1f534SAlex Bennée     uint32_t type;
120e1b1f534SAlex Bennée } VirtIOPCIRegion;
121e1b1f534SAlex Bennée 
122e1b1f534SAlex Bennée typedef struct VirtIOPCIQueue {
123e1b1f534SAlex Bennée   uint16_t num;
124e1b1f534SAlex Bennée   bool enabled;
125805d782dSXuan Zhuo   /*
126805d782dSXuan Zhuo    * No need to migrate the reset status, because it is always 0
127805d782dSXuan Zhuo    * when the migration starts.
128805d782dSXuan Zhuo    */
129805d782dSXuan Zhuo   bool reset;
130e1b1f534SAlex Bennée   uint32_t desc[2];
131e1b1f534SAlex Bennée   uint32_t avail[2];
132e1b1f534SAlex Bennée   uint32_t used[2];
133e1b1f534SAlex Bennée } VirtIOPCIQueue;
134e1b1f534SAlex Bennée 
135e1b1f534SAlex Bennée struct VirtIOPCIProxy {
136e1b1f534SAlex Bennée     PCIDevice pci_dev;
137e1b1f534SAlex Bennée     MemoryRegion bar;
138e1b1f534SAlex Bennée     union {
139e1b1f534SAlex Bennée         struct {
140e1b1f534SAlex Bennée             VirtIOPCIRegion common;
141e1b1f534SAlex Bennée             VirtIOPCIRegion isr;
142e1b1f534SAlex Bennée             VirtIOPCIRegion device;
143e1b1f534SAlex Bennée             VirtIOPCIRegion notify;
144e1b1f534SAlex Bennée             VirtIOPCIRegion notify_pio;
145e1b1f534SAlex Bennée         };
146e1b1f534SAlex Bennée         VirtIOPCIRegion regs[5];
147e1b1f534SAlex Bennée     };
148e1b1f534SAlex Bennée     MemoryRegion modern_bar;
149e1b1f534SAlex Bennée     MemoryRegion io_bar;
150*55fa4be6SGao Shiyuan     /* address space for VirtIOPCIRegions */
151*55fa4be6SGao Shiyuan     AddressSpace modern_cfg_mem_as;
152*55fa4be6SGao Shiyuan     AddressSpace modern_cfg_io_as;
153e1b1f534SAlex Bennée     uint32_t legacy_io_bar_idx;
154e1b1f534SAlex Bennée     uint32_t msix_bar_idx;
155e1b1f534SAlex Bennée     uint32_t modern_io_bar_idx;
156e1b1f534SAlex Bennée     uint32_t modern_mem_bar_idx;
157e1b1f534SAlex Bennée     int config_cap;
158e1b1f534SAlex Bennée     uint32_t flags;
159e1b1f534SAlex Bennée     bool disable_modern;
160e1b1f534SAlex Bennée     bool ignore_backend_features;
161e1b1f534SAlex Bennée     OnOffAuto disable_legacy;
16222733245SLongpeng     /* Transitional device id */
16322733245SLongpeng     uint16_t trans_devid;
164e1b1f534SAlex Bennée     uint32_t class_code;
165e1b1f534SAlex Bennée     uint32_t nvectors;
166e1b1f534SAlex Bennée     uint32_t dfselect;
167e1b1f534SAlex Bennée     uint32_t gfselect;
168e1b1f534SAlex Bennée     uint32_t guest_features[2];
169e1b1f534SAlex Bennée     VirtIOPCIQueue vqs[VIRTIO_QUEUE_MAX];
170e1b1f534SAlex Bennée 
171e1b1f534SAlex Bennée     VirtIOIRQFD *vector_irqfd;
172e1b1f534SAlex Bennée     int nvqs_with_notifiers;
173e1b1f534SAlex Bennée     VirtioBusState bus;
174e1b1f534SAlex Bennée };
175e1b1f534SAlex Bennée 
virtio_pci_modern(VirtIOPCIProxy * proxy)176e1b1f534SAlex Bennée static inline bool virtio_pci_modern(VirtIOPCIProxy *proxy)
177e1b1f534SAlex Bennée {
178e1b1f534SAlex Bennée     return !proxy->disable_modern;
179e1b1f534SAlex Bennée }
180e1b1f534SAlex Bennée 
virtio_pci_legacy(VirtIOPCIProxy * proxy)181e1b1f534SAlex Bennée static inline bool virtio_pci_legacy(VirtIOPCIProxy *proxy)
182e1b1f534SAlex Bennée {
183e1b1f534SAlex Bennée     return proxy->disable_legacy == ON_OFF_AUTO_OFF;
184e1b1f534SAlex Bennée }
185e1b1f534SAlex Bennée 
virtio_pci_force_virtio_1(VirtIOPCIProxy * proxy)186e1b1f534SAlex Bennée static inline void virtio_pci_force_virtio_1(VirtIOPCIProxy *proxy)
187e1b1f534SAlex Bennée {
188e1b1f534SAlex Bennée     proxy->disable_modern = false;
189e1b1f534SAlex Bennée     proxy->disable_legacy = ON_OFF_AUTO_ON;
190e1b1f534SAlex Bennée }
191e1b1f534SAlex Bennée 
virtio_pci_disable_modern(VirtIOPCIProxy * proxy)192e1b1f534SAlex Bennée static inline void virtio_pci_disable_modern(VirtIOPCIProxy *proxy)
193e1b1f534SAlex Bennée {
194e1b1f534SAlex Bennée     proxy->disable_modern = true;
195e1b1f534SAlex Bennée }
196e1b1f534SAlex Bennée 
19722733245SLongpeng uint16_t virtio_pci_get_trans_devid(uint16_t device_id);
19822733245SLongpeng uint16_t virtio_pci_get_class_id(uint16_t device_id);
19922733245SLongpeng 
200e1b1f534SAlex Bennée /*
201e1b1f534SAlex Bennée  * virtio-input-pci: This extends VirtioPCIProxy.
202e1b1f534SAlex Bennée  */
203e1b1f534SAlex Bennée #define TYPE_VIRTIO_INPUT_PCI "virtio-input-pci"
204e1b1f534SAlex Bennée 
205e1b1f534SAlex Bennée /* Virtio ABI version, if we increment this, we break the guest driver. */
206e1b1f534SAlex Bennée #define VIRTIO_PCI_ABI_VERSION          0
207e1b1f534SAlex Bennée 
208e1b1f534SAlex Bennée /* Input for virtio_pci_types_register() */
209e1b1f534SAlex Bennée typedef struct VirtioPCIDeviceTypeInfo {
210e1b1f534SAlex Bennée     /*
211e1b1f534SAlex Bennée      * Common base class for the subclasses below.
212e1b1f534SAlex Bennée      *
213e1b1f534SAlex Bennée      * Required only if transitional_name or non_transitional_name is set.
214e1b1f534SAlex Bennée      *
215e1b1f534SAlex Bennée      * We need a separate base type instead of making all types
216e1b1f534SAlex Bennée      * inherit from generic_name for two reasons:
217e1b1f534SAlex Bennée      * 1) generic_name implements INTERFACE_PCIE_DEVICE, but
218e1b1f534SAlex Bennée      *    transitional_name does not.
219e1b1f534SAlex Bennée      * 2) generic_name has the "disable-legacy" and "disable-modern"
220e1b1f534SAlex Bennée      *    properties, transitional_name and non_transitional name don't.
221e1b1f534SAlex Bennée      */
222e1b1f534SAlex Bennée     const char *base_name;
223e1b1f534SAlex Bennée     /*
224e1b1f534SAlex Bennée      * Generic device type.  Optional.
225e1b1f534SAlex Bennée      *
226e1b1f534SAlex Bennée      * Supports both transitional and non-transitional modes,
227e1b1f534SAlex Bennée      * using the disable-legacy and disable-modern properties.
228e1b1f534SAlex Bennée      * If disable-legacy=auto, (non-)transitional mode is selected
229e1b1f534SAlex Bennée      * depending on the bus where the device is plugged.
230e1b1f534SAlex Bennée      *
231e1b1f534SAlex Bennée      * Implements both INTERFACE_PCIE_DEVICE and INTERFACE_CONVENTIONAL_PCI_DEVICE,
232e1b1f534SAlex Bennée      * but PCI Express is supported only in non-transitional mode.
233e1b1f534SAlex Bennée      *
234e1b1f534SAlex Bennée      * The only type implemented by QEMU 3.1 and older.
235e1b1f534SAlex Bennée      */
236e1b1f534SAlex Bennée     const char *generic_name;
237e1b1f534SAlex Bennée     /*
238e1b1f534SAlex Bennée      * The transitional device type.  Optional.
239e1b1f534SAlex Bennée      *
240e1b1f534SAlex Bennée      * Implements both INTERFACE_PCIE_DEVICE and INTERFACE_CONVENTIONAL_PCI_DEVICE.
241e1b1f534SAlex Bennée      */
242e1b1f534SAlex Bennée     const char *transitional_name;
243e1b1f534SAlex Bennée     /*
244e1b1f534SAlex Bennée      * The non-transitional device type.  Optional.
245e1b1f534SAlex Bennée      *
246e1b1f534SAlex Bennée      * Implements INTERFACE_CONVENTIONAL_PCI_DEVICE only.
247e1b1f534SAlex Bennée      */
248e1b1f534SAlex Bennée     const char *non_transitional_name;
249e1b1f534SAlex Bennée 
250e1b1f534SAlex Bennée     /* Parent type.  If NULL, TYPE_VIRTIO_PCI is used */
251e1b1f534SAlex Bennée     const char *parent;
252e1b1f534SAlex Bennée 
253e1b1f534SAlex Bennée     /* Same as TypeInfo fields: */
254e1b1f534SAlex Bennée     size_t instance_size;
255e1b1f534SAlex Bennée     size_t class_size;
256e1b1f534SAlex Bennée     void (*instance_init)(Object *obj);
257837053a7SPhilippe Mathieu-Daudé     void (*instance_finalize)(Object *obj);
258e1b1f534SAlex Bennée     void (*class_init)(ObjectClass *klass, void *data);
259e1b1f534SAlex Bennée     InterfaceInfo *interfaces;
260e1b1f534SAlex Bennée } VirtioPCIDeviceTypeInfo;
261e1b1f534SAlex Bennée 
262e1b1f534SAlex Bennée /* Register virtio-pci type(s).  @t must be static. */
263e1b1f534SAlex Bennée void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t);
264e1b1f534SAlex Bennée 
265e1b1f534SAlex Bennée /**
266e1b1f534SAlex Bennée  * virtio_pci_optimal_num_queues:
267e1b1f534SAlex Bennée  * @fixed_queues: number of queues that are always present
268e1b1f534SAlex Bennée  *
269e1b1f534SAlex Bennée  * Returns: The optimal number of queues for a multi-queue device, excluding
270e1b1f534SAlex Bennée  * @fixed_queues.
271e1b1f534SAlex Bennée  */
272e1b1f534SAlex Bennée unsigned virtio_pci_optimal_num_queues(unsigned fixed_queues);
27316805428SCindy Lu void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq,
27416805428SCindy Lu                                               int n, bool assign,
27516805428SCindy Lu                                               bool with_irqfd);
276605a16a7SDr. David Alan Gilbert 
277605a16a7SDr. David Alan Gilbert int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy, uint8_t bar, uint64_t offset,
278605a16a7SDr. David Alan Gilbert                            uint64_t length, uint8_t id);
279605a16a7SDr. David Alan Gilbert 
280e1b1f534SAlex Bennée #endif
281