Statistics
| Branch: | Revision:

root / hw / virtio-pci.c @ 983fe826

History | View | Annotate | Download (22.2 kB)

1 53c25cea Paul Brook
/*
2 53c25cea Paul Brook
 * Virtio PCI Bindings
3 53c25cea Paul Brook
 *
4 53c25cea Paul Brook
 * Copyright IBM, Corp. 2007
5 53c25cea Paul Brook
 * Copyright (c) 2009 CodeSourcery
6 53c25cea Paul Brook
 *
7 53c25cea Paul Brook
 * Authors:
8 53c25cea Paul Brook
 *  Anthony Liguori   <aliguori@us.ibm.com>
9 53c25cea Paul Brook
 *  Paul Brook        <paul@codesourcery.com>
10 53c25cea Paul Brook
 *
11 53c25cea Paul Brook
 * This work is licensed under the terms of the GNU GPL, version 2.  See
12 53c25cea Paul Brook
 * the COPYING file in the top-level directory.
13 53c25cea Paul Brook
 *
14 53c25cea Paul Brook
 */
15 53c25cea Paul Brook
16 53c25cea Paul Brook
#include <inttypes.h>
17 53c25cea Paul Brook
18 53c25cea Paul Brook
#include "virtio.h"
19 8172539d Michael S. Tsirkin
#include "virtio-blk.h"
20 8172539d Michael S. Tsirkin
#include "virtio-net.h"
21 53c25cea Paul Brook
#include "pci.h"
22 2f792016 Markus Armbruster
#include "qemu-error.h"
23 aba800a3 Michael S. Tsirkin
#include "msix.h"
24 a1e0fea5 Gerd Hoffmann
#include "net.h"
25 428c149b Christoph Hellwig
#include "block_int.h"
26 97b15621 Gerd Hoffmann
#include "loader.h"
27 ade80dc8 Michael S. Tsirkin
#include "kvm.h"
28 53c25cea Paul Brook
29 53c25cea Paul Brook
/* from Linux's linux/virtio_pci.h */
30 53c25cea Paul Brook
31 53c25cea Paul Brook
/* A 32-bit r/o bitmask of the features supported by the host */
32 53c25cea Paul Brook
#define VIRTIO_PCI_HOST_FEATURES        0
33 53c25cea Paul Brook
34 53c25cea Paul Brook
/* A 32-bit r/w bitmask of features activated by the guest */
35 53c25cea Paul Brook
#define VIRTIO_PCI_GUEST_FEATURES       4
36 53c25cea Paul Brook
37 53c25cea Paul Brook
/* A 32-bit r/w PFN for the currently selected queue */
38 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_PFN            8
39 53c25cea Paul Brook
40 53c25cea Paul Brook
/* A 16-bit r/o queue size for the currently selected queue */
41 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_NUM            12
42 53c25cea Paul Brook
43 53c25cea Paul Brook
/* A 16-bit r/w queue selector */
44 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_SEL            14
45 53c25cea Paul Brook
46 53c25cea Paul Brook
/* A 16-bit r/w queue notifier */
47 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_NOTIFY         16
48 53c25cea Paul Brook
49 53c25cea Paul Brook
/* An 8-bit device status register.  */
50 53c25cea Paul Brook
#define VIRTIO_PCI_STATUS               18
51 53c25cea Paul Brook
52 53c25cea Paul Brook
/* An 8-bit r/o interrupt status register.  Reading the value will return the
53 53c25cea Paul Brook
 * current contents of the ISR and will also clear it.  This is effectively
54 53c25cea Paul Brook
 * a read-and-acknowledge. */
55 53c25cea Paul Brook
#define VIRTIO_PCI_ISR                  19
56 53c25cea Paul Brook
57 aba800a3 Michael S. Tsirkin
/* MSI-X registers: only enabled if MSI-X is enabled. */
58 aba800a3 Michael S. Tsirkin
/* A 16-bit vector for configuration changes. */
59 aba800a3 Michael S. Tsirkin
#define VIRTIO_MSI_CONFIG_VECTOR        20
60 aba800a3 Michael S. Tsirkin
/* A 16-bit vector for selected queue notifications. */
61 aba800a3 Michael S. Tsirkin
#define VIRTIO_MSI_QUEUE_VECTOR         22
62 aba800a3 Michael S. Tsirkin
63 aba800a3 Michael S. Tsirkin
/* Config space size */
64 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_CONFIG_NOMSI         20
65 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_CONFIG_MSI           24
66 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_REGION_SIZE(dev)     (msix_present(dev) ? \
67 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_MSI : \
68 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_NOMSI)
69 aba800a3 Michael S. Tsirkin
70 aba800a3 Michael S. Tsirkin
/* The remaining space is defined by each driver as the per-driver
71 aba800a3 Michael S. Tsirkin
 * configuration space */
72 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_CONFIG(dev)          (msix_enabled(dev) ? \
73 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_MSI : \
74 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_NOMSI)
75 53c25cea Paul Brook
76 53c25cea Paul Brook
/* Virtio ABI version, if we increment this, we break the guest driver. */
77 53c25cea Paul Brook
#define VIRTIO_PCI_ABI_VERSION          0
78 53c25cea Paul Brook
79 53c25cea Paul Brook
/* How many bits to shift physical queue address written to QUEUE_PFN.
80 53c25cea Paul Brook
 * 12 is historical, and due to x86 page size. */
81 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_ADDR_SHIFT    12
82 53c25cea Paul Brook
83 c81131db Alexander Graf
/* We can catch some guest bugs inside here so we continue supporting older
84 c81131db Alexander Graf
   guests. */
85 c81131db Alexander Graf
#define VIRTIO_PCI_BUG_BUS_MASTER        (1 << 0)
86 c81131db Alexander Graf
87 53c25cea Paul Brook
/* QEMU doesn't strictly need write barriers since everything runs in
88 53c25cea Paul Brook
 * lock-step.  We'll leave the calls to wmb() in though to make it obvious for
89 53c25cea Paul Brook
 * KVM or if kqemu gets SMP support.
90 53c25cea Paul Brook
 */
