xref: /openbmc/qemu/include/hw/virtio/virtio-pci.h (revision 67f5b279)
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,
46*5d98e188SJiqian 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 
83*5d98e188SJiqian Chen /* Init The No_Soft_Reset bit of Power Management */
84*5d98e188SJiqian Chen #define VIRTIO_PCI_FLAG_PM_NO_SOFT_RESET \
85*5d98e188SJiqian Chen   (1 << VIRTIO_PCI_FLAG_PM_NO_SOFT_RESET_BIT)
86*5d98e188SJiqian 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;
150e1b1f534SAlex Bennée     uint32_t legacy_io_bar_idx;
151e1b1f534SAlex Bennée     uint32_t msix_bar_idx;
152e1b1f534SAlex Bennée     uint32_t modern_io_bar_idx;
153e1b1f534SAlex Bennée     uint32_t modern_mem_bar_idx;
154e1b1f534SAlex Bennée     int config_cap;
155e1b1f534SAlex Bennée     uint32_t flags;
156e1b1f534SAlex Bennée     bool disable_modern;
157e1b1f534SAlex Bennée     bool ignore_backend_features;
158e1b1f534SAlex Bennée     OnOffAuto disable_legacy;
15922733245SLongpeng     /* Transitional device id */
16022733245SLongpeng     uint16_t trans_devid;
161e1b1f534SAlex Bennée     uint32_t class_code;
162e1b1f534SAlex Bennée     uint32_t nvectors;
163e1b1f534SAlex Bennée     uint32_t dfselect;
164e1b1f534SAlex Bennée     uint32_t gfselect;
165e1b1f534SAlex Bennée     uint32_t guest_features[2];
166e1b1f534SAlex Bennée     VirtIOPCIQueue vqs[VIRTIO_QUEUE_MAX];
167e1b1f534SAlex Bennée 
168e1b1f534SAlex Bennée     VirtIOIRQFD *vector_irqfd;
169e1b1f534SAlex Bennée     int nvqs_with_notifiers;
170e1b1f534SAlex Bennée     VirtioBusState bus;
171e1b1f534SAlex Bennée };
172e1b1f534SAlex Bennée 
virtio_pci_modern(VirtIOPCIProxy * proxy)173e1b1f534SAlex Bennée static inline bool virtio_pci_modern(VirtIOPCIProxy *proxy)
174e1b1f534SAlex Bennée {
175e1b1f534SAlex Bennée     return !proxy->disable_modern;
176e1b1f534SAlex Bennée }
177e1b1f534SAlex Bennée 
virtio_pci_legacy(VirtIOPCIProxy * proxy)178e1b1f534SAlex Bennée static inline bool virtio_pci_legacy(VirtIOPCIProxy *proxy)
179e1b1f534SAlex Bennée {
180e1b1f534SAlex Bennée     return proxy->disable_legacy == ON_OFF_AUTO_OFF;
181e1b1f534SAlex Bennée }
182e1b1f534SAlex Bennée 
virtio_pci_force_virtio_1(VirtIOPCIProxy * proxy)183e1b1f534SAlex Bennée static inline void virtio_pci_force_virtio_1(VirtIOPCIProxy *proxy)
184e1b1f534SAlex Bennée {
185e1b1f534SAlex Bennée     proxy->disable_modern = false;
186e1b1f534SAlex Bennée     proxy->disable_legacy = ON_OFF_AUTO_ON;
187e1b1f534SAlex Bennée }
188e1b1f534SAlex Bennée 
virtio_pci_disable_modern(VirtIOPCIProxy * proxy)189e1b1f534SAlex Bennée static inline void virtio_pci_disable_modern(VirtIOPCIProxy *proxy)
190e1b1f534SAlex Bennée {
191e1b1f534SAlex Bennée     proxy->disable_modern = true;
192e1b1f534SAlex Bennée }
193e1b1f534SAlex Bennée 
19422733245SLongpeng uint16_t virtio_pci_get_trans_devid(uint16_t device_id);
19522733245SLongpeng uint16_t virtio_pci_get_class_id(uint16_t device_id);
19622733245SLongpeng 
197e1b1f534SAlex Bennée /*
198e1b1f534SAlex Bennée  * virtio-input-pci: This extends VirtioPCIProxy.
199e1b1f534SAlex Bennée  */
200e1b1f534SAlex Bennée #define TYPE_VIRTIO_INPUT_PCI "virtio-input-pci"
201e1b1f534SAlex Bennée 
202e1b1f534SAlex Bennée /* Virtio ABI version, if we increment this, we break the guest driver. */
203e1b1f534SAlex Bennée #define VIRTIO_PCI_ABI_VERSION          0
204e1b1f534SAlex Bennée 
205e1b1f534SAlex Bennée /* Input for virtio_pci_types_register() */
206e1b1f534SAlex Bennée typedef struct VirtioPCIDeviceTypeInfo {
207e1b1f534SAlex Bennée     /*
208e1b1f534SAlex Bennée      * Common base class for the subclasses below.
209e1b1f534SAlex Bennée      *
210e1b1f534SAlex Bennée      * Required only if transitional_name or non_transitional_name is set.
211e1b1f534SAlex Bennée      *
212e1b1f534SAlex Bennée      * We need a separate base type instead of making all types
213e1b1f534SAlex Bennée      * inherit from generic_name for two reasons:
214e1b1f534SAlex Bennée      * 1) generic_name implements INTERFACE_PCIE_DEVICE, but
215e1b1f534SAlex Bennée      *    transitional_name does not.
216e1b1f534SAlex Bennée      * 2) generic_name has the "disable-legacy" and "disable-modern"
217e1b1f534SAlex Bennée      *    properties, transitional_name and non_transitional name don't.
218e1b1f534SAlex Bennée      */
219e1b1f534SAlex Bennée     const char *base_name;
220e1b1f534SAlex Bennée     /*
221e1b1f534SAlex Bennée      * Generic device type.  Optional.
222e1b1f534SAlex Bennée      *
223e1b1f534SAlex Bennée      * Supports both transitional and non-transitional modes,
224e1b1f534SAlex Bennée      * using the disable-legacy and disable-modern properties.
225e1b1f534SAlex Bennée      * If disable-legacy=auto, (non-)transitional mode is selected
226e1b1f534SAlex Bennée      * depending on the bus where the device is plugged.
227e1b1f534SAlex Bennée      *
228e1b1f534SAlex Bennée      * Implements both INTERFACE_PCIE_DEVICE and INTERFACE_CONVENTIONAL_PCI_DEVICE,
229e1b1f534SAlex Bennée      * but PCI Express is supported only in non-transitional mode.
230e1b1f534SAlex Bennée      *
231e1b1f534SAlex Bennée      * The only type implemented by QEMU 3.1 and older.
232e1b1f534SAlex Bennée      */
233e1b1f534SAlex Bennée     const char *generic_name;
234e1b1f534SAlex Bennée     /*
235e1b1f534SAlex Bennée      * The transitional device type.  Optional.
236e1b1f534SAlex Bennée      *
237e1b1f534SAlex Bennée      * Implements both INTERFACE_PCIE_DEVICE and INTERFACE_CONVENTIONAL_PCI_DEVICE.
238e1b1f534SAlex Bennée      */
239e1b1f534SAlex Bennée     const char *transitional_name;
240e1b1f534SAlex Bennée     /*
241e1b1f534SAlex Bennée      * The non-transitional device type.  Optional.
242e1b1f534SAlex Bennée      *
243e1b1f534SAlex Bennée      * Implements INTERFACE_CONVENTIONAL_PCI_DEVICE only.
244e1b1f534SAlex Bennée      */
245e1b1f534SAlex Bennée     const char *non_transitional_name;
246e1b1f534SAlex Bennée 
247e1b1f534SAlex Bennée     /* Parent type.  If NULL, TYPE_VIRTIO_PCI is used */
248e1b1f534SAlex Bennée     const char *parent;
249e1b1f534SAlex Bennée 
250e1b1f534SAlex Bennée     /* Same as TypeInfo fields: */
251e1b1f534SAlex Bennée     size_t instance_size;
252e1b1f534SAlex Bennée     size_t class_size;
253e1b1f534SAlex Bennée     void (*instance_init)(Object *obj);
254837053a7SPhilippe Mathieu-Daudé     void (*instance_finalize)(Object *obj);
255e1b1f534SAlex Bennée     void (*class_init)(ObjectClass *klass, void *data);
256e1b1f534SAlex Bennée     InterfaceInfo *interfaces;
257e1b1f534SAlex Bennée } VirtioPCIDeviceTypeInfo;
258e1b1f534SAlex Bennée 
259e1b1f534SAlex Bennée /* Register virtio-pci type(s).  @t must be static. */
260e1b1f534SAlex Bennée void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t);
261e1b1f534SAlex Bennée 
262e1b1f534SAlex Bennée /**
263e1b1f534SAlex Bennée  * virtio_pci_optimal_num_queues:
264e1b1f534SAlex Bennée  * @fixed_queues: number of queues that are always present
265e1b1f534SAlex Bennée  *
266e1b1f534SAlex Bennée  * Returns: The optimal number of queues for a multi-queue device, excluding
267e1b1f534SAlex Bennée  * @fixed_queues.
268e1b1f534SAlex Bennée  */
269e1b1f534SAlex Bennée unsigned virtio_pci_optimal_num_queues(unsigned fixed_queues);
27016805428SCindy Lu void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq,
27116805428SCindy Lu                                               int n, bool assign,
27216805428SCindy Lu                                               bool with_irqfd);
273605a16a7SDr. David Alan Gilbert 
274605a16a7SDr. David Alan Gilbert int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy, uint8_t bar, uint64_t offset,
275605a16a7SDr. David Alan Gilbert                            uint64_t length, uint8_t id);
276605a16a7SDr. David Alan Gilbert 
277e1b1f534SAlex Bennée #endif
278