diff options
Diffstat (limited to 'hw/virtio/virtio-mmio.c')
-rw-r--r-- | hw/virtio/virtio-mmio.c | 54 |
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: |