91 53c25cea Paul Brook
#define wmb() do { } while (0)
92 53c25cea Paul Brook
93 53c25cea Paul Brook
/* PCI bindings.  */
94 53c25cea Paul Brook
95 53c25cea Paul Brook
typedef struct {
96 53c25cea Paul Brook
    PCIDevice pci_dev;
97 53c25cea Paul Brook
    VirtIODevice *vdev;
98 c81131db Alexander Graf
    uint32_t bugs;
99 53c25cea Paul Brook
    uint32_t addr;
100 ab73ff29 Gerd Hoffmann
    uint32_t class_code;
101 a1e0fea5 Gerd Hoffmann
    uint32_t nvectors;
102 428c149b Christoph Hellwig
    BlockConf block;
103 97b15621 Gerd Hoffmann
    NICConf nic;
104 8172539d Michael S. Tsirkin
    uint32_t host_features;
105 98b19252 Amit Shah
    /* Max. number of ports we can have for a the virtio-serial device */
106 98b19252 Amit Shah
    uint32_t max_virtserial_ports;
107 53c25cea Paul Brook
} VirtIOPCIProxy;
108 53c25cea Paul Brook
109 53c25cea Paul Brook
/* virtio device */
110 53c25cea Paul Brook
111 7055e687 Michael S. Tsirkin
static void virtio_pci_notify(void *opaque, uint16_t vector)
112 53c25cea Paul Brook
{
113 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
114 aba800a3 Michael S. Tsirkin
    if (msix_enabled(&proxy->pci_dev))
115 aba800a3 Michael S. Tsirkin
        msix_notify(&proxy->pci_dev, vector);
116 aba800a3 Michael S. Tsirkin
    else
117 aba800a3 Michael S. Tsirkin
        qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
118 53c25cea Paul Brook
}
119 53c25cea Paul Brook
120 ff24bd58 Michael S. Tsirkin
static void virtio_pci_save_config(void * opaque, QEMUFile *f)
121 ff24bd58 Michael S. Tsirkin
{
122 ff24bd58 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
123 ff24bd58 Michael S. Tsirkin
    pci_device_save(&proxy->pci_dev, f);
124 ff24bd58 Michael S. Tsirkin
    msix_save(&proxy->pci_dev, f);
125 ff24bd58 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev))
126 ff24bd58 Michael S. Tsirkin
        qemu_put_be16(f, proxy->vdev->config_vector);
127 ff24bd58 Michael S. Tsirkin
}
128 ff24bd58 Michael S. Tsirkin
129 ff24bd58 Michael S. Tsirkin
static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f)
130 ff24bd58 Michael S. Tsirkin
{
131 ff24bd58 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
132 ff24bd58 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev))
133 ff24bd58 Michael S. Tsirkin
        qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n));
134 ff24bd58 Michael S. Tsirkin
}
135 ff24bd58 Michael S. Tsirkin
136 ff24bd58 Michael S. Tsirkin
static int virtio_pci_load_config(void * opaque, QEMUFile *f)
137 ff24bd58 Michael S. Tsirkin
{
138 ff24bd58 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
139 ff24bd58 Michael S. Tsirkin
    int ret;
140 ff24bd58 Michael S. Tsirkin
    ret = pci_device_load(&proxy->pci_dev, f);
141 e6da7680 Michael S. Tsirkin
    if (ret) {
142 ff24bd58 Michael S. Tsirkin
        return ret;
143 e6da7680 Michael S. Tsirkin
    }
144 ff24bd58 Michael S. Tsirkin
    msix_load(&proxy->pci_dev, f);
145 e6da7680 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev)) {
146 ff24bd58 Michael S. Tsirkin
        qemu_get_be16s(f, &proxy->vdev->config_vector);
147 e6da7680 Michael S. Tsirkin
    } else {
148 e6da7680 Michael S. Tsirkin
        proxy->vdev->config_vector = VIRTIO_NO_VECTOR;
149 e6da7680 Michael S. Tsirkin
    }
150 e6da7680 Michael S. Tsirkin
    if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
151 e6da7680 Michael S. Tsirkin
        return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
152 e6da7680 Michael S. Tsirkin
    }
153 c81131db Alexander Graf
154 c81131db Alexander Graf
    /* Try to find out if the guest has bus master disabled, but is
155 c81131db Alexander Graf
       in ready state. Then we have a buggy guest OS. */
156 c81131db Alexander Graf
    if (!(proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
157 c81131db Alexander Graf
        !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
158 c81131db Alexander Graf
        proxy->bugs |= VIRTIO_PCI_BUG_BUS_MASTER;
159 c81131db Alexander Graf
    }
160 ff24bd58 Michael S. Tsirkin
    return 0;
161 ff24bd58 Michael S. Tsirkin
}
162 ff24bd58 Michael S. Tsirkin
163 ff24bd58 Michael S. Tsirkin
static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f)
164 ff24bd58 Michael S. Tsirkin
{
165 ff24bd58 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
166 ff24bd58 Michael S. Tsirkin
    uint16_t vector;
167 e6da7680 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev)) {
168 e6da7680 Michael S. Tsirkin
        qemu_get_be16s(f, &vector);
169 e6da7680 Michael S. Tsirkin
    } else {
170 e6da7680 Michael S. Tsirkin
        vector = VIRTIO_NO_VECTOR;
171 e6da7680 Michael S. Tsirkin
    }
172 ff24bd58 Michael S. Tsirkin
    virtio_queue_set_vector(proxy->vdev, n, vector);
173 e6da7680 Michael S. Tsirkin
    if (vector != VIRTIO_NO_VECTOR) {
174 e6da7680 Michael S. Tsirkin
        return msix_vector_use(&proxy->pci_dev, vector);
175 e6da7680 Michael S. Tsirkin
    }
176 ff24bd58 Michael S. Tsirkin
    return 0;
