/* Copyright (c) Citrix Systems Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms,
 * with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * *   Redistributions of source code must retain the above
 *     copyright notice, this list of conditions and the
 *     following disclaimer.
 * *   Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the
 *     following disclaimer in the documentation and/or other
 *     materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "hw/pci/pci.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "trace.h"
#include "qom/object.h"

#define TYPE_XEN_PV_DEVICE  "xen-pvdevice"

OBJECT_DECLARE_SIMPLE_TYPE(XenPVDevice, XEN_PV_DEVICE)

struct XenPVDevice {
    /*< private >*/
    PCIDevice       parent_obj;
    /*< public >*/
    uint16_t        vendor_id;
    uint16_t        device_id;
    uint8_t         revision;
    uint32_t        size;
    MemoryRegion    mmio;
};

static uint64_t xen_pv_mmio_read(void *opaque, hwaddr addr,
                                 unsigned size)
{
    trace_xen_pv_mmio_read(addr);

    return ~(uint64_t)0;
}

static void xen_pv_mmio_write(void *opaque, hwaddr addr,
                              uint64_t val, unsigned size)
{
    trace_xen_pv_mmio_write(addr);
}

static const MemoryRegionOps xen_pv_mmio_ops = {
    .read = &xen_pv_mmio_read,
    .write = &xen_pv_mmio_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static const VMStateDescription vmstate_xen_pvdevice = {
    .name = "xen-pvdevice",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_PCI_DEVICE(parent_obj, XenPVDevice),
        VMSTATE_END_OF_LIST()
    }
};

static void xen_pv_realize(PCIDevice *pci_dev, Error **errp)
{
    XenPVDevice *d = XEN_PV_DEVICE(pci_dev);
    uint8_t *pci_conf;

    /* device-id property must always be supplied */
    if (d->device_id == 0xffff) {
        error_setg(errp, "Device ID invalid, it must always be supplied");
        return;
    }

    pci_conf = pci_dev->config;

    pci_set_word(pci_conf + PCI_VENDOR_ID, d->vendor_id);
    pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, d->vendor_id);
    pci_set_word(pci_conf + PCI_DEVICE_ID, d->device_id);
    pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, d->device_id);
    pci_set_byte(pci_conf + PCI_REVISION_ID, d->revision);

    pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_MEMORY);

    pci_config_set_prog_interface(pci_conf, 0);

    pci_conf[PCI_INTERRUPT_PIN] = 1;

    memory_region_init_io(&d->mmio, NULL, &xen_pv_mmio_ops, d,
                          "mmio", d->size);

    pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_MEM_PREFETCH,
                     &d->mmio);
}

static Property xen_pv_props[] = {
    DEFINE_PROP_UINT16("vendor-id", XenPVDevice, vendor_id, PCI_VENDOR_ID_XEN),
    DEFINE_PROP_UINT16("device-id", XenPVDevice, device_id, 0xffff),
    DEFINE_PROP_UINT8("revision", XenPVDevice, revision, 0x01),
    DEFINE_PROP_UINT32("size", XenPVDevice, size, 0x400000),
    DEFINE_PROP_END_OF_LIST()
};

static void xen_pv_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->realize = xen_pv_realize;
    k->class_id = PCI_CLASS_SYSTEM_OTHER;
    dc->desc = "Xen PV Device";
    device_class_set_props(dc, xen_pv_props);
    dc->vmsd = &vmstate_xen_pvdevice;
}

static const TypeInfo xen_pv_type_info = {
    .name          = TYPE_XEN_PV_DEVICE,
    .parent        = TYPE_PCI_DEVICE,
    .instance_size = sizeof(XenPVDevice),
    .class_init    = xen_pv_class_init,
    .interfaces = (InterfaceInfo[]) {
        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
        { },
    },
};

static void xen_pv_register_types(void)
{
    type_register_static(&xen_pv_type_info);
}

type_init(xen_pv_register_types)
