diff options
author | Juan Quintela <quintela@redhat.com> | 2009-08-20 19:42:39 +0200 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2009-08-27 20:30:22 -0500 |
commit | 73534f2f682f2957fabb25e3890481098cc5dcee (patch) | |
tree | 16dc4aa473ce9f024409689a77e3ff775a8f6c66 | |
parent | f16c4abfadf9ae63bd22fb793484912542be0da7 (diff) | |
download | qemu-73534f2f682f2957fabb25e3890481098cc5dcee.tar.gz qemu-73534f2f682f2957fabb25e3890481098cc5dcee.tar.bz2 qemu-73534f2f682f2957fabb25e3890481098cc5dcee.zip |
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 <quintela@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r-- | hw/hw.h | 12 | ||||
-rw-r--r-- | hw/pci.c | 65 |
2 files changed, 55 insertions, 22 deletions
@@ -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 @@ -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; |