177 ff24bd58 Michael S. Tsirkin
}
178 ff24bd58 Michael S. Tsirkin
179 e489030d Michael S. Tsirkin
static void virtio_pci_reset(DeviceState *d)
180 7055e687 Michael S. Tsirkin
{
181 e489030d Michael S. Tsirkin
    VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
182 7055e687 Michael S. Tsirkin
    virtio_reset(proxy->vdev);
183 aba800a3 Michael S. Tsirkin
    msix_reset(&proxy->pci_dev);
184 c81131db Alexander Graf
    proxy->bugs = 0;
185 7055e687 Michael S. Tsirkin
}
186 7055e687 Michael S. Tsirkin
187 53c25cea Paul Brook
static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
188 53c25cea Paul Brook
{
189 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
190 53c25cea Paul Brook
    VirtIODevice *vdev = proxy->vdev;
191 c227f099 Anthony Liguori
    target_phys_addr_t pa;
192 53c25cea Paul Brook
193 53c25cea Paul Brook
    switch (addr) {
194 53c25cea Paul Brook
    case VIRTIO_PCI_GUEST_FEATURES:
195 53c25cea Paul Brook
        /* Guest does not negotiate properly?  We have to assume nothing. */
196 53c25cea Paul Brook
        if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
197 53c25cea Paul Brook
            if (vdev->bad_features)
198 8172539d Michael S. Tsirkin
                val = proxy->host_features & vdev->bad_features(vdev);
199 53c25cea Paul Brook
            else
200 53c25cea Paul Brook
                val = 0;
201 53c25cea Paul Brook
        }
202 53c25cea Paul Brook
        if (vdev->set_features)
203 53c25cea Paul Brook
            vdev->set_features(vdev, val);
204 704a76fc Michael S. Tsirkin
        vdev->guest_features = val;
205 53c25cea Paul Brook
        break;
206 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_PFN:
207 c227f099 Anthony Liguori
        pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
208 1b8e9b27 Michael S. Tsirkin
        if (pa == 0) {
209 1b8e9b27 Michael S. Tsirkin
            virtio_reset(proxy->vdev);
210 1b8e9b27 Michael S. Tsirkin
            msix_unuse_all_vectors(&proxy->pci_dev);
211 1b8e9b27 Michael S. Tsirkin
        }
212 7055e687 Michael S. Tsirkin
        else
213 7055e687 Michael S. Tsirkin
            virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
214 53c25cea Paul Brook
        break;
215 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_SEL:
216 53c25cea Paul Brook
        if (val < VIRTIO_PCI_QUEUE_MAX)
217 53c25cea Paul Brook
            vdev->queue_sel = val;
218 53c25cea Paul Brook
        break;
219 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_NOTIFY:
220 53c25cea Paul Brook
        virtio_queue_notify(vdev, val);
221 53c25cea Paul Brook
        break;
222 53c25cea Paul Brook
    case VIRTIO_PCI_STATUS:
223 3e607cb5 Michael S. Tsirkin
        virtio_set_status(vdev, val & 0xFF);
224 1b8e9b27 Michael S. Tsirkin
        if (vdev->status == 0) {
225 1b8e9b27 Michael S. Tsirkin
            virtio_reset(proxy->vdev);
226 1b8e9b27 Michael S. Tsirkin
            msix_unuse_all_vectors(&proxy->pci_dev);
227 1b8e9b27 Michael S. Tsirkin
        }
228 c81131db Alexander Graf
229 c81131db Alexander Graf
        /* Linux before 2.6.34 sets the device as OK without enabling
230 c81131db Alexander Graf
           the PCI device bus master bit. In this case we need to disable
231 c81131db Alexander Graf
           some safety checks. */
232 c81131db Alexander Graf
        if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&
233 c81131db Alexander Graf
            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
234 c81131db Alexander Graf
            proxy->bugs |= VIRTIO_PCI_BUG_BUS_MASTER;
235 c81131db Alexander Graf
        }
236 53c25cea Paul Brook
        break;
237 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_CONFIG_VECTOR:
238 aba800a3 Michael S. Tsirkin
        msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
239 aba800a3 Michael S. Tsirkin
        /* Make it possible for guest to discover an error took place. */
240 aba800a3 Michael S. Tsirkin
        if (msix_vector_use(&proxy->pci_dev, val) < 0)
241 aba800a3 Michael S. Tsirkin
            val = VIRTIO_NO_VECTOR;
242 aba800a3 Michael S. Tsirkin
        vdev->config_vector = val;
243 aba800a3 Michael S. Tsirkin
        break;
244 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_QUEUE_VECTOR:
245 aba800a3 Michael S. Tsirkin
        msix_vector_unuse(&proxy->pci_dev,
246 aba800a3 Michael S. Tsirkin
                          virtio_queue_vector(vdev, vdev->queue_sel));
247 aba800a3 Michael S. Tsirkin
        /* Make it possible for guest to discover an error took place. */
248 aba800a3 Michael S. Tsirkin
        if (msix_vector_use(&proxy->pci_dev, val) < 0)
249 aba800a3 Michael S. Tsirkin
            val = VIRTIO_NO_VECTOR;
250 aba800a3 Michael S. Tsirkin
        virtio_queue_set_vector(vdev, vdev->queue_sel, val);
251 aba800a3 Michael S. Tsirkin
        break;
252 aba800a3 Michael S. Tsirkin
    default:
253 aba800a3 Michael S. Tsirkin
        fprintf(stderr, "%s: unexpected address 0x%x value 0x%x\n",
254 aba800a3 Michael S. Tsirkin
                __func__, addr, val);
255 aba800a3 Michael S. Tsirkin
        break;
256 53c25cea Paul Brook
    }
