/*
 * QEMU PCI IPMI BT emulation
 *
 * Copyright (c) 2017 Corey Minyard, MontaVista Software, LLC
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "qemu/osdep.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "hw/ipmi/ipmi_bt.h"
#include "hw/pci/pci.h"
#include "qom/object.h"

#define TYPE_PCI_IPMI_BT "pci-ipmi-bt"
OBJECT_DECLARE_SIMPLE_TYPE(PCIIPMIBTDevice, PCI_IPMI_BT)

struct PCIIPMIBTDevice {
    PCIDevice dev;
    IPMIBT bt;
    bool irq_enabled;
    uint32_t uuid;
};

static void pci_ipmi_raise_irq(IPMIBT *ik)
{
    PCIIPMIBTDevice *pik = ik->opaque;

    pci_set_irq(&pik->dev, true);
}

static void pci_ipmi_lower_irq(IPMIBT *ik)
{
    PCIIPMIBTDevice *pik = ik->opaque;

    pci_set_irq(&pik->dev, false);
}

static void pci_ipmi_bt_realize(PCIDevice *pd, Error **errp)
{
    Error *err = NULL;
    PCIIPMIBTDevice *pik = PCI_IPMI_BT(pd);
    IPMIInterface *ii = IPMI_INTERFACE(pd);
    IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);

    if (!pik->bt.bmc) {
        error_setg(errp, "IPMI device requires a bmc attribute to be set");
        return;
    }

    pik->uuid = ipmi_next_uuid();

    pik->bt.bmc->intf = ii;
    pik->bt.opaque = pik;

    pci_config_set_prog_interface(pd->config, 0x02); /* BT */
    pci_config_set_interrupt_pin(pd->config, 0x01);
    pik->bt.use_irq = 1;
    pik->bt.raise_irq = pci_ipmi_raise_irq;
    pik->bt.lower_irq = pci_ipmi_lower_irq;

    iic->init(ii, 8, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    pci_register_bar(pd, 0, PCI_BASE_ADDRESS_SPACE_IO, &pik->bt.io);
}

const VMStateDescription vmstate_PCIIPMIBTDevice = {
    .name = TYPE_IPMI_INTERFACE_PREFIX "pci-bt",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields      = (VMStateField[]) {
        VMSTATE_PCI_DEVICE(dev, PCIIPMIBTDevice),
        VMSTATE_STRUCT(bt, PCIIPMIBTDevice, 1, vmstate_IPMIBT, IPMIBT),
        VMSTATE_END_OF_LIST()
    }
};

static void pci_ipmi_bt_instance_init(Object *obj)
{
    PCIIPMIBTDevice *pik = PCI_IPMI_BT(obj);

    ipmi_bmc_find_and_link(obj, (Object **) &pik->bt.bmc);
}

static void *pci_ipmi_bt_get_backend_data(IPMIInterface *ii)
{
    PCIIPMIBTDevice *pik = PCI_IPMI_BT(ii);

    return &pik->bt;
}

static void pci_ipmi_bt_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);
    PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc);
    IPMIInterfaceClass *iic = IPMI_INTERFACE_CLASS(oc);

    pdc->vendor_id = PCI_VENDOR_ID_QEMU;
    pdc->device_id = PCI_DEVICE_ID_QEMU_IPMI;
    pdc->revision = 1;
    pdc->class_id = PCI_CLASS_SERIAL_IPMI;

    dc->vmsd = &vmstate_PCIIPMIBTDevice;
    dc->desc = "PCI IPMI BT";
    pdc->realize = pci_ipmi_bt_realize;

    iic->get_backend_data = pci_ipmi_bt_get_backend_data;
    ipmi_bt_class_init(iic);
}

static const TypeInfo pci_ipmi_bt_info = {
    .name          = TYPE_PCI_IPMI_BT,
    .parent        = TYPE_PCI_DEVICE,
    .instance_size = sizeof(PCIIPMIBTDevice),
    .instance_init = pci_ipmi_bt_instance_init,
    .class_init    = pci_ipmi_bt_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_IPMI_INTERFACE },
        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
        { }
    }
};

static void pci_ipmi_bt_register_types(void)
{
    type_register_static(&pci_ipmi_bt_info);
}

type_init(pci_ipmi_bt_register_types)
