/*
 * Virtio PMEM PCI device
 *
 * Copyright (C) 2018-2019 Red Hat, Inc.
 *
 * Authors:
 *  Pankaj Gupta <pagupta@redhat.com>
 *  David Hildenbrand <david@redhat.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"

#include "virtio-pmem-pci.h"
#include "hw/mem/memory-device.h"
#include "qapi/error.h"

static void virtio_pmem_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
{
    VirtIOPMEMPCI *pmem_pci = VIRTIO_PMEM_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&pmem_pci->vdev);

    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
}

static void virtio_pmem_pci_set_addr(MemoryDeviceState *md, uint64_t addr,
                                     Error **errp)
{
    object_property_set_uint(OBJECT(md), addr, VIRTIO_PMEM_ADDR_PROP, errp);
}

static uint64_t virtio_pmem_pci_get_addr(const MemoryDeviceState *md)
{
    return object_property_get_uint(OBJECT(md), VIRTIO_PMEM_ADDR_PROP,
                                    &error_abort);
}

static MemoryRegion *virtio_pmem_pci_get_memory_region(MemoryDeviceState *md,
                                                       Error **errp)
{
    VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md);
    VirtIOPMEM *pmem = VIRTIO_PMEM(&pci_pmem->vdev);
    VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem);

    return vpc->get_memory_region(pmem, errp);
}

static uint64_t virtio_pmem_pci_get_plugged_size(const MemoryDeviceState *md,
                                                 Error **errp)
{
    VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md);
    VirtIOPMEM *pmem = VIRTIO_PMEM(&pci_pmem->vdev);
    VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem);
    MemoryRegion *mr = vpc->get_memory_region(pmem, errp);

    /* the plugged size corresponds to the region size */
    return mr ? memory_region_size(mr) : 0;
}

static void virtio_pmem_pci_fill_device_info(const MemoryDeviceState *md,
                                             MemoryDeviceInfo *info)
{
    VirtioPMEMDeviceInfo *vi = g_new0(VirtioPMEMDeviceInfo, 1);
    VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md);
    VirtIOPMEM *pmem = VIRTIO_PMEM(&pci_pmem->vdev);
    VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem);
    DeviceState *dev = DEVICE(md);

    if (dev->id) {
        vi->has_id = true;
        vi->id = g_strdup(dev->id);
    }

    /* let the real device handle everything else */
    vpc->fill_device_info(pmem, vi);

    info->u.virtio_pmem.data = vi;
    info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM;
}

static void virtio_pmem_pci_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
    MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(klass);

    k->realize = virtio_pmem_pci_realize;
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_PMEM;
    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
    pcidev_k->class_id = PCI_CLASS_OTHERS;

    mdc->get_addr = virtio_pmem_pci_get_addr;
    mdc->set_addr = virtio_pmem_pci_set_addr;
    mdc->get_plugged_size = virtio_pmem_pci_get_plugged_size;
    mdc->get_memory_region = virtio_pmem_pci_get_memory_region;
    mdc->fill_device_info = virtio_pmem_pci_fill_device_info;
}

static void virtio_pmem_pci_instance_init(Object *obj)
{
    VirtIOPMEMPCI *dev = VIRTIO_PMEM_PCI(obj);

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_PMEM);
}

static const VirtioPCIDeviceTypeInfo virtio_pmem_pci_info = {
    .base_name             = TYPE_VIRTIO_PMEM_PCI,
    .generic_name          = "virtio-pmem-pci",
    .instance_size = sizeof(VirtIOPMEMPCI),
    .instance_init = virtio_pmem_pci_instance_init,
    .class_init    = virtio_pmem_pci_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_MEMORY_DEVICE },
        { }
    },
};

static void virtio_pmem_pci_register_types(void)
{
    virtio_pci_types_register(&virtio_pmem_pci_info);
}
type_init(virtio_pmem_pci_register_types)