257 53c25cea Paul Brook
}
258 53c25cea Paul Brook
259 aba800a3 Michael S. Tsirkin
static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
260 53c25cea Paul Brook
{
261 53c25cea Paul Brook
    VirtIODevice *vdev = proxy->vdev;
262 53c25cea Paul Brook
    uint32_t ret = 0xFFFFFFFF;
263 53c25cea Paul Brook
264 53c25cea Paul Brook
    switch (addr) {
265 53c25cea Paul Brook
    case VIRTIO_PCI_HOST_FEATURES:
266 8172539d Michael S. Tsirkin
        ret = proxy->host_features;
267 53c25cea Paul Brook
        break;
268 53c25cea Paul Brook
    case VIRTIO_PCI_GUEST_FEATURES:
269 704a76fc Michael S. Tsirkin
        ret = vdev->guest_features;
270 53c25cea Paul Brook
        break;
271 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_PFN:
272 53c25cea Paul Brook
        ret = virtio_queue_get_addr(vdev, vdev->queue_sel)
273 53c25cea Paul Brook
              >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
274 53c25cea Paul Brook
        break;
275 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_NUM:
276 53c25cea Paul Brook
        ret = virtio_queue_get_num(vdev, vdev->queue_sel);
277 53c25cea Paul Brook
        break;
278 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_SEL:
279 53c25cea Paul Brook
        ret = vdev->queue_sel;
280 53c25cea Paul Brook
        break;
281 53c25cea Paul Brook
    case VIRTIO_PCI_STATUS:
282 53c25cea Paul Brook
        ret = vdev->status;
283 53c25cea Paul Brook
        break;
284 53c25cea Paul Brook
    case VIRTIO_PCI_ISR:
285 53c25cea Paul Brook
        /* reading from the ISR also clears it. */
286 53c25cea Paul Brook
        ret = vdev->isr;
287 53c25cea Paul Brook
        vdev->isr = 0;
288 7055e687 Michael S. Tsirkin
        qemu_set_irq(proxy->pci_dev.irq[0], 0);
289 53c25cea Paul Brook
        break;
290 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_CONFIG_VECTOR:
291 aba800a3 Michael S. Tsirkin
        ret = vdev->config_vector;
292 aba800a3 Michael S. Tsirkin
        break;
293 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_QUEUE_VECTOR:
294 aba800a3 Michael S. Tsirkin
        ret = virtio_queue_vector(vdev, vdev->queue_sel);
295 aba800a3 Michael S. Tsirkin
        break;
296 53c25cea Paul Brook
    default:
297 53c25cea Paul Brook
        break;
298 53c25cea Paul Brook
    }
299 53c25cea Paul Brook
300 53c25cea Paul Brook
    return ret;
301 53c25cea Paul Brook
}
302 53c25cea Paul Brook
303 53c25cea Paul Brook
static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr)
304 53c25cea Paul Brook
{
305 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
306 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
307 aba800a3 Michael S. Tsirkin
    addr -= proxy->addr;
308 aba800a3 Michael S. Tsirkin
    if (addr < config)
309 aba800a3 Michael S. Tsirkin
        return virtio_ioport_read(proxy, addr);
310 aba800a3 Michael S. Tsirkin
    addr -= config;
311 53c25cea Paul Brook
    return virtio_config_readb(proxy->vdev, addr);
312 53c25cea Paul Brook
}
313 53c25cea Paul Brook
314 53c25cea Paul Brook
static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr)
315 53c25cea Paul Brook
{
316 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
317 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
318 aba800a3 Michael S. Tsirkin
    addr -= proxy->addr;
319 aba800a3 Michael S. Tsirkin
    if (addr < config)
320 aba800a3 Michael S. Tsirkin
        return virtio_ioport_read(proxy, addr);
321 aba800a3 Michael S. Tsirkin
    addr -= config;
322 53c25cea Paul Brook
    return virtio_config_readw(proxy->vdev, addr);
323 53c25cea Paul Brook
}
324 53c25cea Paul Brook
325 53c25cea Paul Brook
static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr)
326 53c25cea Paul Brook
{
327 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
328 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
329 aba800a3 Michael S. Tsirkin
    addr -= proxy->addr;
330 aba800a3 Michael S. Tsirkin
    if (addr < config)
331 aba800a3 Michael S. Tsirkin
        return virtio_ioport_read(proxy, addr);
332 aba800a3 Michael S. Tsirkin
    addr -= config;
333 53c25cea Paul Brook
    return virtio_config_readl(proxy->vdev, addr);
334 53c25cea Paul Brook
}
335 53c25cea Paul Brook
336 53c25cea Paul Brook
static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val)
337 53c25cea Paul Brook
{
338 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
339 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
340 aba800a3 Michael S. Tsirkin
    addr -= proxy->addr;
341 aba800a3 Michael S. Tsirkin
    if (addr < config) {
342 aba800a3 Michael S. Tsirkin
        virtio_ioport_write(proxy, addr, val);
343 aba800a3 Michael S. Tsirkin
        return;
344 aba800a3 Michael S. Tsirkin
    }
345 aba800a3 Michael S. Tsirkin
    addr -= config;
346 53c25cea Paul Brook
    virtio_config_writeb(proxy->vdev, addr, val);
347 53c25cea Paul Brook
}
348 53c25cea Paul Brook
349 53c25cea Paul Brook
static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val)
350 53c25cea Paul Brook
{
351 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
352 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
353 aba800a3 Michael S. Tsirkin
    addr -= proxy->addr;
354 aba800a3 Michael S. Tsirkin
    if (addr < config) {
355 aba800a3 Michael S. Tsirkin
        virtio_ioport_write(proxy, addr, val);
356 aba800a3 Michael S. Tsirkin
        return;
357 aba800a3 Michael S. Tsirkin
    }
358 aba800a3 Michael S. Tsirkin
    addr -= config;
359 53c25cea Paul Brook
    virtio_config_writew(proxy->vdev, addr, val);
360 53c25cea Paul Brook
}
361 53c25cea Paul Brook
362 53c25cea Paul Brook
static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
363 53c25cea Paul Brook
{
364 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
365 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
366 aba800a3 Michael S. Tsirkin
    addr -= proxy->addr;
367 aba800a3 Michael S. Tsirkin
    if (addr < config) {
368 aba800a3 Michael S. Tsirkin
        virtio_ioport_write(proxy, addr, val);
369 aba800a3 Michael S. Tsirkin
        return;
370 aba800a3 Michael S. Tsirkin
    }
371 aba800a3 Michael S. Tsirkin
    addr -= config;
372 53c25cea Paul Brook
    virtio_config_writel(proxy->vdev, addr, val);
373 53c25cea Paul Brook
}
374 53c25cea Paul Brook
375 53c25cea Paul Brook
static void virtio_map(PCIDevice *pci_dev, int region_num,
376 6e355d90 Isaku Yamahata
                       pcibus_t addr, pcibus_t size, int type)
