This add the reset related sections for every QOM device. Signed-off-by: Damien Hedde <damien.he...@greensocs.com> --- hw/core/qdev-vmstate.c | 41 +++++++++++++++++++++++++++++++++++++++++ hw/core/qdev.c | 12 +++++++++++- include/hw/qdev-core.h | 3 +++ stubs/Makefile.objs | 1 + stubs/device.c | 7 +++++++ 5 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 stubs/device.c
diff --git a/hw/core/qdev-vmstate.c b/hw/core/qdev-vmstate.c index 07b010811f..24f8465c61 100644 --- a/hw/core/qdev-vmstate.c +++ b/hw/core/qdev-vmstate.c @@ -43,3 +43,44 @@ const struct VMStateDescription device_vmstate_reset = { VMSTATE_END_OF_LIST() }, }; + +static VMStateDescription *vmsd_duplicate_and_append( + const VMStateDescription *old_vmsd, + const VMStateDescription *new_subsection) +{ + VMStateDescription *vmsd; + int n = 0; + + assert(old_vmsd && new_subsection); + + vmsd = (VMStateDescription *) g_memdup(old_vmsd, sizeof(*vmsd)); + + if (old_vmsd->subsections) { + while (old_vmsd->subsections[n]) { + n += 1; + } + } + vmsd->subsections = g_new(const VMStateDescription *, n + 2); + + if (old_vmsd->subsections) { + memcpy(vmsd->subsections, old_vmsd->subsections, + sizeof(VMStateDescription *) * n); + } + vmsd->subsections[n] = new_subsection; + vmsd->subsections[n + 1] = NULL; + + return vmsd; +} + +void device_class_build_extended_vmsd(DeviceClass *dc) +{ + assert(dc->vmsd); + assert(!dc->vmsd_ext); + + /* forge a subsection with proper name */ + VMStateDescription *reset; + reset = g_memdup(&device_vmstate_reset, sizeof(*reset)); + reset->name = g_strdup_printf("%s/device_reset", dc->vmsd->name); + + dc->vmsd_ext = vmsd_duplicate_and_append(dc->vmsd, reset); +} diff --git a/hw/core/qdev.c b/hw/core/qdev.c index e9e5f2d5f9..88387d3743 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -45,7 +45,17 @@ bool qdev_hot_removed = false; const VMStateDescription *qdev_get_vmsd(DeviceState *dev) { DeviceClass *dc = DEVICE_GET_CLASS(dev); - return dc->vmsd; + + if (!dc->vmsd) { + return NULL; + } + + if (!dc->vmsd_ext) { + /* build it first time we need it */ + device_class_build_extended_vmsd(dc); + } + + return dc->vmsd_ext; } static void bus_remove_child(BusState *bus, DeviceState *child) diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 1670ae41bb..926d4bbcb1 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -120,6 +120,7 @@ typedef struct DeviceClass { /* device state */ const struct VMStateDescription *vmsd; + const struct VMStateDescription *vmsd_ext; /* Private to qdev / bus. */ const char *bus_type; @@ -520,6 +521,8 @@ void device_class_set_parent_unrealize(DeviceClass *dc, const struct VMStateDescription *qdev_get_vmsd(DeviceState *dev); +void device_class_build_extended_vmsd(DeviceClass *dc); + const char *qdev_fw_name(DeviceState *dev); Object *qdev_get_machine(void); diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 9c7393b08c..432b56f290 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -40,4 +40,5 @@ stub-obj-y += pci-host-piix.o stub-obj-y += ram-block.o stub-obj-y += ramfb.o stub-obj-y += fw_cfg.o +stub-obj-y += device.o stub-obj-$(CONFIG_SOFTMMU) += semihost.o diff --git a/stubs/device.c b/stubs/device.c new file mode 100644 index 0000000000..e9b4f57e5f --- /dev/null +++ b/stubs/device.c @@ -0,0 +1,7 @@ +#include "qemu/osdep.h" +#include "hw/qdev-core.h" + +void device_class_build_extended_vmsd(DeviceClass *dc) +{ + return; +} -- 2.22.0