/*
 * libqos PCI bindings for PC
 *
 * Copyright IBM, Corp. 2012-2013
 *
 * Authors:
 *  Anthony Liguori   <aliguori@us.ibm.com>
 *
 * 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 "libqtest.h"
#include "libqos/pci-pc.h"

#include "hw/pci/pci_regs.h"

#include "qemu-common.h"
#include "qemu/host-utils.h"


#define ACPI_PCIHP_ADDR         0xae00
#define PCI_EJ_BASE             0x0008

typedef struct QPCIBusPC
{
    QPCIBus bus;

    uint32_t pci_hole_start;
    uint32_t pci_hole_size;
    uint32_t pci_hole_alloc;

    uint16_t pci_iohole_start;
    uint16_t pci_iohole_size;
    uint16_t pci_iohole_alloc;
} QPCIBusPC;

static uint8_t qpci_pc_io_readb(QPCIBus *bus, void *addr)
{
    uintptr_t port = (uintptr_t)addr;
    uint8_t value;

    if (port < 0x10000) {
        value = inb(port);
    } else {
        value = readb(port);
    }

    return value;
}

static uint16_t qpci_pc_io_readw(QPCIBus *bus, void *addr)
{
    uintptr_t port = (uintptr_t)addr;
    uint16_t value;

    if (port < 0x10000) {
        value = inw(port);
    } else {
        value = readw(port);
    }

    return value;
}

static uint32_t qpci_pc_io_readl(QPCIBus *bus, void *addr)
{
    uintptr_t port = (uintptr_t)addr;
    uint32_t value;

    if (port < 0x10000) {
        value = inl(port);
    } else {
        value = readl(port);
    }

    return value;
}

static void qpci_pc_io_writeb(QPCIBus *bus, void *addr, uint8_t value)
{
    uintptr_t port = (uintptr_t)addr;

    if (port < 0x10000) {
        outb(port, value);
    } else {
        writeb(port, value);
    }
}

static void qpci_pc_io_writew(QPCIBus *bus, void *addr, uint16_t value)
{
    uintptr_t port = (uintptr_t)addr;

    if (port < 0x10000) {
        outw(port, value);
    } else {
        writew(port, value);
    }
}

static void qpci_pc_io_writel(QPCIBus *bus, void *addr, uint32_t value)
{
    uintptr_t port = (uintptr_t)addr;

    if (port < 0x10000) {
        outl(port, value);
    } else {
        writel(port, value);
    }
}

static uint8_t qpci_pc_config_readb(QPCIBus *bus, int devfn, uint8_t offset)
{
    outl(0xcf8, (1U << 31) | (devfn << 8) | offset);
    return inb(0xcfc);
}

static uint16_t qpci_pc_config_readw(QPCIBus *bus, int devfn, uint8_t offset)
{
    outl(0xcf8, (1U << 31) | (devfn << 8) | offset);
    return inw(0xcfc);
}

static uint32_t qpci_pc_config_readl(QPCIBus *bus, int devfn, uint8_t offset)
{
    outl(0xcf8, (1U << 31) | (devfn << 8) | offset);
    return inl(0xcfc);
}

static void qpci_pc_config_writeb(QPCIBus *bus, int devfn, uint8_t offset, uint8_t value)
{
    outl(0xcf8, (1U << 31) | (devfn << 8) | offset);
    outb(0xcfc, value);
}

static void qpci_pc_config_writew(QPCIBus *bus, int devfn, uint8_t offset, uint16_t value)
{
    outl(0xcf8, (1U << 31) | (devfn << 8) | offset);
    outw(0xcfc, value);
}

static void qpci_pc_config_writel(QPCIBus *bus, int devfn, uint8_t offset, uint32_t value)
{
    outl(0xcf8, (1U << 31) | (devfn << 8) | offset);
    outl(0xcfc, value);
}

static void *qpci_pc_iomap(QPCIBus *bus, QPCIDevice *dev, int barno, uint64_t *sizeptr)
{
    QPCIBusPC *s = container_of(bus, QPCIBusPC, bus);
    static const int bar_reg_map[] = {
        PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_2,
        PCI_BASE_ADDRESS_3, PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5,
    };
    int bar_reg;
    uint32_t addr;
    uint64_t size;
    uint32_t io_type;

    g_assert(barno >= 0 && barno <= 5);
    bar_reg = bar_reg_map[barno];

    qpci_config_writel(dev, bar_reg, 0xFFFFFFFF);
    addr = qpci_config_readl(dev, bar_reg);

    io_type = addr & PCI_BASE_ADDRESS_SPACE;
    if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
        addr &= PCI_BASE_ADDRESS_IO_MASK;
    } else {
        addr &= PCI_BASE_ADDRESS_MEM_MASK;
    }

    size = (1ULL << ctzl(addr));
    if (size == 0) {
        return NULL;
    }
    if (sizeptr) {
        *sizeptr = size;
    }

    if (io_type == PCI_BASE_ADDRESS_SPACE_IO) {
        uint16_t loc;

        g_assert(QEMU_ALIGN_UP(s->pci_iohole_alloc, size) + size
                 <= s->pci_iohole_size);
        s->pci_iohole_alloc = QEMU_ALIGN_UP(s->pci_iohole_alloc, size);
        loc = s->pci_iohole_start + s->pci_iohole_alloc;
        s->pci_iohole_alloc += size;

        qpci_config_writel(dev, bar_reg, loc | PCI_BASE_ADDRESS_SPACE_IO);

        return (void *)(intptr_t)loc;
    } else {
        uint64_t loc;

        g_assert(QEMU_ALIGN_UP(s->pci_hole_alloc, size) + size
                 <= s->pci_hole_size);
        s->pci_hole_alloc = QEMU_ALIGN_UP(s->pci_hole_alloc, size);
        loc = s->pci_hole_start + s->pci_hole_alloc;
        s->pci_hole_alloc += size;

        qpci_config_writel(dev, bar_reg, loc);

        return (void *)(intptr_t)loc;
    }
}

static void qpci_pc_iounmap(QPCIBus *bus, void *data)
{
    /* FIXME */
}

