From 8b896092602dfd06bd06c784cec8639ac082316a Mon Sep 17 00:00:00 2001 From: Jian Jun Chen Date: Thu, 29 Mar 2018 09:23:46 +0800 Subject: [PATCH] dm/VBS-U: expand data structures to support virtio 1.0 Struct virtio_base and struct virtio_vq_info are expanded to support virtio 1.0 framework. The BAR layouts of virtio legacy/transitional/ modern are introduced as well. Signed-off-by: Jian Jun Chen Reviewed-by: Hao Li Reviewed-by: Zhao Yakui Acked-by: Eddie Dong --- hw/pci/virtio/virtio.c | 10 +++++++++ include/virtio.h | 49 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/hw/pci/virtio/virtio.c b/hw/pci/virtio/virtio.c index 119655c0e..e715e9bc5 100644 --- a/hw/pci/virtio/virtio.c +++ b/hw/pci/virtio/virtio.c @@ -96,6 +96,13 @@ virtio_reset_dev(struct virtio_base *base) vq->save_used = 0; vq->pfn = 0; vq->msix_idx = VIRTIO_MSI_NO_VECTOR; + vq->gpa_desc[0] = 0; + vq->gpa_desc[1] = 0; + vq->gpa_avail[0] = 0; + vq->gpa_avail[1] = 0; + vq->gpa_used[0] = 0; + vq->gpa_used[1] = 0; + vq->enabled = 0; } base->negotiated_caps = 0; base->curq = 0; @@ -104,6 +111,9 @@ virtio_reset_dev(struct virtio_base *base) pci_lintr_deassert(base->dev); base->isr = 0; base->msix_cfg_idx = VIRTIO_MSI_NO_VECTOR; + base->device_feature_select = 0; + base->driver_feature_select = 0; + base->config_generation = 0; } /* diff --git a/include/virtio.h b/include/virtio.h index 7c7d529fd..33a03b7d3 100644 --- a/include/virtio.h +++ b/include/virtio.h @@ -378,6 +378,43 @@ struct virtio_vq_info; #define VIRTIO_EVENT_IDX 0x02 /* use the event-index values */ #define VIRTIO_BROKED 0x08 /* ??? */ +/* + * virtio pci device bar layout + * 0 : legacy PIO bar + * 1 : MSIX bar + * 2 : modern PIO bar, used as notify + * 4+5 : modern 64-bit MMIO bar + * + * pci bar layout for legacy/modern/transitional devices + * legacy : (0) + (1) + * modern (no pio notify) : (1) + (4+5) + * modern (with pio notify) : (1) + (2) + (4+5) + * transitional (no pio notify) : (0) + (1) + (4+5) + * transitional (with pio notify) : (0) + (1) + (2) + (4+5) + */ +#define VIRTIO_LEGACY_PIO_BAR_IDX 0 +#define VIRTIO_MODERN_PIO_BAR_IDX 2 +#define VIRTIO_MODERN_MMIO_BAR_IDX 4 + +/* + * region layout in modern mmio bar + * one 4KB region for one capability + */ +#define VIRTIO_CAP_COMMON_OFFSET 0x0000 +#define VIRTIO_CAP_COMMON_SIZE 0x1000 +#define VIRTIO_CAP_ISR_OFFSET 0x1000 +#define VIRTIO_CAP_ISR_SIZE 0x1000 +#define VIRTIO_CAP_DEVICE_OFFSET 0x2000 +#define VIRTIO_CAP_DEVICE_SIZE 0x1000 +#define VIRTIO_CAP_NOTIFY_OFFSET 0x3000 +#define VIRTIO_CAP_NOTIFY_SIZE 0x1000 + +#define VIRTIO_MODERN_MEM_BAR_SIZE (VIRTIO_CAP_NOTIFY_OFFSET + \ + VIRTIO_CAP_NOTIFY_SIZE) + +/* 4-byte notify register for one virtqueue */ +#define VIRTIO_MODERN_NOTIFY_OFF_MULT 4 + /* Common configuration */ #define VIRTIO_PCI_CAP_COMMON_CFG 1 /* Notifications */ @@ -467,12 +504,18 @@ struct virtio_base { int flags; /**< VIRTIO_* flags from above */ pthread_mutex_t *mtx; /**< POSIX mutex, if any */ struct pci_vdev *dev; /**< PCI device instance */ - uint32_t negotiated_caps; /**< negotiated capabilities */ + uint64_t negotiated_caps; /**< negotiated capabilities */ struct virtio_vq_info *queues; /**< one per nvq */ int curq; /**< current queue */ uint8_t status; /**< value from last status write */ uint8_t isr; /**< ISR flags, if not MSI-X */ uint16_t msix_cfg_idx; /**< MSI-X vector for config event */ + uint32_t legacy_pio_bar_idx; /**< index of legacy pio bar */ + uint32_t modern_pio_bar_idx; /**< index of modern pio bar */ + uint32_t modern_mmio_bar_idx; /**< index of modern mmio bar */ + uint8_t config_generation; /**< configuration generation */ + uint32_t device_feature_select; /**< current selected device feature */ + uint32_t driver_feature_select; /**< current selected guest feature */ }; #define VIRTIO_BASE_LOCK(vb) \ @@ -553,6 +596,10 @@ struct virtio_vq_info { volatile struct vring_used *used; /**< the "used" ring */ + uint32_t gpa_desc[2]; /**< gpa of descriptors */ + uint32_t gpa_avail[2]; /**< gpa of avail_ring */ + uint32_t gpa_used[2]; /**< gpa of used_ring */ + bool enabled; /**< whether the virtqueue is enabled */ }; /* as noted above, these are sort of backwards, name-wise */