/*
 * msi.c
 *
 * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
 *                    VA Linux Systems Japan K.K.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "msi.h"
#include "range.h"

/* Eventually those constants should go to Linux pci_regs.h */
#define PCI_MSI_PENDING_32      0x10
#define PCI_MSI_PENDING_64      0x14

/* PCI_MSI_ADDRESS_LO */
#define PCI_MSI_ADDRESS_LO_MASK         (~0x3)

/* If we get rid of cap allocator, we won't need those. */
#define PCI_MSI_32_SIZEOF       0x0a
#define PCI_MSI_64_SIZEOF       0x0e
#define PCI_MSI_32M_SIZEOF      0x14
#define PCI_MSI_64M_SIZEOF      0x18

#define PCI_MSI_VECTORS_MAX     32

/* If we get rid of cap allocator, we won't need this. */
static inline uint8_t msi_cap_sizeof(uint16_t flags)
{
    switch (flags & (PCI_MSI_FLAGS_MASKBIT | PCI_MSI_FLAGS_64BIT)) {
    case PCI_MSI_FLAGS_MASKBIT | PCI_MSI_FLAGS_64BIT:
        return PCI_MSI_64M_SIZEOF;
    case PCI_MSI_FLAGS_64BIT:
        return PCI_MSI_64_SIZEOF;
    case PCI_MSI_FLAGS_MASKBIT:
        return PCI_MSI_32M_SIZEOF;
    case 0:
        return PCI_MSI_32_SIZEOF;
    default:
        abort();
        break;
    }
    return 0;
}

//#define MSI_DEBUG

