/*
 * 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"

#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 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) {
        isa_init_irq(isadev, &iik->irq, 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);
}

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      = (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 isa_ipmi_kcs_init(Object *obj)
{
    ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(obj);

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

    /*
     * 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_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);

    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;
}

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 },
        { }
    }
};

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

type_init(ipmi_register_types)
