/*
 * Standard PCI Bridge Device
 *
 * Copyright (c) 2011 Red Hat Inc. Author: Michael S. Tsirkin <mst@redhat.com>
 *
 * http://www.pcisig.com/specifications/conventional/pci_to_pci_bridge_architecture/
 *
 * 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 "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/pci/pci_bridge.h"
#include "hw/pci/pci_ids.h"
#include "hw/pci/msi.h"
#include "hw/pci/shpc.h"
#include "hw/pci/slotid_cap.h"
#include "exec/memory.h"
#include "hw/pci/pci_bus.h"
#include "hw/hotplug.h"

#define TYPE_PCI_BRIDGE_DEV      "pci-bridge"
#define TYPE_PCI_BRIDGE_SEAT_DEV "pci-bridge-seat"
#define PCI_BRIDGE_DEV(obj) \
    OBJECT_CHECK(PCIBridgeDev, (obj), TYPE_PCI_BRIDGE_DEV)

struct PCIBridgeDev {
    /*< private >*/
    PCIBridge parent_obj;
    /*< public >*/

    MemoryRegion bar;
    uint8_t chassis_nr;
#define PCI_BRIDGE_DEV_F_SHPC_REQ 0
    uint32_t flags;

    OnOffAuto msi;
};
typedef struct PCIBridgeDev PCIBridgeDev;

static int pci_bridge_dev_initfn(PCIDevice *dev)
{
    PCIBridge *br = PCI_BRIDGE(dev);
    PCIBridgeDev *bridge_dev = PCI_BRIDGE_DEV(dev);
    int err;
    Error *local_err = NULL;

    pci_bridge_initfn(dev, TYPE_PCI_BUS);

    if (bridge_dev->flags & (1 << PCI_BRIDGE_DEV_F_SHPC_REQ)) {
        dev->config[PCI_INTERRUPT_PIN] = 0x1;
        memory_region_init(&bridge_dev->bar, OBJECT(dev), "shpc-bar",
                           shpc_bar_size(dev));
        err = shpc_init(dev, &br->sec_bus, &bridge_dev->bar, 0);
        if (err) {
            goto shpc_error;
        }
    } else {
        /* MSI is not applicable without SHPC */
        bridge_dev->msi = ON_OFF_AUTO_OFF;
    }

    err = slotid_cap_init(dev, 0, bridge_dev->chassis_nr, 0);
    if (err) {
        goto slotid_error;
    }

    if (bridge_dev->msi != ON_OFF_AUTO_OFF) {
        /* it means SHPC exists, because MSI is needed by SHPC */

        err = msi_init(dev, 0, 1, true, true, &local_err);
        /* Any error other than -ENOTSUP(board's MSI support is broken)
         * is a programming error */
        assert(!err || err == -ENOTSUP);
        if (err && bridge_dev->msi == ON_OFF_AUTO_ON) {
            /* Can't satisfy user's explicit msi=on request, fail */
            error_append_hint(&local_err, "You have to use msi=auto (default) "
                    "or msi=off with this machine type.\n");
            error_report_err(local_err);
            goto msi_error;
        }
        assert(!local_err || bridge_dev->msi == ON_OFF_AUTO_AUTO);
        /* With msi=auto, we fall back to MSI off silently */
        error_free(local_err);
    }

    if (shpc_present(dev)) {
        /* TODO: spec recommends using 64 bit prefetcheable BAR.
         * Check whether that works well. */
        pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
                         PCI_BASE_ADDRESS_MEM_TYPE_64, &bridge_dev->bar);
    }
    return 0;

msi_error:
    slotid_cap_cleanup(dev);
slotid_error:
    if (shpc_present(dev)) {
        shpc_cleanup(dev, &bridge_dev->bar);
    }
shpc_error:
    pci_bridge_exitfn(dev);

    return err;
}

static void pci_bridge_dev_exitfn(PCIDevice *dev)
{
    PCIBridgeDev *bridge_dev = PCI_BRIDGE_DEV(dev);
    if (msi_present(dev)) {
        msi_uninit(dev);
    }
    slotid_cap_cleanup(dev);
    if (shpc_present(dev)) {
        shpc_cleanup(dev, &bridge_dev->bar);
    }
    pci_bridge_exitfn(dev);
}

static void pci_bridge_dev_instance_finalize(Object *obj)
{
    /* this function is idempotent and handles (PCIDevice.shpc == NULL) */
    shpc_free(PCI_DEVICE(obj));
}

static void pci_bridge_dev_write_config(PCIDevice *d,
                                        uint32_t address, uint32_t val, int len)
{
    pci_bridge_write_config(d, address, val, len);
    if (msi_present(d)) {
        msi_write_config(d, address, val, len);
    }
    if (shpc_present(d)) {
        shpc_cap_write_config(d, address, val, len);
    }
}

