/* virtio-pci.c - pci interface for virtio interface
 *
 * (c) Copyright 2008 Bull S.A.S.
 *
 *  Author: Laurent Vivier <Laurent.Vivier@bull.net>
 *
 * some parts from Linux Virtio PCI driver
 *
 *  Copyright IBM Corp. 2007
 *  Authors: Anthony Liguori  <aliguori@us.ibm.com>
 *
 */

#include "errno.h"
#include "byteswap.h"
#include "etherboot.h"
#include "ipxe/io.h"
#include "ipxe/iomap.h"
#include "ipxe/pci.h"
#include "ipxe/dma.h"
#include "ipxe/reboot.h"
#include "ipxe/virtio-pci.h"
#include "ipxe/virtio-ring.h"

static int vp_alloc_vq(struct vring_virtqueue *vq, u16 num, size_t header_size)
{
    size_t ring_size = PAGE_MASK + vring_size(num);
    size_t vdata_size = num * sizeof(void *);
    size_t queue_size = ring_size + vdata_size + header_size;

    vq->queue = dma_alloc(vq->dma, &vq->map, queue_size, queue_size);
    if (!vq->queue) {
        return -ENOMEM;
    }

    memset ( vq->queue, 0, queue_size );
    vq->queue_size = queue_size;

    /* vdata immediately follows the ring */
    vq->vdata = (void **)(vq->queue + ring_size);

    /* empty header immediately follows vdata */
    vq->empty_header = (struct virtio_net_hdr_modern *)(vq->queue + ring_size + vdata_size);

    return 0;
}

void vp_free_vq(struct vring_virtqueue *vq)
{
    if (vq->queue && vq->queue_size) {
        dma_free(&vq->map, vq->queue, vq->queue_size);
        vq->queue = NULL;
        vq->vdata = NULL;
        vq->queue_size = 0;
    }
}

int vp_find_vq(unsigned int ioaddr, int queue_index,
               struct vring_virtqueue *vq, struct dma_device *dma_dev,
               size_t header_size)
{
   struct vring * vr = &vq->vring;
   u16 num;
   int rc;

   /* select the queue */

   outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL);

   /* check if the queue is available */

   num = inw(ioaddr + VIRTIO_PCI_QUEUE_NUM);
   if (!num) {
           DBG("VIRTIO-PCI ERROR: queue size is 0\n");
           return -1;
   }

   /* check if the queue is already active */

   if (inl(ioaddr + VIRTIO_PCI_QUEUE_PFN)) {
           DBG("VIRTIO-PCI ERROR: queue already active\n");
           return -1;
   }

   vq->queue_index = queue_index;
   vq->dma = dma_dev;

   /* initialize the queue */
   rc = vp_alloc_vq(vq, num, header_size);
   if (rc) {
           DBG("VIRTIO-PCI ERROR: failed to allocate queue memory\n");
           return rc;
   }
   vring_init(vr, num, vq->queue);

   /* activate the queue
    *
    * NOTE: vr->desc is initialized by vring_init()
    */

   outl(dma(&vq->map, vr->desc) >> PAGE_SHIFT, ioaddr + VIRTIO_PCI_QUEUE_PFN);

   return num;
}

#define CFG_POS(vdev, field) \
    (vdev->cfg_cap_pos + offsetof(struct virtio_pci_cfg_cap, field))

static void prep_pci_cfg_cap(struct virtio_pci_modern_device *vdev,
                             struct virtio_pci_region *region,
                             size_t offset, u32 length)
{
    pci_write_config_byte(vdev->pci, CFG_POS(vdev, cap.bar), region->bar);
    pci_write_config_dword(vdev->pci, CFG_POS(vdev, cap.length), length);
    pci_write_config_dword(vdev->pci, CFG_POS(vdev, cap.offset),
        (intptr_t)(region->base + offset));
}

