aboutsummaryrefslogtreecommitdiff
path: root/tests/libqos/virtio.c
diff options
context:
space:
mode:
authorMarc MarĂ­ <marc.mari.barcelo@gmail.com>2014-09-01 12:07:57 +0200
committerStefan Hajnoczi <stefanha@redhat.com>2014-09-08 11:12:43 +0100
commitf294b029aa2beb1c67116e04bff5d331f0b18288 (patch)
treec310d6a49c2e00e2316d8cbac5400aab2838642a /tests/libqos/virtio.c
parentbf3c63d2010c5ef52f8b988bee2a1486a056795f (diff)
libqos: Added indirect descriptor support to virtio implementation
Add functions necessary for working with indirect descriptors. Add test using new functions. Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Marc MarĂ­ <marc.mari.barcelo@gmail.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'tests/libqos/virtio.c')
-rw-r--r--tests/libqos/virtio.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index de92642819..b1cab1f699 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -116,6 +116,51 @@ void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr)
writew(vq->used, 0);
}
+QVRingIndirectDesc *qvring_indirect_desc_setup(QVirtioDevice *d,
+ QGuestAllocator *alloc, uint16_t elem)
+{
+ int i;
+ QVRingIndirectDesc *indirect = g_malloc(sizeof(*indirect));
+
+ indirect->index = 0;
+ indirect->elem = elem;
+ indirect->desc = guest_alloc(alloc, sizeof(QVRingDesc)*elem);
+
+ for (i = 0; i < elem - 1; ++i) {
+ /* indirect->desc[i].addr */
+ writeq(indirect->desc + (16 * i), 0);
+ /* indirect->desc[i].flags */
+ writew(indirect->desc + (16 * i) + 12, QVRING_DESC_F_NEXT);
+ /* indirect->desc[i].next */
+ writew(indirect->desc + (16 * i) + 14, i + 1);
+ }
+
+ return indirect;
+}
+
+void qvring_indirect_desc_add(QVRingIndirectDesc *indirect, uint64_t data,
+ uint32_t len, bool write)
+{
+ uint16_t flags;
+
+ g_assert_cmpint(indirect->index, <, indirect->elem);
+
+ flags = readw(indirect->desc + (16 * indirect->index) + 12);
+
+ if (write) {
+ flags |= QVRING_DESC_F_WRITE;
+ }
+
+ /* indirect->desc[indirect->index].addr */
+ writeq(indirect->desc + (16 * indirect->index), data);
+ /* indirect->desc[indirect->index].len */
+ writel(indirect->desc + (16 * indirect->index) + 8, len);
+ /* indirect->desc[indirect->index].flags */
+ writew(indirect->desc + (16 * indirect->index) + 12, flags);
+
+ indirect->index++;
+}
+
uint32_t qvirtqueue_add(QVirtQueue *vq, uint64_t data, uint32_t len, bool write,
bool next)
{
@@ -140,6 +185,25 @@ uint32_t qvirtqueue_add(QVirtQueue *vq, uint64_t data, uint32_t len, bool write,
return vq->free_head++; /* Return and increase, in this order */
}
+uint32_t qvirtqueue_add_indirect(QVirtQueue *vq, QVRingIndirectDesc *indirect)
+{
+ g_assert(vq->indirect);
+ g_assert_cmpint(vq->size, >=, indirect->elem);
+ g_assert_cmpint(indirect->index, ==, indirect->elem);
+
+ vq->num_free--;
+
+ /* vq->desc[vq->free_head].addr */
+ writeq(vq->desc + (16 * vq->free_head), indirect->desc);
+ /* vq->desc[vq->free_head].len */
+ writel(vq->desc + (16 * vq->free_head) + 8,
+ sizeof(QVRingDesc) * indirect->elem);
+ /* vq->desc[vq->free_head].flags */
+ writew(vq->desc + (16 * vq->free_head) + 12, QVRING_DESC_F_INDIRECT);
+
+ return vq->free_head++; /* Return and increase, in this order */
+}
+
void qvirtqueue_kick(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq,
uint32_t free_head)
{