Commit 53c25cea7d59525ca9aa3fb01cc6947bafbbfb61

Authored by Paul Brook
1 parent d8ee7665

Separate virtio PCI code

Split the PCI host bindings from the VRing transport implementation.

Signed-off-by: Paul Brook <paul@codesourcery.com>
Makefile.target
@@ -489,7 +489,8 @@ OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o dma-helpers.o \ @@ -489,7 +489,8 @@ OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o dma-helpers.o \
489 gdbstub.o gdbstub-xml.o sysbus.o 489 gdbstub.o gdbstub-xml.o sysbus.o
490 # virtio has to be here due to weird dependency between PCI and virtio-net. 490 # virtio has to be here due to weird dependency between PCI and virtio-net.
491 # need to fix this properly 491 # need to fix this properly
492 -OBJS+=virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o 492 +OBJS+=virtio.o virtio-pci.o
  493 +OBJS+=virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o
493 OBJS+=fw_cfg.o 494 OBJS+=fw_cfg.o
494 ifdef CONFIG_KVM 495 ifdef CONFIG_KVM
495 OBJS+=kvm.o kvm-all.o 496 OBJS+=kvm.o kvm-all.o
@@ -1137,21 +1137,21 @@ static void pc_init1(ram_addr_t ram_size, @@ -1137,21 +1137,21 @@ static void pc_init1(ram_addr_t ram_size,
1137 int unit_id = 0; 1137 int unit_id = 0;
1138 1138
1139 while ((index = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) { 1139 while ((index = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) {
1140 - pci_create_simple(pci_bus, -1, "virtio-blk"); 1140 + pci_create_simple(pci_bus, -1, "virtio-blk-pci");
1141 unit_id++; 1141 unit_id++;
1142 } 1142 }
1143 } 1143 }
1144 1144
1145 /* Add virtio balloon device */ 1145 /* Add virtio balloon device */
1146 if (pci_enabled) { 1146 if (pci_enabled) {
1147 - pci_create_simple(pci_bus, -1, "virtio-balloon"); 1147 + pci_create_simple(pci_bus, -1, "virtio-balloon-pci");
1148 } 1148 }
1149 1149
1150 /* Add virtio console devices */ 1150 /* Add virtio console devices */
1151 if (pci_enabled) { 1151 if (pci_enabled) {
1152 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) { 1152 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
1153 if (virtcon_hds[i]) { 1153 if (virtcon_hds[i]) {
1154 - pci_create_simple(pci_bus, -1, "virtio-console"); 1154 + pci_create_simple(pci_bus, -1, "virtio-console-pci");
1155 } 1155 }
1156 } 1156 }
1157 } 1157 }
hw/pci-hotplug.c
@@ -120,7 +120,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon, PCIBus *pci_bus, @@ -120,7 +120,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon, PCIBus *pci_bus,
120 opaque = pci_create_simple(pci_bus, -1, "lsi53c895a"); 120 opaque = pci_create_simple(pci_bus, -1, "lsi53c895a");
121 break; 121 break;
122 case IF_VIRTIO: 122 case IF_VIRTIO:
123 - opaque = pci_create_simple(pci_bus, -1, "virtio-blk"); 123 + opaque = pci_create_simple(pci_bus, -1, "virtio-blk-pci");
124 qdev_init(opaque); 124 qdev_init(opaque);
125 break; 125 break;
126 } 126 }
hw/pci.c
@@ -806,7 +806,7 @@ static const char * const pci_nic_names[] = { @@ -806,7 +806,7 @@ static const char * const pci_nic_names[] = {
806 "rtl8139", 806 "rtl8139",
807 "e1000", 807 "e1000",
808 "pcnet", 808 "pcnet",
809 - "virtio_net", 809 + "virtio-net-pci",
810 NULL 810 NULL
811 }; 811 };
812 812
hw/ppc440_bamboo.c
@@ -111,14 +111,14 @@ static void bamboo_init(ram_addr_t ram_size, @@ -111,14 +111,14 @@ static void bamboo_init(ram_addr_t ram_size,
111 111
112 /* Add virtio block devices. */ 112 /* Add virtio block devices. */
113 while ((i = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) { 113 while ((i = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) {
114 - pci_create_simple(pcibus, -1, "virtio-blk"); 114 + pci_create_simple(pcibus, -1, "virtio-blk-pci");
115 unit_id++; 115 unit_id++;
116 } 116 }
117 117
118 /* Add virtio console devices */ 118 /* Add virtio console devices */
119 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) { 119 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
120 if (virtcon_hds[i]) { 120 if (virtcon_hds[i]) {
121 - pci_create_simple(pcibus, -1, "virtio-console"); 121 + pci_create_simple(pcibus, -1, "virtio-console-pci");
122 } 122 }
123 } 123 }
124 124
hw/ppce500_mpc8544ds.c
@@ -220,7 +220,7 @@ static void mpc8544ds_init(ram_addr_t ram_size, @@ -220,7 +220,7 @@ static void mpc8544ds_init(ram_addr_t ram_size,
220 220
221 /* Add virtio block devices. */ 221 /* Add virtio block devices. */
222 while ((i = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) { 222 while ((i = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) {
223 - pci_create_simple(pci_bus, -1, "virtio-blk"); 223 + pci_create_simple(pci_bus, -1, "virtio-blk-pci");
224 unit_id++; 224 unit_id++;
225 } 225 }
226 226
hw/virtio-balloon.c
@@ -169,17 +169,13 @@ static int virtio_balloon_load(QEMUFile *f, void *opaque, int version_id) @@ -169,17 +169,13 @@ static int virtio_balloon_load(QEMUFile *f, void *opaque, int version_id)
169 return 0; 169 return 0;
170 } 170 }
171 171
172 -static void virtio_balloon_init(PCIDevice *pci_dev) 172 +VirtIODevice *virtio_balloon_init(DeviceState *dev)
173 { 173 {
174 VirtIOBalloon *s; 174 VirtIOBalloon *s;
175 175
176 - s = (VirtIOBalloon *)virtio_init_pci(pci_dev, "virtio-balloon",  
177 - PCI_VENDOR_ID_REDHAT_QUMRANET,  
178 - PCI_DEVICE_ID_VIRTIO_BALLOON,  
179 - PCI_VENDOR_ID_REDHAT_QUMRANET,  
180 - VIRTIO_ID_BALLOON,  
181 - PCI_CLASS_MEMORY_RAM, 0x00,  
182 - 8); 176 + s = (VirtIOBalloon *)virtio_common_init("virtio-balloon",
  177 + VIRTIO_ID_BALLOON,
  178 + 8, sizeof(VirtIOBalloon));
183 179
184 s->vdev.get_config = virtio_balloon_get_config; 180 s->vdev.get_config = virtio_balloon_get_config;
185 s->vdev.set_config = virtio_balloon_set_config; 181 s->vdev.set_config = virtio_balloon_set_config;
@@ -191,12 +187,6 @@ static void virtio_balloon_init(PCIDevice *pci_dev) @@ -191,12 +187,6 @@ static void virtio_balloon_init(PCIDevice *pci_dev)
191 qemu_add_balloon_handler(virtio_balloon_to_target, s); 187 qemu_add_balloon_handler(virtio_balloon_to_target, s);
192 188
193 register_savevm("virtio-balloon", -1, 1, virtio_balloon_save, virtio_balloon_load, s); 189 register_savevm("virtio-balloon", -1, 1, virtio_balloon_save, virtio_balloon_load, s);
194 -}  
195 190
196 -static void virtio_balloon_register_devices(void)  
197 -{  
198 - pci_qdev_register("virtio-balloon", sizeof(VirtIOBalloon),  
199 - virtio_balloon_init); 191 + return &s->vdev;
200 } 192 }
201 -  
202 -device_init(virtio_balloon_register_devices)  
hw/virtio-blk.c
@@ -348,28 +348,24 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id) @@ -348,28 +348,24 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
348 return 0; 348 return 0;
349 } 349 }
350 350
351 -static void virtio_blk_init(PCIDevice *pci_dev) 351 +VirtIODevice *virtio_blk_init(DeviceState *dev)
352 { 352 {
353 VirtIOBlock *s; 353 VirtIOBlock *s;
354 int cylinders, heads, secs; 354 int cylinders, heads, secs;
355 static int virtio_blk_id; 355 static int virtio_blk_id;
356 BlockDriverState *bs; 356 BlockDriverState *bs;
357 357
358 - s = (VirtIOBlock *)virtio_init_pci(pci_dev, "virtio-blk",  
359 - PCI_VENDOR_ID_REDHAT_QUMRANET,  
360 - PCI_DEVICE_ID_VIRTIO_BLOCK,  
361 - PCI_VENDOR_ID_REDHAT_QUMRANET,  
362 - VIRTIO_ID_BLOCK,  
363 - PCI_CLASS_STORAGE_OTHER, 0x00,  
364 - sizeof(struct virtio_blk_config)); 358 + s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
  359 + sizeof(struct virtio_blk_config),
  360 + sizeof(VirtIOBlock));
365 361
366 - bs = qdev_init_bdrv(&pci_dev->qdev, IF_VIRTIO); 362 + bs = qdev_init_bdrv(dev, IF_VIRTIO);
367 s->vdev.get_config = virtio_blk_update_config; 363 s->vdev.get_config = virtio_blk_update_config;
368 s->vdev.get_features = virtio_blk_get_features; 364 s->vdev.get_features = virtio_blk_get_features;
369 s->vdev.reset = virtio_blk_reset; 365 s->vdev.reset = virtio_blk_reset;
370 s->bs = bs; 366 s->bs = bs;
371 s->rq = NULL; 367 s->rq = NULL;
372 - bs->private = &s->vdev.pci_dev; 368 + bs->private = dev;
373 bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs); 369 bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
374 bdrv_set_geometry_hint(s->bs, cylinders, heads, secs); 370 bdrv_set_geometry_hint(s->bs, cylinders, heads, secs);
375 371
@@ -378,11 +374,6 @@ static void virtio_blk_init(PCIDevice *pci_dev) @@ -378,11 +374,6 @@ static void virtio_blk_init(PCIDevice *pci_dev)
378 qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s); 374 qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
379 register_savevm("virtio-blk", virtio_blk_id++, 2, 375 register_savevm("virtio-blk", virtio_blk_id++, 2,
380 virtio_blk_save, virtio_blk_load, s); 376 virtio_blk_save, virtio_blk_load, s);
381 -}  
382 377
383 -static void virtio_blk_register_devices(void)  
384 -{  
385 - pci_qdev_register("virtio-blk", sizeof(VirtIOBlock), virtio_blk_init); 378 + return &s->vdev;
386 } 379 }
387 -  
388 -device_init(virtio_blk_register_devices)  
hw/virtio-blk.h
@@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
16 16
17 #include "virtio.h" 17 #include "virtio.h"
18 #include "block.h" 18 #include "block.h"
19 -#include "pci.h"  
20 19
21 /* from Linux's linux/virtio_blk.h */ 20 /* from Linux's linux/virtio_blk.h */
22 21
hw/virtio-console.c
@@ -123,31 +123,21 @@ static int virtio_console_load(QEMUFile *f, void *opaque, int version_id) @@ -123,31 +123,21 @@ static int virtio_console_load(QEMUFile *f, void *opaque, int version_id)
123 return 0; 123 return 0;
124 } 124 }
125 125
126 -static void virtio_console_init(PCIDevice *pci_dev) 126 +VirtIODevice *virtio_console_init(DeviceState *dev)
127 { 127 {
128 VirtIOConsole *s; 128 VirtIOConsole *s;
129 - s = (VirtIOConsole *)virtio_init_pci(pci_dev, "virtio-console",  
130 - PCI_VENDOR_ID_REDHAT_QUMRANET,  
131 - PCI_DEVICE_ID_VIRTIO_CONSOLE,  
132 - PCI_VENDOR_ID_REDHAT_QUMRANET,  
133 - VIRTIO_ID_CONSOLE,  
134 - PCI_CLASS_DISPLAY_OTHER, 0x00,  
135 - 0); 129 + s = (VirtIOConsole *)virtio_common_init("virtio-console",
  130 + VIRTIO_ID_CONSOLE,
  131 + 0, sizeof(VirtIOConsole));
136 s->vdev.get_features = virtio_console_get_features; 132 s->vdev.get_features = virtio_console_get_features;
137 133
138 s->ivq = virtio_add_queue(&s->vdev, 128, virtio_console_handle_input); 134 s->ivq = virtio_add_queue(&s->vdev, 128, virtio_console_handle_input);
139 s->dvq = virtio_add_queue(&s->vdev, 128, virtio_console_handle_output); 135 s->dvq = virtio_add_queue(&s->vdev, 128, virtio_console_handle_output);
140 136
141 - s->chr = qdev_init_chardev(&pci_dev->qdev); 137 + s->chr = qdev_init_chardev(dev);
142 qemu_chr_add_handlers(s->chr, vcon_can_read, vcon_read, vcon_event, s); 138 qemu_chr_add_handlers(s->chr, vcon_can_read, vcon_read, vcon_event, s);
143 139
144 register_savevm("virtio-console", -1, 1, virtio_console_save, virtio_console_load, s); 140 register_savevm("virtio-console", -1, 1, virtio_console_save, virtio_console_load, s);
145 -}  
146 141
147 -static void virtio_console_register_devices(void)  
148 -{  
149 - pci_qdev_register("virtio-console", sizeof(VirtIOConsole),  
150 - virtio_console_init); 142 + return &s->vdev;
151 } 143 }
152 -  
153 -device_init(virtio_console_register_devices)  
hw/virtio-net.c
@@ -585,18 +585,14 @@ static void virtio_net_cleanup(VLANClientState *vc) @@ -585,18 +585,14 @@ static void virtio_net_cleanup(VLANClientState *vc)
585 virtio_cleanup(&n->vdev); 585 virtio_cleanup(&n->vdev);
586 } 586 }
587 587
588 -static void virtio_net_init(PCIDevice *pci_dev) 588 +VirtIODevice *virtio_net_init(DeviceState *dev)
589 { 589 {
590 VirtIONet *n; 590 VirtIONet *n;
591 static int virtio_net_id; 591 static int virtio_net_id;
592 592
593 - n = (VirtIONet *)virtio_init_pci(pci_dev, "virtio-net",  
594 - PCI_VENDOR_ID_REDHAT_QUMRANET,  
595 - PCI_DEVICE_ID_VIRTIO_NET,  
596 - PCI_VENDOR_ID_REDHAT_QUMRANET,  
597 - VIRTIO_ID_NET,  
598 - PCI_CLASS_NETWORK_ETHERNET, 0x00,  
599 - sizeof(struct virtio_net_config)); 593 + n = (VirtIONet *)virtio_common_init("virtio-net", VIRTIO_ID_NET,
  594 + sizeof(struct virtio_net_config),
  595 + sizeof(VirtIONet));
600 596
601 n->vdev.get_config = virtio_net_get_config; 597 n->vdev.get_config = virtio_net_get_config;
602 n->vdev.set_config = virtio_net_set_config; 598 n->vdev.set_config = virtio_net_set_config;
@@ -607,9 +603,9 @@ static void virtio_net_init(PCIDevice *pci_dev) @@ -607,9 +603,9 @@ static void virtio_net_init(PCIDevice *pci_dev)
607 n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx); 603 n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx);
608 n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx); 604 n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx);
609 n->ctrl_vq = virtio_add_queue(&n->vdev, 16, virtio_net_handle_ctrl); 605 n->ctrl_vq = virtio_add_queue(&n->vdev, 16, virtio_net_handle_ctrl);
610 - qdev_get_macaddr(&pci_dev->qdev, n->mac); 606 + qdev_get_macaddr(dev, n->mac);
611 n->status = VIRTIO_NET_S_LINK_UP; 607 n->status = VIRTIO_NET_S_LINK_UP;
612 - n->vc = qdev_get_vlan_client(&pci_dev->qdev, 608 + n->vc = qdev_get_vlan_client(dev,
613 virtio_net_receive, 609 virtio_net_receive,
614 virtio_net_can_receive, 610 virtio_net_can_receive,
615 virtio_net_cleanup, n); 611 virtio_net_cleanup, n);
@@ -628,11 +624,6 @@ static void virtio_net_init(PCIDevice *pci_dev) @@ -628,11 +624,6 @@ static void virtio_net_init(PCIDevice *pci_dev)
628 624
629 register_savevm("virtio-net", virtio_net_id++, VIRTIO_NET_VM_VERSION, 625 register_savevm("virtio-net", virtio_net_id++, VIRTIO_NET_VM_VERSION,
630 virtio_net_save, virtio_net_load, n); 626 virtio_net_save, virtio_net_load, n);
631 -}  
632 627
633 -static void virtio_net_register_devices(void)  
634 -{  
635 - pci_qdev_register("virtio_net", sizeof(VirtIONet), virtio_net_init); 628 + return &n->vdev;
636 } 629 }
637 -  
638 -device_init(virtio_net_register_devices)  
hw/virtio-pci.c 0 โ†’ 100644
  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 +
  16 +#include <inttypes.h>
  17 +
  18 +#include "virtio.h"
  19 +#include "pci.h"
  20 +#include "sysemu.h"
  21 +
  22 +/* from Linux's linux/virtio_pci.h */
  23 +
  24 +/* A 32-bit r/o bitmask of the features supported by the host */
  25 +#define VIRTIO_PCI_HOST_FEATURES 0
  26 +
  27 +/* A 32-bit r/w bitmask of features activated by the guest */
  28 +#define VIRTIO_PCI_GUEST_FEATURES 4
  29 +
  30 +/* A 32-bit r/w PFN for the currently selected queue */
  31 +#define VIRTIO_PCI_QUEUE_PFN 8
  32 +
  33 +/* A 16-bit r/o queue size for the currently selected queue */
  34 +#define VIRTIO_PCI_QUEUE_NUM 12
  35 +
  36 +/* A 16-bit r/w queue selector */
  37 +#define VIRTIO_PCI_QUEUE_SEL 14
  38 +
  39 +/* A 16-bit r/w queue notifier */
  40 +#define VIRTIO_PCI_QUEUE_NOTIFY 16
  41 +
  42 +/* An 8-bit device status register. */
  43 +#define VIRTIO_PCI_STATUS 18
  44 +
  45 +/* An 8-bit r/o interrupt status register. Reading the value will return the
  46 + * current contents of the ISR and will also clear it. This is effectively
  47 + * a read-and-acknowledge. */
  48 +#define VIRTIO_PCI_ISR 19
  49 +
  50 +#define VIRTIO_PCI_CONFIG 20
  51 +
  52 +/* Virtio ABI version, if we increment this, we break the guest driver. */
  53 +#define VIRTIO_PCI_ABI_VERSION 0
  54 +
  55 +/* How many bits to shift physical queue address written to QUEUE_PFN.
  56 + * 12 is historical, and due to x86 page size. */
  57 +#define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12
  58 +
  59 +/* QEMU doesn't strictly need write barriers since everything runs in
  60 + * lock-step. We'll leave the calls to wmb() in though to make it obvious for
  61 + * KVM or if kqemu gets SMP support.
  62 + */
  63 +#define wmb() do { } while (0)
  64 +
  65 +/* PCI bindings. */
  66 +
  67 +typedef struct {
  68 + PCIDevice pci_dev;
  69 + VirtIODevice *vdev;
  70 + uint32_t addr;
  71 +
  72 + uint16_t vendor;
  73 + uint16_t device;
  74 + uint16_t subvendor;
  75 + uint16_t class_code;
  76 + uint8_t pif;
  77 +} VirtIOPCIProxy;
  78 +
  79 +/* virtio device */
  80 +
  81 +static void virtio_pci_update_irq(void *opaque)
  82 +{
  83 + VirtIOPCIProxy *proxy = opaque;
  84 +
  85 + qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
  86 +}
  87 +
  88 +static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
  89 +{
  90 + VirtIOPCIProxy *proxy = opaque;
  91 + VirtIODevice *vdev = proxy->vdev;
  92 + target_phys_addr_t pa;
  93 +
  94 + addr -= proxy->addr;
  95 +
  96 + switch (addr) {
  97 + case VIRTIO_PCI_GUEST_FEATURES:
  98 + /* Guest does not negotiate properly? We have to assume nothing. */
  99 + if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
  100 + if (vdev->bad_features)
  101 + val = vdev->bad_features(vdev);
  102 + else
  103 + val = 0;
  104 + }
  105 + if (vdev->set_features)
  106 + vdev->set_features(vdev, val);
  107 + vdev->features = val;
  108 + break;
  109 + case VIRTIO_PCI_QUEUE_PFN:
  110 + pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
  111 + virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
  112 + break;
  113 + case VIRTIO_PCI_QUEUE_SEL:
  114 + if (val < VIRTIO_PCI_QUEUE_MAX)
  115 + vdev->queue_sel = val;
  116 + break;
  117 + case VIRTIO_PCI_QUEUE_NOTIFY:
  118 + virtio_queue_notify(vdev, val);
  119 + break;
  120 + case VIRTIO_PCI_STATUS:
  121 + vdev->status = val & 0xFF;
  122 + if (vdev->status == 0)
  123 + virtio_reset(vdev);
  124 + break;
  125 + }
  126 +}
  127 +
  128 +static uint32_t virtio_ioport_read(void *opaque, uint32_t addr)
  129 +{
  130 + VirtIOPCIProxy *proxy = opaque;
  131 + VirtIODevice *vdev = proxy->vdev;
  132 + uint32_t ret = 0xFFFFFFFF;
  133 +
  134 + addr -= proxy->addr;
  135 +
  136 + switch (addr) {
  137 + case VIRTIO_PCI_HOST_FEATURES:
  138 + ret = vdev->get_features(vdev);
  139 + ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY) | (1 << VIRTIO_F_BAD_FEATURE);
  140 + break;
  141 + case VIRTIO_PCI_GUEST_FEATURES:
  142 + ret = vdev->features;
  143 + break;
  144 + case VIRTIO_PCI_QUEUE_PFN:
  145 + ret = virtio_queue_get_addr(vdev, vdev->queue_sel)
  146 + >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
  147 + break;
  148 + case VIRTIO_PCI_QUEUE_NUM:
  149 + ret = virtio_queue_get_num(vdev, vdev->queue_sel);
  150 + break;
  151 + case VIRTIO_PCI_QUEUE_SEL:
  152 + ret = vdev->queue_sel;
  153 + break;
  154 + case VIRTIO_PCI_STATUS:
  155 + ret = vdev->status;
  156 + break;
  157 + case VIRTIO_PCI_ISR:
  158 + /* reading from the ISR also clears it. */
  159 + ret = vdev->isr;
  160 + vdev->isr = 0;
  161 + virtio_update_irq(vdev);
  162 + break;
  163 + default:
  164 + break;
  165 + }
  166 +
  167 + return ret;
  168 +}
  169 +
  170 +static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr)
  171 +{
  172 + VirtIOPCIProxy *proxy = opaque;
  173 + addr -= proxy->addr + VIRTIO_PCI_CONFIG;
  174 + return virtio_config_readb(proxy->vdev, addr);
  175 +}
  176 +
  177 +static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr)
  178 +{
  179 + VirtIOPCIProxy *proxy = opaque;
  180 + addr -= proxy->addr + VIRTIO_PCI_CONFIG;
  181 + return virtio_config_readw(proxy->vdev, addr);
  182 +}
  183 +
  184 +static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr)
  185 +{
  186 + VirtIOPCIProxy *proxy = opaque;
  187 + addr -= proxy->addr + VIRTIO_PCI_CONFIG;
  188 + return virtio_config_readl(proxy->vdev, addr);
  189 +}
  190 +
  191 +static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val)
  192 +{
  193 + VirtIOPCIProxy *proxy = opaque;
  194 + addr -= proxy->addr + VIRTIO_PCI_CONFIG;
  195 + virtio_config_writeb(proxy->vdev, addr, val);
  196 +}
  197 +
  198 +static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val)
  199 +{
  200 + VirtIOPCIProxy *proxy = opaque;
  201 + addr -= proxy->addr + VIRTIO_PCI_CONFIG;
  202 + virtio_config_writew(proxy->vdev, addr, val);
  203 +}
  204 +
  205 +static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
  206 +{
  207 + VirtIOPCIProxy *proxy = opaque;
  208 + addr -= proxy->addr + VIRTIO_PCI_CONFIG;
  209 + virtio_config_writel(proxy->vdev, addr, val);
  210 +}
  211 +
  212 +static void virtio_map(PCIDevice *pci_dev, int region_num,
  213 + uint32_t addr, uint32_t size, int type)
  214 +{
  215 + VirtIOPCIProxy *proxy = container_of(pci_dev, VirtIOPCIProxy, pci_dev);
  216 + VirtIODevice *vdev = proxy->vdev;
  217 + int i;
  218 +
  219 + proxy->addr = addr;
  220 + for (i = 0; i < 3; i++) {
  221 + register_ioport_write(addr, VIRTIO_PCI_CONFIG, 1 << i,
  222 + virtio_ioport_write, proxy);
  223 + register_ioport_read(addr, VIRTIO_PCI_CONFIG, 1 << i,
  224 + virtio_ioport_read, proxy);
  225 + }
  226 +
  227 + if (vdev->config_len) {
  228 + register_ioport_write(addr + VIRTIO_PCI_CONFIG, vdev->config_len, 1,
  229 + virtio_pci_config_writeb, proxy);
  230 + register_ioport_write(addr + VIRTIO_PCI_CONFIG, vdev->config_len, 2,
  231 + virtio_pci_config_writew, proxy);
  232 + register_ioport_write(addr + VIRTIO_PCI_CONFIG, vdev->config_len, 4,
  233 + virtio_pci_config_writel, proxy);
  234 + register_ioport_read(addr + VIRTIO_PCI_CONFIG, vdev->config_len, 1,
  235 + virtio_pci_config_readb, proxy);
  236 + register_ioport_read(addr + VIRTIO_PCI_CONFIG, vdev->config_len, 2,
  237 + virtio_pci_config_readw, proxy);
  238 + register_ioport_read(addr + VIRTIO_PCI_CONFIG, vdev->config_len, 4,
  239 + virtio_pci_config_readl, proxy);
  240 +
  241 + vdev->get_config(vdev, vdev->config);
  242 + }
  243 +}
  244 +
  245 +static const VirtIOBindings virtio_pci_bindings = {
  246 + .update_irq = virtio_pci_update_irq
  247 +};
  248 +
  249 +static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
  250 + uint16_t vendor, uint16_t device,
  251 + uint16_t class_code, uint8_t pif)
  252 +{
  253 + uint8_t *config;
  254 + uint32_t size;
  255 +
  256 + proxy->vdev = vdev;
  257 +
  258 + config = proxy->pci_dev.config;
  259 + pci_config_set_vendor_id(config, vendor);
  260 + pci_config_set_device_id(config, device);
  261 +
  262 + config[0x08] = VIRTIO_PCI_ABI_VERSION;
  263 +
  264 + config[0x09] = pif;
  265 + pci_config_set_class(config, class_code);
  266 + config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL;
  267 +
  268 + config[0x2c] = vendor & 0xFF;
  269 + config[0x2d] = (vendor >> 8) & 0xFF;
  270 + config[0x2e] = vdev->device_id & 0xFF;
  271 + config[0x2f] = (vdev->device_id >> 8) & 0xFF;
  272 +
  273 + config[0x3d] = 1;
  274 +
  275 + size = 20 + vdev->config_len;
  276 + if (size & (size-1))
  277 + size = 1 << qemu_fls(size);
  278 +
  279 + pci_register_io_region(&proxy->pci_dev, 0, size, PCI_ADDRESS_SPACE_IO,
  280 + virtio_map);
  281 +
  282 + virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
  283 +}
  284 +
  285 +static void virtio_blk_init_pci(PCIDevice *pci_dev)
  286 +{
  287 + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
  288 + VirtIODevice *vdev;
  289 +
  290 + vdev = virtio_blk_init(&pci_dev->qdev);
  291 + virtio_init_pci(proxy, vdev,
  292 + PCI_VENDOR_ID_REDHAT_QUMRANET,
  293 + PCI_DEVICE_ID_VIRTIO_BLOCK,
  294 + PCI_CLASS_STORAGE_OTHER,
  295 + 0x00);
  296 +}
  297 +
  298 +static void virtio_console_init_pci(PCIDevice *pci_dev)
  299 +{
  300 + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
  301 + VirtIODevice *vdev;
  302 +
  303 + vdev = virtio_console_init(&pci_dev->qdev);
  304 + virtio_init_pci(proxy, vdev,
  305 + PCI_VENDOR_ID_REDHAT_QUMRANET,
  306 + PCI_DEVICE_ID_VIRTIO_CONSOLE,
  307 + PCI_CLASS_DISPLAY_OTHER,
  308 + 0x00);
  309 +}
  310 +
  311 +static void virtio_net_init_pci(PCIDevice *pci_dev)
  312 +{
  313 + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
  314 + VirtIODevice *vdev;
  315 +
  316 + vdev = virtio_net_init(&pci_dev->qdev);
  317 + virtio_init_pci(proxy, vdev,
  318 + PCI_VENDOR_ID_REDHAT_QUMRANET,
  319 + PCI_DEVICE_ID_VIRTIO_NET,
  320 + PCI_CLASS_NETWORK_ETHERNET,
  321 + 0x00);
  322 +}
  323 +
  324 +static void virtio_balloon_init_pci(PCIDevice *pci_dev)
  325 +{
  326 + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
  327 + VirtIODevice *vdev;
  328 +
  329 + vdev = virtio_balloon_init(&pci_dev->qdev);
  330 + virtio_init_pci(proxy, vdev,
  331 + PCI_VENDOR_ID_REDHAT_QUMRANET,
  332 + PCI_DEVICE_ID_VIRTIO_BALLOON,
  333 + PCI_CLASS_MEMORY_RAM,
  334 + 0x00);
  335 +}
  336 +
  337 +static void virtio_pci_register_devices(void)
  338 +{
  339 + pci_qdev_register("virtio-blk-pci", sizeof(VirtIOPCIProxy),
  340 + virtio_blk_init_pci);
  341 + pci_qdev_register("virtio-net-pci", sizeof(VirtIOPCIProxy),
  342 + virtio_net_init_pci);
  343 + pci_qdev_register("virtio-console-pci", sizeof(VirtIOPCIProxy),
  344 + virtio_console_init_pci);
  345 + pci_qdev_register("virtio-balloon-pci", sizeof(VirtIOPCIProxy),
  346 + virtio_balloon_init_pci);
  347 +}
  348 +
  349 +device_init(virtio_pci_register_devices)
