diff options
Diffstat (limited to 'hw/mem/pc-dimm.c')
-rw-r--r-- | hw/mem/pc-dimm.c | 120 |
1 files changed, 64 insertions, 56 deletions
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 51350d9..ef33062 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "hw/mem/pc-dimm.h" #include "hw/mem/nvdimm.h" +#include "hw/mem/memory-device.h" #include "qapi/error.h" #include "qemu/config-file.h" #include "qapi/visitor.h" @@ -158,11 +159,6 @@ uint64_t pc_existing_dimms_capacity(Error **errp) return cap.size; } -uint64_t get_plugged_memory_size(void) -{ - return pc_existing_dimms_capacity(&error_abort); -} - static int pc_dimm_slot2bitmap(Object *obj, void *opaque) { unsigned long *bitmap = opaque; @@ -238,57 +234,6 @@ static int pc_dimm_built_list(Object *obj, void *opaque) return 0; } -MemoryDeviceInfoList *qmp_pc_dimm_device_list(void) -{ - GSList *dimms = NULL, *item; - MemoryDeviceInfoList *list = NULL, *prev = NULL; - - object_child_foreach(qdev_get_machine(), pc_dimm_built_list, &dimms); - - for (item = dimms; item; item = g_slist_next(item)) { - PCDIMMDevice *dimm = PC_DIMM(item->data); - Object *obj = OBJECT(dimm); - MemoryDeviceInfoList *elem = g_new0(MemoryDeviceInfoList, 1); - MemoryDeviceInfo *info = g_new0(MemoryDeviceInfo, 1); - PCDIMMDeviceInfo *di = g_new0(PCDIMMDeviceInfo, 1); - bool is_nvdimm = object_dynamic_cast(obj, TYPE_NVDIMM); - DeviceClass *dc = DEVICE_GET_CLASS(obj); - DeviceState *dev = DEVICE(obj); - - if (dev->id) { - di->has_id = true; - di->id = g_strdup(dev->id); - } - di->hotplugged = dev->hotplugged; - di->hotpluggable = dc->hotpluggable; - di->addr = dimm->addr; - di->slot = dimm->slot; - di->node = dimm->node; - di->size = object_property_get_uint(obj, PC_DIMM_SIZE_PROP, NULL); - di->memdev = object_get_canonical_path(OBJECT(dimm->hostmem)); - - if (!is_nvdimm) { - info->u.dimm.data = di; - info->type = MEMORY_DEVICE_INFO_KIND_DIMM; - } else { - info->u.nvdimm.data = di; - info->type = MEMORY_DEVICE_INFO_KIND_NVDIMM; - } - elem->value = info; - elem->next = NULL; - if (prev) { - prev->next = elem; - } else { - list = elem; - } - prev = elem; - } - - g_slist_free(dimms); - - return list; -} - uint64_t pc_dimm_get_free_addr(uint64_t address_space_start, uint64_t address_space_size, uint64_t *hint, uint64_t align, uint64_t size, @@ -445,10 +390,63 @@ static MemoryRegion *pc_dimm_get_vmstate_memory_region(PCDIMMDevice *dimm) return host_memory_backend_get_memory(dimm->hostmem, &error_abort); } +static uint64_t pc_dimm_md_get_addr(const MemoryDeviceState *md) +{ + const PCDIMMDevice *dimm = PC_DIMM(md); + + return dimm->addr; +} + +static uint64_t pc_dimm_md_get_region_size(const MemoryDeviceState *md) +{ + /* dropping const here is fine as we don't touch the memory region */ + PCDIMMDevice *dimm = PC_DIMM(md); + const PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(md); + MemoryRegion *mr; + + mr = ddc->get_memory_region(dimm, &error_abort); + if (!mr) { + return 0; + } + + return memory_region_size(mr); +} + +static void pc_dimm_md_fill_device_info(const MemoryDeviceState *md, + MemoryDeviceInfo *info) +{ + PCDIMMDeviceInfo *di = g_new0(PCDIMMDeviceInfo, 1); + const DeviceClass *dc = DEVICE_GET_CLASS(md); + const PCDIMMDevice *dimm = PC_DIMM(md); + const DeviceState *dev = DEVICE(md); + + if (dev->id) { + di->has_id = true; + di->id = g_strdup(dev->id); + } + di->hotplugged = dev->hotplugged; + di->hotpluggable = dc->hotpluggable; + di->addr = dimm->addr; + di->slot = dimm->slot; + di->node = dimm->node; + di->size = object_property_get_uint(OBJECT(dimm), PC_DIMM_SIZE_PROP, + NULL); + di->memdev = object_get_canonical_path(OBJECT(dimm->hostmem)); + + if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { + info->u.nvdimm.data = di; + info->type = MEMORY_DEVICE_INFO_KIND_NVDIMM; + } else { + info->u.dimm.data = di; + info->type = MEMORY_DEVICE_INFO_KIND_DIMM; + } +} + static void pc_dimm_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PCDIMMDeviceClass *ddc = PC_DIMM_CLASS(oc); + MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc); dc->realize = pc_dimm_realize; dc->unrealize = pc_dimm_unrealize; @@ -457,6 +455,12 @@ static void pc_dimm_class_init(ObjectClass *oc, void *data) ddc->get_memory_region = pc_dimm_get_memory_region; ddc->get_vmstate_memory_region = pc_dimm_get_vmstate_memory_region; + + mdc->get_addr = pc_dimm_md_get_addr; + /* for a dimm plugged_size == region_size */ + mdc->get_plugged_size = pc_dimm_md_get_region_size; + mdc->get_region_size = pc_dimm_md_get_region_size; + mdc->fill_device_info = pc_dimm_md_fill_device_info; } static TypeInfo pc_dimm_info = { @@ -466,6 +470,10 @@ static TypeInfo pc_dimm_info = { .instance_init = pc_dimm_init, .class_init = pc_dimm_class_init, .class_size = sizeof(PCDIMMDeviceClass), + .interfaces = (InterfaceInfo[]) { + { TYPE_MEMORY_DEVICE }, + { } + }, }; static void pc_dimm_register_types(void) |