void vpm_iowrite8(struct virtio_pci_modern_device *vdev,
                  struct virtio_pci_region *region, u8 data, size_t offset)
{
    switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
    case VIRTIO_PCI_REGION_MEMORY:
        writeb(data, region->base + offset);
        break;
    case VIRTIO_PCI_REGION_PORT:
        outb(data, region->base + offset);
        break;
    case VIRTIO_PCI_REGION_PCI_CONFIG:
        prep_pci_cfg_cap(vdev, region, offset, 1);
        pci_write_config_byte(vdev->pci, CFG_POS(vdev, pci_cfg_data), data);
        break;
    default:
        assert(0);
        break;
    }
}

void vpm_iowrite16(struct virtio_pci_modern_device *vdev,
                   struct virtio_pci_region *region, u16 data, size_t offset)
{
    data = cpu_to_le16(data);
    switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
    case VIRTIO_PCI_REGION_MEMORY:
        writew(data, region->base + offset);
        break;
    case VIRTIO_PCI_REGION_PORT:
        outw(data, region->base + offset);
        break;
    case VIRTIO_PCI_REGION_PCI_CONFIG:
        prep_pci_cfg_cap(vdev, region, offset, 2);
        pci_write_config_word(vdev->pci, CFG_POS(vdev, pci_cfg_data), data);
        break;
    default:
        assert(0);
        break;
    }
}

void vpm_iowrite32(struct virtio_pci_modern_device *vdev,
                   struct virtio_pci_region *region, u32 data, size_t offset)
{
    data = cpu_to_le32(data);
    switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
    case VIRTIO_PCI_REGION_MEMORY:
        writel(data, region->base + offset);
        break;
    case VIRTIO_PCI_REGION_PORT:
        outl(data, region->base + offset);
        break;
    case VIRTIO_PCI_REGION_PCI_CONFIG:
        prep_pci_cfg_cap(vdev, region, offset, 4);
        pci_write_config_dword(vdev->pci, CFG_POS(vdev, pci_cfg_data), data);
        break;
    default:
        assert(0);
        break;
    }
}

u8 vpm_ioread8(struct virtio_pci_modern_device *vdev,
               struct virtio_pci_region *region, size_t offset)
{
    uint8_t data;
    switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
    case VIRTIO_PCI_REGION_MEMORY:
        data = readb(region->base + offset);
        break;
    case VIRTIO_PCI_REGION_PORT:
        data = inb(region->base + offset);
        break;
    case VIRTIO_PCI_REGION_PCI_CONFIG:
        prep_pci_cfg_cap(vdev, region, offset, 1);
        pci_read_config_byte(vdev->pci, CFG_POS(vdev, pci_cfg_data), &data);
        break;
    default:
        assert(0);
        data = 0;
        break;
    }
    return data;
}

u16 vpm_ioread16(struct virtio_pci_modern_device *vdev,
                 struct virtio_pci_region *region, size_t offset)
{
    uint16_t data;
    switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
    case VIRTIO_PCI_REGION_MEMORY:
        data = readw(region->base + offset);
        break;
    case VIRTIO_PCI_REGION_PORT:
        data = inw(region->base + offset);
        break;
    case VIRTIO_PCI_REGION_PCI_CONFIG:
        prep_pci_cfg_cap(vdev, region, offset, 2);
        pci_read_config_word(vdev->pci, CFG_POS(vdev, pci_cfg_data), &data);
        break;
    default:
        assert(0);
        data = 0;
        break;
    }
    return le16_to_cpu(data);
}