hw/virtio.c
@@ -16,43 +16,6 @@ @@ -16,43 +16,6 @@
16 #include "virtio.h" 16 #include "virtio.h"
17 #include "sysemu.h" 17 #include "sysemu.h"
18 18
19 -/* from Linux's linux/virtio_pci.h */  
20 -  
21 -/* A 32-bit r/o bitmask of the features supported by the host */  
22 -#define VIRTIO_PCI_HOST_FEATURES 0  
23 -  
24 -/* A 32-bit r/w bitmask of features activated by the guest */  
25 -#define VIRTIO_PCI_GUEST_FEATURES 4  
26 -  
27 -/* A 32-bit r/w PFN for the currently selected queue */  
28 -#define VIRTIO_PCI_QUEUE_PFN 8  
29 -  
30 -/* A 16-bit r/o queue size for the currently selected queue */  
31 -#define VIRTIO_PCI_QUEUE_NUM 12  
32 -  
33 -/* A 16-bit r/w queue selector */  
34 -#define VIRTIO_PCI_QUEUE_SEL 14  
35 -  
36 -/* A 16-bit r/w queue notifier */  
37 -#define VIRTIO_PCI_QUEUE_NOTIFY 16  
38 -  
39 -/* An 8-bit device status register. */  
40 -#define VIRTIO_PCI_STATUS 18  
41 -  
42 -/* An 8-bit r/o interrupt status register. Reading the value will return the  
43 - * current contents of the ISR and will also clear it. This is effectively  
44 - * a read-and-acknowledge. */  
45 -#define VIRTIO_PCI_ISR 19  
46 -  
47 -#define VIRTIO_PCI_CONFIG 20  
48 -  
49 -/* Virtio ABI version, if we increment this, we break the guest driver. */  
50 -#define VIRTIO_PCI_ABI_VERSION 0  
51 -  
52 -/* How many bits to shift physical queue address written to QUEUE_PFN.  
53 - * 12 is historical, and due to x86 page size. */  
54 -#define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12  
55 -  
56 /* The alignment to use between consumer and producer parts of vring. 19 /* The alignment to use between consumer and producer parts of vring.
57 * x86 pagesize again. */ 20 * x86 pagesize again. */
58 #define VIRTIO_PCI_VRING_ALIGN 4096 21 #define VIRTIO_PCI_VRING_ALIGN 4096
@@ -102,7 +65,7 @@ typedef struct VRing @@ -102,7 +65,7 @@ typedef struct VRing
102 struct VirtQueue 65 struct VirtQueue
103 { 66 {
104 VRing vring; 67 VRing vring;
105 - uint32_t pfn; 68 + target_phys_addr_t pa;
106 uint16_t last_avail_idx; 69 uint16_t last_avail_idx;
107 int inuse; 70 int inuse;
108 void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq); 71 void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
@@ -111,8 +74,10 @@ struct VirtQueue @@ -111,8 +74,10 @@ struct VirtQueue
111 #define VIRTIO_PCI_QUEUE_MAX 16 74 #define VIRTIO_PCI_QUEUE_MAX 16
112 75
113 /* virt queue functions */ 76 /* virt queue functions */
114 -static void virtqueue_init(VirtQueue *vq, target_phys_addr_t pa) 77 +static void virtqueue_init(VirtQueue *vq)
115 { 78 {
  79 + target_phys_addr_t pa = vq->pa;
  80 +
116 vq->vring.desc = pa; 81 vq->vring.desc = pa;
117 vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc); 82 vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc);
118 vq->vring.used = vring_align(vq->vring.avail + 83 vq->vring.used = vring_align(vq->vring.avail +
@@ -409,17 +374,14 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) @@ -409,17 +374,14 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
409 374
410 /* virtio device */ 375 /* virtio device */
411 376
412 -static VirtIODevice *to_virtio_device(PCIDevice *pci_dev) 377 +void virtio_update_irq(VirtIODevice *vdev)
413 { 378 {
414 - return (VirtIODevice *)pci_dev;  
415 -}  
416 -  
417 -static void virtio_update_irq(VirtIODevice *vdev)  
418 -{  
419 - qemu_set_irq(vdev->pci_dev.irq[0], vdev->isr & 1); 379 + if (vdev->binding->update_irq) {
  380 + vdev->binding->update_irq(vdev->binding_opaque);
  381 + }
420 } 382 }
421 383
422 -static void virtio_reset(void *opaque) 384 +void virtio_reset(void *opaque)
423 { 385 {
424 VirtIODevice *vdev = opaque; 386 VirtIODevice *vdev = opaque;
425 int i; 387 int i;
@@ -438,103 +400,16 @@ static void virtio_reset(void *opaque) @@ -438,103 +400,16 @@ static void virtio_reset(void *opaque)
438 vdev->vq[i].vring.avail = 0; 400 vdev->vq[i].vring.avail = 0;
439 vdev->vq[i].vring.used = 0; 401 vdev->vq[i].vring.used = 0;
440 vdev->vq[i].last_avail_idx = 0; 402 vdev->vq[i].last_avail_idx = 0;
441 - vdev->vq[i].pfn = 0; 403 + vdev->vq[i].pa = 0;
442 } 404 }
443 } 405 }
444 406
445 -static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)  
446 -{  
447 - VirtIODevice *vdev = to_virtio_device(opaque);  
448 - ram_addr_t pa;  
449 -  
450 - addr -= vdev->addr;  
451 -  
452 - switch (addr) {  
453 - case VIRTIO_PCI_GUEST_FEATURES:  
454 - /* Guest does not negotiate properly? We have to assume nothing. */  
455 - if (val & (1 << VIRTIO_F_BAD_FEATURE)) {  
456 - if (vdev->bad_features)  
457 - val = vdev->bad_features(vdev);  
458 - else  
459 - val = 0;  
460 - }  
461 - if (vdev->set_features)  
462 - vdev->set_features(vdev, val);  
463 - vdev->features = val;  
464 - break;  
465 - case VIRTIO_PCI_QUEUE_PFN:  
466 - pa = (ram_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;  
467 - vdev->vq[vdev->queue_sel].pfn = val;  
468 - if (pa == 0) {  
469 - virtio_reset(vdev);  
470 - } else {  
471 - virtqueue_init(&vdev->vq[vdev->queue_sel], pa);  
472 - }  
473 - break;  
474 - case VIRTIO_PCI_QUEUE_SEL:  
475 - if (val < VIRTIO_PCI_QUEUE_MAX)  
476 - vdev->queue_sel = val;  
477 - break;  
478 - case VIRTIO_PCI_QUEUE_NOTIFY:  
479 - if (val < VIRTIO_PCI_QUEUE_MAX && vdev->vq[val].vring.desc)  
480 - vdev->vq[val].handle_output(vdev, &vdev->vq[val]);  
481 - break;  
482 - case VIRTIO_PCI_STATUS:  
483 - vdev->status = val & 0xFF;  
484 - if (vdev->status == 0)  
485 - virtio_reset(vdev);  
486 - break;  
487 - }  
488 -}  
489 -  
490 -static uint32_t virtio_ioport_read(void *opaque, uint32_t addr)  
491 -{  
492 - VirtIODevice *vdev = to_virtio_device(opaque);  
493 - uint32_t ret = 0xFFFFFFFF;  
494 -  
495 - addr -= vdev->addr;  
496 -  
497 - switch (addr) {  
498 - case VIRTIO_PCI_HOST_FEATURES:  
499 - ret = vdev->get_features(vdev);  
500 - ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY) | (1 << VIRTIO_F_BAD_FEATURE);  
501 - break;  
502 - case VIRTIO_PCI_GUEST_FEATURES:  
503 - ret = vdev->features;  
504 - break;  
505 - case VIRTIO_PCI_QUEUE_PFN:  
506 - ret = vdev->vq[vdev->queue_sel].pfn;  
507 - break;  
508 - case VIRTIO_PCI_QUEUE_NUM:  
509 - ret = vdev->vq[vdev->queue_sel].vring.num;  
510 - break;  
511 - case VIRTIO_PCI_QUEUE_SEL:  
512 - ret = vdev->queue_sel;  
513 - break;  
514 - case VIRTIO_PCI_STATUS:  
515 - ret = vdev->status;  
516 - break;  
517 - case VIRTIO_PCI_ISR:  
518 - /* reading from the ISR also clears it. */  
519 - ret = vdev->isr;  
520 - vdev->isr = 0;  
521 - virtio_update_irq(vdev);  
522 - break;  
523 - default:  
524 - break;  
525 - }  
526 -  
527 - return ret;  
528 -}  
529 -  
530 -static uint32_t virtio_config_readb(void *opaque, uint32_t addr) 407 +uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr)
531 { 408 {
532 - VirtIODevice *vdev = opaque;  
533 uint8_t val; 409 uint8_t val;
534 410
535 vdev->get_config(vdev, vdev->config); 411 vdev->get_config(vdev, vdev->config);
536 412
537 - addr -= vdev->addr + VIRTIO_PCI_CONFIG;  
538 if (addr > (vdev->config_len - sizeof(val))) 413 if (addr > (vdev->config_len - sizeof(val)))
539 return (uint32_t)-1; 414 return (uint32_t)-1;
540 415
@@ -542,14 +417,12 @@ static uint32_t virtio_config_readb(void *opaque, uint32_t addr) @@ -542,14 +417,12 @@ static uint32_t virtio_config_readb(void *opaque, uint32_t addr)
542 return val; 417 return val;
543 } 418 }
544 419
545 -static uint32_t virtio_config_readw(void *opaque, uint32_t addr) 420 +uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr)
546 { 421 {
547 - VirtIODevice *vdev = opaque;  
548 uint16_t val; 422 uint16_t val;
549 423
550 vdev->get_config(vdev, vdev->config); 424 vdev->get_config(vdev, vdev->config);
551 425
552 - addr -= vdev->addr + VIRTIO_PCI_CONFIG;  
553 if (addr > (vdev->config_len - sizeof(val))) 426 if (addr > (vdev->config_len - sizeof(val)))
554 return (uint32_t)-1; 427 return (uint32_t)-1;
555 428
@@ -557,14 +430,12 @@ static uint32_t virtio_config_readw(void *opaque, uint32_t addr) @@ -557,14 +430,12 @@ static uint32_t virtio_config_readw(void *opaque, uint32_t addr)
557 return val; 430 return val;
558 } 431 }
559 432
560 -static uint32_t virtio_config_readl(void *opaque, uint32_t addr) 433 +uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr)
561 { 434 {
562 - VirtIODevice *vdev = opaque;  
563 uint32_t val; 435 uint32_t val;
564 436
565 vdev->get_config(vdev, vdev->config); 437 vdev->get_config(vdev, vdev->config);
566 438
567 - addr -= vdev->addr + VIRTIO_PCI_CONFIG;  
568 if (addr > (vdev->config_len - sizeof(val))) 439 if (addr > (vdev->config_len - sizeof(val)))
569 return (uint32_t)-1; 440 return (uint32_t)-1;
570 441
@@ -572,12 +443,10 @@ static uint32_t virtio_config_readl(void *opaque, uint32_t addr) @@ -572,12 +443,10 @@ static uint32_t virtio_config_readl(void *opaque, uint32_t addr)
572 return val; 443 return val;
573 } 444 }
574 445
575 -static void virtio_config_writeb(void *opaque, uint32_t addr, uint32_t data) 446 +void virtio_config_writeb(VirtIODevice *vdev, uint32_t addr, uint32_t data)
576 { 447 {
577 - VirtIODevice *vdev = opaque;  
578 uint8_t val = data; 448 uint8_t val = data;
579 449
580 - addr -= vdev->addr + VIRTIO_PCI_CONFIG;  
581 if (addr > (vdev->config_len - sizeof(val))) 450 if (addr > (vdev->config_len - sizeof(val)))
582 return; 451 return;
583 452
@@ -587,12 +456,10 @@ static void virtio_config_writeb(void *opaque, uint32_t addr, uint32_t data) @@ -587,12 +456,10 @@ static void virtio_config_writeb(void *opaque, uint32_t addr, uint32_t data)
587 vdev->set_config(vdev, vdev->config); 456 vdev->set_config(vdev, vdev->config);
588 } 457 }
589 458
590 -static void virtio_config_writew(void *opaque, uint32_t addr, uint32_t data) 459 +void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data)
591 { 460 {
592 - VirtIODevice *vdev = opaque;  
593 uint16_t val = data; 461 uint16_t val = data;
594 462
595 - addr -= vdev->addr + VIRTIO_PCI_CONFIG;  
596 if (addr > (vdev->config_len - sizeof(val))) 463 if (addr > (vdev->config_len - sizeof(val)))
597 return; 464 return;
598 465
@@ -602,12 +469,10 @@ static void virtio_config_writew(void *opaque, uint32_t addr, uint32_t data) @@ -602,12 +469,10 @@ static void virtio_config_writew(void *opaque, uint32_t addr, uint32_t data)
602 vdev->set_config(vdev, vdev->config); 469 vdev->set_config(vdev, vdev->config);
603 } 470 }
604 471
605 -static void virtio_config_writel(void *opaque, uint32_t addr, uint32_t data) 472 +void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data)
606 { 473 {
607 - VirtIODevice *vdev = opaque;  
608 uint32_t val = data; 474 uint32_t val = data;
609 475
610 - addr -= vdev->addr + VIRTIO_PCI_CONFIG;  
611 if (addr > (vdev->config_len - sizeof(val))) 476 if (addr > (vdev->config_len - sizeof(val)))
612 return; 477 return;
613 478
@@ -617,33 +482,30 @@ static void virtio_config_writel(void *opaque, uint32_t addr, uint32_t data) @@ -617,33 +482,30 @@ static void virtio_config_writel(void *opaque, uint32_t addr, uint32_t data)
617 vdev->set_config(vdev, vdev->config); 482 vdev->set_config(vdev, vdev->config);
618 } 483 }
619 484
620 -static void virtio_map(PCIDevice *pci_dev, int region_num,  
621 - uint32_t addr, uint32_t size, int type) 485 +void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr)
622 { 486 {
623 - VirtIODevice *vdev = to_virtio_device(pci_dev);  
624 - int i;  
625 -  
626 - vdev->addr = addr;  
627 - for (i = 0; i < 3; i++) {  
628 - register_ioport_write(addr, 20, 1 << i, virtio_ioport_write, vdev);  
629 - register_ioport_read(addr, 20, 1 << i, virtio_ioport_read, vdev); 487 + if (addr == 0) {
  488 + virtio_reset(vdev);
  489 + } else {
  490 + vdev->vq[n].pa = addr;
  491 + virtqueue_init(&vdev->vq[n]);
630 } 492 }
  493 +}
  494 +
  495 +target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n)
  496 +{
  497 + return vdev->vq[n].pa;
  498 +}
  499 +
  500 +int virtio_queue_get_num(VirtIODevice *vdev, int n)
  501 +{
  502 + return vdev->vq[n].vring.num;
  503 +}