377 53c25cea Paul Brook
{
378 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = container_of(pci_dev, VirtIOPCIProxy, pci_dev);
379 53c25cea Paul Brook
    VirtIODevice *vdev = proxy->vdev;
380 aba800a3 Michael S. Tsirkin
    unsigned config_len = VIRTIO_PCI_REGION_SIZE(pci_dev) + vdev->config_len;
381 53c25cea Paul Brook
382 53c25cea Paul Brook
    proxy->addr = addr;
383 53c25cea Paul Brook
384 aba800a3 Michael S. Tsirkin
    register_ioport_write(addr, config_len, 1, virtio_pci_config_writeb, proxy);
385 aba800a3 Michael S. Tsirkin
    register_ioport_write(addr, config_len, 2, virtio_pci_config_writew, proxy);
386 aba800a3 Michael S. Tsirkin
    register_ioport_write(addr, config_len, 4, virtio_pci_config_writel, proxy);
387 aba800a3 Michael S. Tsirkin
    register_ioport_read(addr, config_len, 1, virtio_pci_config_readb, proxy);
388 aba800a3 Michael S. Tsirkin
    register_ioport_read(addr, config_len, 2, virtio_pci_config_readw, proxy);
389 aba800a3 Michael S. Tsirkin
    register_ioport_read(addr, config_len, 4, virtio_pci_config_readl, proxy);
390 53c25cea Paul Brook
391 aba800a3 Michael S. Tsirkin
    if (vdev->config_len)
392 53c25cea Paul Brook
        vdev->get_config(vdev, vdev->config);
393 aba800a3 Michael S. Tsirkin
}
394 aba800a3 Michael S. Tsirkin
395 aba800a3 Michael S. Tsirkin
static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
396 aba800a3 Michael S. Tsirkin
                                uint32_t val, int len)
397 aba800a3 Michael S. Tsirkin
{
398 ed757e14 Yan Vugenfirer
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
399 ed757e14 Yan Vugenfirer
400 ed757e14 Yan Vugenfirer
    if (PCI_COMMAND == address) {
401 ed757e14 Yan Vugenfirer
        if (!(val & PCI_COMMAND_MASTER)) {
402 c81131db Alexander Graf
            if (!(proxy->bugs & VIRTIO_PCI_BUG_BUS_MASTER)) {
403 3e607cb5 Michael S. Tsirkin
                virtio_set_status(proxy->vdev,
404 3e607cb5 Michael S. Tsirkin
                                  proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
405 c81131db Alexander Graf
            }
406 ed757e14 Yan Vugenfirer
        }
407 ed757e14 Yan Vugenfirer
    }
408 ed757e14 Yan Vugenfirer
409 aba800a3 Michael S. Tsirkin
    pci_default_write_config(pci_dev, address, val, len);
410 85352471 Michael S. Tsirkin
    msix_write_config(pci_dev, address, val, len);
411 53c25cea Paul Brook
}
412 53c25cea Paul Brook
413 6d74ca5a Michael S. Tsirkin
static unsigned virtio_pci_get_features(void *opaque)
414 6d74ca5a Michael S. Tsirkin
{
415 8172539d Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
416 8172539d Michael S. Tsirkin
    return proxy->host_features;
417 6d74ca5a Michael S. Tsirkin
}
418 6d74ca5a Michael S. Tsirkin
419 ade80dc8 Michael S. Tsirkin
static void virtio_pci_guest_notifier_read(void *opaque)
420 ade80dc8 Michael S. Tsirkin
{
421 ade80dc8 Michael S. Tsirkin
    VirtQueue *vq = opaque;
422 ade80dc8 Michael S. Tsirkin
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
423 ade80dc8 Michael S. Tsirkin
    if (event_notifier_test_and_clear(n)) {
424 ade80dc8 Michael S. Tsirkin
        virtio_irq(vq);
425 ade80dc8 Michael S. Tsirkin
    }
426 ade80dc8 Michael S. Tsirkin
}
427 ade80dc8 Michael S. Tsirkin
428 ade80dc8 Michael S. Tsirkin
static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
429 ade80dc8 Michael S. Tsirkin
{
430 ade80dc8 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
431 ade80dc8 Michael S. Tsirkin
    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
432 ade80dc8 Michael S. Tsirkin
    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
433 ade80dc8 Michael S. Tsirkin
434 ade80dc8 Michael S. Tsirkin
    if (assign) {
435 ade80dc8 Michael S. Tsirkin
        int r = event_notifier_init(notifier, 0);
436 ade80dc8 Michael S. Tsirkin
        if (r < 0) {
437 ade80dc8 Michael S. Tsirkin
            return r;
438 ade80dc8 Michael S. Tsirkin
        }
439 ade80dc8 Michael S. Tsirkin
        qemu_set_fd_handler(event_notifier_get_fd(notifier),
440 ade80dc8 Michael S. Tsirkin
                            virtio_pci_guest_notifier_read, NULL, vq);
441 ade80dc8 Michael S. Tsirkin
    } else {
442 ade80dc8 Michael S. Tsirkin
        qemu_set_fd_handler(event_notifier_get_fd(notifier),
443 ade80dc8 Michael S. Tsirkin
                            NULL, NULL, NULL);
444 ade80dc8 Michael S. Tsirkin
        event_notifier_cleanup(notifier);
445 ade80dc8 Michael S. Tsirkin
    }
446 ade80dc8 Michael S. Tsirkin
447 ade80dc8 Michael S. Tsirkin
    return 0;
448 ade80dc8 Michael S. Tsirkin
}
449 ade80dc8 Michael S. Tsirkin
450 ade80dc8 Michael S. Tsirkin
static int virtio_pci_set_host_notifier(void *opaque, int n, bool assign)
451 ade80dc8 Michael S. Tsirkin
{
452 ade80dc8 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
453 ade80dc8 Michael S. Tsirkin
    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
454 ade80dc8 Michael S. Tsirkin
    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
455 ade80dc8 Michael S. Tsirkin
    int r;
456 ade80dc8 Michael S. Tsirkin
    if (assign) {
457 ade80dc8 Michael S. Tsirkin
        r = event_notifier_init(notifier, 1);
458 ade80dc8 Michael S. Tsirkin
        if (r < 0) {
459 ade80dc8 Michael S. Tsirkin
            return r;
460 ade80dc8 Michael S. Tsirkin
        }
461 ade80dc8 Michael S. Tsirkin
        r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
462 ade80dc8 Michael S. Tsirkin
                                       proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
463 ade80dc8 Michael S. Tsirkin
                                       n, assign);
464 ade80dc8 Michael S. Tsirkin
        if (r < 0) {
465 ade80dc8 Michael S. Tsirkin
            event_notifier_cleanup(notifier);
466 ade80dc8 Michael S. Tsirkin
        }
467 ade80dc8 Michael S. Tsirkin
    } else {
468 ade80dc8 Michael S. Tsirkin
        r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
469 ade80dc8 Michael S. Tsirkin
                                       proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
470 ade80dc8 Michael S. Tsirkin
                                       n, assign);
471 ade80dc8 Michael S. Tsirkin
        if (r < 0) {
472 ade80dc8 Michael S. Tsirkin
            return r;
473 ade80dc8 Michael S. Tsirkin
        }
474 ade80dc8 Michael S. Tsirkin
        event_notifier_cleanup(notifier);
475 ade80dc8 Michael S. Tsirkin
    }