u32 vpm_ioread32(struct virtio_pci_modern_device *vdev,
                 struct virtio_pci_region *region, size_t offset)
{
    uint32_t data;
    switch (region->flags & VIRTIO_PCI_REGION_TYPE_MASK) {
    case VIRTIO_PCI_REGION_MEMORY:
        data = readl(region->base + offset);
        break;
    case VIRTIO_PCI_REGION_PORT:
        data = inl(region->base + offset);
        break;
    case VIRTIO_PCI_REGION_PCI_CONFIG:
        prep_pci_cfg_cap(vdev, region, offset, 4);
        pci_read_config_dword(vdev->pci, CFG_POS(vdev, pci_cfg_data), &data);
        break;
    default:
        assert(0);
        data = 0;
        break;
    }
    return le32_to_cpu(data);
}

int virtio_pci_find_capability(struct pci_device *pci, uint8_t cfg_type)
{
    int pos;
    uint8_t type, bar;

    for (pos = pci_find_capability(pci, PCI_CAP_ID_VNDR);
         pos > 0;
         pos = pci_find_next_capability(pci, pos, PCI_CAP_ID_VNDR)) {

        pci_read_config_byte(pci, pos + offsetof(struct virtio_pci_cap,
            cfg_type), &type);
        pci_read_config_byte(pci, pos + offsetof(struct virtio_pci_cap,
            bar), &bar);

        /* Ignore structures with reserved BAR values */
        if (bar > 0x5) {
            continue;
        }

        if (type == cfg_type) {
            return pos;
        }
    }
    return 0;
}

int virtio_pci_map_capability(struct pci_device *pci, int cap, size_t minlen,
                              u32 align, u32 start, u32 size,
                              struct virtio_pci_region *region)
{
    u8 bar;
    u32 offset, length, base_raw;
    unsigned long base;

    pci_read_config_byte(pci, cap + offsetof(struct virtio_pci_cap, bar), &bar);
    pci_read_config_dword(pci, cap + offsetof(struct virtio_pci_cap, offset),
                          &offset);
    pci_read_config_dword(pci, cap + offsetof(struct virtio_pci_cap, length),
                          &length);

    if (length <= start) {
        DBG("VIRTIO-PCI bad capability len %d (>%d expected)\n", length, start);
        return -EINVAL;
    }
    if (length - start < minlen) {
        DBG("VIRTIO-PCI bad capability len %d (>=%zd expected)\n", length, minlen);
        return -EINVAL;
    }
    length -= start;
    if (start + offset < offset) {
        DBG("VIRTIO-PCI map wrap-around %d+%d\n", start, offset);
        return -EINVAL;
    }
    offset += start;
    if (offset & (align - 1)) {
        DBG("VIRTIO-PCI offset %d not aligned to %d\n", offset, align);
        return -EINVAL;
    }
    if (length > size) {
        length = size;
    }

    if (minlen + offset < minlen ||
        minlen + offset > pci_bar_size(pci, PCI_BASE_ADDRESS(bar))) {
        DBG("VIRTIO-PCI map virtio %zd@%d out of range on bar %i length %ld\n",
            minlen, offset,
            bar, pci_bar_size(pci, PCI_BASE_ADDRESS(bar)));
        return -EINVAL;
    }

    region->base = NULL;
    region->length = length;
    region->bar = bar;

    base = pci_bar_start(pci, PCI_BASE_ADDRESS(bar));
    if (base) {
        pci_read_config_dword(pci, PCI_BASE_ADDRESS(bar), &base_raw);

        if (base_raw & PCI_BASE_ADDRESS_SPACE_IO) {
            /* Region accessed using port I/O */
            region->base = (void *)(base + offset);
            region->flags = VIRTIO_PCI_REGION_PORT;
        } else {
            /* Region mapped into memory space */
            region->base = pci_ioremap(pci, base + offset, length);
            region->flags = VIRTIO_PCI_REGION_MEMORY;
        }
    }
    if (!region->base) {
        /* Region accessed via PCI config space window */
	    region->base = (void *)(intptr_t)offset;
        region->flags = VIRTIO_PCI_REGION_PCI_CONFIG;
    }
    return 0;
}