631 504
632 - if (vdev->config_len) {  
633 - register_ioport_write(addr + 20, vdev->config_len, 1,  
634 - virtio_config_writeb, vdev);  
635 - register_ioport_write(addr + 20, vdev->config_len, 2,  
636 - virtio_config_writew, vdev);  
637 - register_ioport_write(addr + 20, vdev->config_len, 4,  
638 - virtio_config_writel, vdev);  
639 - register_ioport_read(addr + 20, vdev->config_len, 1,  
640 - virtio_config_readb, vdev);  
641 - register_ioport_read(addr + 20, vdev->config_len, 2,  
642 - virtio_config_readw, vdev);  
643 - register_ioport_read(addr + 20, vdev->config_len, 4,  
644 - virtio_config_readl, vdev);  
645 -  
646 - vdev->get_config(vdev, vdev->config); 505 +void virtio_queue_notify(VirtIODevice *vdev, int n)
  506 +{
  507 + if (n < VIRTIO_PCI_QUEUE_MAX && vdev->vq[n].vring.desc) {
  508 + vdev->vq[n].handle_output(vdev, &vdev->vq[n]);
647 } 509 }
648 } 510 }
649 511
@@ -691,9 +553,9 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) @@ -691,9 +553,9 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
691 { 553 {
692 int i; 554 int i;
693 555
694 - pci_device_save(&vdev->pci_dev, f); 556 + /* FIXME: load/save binding. */
  557 + //pci_device_save(&vdev->pci_dev, f);
695 558
696 - qemu_put_be32s(f, &vdev->addr);  
697 qemu_put_8s(f, &vdev->status); 559 qemu_put_8s(f, &vdev->status);
698 qemu_put_8s(f, &vdev->isr); 560 qemu_put_8s(f, &vdev->isr);
699 qemu_put_be16s(f, &vdev->queue_sel); 561 qemu_put_be16s(f, &vdev->queue_sel);
@@ -713,7 +575,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) @@ -713,7 +575,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
713 break; 575 break;
714 576
715 qemu_put_be32(f, vdev->vq[i].vring.num); 577 qemu_put_be32(f, vdev->vq[i].vring.num);
716 - qemu_put_be32s(f, &vdev->vq[i].pfn); 578 + qemu_put_be64(f, vdev->vq[i].pa);
717 qemu_put_be16s(f, &vdev->vq[i].last_avail_idx); 579 qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
718 } 580 }
719 } 581 }
@@ -722,9 +584,9 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) @@ -722,9 +584,9 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
722 { 584 {
723 int num, i; 585 int num, i;
724 586
725 - pci_device_load(&vdev->pci_dev, f); 587 + /* FIXME: load/save binding. */
  588 + //pci_device_load(&vdev->pci_dev, f);
726 589
727 - qemu_get_be32s(f, &vdev->addr);  
728 qemu_get_8s(f, &vdev->status); 590 qemu_get_8s(f, &vdev->status);
729 qemu_get_8s(f, &vdev->isr); 591 qemu_get_8s(f, &vdev->isr);
730 qemu_get_be16s(f, &vdev->queue_sel); 592 qemu_get_be16s(f, &vdev->queue_sel);
@@ -736,14 +598,11 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) @@ -736,14 +598,11 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
736 598
737 for (i = 0; i < num; i++) { 599 for (i = 0; i < num; i++) {
738 vdev->vq[i].vring.num = qemu_get_be32(f); 600 vdev->vq[i].vring.num = qemu_get_be32(f);
739 - qemu_get_be32s(f, &vdev->vq[i].pfn); 601 + vdev->vq[i].pa = qemu_get_be64(f);
740 qemu_get_be16s(f, &vdev->vq[i].last_avail_idx); 602 qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
741 603
742 - if (vdev->vq[i].pfn) {  
743 - target_phys_addr_t pa;  
744 -  
745 - pa = (ram_addr_t)vdev->vq[i].pfn << VIRTIO_PCI_QUEUE_ADDR_SHIFT;  
746 - virtqueue_init(&vdev->vq[i], pa); 604 + if (vdev->vq[i].pa) {
  605 + virtqueue_init(&vdev->vq[i]);
747 } 606 }
748 } 607 }
749 608
@@ -757,40 +616,19 @@ void virtio_cleanup(VirtIODevice *vdev) @@ -757,40 +616,19 @@ void virtio_cleanup(VirtIODevice *vdev)
757 qemu_free(vdev->vq); 616 qemu_free(vdev->vq);
758 } 617 }
759 618
760 -VirtIODevice *virtio_init_pci(PCIDevice *pci_dev, const char *name,  
761 - uint16_t vendor, uint16_t device,  
762 - uint16_t subvendor, uint16_t subdevice,  
763 - uint16_t class_code, uint8_t pif,  
764 - size_t config_size) 619 +VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
  620 + size_t config_size, size_t struct_size)
