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

    virtio_pci_force_virtio_1(vpci_dev);
    qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
}

static void virtio_pmem_pci_set_addr(MemoryDeviceState *md, uint64_t addr,
                                     Error **errp)
{
    object_property_set_uint(OBJECT(md), VIRTIO_PMEM_ADDR_PROP, addr, 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)
