From 73534f2f682f2957fabb25e3890481098cc5dcee Mon Sep 17 00:00:00 2001 From: Juan Quintela Date: Thu, 20 Aug 2009 19:42:39 +0200 Subject: [PATCH] Port PCIDevice state to VMState This uses a variant of buffer, with extra checks. Also uses the new support for cheking that a read value is less or equal than a field. Signed-off-by: Juan Quintela Signed-off-by: Anthony Liguori --- hw/hw.h | 12 +++++++++++ hw/pci.c | 65 +++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 55 insertions(+), 22 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index f7b0a14793..73f2f43281 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -402,6 +402,18 @@ extern const VMStateInfo vmstate_info_buffer; + type_check_array(uint8_t,typeof_field(_state, _field),sizeof(typeof_field(_state,_field))) \ } +extern const VMStateDescription vmstate_pci_device; + +#define VMSTATE_PCI_DEVICE(_field, _state) { \ + .name = (stringify(_field)), \ + .version_id = 2, \ + .size = sizeof(PCIDevice), \ + .vmsd = &vmstate_pci_device, \ + .flags = VMS_STRUCT, \ + .offset = offsetof(_state, _field) \ + + type_check(PCIDevice,typeof_field(_state, _field)) \ +} + /* _f : field name _f_n : num of elements field_name _n : num of elements diff --git a/hw/pci.c b/hw/pci.c index 7644dee90e..2266e23c11 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -140,39 +140,60 @@ int pci_bus_num(PCIBus *s) return s->bus_num; } -void pci_device_save(PCIDevice *s, QEMUFile *f) -{ - int i; - - qemu_put_be32(f, s->version_id); /* PCI device version */ - qemu_put_buffer(f, s->config, 256); - for (i = 0; i < 4; i++) - qemu_put_be32(f, s->irq_state[i]); -} - -int pci_device_load(PCIDevice *s, QEMUFile *f) +static int get_pci_config_device(QEMUFile *f, void *pv, size_t size) { - uint8_t config[PCI_CONFIG_SPACE_SIZE]; - uint32_t version_id; + PCIDevice *s = container_of(pv, PCIDevice, config); + uint8_t config[size]; int i; - version_id = qemu_get_be32(f); - if (version_id > 2) - return -EINVAL; - qemu_get_buffer(f, config, sizeof config); - for (i = 0; i < sizeof config; ++i) + qemu_get_buffer(f, config, size); + for (i = 0; i < size; ++i) if ((config[i] ^ s->config[i]) & s->cmask[i] & ~s->wmask[i]) return -EINVAL; - memcpy(s->config, config, sizeof config); + memcpy(s->config, config, size); pci_update_mappings(s); - if (version_id >= 2) - for (i = 0; i < 4; i ++) - s->irq_state[i] = qemu_get_be32(f); return 0; } +/* just put buffer */ +static void put_pci_config_device(QEMUFile *f, const void *pv, size_t size) +{ + const uint8_t *v = pv; + qemu_put_buffer(f, v, size); +} + +static VMStateInfo vmstate_info_pci_config = { + .name = "pci config", + .get = get_pci_config_device, + .put = put_pci_config_device, +}; + +const VMStateDescription vmstate_pci_device = { + .name = "PCIDevice", + .version_id = 2, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_INT32_LE(version_id, PCIDevice), + VMSTATE_SINGLE(config, PCIDevice, 0, vmstate_info_pci_config, + typeof_field(PCIDevice,config)), + VMSTATE_INT32_ARRAY_V(irq_state, PCIDevice, 4, 2), + VMSTATE_END_OF_LIST() + } +}; + +void pci_device_save(PCIDevice *s, QEMUFile *f) +{ + vmstate_save_state(f, &vmstate_pci_device, s); +} + +int pci_device_load(PCIDevice *s, QEMUFile *f) +{ + return vmstate_load_state(f, &vmstate_pci_device, s, s->version_id); +} + static int pci_set_default_subsystem_id(PCIDevice *pci_dev) { uint16_t *id; -- GitLab