4 * Copyright (c) 2011 Linaro Limited
7 * Peter Maydell <peter.maydell@linaro.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "qemu/osdep.h"
23 #include "standard-headers/linux/virtio_mmio.h"
25 #include "hw/qdev-properties.h"
26 #include "hw/sysbus.h"
27 #include "hw/virtio/virtio.h"
28 #include "migration/qemu-file-types.h"
29 #include "qemu/host-utils.h"
30 #include "qemu/module.h"
31 #include "sysemu/kvm.h"
32 #include "hw/virtio/virtio-mmio.h"
33 #include "qemu/error-report.h"
37 static bool virtio_mmio_ioeventfd_enabled(DeviceState
*d
)
39 return kvm_eventfds_enabled();
42 static int virtio_mmio_ioeventfd_assign(DeviceState
*d
,
43 EventNotifier
*notifier
,
46 VirtIOMMIOProxy
*proxy
= VIRTIO_MMIO(d
);
49 memory_region_add_eventfd(&proxy
->iomem
, VIRTIO_MMIO_QUEUE_NOTIFY
, 4,
52 memory_region_del_eventfd(&proxy
->iomem
, VIRTIO_MMIO_QUEUE_NOTIFY
, 4,
58 static void virtio_mmio_start_ioeventfd(VirtIOMMIOProxy
*proxy
)
60 virtio_bus_start_ioeventfd(&proxy
->bus
);
63 static void virtio_mmio_stop_ioeventfd(VirtIOMMIOProxy
*proxy
)
65 virtio_bus_stop_ioeventfd(&proxy
->bus
);
68 static uint64_t virtio_mmio_read(void *opaque
, hwaddr offset
, unsigned size
)
70 VirtIOMMIOProxy
*proxy
= (VirtIOMMIOProxy
*)opaque
;
71 VirtIODevice
*vdev
= virtio_bus_get_device(&proxy
->bus
);
73 trace_virtio_mmio_read(offset
);
76 /* If no backend is present, we treat most registers as
77 * read-as-zero, except for the magic number, version and
78 * vendor ID. This is not strictly sanctioned by the virtio
79 * spec, but it allows us to provide transports with no backend
80 * plugged in which don't confuse Linux's virtio code: the
81 * probe won't complain about the bad magic number, but the
82 * device ID of zero means no backend will claim it.
85 case VIRTIO_MMIO_MAGIC_VALUE
:
87 case VIRTIO_MMIO_VERSION
:
89 return VIRT_VERSION_LEGACY
;
93 case VIRTIO_MMIO_VENDOR_ID
:
100 if (offset
>= VIRTIO_MMIO_CONFIG
) {
101 offset
-= VIRTIO_MMIO_CONFIG
;
104 return virtio_config_readb(vdev
, offset
);
106 return virtio_config_readw(vdev
, offset
);
108 return virtio_config_readl(vdev
, offset
);
114 qemu_log_mask(LOG_GUEST_ERROR
,
115 "%s: wrong size access to register!\n",
120 case VIRTIO_MMIO_MAGIC_VALUE
:
122 case VIRTIO_MMIO_VERSION
:
124 return VIRT_VERSION_LEGACY
;
128 case VIRTIO_MMIO_DEVICE_ID
:
129 return vdev
->device_id
;
130 case VIRTIO_MMIO_VENDOR_ID
:
132 case VIRTIO_MMIO_DEVICE_FEATURES
:
134 if (proxy
->host_features_sel
) {
137 return vdev
->host_features
;
140 VirtioDeviceClass
*vdc
= VIRTIO_DEVICE_GET_CLASS(vdev
);
141 return (vdev
->host_features
& ~vdc
->legacy_features
)
142 >> (32 * proxy
->host_features_sel
);
144 case VIRTIO_MMIO_QUEUE_NUM_MAX
:
145 if (!virtio_queue_get_num(vdev
, vdev
->queue_sel
)) {
148 return VIRTQUEUE_MAX_SIZE
;
149 case VIRTIO_MMIO_QUEUE_PFN
:
150 if (!proxy
->legacy
) {
151 qemu_log_mask(LOG_GUEST_ERROR
,
152 "%s: read from legacy register (0x%"
153 HWADDR_PRIx
") in non-legacy mode\n",
157 return virtio_queue_get_addr(vdev
, vdev
->queue_sel
)
158 >> proxy
->guest_page_shift
;
159 case VIRTIO_MMIO_QUEUE_READY
:
161 qemu_log_mask(LOG_GUEST_ERROR
,
162 "%s: read from non-legacy register (0x%"
163 HWADDR_PRIx
") in legacy mode\n",
167 return proxy
->vqs
[vdev
->queue_sel
].enabled
;
168 case VIRTIO_MMIO_INTERRUPT_STATUS
:
169 return atomic_read(&vdev
->isr
);
170 case VIRTIO_MMIO_STATUS
:
172 case VIRTIO_MMIO_CONFIG_GENERATION
:
174 qemu_log_mask(LOG_GUEST_ERROR
,
175 "%s: read from non-legacy register (0x%"
176 HWADDR_PRIx
") in legacy mode\n",
180 return vdev
->generation
;
181 case VIRTIO_MMIO_DEVICE_FEATURES_SEL
:
182 case VIRTIO_MMIO_DRIVER_FEATURES
:
183 case VIRTIO_MMIO_DRIVER_FEATURES_SEL
:
184 case VIRTIO_MMIO_GUEST_PAGE_SIZE
:
185 case VIRTIO_MMIO_QUEUE_SEL
:
186 case VIRTIO_MMIO_QUEUE_NUM
:
187 case VIRTIO_MMIO_QUEUE_ALIGN
:
188 case VIRTIO_MMIO_QUEUE_NOTIFY
:
189 case VIRTIO_MMIO_INTERRUPT_ACK
:
190 case VIRTIO_MMIO_QUEUE_DESC_LOW
:
191 case VIRTIO_MMIO_QUEUE_DESC_HIGH
:
192 case VIRTIO_MMIO_QUEUE_AVAIL_LOW
:
193 case VIRTIO_MMIO_QUEUE_AVAIL_HIGH
:
194 case VIRTIO_MMIO_QUEUE_USED_LOW
:
195 case VIRTIO_MMIO_QUEUE_USED_HIGH
:
196 qemu_log_mask(LOG_GUEST_ERROR
,
197 "%s: read of write-only register (0x%" HWADDR_PRIx
")\n",
201 qemu_log_mask(LOG_GUEST_ERROR
,
202 "%s: bad register offset (0x%" HWADDR_PRIx
")\n",
209 static void virtio_mmio_write(void *opaque
, hwaddr offset
, uint64_t value
,
212 VirtIOMMIOProxy
*proxy
= (VirtIOMMIOProxy
*)opaque
;
213 VirtIODevice
*vdev
= virtio_bus_get_device(&proxy
->bus
);
215 trace_virtio_mmio_write_offset(offset
, value
);
218 /* If no backend is present, we just make all registers
219 * write-ignored. This allows us to provide transports with
220 * no backend plugged in.
225 if (offset
>= VIRTIO_MMIO_CONFIG
) {
226 offset
-= VIRTIO_MMIO_CONFIG
;
229 virtio_config_writeb(vdev
, offset
, value
);
232 virtio_config_writew(vdev
, offset
, value
);
235 virtio_config_writel(vdev
, offset
, value
);
243 qemu_log_mask(LOG_GUEST_ERROR
,
244 "%s: wrong size access to register!\n",
249 case VIRTIO_MMIO_DEVICE_FEATURES_SEL
:
251 proxy
->host_features_sel
= 1;
253 proxy
->host_features_sel
= 0;
256 case VIRTIO_MMIO_DRIVER_FEATURES
:
258 if (proxy
->guest_features_sel
) {
259 qemu_log_mask(LOG_GUEST_ERROR
,
260 "%s: attempt to write guest features with "
261 "guest_features_sel > 0 in legacy mode\n",
264 virtio_set_features(vdev
, value
);
267 proxy
->guest_features
[proxy
->guest_features_sel
] = value
;
270 case VIRTIO_MMIO_DRIVER_FEATURES_SEL
:
272 proxy
->guest_features_sel
= 1;
274 proxy
->guest_features_sel
= 0;
277 case VIRTIO_MMIO_GUEST_PAGE_SIZE
:
278 if (!proxy
->legacy
) {
279 qemu_log_mask(LOG_GUEST_ERROR
,
280 "%s: write to legacy register (0x%"
281 HWADDR_PRIx
") in non-legacy mode\n",
285 proxy
->guest_page_shift
= ctz32(value
);
286 if (proxy
->guest_page_shift
> 31) {
287 proxy
->guest_page_shift
= 0;
289 trace_virtio_mmio_guest_page(value
, proxy
->guest_page_shift
);
291 case VIRTIO_MMIO_QUEUE_SEL
:
292 if (value
< VIRTIO_QUEUE_MAX
) {
293 vdev
->queue_sel
= value
;
296 case VIRTIO_MMIO_QUEUE_NUM
:
297 trace_virtio_mmio_queue_write(value
, VIRTQUEUE_MAX_SIZE
);
299 virtio_queue_set_num(vdev
, vdev
->queue_sel
, value
);
300 virtio_queue_update_rings(vdev
, vdev
->queue_sel
);
302 proxy
->vqs
[vdev
->queue_sel
].num
= value
;
305 case VIRTIO_MMIO_QUEUE_ALIGN
:
306 if (!proxy
->legacy
) {
307 qemu_log_mask(LOG_GUEST_ERROR
,
308 "%s: write to legacy register (0x%"
309 HWADDR_PRIx
") in non-legacy mode\n",
313 virtio_queue_set_align(vdev
, vdev
->queue_sel
, value
);
315 case VIRTIO_MMIO_QUEUE_PFN
:
316 if (!proxy
->legacy
) {
317 qemu_log_mask(LOG_GUEST_ERROR
,
318 "%s: write to legacy register (0x%"
319 HWADDR_PRIx
") in non-legacy mode\n",
326 virtio_queue_set_addr(vdev
, vdev
->queue_sel
,
327 value
<< proxy
->guest_page_shift
);
330 case VIRTIO_MMIO_QUEUE_READY
:
332 qemu_log_mask(LOG_GUEST_ERROR
,
333 "%s: write to non-legacy register (0x%"
334 HWADDR_PRIx
") in legacy mode\n",
339 virtio_queue_set_num(vdev
, vdev
->queue_sel
,
340 proxy
->vqs
[vdev
->queue_sel
].num
);
341 virtio_queue_set_rings(vdev
, vdev
->queue_sel
,
342 ((uint64_t)proxy
->vqs
[vdev
->queue_sel
].desc
[1]) << 32 |
343 proxy
->vqs
[vdev
->queue_sel
].desc
[0],
344 ((uint64_t)proxy
->vqs
[vdev
->queue_sel
].avail
[1]) << 32 |
345 proxy
->vqs
[vdev
->queue_sel
].avail
[0],
346 ((uint64_t)proxy
->vqs
[vdev
->queue_sel
].used
[1]) << 32 |
347 proxy
->vqs
[vdev
->queue_sel
].used
[0]);
348 proxy
->vqs
[vdev
->queue_sel
].enabled
= 1;
350 proxy
->vqs
[vdev
->queue_sel
].enabled
= 0;
353 case VIRTIO_MMIO_QUEUE_NOTIFY
:
354 if (value
< VIRTIO_QUEUE_MAX
) {
355 virtio_queue_notify(vdev
, value
);
358 case VIRTIO_MMIO_INTERRUPT_ACK
:
359 atomic_and(&vdev
->isr
, ~value
);
360 virtio_update_irq(vdev
);
362 case VIRTIO_MMIO_STATUS
:
363 if (!(value
& VIRTIO_CONFIG_S_DRIVER_OK
)) {
364 virtio_mmio_stop_ioeventfd(proxy
);
367 if (!proxy
->legacy
&& (value
& VIRTIO_CONFIG_S_FEATURES_OK
)) {
368 virtio_set_features(vdev
,
369 ((uint64_t)proxy
->guest_features
[1]) << 32 |
370 proxy
->guest_features
[0]);
373 virtio_set_status(vdev
, value
& 0xff);
375 if (value
& VIRTIO_CONFIG_S_DRIVER_OK
) {
376 virtio_mmio_start_ioeventfd(proxy
);
379 if (vdev
->status
== 0) {
383 case VIRTIO_MMIO_QUEUE_DESC_LOW
:
385 qemu_log_mask(LOG_GUEST_ERROR
,
386 "%s: write to non-legacy register (0x%"
387 HWADDR_PRIx
") in legacy mode\n",
391 proxy
->vqs
[vdev
->queue_sel
].desc
[0] = value
;
393 case VIRTIO_MMIO_QUEUE_DESC_HIGH
:
395 qemu_log_mask(LOG_GUEST_ERROR
,
396 "%s: write to non-legacy register (0x%"
397 HWADDR_PRIx
") in legacy mode\n",
401 proxy
->vqs
[vdev
->queue_sel
].desc
[1] = value
;
403 case VIRTIO_MMIO_QUEUE_AVAIL_LOW
:
405 qemu_log_mask(LOG_GUEST_ERROR
,
406 "%s: write to non-legacy register (0x%"
407 HWADDR_PRIx
") in legacy mode\n",
411 proxy
->vqs
[vdev
->queue_sel
].avail
[0] = value
;
413 case VIRTIO_MMIO_QUEUE_AVAIL_HIGH
:
415 qemu_log_mask(LOG_GUEST_ERROR
,
416 "%s: write to non-legacy register (0x%"
417 HWADDR_PRIx
") in legacy mode\n",
421 proxy
->vqs
[vdev
->queue_sel
].avail
[1] = value
;
423 case VIRTIO_MMIO_QUEUE_USED_LOW
:
425 qemu_log_mask(LOG_GUEST_ERROR
,
426 "%s: write to non-legacy register (0x%"
427 HWADDR_PRIx
") in legacy mode\n",
431 proxy
->vqs
[vdev
->queue_sel
].used
[0] = value
;
433 case VIRTIO_MMIO_QUEUE_USED_HIGH
:
435 qemu_log_mask(LOG_GUEST_ERROR
,
436 "%s: write to non-legacy register (0x%"
437 HWADDR_PRIx
") in legacy mode\n",
441 proxy
->vqs
[vdev
->queue_sel
].used
[1] = value
;
443 case VIRTIO_MMIO_MAGIC_VALUE
:
444 case VIRTIO_MMIO_VERSION
:
445 case VIRTIO_MMIO_DEVICE_ID
:
446 case VIRTIO_MMIO_VENDOR_ID
:
447 case VIRTIO_MMIO_DEVICE_FEATURES
:
448 case VIRTIO_MMIO_QUEUE_NUM_MAX
:
449 case VIRTIO_MMIO_INTERRUPT_STATUS
:
450 case VIRTIO_MMIO_CONFIG_GENERATION
:
451 qemu_log_mask(LOG_GUEST_ERROR
,
452 "%s: write to read-only register (0x%" HWADDR_PRIx
")\n",
457 qemu_log_mask(LOG_GUEST_ERROR
,
458 "%s: bad register offset (0x%" HWADDR_PRIx
")\n",
463 static const MemoryRegionOps virtio_legacy_mem_ops
= {
464 .read
= virtio_mmio_read
,
465 .write
= virtio_mmio_write
,
466 .endianness
= DEVICE_NATIVE_ENDIAN
,
469 static const MemoryRegionOps virtio_mem_ops
= {
470 .read
= virtio_mmio_read
,
471 .write
= virtio_mmio_write
,
472 .endianness
= DEVICE_LITTLE_ENDIAN
,
475 static void virtio_mmio_update_irq(DeviceState
*opaque
, uint16_t vector
)
477 VirtIOMMIOProxy
*proxy
= VIRTIO_MMIO(opaque
);
478 VirtIODevice
*vdev
= virtio_bus_get_device(&proxy
->bus
);
484 level
= (atomic_read(&vdev
->isr
) != 0);
485 trace_virtio_mmio_setting_irq(level
);
486 qemu_set_irq(proxy
->irq
, level
);
489 static int virtio_mmio_load_config(DeviceState
*opaque
, QEMUFile
*f
)
491 VirtIOMMIOProxy
*proxy
= VIRTIO_MMIO(opaque
);
493 proxy
->host_features_sel
= qemu_get_be32(f
);
494 proxy
->guest_features_sel
= qemu_get_be32(f
);
495 proxy
->guest_page_shift
= qemu_get_be32(f
);
499 static void virtio_mmio_save_config(DeviceState
*opaque
, QEMUFile
*f
)
501 VirtIOMMIOProxy
*proxy
= VIRTIO_MMIO(opaque
);
503 qemu_put_be32(f
, proxy
->host_features_sel
);
504 qemu_put_be32(f
, proxy
->guest_features_sel
);
505 qemu_put_be32(f
, proxy
->guest_page_shift
);
508 static const VMStateDescription vmstate_virtio_mmio_queue_state
= {
509 .name
= "virtio_mmio/queue_state",
511 .minimum_version_id
= 1,
512 .fields
= (VMStateField
[]) {
513 VMSTATE_UINT16(num
, VirtIOMMIOQueue
),
514 VMSTATE_BOOL(enabled
, VirtIOMMIOQueue
),
515 VMSTATE_UINT32_ARRAY(desc
, VirtIOMMIOQueue
, 2),
516 VMSTATE_UINT32_ARRAY(avail
, VirtIOMMIOQueue
, 2),
517 VMSTATE_UINT32_ARRAY(used
, VirtIOMMIOQueue
, 2),
518 VMSTATE_END_OF_LIST()
522 static const VMStateDescription vmstate_virtio_mmio_state_sub
= {
523 .name
= "virtio_mmio/state",
525 .minimum_version_id
= 1,
526 .fields
= (VMStateField
[]) {
527 VMSTATE_UINT32_ARRAY(guest_features
, VirtIOMMIOProxy
, 2),
528 VMSTATE_STRUCT_ARRAY(vqs
, VirtIOMMIOProxy
, VIRTIO_QUEUE_MAX
, 0,
529 vmstate_virtio_mmio_queue_state
,
531 VMSTATE_END_OF_LIST()
535 static const VMStateDescription vmstate_virtio_mmio
= {
536 .name
= "virtio_mmio",
538 .minimum_version_id
= 1,
539 .minimum_version_id_old
= 1,
540 .fields
= (VMStateField
[]) {
541 VMSTATE_END_OF_LIST()
543 .subsections
= (const VMStateDescription
* []) {
544 &vmstate_virtio_mmio_state_sub
,
549 static void virtio_mmio_save_extra_state(DeviceState
*opaque
, QEMUFile
*f
)
551 VirtIOMMIOProxy
*proxy
= VIRTIO_MMIO(opaque
);
553 vmstate_save_state(f
, &vmstate_virtio_mmio
, proxy
, NULL
);
556 static int virtio_mmio_load_extra_state(DeviceState
*opaque
, QEMUFile
*f
)
558 VirtIOMMIOProxy
*proxy
= VIRTIO_MMIO(opaque
);
560 return vmstate_load_state(f
, &vmstate_virtio_mmio
, proxy
, 1);
563 static bool virtio_mmio_has_extra_state(DeviceState
*opaque
)
565 VirtIOMMIOProxy
*proxy
= VIRTIO_MMIO(opaque
);
567 return !proxy
->legacy
;
570 static void virtio_mmio_reset(DeviceState
*d
)
572 VirtIOMMIOProxy
*proxy
= VIRTIO_MMIO(d
);
575 virtio_mmio_stop_ioeventfd(proxy
);
576 virtio_bus_reset(&proxy
->bus
);
577 proxy
->host_features_sel
= 0;
578 proxy
->guest_features_sel
= 0;
579 proxy
->guest_page_shift
= 0;
581 if (!proxy
->legacy
) {
582 proxy
->guest_features
[0] = proxy
->guest_features
[1] = 0;
584 for (i
= 0; i
< VIRTIO_QUEUE_MAX
; i
++) {
585 proxy
->vqs
[i
].enabled
= 0;
586 proxy
->vqs
[i
].num
= 0;
587 proxy
->vqs
[i
].desc
[0] = proxy
->vqs
[i
].desc
[1] = 0;
588 proxy
->vqs
[i
].avail
[0] = proxy
->vqs
[i
].avail
[1] = 0;
589 proxy
->vqs
[i
].used
[0] = proxy
->vqs
[i
].used
[1] = 0;
594 static int virtio_mmio_set_guest_notifier(DeviceState
*d
, int n
, bool assign
,
597 VirtIOMMIOProxy
*proxy
= VIRTIO_MMIO(d
);
598 VirtIODevice
*vdev
= virtio_bus_get_device(&proxy
->bus
);
599 VirtioDeviceClass
*vdc
= VIRTIO_DEVICE_GET_CLASS(vdev
);
600 VirtQueue
*vq
= virtio_get_queue(vdev
, n
);
601 EventNotifier
*notifier
= virtio_queue_get_guest_notifier(vq
);
604 int r
= event_notifier_init(notifier
, 0);
608 virtio_queue_set_guest_notifier_fd_handler(vq
, true, with_irqfd
);
610 virtio_queue_set_guest_notifier_fd_handler(vq
, false, with_irqfd
);
611 event_notifier_cleanup(notifier
);
614 if (vdc
->guest_notifier_mask
&& vdev
->use_guest_notifier_mask
) {
615 vdc
->guest_notifier_mask(vdev
, n
, !assign
);
621 static int virtio_mmio_set_guest_notifiers(DeviceState
*d
, int nvqs
,
624 VirtIOMMIOProxy
*proxy
= VIRTIO_MMIO(d
);
625 VirtIODevice
*vdev
= virtio_bus_get_device(&proxy
->bus
);
626 /* TODO: need to check if kvm-arm supports irqfd */
627 bool with_irqfd
= false;
630 nvqs
= MIN(nvqs
, VIRTIO_QUEUE_MAX
);
632 for (n
= 0; n
< nvqs
; n
++) {
633 if (!virtio_queue_get_num(vdev
, n
)) {
637 r
= virtio_mmio_set_guest_notifier(d
, n
, assign
, with_irqfd
);
646 /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
649 virtio_mmio_set_guest_notifier(d
, n
, !assign
, false);
654 static void virtio_mmio_pre_plugged(DeviceState
*d
, Error
**errp
)
656 VirtIOMMIOProxy
*proxy
= VIRTIO_MMIO(d
);
657 VirtIODevice
*vdev
= virtio_bus_get_device(&proxy
->bus
);
659 if (!proxy
->legacy
) {
660 virtio_add_feature(&vdev
->host_features
, VIRTIO_F_VERSION_1
);
664 /* virtio-mmio device */
666 static Property virtio_mmio_properties
[] = {
667 DEFINE_PROP_BOOL("format_transport_address", VirtIOMMIOProxy
,
668 format_transport_address
, true),
669 DEFINE_PROP_BOOL("force-legacy", VirtIOMMIOProxy
, legacy
, true),
670 DEFINE_PROP_END_OF_LIST(),
673 static void virtio_mmio_realizefn(DeviceState
*d
, Error
**errp
)
675 VirtIOMMIOProxy
*proxy
= VIRTIO_MMIO(d
);
676 SysBusDevice
*sbd
= SYS_BUS_DEVICE(d
);
678 qbus_create_inplace(&proxy
->bus
, sizeof(proxy
->bus
), TYPE_VIRTIO_MMIO_BUS
,
680 sysbus_init_irq(sbd
, &proxy
->irq
);
682 memory_region_init_io(&proxy
->iomem
, OBJECT(d
),
683 &virtio_legacy_mem_ops
, proxy
,
684 TYPE_VIRTIO_MMIO
, 0x200);
686 memory_region_init_io(&proxy
->iomem
, OBJECT(d
),
687 &virtio_mem_ops
, proxy
,
688 TYPE_VIRTIO_MMIO
, 0x200);
690 sysbus_init_mmio(sbd
, &proxy
->iomem
);
693 static void virtio_mmio_class_init(ObjectClass
*klass
, void *data
)
695 DeviceClass
*dc
= DEVICE_CLASS(klass
);
697 dc
->realize
= virtio_mmio_realizefn
;
698 dc
->reset
= virtio_mmio_reset
;
699 set_bit(DEVICE_CATEGORY_MISC
, dc
->categories
);
700 dc
->props
= virtio_mmio_properties
;
703 static const TypeInfo virtio_mmio_info
= {
704 .name
= TYPE_VIRTIO_MMIO
,
705 .parent
= TYPE_SYS_BUS_DEVICE
,
706 .instance_size
= sizeof(VirtIOMMIOProxy
),
707 .class_init
= virtio_mmio_class_init
,
710 /* virtio-mmio-bus. */
712 static char *virtio_mmio_bus_get_dev_path(DeviceState
*dev
)
714 BusState
*virtio_mmio_bus
;
715 VirtIOMMIOProxy
*virtio_mmio_proxy
;
717 SysBusDevice
*proxy_sbd
;
720 virtio_mmio_bus
= qdev_get_parent_bus(dev
);
721 virtio_mmio_proxy
= VIRTIO_MMIO(virtio_mmio_bus
->parent
);
722 proxy_path
= qdev_get_dev_path(DEVICE(virtio_mmio_proxy
));
725 * If @format_transport_address is false, then we just perform the same as
726 * virtio_bus_get_dev_path(): we delegate the address formatting for the
727 * device on the virtio-mmio bus to the bus that the virtio-mmio proxy
728 * (i.e., the device that implements the virtio-mmio bus) resides on. In
729 * this case the base address of the virtio-mmio transport will be
732 if (!virtio_mmio_proxy
->format_transport_address
) {
736 /* Otherwise, we append the base address of the transport. */
737 proxy_sbd
= SYS_BUS_DEVICE(virtio_mmio_proxy
);
738 assert(proxy_sbd
->num_mmio
== 1);
739 assert(proxy_sbd
->mmio
[0].memory
== &virtio_mmio_proxy
->iomem
);
742 path
= g_strdup_printf("%s/virtio-mmio@" TARGET_FMT_plx
, proxy_path
,
743 proxy_sbd
->mmio
[0].addr
);
745 path
= g_strdup_printf("virtio-mmio@" TARGET_FMT_plx
,
746 proxy_sbd
->mmio
[0].addr
);
752 static void virtio_mmio_bus_class_init(ObjectClass
*klass
, void *data
)
754 BusClass
*bus_class
= BUS_CLASS(klass
);
755 VirtioBusClass
*k
= VIRTIO_BUS_CLASS(klass
);
757 k
->notify
= virtio_mmio_update_irq
;
758 k
->save_config
= virtio_mmio_save_config
;
759 k
->load_config
= virtio_mmio_load_config
;
760 k
->save_extra_state
= virtio_mmio_save_extra_state
;
761 k
->load_extra_state
= virtio_mmio_load_extra_state
;
762 k
->has_extra_state
= virtio_mmio_has_extra_state
;
763 k
->set_guest_notifiers
= virtio_mmio_set_guest_notifiers
;
764 k
->ioeventfd_enabled
= virtio_mmio_ioeventfd_enabled
;
765 k
->ioeventfd_assign
= virtio_mmio_ioeventfd_assign
;
766 k
->pre_plugged
= virtio_mmio_pre_plugged
;
767 k
->has_variable_vring_alignment
= true;
768 bus_class
->max_dev
= 1;
769 bus_class
->get_dev_path
= virtio_mmio_bus_get_dev_path
;
772 static const TypeInfo virtio_mmio_bus_info
= {
773 .name
= TYPE_VIRTIO_MMIO_BUS
,
774 .parent
= TYPE_VIRTIO_BUS
,
775 .instance_size
= sizeof(VirtioBusState
),
776 .class_init
= virtio_mmio_bus_class_init
,
779 static void virtio_mmio_register_types(void)
781 type_register_static(&virtio_mmio_bus_info
);
782 type_register_static(&virtio_mmio_info
);
785 type_init(virtio_mmio_register_types
)