1 /* 2 * Virtio PCI Bindings 3 * 4 * Copyright IBM, Corp. 2007 5 * Copyright (c) 2009 CodeSourcery 6 * 7 * Authors: 8 * Anthony Liguori <aliguori@us.ibm.com> 9 * Paul Brook <paul@codesourcery.com> 10 * 11 * This work is licensed under the terms of the GNU GPL, version 2. See 12 * the COPYING file in the top-level directory. 13 */ 14 15 #ifndef QEMU_VIRTIO_PCI_H 16 #define QEMU_VIRTIO_PCI_H 17 18 #include "hw/pci/msi.h" 19 #include "hw/virtio/virtio-blk.h" 20 #include "hw/virtio/virtio-net.h" 21 #include "hw/virtio/virtio-serial.h" 22 #include "hw/virtio/virtio-scsi.h" 23 #include "hw/virtio/virtio-bus.h" 24 #include "hw/virtio/virtio-gpu.h" 25 #include "hw/virtio/virtio-crypto.h" 26 27 typedef struct VirtIOPCIProxy VirtIOPCIProxy; 28 typedef struct VirtIOBlkPCI VirtIOBlkPCI; 29 typedef struct VirtIOSCSIPCI VirtIOSCSIPCI; 30 typedef struct VirtIOSerialPCI VirtIOSerialPCI; 31 typedef struct VirtIONetPCI VirtIONetPCI; 32 typedef struct VirtIOGPUPCI VirtIOGPUPCI; 33 typedef struct VirtIOCryptoPCI VirtIOCryptoPCI; 34 35 /* virtio-pci-bus */ 36 37 typedef struct VirtioBusState VirtioPCIBusState; 38 typedef struct VirtioBusClass VirtioPCIBusClass; 39 40 #define TYPE_VIRTIO_PCI_BUS "virtio-pci-bus" 41 #define VIRTIO_PCI_BUS(obj) \ 42 OBJECT_CHECK(VirtioPCIBusState, (obj), TYPE_VIRTIO_PCI_BUS) 43 #define VIRTIO_PCI_BUS_GET_CLASS(obj) \ 44 OBJECT_GET_CLASS(VirtioPCIBusClass, obj, TYPE_VIRTIO_PCI_BUS) 45 #define VIRTIO_PCI_BUS_CLASS(klass) \ 46 OBJECT_CLASS_CHECK(VirtioPCIBusClass, klass, TYPE_VIRTIO_PCI_BUS) 47 48 enum { 49 VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT, 50 VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, 51 VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT, 52 VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT, 53 VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT, 54 VIRTIO_PCI_FLAG_PAGE_PER_VQ_BIT, 55 VIRTIO_PCI_FLAG_ATS_BIT, 56 VIRTIO_PCI_FLAG_INIT_DEVERR_BIT, 57 VIRTIO_PCI_FLAG_INIT_LNKCTL_BIT, 58 VIRTIO_PCI_FLAG_INIT_PM_BIT, 59 }; 60 61 /* Need to activate work-arounds for buggy guests at vmstate load. */ 62 #define VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION \ 63 (1 << VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT) 64 65 /* Performance improves when virtqueue kick processing is decoupled from the 66 * vcpu thread using ioeventfd for some devices. */ 67 #define VIRTIO_PCI_FLAG_USE_IOEVENTFD (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT) 68 69 /* virtio version flags */ 70 #define VIRTIO_PCI_FLAG_DISABLE_PCIE (1 << VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT) 71 72 /* migrate extra state */ 73 #define VIRTIO_PCI_FLAG_MIGRATE_EXTRA (1 << VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT) 74 75 /* have pio notification for modern device ? */ 76 #define VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY \ 77 (1 << VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT) 78 79 /* page per vq flag to be used by split drivers within guests */ 80 #define VIRTIO_PCI_FLAG_PAGE_PER_VQ \ 81 (1 << VIRTIO_PCI_FLAG_PAGE_PER_VQ_BIT) 82 83 /* address space translation service */ 84 #define VIRTIO_PCI_FLAG_ATS (1 << VIRTIO_PCI_FLAG_ATS_BIT) 85 86 /* Init error enabling flags */ 87 #define VIRTIO_PCI_FLAG_INIT_DEVERR (1 << VIRTIO_PCI_FLAG_INIT_DEVERR_BIT) 88 89 /* Init Link Control register */ 90 #define VIRTIO_PCI_FLAG_INIT_LNKCTL (1 << VIRTIO_PCI_FLAG_INIT_LNKCTL_BIT) 91 92 /* Init Power Management */ 93 #define VIRTIO_PCI_FLAG_INIT_PM (1 << VIRTIO_PCI_FLAG_INIT_PM_BIT) 94 95 typedef struct { 96 MSIMessage msg; 97 int virq; 98 unsigned int users; 99 } VirtIOIRQFD; 100 101 /* 102 * virtio-pci: This is the PCIDevice which has a virtio-pci-bus. 103 */ 104 #define TYPE_VIRTIO_PCI "virtio-pci" 105 #define VIRTIO_PCI_GET_CLASS(obj) \ 106 OBJECT_GET_CLASS(VirtioPCIClass, obj, TYPE_VIRTIO_PCI) 107 #define VIRTIO_PCI_CLASS(klass) \ 108 OBJECT_CLASS_CHECK(VirtioPCIClass, klass, TYPE_VIRTIO_PCI) 109 #define VIRTIO_PCI(obj) \ 110 OBJECT_CHECK(VirtIOPCIProxy, (obj), TYPE_VIRTIO_PCI) 111 112 typedef struct VirtioPCIClass { 113 PCIDeviceClass parent_class; 114 DeviceRealize parent_dc_realize; 115 void (*realize)(VirtIOPCIProxy *vpci_dev, Error **errp); 116 } VirtioPCIClass; 117 118 typedef struct VirtIOPCIRegion { 119 MemoryRegion mr; 120 uint32_t offset; 121 uint32_t size; 122 uint32_t type; 123 } VirtIOPCIRegion; 124 125 typedef struct VirtIOPCIQueue { 126 uint16_t num; 127 bool enabled; 128 uint32_t desc[2]; 129 uint32_t avail[2]; 130 uint32_t used[2]; 131 } VirtIOPCIQueue; 132 133 struct VirtIOPCIProxy { 134 PCIDevice pci_dev; 135 MemoryRegion bar; 136 union { 137 struct { 138 VirtIOPCIRegion common; 139 VirtIOPCIRegion isr; 140 VirtIOPCIRegion device; 141 VirtIOPCIRegion notify; 142 VirtIOPCIRegion notify_pio; 143 }; 144 VirtIOPCIRegion regs[5]; 145 }; 146 MemoryRegion modern_bar; 147 MemoryRegion io_bar; 148 uint32_t legacy_io_bar_idx; 149 uint32_t msix_bar_idx; 150 uint32_t modern_io_bar_idx; 151 uint32_t modern_mem_bar_idx; 152 int config_cap; 153 uint32_t flags; 154 bool disable_modern; 155 bool ignore_backend_features; 156 OnOffAuto disable_legacy; 157 uint32_t class_code; 158 uint32_t nvectors; 159 uint32_t dfselect; 160 uint32_t gfselect; 161 uint32_t guest_features[2]; 162 VirtIOPCIQueue vqs[VIRTIO_QUEUE_MAX]; 163 164 VirtIOIRQFD *vector_irqfd; 165 int nvqs_with_notifiers; 166 VirtioBusState bus; 167 }; 168 169 static inline bool virtio_pci_modern(VirtIOPCIProxy *proxy) 170 { 171 return !proxy->disable_modern; 172 } 173 174 static inline bool virtio_pci_legacy(VirtIOPCIProxy *proxy) 175 { 176 return proxy->disable_legacy == ON_OFF_AUTO_OFF; 177 } 178 179 static inline void virtio_pci_force_virtio_1(VirtIOPCIProxy *proxy) 180 { 181 proxy->disable_modern = false; 182 proxy->disable_legacy = ON_OFF_AUTO_ON; 183 } 184 185 static inline void virtio_pci_disable_modern(VirtIOPCIProxy *proxy) 186 { 187 proxy->disable_modern = true; 188 } 189 190 /* 191 * virtio-scsi-pci: This extends VirtioPCIProxy. 192 */ 193 #define TYPE_VIRTIO_SCSI_PCI "virtio-scsi-pci-base" 194 #define VIRTIO_SCSI_PCI(obj) \ 195 OBJECT_CHECK(VirtIOSCSIPCI, (obj), TYPE_VIRTIO_SCSI_PCI) 196 197 struct VirtIOSCSIPCI { 198 VirtIOPCIProxy parent_obj; 199 VirtIOSCSI vdev; 200 }; 201 202 /* 203 * virtio-blk-pci: This extends VirtioPCIProxy. 204 */ 205 #define TYPE_VIRTIO_BLK_PCI "virtio-blk-pci-base" 206 #define VIRTIO_BLK_PCI(obj) \ 207 OBJECT_CHECK(VirtIOBlkPCI, (obj), TYPE_VIRTIO_BLK_PCI) 208 209 struct VirtIOBlkPCI { 210 VirtIOPCIProxy parent_obj; 211 VirtIOBlock vdev; 212 }; 213 214 /* 215 * virtio-serial-pci: This extends VirtioPCIProxy. 216 */ 217 #define TYPE_VIRTIO_SERIAL_PCI "virtio-serial-pci-base" 218 #define VIRTIO_SERIAL_PCI(obj) \ 219 OBJECT_CHECK(VirtIOSerialPCI, (obj), TYPE_VIRTIO_SERIAL_PCI) 220 221 struct VirtIOSerialPCI { 222 VirtIOPCIProxy parent_obj; 223 VirtIOSerial vdev; 224 }; 225 226 /* 227 * virtio-net-pci: This extends VirtioPCIProxy. 228 */ 229 #define TYPE_VIRTIO_NET_PCI "virtio-net-pci-base" 230 #define VIRTIO_NET_PCI(obj) \ 231 OBJECT_CHECK(VirtIONetPCI, (obj), TYPE_VIRTIO_NET_PCI) 232 233 struct VirtIONetPCI { 234 VirtIOPCIProxy parent_obj; 235 VirtIONet vdev; 236 }; 237 238 /* 239 * virtio-input-pci: This extends VirtioPCIProxy. 240 */ 241 #define TYPE_VIRTIO_INPUT_PCI "virtio-input-pci" 242 243 /* 244 * virtio-gpu-pci: This extends VirtioPCIProxy. 245 */ 246 #define TYPE_VIRTIO_GPU_PCI "virtio-gpu-pci" 247 #define VIRTIO_GPU_PCI(obj) \ 248 OBJECT_CHECK(VirtIOGPUPCI, (obj), TYPE_VIRTIO_GPU_PCI) 249 250 struct VirtIOGPUPCI { 251 VirtIOPCIProxy parent_obj; 252 VirtIOGPU vdev; 253 }; 254 255 /* 256 * virtio-crypto-pci: This extends VirtioPCIProxy. 257 */ 258 #define TYPE_VIRTIO_CRYPTO_PCI "virtio-crypto-pci" 259 #define VIRTIO_CRYPTO_PCI(obj) \ 260 OBJECT_CHECK(VirtIOCryptoPCI, (obj), TYPE_VIRTIO_CRYPTO_PCI) 261 262 struct VirtIOCryptoPCI { 263 VirtIOPCIProxy parent_obj; 264 VirtIOCrypto vdev; 265 }; 266 267 /* Virtio ABI version, if we increment this, we break the guest driver. */ 268 #define VIRTIO_PCI_ABI_VERSION 0 269 270 /* Input for virtio_pci_types_register() */ 271 typedef struct VirtioPCIDeviceTypeInfo { 272 /* 273 * Common base class for the subclasses below. 274 * 275 * Required only if transitional_name or non_transitional_name is set. 276 * 277 * We need a separate base type instead of making all types 278 * inherit from generic_name for two reasons: 279 * 1) generic_name implements INTERFACE_PCIE_DEVICE, but 280 * transitional_name does not. 281 * 2) generic_name has the "disable-legacy" and "disable-modern" 282 * properties, transitional_name and non_transitional name don't. 283 */ 284 const char *base_name; 285 /* 286 * Generic device type. Optional. 287 * 288 * Supports both transitional and non-transitional modes, 289 * using the disable-legacy and disable-modern properties. 290 * If disable-legacy=auto, (non-)transitional mode is selected 291 * depending on the bus where the device is plugged. 292 * 293 * Implements both INTERFACE_PCIE_DEVICE and INTERFACE_CONVENTIONAL_PCI_DEVICE, 294 * but PCI Express is supported only in non-transitional mode. 295 * 296 * The only type implemented by QEMU 3.1 and older. 297 */ 298 const char *generic_name; 299 /* 300 * The transitional device type. Optional. 301 * 302 * Implements both INTERFACE_PCIE_DEVICE and INTERFACE_CONVENTIONAL_PCI_DEVICE. 303 */ 304 const char *transitional_name; 305 /* 306 * The non-transitional device type. Optional. 307 * 308 * Implements INTERFACE_CONVENTIONAL_PCI_DEVICE only. 309 */ 310 const char *non_transitional_name; 311 312 /* Parent type. If NULL, TYPE_VIRTIO_PCI is used */ 313 const char *parent; 314 315 /* Same as TypeInfo fields: */ 316 size_t instance_size; 317 void (*instance_init)(Object *obj); 318 void (*class_init)(ObjectClass *klass, void *data); 319 } VirtioPCIDeviceTypeInfo; 320 321 /* Register virtio-pci type(s). @t must be static. */ 322 void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t); 323 324 #endif 325