/*
 * 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 "qapi/qmp/qdict.h"
#include "hw/pci/pci_regs.h"

#include "qemu/module.h"

#define ACPI_PCIHP_ADDR         0xae00
#define PCI_EJ_BASE             0x0008

static uint8_t qpci_pc_pio_readb(QPCIBus *bus, uint32_t addr)
{
    return qtest_inb(bus->qts, addr);
}

static void qpci_pc_pio_writeb(QPCIBus *bus, uint32_t addr, uint8_t val)
{
    qtest_outb(bus->qts, addr, val);
}

static uint16_t qpci_pc_pio_readw(QPCIBus *bus, uint32_t addr)
{
    return qtest_inw(bus->qts, addr);
}

static void qpci_pc_pio_writew(QPCIBus *bus, uint32_t addr, uint16_t val)
{
    qtest_outw(bus->qts, addr, val);
}

static uint32_t qpci_pc_pio_readl(QPCIBus *bus, uint32_t addr)
{
    return qtest_inl(bus->qts, addr);
}

static void qpci_pc_pio_writel(QPCIBus *bus, uint32_t addr, uint32_t val)
{
    qtest_outl(bus->qts, addr, val);
}

static uint64_t qpci_pc_pio_readq(QPCIBus *bus, uint32_t addr)
{
    return (uint64_t)qtest_inl(bus->qts, addr) +
        ((uint64_t)qtest_inl(bus->qts, addr + 4) << 32);
}

static void qpci_pc_pio_writeq(QPCIBus *bus, uint32_t addr, uint64_t val)
{
    qtest_outl(bus->qts, addr, val & 0xffffffff);
    qtest_outl(bus->qts, addr + 4, val >> 32);
}

static void qpci_pc_memread(QPCIBus *bus, uint32_t addr, void *buf, size_t len)
{
    qtest_memread(bus->qts, addr, buf, len);
}

static void qpci_pc_memwrite(QPCIBus *bus, uint32_t addr,
                             const void *buf, size_t len)
{
    qtest_memwrite(bus->qts, addr, buf, len);
}

static uint8_t qpci_pc_config_readb(QPCIBus *bus, int devfn, uint8_t offset)
{
    qtest_outl(bus->qts, 0xcf8, (1U << 31) | (devfn << 8) | offset);
    return qtest_inb(bus->qts, 0xcfc);
}

static uint16_t qpci_pc_config_readw(QPCIBus *bus, int devfn, uint8_t offset)
{
    qtest_outl(bus->qts, 0xcf8, (1U << 31) | (devfn << 8) | offset);
    return qtest_inw(bus->qts, 0xcfc);
}

static uint32_t qpci_pc_config_readl(QPCIBus *bus, int devfn, uint8_t offset)
{
    qtest_outl(bus->qts, 0xcf8, (1U << 31) | (devfn << 8) | offset);
    return qtest_inl(bus->qts, 0xcfc);
}

static void qpci_pc_config_writeb(QPCIBus *bus, int devfn, uint8_t offset, uint8_t value)
{
    qtest_outl(bus->qts, 0xcf8, (1U << 31) | (devfn << 8) | offset);
    qtest_outb(bus->qts, 0xcfc, value);
}

static void qpci_pc_config_writew(QPCIBus *bus, int devfn, uint8_t offset, uint16_t value)
{
    qtest_outl(bus->qts, 0xcf8, (1U << 31) | (devfn << 8) | offset);
    qtest_outw(bus->qts, 0xcfc, value);
}

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

static void *qpci_pc_get_driver(void *obj, const char *interface)
{
    QPCIBusPC *qpci = obj;
    if (!g_strcmp0(interface, "pci-bus")) {
        return &qpci->bus;
    }
    fprintf(stderr, "%s not present in pci-bus-pc\n", interface);
    g_assert_not_reached();
}

void qpci_init_pc(QPCIBusPC *qpci, QTestState *qts, QGuestAllocator *alloc)
{
    assert(qts);

    /* tests can use pci-bus */
    qpci->bus.has_buggy_msi = false;

    qpci->bus.pio_readb = qpci_pc_pio_readb;
    qpci->bus.pio_readw = qpci_pc_pio_readw;
    qpci->bus.pio_readl = qpci_pc_pio_readl;
    qpci->bus.pio_readq = qpci_pc_pio_readq;

    qpci->bus.pio_writeb = qpci_pc_pio_writeb;
    qpci->bus.pio_writew = qpci_pc_pio_writew;
    qpci->bus.pio_writel = qpci_pc_pio_writel;
    qpci->bus.pio_writeq = qpci_pc_pio_writeq;

    qpci->bus.memread = qpci_pc_memread;
    qpci->bus.memwrite = qpci_pc_memwrite;

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

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

    qpci->bus.qts = qts;
    qpci->bus.pio_alloc_ptr = 0xc000;
    qpci->bus.mmio_alloc_ptr = 0xE0000000;
    qpci->bus.mmio_limit = 0x100000000ULL;

    qpci->obj.get_driver = qpci_pc_get_driver;
}

QPCIBus *qpci_new_pc(QTestState *qts, QGuestAllocator *alloc)
{
    QPCIBusPC *qpci = g_new0(QPCIBusPC, 1);
    qpci_init_pc(qpci, qts, alloc);

    return &qpci->bus;
}

void qpci_free_pc(QPCIBus *bus)
{
    QPCIBusPC *s;

    if (!bus) {
        return;
    }
    s = container_of(bus, QPCIBusPC, bus);

    g_free(s);
}

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

    response = qtest_qmp(qts, "{'execute': 'device_del',"
                              " 'arguments': {'id': %s}}", id);
    g_assert(response);
    g_assert(!qdict_haskey(response, "error"));
    qobject_unref(response);

    qtest_outb(qts, ACPI_PCIHP_ADDR + PCI_EJ_BASE, 1 << slot);

    qtest_qmp_eventwait(qts, "DEVICE_DELETED");
}

static void qpci_pc_register_nodes(void)
{
    qos_node_create_driver("pci-bus-pc", NULL);
    qos_node_produces("pci-bus-pc", "pci-bus");
}

libqos_init(qpci_pc_register_nodes);
