/*
 * Copyright (c) 2007, Intel Corporation.
 *
 * This work is licensed under the terms of the GNU GPL, version 2.  See
 * the COPYING file in the top-level directory.
 *
 * Jiang Yunhong <yunhong.jiang@intel.com>
 *
 * This file implements direct PCI assignment to a HVM guest
 */

#include "qemu/osdep.h"
#include <sys/mman.h>

#include "hw/xen/xen_backend.h"
#include "xen_pt.h"
#include "hw/i386/apic-msidef.h"


#define XEN_PT_AUTO_ASSIGN -1

/* shift count for gflags */
#define XEN_PT_GFLAGS_SHIFT_DEST_ID        0
#define XEN_PT_GFLAGS_SHIFT_RH             8
#define XEN_PT_GFLAGS_SHIFT_DM             9
#define XEN_PT_GFLAGSSHIFT_DELIV_MODE     12
#define XEN_PT_GFLAGSSHIFT_TRG_MODE       15

#define latch(fld) latch[PCI_MSIX_ENTRY_##fld / sizeof(uint32_t)]

/*
 * Helpers
 */

static inline uint8_t msi_vector(uint32_t data)
{
    return (data & MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT;
}

static inline uint8_t msi_dest_id(uint32_t addr)
{
    return (addr & MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT;
}

static inline uint32_t msi_ext_dest_id(uint32_t addr_hi)
{
    return addr_hi & 0xffffff00;
}

static uint32_t msi_gflags(uint32_t data, uint64_t addr)
{
    uint32_t result = 0;
    int rh, dm, dest_id, deliv_mode, trig_mode;

    rh = (addr >> MSI_ADDR_REDIRECTION_SHIFT) & 0x1;
    dm = (addr >> MSI_ADDR_DEST_MODE_SHIFT) & 0x1;
    dest_id = msi_dest_id(addr);
    deliv_mode = (data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7;
    trig_mode = (data >> MSI_DATA_TRIGGER_SHIFT) & 0x1;

    result = dest_id | (rh << XEN_PT_GFLAGS_SHIFT_RH)
        | (dm << XEN_PT_GFLAGS_SHIFT_DM)
        | (deliv_mode << XEN_PT_GFLAGSSHIFT_DELIV_MODE)
        | (trig_mode << XEN_PT_GFLAGSSHIFT_TRG_MODE);

    return result;
}

static inline uint64_t msi_addr64(XenPTMSI *msi)
{
    return (uint64_t)msi->addr_hi << 32 | msi->addr_lo;
}

static int msi_msix_enable(XenPCIPassthroughState *s,
                           uint32_t address,
                           uint16_t flag,
                           bool enable)
{
    uint16_t val = 0;
    int rc;

    if (!address) {
        return -1;
    }

    rc = xen_host_pci_get_word(&s->real_device, address, &val);
    if (rc) {
        XEN_PT_ERR(&s->dev, "Failed to read MSI/MSI-X register (0x%x), rc:%d\n",
                   address, rc);
        return rc;
    }
    if (enable) {
        val |= flag;
    } else {
        val &= ~flag;
    }
    rc = xen_host_pci_set_word(&s->real_device, address, val);
    if (rc) {
        XEN_PT_ERR(&s->dev, "Failed to write MSI/MSI-X register (0x%x), rc:%d\n",
                   address, rc);
    }
    return rc;
}

static int msi_msix_setup(XenPCIPassthroughState *s,
                          uint64_t addr,
                          uint32_t data,
                          int *ppirq,
                          bool is_msix,
                          int msix_entry,
                          bool is_not_mapped)
{
    uint8_t gvec = msi_vector(data);
    int rc = 0;

    assert((!is_msix && msix_entry == 0) || is_msix);

    if (xen_is_pirq_msi(data)) {
        *ppirq = msi_ext_dest_id(addr >> 32) | msi_dest_id(addr);
        if (!*ppirq) {
            /* this probably identifies an misconfiguration of the guest,
             * try the emulated path */
            *ppirq = XEN_PT_UNASSIGNED_PIRQ;
        } else {
            XEN_PT_LOG(&s->dev, "requested pirq %d for MSI%s"
                       " (vec: %#x, entry: %#x)\n",
                       *ppirq, is_msix ? "-X" : "", gvec, msix_entry);
        }
    }

    if (is_not_mapped) {
        uint64_t table_base = 0;

        if (is_msix) {
            table_base = s->msix->table_base;
        }

        rc = xc_physdev_map_pirq_msi(xen_xc, xen_domid, XEN_PT_AUTO_ASSIGN,
                                     ppirq, PCI_DEVFN(s->real_device.dev,
                                                      s->real_device.func),
                                     s->real_device.bus,
                                     msix_entry, table_base);
        if (rc) {
            XEN_PT_ERR(&s->dev,
                       "Mapping of MSI%s (err: %i, vec: %#x, entry %#x)\n",
                       is_msix ? "-X" : "", errno, gvec, msix_entry);
            return rc;
        }
    }

    return 0;
}
static int msi_msix_update(XenPCIPassthroughState *s,
                           uint64_t addr,
                           uint32_t data,
                           int pirq,
                           bool is_msix,
                           int msix_entry,
                           int *old_pirq)
{
    PCIDevice *d = &s->dev;
    uint8_t gvec = msi_vector(data);
    uint32_t gflags = msi_gflags(data, addr);
    int rc = 0;
    uint64_t table_addr = 0;

    XEN_PT_LOG(d, "Updating MSI%s with pirq %d gvec %#x gflags %#x"
               " (entry: %#x)\n",
               is_msix ? "-X" : "", pirq, gvec, gflags, msix_entry);

    if (is_msix) {
        table_addr = s->msix->mmio_base_addr;
    }

    rc = xc_domain_update_msi_irq(xen_xc, xen_domid, gvec,
                                  pirq, gflags, table_addr);

    if (rc) {
        XEN_PT_ERR(d, "Updating of MSI%s failed. (err: %d)\n",
                   is_msix ? "-X" : "", errno);

        if (xc_physdev_unmap_pirq(xen_xc, xen_domid, *old_pirq)) {
            XEN_PT_ERR(d, "Unmapping of MSI%s pirq %d failed. (err: %d)\n",
                       is_msix ? "-X" : "", *old_pirq, errno);
        }
        *old_pirq = XEN_PT_UNASSIGNED_PIRQ;
    }
    return rc;
}

static int msi_msix_disable(XenPCIPassthroughState *s,
                            uint64_t addr,
                            uint32_t data,
                            int pirq,
                            bool is_msix,
                            bool is_binded)
{
    PCIDevice *d = &s->dev;
    uint8_t gvec = msi_vector(data);
    uint32_t gflags = msi_gflags(data, addr);
    int rc = 0;

    if (pirq == XEN_PT_UNASSIGNED_PIRQ) {
        return 0;
    }

    if (is_binded) {
        XEN_PT_LOG(d, "Unbind MSI%s with pirq %d, gvec %#x\n",
                   is_msix ? "-X" : "", pirq, gvec);
        rc = xc_domain_unbind_msi_irq(xen_xc, xen_domid, gvec, pirq, gflags);
        if (rc) {
            XEN_PT_ERR(d, "Unbinding of MSI%s failed. (err: %d, pirq: %d, gvec: %#x)\n",
                       is_msix ? "-X" : "", errno, pirq, gvec);
            return rc;
        }
    }

    XEN_PT_LOG(d, "Unmap MSI%s pirq %d\n", is_msix ? "-X" : "", pirq);
    rc = xc_physdev_unmap_pirq(xen_xc, xen_domid, pirq);
    if (rc) {
        XEN_PT_ERR(d, "Unmapping of MSI%s pirq %d failed. (err: %i)\n",
                   is_msix ? "-X" : "", pirq, errno);
        return rc;
    }

    return 0;
}

/*
 * MSI virtualization functions
 */

static int xen_pt_msi_set_enable(XenPCIPassthroughState *s, bool enable)
{
    XEN_PT_LOG(&s->dev, "%s MSI.\n", enable ? "enabling" : "disabling");

    if (!s->msi) {
        return -1;
    }

    return msi_msix_enable(s, s->msi->ctrl_offset, PCI_MSI_FLAGS_ENABLE,
                           enable);
}

/* setup physical msi, but don't enable it */
int xen_pt_msi_setup(XenPCIPassthroughState *s)
{
    int pirq = XEN_PT_UNASSIGNED_PIRQ;
    int rc = 0;
    XenPTMSI *msi = s->msi;

    if (msi->initialized) {
        XEN_PT_ERR(&s->dev,
                   "Setup physical MSI when it has been properly initialized.\n");
        return -1;
    }

    rc = msi_msix_setup(s, msi_addr64(msi), msi->data, &pirq, false, 0, true);
    if (rc) {
        return rc;
    }

    if (pirq < 0) {
        XEN_PT_ERR(&s->dev, "Invalid pirq number: %d.\n", pirq);
        return -1;
    }

    msi->pirq = pirq;
    XEN_PT_LOG(&s->dev, "MSI mapped with pirq %d.\n", pirq);

    return 0;
}

int xen_pt_msi_update(XenPCIPassthroughState *s)
{
    XenPTMSI *msi = s->msi;
    return msi_msix_update(s, msi_addr64(msi), msi->data, msi->pirq,
                           false, 0, &msi->pirq);
}

void xen_pt_msi_disable(XenPCIPassthroughState *s)
{
    XenPTMSI *msi = s->msi;

    if (!msi) {
        return;
    }

    (void)xen_pt_msi_set_enable(s, false);

    msi_msix_disable(s, msi_addr64(msi), msi->data, msi->pirq, false,
                     msi->initialized);

    /* clear msi info */
    msi->flags &= ~PCI_MSI_FLAGS_ENABLE;
    msi->initialized = false;
    msi->mapped = false;
    msi->pirq = XEN_PT_UNASSIGNED_PIRQ;
}

/*
 * MSI-X virtualization functions
 */

static int msix_set_enable(XenPCIPassthroughState *s, bool enabled)
{
    XEN_PT_LOG(&s->dev, "%s MSI-X.\n", enabled ? "enabling" : "disabling");

    if (!s->msix) {
        return -1;
    }

    return msi_msix_enable(s, s->msix->ctrl_offset, PCI_MSIX_FLAGS_ENABLE,
                           enabled);
}

static int xen_pt_msix_update_one(XenPCIPassthroughState *s, int entry_nr,
                                  uint32_t vec_ctrl)
{
    XenPTMSIXEntry *entry = NULL;
    int pirq;
    int rc;

    if (entry_nr < 0 || entry_nr >= s->msix->total_entries) {
        return -EINVAL;
    }

    entry = &s->msix->msix_entry[entry_nr];

    if (!entry->updated) {
        return 0;
    }

    pirq = entry->pirq;

    /*
     * Update the entry addr and data to the latest values only when the
     * entry is masked or they are all masked, as required by the spec.
     * Addr and data changes while the MSI-X entry is unmasked get deferred
     * until the next masked -> unmasked transition.
     */
    if (pirq == XEN_PT_UNASSIGNED_PIRQ || s->msix->maskall ||
        (vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
        entry->addr = entry->latch(LOWER_ADDR) |
                      ((uint64_t)entry->latch(UPPER_ADDR) << 32);
        entry->data = entry->latch(DATA);
    }

    rc = msi_msix_setup(s, entry->addr, entry->data, &pirq, true, entry_nr,
                        entry->pirq == XEN_PT_UNASSIGNED_PIRQ);
    if (rc) {
        return rc;
    }
    if (entry->pirq == XEN_PT_UNASSIGNED_PIRQ) {
        entry->pirq = pirq;
    }

    rc = msi_msix_update(s, entry->addr, entry->data, pirq, true,
                         entry_nr, &entry->pirq);

    if (!rc) {
        entry->updated = false;
    }

    return rc;
}

int xen_pt_msix_update(XenPCIPassthroughState *s)
{
    XenPTMSIX *msix = s->msix;
    int i;

    for (i = 0; i < msix->total_entries; i++) {
        xen_pt_msix_update_one(s, i, msix->msix_entry[i].latch(VECTOR_CTRL));
    }

    return 0;
}

void xen_pt_msix_disable(XenPCIPassthroughState *s)
{
    int i = 0;

    msix_set_enable(s, false);

    for (i = 0; i < s->msix->total_entries; i++) {
        XenPTMSIXEntry *entry = &s->msix->msix_entry[i];

        msi_msix_disable(s, entry->addr, entry->data, entry->pirq, true, true);

        /* clear MSI-X info */
        entry->pirq = XEN_PT_UNASSIGNED_PIRQ;
        entry->updated = false;
    }
}

int xen_pt_msix_update_remap(XenPCIPassthroughState *s, int bar_index)
{
    XenPTMSIXEntry *entry;
    int i, ret;

    if (!(s->msix && s->msix->bar_index == bar_index)) {
        return 0;
    }

    for (i = 0; i < s->msix->total_entries; i++) {
        entry = &s->msix->msix_entry[i];
        if (entry->pirq != XEN_PT_UNASSIGNED_PIRQ) {
            ret = xc_domain_unbind_pt_irq(xen_xc, xen_domid, entry->pirq,
                                          PT_IRQ_TYPE_MSI, 0, 0, 0, 0);
            if (ret) {
                XEN_PT_ERR(&s->dev, "unbind MSI-X entry %d failed (err: %d)\n",
                           entry->pirq, errno);
            }
            entry->updated = true;
        }
    }
    return xen_pt_msix_update(s);
}

static uint32_t get_entry_value(XenPTMSIXEntry *e, int offset)
{
    assert(!(offset % sizeof(*e->latch)));
    return e->latch[offset / sizeof(*e->latch)];
}

static void set_entry_value(XenPTMSIXEntry *e, int offset, uint32_t val)
{
    assert(!(offset % sizeof(*e->latch)));
    e->latch[offset / sizeof(*e->latch)] = val;
}

static void pci_msix_write(void *opaque, hwaddr addr,
                           uint64_t val, unsigned size)
{
    XenPCIPassthroughState *s = opaque;
    XenPTMSIX *msix = s->msix;
    XenPTMSIXEntry *entry;
    unsigned int entry_nr, offset;

    entry_nr = addr / PCI_MSIX_ENTRY_SIZE;
    if (entry_nr >= msix->total_entries) {
        return;
    }
    entry = &msix->msix_entry[entry_nr];
    offset = addr % PCI_MSIX_ENTRY_SIZE;

    if (offset != PCI_MSIX_ENTRY_VECTOR_CTRL) {
        if (get_entry_value(entry, offset) == val
            && entry->pirq != XEN_PT_UNASSIGNED_PIRQ) {
            return;
        }

        entry->updated = true;
    } else if (msix->enabled && entry->updated &&
               !(val & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
        const volatile uint32_t *vec_ctrl;

        /*
         * If Xen intercepts the mask bit access, entry->vec_ctrl may not be
         * up-to-date. Read from hardware directly.
         */
        vec_ctrl = s->msix->phys_iomem_base + entry_nr * PCI_MSIX_ENTRY_SIZE
            + PCI_MSIX_ENTRY_VECTOR_CTRL;
        xen_pt_msix_update_one(s, entry_nr, *vec_ctrl);
    }

    set_entry_value(entry, offset, val);
}

static uint64_t pci_msix_read(void *opaque, hwaddr addr,
                              unsigned size)
{
    XenPCIPassthroughState *s = opaque;
    XenPTMSIX *msix = s->msix;
    int entry_nr, offset;

    entry_nr = addr / PCI_MSIX_ENTRY_SIZE;
    if (entry_nr < 0) {
        XEN_PT_ERR(&s->dev, "asked MSI-X entry '%i' invalid!\n", entry_nr);
        return 0;
    }

    offset = addr % PCI_MSIX_ENTRY_SIZE;

    if (addr < msix->total_entries * PCI_MSIX_ENTRY_SIZE) {
        return get_entry_value(&msix->msix_entry[entry_nr], offset);
    } else {
        /* Pending Bit Array (PBA) */
        return *(uint32_t *)(msix->phys_iomem_base + addr);
    }
}

static bool pci_msix_accepts(void *opaque, hwaddr addr,
                             unsigned size, bool is_write)
{
    return !(addr & (size - 1));
}

static const MemoryRegionOps pci_msix_ops = {
    .read = pci_msix_read,
    .write = pci_msix_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
        .unaligned = false,
        .accepts = pci_msix_accepts
    },
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
        .unaligned = false
    }
};

int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base)
{
    uint8_t id = 0;
    uint16_t control = 0;
    uint32_t table_off = 0;
    int i, total_entries, bar_index;
    XenHostPCIDevice *hd = &s->real_device;
    PCIDevice *d = &s->dev;
    int fd = -1;
    XenPTMSIX *msix = NULL;
    int rc = 0;

    rc = xen_host_pci_get_byte(hd, base + PCI_CAP_LIST_ID, &id);
    if (rc) {
        return rc;
    }

    if (id != PCI_CAP_ID_MSIX) {
        XEN_PT_ERR(d, "Invalid id %#x base %#x\n", id, base);
        return -1;
    }

    xen_host_pci_get_word(hd, base + PCI_MSIX_FLAGS, &control);
    total_entries = control & PCI_MSIX_FLAGS_QSIZE;
    total_entries += 1;

    s->msix = g_malloc0(sizeof (XenPTMSIX)
                        + total_entries * sizeof (XenPTMSIXEntry));
    msix = s->msix;

    msix->total_entries = total_entries;
    for (i = 0; i < total_entries; i++) {
        msix->msix_entry[i].pirq = XEN_PT_UNASSIGNED_PIRQ;
    }

    memory_region_init_io(&msix->mmio, OBJECT(s), &pci_msix_ops,
                          s, "xen-pci-pt-msix",
                          (total_entries * PCI_MSIX_ENTRY_SIZE
                           + XC_PAGE_SIZE - 1)
                          & XC_PAGE_MASK);

    xen_host_pci_get_long(hd, base + PCI_MSIX_TABLE, &table_off);
    bar_index = msix->bar_index = table_off & PCI_MSIX_FLAGS_BIRMASK;
    table_off = table_off & ~PCI_MSIX_FLAGS_BIRMASK;
    msix->table_base = s->real_device.io_regions[bar_index].base_addr;
    XEN_PT_LOG(d, "get MSI-X table BAR base 0x%"PRIx64"\n", msix->table_base);

    fd = open("/dev/mem", O_RDWR);
    if (fd == -1) {
        rc = -errno;
        XEN_PT_ERR(d, "Can't open /dev/mem: %s\n", strerror(errno));
        goto error_out;
    }
    XEN_PT_LOG(d, "table_off = %#x, total_entries = %d\n",
               table_off, total_entries);
    msix->table_offset_adjust = table_off & 0x0fff;
    msix->phys_iomem_base =
        mmap(NULL,
             total_entries * PCI_MSIX_ENTRY_SIZE + msix->table_offset_adjust,
             PROT_READ,
             MAP_SHARED | MAP_LOCKED,
             fd,
             msix->table_base + table_off - msix->table_offset_adjust);
    close(fd);
    if (msix->phys_iomem_base == MAP_FAILED) {
        rc = -errno;
        XEN_PT_ERR(d, "Can't map physical MSI-X table: %s\n", strerror(errno));
        goto error_out;
    }
    msix->phys_iomem_base = (char *)msix->phys_iomem_base
        + msix->table_offset_adjust;

    XEN_PT_LOG(d, "mapping physical MSI-X table to %p\n",
               msix->phys_iomem_base);

    memory_region_add_subregion_overlap(&s->bar[bar_index], table_off,
                                        &msix->mmio,
                                        2); /* Priority: pci default + 1 */

    return 0;

error_out:
    g_free(s->msix);
    s->msix = NULL;
    return rc;
}

void xen_pt_msix_unmap(XenPCIPassthroughState *s)
{
    XenPTMSIX *msix = s->msix;

    if (!msix) {
        return;
    }

    /* unmap the MSI-X memory mapped register area */
    if (msix->phys_iomem_base) {
        XEN_PT_LOG(&s->dev, "unmapping physical MSI-X table from %p\n",
                   msix->phys_iomem_base);
        munmap(msix->phys_iomem_base, msix->total_entries * PCI_MSIX_ENTRY_SIZE
               + msix->table_offset_adjust);
    }

    memory_region_del_subregion(&s->bar[msix->bar_index], &msix->mmio);
}

void xen_pt_msix_delete(XenPCIPassthroughState *s)
{
    XenPTMSIX *msix = s->msix;

    if (!msix) {
        return;
    }

    object_unparent(OBJECT(&msix->mmio));

    g_free(s->msix);
    s->msix = NULL;
}