void virtio_pci_unmap_capability(struct virtio_pci_region *region)
{
    unsigned region_type = region->flags & VIRTIO_PCI_REGION_TYPE_MASK;
    if (region_type == VIRTIO_PCI_REGION_MEMORY) {
        iounmap(region->base);
    }
}

void vpm_notify(struct virtio_pci_modern_device *vdev,
                struct vring_virtqueue *vq)
{
    vpm_iowrite16(vdev, &vq->notification, (u16)vq->queue_index, 0);
}

int vpm_find_vqs(struct virtio_pci_modern_device *vdev,
                 unsigned nvqs, struct vring_virtqueue *vqs,
                 struct dma_device *dma_dev, size_t header_size)
{
    unsigned i;
    struct vring_virtqueue *vq;
    u16 size, off;
    u32 notify_offset_multiplier;
    int err;

    if (nvqs > vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(num_queues))) {
        return -ENOENT;
    }

    /* Read notify_off_multiplier from config space. */
    pci_read_config_dword(vdev->pci,
        vdev->notify_cap_pos + offsetof(struct virtio_pci_notify_cap,
        notify_off_multiplier),
        &notify_offset_multiplier);

    for (i = 0; i < nvqs; i++) {
        /* Select the queue we're interested in */
        vpm_iowrite16(vdev, &vdev->common, (u16)i, COMMON_OFFSET(queue_select));

        /* Check if queue is either not available or already active. */
        size = vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(queue_size));
        /* QEMU has a bug where queues don't revert to inactive on device
         * reset. Skip checking the queue_enable field until it is fixed.
         */
        if (!size /*|| vpm_ioread16(vdev, &vdev->common.queue_enable)*/)
            return -ENOENT;

        if (size & (size - 1)) {
            DBG("VIRTIO-PCI %p: bad queue size %d\n", vdev, size);
            return -EINVAL;
        }

        if (size > MAX_QUEUE_NUM) {
            /* iPXE networking tends to be not perf critical so there's no
             * need to accept large queue sizes.
             */
            size = MAX_QUEUE_NUM;
        }

        vq = &vqs[i];
        vq->queue_index = i;
        vq->dma = dma_dev;

        /* get offset of notification word for this vq */
        off = vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(queue_notify_off));

        err = vp_alloc_vq(vq, size, header_size);
        if (err) {
            DBG("VIRTIO-PCI %p: failed to allocate queue memory\n", vdev);
            return err;
        }
        vring_init(&vq->vring, size, vq->queue);

        /* activate the queue */
        vpm_iowrite16(vdev, &vdev->common, size, COMMON_OFFSET(queue_size));

        vpm_iowrite64(vdev, &vdev->common,
                      dma(&vq->map, vq->vring.desc),
                      COMMON_OFFSET(queue_desc_lo),
                      COMMON_OFFSET(queue_desc_hi));
        vpm_iowrite64(vdev, &vdev->common,
                      dma(&vq->map, vq->vring.avail),
                      COMMON_OFFSET(queue_avail_lo),
                      COMMON_OFFSET(queue_avail_hi));
        vpm_iowrite64(vdev, &vdev->common,
                      dma(&vq->map, vq->vring.used),
                      COMMON_OFFSET(queue_used_lo),
                      COMMON_OFFSET(queue_used_hi));

        err = virtio_pci_map_capability(vdev->pci,
            vdev->notify_cap_pos, 2, 2,
            off * notify_offset_multiplier, 2,
            &vq->notification);
        if (err) {
            return err;
        }
    }

    /* Select and activate all queues. Has to be done last: once we do
     * this, there's no way to go back except reset.
     */
    for (i = 0; i < nvqs; i++) {
        vq = &vqs[i];
        vpm_iowrite16(vdev, &vdev->common, (u16)vq->queue_index,
                      COMMON_OFFSET(queue_select));
        vpm_iowrite16(vdev, &vdev->common, 1, COMMON_OFFSET(queue_enable));
    }
    return 0;
}