QPCIBus *qpci_init_pc(void)
{
    QPCIBusPC *ret;

    ret = g_malloc(sizeof(*ret));

    ret->bus.io_readb = qpci_pc_io_readb;
    ret->bus.io_readw = qpci_pc_io_readw;
    ret->bus.io_readl = qpci_pc_io_readl;

    ret->bus.io_writeb = qpci_pc_io_writeb;
    ret->bus.io_writew = qpci_pc_io_writew;
    ret->bus.io_writel = qpci_pc_io_writel;

    ret->bus.config_readb = qpci_pc_config_readb;
    ret->bus.config_readw = qpci_pc_config_readw;
    ret->bus.config_readl = qpci_pc_config_readl;

    ret->bus.config_writeb = qpci_pc_config_writeb;
    ret->bus.config_writew = qpci_pc_config_writew;
    ret->bus.config_writel = qpci_pc_config_writel;

    ret->bus.iomap = qpci_pc_iomap;
    ret->bus.iounmap = qpci_pc_iounmap;

    ret->pci_hole_start = 0xE0000000;
    ret->pci_hole_size = 0x20000000;
    ret->pci_hole_alloc = 0;

    ret->pci_iohole_start = 0xc000;
    ret->pci_iohole_size = 0x4000;
    ret->pci_iohole_alloc = 0;

    return &ret->bus;
}

void qpci_free_pc(QPCIBus *bus)
{
    QPCIBusPC *s = container_of(bus, QPCIBusPC, bus);

    g_free(s);
}

void qpci_plug_device_test(const char *driver, const char *id,
                           uint8_t slot, const char *opts)
{
    QDict *response;
    char *cmd;

    cmd = g_strdup_printf("{'execute': 'device_add',"
                          " 'arguments': {"
                          "   'driver': '%s',"
                          "   'addr': '%d',"
                          "   %s%s"
                          "   'id': '%s'"
                          "}}", driver, slot,
                          opts ? opts : "", opts ? "," : "",
                          id);
    response = qmp(cmd);
    g_free(cmd);
    g_assert(response);
    g_assert(!qdict_haskey(response, "error"));
    QDECREF(response);
}

void qpci_unplug_acpi_device_test(const char *id, uint8_t slot)
{
    QDict *response;
    char *cmd;

    cmd = g_strdup_printf("{'execute': 'device_del',"
                          " 'arguments': {"
                          "   'id': '%s'"
                          "}}", id);
    response = qmp(cmd);
    g_free(cmd);
    g_assert(response);
    g_assert(!qdict_haskey(response, "error"));
    QDECREF(response);

    outb(ACPI_PCIHP_ADDR + PCI_EJ_BASE, 1 << slot);

    response = qmp("");
    g_assert(response);
    g_assert(qdict_haskey(response, "event"));
    g_assert(!strcmp(qdict_get_str(response, "event"), "DEVICE_DELETED"));
    QDECREF(response);
}
