Begin work on true virtio mmio Kill tests/vmrunkernel.c Our makefiles, plus emacs...
[akaros.git] / user / vmm / virtio_ring.c
index 62cd554..ee8a9d3 100644 (file)
@@ -28,6 +28,8 @@
 #include <stdint.h>
 #include <err.h>
 #include <sys/mman.h>
+#include <parlib/uthread.h>
+#include <parlib/ros_debug.h>
 #include <vmm/virtio.h>
 
 #define BAD_RING(_vq, fmt, args...)                            \
@@ -230,7 +232,7 @@ static inline int virtqueue_add_avail(struct virtqueue *_vq,
        canary = vq->vq.num_free;
 
        if (vq->vq.num_free < total_sg) {
-               if (0) fprintf(stderr, "Can't add buf len %i - avail = %i\n",
+               if (1) fprintf(stderr, "Can't add buf len %i - avail = %i\n",
                                 total_sg, vq->vq.num_free);
                /* FIXME: for historical reasons, we force a notify here if
                 * there are outgoing parts to the buffer.  Presumably the
@@ -286,7 +288,7 @@ add_head:
        if (unlikely(vq->num_added == (1 << 16) - 1))
                virtqueue_kick(_vq);
 
-       if (0) fprintf(stderr, "Added buffer head %i to %p\n", head, vq);
+       if (1) fprintf(stderr, "Added buffer head %i to %p\n", head, vq);
        END_USE(vq);
        BUG_ON(vq->vq.num_free > canary);
        return 0;
@@ -476,7 +478,7 @@ void *virtqueue_get_buf_used(struct virtqueue *_vq, unsigned int *len)
        }
 
        if (!more_used(vq)) {
-               if (0) fprintf(stderr, "No more buffers in queue\n");
+               if (1) fprintf(stderr, "No more buffers in queue\n");
                END_USE(vq);
                return NULL;
        }
@@ -682,7 +684,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
 
        /* We assume num is a power of 2. */
        if (num & (num - 1)) {
-               if (0) fprintf(stderr, "Bad virtqueue length %u\n", num);
+               if (1) fprintf(stderr, "Bad virtqueue length %u\n", num);
                exit(1);
        }
 
@@ -854,7 +856,7 @@ int virtio_get_buf_avail_start(struct virtqueue *_vq, uint16_t *last_avail_idx,
        head = vq->vring.avail->ring[i];
 
        if (head >= vq->vring.num) {
-               if (0) fprintf(stderr, "Guest says index %u > %u is available",
+               if (1) fprintf(stderr, "Guest says index %u > %u is available",
                           head, vq->vring.num);
                return -EINVAL;
        }
@@ -868,7 +870,7 @@ int virtio_get_buf_avail_start(struct virtqueue *_vq, uint16_t *last_avail_idx,
        }
 
        if (sgp) {
-               if (0) fprintf(stderr, "entry @%d is %d long\n", head, sglen);
+               if (1) fprintf(stderr, "entry @%d is %d long\n", head, sglen);
 
                sg = calloc(sglen, sizeof(*sg));
                *sgp = sg;
@@ -965,10 +967,24 @@ unsigned int wait_for_vq_desc(struct virtqueue *_vq,
        unsigned int i, head, max;
        struct vring_desc *desc;
        uint16_t last_avail = lg_last_avail(vq);
+       int j = 0;
 
+       if (1){
+                fprintf(stderr, "out_num %p in_num %p\n", out_num, in_num);
+               fprintf(stderr, "va %p vq->vring %p\n", vq, vq->vring);
+       }
        *out_num = *in_num = 0;
        /* There's nothing available? */
+fprintf(stderr, "last_avail %d\n"); 
+       while (! vq->vring.avail) {
+               uthread_sleep(1);
+               fprintf(stderr, "last_avail %p\n", vq->vring.avail); 
+               hexdump(stderr, &(vq->vring), 96);
+       }
+               ;
+fprintf(stderr, "vq %p vq->vring.avail %p idx %d\n", vq, vq->vring.avail, vq->vring.avail);
        while (last_avail == vq->vring.avail->idx) {
+fprintf(stderr, "%d.", j++);
                //uint64_t event;
                if (virtqueue_is_broken(_vq)) {
                        return 0;
@@ -979,29 +995,35 @@ unsigned int wait_for_vq_desc(struct virtqueue *_vq,
                 * Guest about what we've used up to now.
 
                trigger_irq(vq);
+fprintf(stderr, "%d.", j++);
                 */
                /* OK, now we need to know about added descriptors. */
                vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
 
+fprintf(stderr, "%d.", j++);
                /*
                 * They could have slipped one in as we were doing that: make
                 * sure it's written, then check again.
                 */
                mb();
+fprintf(stderr, "%d.", j++);
                if (last_avail != vq->vring.avail->idx) {
                        vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
                        break;
                }
 
+fprintf(stderr, "%d.", j++);
                /* Nothing new?  Wait for eventfd to tell us they refilled. *
                if (read(vq->eventfd, &event, sizeof(event)) != sizeof(event))
                        errx(1, "Event read failed?");
                */
                /* We don't need to be notified again. */
                vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
+fprintf(stderr, "%d.", j++);
        }
 
        /* Check it isn't doing very strange things with descriptor numbers. */
+fprintf(stderr, "out of loop %d.", j++);
        if ((uint16_t)(vq->vring.avail->idx - last_avail) > vq->vring.num)
                errx(1, "Guest moved used index from %u to %u",
                     last_avail, vq->vring.avail->idx);
@@ -1012,6 +1034,7 @@ unsigned int wait_for_vq_desc(struct virtqueue *_vq,
         */
        rmb();
 
+fprintf(stderr, "out of loop %d.", j++);
        /*
         * Grab the next descriptor number they're advertising, and increment
         * the index we've seen.
@@ -1019,13 +1042,16 @@ unsigned int wait_for_vq_desc(struct virtqueue *_vq,
        head = vq->vring.avail->ring[last_avail % vq->vring.num];
        lg_last_avail(vq)++;
 
+fprintf(stderr, "out of loop %d.", j++);
        /* If their number is silly, that's a fatal mistake. */
        if (head >= vq->vring.num)
                errx(1, "Guest says index %u is available", head);
 
+fprintf(stderr, "out of loop %d.", j++);
        /* When we start there are none of either input nor output. */
        *out_num = *in_num = 0;
 
+fprintf(stderr, "out of loop %d.", j++);
        max = vq->vring.num;
        desc = vq->vring.desc;
        i = head;
@@ -1050,7 +1076,10 @@ unsigned int wait_for_vq_desc(struct virtqueue *_vq,
                i = 0;
        }
 
+
+fprintf(stderr, "out of loop %d.", j++);
        do {
+fprintf(stderr, "do loop %d.", j++);
                /* Grab the first descriptor, and check it's OK. */
                iov[*out_num + *in_num].length = desc[i].len;
                iov[*out_num + *in_num].v
@@ -1073,6 +1102,7 @@ unsigned int wait_for_vq_desc(struct virtqueue *_vq,
                        errx(1, "Looped descriptor");
        } while ((i = next_desc(desc, i, max)) != max);
 
+fprintf(stderr, "RETURN head %d\n", head);
        return head;
 }