summaryrefslogtreecommitdiff
path: root/hw/virtio/virtio-mmio.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/virtio/virtio-mmio.c')
-rw-r--r--hw/virtio/virtio-mmio.c54
1 files changed, 44 insertions, 10 deletions
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 883b67d394..962459e64c 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -193,6 +193,10 @@ static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size)
__func__, offset);
return 0;
}
+
+ if (vdev->device_mode) {
+ return virtio_queue_get_ready(vdev, vdev->queue_sel);
+ }
return proxy->vqs[vdev->queue_sel].enabled;
case VIRTIO_MMIO_INTERRUPT_STATUS:
return qatomic_read(&vdev->isr);
@@ -215,21 +219,42 @@ static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size)
* the shared memory doesn't exist
*/
return -1;
+ case VIRTIO_MMIO_QUEUE_NUM:
+ if (vdev->device_mode)
+ return virtio_queue_get_num(vdev, vdev->queue_sel);
+ /* fallthrough */
+ case VIRTIO_MMIO_QUEUE_DESC_LOW:
+ if (vdev->device_mode)
+ return virtio_queue_get_addr(vdev, vdev->queue_sel) & 0xFFFFFFFF;
+ /* fallthrough */
+ case VIRTIO_MMIO_QUEUE_DESC_HIGH:
+ if (vdev->device_mode)
+ return virtio_queue_get_addr(vdev, vdev->queue_sel) >> 32;
+ /* fallthrough */
+ case VIRTIO_MMIO_QUEUE_AVAIL_LOW:
+ if (vdev->device_mode)
+ return virtio_queue_get_avail_addr(vdev, vdev->queue_sel) & 0xFFFFFFFF;
+ /* fallthrough */
+ case VIRTIO_MMIO_QUEUE_AVAIL_HIGH:
+ if (vdev->device_mode)
+ return virtio_queue_get_avail_addr(vdev, vdev->queue_sel) >> 32;
+ /* fallthrough */
+ case VIRTIO_MMIO_QUEUE_USED_LOW:
+ if (vdev->device_mode)
+ return virtio_queue_get_used_addr(vdev, vdev->queue_sel) & 0xFFFFFFFF;
+ /* fallthrough */
+ case VIRTIO_MMIO_QUEUE_USED_HIGH:
+ if (vdev->device_mode)
+ return virtio_queue_get_used_addr(vdev, vdev->queue_sel) >> 32;
+ /* fallthrough */
case VIRTIO_MMIO_DEVICE_FEATURES_SEL:
case VIRTIO_MMIO_DRIVER_FEATURES:
case VIRTIO_MMIO_DRIVER_FEATURES_SEL:
case VIRTIO_MMIO_GUEST_PAGE_SIZE:
case VIRTIO_MMIO_QUEUE_SEL:
- case VIRTIO_MMIO_QUEUE_NUM:
case VIRTIO_MMIO_QUEUE_ALIGN:
case VIRTIO_MMIO_QUEUE_NOTIFY:
case VIRTIO_MMIO_INTERRUPT_ACK:
- case VIRTIO_MMIO_QUEUE_DESC_LOW:
- case VIRTIO_MMIO_QUEUE_DESC_HIGH:
- case VIRTIO_MMIO_QUEUE_AVAIL_LOW:
- case VIRTIO_MMIO_QUEUE_AVAIL_HIGH:
- case VIRTIO_MMIO_QUEUE_USED_LOW:
- case VIRTIO_MMIO_QUEUE_USED_HIGH:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: read of write-only register (0x%" HWADDR_PRIx ")\n",
__func__, offset);
@@ -415,7 +440,10 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
virtio_update_irq(vdev);
break;
case VIRTIO_MMIO_STATUS:
- if (!(value & VIRTIO_CONFIG_S_DRIVER_OK)) {
+ if (vdev->device_mode) {
+ if (!(value & VIRTIO_CONFIG_S_FEATURES_OK))
+ virtio_mmio_stop_ioeventfd(proxy);
+ } else if( !(value & VIRTIO_CONFIG_S_DRIVER_OK)) {
virtio_mmio_stop_ioeventfd(proxy);
}
@@ -427,7 +455,10 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
virtio_set_status(vdev, value & 0xff);
- if (value & VIRTIO_CONFIG_S_DRIVER_OK) {
+ if (vdev->device_mode) {
+ if (value & VIRTIO_CONFIG_S_FEATURES_OK)
+ virtio_mmio_start_ioeventfd(proxy);
+ } else if (value & VIRTIO_CONFIG_S_DRIVER_OK) {
virtio_mmio_start_ioeventfd(proxy);
}
@@ -496,11 +527,14 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
}
proxy->vqs[vdev->queue_sel].used[1] = value;
break;
+ case VIRTIO_MMIO_DEVICE_FEATURES:
+ if (vdev->device_mode)
+ proxy->guest_features[proxy->host_features_sel] = value;
+ /* fallthrough */
case VIRTIO_MMIO_MAGIC_VALUE:
case VIRTIO_MMIO_VERSION:
case VIRTIO_MMIO_DEVICE_ID:
case VIRTIO_MMIO_VENDOR_ID:
- case VIRTIO_MMIO_DEVICE_FEATURES:
case VIRTIO_MMIO_QUEUE_NUM_MAX:
case VIRTIO_MMIO_INTERRUPT_STATUS:
case VIRTIO_MMIO_CONFIG_GENERATION: