/*
 * Copyright 2017, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
 * See "LICENSE_GPLv2.txt" for details.
 *
 * @TAG(DATA61_GPL)
 */

#include <autoconf.h>
#include <sel4vmm/gen_config.h>

#include <string.h>

#include <vmm/driver/virtio_emul.h>
#include <ethdrivers/virtio/virtio_pci.h>
#include <ethdrivers/virtio/virtio_net.h>
#include <ethdrivers/virtio/virtio_ring.h>
#include <ethdrivers/virtio/virtio_config.h>

#define RX_QUEUE 0
#define TX_QUEUE 1

#define BUF_SIZE 2048

typedef struct ethif_virtio_emul_internal {
    struct eth_driver driver;
    int status;
    uint8_t mac[6];
    uint16_t queue;
    struct vring vring[2];
    uint16_t queue_size[2];
    uint32_t queue_pfn[2];
    uint16_t last_idx[2];
    vspace_t guest_vspace;
    ps_dma_man_t dma_man;
} ethif_virtio_emul_internal_t;

typedef struct emul_tx_cookie {
    uint16_t desc_head;
    void *vaddr;
} emul_tx_cookie_t;

static int read_guest_mem(uintptr_t phys, void *vaddr, size_t size, size_t offset, void *cookie) {
    memcpy(cookie + offset, vaddr, size);
    return 0;
}

static int write_guest_mem(uintptr_t phys, void *vaddr, size_t size, size_t offset, void *cookie) {
    memcpy(vaddr, cookie + offset, size);
    return 0;
}

static uint16_t ring_avail_idx(ethif_virtio_emul_t *emul, struct vring *vring) {
    uint16_t idx;
    vmm_guest_vspace_touch(&emul->internal->guest_vspace, (uintptr_t)&vring->avail->idx, sizeof(vring->avail->idx), read_guest_mem, &idx);
    return idx;
}

static uint16_t ring_avail(ethif_virtio_emul_t *emul, struct vring *vring, uint16_t idx) {
    uint16_t elem;
    vmm_guest_vspace_touch(&emul->internal->guest_vspace, (uintptr_t)&(vring->avail->ring[idx % vring->num]), sizeof(elem), read_guest_mem, &elem);
    return elem;
}

static struct vring_desc ring_desc(ethif_virtio_emul_t *emul, struct vring *vring, uint16_t idx) {
    struct vring_desc desc;
    vmm_guest_vspace_touch(&emul->internal->guest_vspace, (uintptr_t)&(vring->desc[idx]), sizeof(desc), read_guest_mem, &desc);
    return desc;
}

static void ring_used_add(ethif_virtio_emul_t *emul, struct vring *vring, struct vring_used_elem elem) {
    uint16_t guest_idx;
    vmm_guest_vspace_touch(&emul->internal->guest_vspace, (uintptr_t)&vring->used->idx, sizeof(vring->used->idx), read_guest_mem, &guest_idx);
    vmm_guest_vspace_touch(&emul->internal->guest_vspace, (uintptr_t)&vring->used->ring[guest_idx % vring->num], sizeof(elem), write_guest_mem, &elem);
    guest_idx++;
    vmm_guest_vspace_touch(&emul->internal->guest_vspace, (uintptr_t)&vring->used->idx, sizeof(vring->used->idx), write_guest_mem, &guest_idx);
}

static uintptr_t emul_allocate_rx_buf(void *iface, size_t buf_size, void **cookie) {
    ethif_virtio_emul_t *emul = (ethif_virtio_emul_t*)iface;
    ethif_virtio_emul_internal_t *net = emul->internal;
    if (buf_size > BUF_SIZE) {
        return 0;
    }
    void *vaddr = ps_dma_alloc(&net->dma_man, BUF_SIZE, net->driver.dma_alignment, 1, PS_MEM_NORMAL);
    if (!vaddr) {
        return 0;
    }
    uintptr_t phys = ps_dma_pin(&net->dma_man, vaddr, BUF_SIZE);
    *cookie = vaddr;
    return phys;
}

static void emul_rx_complete(void *iface, unsigned int num_bufs, void **cookies, unsigned int *lens) {
    ethif_virtio_emul_t *emul = (ethif_virtio_emul_t*)iface;
    ethif_virtio_emul_internal_t *net = emul->internal;
    unsigned int tot_len = 0;
    int i;
    struct vring *vring = &net->vring[RX_QUEUE];
    for (i = 0; i < num_bufs; i++) {
        tot_len += lens[i];
    }
    /* grab the next receive chain */
    struct virtio_net_hdr virtio_hdr;
    memset(&virtio_hdr, 0, sizeof(virtio_hdr));
    uint16_t guest_idx = ring_avail_idx(emul, vring);
    uint16_t idx = net->last_idx[RX_QUEUE];
    if (idx != guest_idx) {
        /* total length of the written packet so far */
        size_t tot_written = 0;
        /* amount of the current descriptor written */
        size_t desc_written = 0;
        /* how much we have written of the current buffer */
        size_t buf_written = 0;
        /* the current buffer. -1 indicates the virtio net buffer */
        int current_buf = -1;
        uint16_t desc_head = ring_avail(emul, vring, idx);
        /* start walking the descriptors */
        struct vring_desc desc;
        uint16_t desc_idx = desc_head;
        do {
            desc = ring_desc(emul, vring, desc_idx);
            /* determine how much we can copy */
            uint32_t copy;
            void *buf_base = NULL;
            if (current_buf == -1) {
                copy = sizeof(struct virtio_net_hdr) - buf_written;
                buf_base = &virtio_hdr;
            } else {
                copy = lens[current_buf] - buf_written;
                buf_base = cookies[current_buf];
            }
            copy = MIN(copy, desc.len - desc_written);
            /* copy it */
            vmm_guest_vspace_touch(&net->guest_vspace, (uintptr_t)desc.addr + desc_written, copy, write_guest_mem, buf_base + buf_written);
            /* update amounts */
            tot_written += copy;
            desc_written += copy;
            buf_written += copy;
            /* see what's gone over */
            if (desc_written == desc.len) {
                if (!desc.flags & VRING_DESC_F_NEXT) {
                    /* descriptor chain is too short to hold the whole packet.
                     * just truncate */
                    break;
                }
                desc_idx = desc.next;
                desc_written = 0;
            }
            if (current_buf == -1) {
                if (buf_written == sizeof(struct virtio_net_hdr)) {
                    current_buf++;
                    buf_written = 0;
                }
            } else {
                if (buf_written == lens[current_buf]) {
                    current_buf++;
                    buf_written = 0;
                }
            }
        } while (current_buf < num_bufs);
        /* now put it in the used ring */
        struct vring_used_elem used_elem = {desc_head, tot_written};
        ring_used_add(emul, vring, used_elem);

        /* record that we've used this descriptor chain now */
        net->last_idx[RX_QUEUE]++;
        /* notify the guest that there is something in its used ring */
        net->driver.i_fn.raw_handleIRQ(&net->driver, 0);
    }
    for (i = 0; i < num_bufs; i++) {
        ps_dma_unpin(&net->dma_man, cookies[i], BUF_SIZE);
        ps_dma_free(&net->dma_man, cookies[i], BUF_SIZE);
    }
}

static void emul_tx_complete(void *iface, void *cookie) {
    ethif_virtio_emul_t *emul = (ethif_virtio_emul_t*)iface;
    ethif_virtio_emul_internal_t *net = emul->internal;
    emul_tx_cookie_t *tx_cookie = (emul_tx_cookie_t*)cookie;
    /* free the dma memory */
    ps_dma_unpin(&net->dma_man, tx_cookie->vaddr, BUF_SIZE);
    ps_dma_free(&net->dma_man, tx_cookie->vaddr, BUF_SIZE);
    /* put the descriptor chain into the used list */
    struct vring_used_elem used_elem = {tx_cookie->desc_head, 0};
    ring_used_add(emul, &net->vring[TX_QUEUE], used_elem);
    free(tx_cookie);
    /* notify the guest that we have completed some of its buffers */
    net->driver.i_fn.raw_handleIRQ(&net->driver, 0);
}

static void emul_notify_tx(ethif_virtio_emul_t *emul) {
    ethif_virtio_emul_internal_t *net = emul->internal;
    struct vring *vring = &net->vring[TX_QUEUE];
    /* read the index */
    uint16_t guest_idx = ring_avail_idx(emul, vring);
    /* process what we can of the ring */
    uint16_t idx = net->last_idx[TX_QUEUE];
    while (idx != guest_idx) {
        uint16_t desc_head;
        /* read the head of the descriptor chain */
        desc_head = ring_avail(emul, vring, idx);
        /* allocate a packet */
        void *vaddr = ps_dma_alloc(&net->dma_man, BUF_SIZE, net->driver.dma_alignment, 1, PS_MEM_NORMAL);
        if (!vaddr) {
            /* try again later */
            break;
        }
        uintptr_t phys = ps_dma_pin(&net->dma_man, vaddr, BUF_SIZE);
        assert(phys);
        /* length of the final packet to deliver */
        uint32_t len = 0;
        /* we want to skip the initial virtio header, as this should
         * not be sent to the actual ethernet driver. This records
         * how much we have skipped so far. */
        uint32_t skipped = 0;
        /* start walking the descriptors */
        struct vring_desc desc;
        uint16_t desc_idx = desc_head;
        do {
            desc = ring_desc(emul, vring, desc_idx);
            uint32_t skip = 0;
            /* if we haven't yet skipped the full virtio net header, work
             * out how much of this descriptor should be skipped */
            if (skipped < sizeof(struct virtio_net_hdr)) {
                skip = MIN(sizeof(struct virtio_net_hdr) - skipped, desc.len);
                skipped += skip;
            }
            /* truncate packets that are too large */
            uint32_t this_len = desc.len - skip;
            this_len = MIN(BUF_SIZE - len, this_len);
            vmm_guest_vspace_touch(&net->guest_vspace, (uintptr_t)desc.addr + skip, this_len, read_guest_mem, vaddr + len);
            len += this_len;
            desc_idx = desc.next;
        } while (desc.flags & VRING_DESC_F_NEXT);
        /* ship it */
        emul_tx_cookie_t *cookie = malloc(sizeof(*cookie));
        assert(cookie);
        cookie->desc_head = desc_head;
        cookie->vaddr = vaddr;
        int result = net->driver.i_fn.raw_tx(&net->driver, 1, &phys, &len, cookie);
        switch (result) {
        case ETHIF_TX_COMPLETE:
            emul_tx_complete(emul, cookie);
            break;
        case ETHIF_TX_FAILED:
            ps_dma_unpin(&net->dma_man, vaddr, BUF_SIZE);
            ps_dma_free(&net->dma_man, vaddr, BUF_SIZE);
            free(cookie);
            break;
        }
        /* next */
        idx++;
    }
    /* update which parts of the ring we have processed */
    net->last_idx[TX_QUEUE] = idx;
}

static void emul_tx_complete_external(void *iface, void *cookie) {
    emul_tx_complete(iface, cookie);
    /* space may have cleared for additional transmits */
    emul_notify_tx(iface);
}

static struct raw_iface_callbacks emul_callbacks = {
    .tx_complete = emul_tx_complete_external,
    .rx_complete = emul_rx_complete,
    .allocate_rx_buf = emul_allocate_rx_buf
};

static int emul_io_in(struct ethif_virtio_emul *emul, unsigned int offset, unsigned int size, unsigned int *result) {
    switch(offset) {
    case VIRTIO_PCI_HOST_FEATURES:
        assert(size == 4);
        *result = BIT(VIRTIO_NET_F_MAC);
        break;
    case VIRTIO_PCI_STATUS:
        assert(size == 1);
        *result = emul->internal->status;
        break;
    case VIRTIO_PCI_QUEUE_NUM:
        assert(size == 2);
        *result = emul->internal->queue_size[emul->internal->queue];
        break;
    case 0x14 ... 0x19:
        assert(size == 1);
        *result = emul->internal->mac[offset - 0x14];
        break;
    case VIRTIO_PCI_QUEUE_PFN:
        assert(size == 4);
        *result = emul->internal->queue_pfn[emul->internal->queue];
        break;
    case VIRTIO_PCI_ISR:
        assert(size == 1);
        *result = 1;
        break;
    default:
        printf("Unhandled offset of 0x%x of size %d, reading\n", offset, size);
        assert(!"panic");
    }
    return 0;
}

