2 * Virtio PMEM PCI device
4 * Copyright (C) 2018-2019 Red Hat, Inc.
7 * Pankaj Gupta <pagupta@redhat.com>
8 * David Hildenbrand <david@redhat.com>
10 * This work is licensed under the terms of the GNU GPL, version 2.
11 * See the COPYING file in the top-level directory.
14 #include "qemu/osdep.h"
16 #include "virtio-pmem-pci.h"
17 #include "hw/mem/memory-device.h"
18 #include "qapi/error.h"
20 static void virtio_pmem_pci_realize(VirtIOPCIProxy
*vpci_dev
, Error
**errp
)
22 VirtIOPMEMPCI
*pmem_pci
= VIRTIO_PMEM_PCI(vpci_dev
);
23 DeviceState
*vdev
= DEVICE(&pmem_pci
->vdev
);
25 qdev_realize(vdev
, BUS(&vpci_dev
->bus
), errp
);
28 static void virtio_pmem_pci_set_addr(MemoryDeviceState
*md
, uint64_t addr
,
31 object_property_set_uint(OBJECT(md
), addr
, VIRTIO_PMEM_ADDR_PROP
, errp
);
34 static uint64_t virtio_pmem_pci_get_addr(const MemoryDeviceState
*md
)
36 return object_property_get_uint(OBJECT(md
), VIRTIO_PMEM_ADDR_PROP
,
40 static MemoryRegion
*virtio_pmem_pci_get_memory_region(MemoryDeviceState
*md
,
43 VirtIOPMEMPCI
*pci_pmem
= VIRTIO_PMEM_PCI(md
);
44 VirtIOPMEM
*pmem
= VIRTIO_PMEM(&pci_pmem
->vdev
);
45 VirtIOPMEMClass
*vpc
= VIRTIO_PMEM_GET_CLASS(pmem
);
47 return vpc
->get_memory_region(pmem
, errp
);
50 static uint64_t virtio_pmem_pci_get_plugged_size(const MemoryDeviceState
*md
,
53 VirtIOPMEMPCI
*pci_pmem
= VIRTIO_PMEM_PCI(md
);
54 VirtIOPMEM
*pmem
= VIRTIO_PMEM(&pci_pmem
->vdev
);
55 VirtIOPMEMClass
*vpc
= VIRTIO_PMEM_GET_CLASS(pmem
);
56 MemoryRegion
*mr
= vpc
->get_memory_region(pmem
, errp
);
58 /* the plugged size corresponds to the region size */
59 return mr
? memory_region_size(mr
) : 0;
62 static void virtio_pmem_pci_fill_device_info(const MemoryDeviceState
*md
,
63 MemoryDeviceInfo
*info
)
65 VirtioPMEMDeviceInfo
*vi
= g_new0(VirtioPMEMDeviceInfo
, 1);
66 VirtIOPMEMPCI
*pci_pmem
= VIRTIO_PMEM_PCI(md
);
67 VirtIOPMEM
*pmem
= VIRTIO_PMEM(&pci_pmem
->vdev
);
68 VirtIOPMEMClass
*vpc
= VIRTIO_PMEM_GET_CLASS(pmem
);
69 DeviceState
*dev
= DEVICE(md
);
73 vi
->id
= g_strdup(dev
->id
);
76 /* let the real device handle everything else */
77 vpc
->fill_device_info(pmem
, vi
);
79 info
->u
.virtio_pmem
.data
= vi
;
80 info
->type
= MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM
;
83 static void virtio_pmem_pci_class_init(ObjectClass
*klass
, void *data
)
85 DeviceClass
*dc
= DEVICE_CLASS(klass
);
86 VirtioPCIClass
*k
= VIRTIO_PCI_CLASS(klass
);
87 PCIDeviceClass
*pcidev_k
= PCI_DEVICE_CLASS(klass
);
88 MemoryDeviceClass
*mdc
= MEMORY_DEVICE_CLASS(klass
);
90 k
->realize
= virtio_pmem_pci_realize
;
91 set_bit(DEVICE_CATEGORY_MISC
, dc
->categories
);
92 pcidev_k
->vendor_id
= PCI_VENDOR_ID_REDHAT_QUMRANET
;
93 pcidev_k
->device_id
= PCI_DEVICE_ID_VIRTIO_PMEM
;
94 pcidev_k
->revision
= VIRTIO_PCI_ABI_VERSION
;
95 pcidev_k
->class_id
= PCI_CLASS_OTHERS
;
97 mdc
->get_addr
= virtio_pmem_pci_get_addr
;
98 mdc
->set_addr
= virtio_pmem_pci_set_addr
;
99 mdc
->get_plugged_size
= virtio_pmem_pci_get_plugged_size
;
100 mdc
->get_memory_region
= virtio_pmem_pci_get_memory_region
;
101 mdc
->fill_device_info
= virtio_pmem_pci_fill_device_info
;
104 static void virtio_pmem_pci_instance_init(Object
*obj
)
106 VirtIOPMEMPCI
*dev
= VIRTIO_PMEM_PCI(obj
);
108 virtio_instance_init_common(obj
, &dev
->vdev
, sizeof(dev
->vdev
),
112 static const VirtioPCIDeviceTypeInfo virtio_pmem_pci_info
= {
113 .base_name
= TYPE_VIRTIO_PMEM_PCI
,
114 .generic_name
= "virtio-pmem-pci",
115 .instance_size
= sizeof(VirtIOPMEMPCI
),
116 .instance_init
= virtio_pmem_pci_instance_init
,
117 .class_init
= virtio_pmem_pci_class_init
,
118 .interfaces
= (InterfaceInfo
[]) {
119 { TYPE_MEMORY_DEVICE
},
124 static void virtio_pmem_pci_register_types(void)
126 virtio_pci_types_register(&virtio_pmem_pci_info
);
128 type_init(virtio_pmem_pci_register_types
)