476 ade80dc8 Michael S. Tsirkin
    return r;
477 ade80dc8 Michael S. Tsirkin
}
478 ade80dc8 Michael S. Tsirkin
479 53c25cea Paul Brook
static const VirtIOBindings virtio_pci_bindings = {
480 ff24bd58 Michael S. Tsirkin
    .notify = virtio_pci_notify,
481 ff24bd58 Michael S. Tsirkin
    .save_config = virtio_pci_save_config,
482 ff24bd58 Michael S. Tsirkin
    .load_config = virtio_pci_load_config,
483 ff24bd58 Michael S. Tsirkin
    .save_queue = virtio_pci_save_queue,
484 ff24bd58 Michael S. Tsirkin
    .load_queue = virtio_pci_load_queue,
485 6d74ca5a Michael S. Tsirkin
    .get_features = virtio_pci_get_features,
486 ade80dc8 Michael S. Tsirkin
    .set_host_notifier = virtio_pci_set_host_notifier,
487 ade80dc8 Michael S. Tsirkin
    .set_guest_notifier = virtio_pci_set_guest_notifier,
488 53c25cea Paul Brook
};
489 53c25cea Paul Brook
490 53c25cea Paul Brook
static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
491 53c25cea Paul Brook
                            uint16_t vendor, uint16_t device,
492 53c25cea Paul Brook
                            uint16_t class_code, uint8_t pif)
493 53c25cea Paul Brook
{
494 53c25cea Paul Brook
    uint8_t *config;
495 53c25cea Paul Brook
    uint32_t size;
496 53c25cea Paul Brook
497 53c25cea Paul Brook
    proxy->vdev = vdev;
498 53c25cea Paul Brook
499 53c25cea Paul Brook
    config = proxy->pci_dev.config;
500 53c25cea Paul Brook
    pci_config_set_vendor_id(config, vendor);
501 53c25cea Paul Brook
    pci_config_set_device_id(config, device);
502 53c25cea Paul Brook
503 53c25cea Paul Brook
    config[0x08] = VIRTIO_PCI_ABI_VERSION;
504 53c25cea Paul Brook
505 53c25cea Paul Brook
    config[0x09] = pif;
506 53c25cea Paul Brook
    pci_config_set_class(config, class_code);
507 53c25cea Paul Brook
    config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL;
508 53c25cea Paul Brook
509 53c25cea Paul Brook
    config[0x2c] = vendor & 0xFF;
510 53c25cea Paul Brook
    config[0x2d] = (vendor >> 8) & 0xFF;
511 53c25cea Paul Brook
    config[0x2e] = vdev->device_id & 0xFF;
512 53c25cea Paul Brook
    config[0x2f] = (vdev->device_id >> 8) & 0xFF;
513 53c25cea Paul Brook
514 53c25cea Paul Brook
    config[0x3d] = 1;
515 53c25cea Paul Brook
516 5a1fc5e8 Michael S. Tsirkin
    if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, 1, 0)) {
517 aba800a3 Michael S. Tsirkin
        pci_register_bar(&proxy->pci_dev, 1,
518 aba800a3 Michael S. Tsirkin
                         msix_bar_size(&proxy->pci_dev),
519 0392a017 Isaku Yamahata
                         PCI_BASE_ADDRESS_SPACE_MEMORY,
520 aba800a3 Michael S. Tsirkin
                         msix_mmio_map);
521 aba800a3 Michael S. Tsirkin
    } else
522 aba800a3 Michael S. Tsirkin
        vdev->nvectors = 0;
523 aba800a3 Michael S. Tsirkin
524 ed757e14 Yan Vugenfirer
    proxy->pci_dev.config_write = virtio_write_config;
525 ed757e14 Yan Vugenfirer
526 aba800a3 Michael S. Tsirkin
    size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev) + vdev->config_len;
527 53c25cea Paul Brook
    if (size & (size-1))
528 53c25cea Paul Brook
        size = 1 << qemu_fls(size);
529 53c25cea Paul Brook
530 0392a017 Isaku Yamahata
    pci_register_bar(&proxy->pci_dev, 0, size, PCI_BASE_ADDRESS_SPACE_IO,
531 53c25cea Paul Brook
                           virtio_map);
532 53c25cea Paul Brook
533 53c25cea Paul Brook
    virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
534 8172539d Michael S. Tsirkin
    proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
535 8172539d Michael S. Tsirkin
    proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
536 8172539d Michael S. Tsirkin
    proxy->host_features = vdev->get_features(vdev, proxy->host_features);