765 { 621 {
766 VirtIODevice *vdev; 622 VirtIODevice *vdev;
767 - uint8_t *config;  
768 - uint32_t size;  
769 623
770 - vdev = to_virtio_device(pci_dev); 624 + vdev = qemu_mallocz(struct_size);
771 625
  626 + vdev->device_id = device_id;
772 vdev->status = 0; 627 vdev->status = 0;
773 vdev->isr = 0; 628 vdev->isr = 0;
774 vdev->queue_sel = 0; 629 vdev->queue_sel = 0;
775 vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX); 630 vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
776 631
777 - config = pci_dev->config;  
778 - pci_config_set_vendor_id(config, vendor);  
779 - pci_config_set_device_id(config, device);  
780 -  
781 - config[0x08] = VIRTIO_PCI_ABI_VERSION;  
782 -  
783 - config[0x09] = pif;  
784 - pci_config_set_class(config, class_code);  
785 - config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL;  
786 -  
787 - config[0x2c] = subvendor & 0xFF;  
788 - config[0x2d] = (subvendor >> 8) & 0xFF;  
789 - config[0x2e] = subdevice & 0xFF;  
790 - config[0x2f] = (subdevice >> 8) & 0xFF;  
791 -  
792 - config[0x3d] = 1;  
793 -  
794 vdev->name = name; 632 vdev->name = name;
795 vdev->config_len = config_size; 633 vdev->config_len = config_size;
796 if (vdev->config_len) 634 if (vdev->config_len)
@@ -798,13 +636,13 @@ VirtIODevice *virtio_init_pci(PCIDevice *pci_dev, const char *name, @@ -798,13 +636,13 @@ VirtIODevice *virtio_init_pci(PCIDevice *pci_dev, const char *name,
798 else 636 else
799 vdev->config = NULL; 637 vdev->config = NULL;
800 638
801 - size = 20 + config_size;  
802 - if (size & (size-1))  
803 - size = 1 << qemu_fls(size);  
804 -  
805 - pci_register_io_region(pci_dev, 0, size, PCI_ADDRESS_SPACE_IO,  
806 - virtio_map);  
807 qemu_register_reset(virtio_reset, vdev); 639 qemu_register_reset(virtio_reset, vdev);
808 -  
809 return vdev; 640 return vdev;
810 } 641 }
  642 +
  643 +void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
  644 + void *opaque)
  645 +{
  646 + vdev->binding = binding;
  647 + vdev->binding_opaque = opaque;
  648 +}