static void qdev_pci_bridge_dev_reset(DeviceState *qdev)
{
    PCIDevice *dev = PCI_DEVICE(qdev);

    pci_bridge_reset(qdev);
    if (shpc_present(dev)) {
        shpc_reset(dev);
    }
}

static Property pci_bridge_dev_properties[] = {
                    /* Note: 0 is not a legal chassis number. */
    DEFINE_PROP_UINT8(PCI_BRIDGE_DEV_PROP_CHASSIS_NR, PCIBridgeDev, chassis_nr,
                      0),
    DEFINE_PROP_ON_OFF_AUTO(PCI_BRIDGE_DEV_PROP_MSI, PCIBridgeDev, msi,
                            ON_OFF_AUTO_AUTO),
    DEFINE_PROP_BIT(PCI_BRIDGE_DEV_PROP_SHPC, PCIBridgeDev, flags,
                    PCI_BRIDGE_DEV_F_SHPC_REQ, true),
    DEFINE_PROP_END_OF_LIST(),
};

static bool pci_device_shpc_present(void *opaque, int version_id)
{
    PCIDevice *dev = opaque;

    return shpc_present(dev);
}

static const VMStateDescription pci_bridge_dev_vmstate = {
    .name = "pci_bridge",
    .fields = (VMStateField[]) {
        VMSTATE_PCI_DEVICE(parent_obj, PCIBridge),
        SHPC_VMSTATE(shpc, PCIDevice, pci_device_shpc_present),
        VMSTATE_END_OF_LIST()
    }
};

static void pci_bridge_dev_hotplug_cb(HotplugHandler *hotplug_dev,
                                      DeviceState *dev, Error **errp)
{
    PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev);

    if (!shpc_present(pci_hotplug_dev)) {
        error_setg(errp, "standard hotplug controller has been disabled for "
                   "this %s", TYPE_PCI_BRIDGE_DEV);
        return;
    }
    shpc_device_hotplug_cb(hotplug_dev, dev, errp);
}

static void pci_bridge_dev_hot_unplug_request_cb(HotplugHandler *hotplug_dev,
                                                 DeviceState *dev,
                                                 Error **errp)
{
    PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev);

    if (!shpc_present(pci_hotplug_dev)) {
        error_setg(errp, "standard hotplug controller has been disabled for "
                   "this %s", TYPE_PCI_BRIDGE_DEV);
        return;
    }
    shpc_device_hot_unplug_request_cb(hotplug_dev, dev, errp);
}

static void pci_bridge_dev_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);

    k->init = pci_bridge_dev_initfn;
    k->exit = pci_bridge_dev_exitfn;
    k->config_write = pci_bridge_dev_write_config;
    k->vendor_id = PCI_VENDOR_ID_REDHAT;
    k->device_id = PCI_DEVICE_ID_REDHAT_BRIDGE;
    k->class_id = PCI_CLASS_BRIDGE_PCI;
    k->is_bridge = 1,
    dc->desc = "Standard PCI Bridge";
    dc->reset = qdev_pci_bridge_dev_reset;
    dc->props = pci_bridge_dev_properties;
    dc->vmsd = &pci_bridge_dev_vmstate;
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
    hc->plug = pci_bridge_dev_hotplug_cb;
    hc->unplug_request = pci_bridge_dev_hot_unplug_request_cb;
}

static const TypeInfo pci_bridge_dev_info = {
    .name              = TYPE_PCI_BRIDGE_DEV,
    .parent            = TYPE_PCI_BRIDGE,
    .instance_size     = sizeof(PCIBridgeDev),
    .class_init        = pci_bridge_dev_class_init,
    .instance_finalize = pci_bridge_dev_instance_finalize,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_HOTPLUG_HANDLER },
        { }
    }
};

/*
 * Multiseat bridge.  Same as the standard pci bridge, only with a
 * different pci id, so we can match it easily in the guest for
 * automagic multiseat configuration.  See docs/multiseat.txt for more.
 */
static void pci_bridge_dev_seat_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->device_id = PCI_DEVICE_ID_REDHAT_BRIDGE_SEAT;
    dc->desc = "Standard PCI Bridge (multiseat)";
}

static const TypeInfo pci_bridge_dev_seat_info = {
    .name              = TYPE_PCI_BRIDGE_SEAT_DEV,
    .parent            = TYPE_PCI_BRIDGE_DEV,
    .instance_size     = sizeof(PCIBridgeDev),
    .class_init        = pci_bridge_dev_seat_class_init,
};

static void pci_bridge_dev_register(void)
{
    type_register_static(&pci_bridge_dev_info);
    type_register_static(&pci_bridge_dev_seat_info);
}

type_init(pci_bridge_dev_register);