537 53c25cea Paul Brook
}
538 53c25cea Paul Brook
539 81a322d4 Gerd Hoffmann
static int virtio_blk_init_pci(PCIDevice *pci_dev)
540 53c25cea Paul Brook
{
541 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
542 53c25cea Paul Brook
    VirtIODevice *vdev;
543 53c25cea Paul Brook
544 ab73ff29 Gerd Hoffmann
    if (proxy->class_code != PCI_CLASS_STORAGE_SCSI &&
545 ab73ff29 Gerd Hoffmann
        proxy->class_code != PCI_CLASS_STORAGE_OTHER)
546 ab73ff29 Gerd Hoffmann
        proxy->class_code = PCI_CLASS_STORAGE_SCSI;
547 53c25cea Paul Brook
548 428c149b Christoph Hellwig
    if (!proxy->block.dinfo) {
549 1ecda02b Markus Armbruster
        error_report("virtio-blk-pci: drive property not set");
550 81a322d4 Gerd Hoffmann
        return -1;
551 d176c495 Gerd Hoffmann
    }
552 428c149b Christoph Hellwig
    vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block);
553 177539e0 Gerd Hoffmann
    vdev->nvectors = proxy->nvectors;
554 53c25cea Paul Brook
    virtio_init_pci(proxy, vdev,
555 53c25cea Paul Brook
                    PCI_VENDOR_ID_REDHAT_QUMRANET,
556 85c2c735 Mark McLoughlin
                    PCI_DEVICE_ID_VIRTIO_BLOCK,
557 85c2c735 Mark McLoughlin
                    proxy->class_code, 0x00);
558 177539e0 Gerd Hoffmann
    /* make the actual value visible */
559 177539e0 Gerd Hoffmann
    proxy->nvectors = vdev->nvectors;
560 81a322d4 Gerd Hoffmann
    return 0;
561 21d58b57 Mark McLoughlin
}
562 21d58b57 Mark McLoughlin
563 0f457d91 Michael S. Tsirkin
static int virtio_exit_pci(PCIDevice *pci_dev)
564 0f457d91 Michael S. Tsirkin
{
565 0f457d91 Michael S. Tsirkin
    return msix_uninit(pci_dev);
566 0f457d91 Michael S. Tsirkin
}
567 0f457d91 Michael S. Tsirkin
568 56a14938 Gerd Hoffmann
static int virtio_blk_exit_pci(PCIDevice *pci_dev)
569 56a14938 Gerd Hoffmann
{
570 56a14938 Gerd Hoffmann
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
571 56a14938 Gerd Hoffmann
572 428c149b Christoph Hellwig
    drive_uninit(proxy->block.dinfo);
573 0f457d91 Michael S. Tsirkin
    return virtio_exit_pci(pci_dev);
574 56a14938 Gerd Hoffmann
}
575 56a14938 Gerd Hoffmann
576 98b19252 Amit Shah
static int virtio_serial_init_pci(PCIDevice *pci_dev)
577 21d58b57 Mark McLoughlin
{
578 d6beee99 Gerd Hoffmann
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
579 85c2c735 Mark McLoughlin
    VirtIODevice *vdev;
580 85c2c735 Mark McLoughlin
581 d6beee99 Gerd Hoffmann
    if (proxy->class_code != PCI_CLASS_COMMUNICATION_OTHER &&
582 d6beee99 Gerd Hoffmann
        proxy->class_code != PCI_CLASS_DISPLAY_OTHER && /* qemu 0.10 */
583 d6beee99 Gerd Hoffmann
        proxy->class_code != PCI_CLASS_OTHERS)          /* qemu-kvm  */
584 d6beee99 Gerd Hoffmann
        proxy->class_code = PCI_CLASS_COMMUNICATION_OTHER;
585 d6beee99 Gerd Hoffmann
586 98b19252 Amit Shah
    vdev = virtio_serial_init(&pci_dev->qdev, proxy->max_virtserial_ports);
587 25fe3654 Amit Shah
    if (!vdev) {
588 25fe3654 Amit Shah
        return -1;
589 25fe3654 Amit Shah
    }
590 573fb60c Amit Shah
    vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
591 573fb60c Amit Shah
                                        ? proxy->max_virtserial_ports + 1
592 573fb60c Amit Shah
                                        : proxy->nvectors;
593 85c2c735 Mark McLoughlin
    virtio_init_pci(proxy, vdev,
594 85c2c735 Mark McLoughlin
                    PCI_VENDOR_ID_REDHAT_QUMRANET,
595 85c2c735 Mark McLoughlin
                    PCI_DEVICE_ID_VIRTIO_CONSOLE,
596 85c2c735 Mark McLoughlin
                    proxy->class_code, 0x00);
597 a1829205 Amit Shah
    proxy->nvectors = vdev->nvectors;
598 81a322d4 Gerd Hoffmann
    return 0;
599 53c25cea Paul Brook
}
600 53c25cea Paul Brook
601 81a322d4 Gerd Hoffmann
static int virtio_net_init_pci(PCIDevice *pci_dev)
602 53c25cea Paul Brook
{
603 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
604 53c25cea Paul Brook
    VirtIODevice *vdev;
605 53c25cea Paul Brook
606 97b15621 Gerd Hoffmann
    vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic);
607 a1e0fea5 Gerd Hoffmann
608 97b15621 Gerd Hoffmann
    vdev->nvectors = proxy->nvectors;
609 53c25cea Paul Brook
    virtio_init_pci(proxy, vdev,
610 53c25cea Paul Brook
                    PCI_VENDOR_ID_REDHAT_QUMRANET,
611 53c25cea Paul Brook
                    PCI_DEVICE_ID_VIRTIO_NET,
612 53c25cea Paul Brook
                    PCI_CLASS_NETWORK_ETHERNET,
613 53c25cea Paul Brook
                    0x00);
614 a1e0fea5 Gerd Hoffmann
615 a1e0fea5 Gerd Hoffmann
    /* make the actual value visible */
616 a1e0fea5 Gerd Hoffmann
    proxy->nvectors = vdev->nvectors;
617 81a322d4 Gerd Hoffmann
    return 0;
