/*
 * libqos virtio driver
 *
 * Copyright (c) 2014 Marc Marí
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qemu/bswap.h"
#include "../libqtest.h"
#include "virtio.h"
#include "standard-headers/linux/virtio_config.h"
#include "standard-headers/linux/virtio_ring.h"

/*
 * qtest_readX/writeX() functions transfer host endian from/to guest endian.
 * This works great for Legacy VIRTIO devices where we need guest endian
 * accesses.  For VIRTIO 1.0 the vring is little-endian so the automatic guest
 * endianness conversion is not wanted.
 *
 * The following qvirtio_readX/writeX() functions handle Legacy and VIRTIO 1.0
 * accesses seamlessly.
 */
static uint16_t qvirtio_readw(QVirtioDevice *d, QTestState *qts, uint64_t addr)
{
    uint16_t val = qtest_readw(qts, addr);

    if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) {
        val = bswap16(val);
    }
    return val;
}

static uint32_t qvirtio_readl(QVirtioDevice *d, QTestState *qts, uint64_t addr)
{
    uint32_t val = qtest_readl(qts, addr);

    if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) {
        val = bswap32(val);
    }
    return val;
}

static void qvirtio_writew(QVirtioDevice *d, QTestState *qts,
                           uint64_t addr, uint16_t val)
{
    if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) {
        val = bswap16(val);
    }
    qtest_writew(qts, addr, val);
}

static void qvirtio_writel(QVirtioDevice *d, QTestState *qts,
                           uint64_t addr, uint32_t val)
{
    if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) {
        val = bswap32(val);
    }
    qtest_writel(qts, addr, val);
}

static void qvirtio_writeq(QVirtioDevice *d, QTestState *qts,
                           uint64_t addr, uint64_t val)
{
    if (d->features & (1ull << VIRTIO_F_VERSION_1) && qtest_big_endian(qts)) {
        val = bswap64(val);
    }
    qtest_writeq(qts, addr, val);
}

uint8_t qvirtio_config_readb(QVirtioDevice *d, uint64_t addr)
{
    g_assert_true(d->features_negotiated);
    return d->bus->config_readb(d, addr);
}

uint16_t qvirtio_config_readw(QVirtioDevice *d, uint64_t addr)
{
    g_assert_true(d->features_negotiated);
    return d->bus->config_readw(d, addr);
}

uint32_t qvirtio_config_readl(QVirtioDevice *d, uint64_t addr)
{
    g_assert_true(d->features_negotiated);
    return d->bus->config_readl(d, addr);
}

uint64_t qvirtio_config_readq(QVirtioDevice *d, uint64_t addr)
{
    g_assert_true(d->features_negotiated);
    return d->bus->config_readq(d, addr);
}

uint64_t qvirtio_get_features(QVirtioDevice *d)
{
    return d->bus->get_features(d);
}

void qvirtio_set_features(QVirtioDevice *d, uint64_t features)
{
    g_assert(!(features & QVIRTIO_F_BAD_FEATURE));

    d->features = features;
    d->bus->set_features(d, features);

    /*
     * This could be a separate function for drivers that want to access
     * configuration space before setting FEATURES_OK, but no existing users
     * need that and it's less code for callers if this is done implicitly.
     */
    if (features & (1ull << VIRTIO_F_VERSION_1)) {
        uint8_t status = d->bus->get_status(d) |
                         VIRTIO_CONFIG_S_FEATURES_OK;

        d->bus->set_status(d, status);
        g_assert_cmphex(d->bus->get_status(d), ==, status);
    }

    d->features_negotiated = true;
}

QVirtQueue *qvirtqueue_setup(QVirtioDevice *d,
                             QGuestAllocator *alloc, uint16_t index)
{
    g_assert_true(d->features_negotiated);
    return d->bus->virtqueue_setup(d, alloc, index);
}

void qvirtqueue_cleanup(const QVirtioBus *bus, QVirtQueue *vq,
                        QGuestAllocator *alloc)
{
    return bus->virtqueue_cleanup(vq, alloc);
}

void qvirtio_reset(QVirtioDevice *d)
{
    d->bus->set_status(d, 0);
    g_assert_cmphex(d->bus->get_status(d), ==, 0);
    d->features_negotiated = false;
}

void qvirtio_set_acknowledge(QVirtioDevice *d)
{
    d->bus->set_status(d, d->bus->get_status(d) | VIRTIO_CONFIG_S_ACKNOWLEDGE);
    g_assert_cmphex(d->bus->get_status(d), ==, VIRTIO_CONFIG_S_ACKNOWLEDGE);
}

void qvirtio_set_driver(QVirtioDevice *d)
{
    d->bus->set_status(d, d->bus->get_status(d) | VIRTIO_CONFIG_S_DRIVER);
    g_assert_cmphex(d->bus->get_status(d), ==,
                    VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_ACKNOWLEDGE);
}

void qvirtio_set_driver_ok(QVirtioDevice *d)
{
    d->bus->set_status(d, d->bus->get_status(d) | VIRTIO_CONFIG_S_DRIVER_OK);
    g_assert_cmphex(d->bus->get_status(d), ==, VIRTIO_CONFIG_S_DRIVER_OK |
                    VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_ACKNOWLEDGE |
                    (d->features & (1ull << VIRTIO_F_VERSION_1) ?
                     VIRTIO_CONFIG_S_FEATURES_OK : 0));
}

void qvirtio_wait_queue_isr(QTestState *qts, QVirtioDevice *d,
                            QVirtQueue *vq, gint64 timeout_us)
{
    gint64 start_time = g_get_monotonic_time();

    for (;;) {
        qtest_clock_step(qts, 100);
        if (d->bus->get_queue_isr_status(d, vq)) {
            return;
        }
        g_assert(g_get_monotonic_time() - start_time <= timeout_us);
    }
}

/* Wait for the status byte at given guest memory address to be set
 *
 * The virtqueue interrupt must not be raised, making this useful for testing
 * event_index functionality.
 */
uint8_t qvirtio_wait_status_byte_no_isr(QTestState *qts, QVirtioDevice *d,
                                        QVirtQueue *vq,
                                        uint64_t addr,
                                        gint64 timeout_us)
{
    gint64 start_time = g_get_monotonic_time();
    uint8_t val;

    while ((val = qtest_readb(qts, addr)) == 0xff) {
        qtest_clock_step(qts, 100);
        g_assert(!d->bus->get_queue_isr_status(d, vq));
        g_assert(g_get_monotonic_time() - start_time <= timeout_us);
    }
    return val;
}

/*
 * qvirtio_wait_used_elem:
 * @desc_idx: The next expected vq->desc[] index in the used ring
 * @len: A pointer that is filled with the length written into the buffer, may
 *       be NULL
 * @timeout_us: How many microseconds to wait before failing
 *
 * This function waits for the next completed request on the used ring.
 */
void qvirtio_wait_used_elem(QTestState *qts, QVirtioDevice *d,
                            QVirtQueue *vq,
                            uint32_t desc_idx,
                            uint32_t *len,
                            gint64 timeout_us)
{
    gint64 start_time = g_get_monotonic_time();

    for (;;) {
        uint32_t got_desc_idx;

        qtest_clock_step(qts, 100);

        if (d->bus->get_queue_isr_status(d, vq) &&
            qvirtqueue_get_buf(qts, vq, &got_desc_idx, len)) {
            g_assert_cmpint(got_desc_idx, ==, desc_idx);
            return;
        }

        g_assert(g_get_monotonic_time() - start_time <= timeout_us);
    }
}

void qvirtio_wait_config_isr(QVirtioDevice *d, gint64 timeout_us)
{
    d->bus->wait_config_isr_status(d, timeout_us);
}

void qvring_init(QTestState *qts, const QGuestAllocator *alloc, QVirtQueue *vq,
                 uint64_t addr)
{
    int i;

    vq->desc = addr;
    vq->avail = vq->desc + vq->size * sizeof(struct vring_desc);
    vq->used = (uint64_t)((vq->avail + sizeof(uint16_t) * (3 + vq->size)
        + vq->align - 1) & ~(vq->align - 1));

    for (i = 0; i < vq->size - 1; i++) {
        /* vq->desc[i].addr */
        qvirtio_writeq(vq->vdev, qts, vq->desc + (16 * i), 0);
        /* vq->desc[i].next */
        qvirtio_writew(vq->vdev, qts, vq->desc + (16 * i) + 14, i + 1);
    }

    /* vq->avail->flags */
    qvirtio_writew(vq->vdev, qts, vq->avail, 0);
    /* vq->avail->idx */
    qvirtio_writew(vq->vdev, qts, vq->avail + 2, 0);
    /* vq->avail->used_event */
    qvirtio_writew(vq->vdev, qts, vq->avail + 4 + (2 * vq->size), 0);

    /* vq->used->flags */
    qvirtio_writew(vq->vdev, qts, vq->used, 0);
    /* vq->used->idx */
    qvirtio_writew(vq->vdev, qts, vq->used + 2, 0);
    /* vq->used->avail_event */
    qvirtio_writew(vq->vdev, qts, vq->used + 2 +
                   sizeof(struct vring_used_elem) * vq->size, 0);
}

QVRingIndirectDesc *qvring_indirect_desc_setup(QTestState *qs, 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(struct vring_desc) * elem);

    for (i = 0; i < elem - 1; ++i) {
        /* indirect->desc[i].addr */
        qvirtio_writeq(d, qs, indirect->desc + (16 * i), 0);
        /* indirect->desc[i].flags */
        qvirtio_writew(d, qs, indirect->desc + (16 * i) + 12,
                       VRING_DESC_F_NEXT);
        /* indirect->desc[i].next */
        qvirtio_writew(d, qs, indirect->desc + (16 * i) + 14, i + 1);
    }

    return indirect;
}

void qvring_indirect_desc_add(QVirtioDevice *d, QTestState *qts,
                              QVRingIndirectDesc *indirect,
                              uint64_t data, uint32_t len, bool write)
{
    uint16_t flags;

    g_assert_cmpint(indirect->index, <, indirect->elem);

    flags = qvirtio_readw(d, qts, indirect->desc +
                                  (16 * indirect->index) + 12);

    if (write) {
        flags |= VRING_DESC_F_WRITE;
    }

    /* indirect->desc[indirect->index].addr */
    qvirtio_writeq(d, qts, indirect->desc + (16 * indirect->index), data);
    /* indirect->desc[indirect->index].len */
    qvirtio_writel(d, qts, indirect->desc + (16 * indirect->index) + 8, len);
    /* indirect->desc[indirect->index].flags */
    qvirtio_writew(d, qts, indirect->desc + (16 * indirect->index) + 12,
                   flags);

    indirect->index++;
}

uint32_t qvirtqueue_add(QTestState *qts, QVirtQueue *vq, uint64_t data,
                        uint32_t len, bool write, bool next)
{
    uint16_t flags = 0;
    vq->num_free--;

    if (write) {
        flags |= VRING_DESC_F_WRITE;
    }

    if (next) {
        flags |= VRING_DESC_F_NEXT;
    }

    /* vq->desc[vq->free_head].addr */
    qvirtio_writeq(vq->vdev, qts, vq->desc + (16 * vq->free_head), data);
    /* vq->desc[vq->free_head].len */
    qvirtio_writel(vq->vdev, qts, vq->desc + (16 * vq->free_head) + 8, len);
    /* vq->desc[vq->free_head].flags */
    qvirtio_writew(vq->vdev, qts, vq->desc + (16 * vq->free_head) + 12, flags);

    return vq->free_head++; /* Return and increase, in this order */
}

uint32_t qvirtqueue_add_indirect(QTestState *qts, 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 */
    qvirtio_writeq(vq->vdev, qts, vq->desc + (16 * vq->free_head),
                   indirect->desc);
    /* vq->desc[vq->free_head].len */
    qvirtio_writel(vq->vdev, qts, vq->desc + (16 * vq->free_head) + 8,
                   sizeof(struct vring_desc) * indirect->elem);
    /* vq->desc[vq->free_head].flags */
    qvirtio_writew(vq->vdev, qts, vq->desc + (16 * vq->free_head) + 12,
                   VRING_DESC_F_INDIRECT);

    return vq->free_head++; /* Return and increase, in this order */
}

void qvirtqueue_kick(QTestState *qts, QVirtioDevice *d, QVirtQueue *vq,
                     uint32_t free_head)
{
    /* vq->avail->idx */
    uint16_t idx = qvirtio_readw(d, qts, vq->avail + 2);
    /* vq->used->flags */
    uint16_t flags;
    /* vq->used->avail_event */
    uint16_t avail_event;

    /* vq->avail->ring[idx % vq->size] */
    qvirtio_writew(d, qts, vq->avail + 4 + (2 * (idx % vq->size)), free_head);
    /* vq->avail->idx */
    qvirtio_writew(d, qts, vq->avail + 2, idx + 1);

    /* Must read after idx is updated */
    flags = qvirtio_readw(d, qts, vq->avail);
    avail_event = qvirtio_readw(d, qts, vq->used + 4 +
                                sizeof(struct vring_used_elem) * vq->size);

    /* < 1 because we add elements to avail queue one by one */
    if ((flags & VRING_USED_F_NO_NOTIFY) == 0 &&
                            (!vq->event || (uint16_t)(idx-avail_event) < 1)) {
        d->bus->virtqueue_kick(d, vq);
    }
}

/*
 * qvirtqueue_get_buf:
 * @desc_idx: A pointer that is filled with the vq->desc[] index, may be NULL
 * @len: A pointer that is filled with the length written into the buffer, may
 *       be NULL
 *
 * This function gets the next used element if there is one ready.
 *
 * Returns: true if an element was ready, false otherwise
 */
bool qvirtqueue_get_buf(QTestState *qts, QVirtQueue *vq, uint32_t *desc_idx,
                        uint32_t *len)
{
    uint16_t idx;
    uint64_t elem_addr, addr;

    idx = qvirtio_readw(vq->vdev, qts,
                        vq->used + offsetof(struct vring_used, idx));
    if (idx == vq->last_used_idx) {
        return false;
    }

    elem_addr = vq->used +
        offsetof(struct vring_used, ring) +
        (vq->last_used_idx % vq->size) *
        sizeof(struct vring_used_elem);

    if (desc_idx) {
        addr = elem_addr + offsetof(struct vring_used_elem, id);
        *desc_idx = qvirtio_readl(vq->vdev, qts, addr);
    }

    if (len) {
        addr = elem_addr + offsetof(struct vring_used_elem, len);
        *len = qvirtio_readw(vq->vdev, qts, addr);
    }

    vq->last_used_idx++;
    return true;
}

void qvirtqueue_set_used_event(QTestState *qts, QVirtQueue *vq, uint16_t idx)
{
    g_assert(vq->event);

    /* vq->avail->used_event */
    qvirtio_writew(vq->vdev, qts, vq->avail + 4 + (2 * vq->size), idx);
}

void qvirtio_start_device(QVirtioDevice *vdev)
{
    qvirtio_reset(vdev);
    qvirtio_set_acknowledge(vdev);
    qvirtio_set_driver(vdev);
}

bool qvirtio_is_big_endian(QVirtioDevice *d)
{
    return d->big_endian;
}
