| 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-bus.h" |
| 20 | #include "qom/object.h" |
| 21 | |
| 22 | |
| 23 | /* virtio-pci-bus */ |
| 24 | |
| 25 | typedef struct VirtioBusState VirtioPCIBusState; |
| 26 | typedef struct VirtioBusClass VirtioPCIBusClass; |
| 27 | |
| 28 | #define TYPE_VIRTIO_PCI_BUS "virtio-pci-bus" |
| 29 | DECLARE_OBJ_CHECKERS(VirtioPCIBusState, VirtioPCIBusClass, |
| 30 | VIRTIO_PCI_BUS, TYPE_VIRTIO_PCI_BUS) |
| 31 | |
| 32 | enum { |
| 33 | VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT, |
| 34 | VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, |
| 35 | VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT, |
| 36 | VIRTIO_PCI_FLAG_PAGE_PER_VQ_BIT, |
| 37 | VIRTIO_PCI_FLAG_ATS_BIT, |
| 38 | VIRTIO_PCI_FLAG_INIT_FLR_BIT, |
| 39 | VIRTIO_PCI_FLAG_AER_BIT, |
| 40 | VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED_BIT, |
| 41 | VIRTIO_PCI_FLAG_PM_NO_SOFT_RESET_BIT, |
| 42 | }; |
| 43 | |
| 44 | /* Need to activate work-arounds for buggy guests at vmstate load. */ |
| 45 | #define VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION \ |
| 46 | (1 << VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT) |
| 47 | |
| 48 | /* Performance improves when virtqueue kick processing is decoupled from the |
| 49 | * vcpu thread using ioeventfd for some devices. */ |
| 50 | #define VIRTIO_PCI_FLAG_USE_IOEVENTFD (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT) |
| 51 | |
| 52 | /* have pio notification for modern device ? */ |
| 53 | #define VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY \ |
| 54 | (1 << VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT) |
| 55 | |
| 56 | /* page per vq flag to be used by split drivers within guests */ |
| 57 | #define VIRTIO_PCI_FLAG_PAGE_PER_VQ \ |
| 58 | (1 << VIRTIO_PCI_FLAG_PAGE_PER_VQ_BIT) |
| 59 | |
| 60 | /* address space translation service */ |
| 61 | #define VIRTIO_PCI_FLAG_ATS (1 << VIRTIO_PCI_FLAG_ATS_BIT) |
| 62 | |
| 63 | /* Init The No_Soft_Reset bit of Power Management */ |
| 64 | #define VIRTIO_PCI_FLAG_PM_NO_SOFT_RESET \ |
| 65 | (1 << VIRTIO_PCI_FLAG_PM_NO_SOFT_RESET_BIT) |
| 66 | |
| 67 | /* Init Function Level Reset capability */ |
| 68 | #define VIRTIO_PCI_FLAG_INIT_FLR (1 << VIRTIO_PCI_FLAG_INIT_FLR_BIT) |
| 69 | |
| 70 | /* Advanced Error Reporting capability */ |
| 71 | #define VIRTIO_PCI_FLAG_AER (1 << VIRTIO_PCI_FLAG_AER_BIT) |
| 72 | |
| 73 | /* Page Aligned Address space Translation Service */ |
| 74 | #define VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED \ |
| 75 | (1 << VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED_BIT) |
| 76 | |
| 77 | typedef struct { |
| 78 | MSIMessage msg; |
| 79 | int virq; |
| 80 | unsigned int users; |
| 81 | } VirtIOIRQFD; |
| 82 | |
| 83 | /* |
| 84 | * virtio-pci: This is the PCIDevice which has a virtio-pci-bus. |
| 85 | */ |
| 86 | #define TYPE_VIRTIO_PCI "virtio-pci" |
| 87 | OBJECT_DECLARE_TYPE(VirtIOPCIProxy, VirtioPCIClass, VIRTIO_PCI) |
| 88 | |
| 89 | struct VirtioPCIClass { |
| 90 | PCIDeviceClass parent_class; |
| 91 | DeviceRealize parent_dc_realize; |
| 92 | void (*realize)(VirtIOPCIProxy *vpci_dev, Error **errp); |
| 93 | }; |
| 94 | |
| 95 | typedef struct VirtIOPCIRegion { |
| 96 | MemoryRegion mr; |
| 97 | uint32_t offset; |
| 98 | uint32_t size; |
| 99 | uint32_t type; |
| 100 | } VirtIOPCIRegion; |
| 101 | |
| 102 | typedef struct VirtIOPCIQueue { |
| 103 | uint16_t num; |
| 104 | bool enabled; |
| 105 | /* |
| 106 | * No need to migrate the reset status, because it is always 0 |
| 107 | * when the migration starts. |
| 108 | */ |
| 109 | bool reset; |
| 110 | uint32_t desc[2]; |
| 111 | uint32_t avail[2]; |
| 112 | uint32_t used[2]; |
| 113 | } VirtIOPCIQueue; |
| 114 | |
| 115 | struct VirtIOPCIProxy { |
| 116 | PCIDevice pci_dev; |
| 117 | MemoryRegion bar; |
| 118 | union { |
| 119 | struct { |
| 120 | VirtIOPCIRegion common; |
| 121 | VirtIOPCIRegion isr; |
| 122 | VirtIOPCIRegion device; |
| 123 | VirtIOPCIRegion notify; |
| 124 | VirtIOPCIRegion notify_pio; |
| 125 | }; |
| 126 | VirtIOPCIRegion regs[5]; |
| 127 | }; |
| 128 | MemoryRegion modern_bar; |
| 129 | MemoryRegion io_bar; |
| 130 | /* address space for VirtIOPCIRegions */ |
| 131 | AddressSpace modern_cfg_mem_as; |
| 132 | AddressSpace modern_cfg_io_as; |
| 133 | uint32_t legacy_io_bar_idx; |
| 134 | uint32_t msix_bar_idx; |
| 135 | uint32_t modern_io_bar_idx; |
| 136 | uint32_t modern_mem_bar_idx; |
| 137 | int config_cap; |
| 138 | uint16_t last_pcie_cap_offset; |
| 139 | uint32_t flags; |
| 140 | bool disable_modern; |
| 141 | OnOffAuto disable_legacy; |
| 142 | /* Transitional device id */ |
| 143 | uint16_t trans_devid; |
| 144 | uint32_t class_code; |
| 145 | uint32_t nvectors; |
| 146 | uint32_t dfselect; |
| 147 | uint32_t gfselect; |
| 148 | uint32_t guest_features[VIRTIO_FEATURES_NU32S]; |
| 149 | VirtIOPCIQueue vqs[VIRTIO_QUEUE_MAX]; |
| 150 | |
| 151 | VirtIOIRQFD *vector_irqfd; |
| 152 | int nvqs_with_notifiers; |
| 153 | VirtioBusState bus; |
| 154 | }; |
| 155 | |
| 156 | static inline bool virtio_pci_modern(VirtIOPCIProxy *proxy) |
| 157 | { |
| 158 | return !proxy->disable_modern; |
| 159 | } |
| 160 | |
| 161 | static inline bool virtio_pci_legacy(VirtIOPCIProxy *proxy) |
| 162 | { |
| 163 | return proxy->disable_legacy == ON_OFF_AUTO_OFF; |
| 164 | } |
| 165 | |
| 166 | static inline void virtio_pci_force_virtio_1(VirtIOPCIProxy *proxy) |
| 167 | { |
| 168 | proxy->disable_modern = false; |
| 169 | proxy->disable_legacy = ON_OFF_AUTO_ON; |
| 170 | } |
| 171 | |
| 172 | static inline void virtio_pci_disable_modern(VirtIOPCIProxy *proxy) |
| 173 | { |
| 174 | proxy->disable_modern = true; |
| 175 | } |
| 176 | |
| 177 | uint16_t virtio_pci_get_trans_devid(uint16_t device_id); |
| 178 | uint16_t virtio_pci_get_class_id(uint16_t device_id); |
| 179 | |
| 180 | /* |
| 181 | * virtio-input-pci: This extends VirtioPCIProxy. |
| 182 | */ |
| 183 | #define TYPE_VIRTIO_INPUT_PCI "virtio-input-pci" |
| 184 | |
| 185 | /* Virtio ABI version, if we increment this, we break the guest driver. */ |
| 186 | #define VIRTIO_PCI_ABI_VERSION 0 |
| 187 | |
| 188 | /* Input for virtio_pci_types_register() */ |
| 189 | typedef struct VirtioPCIDeviceTypeInfo { |
| 190 | /* |
| 191 | * Common base class for the subclasses below. |
| 192 | * |
| 193 | * Required only if transitional_name or non_transitional_name is set. |
| 194 | * |
| 195 | * We need a separate base type instead of making all types |
| 196 | * inherit from generic_name for two reasons: |
| 197 | * 1) generic_name implements INTERFACE_PCIE_DEVICE, but |
| 198 | * transitional_name does not. |
| 199 | * 2) generic_name has the "disable-legacy" and "disable-modern" |
| 200 | * properties, transitional_name and non_transitional name don't. |
| 201 | */ |
| 202 | const char *base_name; |
| 203 | /* |
| 204 | * Generic device type. Optional. |
| 205 | * |
| 206 | * Supports both transitional and non-transitional modes, |
| 207 | * using the disable-legacy and disable-modern properties. |
| 208 | * If disable-legacy=auto, (non-)transitional mode is selected |
| 209 | * depending on the bus where the device is plugged. |
| 210 | * |
| 211 | * Implements both INTERFACE_PCIE_DEVICE and INTERFACE_CONVENTIONAL_PCI_DEVICE, |
| 212 | * but PCI Express is supported only in non-transitional mode. |
| 213 | * |
| 214 | * The only type implemented by QEMU 3.1 and older. |
| 215 | */ |
| 216 | const char *generic_name; |
| 217 | /* |
| 218 | * The transitional device type. Optional. |
| 219 | * |
| 220 | * Implements both INTERFACE_PCIE_DEVICE and INTERFACE_CONVENTIONAL_PCI_DEVICE. |
| 221 | */ |
| 222 | const char *transitional_name; |
| 223 | /* |
| 224 | * The non-transitional device type. Optional. |
| 225 | * |
| 226 | * Implements INTERFACE_CONVENTIONAL_PCI_DEVICE only. |
| 227 | */ |
| 228 | const char *non_transitional_name; |
| 229 | |
| 230 | /* Parent type. If NULL, TYPE_VIRTIO_PCI is used */ |
| 231 | const char *parent; |
| 232 | |
| 233 | /* Same as TypeInfo fields: */ |
| 234 | size_t instance_size; |
| 235 | size_t class_size; |
| 236 | void (*instance_init)(Object *obj); |
| 237 | void (*instance_finalize)(Object *obj); |
| 238 | void (*class_init)(ObjectClass *klass, const void *data); |
| 239 | const InterfaceInfo *interfaces; |
| 240 | } VirtioPCIDeviceTypeInfo; |
| 241 | |
| 242 | /* Register virtio-pci type(s). @t must be static. */ |
| 243 | void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t); |
| 244 | |
| 245 | /** |
| 246 | * virtio_pci_optimal_num_queues: |
| 247 | * @fixed_queues: number of queues that are always present |
| 248 | * |
| 249 | * Returns: The optimal number of queues for a multi-queue device, excluding |
| 250 | * @fixed_queues. |
| 251 | */ |
| 252 | unsigned virtio_pci_optimal_num_queues(unsigned fixed_queues); |
| 253 | |
| 254 | int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy, uint8_t bar, uint64_t offset, |
| 255 | uint64_t length, uint8_t id); |
| 256 | |
| 257 | #endif |