hw/virtio.h
@@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
15 #define _QEMU_VIRTIO_H 15 #define _QEMU_VIRTIO_H
16 16
17 #include "hw.h" 17 #include "hw.h"
18 -#include "pci.h" 18 +#include "qdev.h"
19 19
20 /* from Linux's linux/virtio_config.h */ 20 /* from Linux's linux/virtio_config.h */
21 21
@@ -70,13 +70,15 @@ typedef struct VirtQueueElement @@ -70,13 +70,15 @@ typedef struct VirtQueueElement
70 struct iovec out_sg[VIRTQUEUE_MAX_SIZE]; 70 struct iovec out_sg[VIRTQUEUE_MAX_SIZE];
71 } VirtQueueElement; 71 } VirtQueueElement;
72 72
  73 +typedef struct {
  74 + void (*update_irq)(void * opaque);
  75 +} VirtIOBindings;
  76 +
73 #define VIRTIO_PCI_QUEUE_MAX 16 77 #define VIRTIO_PCI_QUEUE_MAX 16
74 78
75 struct VirtIODevice 79 struct VirtIODevice
76 { 80 {
77 - PCIDevice pci_dev;  
78 const char *name; 81 const char *name;
79 - uint32_t addr;  
80 uint8_t status; 82 uint8_t status;
81 uint8_t isr; 83 uint8_t isr;
82 uint16_t queue_sel; 84 uint16_t queue_sel;
@@ -90,14 +92,11 @@ struct VirtIODevice @@ -90,14 +92,11 @@ struct VirtIODevice
90 void (*set_config)(VirtIODevice *vdev, const uint8_t *config); 92 void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
91 void (*reset)(VirtIODevice *vdev); 93 void (*reset)(VirtIODevice *vdev);
92 VirtQueue *vq; 94 VirtQueue *vq;
  95 + const VirtIOBindings *binding;
  96 + void *binding_opaque;
  97 + uint16_t device_id;
93 }; 98 };
94 99
95 -VirtIODevice *virtio_init_pci(PCIDevice *pci_dev, const char *name,  
96 - uint16_t vendor, uint16_t device,  
97 - uint16_t subvendor, uint16_t subdevice,  
98 - uint16_t class_code, uint8_t pif,  
99 - size_t config_size);  
100 -  
101 VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, 100 VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
102 void (*handle_output)(VirtIODevice *, 101 void (*handle_output)(VirtIODevice *,
103 VirtQueue *)); 102 VirtQueue *));
@@ -127,4 +126,30 @@ int virtio_queue_ready(VirtQueue *vq); @@ -127,4 +126,30 @@ int virtio_queue_ready(VirtQueue *vq);
127 126
128 int virtio_queue_empty(VirtQueue *vq); 127 int virtio_queue_empty(VirtQueue *vq);
129 128
  129 +/* Host binding interface. */
  130 +
  131 +VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
  132 + size_t config_size, size_t struct_size);
  133 +uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr);
  134 +uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr);
  135 +uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr);
  136 +void virtio_config_writeb(VirtIODevice *vdev, uint32_t addr, uint32_t data);
  137 +void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data);
  138 +void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data);
  139 +void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr);
  140 +target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n);
  141 +int virtio_queue_get_num(VirtIODevice *vdev, int n);
  142 +void virtio_queue_notify(VirtIODevice *vdev, int n);
  143 +void virtio_reset(void *opaque);
  144 +void virtio_update_irq(VirtIODevice *vdev);
  145 +
  146 +void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
  147 + void *opaque);
  148 +
  149 +/* Base devices. */
  150 +VirtIODevice *virtio_blk_init(DeviceState *dev);
  151 +VirtIODevice *virtio_net_init(DeviceState *dev);
  152 +VirtIODevice *virtio_console_init(DeviceState *dev);
  153 +VirtIODevice *virtio_balloon_init(DeviceState *dev);
  154 +
130 #endif 155 #endif