Commit 7055e687cd4cea5befefb2d8012e4e2574cfa9b3
Committed by
Anthony Liguori
1 parent
54c96da7
qemu/virtio: virtio support for many interrupt vectors
Extend virtio to support many interrupt vectors, and rearrange code in preparation for multi-vector support (mostly move reset out to bindings, because we will have to reset the vectors in transport-specific code). Actual bindings in pci, and use in net, to follow. Load and save are not connected to bindings yet, so they are left stubbed out for now. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing
4 changed files
with
81 additions
and
25 deletions
hw/syborg_virtio.c
@@ -134,7 +134,10 @@ static void syborg_virtio_writel(void *opaque, target_phys_addr_t offset, | @@ -134,7 +134,10 @@ static void syborg_virtio_writel(void *opaque, target_phys_addr_t offset, | ||
134 | vdev->features = value; | 134 | vdev->features = value; |
135 | break; | 135 | break; |
136 | case SYBORG_VIRTIO_QUEUE_BASE: | 136 | case SYBORG_VIRTIO_QUEUE_BASE: |
137 | - virtio_queue_set_addr(vdev, vdev->queue_sel, value); | 137 | + if (value == 0) |
138 | + virtio_reset(vdev); | ||
139 | + else | ||
140 | + virtio_queue_set_addr(vdev, vdev->queue_sel, value); | ||
138 | break; | 141 | break; |
139 | case SYBORG_VIRTIO_QUEUE_SEL: | 142 | case SYBORG_VIRTIO_QUEUE_SEL: |
140 | if (value < VIRTIO_PCI_QUEUE_MAX) | 143 | if (value < VIRTIO_PCI_QUEUE_MAX) |
@@ -228,7 +231,7 @@ static CPUWriteMemoryFunc *syborg_virtio_writefn[] = { | @@ -228,7 +231,7 @@ static CPUWriteMemoryFunc *syborg_virtio_writefn[] = { | ||
228 | syborg_virtio_writel | 231 | syborg_virtio_writel |
229 | }; | 232 | }; |
230 | 233 | ||
231 | -static void syborg_virtio_update_irq(void *opaque) | 234 | +static void syborg_virtio_update_irq(void *opaque, uint16_t vector) |
232 | { | 235 | { |
233 | SyborgVirtIOProxy *proxy = opaque; | 236 | SyborgVirtIOProxy *proxy = opaque; |
234 | int level; | 237 | int level; |
@@ -239,7 +242,7 @@ static void syborg_virtio_update_irq(void *opaque) | @@ -239,7 +242,7 @@ static void syborg_virtio_update_irq(void *opaque) | ||
239 | } | 242 | } |
240 | 243 | ||
241 | static VirtIOBindings syborg_virtio_bindings = { | 244 | static VirtIOBindings syborg_virtio_bindings = { |
242 | - .update_irq = syborg_virtio_update_irq | 245 | + .notify = syborg_virtio_update_irq |
243 | }; | 246 | }; |
244 | 247 | ||
245 | static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev) | 248 | static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev) |
@@ -248,6 +251,8 @@ static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev) | @@ -248,6 +251,8 @@ static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev) | ||
248 | 251 | ||
249 | proxy->vdev = vdev; | 252 | proxy->vdev = vdev; |
250 | 253 | ||
254 | + /* Don't support multiple vectors */ | ||
255 | + proxy->vdev->nvectors = 0; | ||
251 | sysbus_init_irq(&proxy->busdev, &proxy->irq); | 256 | sysbus_init_irq(&proxy->busdev, &proxy->irq); |
252 | iomemtype = cpu_register_io_memory(syborg_virtio_readfn, | 257 | iomemtype = cpu_register_io_memory(syborg_virtio_readfn, |
253 | syborg_virtio_writefn, proxy); | 258 | syborg_virtio_writefn, proxy); |
@@ -255,6 +260,8 @@ static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev) | @@ -255,6 +260,8 @@ static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev) | ||
255 | 260 | ||
256 | proxy->id = ((uint32_t)0x1af4 << 16) | vdev->device_id; | 261 | proxy->id = ((uint32_t)0x1af4 << 16) | vdev->device_id; |
257 | 262 | ||
263 | + qemu_register_reset(virtio_reset, 0, vdev); | ||
264 | + | ||
258 | virtio_bind_device(vdev, &syborg_virtio_bindings, proxy); | 265 | virtio_bind_device(vdev, &syborg_virtio_bindings, proxy); |
259 | } | 266 | } |
260 | 267 |
hw/virtio-pci.c
@@ -78,13 +78,19 @@ typedef struct { | @@ -78,13 +78,19 @@ typedef struct { | ||
78 | 78 | ||
79 | /* virtio device */ | 79 | /* virtio device */ |
80 | 80 | ||
81 | -static void virtio_pci_update_irq(void *opaque) | 81 | +static void virtio_pci_notify(void *opaque, uint16_t vector) |
82 | { | 82 | { |
83 | VirtIOPCIProxy *proxy = opaque; | 83 | VirtIOPCIProxy *proxy = opaque; |
84 | 84 | ||
85 | qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1); | 85 | qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1); |
86 | } | 86 | } |
87 | 87 | ||
88 | +static void virtio_pci_reset(void *opaque) | ||
89 | +{ | ||
90 | + VirtIOPCIProxy *proxy = opaque; | ||
91 | + virtio_reset(proxy->vdev); | ||
92 | +} | ||
93 | + | ||
88 | static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) | 94 | static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
89 | { | 95 | { |
90 | VirtIOPCIProxy *proxy = opaque; | 96 | VirtIOPCIProxy *proxy = opaque; |
@@ -108,7 +114,10 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -108,7 +114,10 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
108 | break; | 114 | break; |
109 | case VIRTIO_PCI_QUEUE_PFN: | 115 | case VIRTIO_PCI_QUEUE_PFN: |
110 | pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT; | 116 | pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT; |
111 | - virtio_queue_set_addr(vdev, vdev->queue_sel, pa); | 117 | + if (pa == 0) |
118 | + virtio_pci_reset(proxy); | ||
119 | + else | ||
120 | + virtio_queue_set_addr(vdev, vdev->queue_sel, pa); | ||
112 | break; | 121 | break; |
113 | case VIRTIO_PCI_QUEUE_SEL: | 122 | case VIRTIO_PCI_QUEUE_SEL: |
114 | if (val < VIRTIO_PCI_QUEUE_MAX) | 123 | if (val < VIRTIO_PCI_QUEUE_MAX) |
@@ -120,7 +129,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -120,7 +129,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
120 | case VIRTIO_PCI_STATUS: | 129 | case VIRTIO_PCI_STATUS: |
121 | vdev->status = val & 0xFF; | 130 | vdev->status = val & 0xFF; |
122 | if (vdev->status == 0) | 131 | if (vdev->status == 0) |
123 | - virtio_reset(vdev); | 132 | + virtio_pci_reset(proxy); |
124 | break; | 133 | break; |
125 | } | 134 | } |
126 | } | 135 | } |
@@ -160,7 +169,7 @@ static uint32_t virtio_ioport_read(void *opaque, uint32_t addr) | @@ -160,7 +169,7 @@ static uint32_t virtio_ioport_read(void *opaque, uint32_t addr) | ||
160 | /* reading from the ISR also clears it. */ | 169 | /* reading from the ISR also clears it. */ |
161 | ret = vdev->isr; | 170 | ret = vdev->isr; |
162 | vdev->isr = 0; | 171 | vdev->isr = 0; |
163 | - virtio_update_irq(vdev); | 172 | + qemu_set_irq(proxy->pci_dev.irq[0], 0); |
164 | break; | 173 | break; |
165 | default: | 174 | default: |
166 | break; | 175 | break; |
@@ -245,7 +254,7 @@ static void virtio_map(PCIDevice *pci_dev, int region_num, | @@ -245,7 +254,7 @@ static void virtio_map(PCIDevice *pci_dev, int region_num, | ||
245 | } | 254 | } |
246 | 255 | ||
247 | static const VirtIOBindings virtio_pci_bindings = { | 256 | static const VirtIOBindings virtio_pci_bindings = { |
248 | - .update_irq = virtio_pci_update_irq | 257 | + .notify = virtio_pci_notify |
249 | }; | 258 | }; |
250 | 259 | ||
251 | static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, | 260 | static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, |
@@ -257,6 +266,9 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, | @@ -257,6 +266,9 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, | ||
257 | 266 | ||
258 | proxy->vdev = vdev; | 267 | proxy->vdev = vdev; |
259 | 268 | ||
269 | + /* No support for multiple vectors yet. */ | ||
270 | + proxy->vdev->nvectors = 0; | ||
271 | + | ||
260 | config = proxy->pci_dev.config; | 272 | config = proxy->pci_dev.config; |
261 | pci_config_set_vendor_id(config, vendor); | 273 | pci_config_set_vendor_id(config, vendor); |
262 | pci_config_set_device_id(config, device); | 274 | pci_config_set_device_id(config, device); |
@@ -281,6 +293,8 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, | @@ -281,6 +293,8 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, | ||
281 | pci_register_bar(&proxy->pci_dev, 0, size, PCI_ADDRESS_SPACE_IO, | 293 | pci_register_bar(&proxy->pci_dev, 0, size, PCI_ADDRESS_SPACE_IO, |
282 | virtio_map); | 294 | virtio_map); |
283 | 295 | ||
296 | + qemu_register_reset(virtio_pci_reset, 0, proxy); | ||
297 | + | ||
284 | virtio_bind_device(vdev, &virtio_pci_bindings, proxy); | 298 | virtio_bind_device(vdev, &virtio_pci_bindings, proxy); |
285 | } | 299 | } |
286 | 300 |
hw/virtio.c
@@ -68,6 +68,7 @@ struct VirtQueue | @@ -68,6 +68,7 @@ struct VirtQueue | ||
68 | target_phys_addr_t pa; | 68 | target_phys_addr_t pa; |
69 | uint16_t last_avail_idx; | 69 | uint16_t last_avail_idx; |
70 | int inuse; | 70 | int inuse; |
71 | + uint16_t vector; | ||
71 | void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq); | 72 | void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq); |
72 | }; | 73 | }; |
73 | 74 | ||
@@ -421,12 +422,16 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) | @@ -421,12 +422,16 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) | ||
421 | } | 422 | } |
422 | 423 | ||
423 | /* virtio device */ | 424 | /* virtio device */ |
425 | +static void virtio_notify_vector(VirtIODevice *vdev, uint16_t vector) | ||
426 | +{ | ||
427 | + if (vdev->binding->notify) { | ||
428 | + vdev->binding->notify(vdev->binding_opaque, vector); | ||
429 | + } | ||
430 | +} | ||
424 | 431 | ||
425 | void virtio_update_irq(VirtIODevice *vdev) | 432 | void virtio_update_irq(VirtIODevice *vdev) |
426 | { | 433 | { |
427 | - if (vdev->binding->update_irq) { | ||
428 | - vdev->binding->update_irq(vdev->binding_opaque); | ||
429 | - } | 434 | + virtio_notify_vector(vdev, VIRTIO_NO_VECTOR); |
430 | } | 435 | } |
431 | 436 | ||
432 | void virtio_reset(void *opaque) | 437 | void virtio_reset(void *opaque) |
@@ -441,7 +446,8 @@ void virtio_reset(void *opaque) | @@ -441,7 +446,8 @@ void virtio_reset(void *opaque) | ||
441 | vdev->queue_sel = 0; | 446 | vdev->queue_sel = 0; |
442 | vdev->status = 0; | 447 | vdev->status = 0; |
443 | vdev->isr = 0; | 448 | vdev->isr = 0; |
444 | - virtio_update_irq(vdev); | 449 | + vdev->config_vector = VIRTIO_NO_VECTOR; |
450 | + virtio_notify_vector(vdev, vdev->config_vector); | ||
445 | 451 | ||
446 | for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { | 452 | for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { |
447 | vdev->vq[i].vring.desc = 0; | 453 | vdev->vq[i].vring.desc = 0; |
@@ -449,6 +455,7 @@ void virtio_reset(void *opaque) | @@ -449,6 +455,7 @@ void virtio_reset(void *opaque) | ||
449 | vdev->vq[i].vring.used = 0; | 455 | vdev->vq[i].vring.used = 0; |
450 | vdev->vq[i].last_avail_idx = 0; | 456 | vdev->vq[i].last_avail_idx = 0; |
451 | vdev->vq[i].pa = 0; | 457 | vdev->vq[i].pa = 0; |
458 | + vdev->vq[i].vector = VIRTIO_NO_VECTOR; | ||
452 | } | 459 | } |
453 | } | 460 | } |
454 | 461 | ||
@@ -532,12 +539,8 @@ void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data) | @@ -532,12 +539,8 @@ void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data) | ||
532 | 539 | ||
533 | void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr) | 540 | void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr) |
534 | { | 541 | { |
535 | - if (addr == 0) { | ||
536 | - virtio_reset(vdev); | ||
537 | - } else { | ||
538 | - vdev->vq[n].pa = addr; | ||
539 | - virtqueue_init(&vdev->vq[n]); | ||
540 | - } | 542 | + vdev->vq[n].pa = addr; |
543 | + virtqueue_init(&vdev->vq[n]); | ||
541 | } | 544 | } |
542 | 545 | ||
543 | target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n) | 546 | target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n) |
@@ -557,6 +560,18 @@ void virtio_queue_notify(VirtIODevice *vdev, int n) | @@ -557,6 +560,18 @@ void virtio_queue_notify(VirtIODevice *vdev, int n) | ||
557 | } | 560 | } |
558 | } | 561 | } |
559 | 562 | ||
563 | +uint16_t virtio_queue_vector(VirtIODevice *vdev, int n) | ||
564 | +{ | ||
565 | + return n < VIRTIO_PCI_QUEUE_MAX ? vdev->vq[n].vector : | ||
566 | + VIRTIO_NO_VECTOR; | ||
567 | +} | ||
568 | + | ||
569 | +void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector) | ||
570 | +{ | ||
571 | + if (n < VIRTIO_PCI_QUEUE_MAX) | ||
572 | + vdev->vq[n].vector = vector; | ||
573 | +} | ||
574 | + | ||
560 | VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, | 575 | VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, |
561 | void (*handle_output)(VirtIODevice *, VirtQueue *)) | 576 | void (*handle_output)(VirtIODevice *, VirtQueue *)) |
562 | { | 577 | { |
@@ -585,7 +600,7 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) | @@ -585,7 +600,7 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) | ||
585 | return; | 600 | return; |
586 | 601 | ||
587 | vdev->isr |= 0x01; | 602 | vdev->isr |= 0x01; |
588 | - virtio_update_irq(vdev); | 603 | + virtio_notify_vector(vdev, vq->vector); |
589 | } | 604 | } |
590 | 605 | ||
591 | void virtio_notify_config(VirtIODevice *vdev) | 606 | void virtio_notify_config(VirtIODevice *vdev) |
@@ -594,7 +609,7 @@ void virtio_notify_config(VirtIODevice *vdev) | @@ -594,7 +609,7 @@ void virtio_notify_config(VirtIODevice *vdev) | ||
594 | return; | 609 | return; |
595 | 610 | ||
596 | vdev->isr |= 0x03; | 611 | vdev->isr |= 0x03; |
597 | - virtio_update_irq(vdev); | 612 | + virtio_notify_vector(vdev, vdev->config_vector); |
598 | } | 613 | } |
599 | 614 | ||
600 | void virtio_save(VirtIODevice *vdev, QEMUFile *f) | 615 | void virtio_save(VirtIODevice *vdev, QEMUFile *f) |
@@ -603,6 +618,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) | @@ -603,6 +618,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) | ||
603 | 618 | ||
604 | /* FIXME: load/save binding. */ | 619 | /* FIXME: load/save binding. */ |
605 | //pci_device_save(&vdev->pci_dev, f); | 620 | //pci_device_save(&vdev->pci_dev, f); |
621 | + //msix_save(&vdev->pci_dev, f); | ||
606 | 622 | ||
607 | qemu_put_8s(f, &vdev->status); | 623 | qemu_put_8s(f, &vdev->status); |
608 | qemu_put_8s(f, &vdev->isr); | 624 | qemu_put_8s(f, &vdev->isr); |
@@ -611,6 +627,9 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) | @@ -611,6 +627,9 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) | ||
611 | qemu_put_be32(f, vdev->config_len); | 627 | qemu_put_be32(f, vdev->config_len); |
612 | qemu_put_buffer(f, vdev->config, vdev->config_len); | 628 | qemu_put_buffer(f, vdev->config, vdev->config_len); |
613 | 629 | ||
630 | + if (vdev->nvectors) | ||
631 | + qemu_put_be16s(f, &vdev->config_vector); | ||
632 | + | ||
614 | for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { | 633 | for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { |
615 | if (vdev->vq[i].vring.num == 0) | 634 | if (vdev->vq[i].vring.num == 0) |
616 | break; | 635 | break; |
@@ -625,6 +644,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) | @@ -625,6 +644,8 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) | ||
625 | qemu_put_be32(f, vdev->vq[i].vring.num); | 644 | qemu_put_be32(f, vdev->vq[i].vring.num); |
626 | qemu_put_be64(f, vdev->vq[i].pa); | 645 | qemu_put_be64(f, vdev->vq[i].pa); |
627 | qemu_put_be16s(f, &vdev->vq[i].last_avail_idx); | 646 | qemu_put_be16s(f, &vdev->vq[i].last_avail_idx); |
647 | + if (vdev->nvectors) | ||
648 | + qemu_put_be16s(f, &vdev->vq[i].vector); | ||
628 | } | 649 | } |
629 | } | 650 | } |
630 | 651 | ||
@@ -634,6 +655,7 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) | @@ -634,6 +655,7 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) | ||
634 | 655 | ||
635 | /* FIXME: load/save binding. */ | 656 | /* FIXME: load/save binding. */ |
636 | //pci_device_load(&vdev->pci_dev, f); | 657 | //pci_device_load(&vdev->pci_dev, f); |
658 | + //r = msix_load(&vdev->pci_dev, f); | ||
637 | 659 | ||
638 | qemu_get_8s(f, &vdev->status); | 660 | qemu_get_8s(f, &vdev->status); |
639 | qemu_get_8s(f, &vdev->isr); | 661 | qemu_get_8s(f, &vdev->isr); |
@@ -642,6 +664,10 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) | @@ -642,6 +664,10 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) | ||
642 | vdev->config_len = qemu_get_be32(f); | 664 | vdev->config_len = qemu_get_be32(f); |
643 | qemu_get_buffer(f, vdev->config, vdev->config_len); | 665 | qemu_get_buffer(f, vdev->config, vdev->config_len); |
644 | 666 | ||
667 | + if (vdev->nvectors) { | ||
668 | + qemu_get_be16s(f, &vdev->config_vector); | ||
669 | + //msix_vector_use(&vdev->pci_dev, vdev->config_vector); | ||
670 | + } | ||
645 | num = qemu_get_be32(f); | 671 | num = qemu_get_be32(f); |
646 | 672 | ||
647 | for (i = 0; i < num; i++) { | 673 | for (i = 0; i < num; i++) { |
@@ -652,9 +678,13 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) | @@ -652,9 +678,13 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) | ||
652 | if (vdev->vq[i].pa) { | 678 | if (vdev->vq[i].pa) { |
653 | virtqueue_init(&vdev->vq[i]); | 679 | virtqueue_init(&vdev->vq[i]); |
654 | } | 680 | } |
681 | + if (vdev->nvectors) { | ||
682 | + qemu_get_be16s(f, &vdev->vq[i].vector); | ||
683 | + //msix_vector_use(&vdev->pci_dev, vdev->config_vector); | ||
684 | + } | ||
655 | } | 685 | } |
656 | 686 | ||
657 | - virtio_update_irq(vdev); | 687 | + virtio_notify_vector(vdev, VIRTIO_NO_VECTOR); |
658 | } | 688 | } |
659 | 689 | ||
660 | void virtio_cleanup(VirtIODevice *vdev) | 690 | void virtio_cleanup(VirtIODevice *vdev) |
@@ -675,6 +705,7 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id, | @@ -675,6 +705,7 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id, | ||
675 | vdev->status = 0; | 705 | vdev->status = 0; |
676 | vdev->isr = 0; | 706 | vdev->isr = 0; |
677 | vdev->queue_sel = 0; | 707 | vdev->queue_sel = 0; |
708 | + vdev->config_vector = VIRTIO_NO_VECTOR; | ||
678 | vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX); | 709 | vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX); |
679 | 710 | ||
680 | vdev->name = name; | 711 | vdev->name = name; |
@@ -684,8 +715,6 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id, | @@ -684,8 +715,6 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id, | ||
684 | else | 715 | else |
685 | vdev->config = NULL; | 716 | vdev->config = NULL; |
686 | 717 | ||
687 | - qemu_register_reset(virtio_reset, 0, vdev); | ||
688 | - | ||
689 | return vdev; | 718 | return vdev; |
690 | } | 719 | } |
691 | 720 |
hw/virtio.h
@@ -75,11 +75,13 @@ typedef struct VirtQueueElement | @@ -75,11 +75,13 @@ typedef struct VirtQueueElement | ||
75 | } VirtQueueElement; | 75 | } VirtQueueElement; |
76 | 76 | ||
77 | typedef struct { | 77 | typedef struct { |
78 | - void (*update_irq)(void * opaque); | 78 | + void (*notify)(void * opaque, uint16_t vector); |
79 | } VirtIOBindings; | 79 | } VirtIOBindings; |
80 | 80 | ||
81 | #define VIRTIO_PCI_QUEUE_MAX 16 | 81 | #define VIRTIO_PCI_QUEUE_MAX 16 |
82 | 82 | ||
83 | +#define VIRTIO_NO_VECTOR 0xffff | ||
84 | + | ||
83 | struct VirtIODevice | 85 | struct VirtIODevice |
84 | { | 86 | { |
85 | const char *name; | 87 | const char *name; |
@@ -89,6 +91,8 @@ struct VirtIODevice | @@ -89,6 +91,8 @@ struct VirtIODevice | ||
89 | uint32_t features; | 91 | uint32_t features; |
90 | size_t config_len; | 92 | size_t config_len; |
91 | void *config; | 93 | void *config; |
94 | + uint16_t config_vector; | ||
95 | + int nvectors; | ||
92 | uint32_t (*get_features)(VirtIODevice *vdev); | 96 | uint32_t (*get_features)(VirtIODevice *vdev); |
93 | uint32_t (*bad_features)(VirtIODevice *vdev); | 97 | uint32_t (*bad_features)(VirtIODevice *vdev); |
94 | void (*set_features)(VirtIODevice *vdev, uint32_t val); | 98 | void (*set_features)(VirtIODevice *vdev, uint32_t val); |
@@ -118,7 +122,7 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq); | @@ -118,7 +122,7 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq); | ||
118 | 122 | ||
119 | void virtio_save(VirtIODevice *vdev, QEMUFile *f); | 123 | void virtio_save(VirtIODevice *vdev, QEMUFile *f); |
120 | 124 | ||
121 | -void virtio_load(VirtIODevice *vdev, QEMUFile *f); | 125 | +int virtio_load(VirtIODevice *vdev, QEMUFile *f); |
122 | 126 | ||
123 | void virtio_cleanup(VirtIODevice *vdev); | 127 | void virtio_cleanup(VirtIODevice *vdev); |
124 | 128 | ||
@@ -144,6 +148,8 @@ void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr); | @@ -144,6 +148,8 @@ void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr); | ||
144 | target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n); | 148 | target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n); |
145 | int virtio_queue_get_num(VirtIODevice *vdev, int n); | 149 | int virtio_queue_get_num(VirtIODevice *vdev, int n); |
146 | void virtio_queue_notify(VirtIODevice *vdev, int n); | 150 | void virtio_queue_notify(VirtIODevice *vdev, int n); |
151 | +uint16_t virtio_queue_vector(VirtIODevice *vdev, int n); | ||
152 | +void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector); | ||
147 | void virtio_reset(void *opaque); | 153 | void virtio_reset(void *opaque); |
148 | void virtio_update_irq(VirtIODevice *vdev); | 154 | void virtio_update_irq(VirtIODevice *vdev); |
149 | 155 |