/*
 * QEMU ISA IPMI KCS emulation
 *
 * Copyright (c) 2015,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 "qemu/module.h"
#include "qapi/error.h"
#include "hw/irq.h"
#include "hw/ipmi/ipmi_kcs.h"
#include "hw/isa/isa.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "qom/object.h"
#include "hw/acpi/ipmi.h"

#define TYPE_ISA_IPMI_KCS "isa-ipmi-kcs"
OBJECT_DECLARE_SIMPLE_TYPE(ISAIPMIKCSDevice, ISA_IPMI_KCS)

struct ISAIPMIKCSDevice {
    ISADevice dev;
    int32_t isairq;
    qemu_irq irq;
    IPMIKCS kcs;
    uint32_t uuid;
};

static void isa_ipmi_kcs_get_fwinfo(IPMIInterface *ii, IPMIFwInfo *info)
{
    ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(ii);

    ipmi_kcs_get_fwinfo(&iik->kcs, info);
    info->interrupt_number = iik->isairq;
    info->uuid = iik->uuid;
}

static void isa_ipmi_kcs_raise_irq(IPMIKCS *ik)
{
    ISAIPMIKCSDevice *iik = ik->opaque;

    qemu_irq_raise(iik->irq);
}

static void isa_ipmi_kcs_lower_irq(IPMIKCS *ik)
{
    ISAIPMIKCSDevice *iik = ik->opaque;

    qemu_irq_lower(iik->irq);
}

static bool vmstate_kcs_before_version2(void *opaque, int version)
{
    return version <= 1;
}

static const VMStateDescription vmstate_ISAIPMIKCSDevice = {
    .name = TYPE_IPMI_INTERFACE,
    .version_id = 2,
    .minimum_version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_VSTRUCT_TEST(kcs, ISAIPMIKCSDevice, vmstate_kcs_before_version2,
                             0, vmstate_IPMIKCS, IPMIKCS, 1),
        VMSTATE_VSTRUCT_V(kcs, ISAIPMIKCSDevice, 2, vmstate_IPMIKCS,
                          IPMIKCS, 2),
        VMSTATE_END_OF_LIST()
    }
};

static void ipmi_isa_realize(DeviceState *dev, Error **errp)
{
    Error *err = NULL;
    ISADevice *isadev = ISA_DEVICE(dev);
    ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(dev);
    IPMIInterface *ii = IPMI_INTERFACE(dev);
    IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);

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

    iik->uuid = ipmi_next_uuid();

    iik->kcs.bmc->intf = ii;
    iik->kcs.opaque = iik;

    iic->init(ii, 0, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    if (iik->isairq > 0) {
        iik->irq = isa_get_irq(isadev, iik->isairq);
        iik->kcs.use_irq = 1;
        iik->kcs.raise_irq = isa_ipmi_kcs_raise_irq;
        iik->kcs.lower_irq = isa_ipmi_kcs_lower_irq;
    }

    qdev_set_legacy_instance_id(dev, iik->kcs.io_base, iik->kcs.io_length);

    isa_register_ioport(isadev, &iik->kcs.io, iik->kcs.io_base);

    /*
     * Version 1 had an incorrect name, it clashed with the BT
     * IPMI device, so receive it, but transmit a different
     * version.
     */
    vmstate_register(NULL, 0, &vmstate_ISAIPMIKCSDevice, iik);
}

static void isa_ipmi_kcs_init(Object *obj)
{
    ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(obj);

    ipmi_bmc_find_and_link(obj, (Object **) &iik->kcs.bmc);
}

static void *isa_ipmi_kcs_get_backend_data(IPMIInterface *ii)
{
    ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(ii);

    return &iik->kcs;
}

static Property ipmi_isa_properties[] = {
    DEFINE_PROP_UINT32("ioport", ISAIPMIKCSDevice, kcs.io_base,  0xca2),
    DEFINE_PROP_INT32("irq",   ISAIPMIKCSDevice, isairq,  5),
    DEFINE_PROP_END_OF_LIST(),
};

static void isa_ipmi_kcs_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);
    IPMIInterfaceClass *iic = IPMI_INTERFACE_CLASS(oc);
    AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(oc);

    dc->realize = ipmi_isa_realize;
    device_class_set_props(dc, ipmi_isa_properties);

    iic->get_backend_data = isa_ipmi_kcs_get_backend_data;
    ipmi_kcs_class_init(iic);
    iic->get_fwinfo = isa_ipmi_kcs_get_fwinfo;
    adevc->build_dev_aml = build_ipmi_dev_aml;
}

static const TypeInfo isa_ipmi_kcs_info = {
    .name          = TYPE_ISA_IPMI_KCS,
    .parent        = TYPE_ISA_DEVICE,
    .instance_size = sizeof(ISAIPMIKCSDevice),
    .instance_init = isa_ipmi_kcs_init,
    .class_init    = isa_ipmi_kcs_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_IPMI_INTERFACE },
        { TYPE_ACPI_DEV_AML_IF },
        { }
    }
};

static void ipmi_register_types(void)
{
    type_register_static(&isa_ipmi_kcs_info);
}

type_init(ipmi_register_types)