static int emul_io_out(struct ethif_virtio_emul *emul, unsigned int offset, unsigned int size, unsigned int value) {
    switch(offset) {
    case VIRTIO_PCI_GUEST_FEATURES:
        assert(size == 4);
        assert(value == BIT(VIRTIO_NET_F_MAC));
        break;
    case VIRTIO_PCI_STATUS:
        assert(size == 1);
        emul->internal->status = value & 0xff;
        break;
    case VIRTIO_PCI_QUEUE_SEL:
        assert(size == 2);
        emul->internal->queue = (value & 0xffff);
        assert(emul->internal->queue == 0 || emul->internal->queue == 1);
        break;
    case VIRTIO_PCI_QUEUE_PFN: {
        assert(size == 4);
        int queue = emul->internal->queue;
        emul->internal->queue_pfn[queue] = value;
        vring_init(&emul->internal->vring[queue], emul->internal->queue_size[queue], (void*)(uintptr_t)(value << 12), VIRTIO_PCI_VRING_ALIGN);
        break;
    }
    case VIRTIO_PCI_QUEUE_NOTIFY:
        if (value == RX_QUEUE) {
            /* Currently RX packets will just get dropped if there was no space
             * so we will never have work to do if the client suddenly adds
             * more buffers */
        } else if (value == TX_QUEUE) {
            emul_notify_tx(emul);
        }
        break;
    default:
        printf("Unhandled offset of 0x%x of size %d, writing 0x%x\n", offset, size, value);
        assert(!"panic");
    }
    return 0;
}

static int emul_notify(ethif_virtio_emul_t *emul) {
    if (emul->internal->status != VIRTIO_CONFIG_S_DRIVER_OK) {
        return -1;
    }
    emul_notify_tx(emul);
    return 0;
}

ethif_virtio_emul_t *ethif_virtio_emul_init(ps_io_ops_t io_ops, int queue_size, vspace_t *guest_vspace, ethif_driver_init driver, void *config) {
    ethif_virtio_emul_t *emul = NULL;
    ethif_virtio_emul_internal_t *internal = NULL;
    int err;
    emul = malloc(sizeof(*emul));
    internal = malloc(sizeof(*internal));
    if (!emul || !internal) {
        goto error;
    }
    memset(emul, 0, sizeof(*emul));
    memset(internal, 0, sizeof(*internal));
    emul->internal = internal;
    emul->io_in = emul_io_in;
    emul->io_out = emul_io_out;
    emul->notify = emul_notify;
    internal->queue_size[RX_QUEUE] = queue_size;
    internal->queue_size[TX_QUEUE] = queue_size;
    /* create dummy rings. we never actually dereference the rings so they can be null */
    vring_init(&internal->vring[RX_QUEUE], emul->internal->queue_size[RX_QUEUE], 0, VIRTIO_PCI_VRING_ALIGN);
    vring_init(&internal->vring[TX_QUEUE], emul->internal->queue_size[RX_QUEUE], 0, VIRTIO_PCI_VRING_ALIGN);
    internal->driver.cb_cookie = emul;
    internal->driver.i_cb = emul_callbacks;
    internal->guest_vspace = *guest_vspace;
    internal->dma_man = io_ops.dma_manager;
    err = driver(&internal->driver, io_ops, config);
    if (err) {
        ZF_LOGE("Fafiled to initialize driver");
        goto error;
    }
    int mtu;
    internal->driver.i_fn.low_level_init(&internal->driver, internal->mac, &mtu);
    return emul;
error:
    if (emul) {
        free(emul);
    }
    if (internal) {
        free(internal);
    }
    return NULL;
}