#ifdef MSI_DEBUG
# define MSI_DPRINTF(fmt, ...)                                          \
    fprintf(stderr, "%s:%d " fmt, __func__, __LINE__, ## __VA_ARGS__)
#else
# define MSI_DPRINTF(fmt, ...)  do { } while (0)
#endif
#define MSI_DEV_PRINTF(dev, fmt, ...)                                   \
    MSI_DPRINTF("%s:%x " fmt, (dev)->name, (dev)->devfn, ## __VA_ARGS__)

static inline unsigned int msi_nr_vectors(uint16_t flags)
{
    return 1U <<
        ((flags & PCI_MSI_FLAGS_QSIZE) >> (ffs(PCI_MSI_FLAGS_QSIZE) - 1));
}

static inline uint8_t msi_flags_off(const PCIDevice* dev)
{
    return dev->msi_cap + PCI_MSI_FLAGS;
}

static inline uint8_t msi_address_lo_off(const PCIDevice* dev)
{
    return dev->msi_cap + PCI_MSI_ADDRESS_LO;
}

static inline uint8_t msi_address_hi_off(const PCIDevice* dev)
{
    return dev->msi_cap + PCI_MSI_ADDRESS_HI;
}

static inline uint8_t msi_data_off(const PCIDevice* dev, bool msi64bit)
{
    return dev->msi_cap + (msi64bit ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32);
}

static inline uint8_t msi_mask_off(const PCIDevice* dev, bool msi64bit)
{
    return dev->msi_cap + (msi64bit ? PCI_MSI_MASK_64 : PCI_MSI_MASK_32);
}

static inline uint8_t msi_pending_off(const PCIDevice* dev, bool msi64bit)
{
    return dev->msi_cap + (msi64bit ? PCI_MSI_PENDING_64 : PCI_MSI_PENDING_32);
}

bool msi_enabled(const PCIDevice *dev)
{
    return msi_present(dev) &&
        (pci_get_word(dev->config + msi_flags_off(dev)) &
         PCI_MSI_FLAGS_ENABLE);
}

int msi_init(struct PCIDevice *dev, uint8_t offset,
             unsigned int nr_vectors, bool msi64bit, bool msi_per_vector_mask)
{
    unsigned int vectors_order;
    uint16_t flags;
    uint8_t cap_size;
    int config_offset;
    MSI_DEV_PRINTF(dev,
                   "init offset: 0x%"PRIx8" vector: %"PRId8
                   " 64bit %d mask %d\n",
                   offset, nr_vectors, msi64bit, msi_per_vector_mask);

    assert(!(nr_vectors & (nr_vectors - 1)));   /* power of 2 */
    assert(nr_vectors > 0);
    assert(nr_vectors <= PCI_MSI_VECTORS_MAX);
    /* the nr of MSI vectors is up to 32 */
    vectors_order = ffs(nr_vectors) - 1;

    flags = vectors_order << (ffs(PCI_MSI_FLAGS_QMASK) - 1);
    if (msi64bit) {
        flags |= PCI_MSI_FLAGS_64BIT;
    }
    if (msi_per_vector_mask) {
        flags |= PCI_MSI_FLAGS_MASKBIT;
    }

    cap_size = msi_cap_sizeof(flags);
    config_offset = pci_add_capability(dev, PCI_CAP_ID_MSI, offset, cap_size);
    if (config_offset < 0) {
        return config_offset;
    }

    dev->msi_cap = config_offset;
    dev->cap_present |= QEMU_PCI_CAP_MSI;

    pci_set_word(dev->config + msi_flags_off(dev), flags);
    pci_set_word(dev->wmask + msi_flags_off(dev),
                 PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE);
    pci_set_long(dev->wmask + msi_address_lo_off(dev),
                 PCI_MSI_ADDRESS_LO_MASK);
    if (msi64bit) {
        pci_set_long(dev->wmask + msi_address_hi_off(dev), 0xffffffff);
    }
    pci_set_word(dev->wmask + msi_data_off(dev, msi64bit), 0xffff);

    if (msi_per_vector_mask) {
        /* Make mask bits 0 to nr_vectors - 1 writable. */
        pci_set_long(dev->wmask + msi_mask_off(dev, msi64bit),
                     0xffffffff >> (PCI_MSI_VECTORS_MAX - nr_vectors));
    }
    return config_offset;
}

void msi_uninit(struct PCIDevice *dev)
{
    uint16_t flags;
    uint8_t cap_size;

    if (!(dev->cap_present & QEMU_PCI_CAP_MSI)) {
        return;
    }
    flags = pci_get_word(dev->config + msi_flags_off(dev));
    cap_size = msi_cap_sizeof(flags);
    pci_del_capability(dev, PCI_CAP_ID_MSI, cap_size);
    dev->cap_present &= ~QEMU_PCI_CAP_MSI;

    MSI_DEV_PRINTF(dev, "uninit\n");
}

void msi_reset(PCIDevice *dev)
{
    uint16_t flags;
    bool msi64bit;

    flags = pci_get_word(dev->config + msi_flags_off(dev));
    flags &= ~(PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE);
    msi64bit = flags & PCI_MSI_FLAGS_64BIT;

    pci_set_word(dev->config + msi_flags_off(dev), flags);
    pci_set_long(dev->config + msi_address_lo_off(dev), 0);
    if (msi64bit) {
        pci_set_long(dev->config + msi_address_hi_off(dev), 0);
    }
    pci_set_word(dev->config + msi_data_off(dev, msi64bit), 0);
    if (flags & PCI_MSI_FLAGS_MASKBIT) {
        pci_set_long(dev->config + msi_mask_off(dev, msi64bit), 0);
        pci_set_long(dev->config + msi_pending_off(dev, msi64bit), 0);
    }
    MSI_DEV_PRINTF(dev, "reset\n");
}

static bool msi_is_masked(const PCIDevice *dev, unsigned int vector)
{
    uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
    uint32_t mask;
    assert(vector < PCI_MSI_VECTORS_MAX);

    if (!(flags & PCI_MSI_FLAGS_MASKBIT)) {
        return false;
    }

    mask = pci_get_long(dev->config +
                        msi_mask_off(dev, flags & PCI_MSI_FLAGS_64BIT));
    return mask & (1U << vector);
}

void msi_notify(PCIDevice *dev, unsigned int vector)
{
    uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
    bool msi64bit = flags & PCI_MSI_FLAGS_64BIT;
    unsigned int nr_vectors = msi_nr_vectors(flags);
    uint64_t address;
    uint32_t data;

    assert(vector < nr_vectors);
    if (msi_is_masked(dev, vector)) {
        assert(flags & PCI_MSI_FLAGS_MASKBIT);
        pci_long_test_and_set_mask(
            dev->config + msi_pending_off(dev, msi64bit), 1U << vector);
        MSI_DEV_PRINTF(dev, "pending vector 0x%x\n", vector);
        return;
    }

    if (msi64bit) {
        address = pci_get_quad(dev->config + msi_address_lo_off(dev));
    } else {
        address = pci_get_long(dev->config + msi_address_lo_off(dev));
    }

    /* upper bit 31:16 is zero */
    data = pci_get_word(dev->config + msi_data_off(dev, msi64bit));
    if (nr_vectors > 1) {
        data &= ~(nr_vectors - 1);
        data |= vector;
    }

    MSI_DEV_PRINTF(dev,
                   "notify vector 0x%x"
                   " address: 0x%"PRIx64" data: 0x%"PRIx32"\n",
                   vector, address, data);
    stl_le_phys(address, data);
}

/* call this function after updating configs by pci_default_write_config(). */
void msi_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int len)
{
    uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
    bool msi64bit = flags & PCI_MSI_FLAGS_64BIT;
    bool msi_per_vector_mask = flags & PCI_MSI_FLAGS_MASKBIT;
    unsigned int nr_vectors;
    uint8_t log_num_vecs;
    uint8_t log_max_vecs;
    unsigned int vector;
    uint32_t pending;

    if (!ranges_overlap(addr, len, dev->msi_cap, msi_cap_sizeof(flags))) {
        return;
    }

#ifdef MSI_DEBUG
    MSI_DEV_PRINTF(dev, "addr 0x%"PRIx32" val 0x%"PRIx32" len %d\n",
                   addr, val, len);
    MSI_DEV_PRINTF(dev, "ctrl: 0x%"PRIx16" address: 0x%"PRIx32,
                   flags,
                   pci_get_long(dev->config + msi_address_lo_off(dev)));
    if (msi64bit) {
        fprintf(stderr, " address-hi: 0x%"PRIx32,
                pci_get_long(dev->config + msi_address_hi_off(dev)));
    }
    fprintf(stderr, " data: 0x%"PRIx16,
            pci_get_word(dev->config + msi_data_off(dev, msi64bit)));
    if (flags & PCI_MSI_FLAGS_MASKBIT) {
        fprintf(stderr, " mask 0x%"PRIx32" pending 0x%"PRIx32,
                pci_get_long(dev->config + msi_mask_off(dev, msi64bit)),
                pci_get_long(dev->config + msi_pending_off(dev, msi64bit)));
    }
    fprintf(stderr, "\n");
#endif

    if (!(flags & PCI_MSI_FLAGS_ENABLE)) {
        return;
    }

    /*
     * Now MSI is enabled, clear INTx# interrupts.
     * the driver is prohibited from writing enable bit to mask
     * a service request. But the guest OS could do this.
     * So we just discard the interrupts as moderate fallback.
     *
     * 6.8.3.3. Enabling Operation
     *   While enabled for MSI or MSI-X operation, a function is prohibited
     *   from using its INTx# pin (if implemented) to request
     *   service (MSI, MSI-X, and INTx# are mutually exclusive).
     */
    pci_device_deassert_intx(dev);

    /*
     * nr_vectors might be set bigger than capable. So clamp it.
     * This is not legal by spec, so we can do anything we like,
     * just don't crash the host
     */
    log_num_vecs =
        (flags & PCI_MSI_FLAGS_QSIZE) >> (ffs(PCI_MSI_FLAGS_QSIZE) - 1);
    log_max_vecs =
        (flags & PCI_MSI_FLAGS_QMASK) >> (ffs(PCI_MSI_FLAGS_QMASK) - 1);
    if (log_num_vecs > log_max_vecs) {
        flags &= ~PCI_MSI_FLAGS_QSIZE;
        flags |= log_max_vecs << (ffs(PCI_MSI_FLAGS_QSIZE) - 1);
        pci_set_word(dev->config + msi_flags_off(dev), flags);
    }

    if (!msi_per_vector_mask) {
        /* if per vector masking isn't supported,
           there is no pending interrupt. */
        return;
    }

    nr_vectors = msi_nr_vectors(flags);

    /* This will discard pending interrupts, if any. */
    pending = pci_get_long(dev->config + msi_pending_off(dev, msi64bit));
    pending &= 0xffffffff >> (PCI_MSI_VECTORS_MAX - nr_vectors);
    pci_set_long(dev->config + msi_pending_off(dev, msi64bit), pending);

    /* deliver pending interrupts which are unmasked */
    for (vector = 0; vector < nr_vectors; ++vector) {
        if (msi_is_masked(dev, vector) || !(pending & (1U << vector))) {
            continue;
        }

        pci_long_test_and_clear_mask(
            dev->config + msi_pending_off(dev, msi64bit), 1U << vector);
        msi_notify(dev, vector);
    }
}

unsigned int msi_nr_vectors_allocated(const PCIDevice *dev)
{
    uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
    return msi_nr_vectors(flags);
}
