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 virtio_pci_force_virtio_1(vpci_dev
);
26 qdev_realize(vdev
, BUS(&vpci_dev
->bus
), errp
);
29 static void virtio_pmem_pci_set_addr(MemoryDeviceState
*md
, uint64_t addr
,
32 object_property_set_uint(OBJECT(md
), VIRTIO_PMEM_ADDR_PROP
, addr
, errp
);
35 static uint64_t virtio_pmem_pci_get_addr(const MemoryDeviceState
*md
)
37 return object_property_get_uint(OBJECT(md
), VIRTIO_PMEM_ADDR_PROP
,
41 static MemoryRegion
*virtio_pmem_pci_get_memory_region(MemoryDeviceState
*md
,
44 VirtIOPMEMPCI
*pci_pmem
= VIRTIO_PMEM_PCI(md
);
45 VirtIOPMEM
*pmem
= VIRTIO_PMEM(&pci_pmem
->vdev
);
46 VirtIOPMEMClass
*vpc
= VIRTIO_PMEM_GET_CLASS(pmem
);
48 return vpc
->get_memory_region(pmem
, errp
);
51 static uint64_t virtio_pmem_pci_get_plugged_size(const MemoryDeviceState
*md
,
54 VirtIOPMEMPCI
*pci_pmem
= VIRTIO_PMEM_PCI(md
);
55 VirtIOPMEM
*pmem
= VIRTIO_PMEM(&pci_pmem
->vdev
);
56 VirtIOPMEMClass
*vpc
= VIRTIO_PMEM_GET_CLASS(pmem
);
57 MemoryRegion
*mr
= vpc
->get_memory_region(pmem
, errp
);
59 /* the plugged size corresponds to the region size */
60 return mr
? memory_region_size(mr
) : 0;
63 static void virtio_pmem_pci_fill_device_info(const MemoryDeviceState
*md
,
64 MemoryDeviceInfo
*info
)
66 VirtioPMEMDeviceInfo
*vi
= g_new0(VirtioPMEMDeviceInfo
, 1);
67 VirtIOPMEMPCI
*pci_pmem
= VIRTIO_PMEM_PCI(md
);
68 VirtIOPMEM
*pmem
= VIRTIO_PMEM(&pci_pmem
->vdev
);
69 VirtIOPMEMClass
*vpc
= VIRTIO_PMEM_GET_CLASS(pmem
);
70 DeviceState
*dev
= DEVICE(md
);
74 vi
->id
= g_strdup(dev
->id
);
77 /* let the real device handle everything else */
78 vpc
->fill_device_info(pmem
, vi
);
80 info
->u
.virtio_pmem
.data
= vi
;
81 info
->type
= MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM
;
84 static void virtio_pmem_pci_class_init(ObjectClass
*klass
, void *data
)
86 DeviceClass
*dc
= DEVICE_CLASS(klass
);
87 VirtioPCIClass
*k
= VIRTIO_PCI_CLASS(klass
);
88 PCIDeviceClass
*pcidev_k
= PCI_DEVICE_CLASS(klass
);
89 MemoryDeviceClass
*mdc
= MEMORY_DEVICE_CLASS(klass
);
91 k
->realize
= virtio_pmem_pci_realize
;
92 set_bit(DEVICE_CATEGORY_MISC
, dc
->categories
);
93 pcidev_k
->vendor_id
= PCI_VENDOR_ID_REDHAT_QUMRANET
;
94 pcidev_k
->device_id
= PCI_DEVICE_ID_VIRTIO_PMEM
;
95 pcidev_k
->revision
= VIRTIO_PCI_ABI_VERSION
;
96 pcidev_k
->class_id
= PCI_CLASS_OTHERS
;
98 mdc
->get_addr
= virtio_pmem_pci_get_addr
;
99 mdc
->set_addr
= virtio_pmem_pci_set_addr
;
100 mdc
->get_plugged_size
= virtio_pmem_pci_get_plugged_size
;
101 mdc
->get_memory_region
= virtio_pmem_pci_get_memory_region
;
102 mdc
->fill_device_info
= virtio_pmem_pci_fill_device_info
;
105 static void virtio_pmem_pci_instance_init(Object
*obj
)
107 VirtIOPMEMPCI
*dev
= VIRTIO_PMEM_PCI(obj
);
109 virtio_instance_init_common(obj
, &dev
->vdev
, sizeof(dev
->vdev
),
113 static const VirtioPCIDeviceTypeInfo virtio_pmem_pci_info
= {
114 .base_name
= TYPE_VIRTIO_PMEM_PCI
,
115 .generic_name
= "virtio-pmem-pci",
116 .instance_size
= sizeof(VirtIOPMEMPCI
),
117 .instance_init
= virtio_pmem_pci_instance_init
,
118 .class_init
= virtio_pmem_pci_class_init
,
119 .interfaces
= (InterfaceInfo
[]) {
120 { TYPE_MEMORY_DEVICE
},
125 static void virtio_pmem_pci_register_types(void)
127 virtio_pci_types_register(&virtio_pmem_pci_info
);
129 type_init(virtio_pmem_pci_register_types
)