[SeaBIOS] [PATCH v3 10/25] virtio: make features 64bit, support version 1.0 features

Gerd Hoffmann kraxel at redhat.com
Wed Jul 1 16:40:55 CEST 2015


Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
---
 src/hw/virtio-blk.c |  2 +-
 src/hw/virtio-pci.c | 33 +++++++++++++++++++++++++++++++++
 src/hw/virtio-pci.h | 12 +++---------
 3 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c
index 1a13129..8378a34 100644
--- a/src/hw/virtio-blk.c
+++ b/src/hw/virtio-blk.c
@@ -123,7 +123,7 @@ init_virtio_blk(struct pci_device *pci)
     struct virtio_blk_config cfg;
     vp_get(&vdrive->vp, 0, &cfg, sizeof(cfg));
 
-    u32 f = vp_get_features(&vdrive->vp);
+    u64 f = vp_get_features(&vdrive->vp);
     vdrive->drive.blksize = (f & (1 << VIRTIO_BLK_F_BLK_SIZE)) ?
         cfg.blk_size : DISK_SECTOR_SIZE;
 
diff --git a/src/hw/virtio-pci.c b/src/hw/virtio-pci.c
index 3c8fb7b..5ae6a76 100644
--- a/src/hw/virtio-pci.c
+++ b/src/hw/virtio-pci.c
@@ -24,6 +24,39 @@
 #include "virtio-pci.h"
 #include "virtio-ring.h"
 
+u64 vp_get_features(struct vp_device *vp)
+{
+    u32 f0, f1;
+
+    if (vp->use_modern) {
+        vp_write(&vp->common, virtio_pci_common_cfg, device_feature_select, 0);
+        f0 = vp_read(&vp->common, virtio_pci_common_cfg, device_feature);
+        vp_write(&vp->common, virtio_pci_common_cfg, device_feature_select, 1);
+        f1 = vp_read(&vp->common, virtio_pci_common_cfg, device_feature);
+    } else {
+        f0 = vp_read(&vp->legacy, virtio_pci_legacy, host_features);
+        f1 = 0;
+    }
+    return ((u64)f1 << 32) | f0;
+}
+
+void vp_set_features(struct vp_device *vp, u64 features)
+{
+    u32 f0, f1;
+
+    f0 = features;
+    f1 = features >> 32;
+
+    if (vp->use_modern) {
+        vp_write(&vp->common, virtio_pci_common_cfg, guest_feature_select, 0);
+        vp_write(&vp->common, virtio_pci_common_cfg, guest_feature, f0);
+        vp_write(&vp->common, virtio_pci_common_cfg, guest_feature_select, 1);
+        vp_write(&vp->common, virtio_pci_common_cfg, guest_feature, f1);
+    } else {
+        vp_write(&vp->legacy, virtio_pci_legacy, guest_features, f0);
+    }
+}
+
 int vp_find_vq(struct vp_device *vp, int queue_index,
                struct vring_virtqueue **p_vq)
 {
diff --git a/src/hw/virtio-pci.h b/src/hw/virtio-pci.h
index f7510f2..962d6c0 100644
--- a/src/hw/virtio-pci.h
+++ b/src/hw/virtio-pci.h
@@ -125,6 +125,7 @@ struct vp_cap {
 struct vp_device {
     unsigned int ioaddr;
     struct vp_cap common, notify, isr, device, legacy;
+    u8 use_modern;
 };
 
 static inline u64 _vp_read(struct vp_cap *cap, u32 offset, u8 size)
@@ -213,15 +214,8 @@ static inline void _vp_write(struct vp_cap *cap, u32 offset, u8 size, u64 var)
     _vp_write(_cap, offsetof(_struct, _field),          \
              sizeof(((_struct *)0)->_field), _var)
 
-static inline u32 vp_get_features(struct vp_device *vp)
-{
-    return inl(GET_LOWFLAT(vp->ioaddr) + VIRTIO_PCI_HOST_FEATURES);
-}
-
-static inline void vp_set_features(struct vp_device *vp, u32 features)
-{
-    outl(features, GET_LOWFLAT(vp->ioaddr) + VIRTIO_PCI_GUEST_FEATURES);
-}
+u64 vp_get_features(struct vp_device *vp);
+void vp_set_features(struct vp_device *vp, u64 features);
 
 static inline void vp_get(struct vp_device *vp, unsigned offset,
                      void *buf, unsigned len)
-- 
1.8.3.1




More information about the SeaBIOS mailing list