618 53c25cea Paul Brook
}
619 53c25cea Paul Brook
620 97b15621 Gerd Hoffmann
static int virtio_net_exit_pci(PCIDevice *pci_dev)
621 97b15621 Gerd Hoffmann
{
622 97b15621 Gerd Hoffmann
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
623 97b15621 Gerd Hoffmann
624 97b15621 Gerd Hoffmann
    virtio_net_exit(proxy->vdev);
625 97b15621 Gerd Hoffmann
    return virtio_exit_pci(pci_dev);
626 97b15621 Gerd Hoffmann
}
627 97b15621 Gerd Hoffmann
628 81a322d4 Gerd Hoffmann
static int virtio_balloon_init_pci(PCIDevice *pci_dev)
629 53c25cea Paul Brook
{
630 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
631 53c25cea Paul Brook
    VirtIODevice *vdev;
632 53c25cea Paul Brook
633 53c25cea Paul Brook
    vdev = virtio_balloon_init(&pci_dev->qdev);
634 53c25cea Paul Brook
    virtio_init_pci(proxy, vdev,
635 53c25cea Paul Brook
                    PCI_VENDOR_ID_REDHAT_QUMRANET,
636 53c25cea Paul Brook
                    PCI_DEVICE_ID_VIRTIO_BALLOON,
637 53c25cea Paul Brook
                    PCI_CLASS_MEMORY_RAM,
638 53c25cea Paul Brook
                    0x00);
639 81a322d4 Gerd Hoffmann
    return 0;
640 53c25cea Paul Brook
}
641 53c25cea Paul Brook
642 0aab0d3a Gerd Hoffmann
static PCIDeviceInfo virtio_info[] = {
643 0aab0d3a Gerd Hoffmann
    {
644 0aab0d3a Gerd Hoffmann
        .qdev.name = "virtio-blk-pci",
645 0aab0d3a Gerd Hoffmann
        .qdev.size = sizeof(VirtIOPCIProxy),
646 0aab0d3a Gerd Hoffmann
        .init      = virtio_blk_init_pci,
647 56a14938 Gerd Hoffmann
        .exit      = virtio_blk_exit_pci,
648 ab73ff29 Gerd Hoffmann
        .qdev.props = (Property[]) {
649 72c61d0b Gerd Hoffmann
            DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
650 428c149b Christoph Hellwig
            DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
651 177539e0 Gerd Hoffmann
            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
652 8172539d Michael S. Tsirkin
            DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
653 72c61d0b Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
654 ab73ff29 Gerd Hoffmann
        },
655 e489030d Michael S. Tsirkin
        .qdev.reset = virtio_pci_reset,
656 0aab0d3a Gerd Hoffmann
    },{
657 a1e0fea5 Gerd Hoffmann
        .qdev.name  = "virtio-net-pci",
658 a1e0fea5 Gerd Hoffmann
        .qdev.size  = sizeof(VirtIOPCIProxy),
659 a1e0fea5 Gerd Hoffmann
        .init       = virtio_net_init_pci,
660 97b15621 Gerd Hoffmann
        .exit       = virtio_net_exit_pci,
661 8c52c8f3 Gerd Hoffmann
        .romfile    = "pxe-virtio.bin",
662 a1e0fea5 Gerd Hoffmann
        .qdev.props = (Property[]) {
663 97b15621 Gerd Hoffmann
            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
664 8172539d Michael S. Tsirkin
            DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
665 97b15621 Gerd Hoffmann
            DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
666 72c61d0b Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
667 a1e0fea5 Gerd Hoffmann
        },
668 e489030d Michael S. Tsirkin
        .qdev.reset = virtio_pci_reset,
669 0aab0d3a Gerd Hoffmann
    },{
670 98b19252 Amit Shah
        .qdev.name = "virtio-serial-pci",
671 98b19252 Amit Shah
        .qdev.alias = "virtio-serial",
672 0aab0d3a Gerd Hoffmann
        .qdev.size = sizeof(VirtIOPCIProxy),
673 98b19252 Amit Shah
        .init      = virtio_serial_init_pci,
674 0f457d91 Michael S. Tsirkin
        .exit      = virtio_exit_pci,
675 d6beee99 Gerd Hoffmann
        .qdev.props = (Property[]) {
676 573fb60c Amit Shah
            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
677 573fb60c Amit Shah
                               DEV_NVECTORS_UNSPECIFIED),
678 72c61d0b Gerd Hoffmann
            DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
679 8172539d Michael S. Tsirkin
            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
680 98b19252 Amit Shah
            DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, max_virtserial_ports,
681 98b19252 Amit Shah
                               31),
682 72c61d0b Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
683 d6beee99 Gerd Hoffmann
        },
684 e489030d Michael S. Tsirkin
        .qdev.reset = virtio_pci_reset,
685 0aab0d3a Gerd Hoffmann
    },{
686 0aab0d3a Gerd Hoffmann
        .qdev.name = "virtio-balloon-pci",
687 0aab0d3a Gerd Hoffmann
        .qdev.size = sizeof(VirtIOPCIProxy),
688 0aab0d3a Gerd Hoffmann
        .init      = virtio_balloon_init_pci,
689 0f457d91 Michael S. Tsirkin
        .exit      = virtio_exit_pci,
690 8172539d Michael S. Tsirkin
        .qdev.props = (Property[]) {
691 8172539d Michael S. Tsirkin
            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
692 8172539d Michael S. Tsirkin
            DEFINE_PROP_END_OF_LIST(),
693 8172539d Michael S. Tsirkin
        },
694 e489030d Michael S. Tsirkin
        .qdev.reset = virtio_pci_reset,
695 0aab0d3a Gerd Hoffmann
    },{
696 0aab0d3a Gerd Hoffmann
        /* end of list */
697 0aab0d3a Gerd Hoffmann
    }
698 0aab0d3a Gerd Hoffmann
};
699 0aab0d3a Gerd Hoffmann
700 53c25cea Paul Brook
static void virtio_pci_register_devices(void)
701 53c25cea Paul Brook
{
702 0aab0d3a Gerd Hoffmann
    pci_qdev_register_many(virtio_info);
703 53c25cea Paul Brook
}
704 53c25cea Paul Brook
705 53c25cea Paul Brook
device_init(virtio_pci_register_devices)