virtio console can't support V2, have to use V1.
authorRonald G. Minnich <rminnich@gmail.com>
Wed, 12 Aug 2015 16:59:24 +0000 (09:59 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 2 Nov 2015 23:24:25 +0000 (18:24 -0500)
But also fixed the features crap.

The features stuff is damned confusing but it boils down to
"if you support v2, you have to say you support v1. And if you support
v1 you have to accept v1."

I don't know, I still don't get it all.

Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
tests/vmm/vmrunkernel.c
user/vmm/include/virtio_mmio.h
user/vmm/virtio-mmio.c

index 243b1b0..86a6eeb 100644 (file)
@@ -166,7 +166,7 @@ void *consin(void *arg)
 static struct vqdev vqdev= {
 name: "console",
 dev: VIRTIO_ID_CONSOLE,
-features: VIRTIO_F_VERSION_1,
+device_features: 0, /* Can't do it: linux console device does not support it. VIRTIO_F_VERSION_1*/
 numvqs: 2,
 vqs: {
                {name: "consin", maxqnum: 2, f: &consin, arg: (void *)0},
index 03e89f3..5671c22 100644 (file)
@@ -165,7 +165,7 @@ struct vqdev {
        /* Set up usually as a static initializer */
        char *name;
        uint32_t dev; // e.g. VIRTIO_ID_CONSOLE);
-       uint64_t features;
+       uint64_t device_features, driver_features;
        int numvqs;
        struct vq vqs[];
 };
index 09bead0..b3e9e30 100644 (file)
@@ -46,7 +46,10 @@ int debug_virtio_mmio = 1;
 
 
 #define VIRT_MAGIC 0x74726976 /* 'virt' */
-#define VIRT_VERSION 2
+/* version is a real mess. A real mess. I don't understand it at all. Let's stick with 1, which sucks, 
+ * instead of 2, which seems to be not supported right. I think.
+ */
+#define VIRT_VERSION 1
 #define VIRT_VENDOR 0x554D4551 /* 'QEMU' */
 
 
@@ -58,7 +61,7 @@ typedef struct {
        int pagesize;
        int page_shift;
        int device_features_word; // if this is 1, use the high 32 bits. 
-       int guest_features_sel;
+       int driver_features_word;
        struct vqdev *vqdev;
 } mmiostate;
 
@@ -107,6 +110,7 @@ static uint32_t virtio_mmio_read(uint64_t gpa)
 {
 
        unsigned int offset = gpa - mmio.bar;
+       uint32_t low;
        
        DPRINTF("virtio_mmio_read offset %s 0x%x\n", virtio_names[offset],(int)offset);
 
@@ -169,8 +173,10 @@ fprintf(stderr, "FUCK2 0x%x\n", offset);
     case VIRTIO_MMIO_VENDOR_ID:
            return VIRT_VENDOR;
     case VIRTIO_MMIO_DEVICE_FEATURES:
-       DPRINTF("RETURN 0x%x \n", mmio.vqdev->features);
-           return mmio.vqdev->features >> (mmio.device_features_word) ? 32 : 0;
+       low = mmio.vqdev->device_features >> ((mmio.device_features_word) ? 32 : 0);
+       DPRINTF("RETURN from 0x%x 32 bits of word %s : 0x%x \n", mmio.vqdev->device_features, 
+                               mmio.device_features_word ? "high" : "low", low);
+           return low;
     case VIRTIO_MMIO_QUEUE_NUM_MAX:
            DPRINTF("For q %d, qnum is %d\n", mmio.qsel, mmio.vqdev->vqs[mmio.qsel].qnum);
            return mmio.vqdev->vqs[mmio.qsel].maxqnum;
@@ -239,24 +245,31 @@ static void virtio_mmio_write(uint64_t gpa, uint32_t value)
     case VIRTIO_MMIO_DEVICE_FEATURES:
        if (mmio.device_features_word) {
            /* changing the high word. */
-           low = mmio.vqdev->features;
+           low = mmio.vqdev->device_features;
            high = value;
        } else {
            /* changing the low word. */
-           high = (mmio.vqdev->features >> 32);
+           high = (mmio.vqdev->device_features >> 32);
            low = value;
        }
-       mmio.vqdev->features = ((uint64_t)high << 32) | low;
-       DPRINTF("Set VIRTIO_MMIO_DEVICE_FEATURES to %p\n", mmio.vqdev->features);
+       mmio.vqdev->device_features = ((uint64_t)high << 32) | low;
+       DPRINTF("Set VIRTIO_MMIO_DEVICE_FEATURES to %p\n", mmio.vqdev->device_features);
        break;
-       /* what's the difference here? Maybe FEATURES is the one you offer. */
     case VIRTIO_MMIO_DRIVER_FEATURES:
-        if (!mmio.guest_features_sel) {
-            mmio.guest_features_sel = value;
-        }
+       if (mmio.driver_features_word) {
+           /* changing the high word. */
+           low = mmio.vqdev->driver_features;
+           high = value;
+       } else {
+           /* changing the low word. */
+           high = (mmio.vqdev->driver_features >> 32);
+           low = value;
+       }
+       mmio.vqdev->driver_features = ((uint64_t)high << 32) | low;
+       DPRINTF("Set VIRTIO_MMIO_DRIVER_FEATURES to %p\n", mmio.vqdev->driver_features);
         break;
     case VIRTIO_MMIO_DRIVER_FEATURES_SEL:
-           mmio.guest_features_sel = value;
+           mmio.driver_features_word = value;
         break;
 
     case VIRTIO_MMIO_GUEST_PAGE_SIZE: