/*
 * 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 "libqos/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)
{
    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->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;
}
